Skip to content

Instantly share code, notes, and snippets.

@timjs
Last active April 26, 2024 10:39
Show Gist options
  • Save timjs/3458c24c732ad3897392ca5da7a4f223 to your computer and use it in GitHub Desktop.
Save timjs/3458c24c732ad3897392ca5da7a4f223 to your computer and use it in GitHub Desktop.
module Main exposing (..)
import Browser
import Html exposing (Html, button, div, h1, input, span, text)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick, onInput)
import Payments
import Random
-- MAIN
main : Program () Model Msg
main =
Browser.element
{ init = init
, update = update
, view = view
, subscriptions = \_ -> Sub.none
}
-- MODEL
type alias Model =
{ amount : Int
, message : String
, cardNumber : String
, owner : String
}
init : () -> ( Model, Cmd Msg )
init () =
( { amount = 0
, message = ""
, cardNumber = ""
, owner = ""
}
, Cmd.none
)
-- UPDATE
type Msg
= UserManipulatesCounter Int
| UserWantsRandomCounter
| ElmGeneratedCounter Int
| UserPushedCreditcard
| UserPushedCash
| UserPushedReset
| UserChangesCreditcardNumber String
| UserChangesOwner String
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
UserManipulatesCounter n -> ( { model | amount = model.amount + n }, Cmd.none )
UserWantsRandomCounter -> ( model, Random.generate ElmGeneratedCounter (Random.int 1 100) )
ElmGeneratedCounter n -> ( { model | amount = n }, Cmd.none )
UserPushedCreditcard -> ( { model | message = Debug.toString (Payments.create (Payments.AmountOf (toFloat model.amount) Payments.Dollar) (Payments.createMethodCredit Payments.VisaCard model.cardNumber model.owner)) }, Cmd.none )
UserPushedCash -> ( { model | message = Debug.toString (Payments.create (Payments.AmountOf (toFloat model.amount) Payments.Dollar) Payments.createMethodCash) }, Cmd.none )
UserPushedReset -> ( { model | amount = 0 }, Cmd.none )
UserChangesCreditcardNumber text -> ( { model | cardNumber = text }, Cmd.none )
UserChangesOwner text -> ( { model | owner = text }, Cmd.none )
-- VIEW
amountSelectors : List (Html Msg)
amountSelectors =
h1 [] [ text "Choose amount:" ]
:: button [ onClick UserWantsRandomCounter ] [ text "Random!" ]
:: List.map counterButton [ -1, -10, 1, 10 ]
counterButton : Int -> Html Msg
counterButton n =
let
label =
(if n > 0 then
"+"
else
""
)
++ String.fromInt n
in
button
[ onClick (UserManipulatesCounter n) ]
[ text label ]
creditCardSelectors : { a | amount : Int, cardNumber : String, owner : String } -> List (Html Msg)
creditCardSelectors model =
[ button [ onClick UserPushedReset ] [ text "Reset" ]
, div [] [ text (String.fromInt model.amount) ]
, div []
[ input [ placeholder "CreditCard", value model.cardNumber, onInput UserChangesCreditcardNumber ] []
, span [] [ text (String.fromInt (String.length model.cardNumber)) ]
]
, div []
[ input [ placeholder "Name", value model.owner, onInput UserChangesOwner ] []
]
, div [] [ text "Pay" ]
, div []
[ button [ onClick UserPushedCreditcard ] [ text "Creditcard" ]
, button [ onClick UserPushedCash ] [ text "Cash" ]
]
]
view : Model -> Html Msg
view model =
div []
(List.concat
[ amountSelectors
, creditCardSelectors model
--, div [] [ text (Debug.toString (Payments.testOutput))]
, [ div [] [ text model.message ] ]
]
)
module Payments exposing
( Amount(..)
, Currency(..)
, Payment
, Provider(..)
, addAmounts
, create
, createMethodCash
, createMethodCredit
)
type Currency
= Euro
| Dollar
| Yen
type Amount
= AmountOf Float Currency
type Provider
= MasterCard
| VisaCard
type alias Payment =
{ amount : Amount
, method : PaymentMethod
}
type PaymentMethod
= Cash
| CreditCard
{ provider : Provider
, number : String
, owner : String
}
create : Amount -> Maybe PaymentMethod -> Maybe Payment
create amount justMethod =
case justMethod of
Just method ->
Just
{ amount = amount
, method = method
}
Nothing -> Nothing
createMethodCredit : Provider -> String -> String -> Maybe PaymentMethod
createMethodCredit provider number owner =
if
String.length number
== 16
&& String.length owner
> 0
&& String.all Char.isDigit number
then
Just
(CreditCard
{ provider = provider
, number = number
, owner = owner
}
)
else
Nothing
createMethodCash : Maybe PaymentMethod
createMethodCash = Just Cash
addAmounts : Amount -> Amount -> Amount
addAmounts (AmountOf n1 c1) (AmountOf n2 _) =
AmountOf (n1 - n2) c1
--testOutput : Maybe Payment
--testOutput = create (AmountOf 15.0 Dollar) (createMethodCredit VisaCard "1234567890123456" "Harold Prins")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment