elm-pages-v3-beta/examples/pokedex/src/Page/PokedexNumber_.elm

144 lines
3.7 KiB
Elm
Raw Normal View History

2021-06-01 20:57:08 +03:00
module Page.PokedexNumber_ exposing (Data, Model, Msg, page)
import DataSource exposing (DataSource)
import DataSource.Http
import Head
import Head.Seo as Seo
import Html exposing (..)
import Html.Attributes exposing (src)
import OptimizedDecoder as Decode
import Page exposing (Page, PageWithState, StaticPayload)
import PageServerResponse exposing (PageServerResponse)
2021-06-01 20:57:08 +03:00
import Pages.PageUrl exposing (PageUrl)
import Pages.Url
import Secrets
2022-01-01 03:15:41 +03:00
import Server.Response
2021-06-01 20:57:08 +03:00
import Shared
import View exposing (View)
type alias Model =
2021-12-15 20:26:23 +03:00
{}
2021-06-01 20:57:08 +03:00
type alias Msg =
Never
type alias RouteParams =
2021-06-03 21:58:35 +03:00
{ pokedexNumber : String }
2021-06-01 20:57:08 +03:00
page : Page RouteParams Data
page =
2021-12-24 00:34:19 +03:00
Page.preRenderWithFallback
2021-06-01 20:57:08 +03:00
{ head = head
, pages = pages
2021-06-01 20:57:08 +03:00
, data = data
}
|> Page.buildNoState { view = view }
pages : DataSource (List RouteParams)
pages =
2021-06-01 20:57:08 +03:00
DataSource.succeed []
data : RouteParams -> DataSource (PageServerResponse Data)
data { pokedexNumber } =
let
asNumber : Int
asNumber =
String.toInt pokedexNumber |> Maybe.withDefault -1
in
if asNumber < 1 then
notFoundResponse "Pokedex numbers must be 1 or greater."
else if asNumber > 898 && asNumber < 10001 || asNumber > 10194 then
notFoundResponse "The pokedex is empty in that range."
else
DataSource.map2 Data
(DataSource.Http.get (Secrets.succeed "https://elm-pages-pokedex.netlify.app/.netlify/functions/time")
Decode.string
)
(DataSource.Http.get (Secrets.succeed ("https://pokeapi.co/api/v2/pokemon/" ++ pokedexNumber))
(Decode.map2 Pokemon
(Decode.field "forms" (Decode.index 0 (Decode.field "name" Decode.string)))
(Decode.field "types" (Decode.list (Decode.field "type" (Decode.field "name" Decode.string))))
)
2021-06-02 00:38:03 +03:00
)
|> DataSource.map PageServerResponse.RenderPage
notFoundResponse : String -> DataSource (PageServerResponse Data)
notFoundResponse message =
2022-01-01 03:15:41 +03:00
Server.Response.stringBody ("Not found.\n\n" ++ message)
|> Server.Response.withStatusCode 404
|> PageServerResponse.ServerResponse
|> DataSource.succeed
2021-06-02 00:38:03 +03:00
type alias Pokemon =
{ name : String
, abilities : List String
}
2021-06-01 20:57:08 +03:00
head :
StaticPayload Data RouteParams
-> List Head.Tag
head static =
Seo.summary
{ canonicalUrlOverride = Nothing
2021-12-15 23:35:50 +03:00
, siteName = "elm-pages Pokedex"
2021-06-01 20:57:08 +03:00
, image =
2021-12-15 23:35:50 +03:00
{ url = static.routeParams |> pokemonImage |> Pages.Url.external
, alt = static.data.pokemon.name
2021-06-01 20:57:08 +03:00
, dimensions = Nothing
, mimeType = Nothing
}
, description = "TODO"
, locale = Nothing
2021-12-15 23:35:50 +03:00
, title =
"Pokedex #"
++ static.routeParams.pokedexNumber
++ " "
++ static.data.pokemon.name
2021-06-01 20:57:08 +03:00
}
|> Seo.website
type alias Data =
2021-06-02 00:38:03 +03:00
{ time : String
, pokemon : Pokemon
2021-06-01 20:57:08 +03:00
}
view :
Maybe PageUrl
-> Shared.Model
-> StaticPayload Data RouteParams
-> View Msg
view maybeUrl sharedModel static =
2021-06-02 00:38:03 +03:00
{ title = static.data.pokemon.name
2021-06-01 20:57:08 +03:00
, body =
[ h1 []
2021-06-02 00:38:03 +03:00
[ text static.data.pokemon.name
2021-06-01 20:57:08 +03:00
]
2021-06-02 00:38:03 +03:00
, text (static.data.pokemon.abilities |> String.join ", ")
2021-06-01 20:57:08 +03:00
, img
2021-12-15 23:35:50 +03:00
[ static.routeParams |> pokemonImage |> src
2021-06-01 20:57:08 +03:00
]
[]
2021-06-02 00:38:03 +03:00
, p []
[ text static.data.time
]
2021-06-01 20:57:08 +03:00
]
}
2021-12-15 23:35:50 +03:00
pokemonImage : RouteParams -> String
pokemonImage routeParams =
"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/" ++ routeParams.pokedexNumber ++ ".png"