diff --git a/client/elm.json b/client/elm.json index d23066e..ec54e15 100644 --- a/client/elm.json +++ b/client/elm.json @@ -12,13 +12,16 @@ "elm/html": "1.0.0", "elm/http": "2.0.0", "elm/json": "1.1.3", - "elm/url": "1.0.0" + "elm/url": "1.0.0", + "rtfeldman/elm-css": "18.0.0" }, "indirect": { "elm/bytes": "1.0.8", "elm/file": "1.0.5", "elm/time": "1.0.0", - "elm/virtual-dom": "1.0.3" + "elm/virtual-dom": "1.0.3", + "robinheghan/murmur3": "1.0.0", + "rtfeldman/elm-hex": "1.0.0" } }, "test-dependencies": { diff --git a/client/src/CreatePage.elm b/client/src/CreatePage.elm index 220577f..a1735f0 100644 --- a/client/src/CreatePage.elm +++ b/client/src/CreatePage.elm @@ -1,10 +1,13 @@ module CreatePage exposing (Model, Msg, init, update, view) import Browser.Navigation as Nav -import Html exposing (Html, text) -import Html.Attributes as Attr -import Html.Events as Events +import Css +import Css.Media as Media +import Html.Styled exposing (..) +import Html.Styled.Attributes as Attr +import Html.Styled.Events as Events import Http +import Input import Json.Decode as Decode exposing (Decoder) import Json.Decode.Pipeline exposing (required) import Json.Encode as Encode @@ -23,12 +26,36 @@ init = } +descriptionStyles : Css.Style +descriptionStyles = + Css.marginTop (Css.px 0) + + +inputLineStyles : Css.Style +inputLineStyles = + Css.batch + [ Css.displayFlex + , Media.withMedia + [ Media.only Media.screen [ Media.maxWidth (Css.px 500) ] ] + [ Css.display Css.block ] + ] + + view : Model -> Html Msg view model = - Html.div [] - [ Html.form [ Events.onSubmit (ClickedCreate model.link) ] - [ Html.input [ Attr.type_ "text", Events.onInput LinkUpdated ] [] - , Html.button [ Attr.type_ "submit" ] [ text "Create doglink" ] + div [] + [ form [ Events.onSubmit (ClickedCreate model.link) ] + [ p [ Attr.css [ descriptionStyles ] ] + [ text "A Doglink is just an alias, or a redirect for an existing link. Paste a link you want to redirect to into the field below!" + ] + , div [ Attr.css [ inputLineStyles ] ] + [ Input.text + [ Attr.placeholder "https://example.com" + , Events.onInput LinkUpdated + ] + [] + , Input.submitButton [] [ text "Create doglink" ] + ] ] , case model.error of Just error -> @@ -41,9 +68,9 @@ view model = viewError : String -> Html msg viewError error = - Html.div [] - [ Html.h3 [] [ text "Couldn't create doglink" ] - , Html.p [] [ text error ] + div [] + [ h3 [] [ text "Couldn't create doglink" ] + , p [] [ text error ] ] @@ -56,7 +83,7 @@ type Msg update : String -> Nav.Key -> Msg -> Model -> ( Model, Cmd Msg ) update origin key msg model = case msg of - ClickedCreate link -> + ClickedCreate _ -> ( model, createLink origin model ) LinkUpdated link -> diff --git a/client/src/Input.elm b/client/src/Input.elm new file mode 100644 index 0000000..172fd83 --- /dev/null +++ b/client/src/Input.elm @@ -0,0 +1,100 @@ +module Input exposing (copyButton, submitButton, text) + +import Css +import Css.Media as Media +import Html.Styled as Html exposing (..) +import Html.Styled.Attributes as Attr + + +sharedStyles : Css.Style +sharedStyles = + Css.batch + [ Css.borderStyle Css.solid + , Css.borderWidth (Css.px 1) + , Css.fontSize (Css.px 16) + , Css.height (Css.px 40) + , Css.lineHeight (Css.px 30) + , Css.outline Css.none + , Css.padding2 (Css.px 4) (Css.px 16) + , Media.withMedia + [ Media.only Media.screen [ Media.maxWidth (Css.px 500) ] ] + [ Css.borderRadius (Css.px 4) + , Css.width (Css.pct 100) + ] + ] + + +inputStyles : Css.Style +inputStyles = + Css.batch + [ Css.borderRadius4 (Css.px 4) (Css.px 0) (Css.px 0) (Css.px 4) + , Css.borderColor (Css.hex "bbb") + , Css.boxShadow5 Css.inset (Css.px 0) (Css.px 0) (Css.px 4) (Css.rgba 0 0 0 0.1) + , Css.focus + [ Css.borderColor (Css.hex "c92a60") + , Css.boxShadow5 Css.inset (Css.px 0) (Css.px 0) (Css.px 3) (Css.hex "c92a60") + ] + , Css.hover [ Css.borderColor (Css.hex "c92a60") ] + , Css.flex (Css.int 1) + , Media.withMedia + [ Media.only Media.screen [ Media.maxWidth (Css.px 500) ] ] + [ Css.flex Css.none ] + , sharedStyles + ] + + +buttonStyles : Css.Style +buttonStyles = + Css.batch + [ Css.borderRadius4 (Css.px 0) (Css.px 4) (Css.px 4) (Css.px 0) + , Css.cursor Css.pointer + , Css.overflow Css.hidden + , Css.whiteSpace Css.noWrap + , Media.withMedia + [ Media.only Media.screen [ Media.maxWidth (Css.px 500) ] ] + [ Css.marginTop (Css.px 8) ] + , sharedStyles + ] + + +submitButtonStyles : Css.Style +submitButtonStyles = + Css.batch + [ buttonStyles + , Css.backgroundColor (Css.hex "c92a60") + , Css.borderColor (Css.hex "9d2a60") + , Css.color (Css.hex "fff") + , Css.hover + [ Css.backgroundColor (Css.hex "9d2a60") + , Css.borderColor (Css.hex "662041") + ] + ] + + +copyButtonStyles : Css.Style +copyButtonStyles = + Css.batch + [ buttonStyles + , Css.backgroundColor (Css.hex "e5e5e5") + , Css.borderColor (Css.hex "ccc") + , Css.color (Css.hex "222") + , Css.hover + [ Css.backgroundColor (Css.hex "ddd") + , Css.borderColor (Css.hex "aaa") + ] + ] + + +text : List (Attribute msg) -> List (Html msg) -> Html msg +text attrs content = + Html.input (Attr.css [ inputStyles ] :: Attr.type_ "text" :: attrs) content + + +submitButton : List (Attribute msg) -> List (Html msg) -> Html msg +submitButton attrs content = + Html.button (Attr.css [ submitButtonStyles ] :: Attr.type_ "submit " :: attrs) content + + +copyButton : List (Attribute msg) -> List (Html msg) -> Html msg +copyButton attrs content = + Html.button (Attr.css [ copyButtonStyles ] :: attrs) content diff --git a/client/src/Main.elm b/client/src/Main.elm index 41488e9..20e7666 100644 --- a/client/src/Main.elm +++ b/client/src/Main.elm @@ -3,7 +3,11 @@ module Main exposing (..) import Browser exposing (Document) import Browser.Navigation as Nav import CreatePage -import Html exposing (Html, text) +import Css +import Css.Media as Media +import Html +import Html.Styled exposing (..) +import Html.Styled.Attributes exposing (css, href, src) import ShowPage import Url exposing (Url) import Url.Parser as Parser exposing (Parser) @@ -26,21 +30,73 @@ type Page | ShowPage ShowPage.Model +sharedStyles : Css.Style +sharedStyles = + Css.batch + [ Css.margin Css.auto + , Css.maxWidth (Css.px 500) + , Css.width (Css.pct 100) + ] + + +headerSectionStyles : Css.Style +headerSectionStyles = + Css.batch + [ Media.withMedia + [ Media.only Media.screen [ Media.maxWidth (Css.px 500) ] ] + [ Css.padding2 (Css.px 0) (Css.px 16) ] + , sharedStyles + ] + + +sectionStyles : Css.Style +sectionStyles = + Css.batch + [ Css.backgroundColor (Css.hex "fff") + , Css.borderRadius (Css.px 4) + , Css.color (Css.hex "222") + , Css.padding (Css.px 16) + , Media.withMedia + [ Media.only Media.screen [ Media.maxWidth (Css.px 500) ] ] + [ Css.borderRadius (Css.px 0) ] + , sharedStyles + ] + + +headerStyles : Css.Style +headerStyles = + Css.marginBottom (Css.px 0) + + +subHeaderStyles : Css.Style +subHeaderStyles = + Css.batch + [ Css.fontStyle Css.italic + , Css.marginTop (Css.px 0) + ] + + view : Model -> Document Msg view model = { title = "Doglinks" , body = - [ Html.h1 [] [ text "Doglinks" ] - , Html.p [] [ text "Create your doglinks here" ] - , case model.page of - CreatePage page -> - CreatePage.view page - |> Html.map CreateMsg + List.map toUnstyled + [ section [ css [ headerSectionStyles ] ] + [ h1 [ css [ headerStyles ] ] [ text "Doglinks" ] + , p [ css [ subHeaderStyles ] ] [ text "Create your doglinks here" ] + ] + , section + [ css [ sectionStyles ] ] + [ case model.page of + CreatePage page -> + CreatePage.view page + |> Html.Styled.map CreateMsg - ShowPage page -> - ShowPage.view model.origin page - |> Html.map ShowMsg - ] + ShowPage page -> + ShowPage.view model.origin page + |> Html.Styled.map ShowMsg + ] + ] } @@ -89,7 +145,7 @@ update msg model = ShowPage page -> let ( pageModel, pageMsg ) = - ShowPage.update model.key showMsg page + ShowPage.update showMsg page in ( { model | page = ShowPage pageModel }, Cmd.map ShowMsg pageMsg ) diff --git a/client/src/ShowPage.elm b/client/src/ShowPage.elm index a7933fa..42d1997 100644 --- a/client/src/ShowPage.elm +++ b/client/src/ShowPage.elm @@ -1,10 +1,11 @@ port module ShowPage exposing (Model, Msg, init, subscriptions, update, view) -import Browser -import Browser.Navigation as Nav -import Html exposing (Html, text) -import Html.Attributes as Attr -import Html.Events as Events +import Css +import Css.Media as Media +import Html.Styled exposing (..) +import Html.Styled.Attributes as Attr +import Html.Styled.Events as Events +import Input import Process import Task @@ -22,17 +23,60 @@ init uuid = } +headerStyles : Css.Style +headerStyles = + Css.batch + [ Css.margin (Css.px 0) + ] + + +descriptionStyles : Css.Style +descriptionStyles = + Css.batch [] + + +copyLineStyles : Css.Style +copyLineStyles = + Css.batch + [ Css.displayFlex + , Media.withMedia + [ Media.only Media.screen [ Media.maxWidth (Css.px 500) ] ] + [ Css.display Css.block ] + ] + + +homeSectionStyles : Css.Style +homeSectionStyles = + Css.paddingTop (Css.px 10) + + +homeStyles : Css.Style +homeStyles = + Css.batch + [ Css.color (Css.hex "c92a60") + , Css.active [ Css.color (Css.hex "c92a60") ] + , Css.focus [ Css.color (Css.hex "c92a60") ] + , Css.hover [ Css.color (Css.hex "9d2a60") ] + , Css.visited + [ Css.color (Css.hex "c92a60") + , Css.hover [ Css.color (Css.hex "9d2a60") ] + ] + ] + + view : String -> Model -> Html Msg view origin model = let dogLink = origin ++ "/link/" ++ model.uuid in - Html.div [] - [ Html.h3 [] [ text "Doglink created!" ] - , Html.div [] - [ Html.input [ Attr.type_ "text", Attr.id "copy-doglink", Attr.value dogLink ] [] - , Html.a [ Attr.href "#", Events.onClick ClickedCopy ] + div [] + [ h3 [ Attr.css [ headerStyles ] ] [ text "Doglink created!" ] + , p [ Attr.css [ descriptionStyles ] ] + [ text "Here's your Doglink! You can copy this and paste it wherever you might find useful. Maybe on twitter! I'm not your boss." ] + , div [ Attr.css [ copyLineStyles ] ] + [ Input.text [ Attr.id "copy-doglink", Attr.value dogLink ] [] + , Input.copyButton [ Events.onClick ClickedCopy ] [ if model.copied then text "Copied!" @@ -40,8 +84,8 @@ view origin model = text "Copy" ] ] - , Html.div [] - [ Html.a [ Attr.href "/" ] [ text "Return Home" ] + , div [ Attr.css [ homeSectionStyles ] ] + [ a [ Attr.css [ homeStyles ], Attr.href "/" ] [ text "Return Home" ] ] ] @@ -52,11 +96,11 @@ type Msg | ExpiredCopy -update : Nav.Key -> Msg -> Model -> ( Model, Cmd Msg ) -update key msg model = +update : Msg -> Model -> ( Model, Cmd Msg ) +update msg model = case msg of ClickedCopy -> - ( model, copyLink ()) + ( model, copyLink () ) LinkCopied -> ( { model | copied = True }, expireCopy )