diff options
author | Guillermo Ramos | 2025-02-24 11:10:13 +0100 |
---|---|---|
committer | Guillermo Ramos | 2025-02-24 13:18:08 +0100 |
commit | f443a4b4941913017cf6c1ab1ed38120f7ce9e56 (patch) | |
tree | ce99a097247a87c7f0c0c509a17142ed93e8d82e /front/src | |
parent | 42361110cfcf394f2224bf5c719ee1986a54d04c (diff) | |
download | hiccup-f443a4b4941913017cf6c1ab1ed38120f7ce9e56.tar.gz |
Initial contribution, UI improvements
Diffstat (limited to 'front/src')
-rw-r--r-- | front/src/Main.elm | 174 |
1 files changed, 137 insertions, 37 deletions
diff --git a/front/src/Main.elm b/front/src/Main.elm index 62ed651..85b4057 100644 --- a/front/src/Main.elm +++ b/front/src/Main.elm @@ -68,18 +68,24 @@ simDecoder = (field "payed_amortized" float) -type alias SimSpecsTxt = - { principalTxt : String +type alias SimSpecsRaw = + { totalValueTxt : String + , initialTxt : String + , financedRateTxt : String , i1Txt : String , yearsTxt : String } -simSpecsParse : SimSpecsTxt -> Maybe SimSpecs -simSpecsParse { principalTxt, i1Txt, yearsTxt } = - case ( String.toFloat principalTxt, String.toFloat i1Txt, String.toInt yearsTxt ) of - ( Just principal, Just i1, Just years ) -> - Just { principal = principal, i1 = i1, years = years } +simSpecsParse : SimSpecsRaw -> Maybe SimSpecs +simSpecsParse { totalValueTxt, financedRateTxt, i1Txt, yearsTxt } = + case + ( List.map String.toFloat [ totalValueTxt, i1Txt ] + , List.map String.toInt [ financedRateTxt, yearsTxt ] + ) + of + ( [ Just totalValue, Just i1 ], [ Just rate, Just years ] ) -> + Just { principal = totalValue * toFloat rate / 100, i1 = i1, years = years } _ -> Nothing @@ -94,7 +100,7 @@ type alias SimSpecs = type alias Model = { error : String - , simSpecsTxt : SimSpecsTxt + , simSpecsRaw : SimSpecsRaw , expandedYears : Set Int , simulation : Maybe Simulation } @@ -135,10 +141,10 @@ runSimulation simSpecs = init : () -> ( Model, Cmd Msg ) init () = let - simSpecsTxt = - { principalTxt = "200000", i1Txt = "1.621", yearsTxt = "30" } + simSpecsRaw = + { totalValueTxt = "200000", financedRateTxt = "80", initialTxt = "40000", i1Txt = "1.621", yearsTxt = "30" } in - ( { error = "", simSpecsTxt = simSpecsTxt, expandedYears = Set.empty, simulation = Nothing }, Cmd.none ) + ( { error = "", simSpecsRaw = simSpecsRaw, expandedYears = Set.empty, simulation = Nothing }, Cmd.none ) @@ -147,10 +153,32 @@ init () = type SimSpecUpdate = Principal + | Rate + | Initial | I1 | Years +initialToRate : Float -> Int -> Float +initialToRate initial principal = + 100 - (100 * initial / toFloat principal) + + +rateToInitial : Float -> Int -> Float +rateToInitial rate principal = + toFloat principal * ((100 - rate) / 100) + + +convertInitialRate : (Float -> Int -> Float) -> String -> String -> Maybe String +convertInitialRate convert val totalValueTxt = + case ( String.toFloat val, String.toInt totalValueTxt ) of + ( Just x, Just totalValue ) -> + Just <| String.fromFloat <| convert x totalValue + + _ -> + Nothing + + type Msg = GotSimulation (Result Http.Error Simulation) | UpdateSimSpecs SimSpecUpdate String @@ -176,21 +204,37 @@ update msg model = UpdateSimSpecs u val -> let - simSpecsTxt = - model.simSpecsTxt + simSpecsRaw = + model.simSpecsRaw newSimSpecsTxt = case u of Principal -> - { simSpecsTxt | principalTxt = val } + { simSpecsRaw | totalValueTxt = val } + + Rate -> + { simSpecsRaw + | financedRateTxt = val + , initialTxt = + Maybe.withDefault simSpecsRaw.initialTxt <| + convertInitialRate rateToInitial val simSpecsRaw.totalValueTxt + } + + Initial -> + { simSpecsRaw + | initialTxt = val + , financedRateTxt = + Maybe.withDefault simSpecsRaw.financedRateTxt <| + convertInitialRate initialToRate val simSpecsRaw.totalValueTxt + } I1 -> - { simSpecsTxt | i1Txt = val } + { simSpecsRaw | i1Txt = val } Years -> - { simSpecsTxt | yearsTxt = val } + { simSpecsRaw | yearsTxt = val } in - ( { model | simSpecsTxt = newSimSpecsTxt }, Cmd.none ) + ( { model | simSpecsRaw = newSimSpecsTxt }, Cmd.none ) SetExpandedYears eyears -> ( { model | expandedYears = eyears }, Cmd.none ) @@ -239,14 +283,14 @@ errorToString error = errorMessage -specsView : SimSpecsTxt -> Html Msg -specsView simSpecsTxt = +specsView : SimSpecsRaw -> Html Msg +specsView simSpecsRaw = let - { principalTxt, i1Txt, yearsTxt } = - simSpecsTxt + { totalValueTxt, financedRateTxt, initialTxt, i1Txt, yearsTxt } = + simSpecsRaw simSpecs = - simSpecsParse simSpecsTxt + simSpecsParse simSpecsRaw simButAttrs = case simSpecs of @@ -257,31 +301,58 @@ specsView simSpecsTxt = [ onClick (RunSimulation specs) ] in div [] - [ div [ class "flex" ] - [ text "Principal: " + [ div [] + [ text "Property price: " , input [ type_ "range" , class "accent-lime-300" , Html.Attributes.min "0" , Html.Attributes.max "1000000" - , step "10000" - , value principalTxt + , step "5000" + , value totalValueTxt , onInput (UpdateSimSpecs Principal) ] [] - , text principalTxt + , text totalValueTxt ] , div [ class "flex" ] + [ div [ class "" ] + [ text "Initial contribution: " + , input + [ class "w-[100px] border border-lime-500 border-2 px-2" + , Html.Attributes.min "0" + , Html.Attributes.max totalValueTxt + , value initialTxt + , onInput (UpdateSimSpecs Initial) + ] + [] + ] + , div [ class "ml-4" ] + [ text " (" + , input + [ class "w-[50px] border border-lime-500 border-2 px-2" + , Html.Attributes.min "10" + , Html.Attributes.max "100" + , value financedRateTxt + , onInput (UpdateSimSpecs Rate) + ] + [] + , text "%)" + ] + ] + , div [] [ text "Interest rate: " , input - [ Html.Attributes.min "0" + [ class "w-[80px] border border-lime-500 border-2 px-2" + , Html.Attributes.min "0" , Html.Attributes.max "100" , value i1Txt , onInput (UpdateSimSpecs I1) ] [] + , text " % TIN" ] - , div [ class "flex" ] + , div [ class "flex mb-2" ] [ text "Years: " , input [ type_ "range" @@ -323,7 +394,15 @@ capitalSumView : Capital -> Html Msg capitalSumView { principal, interest } = let partsTitle = - String.concat [ "Principal: ", Round.round 2 principal, "\nInterest: ", Round.round 2 interest ] + String.concat + [ "Principal: " + , Round.round 2 principal + , "\nInterest: " + , Round.round 2 interest + , " (" + , Round.round 2 (100 * interest / (principal + interest)) + , "% from total)" + ] in span [ class "underline", title partsTitle ] [ text (Round.round 2 (principal + interest)) ] @@ -394,24 +473,45 @@ quotaView m { period, payed, pending_principal } = simView : Model -> Simulation -> Html Msg simView m { history, topay, payed } = + let + { totalValueTxt, initialTxt } = + m.simSpecsRaw + + total = + Round.round 2 <| + topay.principal + + topay.interest + + Maybe.withDefault 0 + (String.toFloat initialTxt) + in div [] - [ historyView m history - , div [] [ text "to pay: ", capitalSumView topay ] - , div [] [ text "payed: ", capitalSumView payed ] + [ hr [ class "my-5" ] [] + , div [] + [ text "To pay: " + , text total + , text " (" + , text initialTxt + , text " initial + " + , capitalSumView topay + , text " financed)" + ] + + -- , div [] [ text "payed: ", capitalSumView payed ] + , historyView m history ] view : Model -> Html Msg view m = - div [ class "flex flex-row max-w-sm mx-auto" ] - [ div [ class "flex flex-col items-center" ] - [ specsView m.simSpecsTxt + div [ class "flex flex-col max-w-lg mx-auto items-center" ] + [ div [ class "min-w-full" ] + [ specsView m.simSpecsRaw , case m.simulation of Nothing -> text "" Just sim -> simView m sim - , div [] [ text m.error ] + , text m.error ] ] |