Skip to content

Commit

Permalink
Merge pull request #14 from dwyl/capture-page-#8
Browse files Browse the repository at this point in the history
Capture page
  • Loading branch information
nelsonic authored Mar 6, 2020
2 parents 61692c9 + df0d1cb commit 470e2f0
Show file tree
Hide file tree
Showing 9 changed files with 989 additions and 210 deletions.
910 changes: 703 additions & 207 deletions elm.js

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion src/Endpoint.elm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Endpoint exposing (Endpoint, authUrls, personInfo, toString, url)
module Endpoint exposing (Endpoint, authUrls, captures, personInfo, toString, url)

import Url.Builder exposing (QueryParameter)

Expand Down Expand Up @@ -36,3 +36,8 @@ authUrls =
personInfo : Endpoint
personInfo =
url [ "api", "person", "info" ] []


captures : Endpoint
captures =
url [ "api", "capture" ] []
26 changes: 26 additions & 0 deletions src/Main.elm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Html exposing (..)
import Html.Attributes exposing (..)
import Page
import Pages.Auth as Auth
import Pages.Capture as Capture
import Pages.Home as Home
import Pages.Session as PagesSession
import Route
Expand Down Expand Up @@ -36,6 +37,7 @@ type Model
| Session PagesSession.Model
| NotFound Session.Session
| Logout Session.Session
| Capture Capture.Model



Expand Down Expand Up @@ -67,6 +69,7 @@ type Msg
| GotHomeMsg Home.Msg
| GotAuthMsg Auth.Msg
| GotPagesSessionMsg PagesSession.Msg
| GotCaptureMsg Capture.Msg


update : Msg -> Model -> ( Model, Cmd Msg )
Expand Down Expand Up @@ -104,6 +107,13 @@ update msg model =
in
( Session subModel, Cmd.map GotPagesSessionMsg subMsg )

( GotCaptureMsg captureMsg, Capture captureModel ) ->
let
( subModel, subMsg ) =
Capture.update captureMsg captureModel
in
( Capture subModel, Cmd.map GotCaptureMsg subMsg )

-- combining the msg and the model.page allow us to filter out
-- messages coming from the wrong page
( _, _ ) ->
Expand Down Expand Up @@ -150,6 +160,13 @@ loadRoute maybeRoute model =
]
)

Just Route.Capture ->
let
( subModel, subMsg ) =
Capture.init session
in
( Capture subModel, Cmd.map GotCaptureMsg subMsg )


subscriptions : Model -> Sub Msg
subscriptions model =
Expand All @@ -169,6 +186,9 @@ subscriptions model =
Logout _ ->
Sub.none

Capture captureModel ->
Sub.map GotCaptureMsg (Capture.subscriptions captureModel)


view : Model -> Browser.Document Msg
view model =
Expand Down Expand Up @@ -198,6 +218,9 @@ view model =
]
}

Capture captureModel ->
Page.view GotCaptureMsg (Capture.view captureModel)


toSession : Model -> Session.Session
toSession page =
Expand All @@ -217,6 +240,9 @@ toSession page =
Logout session ->
session

Capture m ->
Capture.toSession m


toNavKey : Model -> Nav.Key
toNavKey model =
Expand Down
220 changes: 220 additions & 0 deletions src/Pages/Capture.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
module Pages.Capture exposing (Model, Msg(..), init, subscriptions, toSession, update, view)

import Asset
import Endpoint
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick, onInput)
import Http
import Json.Decode as JD
import Json.Encode as JE
import Page
import Route
import Session exposing (..)



-- Model


type alias Model =
{ session : Session
, captures : List Capture
, newCapture : Capture
, error : String
}


type alias Capture =
{ text : String
, completed : Bool
}


initCapture : Capture
initCapture =
Capture "" False


init : Session -> ( Model, Cmd Msg )
init session =
( Model session [] initCapture "", getCaptures (token session) )



-- Update


type Msg
= GotSession Session
| GotCaptures (Result Http.Error (List Capture))
| CaptureSaved (Result Http.Error Capture)
| UpdateNewCapture String
| AddCapture


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
GotSession session ->
( { model | session = session }
, Route.replaceUrl (Session.navKey model.session) Route.Home
)

GotCaptures result ->
case result of
Ok captures ->
( { model | captures = captures, error = "" }, Cmd.none )

Err httpError ->
case httpError of
Http.BadStatus 401 ->
( { model | error = "Access not authorised" }, Cmd.none )

Http.BadStatus 404 ->
( { model | error = "User information can't be retrieved" }, Cmd.none )

_ ->
( { model | error = "Error while getting the captures" }, Cmd.none )

CaptureSaved result ->
case result of
Ok _ ->
( { model | error = "" }, getCaptures (token model.session) )

Err httpError ->
case httpError of
Http.BadStatus 401 ->
( { model | error = "Access not authorised" }, Cmd.none )

Http.BadStatus 404 ->
( { model | error = "create capture endpoint not found" }, Cmd.none )

_ ->
( { model | error = "Error while creating the capture" }, Cmd.none )

