From bc36b0da6677b4cac00009274165c37cc6bd7bb9 Mon Sep 17 00:00:00 2001 From: Ingar Almklov Date: Sun, 1 Dec 2019 17:43:14 +0100 Subject: [PATCH] Frontend: actually submit email --- elm.json | 56 +++++++++++--------- src/Main.elm | 142 ++++++++++++++++++++++++++++++++++----------------- 2 files changed, 127 insertions(+), 71 deletions(-) diff --git a/elm.json b/elm.json index dfb73de..ecbf011 100644 --- a/elm.json +++ b/elm.json @@ -1,29 +1,35 @@ { - "type": "application", - "source-directories": ["src"], - "elm-version": "0.19.1", - "dependencies": { - "direct": { - "elm/browser": "1.0.2", - "elm/core": "1.0.2", - "elm/html": "1.0.0", - "rtfeldman/elm-validate": "4.0.1", - "tesk9/accessible-html": "4.0.0" + "type": "application", + "source-directories": [ + "src" + ], + "elm-version": "0.19.1", + "dependencies": { + "direct": { + "elm/browser": "1.0.2", + "elm/core": "1.0.2", + "elm/html": "1.0.0", + "elm/http": "2.0.0", + "elm/json": "1.1.2", + "krisajenkins/remotedata": "6.0.1", + "rtfeldman/elm-validate": "4.0.1", + "tesk9/accessible-html": "4.0.0" + }, + "indirect": { + "elm/bytes": "1.0.8", + "elm/file": "1.0.5", + "elm/regex": "1.0.0", + "elm/time": "1.0.0", + "elm/url": "1.0.0", + "elm/virtual-dom": "1.0.2" + } }, - "indirect": { - "elm/json": "1.1.2", - "elm/regex": "1.0.0", - "elm/time": "1.0.0", - "elm/url": "1.0.0", - "elm/virtual-dom": "1.0.2" + "test-dependencies": { + "direct": { + "elm-explorations/test": "1.0.0" + }, + "indirect": { + "elm/random": "1.0.0" + } } - }, - "test-dependencies": { - "direct": { - "elm-explorations/test": "1.0.0" - }, - "indirect": { - "elm/random": "1.0.0" - } - } } diff --git a/src/Main.elm b/src/Main.elm index 5a4df68..d200821 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -1,10 +1,14 @@ module Main exposing (Model, Msg(..), init, main, update, view) -import Accessibility as Html exposing (..) +import Accessibility exposing (..) import Browser import Html exposing (Html) -import Html.Attributes exposing (class, href, id, placeholder, type_) +import Html.Attributes exposing (class, disabled, href, id, placeholder, type_) import Html.Events exposing (onClick, onInput) +import Http +import Json.Decode as Decode +import Json.Encode as Encode +import RemoteData exposing (RemoteData(..), WebData) import Validate @@ -15,26 +19,49 @@ import Validate type alias Model = { email : String , validationError : Maybe String + , submitStatus : WebData () } init : ( Model, Cmd Msg ) init = - ( { email = "", validationError = Nothing }, Cmd.none ) + ( { email = "" + , validationError = Nothing + , submitStatus = NotAsked + } + , Cmd.none + ) ---- UPDATE ---- -submitEmail : String -> Cmd msg +submitEmail : String -> Cmd Msg submitEmail email = - Cmd.none + let + url = + "/.netlify/functions/save-email" + + body = + Http.jsonBody <| + Encode.object + [ ( "email", Encode.string email ) ] + in + Http.post + { url = url + , body = body + , expect = + Http.expectJson + (RemoteData.fromResult >> SubmitCompleted) + (Decode.succeed ()) + } type Msg = EmailUpdated String | SubmitClicked + | SubmitCompleted (WebData ()) update : Msg -> Model -> ( Model, Cmd Msg ) @@ -47,13 +74,22 @@ update msg model = SubmitClicked -> if Validate.isValidEmail model.email then - ( model, submitEmail model.email ) + ( { model + | submitStatus = Loading + } + , submitEmail model.email + ) else ( { model | validationError = Just "This looks like an invalid email address" } , Cmd.none ) + SubmitCompleted data -> + ( { model | submitStatus = data } + , Cmd.none + ) + ---- VIEW ---- @@ -66,32 +102,12 @@ view model = , p [ class "intro" ] [ text "May 15 and 16 in Oslo, Norway" ] - , form [ class "form" ] - [ p [ class "newsletterIntro" ] - [ div [] [ text "Want to stay up to date with the latest news?" ] - , div [] [ text "Sign up for our newsletter!" ] - ] - , div [ class "inputContainer" ] - [ labelHidden "email-input" - [] - (text "hello@osloelmdays.no") - (inputText model.email - [ id "email-input" - , placeholder "hello@osloelmdays.no" - , class "email" - , onInput EmailUpdated - ] - ) - ] - , case model.validationError of - Just err -> - div [ class "validationError" ] [ text err ] - - Nothing -> - text "" - , button [ class "submitButton", type_ "button", onClick SubmitClicked ] - [ text "Submit" ] - ] + , case model.submitStatus of + Success _ -> + p [] [ text "Thanks for subscribing!" ] + + _ -> + viewSignupForm model , p [ class "removeFromNewsletter" ] [ span [] [ text "If you want to be removed from the newsletter, send an email to " @@ -99,21 +115,55 @@ view model = , a [ href "mailto:hello@osloelmdays.no" ] [ text "hello@osloelmdays.no" ] ] + ] + + +viewSignupForm : Model -> Html Msg +viewSignupForm model = + form [ class "form" ] + [ p [ class "newsletterIntro" ] + [ div [] [ text "Want to stay up to date with the latest news?" ] + , div [] [ text "Sign up for our newsletter!" ] + ] + , div [ class "inputContainer" ] + [ labelHidden "email-input" + [] + (text "hello@osloelmdays.no") + (inputText model.email + [ id "email-input" + , placeholder "hello@osloelmdays.no" + , class "email" + , onInput EmailUpdated + ] + ) + ] + , case model.validationError of + Just err -> + div [ class "validationError" ] [ text err ] + + Nothing -> + text "" + , case model.submitStatus of + Failure _ -> + div [ class "validationError" ] + [ text "Something went wrong while submitting" ] + + _ -> + text "" + , button + [ class "submitButton" + , type_ "button" + , onClick SubmitClicked + , disabled <| RemoteData.isLoading model.submitStatus + ] + [ text <| + case model.submitStatus of + Loading -> + "Submitting..." - -- , Element.paragraph [ Font.size 16 ] - -- [ Element.text "If you want to be removed from the newsletter, send an email to " - -- , Element.link - -- [ Font.underline - -- , Element.mouseOver - -- [ Font.color <| color.yellow - -- ] - -- , Element.htmlAttribute <| - -- HtmlA.style "transition" "all 0.2s ease-in-out" - -- ] - -- { url = "mailto:hello@osloelmday.no" - -- , label = Element.text "hello@osloelmday.no" - -- } - -- ] + _ -> + "Submit" + ] ]