aboutsummaryrefslogtreecommitdiff
path: root/src/client/View
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/View')
-rw-r--r--src/client/View/Color.elm12
-rw-r--r--src/client/View/Date.elm48
-rw-r--r--src/client/View/Errors.elm21
-rw-r--r--src/client/View/Events.elm15
-rw-r--r--src/client/View/Form.elm153
-rw-r--r--src/client/View/Header.elm60
-rw-r--r--src/client/View/Plural.elm11
7 files changed, 320 insertions, 0 deletions
diff --git a/src/client/View/Color.elm b/src/client/View/Color.elm
new file mode 100644
index 0000000..a2a20c7
--- /dev/null
+++ b/src/client/View/Color.elm
@@ -0,0 +1,12 @@
+module View.Color exposing (..)
+
+import Color exposing (Color)
+
+chestnutRose : Color
+chestnutRose = Color.rgb 207 92 86
+
+white : Color
+white = Color.white
+
+silver : Color
+silver = Color.rgb 200 200 200
diff --git a/src/client/View/Date.elm b/src/client/View/Date.elm
new file mode 100644
index 0000000..35806ba
--- /dev/null
+++ b/src/client/View/Date.elm
@@ -0,0 +1,48 @@
+module View.Date exposing
+ ( shortView
+ , longView
+ , monthView
+ )
+
+import Date exposing (..)
+import Date.Extra.Core as Date
+import String
+
+import Model.Translations exposing (..)
+
+shortView : Date -> Translations -> String
+shortView date translations =
+ let params =
+ [ String.pad 2 '0' (toString (Date.day date))
+ , String.pad 2 '0' (toString (Date.monthToInt (Date.month date)))
+ , toString (Date.year date)
+ ]
+ in getParamMessage params translations "ShortDate"
+
+longView : Date -> Translations -> String
+longView date translations =
+ let params =
+ [ toString (Date.day date)
+ , (getMessage translations (getMonthKey (Date.month date)))
+ , toString (Date.year date)
+ ]
+ in getParamMessage params translations "LongDate"
+
+monthView : Translations -> Month -> String
+monthView translations month = getMessage translations (getMonthKey month)
+
+getMonthKey : Month -> String
+getMonthKey month =
+ case month of
+ Jan -> "January"
+ Feb -> "February"
+ Mar -> "March"
+ Apr -> "April"
+ May -> "May"
+ Jun -> "June"
+ Jul -> "July"
+ Aug -> "August"
+ Sep -> "September"
+ Oct -> "October"
+ Nov -> "November"
+ Dec -> "December"
diff --git a/src/client/View/Errors.elm b/src/client/View/Errors.elm
new file mode 100644
index 0000000..3e25c99
--- /dev/null
+++ b/src/client/View/Errors.elm
@@ -0,0 +1,21 @@
+module View.Errors exposing
+ ( view
+ )
+
+import Html exposing (..)
+import Html.Attributes exposing (..)
+import Html.Events exposing (..)
+
+import Model.Translations exposing (Translations, getMessage)
+
+view : Translations -> List String -> Html msg
+view translations errors =
+ ul
+ [ class "errors" ]
+ ( List.map (errorView translations) errors)
+
+errorView : Translations -> String -> Html msg
+errorView translations error =
+ li
+ [ class "error" ]
+ [ text <| getMessage translations error ]
diff --git a/src/client/View/Events.elm b/src/client/View/Events.elm
new file mode 100644
index 0000000..d71d67d
--- /dev/null
+++ b/src/client/View/Events.elm
@@ -0,0 +1,15 @@
+module View.Events exposing
+ ( onSubmitPrevDefault
+ )
+
+import Json.Decode as Decode
+import Html exposing (..)
+import Html.Events exposing (..)
+import Html.Attributes exposing (..)
+
+onSubmitPrevDefault : msg -> Attribute msg
+onSubmitPrevDefault value =
+ onWithOptions
+ "submit"
+ { defaultOptions | preventDefault = True }
+ (Decode.succeed value)
diff --git a/src/client/View/Form.elm b/src/client/View/Form.elm
new file mode 100644
index 0000000..7a4965d
--- /dev/null
+++ b/src/client/View/Form.elm
@@ -0,0 +1,153 @@
+module View.Form exposing
+ ( textInput
+ , colorInput
+ , selectInput
+ , radioInputs
+ , hiddenSubmit
+ )
+
+import Html exposing (..)
+import Html.Attributes exposing (..)
+import Html.Events exposing (..)
+
+import FontAwesome
+import View.Color as Color
+
+import Form exposing (Form, FieldState)
+import Form.Input as Input
+import Form.Error as FormError exposing (ErrorValue(..))
+import Form.Field as Field
+
+import Msg exposing (Msg)
+
+import LoggedData exposing (LoggedData)
+
+import Model.Translations as Translations exposing (Translations)
+
+import Utils.Maybe exposing (isJust)
+
+textInput : Translations -> Form String a -> String -> String -> Html Form.Msg
+textInput translations form formName fieldName =
+ let field = Form.getFieldAsString fieldName form
+ fieldId = formName ++ fieldName
+ in div
+ [ classList
+ [ ("textInput", True)
+ , ("error", isJust field.liveError)
+ ]
+ ]
+ [ Input.textInput
+ field
+ [ id fieldId
+ , classList [ ("filled", isJust field.value) ]
+ , value (Maybe.withDefault "" field.value)
+ ]
+ , label
+ [ for fieldId ]
+ [ text (Translations.getMessage translations fieldId) ]
+ , button
+ [ type_ "button"
+ , onClick (Form.Input fieldName Form.Text Field.EmptyField)
+ , tabindex -1
+ ]
+ [ FontAwesome.times Color.silver 15 ]
+ , formError translations field
+ ]
+
+colorInput : Translations -> Form String a -> String -> String -> Html Form.Msg
+colorInput translations form formName fieldName =
+ let field = Form.getFieldAsString fieldName form
+ in div
+ [ classList
+ [ ("colorInput", True)
+ , ("error", isJust field.liveError)
+ ]
+ ]
+ [ label
+ [ for (formName ++ fieldName) ]
+ [ text (Translations.getMessage translations (formName ++ fieldName)) ]
+ , Input.textInput
+ field
+ [ id (formName ++ fieldName)
+ , type_ "color"
+ ]
+ ]
+
+radioInputs : Translations -> Form String a -> String -> String -> List String -> Html Form.Msg
+radioInputs translations form formName radioName fieldNames =
+ let field = Form.getFieldAsString radioName form
+ in div
+ [ classList
+ [ ("radioGroup", True)
+ , ("error", isJust field.liveError)
+ ]
+ ]
+ [ div
+ [ class "title" ]
+ [ text (Translations.getMessage translations (formName ++ radioName) ) ]
+ , div
+ [ class "radioInputs" ]
+ (List.map (radioInput translations field formName) fieldNames)
+ , formError translations field
+ ]
+
+radioInput : Translations -> FieldState String String -> String -> String -> Html Form.Msg
+radioInput translations field formName fieldName =
+ div
+ [ class "radioInput" ]
+ [ Input.radioInput
+ field.path
+ field
+ [ id (formName ++ fieldName)
+ , value fieldName
+ , checked (field.value == Just fieldName)
+ ]
+ , label
+ [ for (formName ++ fieldName) ]
+ [ text (Translations.getMessage translations (formName ++ fieldName))
+ ]
+ ]
+
+selectInput : Translations -> Form String a -> String -> String -> List (String, String) -> Html Form.Msg
+selectInput translations form formName selectName options =
+ let field = Form.getFieldAsString selectName form
+ fieldId = formName ++ selectName
+ in div
+ [ classList
+ [ ("selectInput", True)
+ , ("error", isJust field.liveError)
+ ]
+ ]
+ [ label
+ [ for fieldId ]
+ [ text (Translations.getMessage translations fieldId) ]
+ , Input.selectInput
+ (("", "") :: options)
+ field
+ [ id fieldId ]
+ , formError translations field
+ ]
+
+formError : Translations -> FieldState String a -> Html msg
+formError translations field =
+ case field.liveError of
+ Just error ->
+ let errorElement error params =
+ div
+ [ class "errorMessage" ]
+ [ text (Translations.getParamMessage params translations error) ]
+ in case error of
+ CustomError key -> errorElement key []
+ SmallerIntThan n -> errorElement "SmallerIntThan" [toString n]
+ GreaterIntThan n -> errorElement "GreaterIntThan" [toString n]
+ error -> errorElement (toString error) []
+ Nothing ->
+ text ""
+
+hiddenSubmit : msg -> Html msg
+hiddenSubmit msg =
+ button
+ [ style [ ("display", "none") ]
+ , onClick msg
+ ]
+ []
diff --git a/src/client/View/Header.elm b/src/client/View/Header.elm
new file mode 100644
index 0000000..12fb87c
--- /dev/null
+++ b/src/client/View/Header.elm
@@ -0,0 +1,60 @@
+module View.Header exposing
+ ( view
+ )
+
+import Dict
+
+import FontAwesome
+import View.Color as Color
+
+import Page exposing (..)
+
+import Html exposing (..)
+import Html.Attributes exposing (..)
+import Html.Events exposing (..)
+
+import Model exposing (Model)
+import Model.Translations exposing (getMessage)
+import Msg exposing (..)
+import Model.View exposing (..)
+
+view : Model -> Html Msg
+view model =
+ header
+ []
+ ( [ div [ class "title" ] [ text (getMessage model.translations "SharedCost") ] ]
+ ++ let item page name =
+ a
+ [ href (Page.toHash page)
+ , classList
+ [ ("item", True)
+ , ("current", model.page == page)
+ ]
+ ]
+ [ text (getMessage model.translations name)
+ ]
+ in case model.view of
+ LoggedInView { me, users } ->
+ [ item Home "PaymentsTitle"
+ , item Income "Income"
+ , item Categories "Categories"
+ , item Statistics "Statistics"
+ , div
+ [ class "nameSignOut" ]
+ [ div
+ [ class "name" ]
+ [ Dict.get me users
+ |> Maybe.map .name
+ |> Maybe.withDefault ""
+ |> text
+ ]
+ , button
+ [ class "signOut item"
+ , onClick SignOut
+ ]
+ [ FontAwesome.power_off Color.white 30 ]
+ ]
+ ]
+ _ ->
+ []
+ )
diff --git a/src/client/View/Plural.elm b/src/client/View/Plural.elm
new file mode 100644
index 0000000..c36eaca
--- /dev/null
+++ b/src/client/View/Plural.elm
@@ -0,0 +1,11 @@
+module View.Plural exposing
+ ( plural
+ )
+
+import Model.Translations exposing (Translations, getMessage)
+
+plural : Translations -> Int -> String -> String -> String
+plural translations n single multiple =
+ let singleMessage = getMessage translations single
+ multipleMessage = getMessage translations multiple
+ in (toString n) ++ " " ++ if n <= 1 then singleMessage else multipleMessage