UpdateNewCapture text ->
let
newCapture =
{ text = text, completed = False }
in
( { model | newCapture = newCapture }, Cmd.none )

-- save capture in database
AddCapture ->
( { model | newCapture = initCapture }, saveCapture (token model.session) model.newCapture )



-- View


view : Model -> Page.PageStructure Msg
view model =
{ title = "Capture"
, content =
[ a [ Route.href Route.Home ] [ img [ Asset.src Asset.logo, class "center db pt2" ] [] ]
, h1 [ class "tc" ] [ text "Dwyl application" ]
, case model.session of
Session.Guest _ ->
a [ Route.href Route.Home, class "tc db" ] [ text "Not logged in yet!" ]

Session.Session _ _ ->
div []
[ if String.isEmpty model.error then
div []
[ div [ class "w-60 center tc" ]
[ input [ class "w-80 mr2", value model.newCapture.text, onInput UpdateNewCapture ] []
, button [ class "pointer", onClick AddCapture ] [ text "Add Capture" ]
]
, div [ class "w-50 center" ] <| List.map (\capture -> showCapture capture) model.captures
]

else
p [ class "red tc" ] [ text model.error ]
]
]
}


toSession : Model -> Session
toSession model =
model.session


subscriptions : Model -> Sub Msg
subscriptions model =
Session.changeSession GotSession (Session.navKey model.session)



-- captures


getCaptures : String -> Cmd Msg
getCaptures token =
Http.request
{ method = "GET"
, headers = [ Http.header "authorization" ("Bearer " ++ token) ]
, url = Endpoint.toString Endpoint.captures
, body = Http.emptyBody
, expect = Http.expectJson GotCaptures capturesDecoder
, timeout = Nothing
, tracker = Nothing
}


saveCapture : String -> Capture -> Cmd Msg
saveCapture token capture =
Http.request
{ method = "POST"
, headers = [ Http.header "authorization" ("Bearer " ++ token) ]
, url = Endpoint.toString Endpoint.captures
, body = Http.jsonBody <| captureEncode capture
, expect = Http.expectJson CaptureSaved savedCaptureDecoder
, timeout = Nothing
, tracker = Nothing
}



-- captures decoder


capturesDecoder : JD.Decoder (List Capture)
capturesDecoder =
JD.field "data" (JD.list captureDecoder)


savedCaptureDecoder : JD.Decoder Capture
savedCaptureDecoder =
JD.field "data" captureDecoder


captureDecoder : JD.Decoder Capture
captureDecoder =
JD.map2 Capture
(JD.field "text" JD.string)
(JD.field "completed" JD.bool)


captureEncode : Capture -> JD.Value
captureEncode capture =
JE.object
[ ( "text", JE.string capture.text ) ]



-- show capture


showCapture : Capture -> Html Msg
showCapture capture =
div [ class "pa2" ]
[ label
[ class "dib pa2" ]
[ input [ type_ "checkbox", checked capture.completed, class "mr2" ] []
, text capture.text
]
, button [ class "fr" ] [ text "Start" ]
]
1 change: 1 addition & 0 deletions src/Pages/Home.elm
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ view model =
Session.Session _ person ->
div []
[ span [ class "tc db" ] [ text <| "logged in with: " ++ person.email ]
, a [ Route.href Route.Capture, class "tc db" ] [ text "capture" ]
, a [ Route.href Route.Logout, class "tc db" ] [ text "logout" ]
]
]
Expand Down
1 change: 0 additions & 1 deletion src/Pages/Session.elm
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ update msg model =

getPersonInfo : String -> Cmd Msg
getPersonInfo token =
-- make sure to update the backend app endpoint to return a user info
Http.request
{ method = "GET"
, headers = [ Http.header "authorization" ("Bearer " ++ token) ]
Expand Down
5 changes: 5 additions & 0 deletions src/Route.elm
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Route
= Home
| Auth (Maybe String)
| Logout
| Capture


routeParser : Parser.Parser (Route -> a) a
Expand All @@ -24,6 +25,7 @@ routeParser =
[ Parser.map Home Parser.top
, Parser.map Auth (Parser.s "auth" <?> Query.string "jwt")
, Parser.map Logout (Parser.s "logout")
, Parser.map Capture (Parser.s "capture")
]


Expand Down Expand Up @@ -52,6 +54,9 @@ routeToString route =
Logout ->
"/logout"

Capture ->
"/capture"


replaceUrl : Nav.Key -> Route -> Cmd msg
replaceUrl key route =
Expand Down
12 changes: 11 additions & 1 deletion src/Session.elm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
port module Session exposing (Person, Session(..), changeSession, decode, encode, logout, navKey, onSessionChange, storeSession)
port module Session exposing (Person, Session(..), changeSession, decode, encode, logout, navKey, onSessionChange, storeSession, token)

{-| Represent the current user
The user can be authenticated or a guest
Expand Down Expand Up @@ -48,6 +48,16 @@ navKey session =
key


token : Session -> String
token session =
case session of
Guest _ ->
""

Session _ person ->
person.token


port storeSession : Maybe JD.Value -> Cmd msg


Expand Down
Loading

0 comments on commit 470e2f0

Please sign in to comment.