about summary refs log tree commit diff
path: root/client
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2020-08-02T10·16+0100
committerWilliam Carroll <wpcarro@gmail.com>2020-08-02T10·16+0100
commit699892883ceaffb64e0d9b9aaab67313a60a5428 (patch)
treec3dd3e40d3a18de274f3b0a4654137ebc3102b75 /client
parentd5bc6f963d4c8cdb8990a9946d9a142a32e13d3c (diff)
Support deleting trips from the client
TL;DR:
- Ensure Types.TripPK in Types.hs uses Calendar.Day for startDate
- Prefer verbiage "GotCreateTrip" to "CreatedTrip"
- Extend Utils.deleteWithCredentials to accept a body parameter
- Support a delete button in the UI
Diffstat (limited to 'client')
-rw-r--r--client/src/State.elm57
-rw-r--r--client/src/User.elm84
-rw-r--r--client/src/Utils.elm5
3 files changed, 103 insertions, 43 deletions
diff --git a/client/src/State.elm b/client/src/State.elm
index 190cab7eacae..d3db7ddf2967 100644
--- a/client/src/State.elm
+++ b/client/src/State.elm
@@ -49,6 +49,7 @@ type Msg
     | AttemptLogout
     | AttemptDeleteUser String
     | AttemptCreateTrip Date.Date Date.Date
+    | AttemptDeleteTrip String Date.Date
       -- Inbound network
     | GotUsers (WebData AllUsers)
     | GotTrips (WebData (List Trip))
@@ -56,7 +57,8 @@ type Msg
     | GotLogin (Result Http.Error Session)
     | GotLogout (Result Http.Error String)
     | GotDeleteUser (Result Http.Error String)
-    | CreatedTrip (Result Http.Error ())
+    | GotCreateTrip (Result Http.Error ())
+    | GotDeleteTrip (Result Http.Error ())
 
 
 type Route
@@ -135,6 +137,7 @@ type alias Model =
     , signUpError : Maybe Http.Error
     , deleteUserError : Maybe Http.Error
     , createTripError : Maybe Http.Error
+    , deleteTripError : Maybe Http.Error
     }
 
 
@@ -269,7 +272,28 @@ createTrip { username, destination, startDate, endDate, comment } =
                     , ( "comment", JE.string comment )
                     ]
                 )
-        , expect = Http.expectWhatever CreatedTrip
+        , expect = Http.expectWhatever GotCreateTrip
+        }
+
+
+deleteTrip :
+    { username : String
+    , destination : String
+    , startDate : Date.Date
+    }
+    -> Cmd Msg
+deleteTrip { username, destination, startDate } =
+    Utils.deleteWithCredentials
+        { url = endpoint [ "trips" ] []
+        , body =
+            Http.jsonBody
+                (JE.object
+                    [ ( "username", JE.string username )
+                    , ( "destination", JE.string destination )
+                    , ( "startDate", encodeDate startDate )
+                    ]
+                )
+        , expect = Http.expectWhatever GotDeleteTrip
         }
 
 
@@ -277,6 +301,7 @@ deleteUser : String -> Cmd Msg
 deleteUser username =
     Utils.deleteWithCredentials
         { url = endpoint [ "user", username ] []
+        , body = Http.emptyBody
         , expect = Http.expectString GotDeleteUser
         }
 
@@ -413,6 +438,7 @@ prod _ url key =
       , signUpError = Nothing
       , deleteUserError = Nothing
       , createTripError = Nothing
+      , deleteTripError = Nothing
       }
     , Cmd.batch
         [ Cmd.map UpdateTripStartDate startDatePickerCmd
@@ -651,7 +677,7 @@ update msg model =
                         }
             )
 
