diff options
author | Vincent Ambo <mail@tazj.in> | 2021-12-13T22·51+0300 |
---|---|---|
committer | Vincent Ambo <mail@tazj.in> | 2021-12-13T23·15+0300 |
commit | 019f8fd2113df4c5247c3969c60fd4f0e08f91f7 (patch) | |
tree | 76a857f61aa88f62a30e854651e8439db77fd0ea /users/wpcarro/assessments/tt/client/src/UI.elm | |
parent | 464bbcb15c09813172c79820bcf526bb10cf4208 (diff) | |
parent | 6123e976928ca3d8d93f0b2006b10b5f659eb74d (diff) |
subtree(users/wpcarro): docking briefcase at '24f5a642' r/3226
git-subtree-dir: users/wpcarro git-subtree-mainline: 464bbcb15c09813172c79820bcf526bb10cf4208 git-subtree-split: 24f5a642af3aa1627bbff977f0a101907a02c69f Change-Id: I6105b3762b79126b3488359c95978cadb3efa789
Diffstat (limited to 'users/wpcarro/assessments/tt/client/src/UI.elm')
-rw-r--r-- | users/wpcarro/assessments/tt/client/src/UI.elm | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/users/wpcarro/assessments/tt/client/src/UI.elm b/users/wpcarro/assessments/tt/client/src/UI.elm new file mode 100644 index 000000000000..7f8f379795f7 --- /dev/null +++ b/users/wpcarro/assessments/tt/client/src/UI.elm @@ -0,0 +1,318 @@ +module UI exposing (..) + +import Date +import DatePicker exposing (defaultSettings) +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (..) +import State +import Tailwind + + +label_ : { for_ : String, text_ : String } -> Html msg +label_ { for_, text_ } = + label + [ [ "block" + , "text-gray-700" + , "text-sm" + , "font-bold" + , "mb-2" + ] + |> Tailwind.use + |> class + , for for_ + ] + [ text text_ ] + + +errorBanner : { title : String, body : String } -> Html msg +errorBanner { title, body } = + div + [ [ "text-left" + , "fixed" + , "container" + , "top-0" + , "mt-6" + ] + |> Tailwind.use + |> class + , style "left" "50%" + + -- TODO(wpcarro): Consider supporting breakpoints, but for now + -- don't. + , style "width" "800px" + , style "margin-left" "-400px" + ] + [ div + [ [ "bg-red-500" + , "text-white" + , "font-bold" + , "rounded-t" + , "px-4" + , "py-2" + ] + |> Tailwind.use + |> class + ] + [ text title ] + , div + [ [ "border" + , "border-t-0" + , "border-red-400" + , "rounded-b" + , "bg-red-100" + , "px-4" + , "py-3" + , "text-red-700" + ] + |> Tailwind.use + |> class + ] + [ p [] [ text body ] ] + ] + + +baseButton : + { label : String + , enabled : Bool + , handleClick : msg + , extraClasses : List String + } + -> Html msg +baseButton { label, enabled, handleClick, extraClasses } = + button + [ [ if enabled then + "bg-blue-500" + + else + "bg-gray-500" + , if enabled then + "hover:bg-blue-700" + + else + "" + , if enabled then + "" + + else + "cursor-not-allowed" + , "text-white" + , "font-bold" + , "py-1" + , "shadow-lg" + , "px-4" + , "rounded" + , "focus:outline-none" + , "focus:shadow-outline" + ] + ++ extraClasses + |> Tailwind.use + |> class + , onClick handleClick + , disabled (not enabled) + ] + [ text label ] + + +simpleButton : + { label : String + , handleClick : msg + } + -> Html msg +simpleButton { label, handleClick } = + baseButton + { label = label + , enabled = True + , handleClick = handleClick + , extraClasses = [] + } + + +disabledButton : + { label : String } + -> Html State.Msg +disabledButton { label } = + baseButton + { label = label + , enabled = False + , handleClick = State.DoNothing + , extraClasses = [] + } + + +textButton : + { label : String + , handleClick : msg + } + -> Html msg +textButton { label, handleClick } = + button + [ [ "text-blue-600" + , "hover:text-blue-500" + , "font-bold" + , "hover:underline" + , "focus:outline-none" + ] + |> Tailwind.use + |> class + , onClick handleClick + ] + [ text label ] + + +textField : + { pholder : String + , inputId : String + , handleInput : String -> msg + , inputValue : String + } + -> Html msg +textField { pholder, inputId, handleInput, inputValue } = + input + [ [ "shadow" + , "appearance-none" + , "border" + , "rounded" + , "w-full" + , "py-2" + , "px-3" + , "text-gray-700" + , "leading-tight" + , "focus:outline-none" + , "focus:shadow-outline" + ] + |> Tailwind.use + |> class + , id inputId + , value inputValue + , placeholder pholder + , onInput handleInput + ] + [] + + +toggleButton : + { toggled : Bool + , label : String + , handleEnable : msg + , handleDisable : msg + } + -> Html msg +toggleButton { toggled, label, handleEnable, handleDisable } = + button + [ [ if toggled then + "bg-blue-700" + + else + "bg-blue-500" + , "hover:bg-blue-700" + , "text-white" + , "font-bold" + , "py-2" + , "px-4" + , "rounded" + , "focus:outline-none" + , "focus:shadow-outline" + ] + |> Tailwind.use + |> class + , onClick + (if toggled then + handleDisable + + else + handleEnable + ) + ] + [ text label ] + + +paragraph : String -> Html msg +paragraph x = + p [ [ "text-xl" ] |> Tailwind.use |> class ] [ text x ] + + +header : Int -> String -> Html msg +header which x = + let + hStyles = + case which of + 1 -> + [ "text-6xl" + , "py-12" + ] + + 2 -> + [ "text-3xl" + , "py-6" + ] + + _ -> + [ "text-2xl" + , "py-2" + ] + in + h1 + [ hStyles + ++ [ "font-bold" + , "text-gray-700" + ] + |> Tailwind.use + |> class + ] + [ text x ] + + +link : String -> String -> Html msg +link path label = + a + [ href path + , [ "underline" + , "text-blue-600" + , "text-xl" + ] + |> Tailwind.use + |> class + ] + [ text label ] + + +absentData : { handleFetch : msg } -> Html msg +absentData { handleFetch } = + div [] + [ paragraph "Welp... it looks like you've caught us in a state that we considered impossible: we did not fetch the data upon which this page depends. Maybe you can help us out by clicking the super secret, highly privileged \"Fetch data\" button below (we don't normally show people this)." + , div [ [ "py-4" ] |> Tailwind.use |> class ] + [ simpleButton + { label = "Fetch data" + , handleClick = handleFetch + } + ] + ] + + +datePicker : + { mDate : Maybe Date.Date + , prompt : String + , prefix : String + , picker : DatePicker.DatePicker + , onUpdate : DatePicker.Msg -> State.Msg + } + -> Html State.Msg +datePicker { mDate, prompt, prefix, picker, onUpdate } = + let + settings = + { defaultSettings + | placeholder = prompt + , inputClassList = + [ ( "text-center", True ) + , ( "py-2", True ) + ] + } + in + div [ [ "w-1/2", "py-4", "mx-auto" ] |> Tailwind.use |> class ] + [ DatePicker.view mDate settings picker |> Html.map onUpdate ] + + +wrapNoPrint : Html State.Msg -> Html State.Msg +wrapNoPrint component = + div [ [ "no-print" ] |> Tailwind.use |> class ] [ component ] |