onasty/web/src/Pages/SignIn.elm(view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
module Pages.SignIn exposing (Model, Msg, page)
import Api
import Api.Auth
import Data.Credentials exposing (Credentials)
import Effect exposing (Effect)
import Html exposing (Html)
import Html.Attributes as Attr
import Html.Events
import Http
import Page exposing (Page)
import Route exposing (Route)
import Route.Path
import Shared
import View exposing (View)
page : Shared.Model -> Route () -> Page Model Msg
page shared _ =
Page.new
{ init = init shared
, update = update
, subscriptions = subscriptions
, view = view
}
-- INIT
type alias Model =
{ email : String
, password : String
, isSubmittingForm : Bool
, error : Maybe Http.Error
}
init : Shared.Model -> () -> ( Model, Effect Msg )
init shared _ =
( { isSubmittingForm = False
, email = ""
, password = ""
, error = Nothing
}
, case shared.credentials of
Just _ ->
Effect.pushRoutePath Route.Path.Home_
Nothing ->
Effect.none
)
-- UPDATE
type Msg
= UserUpdatedInput Field String
| UserClickedSubmit
| ApiSignInResponded (Result Http.Error Credentials)
type Field
= Email
| Password
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
case msg of
UserClickedSubmit ->
( { model | isSubmittingForm = True }
, Api.Auth.signin
{ onResponse = ApiSignInResponded
, email = model.email
, password = model.password
}
)
UserUpdatedInput Email email ->
( { model | email = email }, Effect.none )
UserUpdatedInput Password password ->
( { model | password = password }, Effect.none )
ApiSignInResponded (Ok credentials) ->
( { model | isSubmittingForm = False }
, Effect.signin credentials
)
ApiSignInResponded (Err error) ->
( { model | isSubmittingForm = False, error = Just error }
, Effect.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.none
-- VIEW
view : Model -> View Msg
view model =
{ title = "Sign-in"
, body =
[ Html.div []
[ Html.div []
[ Html.div []
[ Html.h1 [] [ Html.text "Sign in" ]
, viewError model.error
, viewForm model
]
]
]
]
}
viewForm : Model -> Html Msg
viewForm model =
Html.form [ Html.Events.onSubmit UserClickedSubmit ]
[ viewFormInput { field = Email, value = model.email }
, viewFormInput { field = Password, value = model.password }
, viewFormControls model
]
viewError : Maybe Http.Error -> Html Msg
viewError maybeError =
case maybeError of
Just error ->
Html.div [ Attr.style "color" "red" ]
[ Html.text (Api.errorToFriendlyMessage error) ]
Nothing ->
Html.text ""
viewFormInput : { field : Field, value : String } -> Html Msg
viewFormInput opts =
Html.div []
[ Html.label [] [ Html.text (fromFieldToLabel opts.field) ]
, Html.div []
[ Html.input
[ Attr.type_ (fromFieldToInputType opts.field)
, Attr.value opts.value
, Html.Events.onInput (UserUpdatedInput opts.field)
]
[]
]
]
viewFormControls : Model -> Html Msg
viewFormControls model =
Html.div []
[ Html.button
[ Attr.disabled model.isSubmittingForm ]
[ Html.text "Sign In" ]
]
fromFieldToLabel : Field -> String
fromFieldToLabel field =
case field of
Email ->
"Email address"
Password ->
"Password"
fromFieldToInputType : Field -> String
fromFieldToInputType field =
case field of
Email ->
"email"
Password ->
"password"
|