Basic working example

This commit is contained in:
Anthony Cicchetti 2019-09-29 15:16:54 -04:00
commit 5b1009f4eb
5 changed files with 249 additions and 0 deletions

7
.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
# elm-package generated files
elm-stuff
# elm-repl generated files
repl-temp-*
leaderboard.js
leaderboard.min.js

33
elm.json Normal file
View file

@ -0,0 +1,33 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.0",
"dependencies": {
"direct": {
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
"elm/browser": "1.0.1",
"elm/core": "1.0.2",
"elm/html": "1.0.0",
"elm/http": "2.0.0",
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"justinmimbs/date": "3.2.0",
"rundis/elm-bootstrap": "5.2.0"
},
"indirect": {
"avh4/elm-color": "1.0.0",
"elm/bytes": "1.0.8",
"elm/file": "1.0.5",
"elm/parser": "1.1.0",
"elm/regex": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.2"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}

18
index.html Normal file
View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="leaderboard.js"></script>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div id="my-leaderboard-app"></div>
<script>
var app = Elm.Leaderboard.init({
node: document.getElementById('my-leaderboard-app')
})
</script>
</body>
</html>

19
justfile Normal file
View file

@ -0,0 +1,19 @@
watch: build
elm-live src/Leaderboard.elm --open -- --output=leaderboard.js
build:
elm make src/Leaderboard.elm --output=leaderboard.js
install:
yarn global add elm-format elm-test elm-oracle elm-live
nodenv rehash
debug:
elm-live src/Leaderboard.elm --open -- --debug --output=leaderboard.js
build_release:
elm make src/Leaderboard.elm --optimize --output=leaderboard.js
uglifyjs leaderboard.js --compress "pure_funcs=[F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9],pure_getters,keep_fargs=false,unsafe_comps,unsafe" | uglifyjs --mangle --output=leaderboard.min.js
deploy: build_release
rsync index.html leaderboard.min.js anthonycicchetti.com:/var/www/crossword.anthonycicchetti.com/public

172
src/Leaderboard.elm Normal file
View file

@ -0,0 +1,172 @@
module Leaderboard exposing (main)
import Browser
import Date
import Debug exposing (toString)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick, onInput)
import Http
import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (hardcoded, optional, required)
import Task exposing (Task)
--- CONSTANTS
apiUrlPrefix : String
apiUrlPrefix =
"https://acicchetti.dev/crossword/v1"
--- DECODERS
entryDecoder : Decoder Entry
entryDecoder =
Decode.succeed Entry
|> required "name" Decode.string
|> required "time" Decode.string
scoreDecoder : String -> Decoder Score
scoreDecoder score =
Decode.string
--- MODEL
type alias Model =
{ date : String
, entries : List Entry
, alertMessage : Maybe String
, newDate : String
}
type alias Entry =
{ name : String
, score : Score
}
type alias Score =
String
--- UPDATE
type Msg
= NewDate String
| NewEntries (Result Http.Error (List Entry))
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NewDate newDate ->
( { model
| date = newDate
, entries = []
, newDate = ""
}
, getScores newDate
)
NewEntries (Ok newEntries) ->
( { model | entries = List.sortBy .score newEntries }, Cmd.none )
NewEntries (Err err) ->
-- ( { model | alertMessage = Just (toString err) }, Cmd.none)
( model, Cmd.none )
--- COMMANDS
getScores : String -> Cmd Msg
getScores newDate =
Http.request
{ method = "GET"
, headers = [ Http.header "Access-Control-Allow-Origin" "https://acicchetti.dev" ]
, url = apiUrlPrefix ++ "/" ++ newDate
, body = Http.emptyBody
, expect = Http.expectJson NewEntries (Decode.list entryDecoder)
, timeout = Nothing
, tracker = Nothing
}
--- VIEW
viewDate : String -> Html Msg
viewDate date =
h2 []
[ text date ]
viewEntryList : List Entry -> Html Msg
viewEntryList entries =
ul []
(List.map
(\entry ->
li []
[ div [] [ text entry.name ]
, div [] [ text entry.score ]
]
)
entries
)
view : Model -> Html Msg
view model =
div []
[ div []
[ input
[ type_ "date"
, placeholder model.date
, onInput NewDate
, value model.date
]
[]
]
, viewEntryList model.entries
, text (Maybe.withDefault "" model.alertMessage)
]
--- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
init : () -> ( Model, Cmd Msg )
init _ =
( Model "2019-09-29" [] Nothing ""
, getScores "2019-09-29"
)
main : Program () Model Msg
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}