diff options
author | Guillermo Ramos | 2025-03-08 16:00:08 +0100 |
---|---|---|
committer | Guillermo Ramos | 2025-03-08 16:30:57 +0100 |
commit | 07abf01ff0ab3a706f7e3783ed613cd2d9eb4cd7 (patch) | |
tree | 6dfee5644e28aa1a315b8eb62763f0bf24ef1b68 /front/src | |
parent | e93e62ee9f573c494d570f7d5ec5e065e2d8ff73 (diff) | |
download | hiccup-07abf01ff0ab3a706f7e3783ed613cd2d9eb4cd7.tar.gz |
Toggle currency + EUR/USD
Diffstat (limited to 'front/src')
-rw-r--r-- | front/src/Main.elm | 218 |
1 files changed, 155 insertions, 63 deletions
diff --git a/front/src/Main.elm b/front/src/Main.elm index 6c9b5fe..4c70e37 100644 --- a/front/src/Main.elm +++ b/front/src/Main.elm @@ -49,16 +49,6 @@ import Url.Parser.Query as UQ --- CONSTANTS - - -{-| TODO decide by locale --} -amountSep = - { thousands = '.', decimal = ',' } - - - -- LOCALE @@ -132,7 +122,6 @@ make_t lang str = --- "TODO TRANS" -- MAIN @@ -180,22 +169,22 @@ capitalDecoder = capitalSumView : Model -> Capital -> Html Msg -capitalSumView { t } { principal, interest } = +capitalSumView { t, settings } { principal, interest } = let partsTitle = String.concat [ t "Principal: " - , amountToString principal + , amountToString settings.currency principal , "\n" , t "Interest: " - , amountToString interest + , amountToString settings.currency interest , " (" , Round.round 2 (100 * interest / (principal + interest)) , t "% from total" , ")" ] in - span [ class "underline", title partsTitle ] [ amountView (principal + interest) ] + span [ class "underline", title partsTitle ] [ amountView settings.currency (principal + interest) ] type alias MortgageSim = @@ -339,24 +328,91 @@ langFromString lang = EN +type Currency + = USD + | EUR + + +currencyToString : Currency -> String +currencyToString curr = + case curr of + EUR -> + "EUR" + + USD -> + "USD" + + +currencyFromString : String -> Currency +currencyFromString curr = + case curr of + "EUR" -> + EUR + + _ -> + USD + + +currencyPP : Currency -> String +currencyPP curr = + case curr of + EUR -> + "€" + + USD -> + "$" + + +currencySep : Currency -> { thousands : Char, decimal : Char } +currencySep curr = + case curr of + EUR -> + { thousands = '.', decimal = ',' } + + USD -> + { thousands = ',', decimal = '.' } + + +type CurrencyOrder + = Prefix + | Postfix + + +currencyOrder : Currency -> CurrencyOrder +currencyOrder curr = + case curr of + EUR -> + Postfix + + USD -> + Prefix + + type alias Settings = - { lang : Language } + { lang : Language + , currency : Currency + } defaultSettings : Settings defaultSettings = - { lang = ES } + { lang = ES + , currency = EUR + } settingsParser : UQ.Parser Settings settingsParser = - UQ.map Settings + UQ.map2 Settings (UQ.map (Maybe.withDefault defaultSettings.lang << Maybe.map langFromString) <| UQ.string "lang") + (UQ.map (Maybe.withDefault defaultSettings.currency << Maybe.map currencyFromString) <| UQ.string "currency") settingsToQS : Settings -> List UB.QueryParameter -settingsToQS { lang } = - [ UB.string "lang" (langToString lang) ] +settingsToQS { lang, currency } = + [ UB.string "lang" (langToString lang) + , UB.string "currency" (currencyToString currency) + ] type alias Model = @@ -477,6 +533,7 @@ type SpecField type SettingsChange = ToggleLang + | ToggleCurrency type Msg @@ -602,6 +659,17 @@ update msg m = ES -> EN } + + ToggleCurrency -> + { settings + | currency = + case settings.currency of + EUR -> + USD + + USD -> + EUR + } in ( m, Nav.pushUrl m.navKey (modelToUrl { m | settings = newSettings }) ) @@ -654,57 +722,78 @@ slider attributes onInputMsg valueTxt = -- VIEW -amountToString : Float -> String -amountToString amount = +insertThousandsSep : Currency -> String -> String +insertThousandsSep currency str = let - amountStr = - Round.round 2 amount + l = + List.reverse <| String.toList str - insertThousandsSep str = - let - l = - List.reverse <| String.toList str + indexed = + List.map2 Tuple.pair (List.range 0 (String.length str)) l + + withCommas = + List.concatMap + (\( i, c ) -> + if i > 0 && modBy 3 i == 0 then + [ (currencySep currency).thousands, c ] - indexed = - List.map2 Tuple.pair (List.range 0 (String.length str)) l + else + [ c ] + ) + indexed + in + String.fromList <| List.reverse withCommas - withCommas = - List.concatMap - (\( i, c ) -> - if i > 0 && modBy 3 i == 0 then - [ amountSep.thousands, c ] - else - [ c ] - ) - indexed - in - String.fromList <| List.reverse withCommas +amountToString : Currency -> Float -> String +amountToString currency amount = + let + amountStr = + Round.round 2 amount in case String.split "." amountStr of int :: float :: [] -> - String.join (String.fromChar amountSep.decimal) - [ insertThousandsSep int - , float - ] + let + strs = + [ insertThousandsSep currency int + , String.fromChar (currencySep currency).decimal + , float + ] + in + String.join "" <| + case currencyOrder currency of + Prefix -> + [ currencyPP currency ] ++ strs + + Postfix -> + strs ++ [ currencyPP currency ] _ -> amountStr -amountView : Float -> Html Msg -amountView amount = +amountView : Currency -> Float -> Html Msg +amountView currency amount = let amountStr = - amountToString amount + Round.round 2 amount in - case String.split (String.fromChar amountSep.decimal) amountStr of + case String.split "." amountStr of int :: float :: [] -> - span [] - [ text int - , text <| String.fromChar amountSep.decimal - , span [ class "text-xs" ] [ text float ] - ] + let + els = + [ text (insertThousandsSep currency int) + , text <| String.fromChar (currencySep currency).decimal + , span [ class "text-sm" ] [ text float ] + ] + in + span [] <| + case currencyOrder currency of + Prefix -> + [ text (currencyPP currency) ] ++ els + + Postfix -> + els ++ [ text (currencyPP currency) ] _ -> text amountStr @@ -793,8 +882,8 @@ specsView { t, settings, rawSpecs } = , div [ class "flex" ] [ button (secondaryButAttrs ++ [ class "mr-1", onClick (UpdateSettings ToggleLang) ]) [ text <| langToString settings.lang ] - - -- , button (secondaryButAttrs ++ []) [ text "€" ] + , button (secondaryButAttrs ++ [ class "mr-1", onClick (UpdateSettings ToggleCurrency) ]) + [ text <| currencyPP settings.currency ] ] ] ] @@ -874,7 +963,7 @@ quotaView m { period, payed, pending_principal } = , text (String.fromInt period) , capitalSumView m payed - , amountView pending_principal + , amountView m.settings.currency pending_principal ] ) @@ -885,7 +974,7 @@ quotaView m { period, payed, pending_principal } = , text (String.fromInt period) , capitalSumView m payed - , amountView pending_principal + , amountView m.settings.currency pending_principal ] ) @@ -896,6 +985,9 @@ quotaView m { period, payed, pending_principal } = simView : Model -> ( RawSpecs, MortgageSim ) -> Html Msg simView m ( rawSpecs, { history, topay, payed } ) = let + currency = + m.settings.currency + t = m.t @@ -918,19 +1010,19 @@ simView m ( rawSpecs, { history, topay, payed } ) = [ hr [ class "my-5" ] [] , pre [ class "leading-none" ] [ text <| t "Total to pay: " - , amountView (topay.principal + topay.interest + initial + vat + fee) + , amountView currency (topay.principal + topay.interest + initial + vat + fee) , text "\n├ " , text <| t "Initial payment: " - , amountView (initial + vat + fee) + , amountView currency (initial + vat + fee) , text "\n│ ├ " , text <| t "Property: " - , amountView initial + , amountView currency initial , text "\n│ ├ " , text <| t "Agent fee: " - , amountView fee + , amountView currency fee , text "\n│ └ " , text <| t "VAT: " - , amountView vat + , amountView currency vat , text "\n└ " , text <| t "Financed (mortgage): " , capitalSumView m topay |