recipes.coopcloud.tech/src/Pages/Top.elm

251 lines
6.0 KiB
Elm
Raw Normal View History

2021-04-17 21:42:28 +00:00
module Pages.Top exposing (Model, Msg, Params, page)
2021-04-19 23:31:11 +00:00
import Html exposing (Html, button, div, h2, h5, img, text, ul, li, a, p, span, i)
2021-04-18 10:47:50 +00:00
import Html.Attributes exposing (src, style, class, alt, href)
2021-04-17 21:42:28 +00:00
import Html.Events exposing (onClick)
import Http
import Json.Decode as Decode
2021-04-19 23:31:11 +00:00
import Spa.Generated.Route as Route
2021-04-17 21:42:28 +00:00
import Spa.Document exposing (Document)
import Spa.Page as Page exposing (Page)
import Spa.Url as Url exposing (Url)
2021-04-24 13:36:56 +00:00
import Util exposing (by, andThen, Direction(..))
2021-04-17 21:42:28 +00:00
page : Page Params Model Msg
page =
Page.element
{ init = init
, update = update
, view = view
, subscriptions = subscriptions
}
-- INIT
type alias Params =
()
type alias App =
{ name : String
, category : String
, repository : Maybe String
, versions : Maybe (List String)
2021-04-18 10:47:50 +00:00
, icon : Maybe String
, status : String
, slug : String
, website : Maybe String
2021-04-17 21:42:28 +00:00
}
type Model
= Failure
| Loading
| Success (List App)
init : Url Params -> ( Model, Cmd Msg )
init { params } =
( Loading, loadApps )
2021-04-18 10:47:50 +00:00
default_image : String
2021-04-24 13:36:56 +00:00
default_image = "/logo.png"
2021-04-18 10:47:50 +00:00
2021-04-17 21:42:28 +00:00
-- UPDATE
type Msg
= MorePlease
| GotApps (Result Http.Error (List App))
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
MorePlease ->
( Loading, loadApps )
GotApps result ->
case result of
Ok apps ->
( Success apps, Cmd.none )
Err _ ->
( Failure, Cmd.none )
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> Document Msg
view model =
2021-04-18 10:47:50 +00:00
{ title = "abra apps"
2021-04-17 21:42:28 +00:00
, body = [ body model ]
}
body : Model -> Html Msg
body model =
2021-04-18 10:47:50 +00:00
div [ class "pt-3" ]
2021-04-17 21:42:28 +00:00
[ viewApps model
]
2021-04-24 13:36:56 +00:00
appScore : App -> Int
appScore app =
case app.status of
"1" ->
1
"2" ->
2
"3" ->
3
"4" ->
4
_ ->
5
2021-04-19 23:31:11 +00:00
viewStatusBadge : App -> Html Msg
viewStatusBadge app =
2021-04-18 10:47:50 +00:00
let
status_class =
case app.status of
"1" ->
"badge-success"
"2" ->
"badge-info"
"3" ->
"badge-warning"
"4" ->
"badge-danger"
_ ->
"badge-dark"
status_score =
case app.status of
"" ->
"?"
score ->
score
2021-04-18 10:47:50 +00:00
in
span [ class ("card-link badge " ++ status_class) ]
[ text ("Score: " ++ status_score) ]
2021-04-18 10:47:50 +00:00
2021-04-19 23:31:11 +00:00
viewApp : App -> Html Msg
viewApp app =
2021-04-18 10:47:50 +00:00
let
icon_url =
case app.icon of
Just "" ->
default_image
Just i ->
i
Nothing ->
default_image
repository_link =
case app.repository of
2021-04-19 23:31:11 +00:00
Just link ->
a [ class "card-link", href link ]
[
i [ class "fab fa-git-alt" ] []
2021-04-23 17:06:06 +00:00
, text "code"
2021-04-19 23:31:11 +00:00
]
2021-04-18 10:47:50 +00:00
Nothing ->
text ""
website_link =
case app.website of
Just link ->
case link of
"" ->
text ""
_ ->
a [ class "card-link", href link ]
[ i [ class "fas fa-home" ] []
, text "homepage" ]
Nothing ->
text ""
app_href = Route.toString <| Route.App_String { app = app.slug }
2021-04-18 10:47:50 +00:00
in
div [ class "col-4 mb-3" ]
[ div [ class "card" ]
[ img [ class "card-img-top", src icon_url, alt ("icon for " ++ app.name) ] []
, div [ class "card-body" ]
2021-04-19 23:31:11 +00:00
[ h5 [ class "card-title" ]
2021-04-23 17:06:06 +00:00
[ a [ href app_href ] [ text app.name ] ]
, repository_link
, website_link
2021-04-23 17:06:06 +00:00
, a [ class "card-link", href app_href ]
[ i [ class "fas fa-book" ] []
, text "docs" ]
]
2021-04-18 10:47:50 +00:00
, div [ class "card-footer" ]
[ span [ class "card-link badge badge-secondary" ] [ text app.category ]
2021-04-19 23:31:11 +00:00
, viewStatusBadge app
2021-04-17 21:42:28 +00:00
]
]
]
2021-04-24 13:36:56 +00:00
2021-04-17 21:42:28 +00:00
viewApps : Model -> Html Msg
viewApps model =
case model of
Failure ->
div [ ]
[ text "I could not load a random cat for some reason. "
, button [ onClick MorePlease ] [ text "Try Again!" ]
]
Loading ->
text "Loading..."
Success apps ->
div []
[ div [ class "row" ]
2021-04-24 13:36:56 +00:00
(List.map viewApp (apps |> List.sortWith
(by appScore ASC
|> andThen .name ASC))
)
2021-04-17 21:42:28 +00:00
]
-- HTTP
loadApps : Cmd Msg
loadApps =
Http.get
2021-04-24 13:36:56 +00:00
{ url = "/abra-apps-list.json"
2021-04-17 21:42:28 +00:00
, expect = Http.expectJson GotApps appListDecoder
}
2021-04-18 10:47:50 +00:00
featuresDecoder =
(Decode.oneOf
[ Decode.at [ "status" ] Decode.string
, Decode.succeed ""
]
)
2021-04-17 21:42:28 +00:00
appDecoder : Decode.Decoder App
appDecoder =
Decode.map8
2021-04-17 21:42:28 +00:00
App
(Decode.field "name" Decode.string)
(Decode.field "category" Decode.string)
2021-04-18 10:47:50 +00:00
(Decode.maybe (Decode.field "repository" Decode.string))
2021-04-17 21:42:28 +00:00
(Decode.succeed Nothing)
2021-04-18 10:47:50 +00:00
(Decode.maybe (Decode.field "icon" Decode.string))
(Decode.at [ "features" ] featuresDecoder)
(Decode.field "slug" Decode.string)
(Decode.maybe (Decode.field "website" Decode.string))
2021-04-17 21:42:28 +00:00
appListDecoder : Decode.Decoder (List App)
appListDecoder =
Decode.list appDecoder