update frontend to allow creating tasks.

This commit is contained in:
Drew Galbraith 2024-07-05 22:55:46 -07:00
parent 637a246caa
commit d2dfbb9a4a
1 changed files with 115 additions and 13 deletions

View File

@ -2,9 +2,12 @@ module Dashboard exposing (Model, Msg, Task, init, update, view)
import Browser exposing (Document)
import Browser.Navigation as Nav
import Html exposing (Html, div, text)
import Html exposing (Html, button, div, input, text, textarea)
import Html.Attributes exposing (placeholder, value)
import Html.Events exposing (onClick, onInput)
import Http
import Json.Decode exposing (Decoder, field, int, list, map3, maybe, string)
import Json.Encode as Encode
type alias Task =
@ -14,9 +17,22 @@ type alias Task =
}
type alias CreateTaskInfo =
{ title : String, description : String }
defaultCreateTask : CreateTaskInfo
defaultCreateTask =
{ title = ""
, description = ""
}
type alias Model =
{ navKey : Nav.Key
, tasks : Status (List Task)
, createTaskCollapsed : Bool
, createTask : CreateTaskInfo
}
@ -28,16 +44,21 @@ type Status a
init : Nav.Key -> ( Model, Cmd Msg )
init navKey =
( Model navKey Loading
( Model navKey Loading True defaultCreateTask
, Http.get
{ url = "http://localhost:3000/tasks"
, expect = Http.expectJson GotTasks taskDecoder
, expect = Http.expectJson GotTasks (list taskDecoder)
}
)
type Msg
= GotTasks (Result Http.Error (List Task))
| ToggleCreateTask
| CreateTask
| GotTaskCreated (Result Http.Error Task)
| CreateTaskUpdateTitle String
| CreateTaskUpdateDescription String
update : Msg -> Model -> ( Model, Cmd Msg )
@ -51,11 +72,51 @@ update msg model =
Err _ ->
( { model | tasks = Failure }, Cmd.none )
ToggleCreateTask ->
( { model | createTaskCollapsed = not model.createTaskCollapsed }
, Cmd.none
)
taskDecoder : Decoder (List Task)
CreateTask ->
( model
, Http.post
{ url = "http://localhost:3000/tasks"
, body = Http.jsonBody (taskEncoder model.createTask)
, expect = Http.expectJson GotTaskCreated taskDecoder
}
)
GotTaskCreated result ->
case result of
Ok task ->
case model.tasks of
Success tasks ->
( { model | tasks = Success (task :: tasks) }, Cmd.none )
_ ->
( { model | tasks = Success [ task ] }, Cmd.none )
Err _ ->
( model, Cmd.none )
CreateTaskUpdateTitle title ->
let
createTask =
model.createTask
in
( { model | createTask = { createTask | title = title } }, Cmd.none )
CreateTaskUpdateDescription description ->
let
createTask =
model.createTask
in
( { model | createTask = { createTask | description = description } }, Cmd.none )
taskDecoder : Decoder Task
taskDecoder =
list
(map3 Task
map3 Task
(field "id" int)
(field "title" string)
(maybe
@ -63,7 +124,14 @@ taskDecoder =
string
)
)
)
taskEncoder : CreateTaskInfo -> Encode.Value
taskEncoder task =
Encode.object
[ ( "title", Encode.string task.title )
, ( "description", Encode.string task.description )
]
view : Model -> Document Msg
@ -83,4 +151,38 @@ viewBody model =
div [] [ text "Loading" ]
Success tasks ->
div [] [ text ("Loaded " ++ String.fromInt (List.length tasks) ++ " tasks") ]
div []
[ text ("Loaded " ++ String.fromInt (List.length tasks) ++ "tasks")
, viewCreate model
]
viewCreate : Model -> Html Msg
viewCreate model =
if model.createTaskCollapsed then
div [] [ button [ onClick ToggleCreateTask ] [ text "+ Expand" ] ]
else
div []
[ button [ onClick ToggleCreateTask ] [ text "- Collapse" ]
, div []
[ input
[ placeholder "Task Title"
, value
model.createTask.title
, onInput CreateTaskUpdateTitle
]
[]
]
, div []
[ textarea
[ placeholder "Task Description"
, value
model.createTask.description
, onInput CreateTaskUpdateDescription
]
[]
]
, div []
[ button [ onClick CreateTask ] [ text "Create Task" ] ]
]