-        CreatedTrip result ->
+        GotCreateTrip result ->
             case result of
                 Ok _ ->
                     ( { model
@@ -674,6 +700,31 @@ update msg model =
                     , sleepAndClearErrors
                     )
 
+        -- DELETE /trips
+        AttemptDeleteTrip destination startDate ->
+            ( model
+            , case model.session of
+                Nothing ->
+                    Cmd.none
+
+                Just session ->
+                    deleteTrip
+                        { username = session.username
+                        , destination = destination
+                        , startDate = startDate
+                        }
+            )
+
+        GotDeleteTrip result ->
+            case result of
+                Ok _ ->
+                    ( model, fetchTrips )
+
+                Err e ->
+                    ( { model | deleteTripError = Just e }
+                    , sleepAndClearErrors
+                    )
+
         -- POST /accounts
         AttemptSignUp ->
             ( model
diff --git a/client/src/User.elm b/client/src/User.elm
index 5216eeada03e..48aca865231d 100644
--- a/client/src/User.elm
+++ b/client/src/User.elm
@@ -71,7 +71,30 @@ createTrip model =
         ]
 
 
-trips : State.Model -> Html msg
+renderTrip : State.Trip -> Html State.Msg
+renderTrip trip =
+    li
+        [ [ "py-2" ]
+            |> Tailwind.use
+            |> class
+        ]
+        [ p []
+            [ text
+                (Date.toIsoString trip.startDate
+                    ++ " - "
+                    ++ Date.toIsoString trip.endDate
+                    ++ " -> "
+                    ++ trip.destination
+                )
+            ]
+        , UI.textButton
+            { label = "Delete"
+            , handleClick = State.AttemptDeleteTrip trip.destination trip.startDate
+            }
+        ]
+
+
+trips : State.Model -> Html State.Msg
 trips model =
     div []
         [ UI.header 3 "Upcoming Trips"
@@ -86,45 +109,30 @@ trips model =
                 UI.paragraph ("Error: " ++ Utils.explainHttpError e)
 
             RemoteData.Success xs ->
-                ul []
-                    (xs
-                        |> List.map
-                            (\trip ->
-                                li
-                                    [ [ "py-2" ]
-                                        |> Tailwind.use
-                                        |> class
-                                    ]
-                                    [ text
-                                        (Date.toIsoString trip.startDate
-                                            ++ " - "
-                                            ++ Date.toIsoString trip.endDate
-                                            ++ " -> "
-                                            ++ trip.destination
-                                        )
-                                    ]
-                            )
-                    )
+                ul [] (xs |> List.map renderTrip)
         ]
 
 
 render : State.Model -> Html State.Msg
 render model =
-    div
-        [ class
-            ([ "container"
-             , "mx-auto"
-             , "text-center"
-             ]
-                |> Tailwind.use
-            )
-        ]
-        [ UI.header 2 ("Welcome, " ++ model.username ++ "!")
-        , createTrip model
-        , trips model
-        , UI.textButton
-            { label = "Logout"
-            , handleClick = State.AttemptLogout
-            }
-        , Common.allErrors model
-        ]
+    Common.withSession model
+        (\session ->
+            div
+                [ class
+                    ([ "container"
+                     , "mx-auto"
+                     , "text-center"
+                     ]
+                        |> Tailwind.use
+                    )
+                ]
+                [ UI.header 2 ("Welcome, " ++ session.username ++ "!")
+                , createTrip model
+                , trips model
+                , UI.textButton
+                    { label = "Logout"
+                    , handleClick = State.AttemptLogout
+                    }
+                , Common.allErrors model
+                ]
+        )
diff --git a/client/src/Utils.elm b/client/src/Utils.elm
index 0f6c61ed286f..28f15fb5c101 100644
--- a/client/src/Utils.elm
+++ b/client/src/Utils.elm
@@ -62,17 +62,18 @@ postWithCredentials { url, body, expect } =
 
 deleteWithCredentials :
     { url : String
+    , body : Http.Body
     , expect : Http.Expect msg
     }
     -> Cmd msg
-deleteWithCredentials { url, expect } =
+deleteWithCredentials { url, body, expect } =
     Http.riskyRequest
         { url = url
         , headers = [ Http.header "Origin" Shared.clientOrigin ]
         , method = "DELETE"
         , timeout = Nothing
         , tracker = Nothing
-        , body = Http.emptyBody
+        , body = body
         , expect = expect
         }