From 4316c73c352ce52de4494b22001f34cd0681831b Mon Sep 17 00:00:00 2001 From: Guillermo Ramos Date: Thu, 6 Mar 2025 23:14:42 +0100 Subject: Cleanup --- front/src/Main.elm | 321 ++++++++++++++++++++++++----------------------------- 1 file changed, 144 insertions(+), 177 deletions(-) diff --git a/front/src/Main.elm b/front/src/Main.elm index 35ec06d..ca81647 100644 --- a/front/src/Main.elm +++ b/front/src/Main.elm @@ -66,19 +66,6 @@ main = -- MODEL -type alias Capital = - { principal : Float - , interest : Float - } - - -capitalDecoder : Decoder Capital -capitalDecoder = - map2 Capital - (field "principal" float) - (field "interest" float) - - type alias Quota = { period : Int , payed : Capital @@ -94,7 +81,20 @@ quotaDecoder = (field "pending_principal" float) -type alias FinanceSim = +type alias Capital = + { principal : Float + , interest : Float + } + + +capitalDecoder : Decoder Capital +capitalDecoder = + map2 Capital + (field "principal" float) + (field "interest" float) + + +type alias MortgageSim = { history : List Quota , topay : Capital , payed : Capital @@ -102,22 +102,16 @@ type alias FinanceSim = } -simDecoder : Decoder FinanceSim +simDecoder : Decoder MortgageSim simDecoder = - map4 FinanceSim + map4 MortgageSim (field "history" (list quotaDecoder)) (field "topay" capitalDecoder) (field "payed" capitalDecoder) (field "payed_amortized" float) -type alias Simulation = - { financed : FinanceSim - , initial : Float - } - - -type alias SimSpecsRaw = +type alias RawSpecs = { title : String , totalValue : String , initial : String @@ -127,8 +121,8 @@ type alias SimSpecsRaw = } -defaultSimSpecsRaw : SimSpecsRaw -defaultSimSpecsRaw = +defaultRawSpecs : RawSpecs +defaultRawSpecs = { title = "" , totalValue = "200000" , initial = "40000" @@ -138,19 +132,19 @@ defaultSimSpecsRaw = } -simSpecsRawParser : UQ.Parser SimSpecsRaw -simSpecsRawParser = - UQ.map6 SimSpecsRaw - (UQ.map (Maybe.withDefault defaultSimSpecsRaw.title) <| UQ.string "title") - (UQ.map (Maybe.withDefault defaultSimSpecsRaw.totalValue) <| UQ.string "totalValue") - (UQ.map (Maybe.withDefault defaultSimSpecsRaw.initial) <| UQ.string "initial") - (UQ.map (Maybe.withDefault defaultSimSpecsRaw.financedRate) <| UQ.string "financedRate") - (UQ.map (Maybe.withDefault defaultSimSpecsRaw.i1) <| UQ.string "i1") - (UQ.map (Maybe.withDefault defaultSimSpecsRaw.years) <| UQ.string "years") +rawSpecsParser : UQ.Parser RawSpecs +rawSpecsParser = + UQ.map6 RawSpecs + (UQ.map (Maybe.withDefault defaultRawSpecs.title) <| UQ.string "title") + (UQ.map (Maybe.withDefault defaultRawSpecs.totalValue) <| UQ.string "totalValue") + (UQ.map (Maybe.withDefault defaultRawSpecs.initial) <| UQ.string "initial") + (UQ.map (Maybe.withDefault defaultRawSpecs.financedRate) <| UQ.string "financedRate") + (UQ.map (Maybe.withDefault defaultRawSpecs.i1) <| UQ.string "i1") + (UQ.map (Maybe.withDefault defaultRawSpecs.years) <| UQ.string "years") -simSpecsRawToQS : SimSpecsRaw -> String -simSpecsRawToQS { title, totalValue, initial, financedRate, i1, years } = +rawSpecsToURL : RawSpecs -> String +rawSpecsToURL { title, totalValue, initial, financedRate, i1, years } = UB.toQuery <| [ UB.string "title" title , UB.string "totalValue" totalValue @@ -161,15 +155,15 @@ simSpecsRawToQS { title, totalValue, initial, financedRate, i1, years } = ] -type alias SimSpecs = +type alias MortgageSpecs = { principal : Float , i1 : Float , years : Int } -simSpecsParse : SimSpecsRaw -> Maybe SimSpecs -simSpecsParse { totalValue, financedRate, i1, years } = +parseMortgageSpecs : RawSpecs -> Maybe MortgageSpecs +parseMortgageSpecs { totalValue, financedRate, i1, years } = case ( List.map String.toFloat [ totalValue, i1 ] , List.map String.toInt [ financedRate, years ] @@ -182,57 +176,42 @@ simSpecsParse { totalValue, financedRate, i1, years } = Nothing -type alias Model = - { error : String - , navKey : Nav.Key - , simSpecsRaw : SimSpecsRaw - , expandedYears : Set Int - , simulation : Maybe Simulation - } - - -qs : List ( String, String ) -> String -qs ss = - String.join "&" (List.map (\( s, t ) -> String.join "=" [ s, t ]) ss) - - -simSpecsToURL : SimSpecs -> String -simSpecsToURL { principal, i1, years } = - let - base = - "/api/simulate" - in - String.concat - [ base - , "?" - , qs - [ ( "principal", String.fromFloat principal ) - , ( "i1" - , String.fromFloat (i1 / 100) - ) - , ( "years", String.fromInt years ) - ] +mortgageSpecsToURL : MortgageSpecs -> String +mortgageSpecsToURL { principal, i1, years } = + UB.absolute [ "/api/simulate" ] + [ UB.string "principal" (String.fromFloat principal) + , UB.string "i1" (String.fromFloat (i1 / 100)) + , UB.int "years" years ] -runSimulation : Model -> SimSpecs -> Cmd Msg -runSimulation m simSpecs = +runMortgageSim : Model -> MortgageSpecs -> Cmd Msg +runMortgageSim m mortgageSpecs = Http.get - { url = simSpecsToURL simSpecs - , expect = Http.expectJson (GotSimulation m) simDecoder + { url = mortgageSpecsToURL mortgageSpecs + , expect = Http.expectJson (GotMortgageSim m) simDecoder } +type alias Model = + { error : String + , navKey : Nav.Key + , rawSpecs : RawSpecs + , expandedYears : Set Int + , simulation : Maybe ( RawSpecs, MortgageSim ) + } + + type Route = NotFound - | Root SimSpecsRaw + | Root RawSpecs -routeQuery : Route -> SimSpecsRaw +routeQuery : Route -> RawSpecs routeQuery route = case route of NotFound -> - defaultSimSpecsRaw + defaultRawSpecs Root query -> query @@ -241,7 +220,7 @@ routeQuery route = routeParser : U.Parser (Route -> a) a routeParser = U.oneOf - [ U.map Root (U.top simSpecsRawParser) + [ U.map Root (U.top rawSpecsParser) ] @@ -252,13 +231,9 @@ toRoute url = init : () -> Url -> Nav.Key -> ( Model, Cmd Msg ) init () url navKey = - let - simSpecsRaw = - routeQuery (toRoute url) - in ( { navKey = navKey , error = "" - , simSpecsRaw = simSpecsRaw + , rawSpecs = routeQuery (toRoute url) , expandedYears = Set.empty , simulation = Nothing } @@ -270,15 +245,6 @@ init () url navKey = -- UPDATE -type SimSpecUpdate - = Title - | Principal - | Rate - | Initial - | I1 - | Years - - initialToRate : Float -> Int -> Float initialToRate initial principal = 100 - (100 * initial / toFloat principal) @@ -299,99 +265,128 @@ convertInitialRate convert val totalValue = Nothing +errorToString : Http.Error -> String +errorToString error = + case error of + Http.BadUrl url -> + "The URL " ++ url ++ " was invalid" + + Http.Timeout -> + "Unable to reach the server, try again" + + Http.NetworkError -> + "Unable to reach the server, check your network connection" + + Http.BadStatus 500 -> + "The server had a problem, try again later" + + Http.BadStatus 400 -> + "Verify your information and try again" + + Http.BadStatus _ -> + "Unknown error" + + Http.BadBody errorMessage -> + errorMessage + + +type SpecField + = Title + | Principal + | Rate + | Initial + | I1 + | Years + + type Msg - = GotSimulation Model (Result Http.Error FinanceSim) - | UpdateSimSpecs SimSpecUpdate String - | RunSimulation SimSpecs - | SetExpandedYears (Set Int) - | SetUrl UrlRequest + = SetUrl UrlRequest | ChangedUrl Url + | UpdateSpecs SpecField String + | RunMortgageSim MortgageSpecs + | GotMortgageSim Model (Result Http.Error MortgageSim) + | SetExpandedYears (Set Int) update : Msg -> Model -> ( Model, Cmd Msg ) -update msg model = +update msg m = let _ = Debug.log "UPDATE!" msg in case msg of - GotSimulation m (Ok financed) -> - ( { model + GotMortgageSim old_m (Ok msim) -> + ( { m | simulation = - Just - { initial = Maybe.withDefault 0 <| String.toFloat m.simSpecsRaw.initial - , financed = financed - } + Just ( old_m.rawSpecs, msim ) } , Cmd.none ) - GotSimulation _ (Err err) -> - ( { model | error = errorToString err }, Cmd.none ) + GotMortgageSim _ (Err err) -> + ( { m | error = errorToString err }, Cmd.none ) - RunSimulation specs -> - ( model + RunMortgageSim specs -> + ( m , batch - [ runSimulation model specs - , Nav.pushUrl model.navKey (simSpecsRawToQS model.simSpecsRaw) + [ runMortgageSim m specs + , Nav.pushUrl m.navKey (rawSpecsToURL m.rawSpecs) ] ) SetUrl (Internal url) -> - -- TODO - ( model, Nav.pushUrl model.navKey (Url.toString url) ) + ( m, Nav.pushUrl m.navKey (Url.toString url) ) SetUrl (External url) -> - -- TODO - ( model, Nav.load url ) + ( m, Nav.load url ) ChangedUrl url -> - ( model, Cmd.none ) + ( m, Cmd.none ) - UpdateSimSpecs u val -> + UpdateSpecs field val -> let - simSpecsRaw = - model.simSpecsRaw + rawSpecs = + m.rawSpecs - newSimSpecsRaw = - case u of + newRawSpecs = + case field of Title -> - { simSpecsRaw | title = val } + { rawSpecs | title = val } Principal -> - { simSpecsRaw + { rawSpecs | totalValue = val , initial = - Maybe.withDefault simSpecsRaw.initial <| - convertInitialRate rateToInitial simSpecsRaw.financedRate val + Maybe.withDefault rawSpecs.initial <| + convertInitialRate rateToInitial rawSpecs.financedRate val } Rate -> - { simSpecsRaw + { rawSpecs | financedRate = val , initial = - Maybe.withDefault simSpecsRaw.initial <| - convertInitialRate rateToInitial val simSpecsRaw.totalValue + Maybe.withDefault rawSpecs.initial <| + convertInitialRate rateToInitial val rawSpecs.totalValue } Initial -> - { simSpecsRaw + { rawSpecs | initial = val , financedRate = - Maybe.withDefault simSpecsRaw.financedRate <| - convertInitialRate initialToRate val simSpecsRaw.totalValue + Maybe.withDefault rawSpecs.financedRate <| + convertInitialRate initialToRate val rawSpecs.totalValue } I1 -> - { simSpecsRaw | i1 = val } + { rawSpecs | i1 = val } Years -> - { simSpecsRaw | years = val } + { rawSpecs | years = val } in - ( { model | simSpecsRaw = newSimSpecsRaw }, Cmd.none ) + ( { m | rawSpecs = newRawSpecs }, Cmd.none ) SetExpandedYears eyears -> - ( { model | expandedYears = eyears }, Cmd.none ) + ( { m | expandedYears = eyears }, Cmd.none ) @@ -412,47 +407,19 @@ clickableAttrs msg = -- VIEW -errorToString : Http.Error -> String -errorToString error = - case error of - Http.BadUrl url -> - "The URL " ++ url ++ " was invalid" - - Http.Timeout -> - "Unable to reach the server, try again" - - Http.NetworkError -> - "Unable to reach the server, check your network connection" - - Http.BadStatus 500 -> - "The server had a problem, try again later" - - Http.BadStatus 400 -> - "Verify your information and try again" - - Http.BadStatus _ -> - "Unknown error" - - Http.BadBody errorMessage -> - errorMessage - - -specsView : SimSpecsRaw -> Html Msg -specsView simSpecsRaw = +specsView : RawSpecs -> Html Msg +specsView rawSpecs = let { title, totalValue, financedRate, initial, i1, years } = - simSpecsRaw - - simSpecs = - simSpecsParse simSpecsRaw + rawSpecs simButAttrs = - case simSpecs of + case parseMortgageSpecs rawSpecs of Nothing -> [ disabled True ] Just specs -> - [ onClick (RunSimulation specs) ] + [ onClick (RunMortgageSim specs) ] in div [] [ div [] @@ -460,7 +427,7 @@ specsView simSpecsRaw = [ class "min-w-full mb-2 py-1 px-3 text-xl font-bold lime-100" , placeholder "Title..." , value title - , onInput (UpdateSimSpecs Title) + , onInput (UpdateSpecs Title) ] [] ] @@ -473,7 +440,7 @@ specsView simSpecsRaw = , Html.Attributes.max "1000000" , step "5000" , value totalValue - , onInput (UpdateSimSpecs Principal) + , onInput (UpdateSpecs Principal) ] [] , text totalValue @@ -486,7 +453,7 @@ specsView simSpecsRaw = , Html.Attributes.min "0" , Html.Attributes.max totalValue , value initial - , onInput (UpdateSimSpecs Initial) + , onInput (UpdateSpecs Initial) ] [] ] @@ -497,7 +464,7 @@ specsView simSpecsRaw = , Html.Attributes.min "10" , Html.Attributes.max "100" , value financedRate - , onInput (UpdateSimSpecs Rate) + , onInput (UpdateSpecs Rate) ] [] , text "%)" @@ -510,7 +477,7 @@ specsView simSpecsRaw = , Html.Attributes.min "0" , Html.Attributes.max "100" , value i1 - , onInput (UpdateSimSpecs I1) + , onInput (UpdateSpecs I1) ] [] , text " % (nominal)" @@ -524,7 +491,7 @@ specsView simSpecsRaw = , Html.Attributes.max "50" , step "1" , value years - , onInput (UpdateSimSpecs Years) + , onInput (UpdateSpecs Years) ] [] , text years @@ -634,11 +601,11 @@ quotaView m { period, payed, pending_principal } = text "" -simView : Model -> Simulation -> Html Msg -simView m { initial, financed } = +simView : Model -> ( RawSpecs, MortgageSim ) -> Html Msg +simView m ( rawSpecs, { history, topay, payed } ) = let - { history, topay, payed } = - financed + initial = + Maybe.withDefault 0 <| String.toFloat rawSpecs.initial total = topay.principal + topay.interest + initial @@ -666,7 +633,7 @@ view m = , body = [ div [ class "flex flex-col max-w-lg mx-auto items-center mt-2 p-3 border-2 rounded-md border-gray-500 bg-gray-100" ] [ div [ class "min-w-full" ] - [ specsView m.simSpecsRaw + [ specsView m.rawSpecs , case m.simulation of Nothing -> text "" -- cgit v1.2.3