131 lines
3.4 KiB
Elm
131 lines
3.4 KiB
Elm
module CreatePage exposing (Model, Msg, init, update, view)
|
|
|
|
import Browser.Navigation as Nav
|
|
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
|
|
|
|
|
|
type alias Model =
|
|
{ link : String
|
|
, error : Maybe String
|
|
}
|
|
|
|
|
|
init : Model
|
|
init =
|
|
{ link = ""
|
|
, error = Nothing
|
|
}
|
|
|
|
|
|
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 =
|
|
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 ->
|
|
viewError error
|
|
|
|
Nothing ->
|
|
text ""
|
|
]
|
|
|
|
|
|
viewError : String -> Html msg
|
|
viewError error =
|
|
div []
|
|
[ h3 [] [ text "Couldn't create doglink" ]
|
|
, p [] [ text error ]
|
|
]
|
|
|
|
|
|
type Msg
|
|
= ClickedCreate String
|
|
| LinkUpdated String
|
|
| GotUuid (Result Http.Error String)
|
|
|
|
|
|
update : String -> Nav.Key -> Msg -> Model -> ( Model, Cmd Msg )
|
|
update origin key msg model =
|
|
case msg of
|
|
ClickedCreate _ ->
|
|
( model, createLink origin model )
|
|
|
|
LinkUpdated link ->
|
|
( { model | link = link }, Cmd.none )
|
|
|
|
GotUuid (Ok uuid) ->
|
|
( model, Nav.pushUrl key ("/" ++ uuid) )
|
|
|
|
GotUuid (Err error) ->
|
|
case error of
|
|
Http.BadUrl url ->
|
|
( { model | error = Just ("Bad url: " ++ url) }, Cmd.none )
|
|
|
|
Http.Timeout ->
|
|
( { model | error = Just "Request timed out" }, Cmd.none )
|
|
|
|
Http.NetworkError ->
|
|
( { model | error = Just "Couldn't talk to server" }, Cmd.none )
|
|
|
|
Http.BadStatus int ->
|
|
( { model | error = Just ("Server responded with invalid status: " ++ String.fromInt int) }, Cmd.none )
|
|
|
|
Http.BadBody body ->
|
|
( { model | error = Just ("Server responed with unexpected data: " ++ body) }, Cmd.none )
|
|
|
|
|
|
createLink : String -> Model -> Cmd Msg
|
|
createLink origin model =
|
|
Http.post
|
|
{ url = origin ++ "/link"
|
|
, body = Http.jsonBody (encodeLink model.link)
|
|
, expect = Http.expectJson GotUuid uuidDecoder
|
|
}
|
|
|
|
|
|
uuidDecoder : Decoder String
|
|
uuidDecoder =
|
|
Decode.succeed identity
|
|
|> required "uuid" Decode.string
|
|
|
|
|
|
encodeLink : String -> Encode.Value
|
|
encodeLink link =
|
|
Encode.object [ ( "url", Encode.string link ) ]
|