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 exposing (Document)
import Browser.Navigation as Nav 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 Http
import Json.Decode exposing (Decoder, field, int, list, map3, maybe, string) import Json.Decode exposing (Decoder, field, int, list, map3, maybe, string)
import Json.Encode as Encode
type alias Task = 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 = type alias Model =
{ navKey : Nav.Key { navKey : Nav.Key
, tasks : Status (List Task) , tasks : Status (List Task)
, createTaskCollapsed : Bool
, createTask : CreateTaskInfo
} }
@ -28,16 +44,21 @@ type Status a
init : Nav.Key -> ( Model, Cmd Msg ) init : Nav.Key -> ( Model, Cmd Msg )
init navKey = init navKey =
( Model navKey Loading ( Model navKey Loading True defaultCreateTask
, Http.get , Http.get
{ url = "http://localhost:3000/tasks" { url = "http://localhost:3000/tasks"
, expect = Http.expectJson GotTasks taskDecoder , expect = Http.expectJson GotTasks (list taskDecoder)
} }
) )
type Msg type Msg
= GotTasks (Result Http.Error (List Task)) = GotTasks (Result Http.Error (List Task))
| ToggleCreateTask
| CreateTask
| GotTaskCreated (Result Http.Error Task)
| CreateTaskUpdateTitle String
| CreateTaskUpdateDescription String
update : Msg -> Model -> ( Model, Cmd Msg ) update : Msg -> Model -> ( Model, Cmd Msg )
@ -51,21 +72,68 @@ update msg model =
Err _ -> Err _ ->
( { model | tasks = Failure }, Cmd.none ) ( { 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 = taskDecoder =
list map3 Task
(map3 Task (field "id" int)
(field "id" int) (field "title" string)
(field "title" string) (maybe
(maybe (field "description"
(field "description" string
string
)
) )
) )
taskEncoder : CreateTaskInfo -> Encode.Value
taskEncoder task =
Encode.object
[ ( "title", Encode.string task.title )
, ( "description", Encode.string task.description )
]
view : Model -> Document Msg view : Model -> Document Msg
view model = view model =
{ title = "Dashboard" { title = "Dashboard"
@ -83,4 +151,38 @@ viewBody model =
div [] [ text "Loading" ] div [] [ text "Loading" ]
Success tasks -> 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" ] ]
]