├── RLBServer
├── user
├── package.json
└── README.md
├── .gitignore
├── 07RLBStarter
├── README.md
├── package.json
├── dist
│ └── index.html
├── elm-package.json
├── gulpfile.js
└── src
│ ├── Main.elm
│ ├── Login.elm
│ ├── LeaderBoard.elm
│ └── Runner.elm
├── 04Websocket
├── README.md
├── package.json
├── elm-package.json
├── server.js
└── Main.elm
├── 06Ports
├── package.json
├── elm-package.json
├── completed
│ ├── elm-package.json
│ ├── appfb.js
│ ├── gulpfile.js
│ ├── index.html
│ └── Main.elm
├── README.md
├── appfb.js
├── gulpfile.js
├── index.html
└── Main.elm
├── 09RLBLogin
├── package.json
├── dist
│ └── index.html
├── elm-package.json
├── gulpfile.js
└── src
│ ├── LeaderBoard.elm
│ ├── Login.elm
│ └── Runner.elm
├── 11RLBLogout
├── package.json
├── elm-package.json
├── dist
│ └── index.html
├── gulpfile.js
└── src
│ ├── LeaderBoard.elm
│ ├── Login.elm
│ └── Runner.elm
├── 08RLBNavigation
├── package.json
├── dist
│ └── index.html
├── completed
│ ├── package.json
│ ├── dist
│ │ └── index.html
│ ├── elm-package.json
│ ├── gulpfile.js
│ └── src
│ │ ├── Login.elm
│ │ ├── LeaderBoard.elm
│ │ └── Runner.elm
├── elm-package.json
├── gulpfile.js
└── src
│ ├── Login.elm
│ ├── LeaderBoard.elm
│ ├── Main.elm
│ └── Runner.elm
├── 10RLBLoginToken
├── package.json
├── elm-package.json
├── dist
│ └── index.html
├── gulpfile.js
└── src
│ ├── LeaderBoard.elm
│ ├── Login.elm
│ └── Runner.elm
├── 13RLBAddRunner
├── package.json
├── completed
│ ├── package.json
│ ├── elm-package.json
│ ├── dist
│ │ └── index.html
│ ├── gulpfile.js
│ └── src
│ │ ├── LeaderBoard.elm
│ │ └── Login.elm
├── elm-package.json
├── dist
│ └── index.html
├── gulpfile.js
└── src
│ ├── LeaderBoard.elm
│ └── Login.elm
├── 14RLBWebsocket
├── package.json
├── completed
│ ├── package.json
│ ├── elm-package.json
│ ├── dist
│ │ └── index.html
│ ├── gulpfile.js
│ └── src
│ │ └── Login.elm
├── elm-package.json
├── dist
│ └── index.html
├── gulpfile.js
└── src
│ └── Login.elm
├── 16RLBFilterRunner
├── package.json
├── dist
│ └── index.html
├── elm-package.json
├── gulpfile.js
└── src
│ └── Login.elm
├── 12RLBLockRunnerPage
├── package.json
├── elm-package.json
├── dist
│ └── index.html
├── gulpfile.js
└── src
│ ├── LeaderBoard.elm
│ ├── Login.elm
│ └── Runner.elm
├── 15RLBEstimatedDistance
├── package.json
├── dist
│ └── index.html
├── elm-package.json
├── gulpfile.js
└── src
│ └── Login.elm
├── 00Review
├── elm-package.json
└── Login.elm
├── 01The-Elm-Architecture
├── elm-package.json
├── LeaderBoard.elm
├── Login.elm
└── Main.elm
├── 02Effects
├── elm-package.json
├── Main.elm
└── Completed.elm
├── 05Navigation
├── elm-package.json
└── Main.elm
├── 03JSON
├── elm-package.json
├── SimpleDecoding.elm
└── Main.elm
└── README.md
/RLBServer/user:
--------------------------------------------------------------------------------
1 | APP_USERNAME=james
2 | APP_PASSWORD=1234
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | elm-stuff
2 | node_modules
3 | .DS_Store
4 | bundle.js
5 | app.css.map
6 | *.db
7 |
--------------------------------------------------------------------------------
/07RLBStarter/README.md:
--------------------------------------------------------------------------------
1 | ### Notes
2 |
3 | This dir contains the starter / build process for the Race Leaderboard App.
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/04Websocket/README.md:
--------------------------------------------------------------------------------
1 | # To Run This Example do the following
2 |
3 | 1. Run `npm install` from within the `04Websocket` directory to install the nodejs dependencies.
4 | 2. Run `node server.js` from within the `04Websocket` directory to start the websocket server.
5 | 3. Run `elm reactor` from within the `04Websocket`
6 |
--------------------------------------------------------------------------------
/06Ports/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-util": "^3.0.7",
16 | "st": "^1.1.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/04Websocket/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "04Websocket",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "node server.js"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "dateformat": "^1.0.12",
15 | "rx": "^4.1.0",
16 | "ws": "^1.1.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/07RLBStarter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/09RLBLogin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/11RLBLogout/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/07RLBStarter/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/08RLBNavigation/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/09RLBLogin/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/10RLBLoginToken/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/13RLBAddRunner/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/14RLBWebsocket/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/16RLBFilterRunner/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/08RLBNavigation/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/12RLBLockRunnerPage/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/15RLBEstimatedDistance/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/08RLBNavigation/completed/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/13RLBAddRunner/completed/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/14RLBWebsocket/completed/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "clear": "0.0.1",
14 | "gulp": "^3.9.1",
15 | "gulp-livereload": "^3.8.1",
16 | "gutil": "^1.6.4",
17 | "st": "^1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/08RLBNavigation/completed/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/00Review/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | "."
8 | ],
9 | "exposed-modules": [],
10 | "dependencies": {
11 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
12 | "elm-lang/html": "2.0.0 <= v < 3.0.0"
13 | },
14 | "elm-version": "0.18.0 <= v < 0.19.0"
15 | }
16 |
--------------------------------------------------------------------------------
/06Ports/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | "."
8 | ],
9 | "exposed-modules": [],
10 | "dependencies": {
11 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
12 | "elm-lang/html": "2.0.0 <= v < 3.0.0"
13 | },
14 | "elm-version": "0.18.0 <= v < 0.19.0"
15 | }
16 |
--------------------------------------------------------------------------------
/06Ports/completed/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | "."
8 | ],
9 | "exposed-modules": [],
10 | "dependencies": {
11 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
12 | "elm-lang/html": "2.0.0 <= v < 3.0.0"
13 | },
14 | "elm-version": "0.18.0 <= v < 0.19.0"
15 | }
16 |
--------------------------------------------------------------------------------
/01The-Elm-Architecture/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | "."
8 | ],
9 | "exposed-modules": [],
10 | "dependencies": {
11 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
12 | "elm-lang/html": "2.0.0 <= v < 3.0.0"
13 | },
14 | "elm-version": "0.18.0 <= v < 0.19.0"
15 | }
16 |
--------------------------------------------------------------------------------
/07RLBStarter/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
13 | "elm-lang/html": "2.0.0 <= v < 3.0.0"
14 | },
15 | "elm-version": "0.18.0 <= v < 0.19.0"
16 | }
17 |
--------------------------------------------------------------------------------
/02Effects/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | "."
8 | ],
9 | "exposed-modules": [],
10 | "dependencies": {
11 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
12 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
13 | "elm-lang/http": "1.0.0 <= v < 2.0.0"
14 | },
15 | "elm-version": "0.18.0 <= v < 0.19.0"
16 | }
17 |
--------------------------------------------------------------------------------
/04Websocket/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | "."
8 | ],
9 | "exposed-modules": [],
10 | "dependencies": {
11 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
12 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
13 | "elm-lang/websocket": "1.0.2 <= v < 2.0.0"
14 | },
15 | "elm-version": "0.18.0 <= v < 0.19.0"
16 | }
17 |
--------------------------------------------------------------------------------
/05Navigation/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | "."
8 | ],
9 | "exposed-modules": [],
10 | "dependencies": {
11 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
12 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
13 | "elm-lang/navigation": "2.0.0 <= v < 3.0.0"
14 | },
15 | "elm-version": "0.18.0 <= v < 0.19.0"
16 | }
17 |
--------------------------------------------------------------------------------
/08RLBNavigation/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
13 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
14 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0"
15 | },
16 | "elm-version": "0.18.0 <= v < 0.19.0"
17 | }
18 |
--------------------------------------------------------------------------------
/08RLBNavigation/completed/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
13 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
14 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0"
15 | },
16 | "elm-version": "0.18.0 <= v < 0.19.0"
17 | }
18 |
--------------------------------------------------------------------------------
/03JSON/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | "."
8 | ],
9 | "exposed-modules": [],
10 | "dependencies": {
11 | "NoRedInk/elm-decode-pipeline": "3.0.0 <= v < 4.0.0",
12 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
13 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
14 | "elm-lang/http": "1.0.0 <= v < 2.0.0"
15 | },
16 | "elm-version": "0.18.0 <= v < 0.19.0"
17 | }
18 |
--------------------------------------------------------------------------------
/09RLBLogin/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
13 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
14 | "elm-lang/http": "1.0.0 <= v < 2.0.0",
15 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0"
16 | },
17 | "elm-version": "0.18.0 <= v < 0.19.0"
18 | }
19 |
--------------------------------------------------------------------------------
/11RLBLogout/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
13 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
14 | "elm-lang/http": "1.0.0 <= v < 2.0.0",
15 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0"
16 | },
17 | "elm-version": "0.18.0 <= v < 0.19.0"
18 | }
19 |
--------------------------------------------------------------------------------
/13RLBAddRunner/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
13 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
14 | "elm-lang/http": "1.0.0 <= v < 2.0.0",
15 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0"
16 | },
17 | "elm-version": "0.18.0 <= v < 0.19.0"
18 | }
19 |
--------------------------------------------------------------------------------
/10RLBLoginToken/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
13 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
14 | "elm-lang/http": "1.0.0 <= v < 2.0.0",
15 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0"
16 | },
17 | "elm-version": "0.18.0 <= v < 0.19.0"
18 | }
19 |
--------------------------------------------------------------------------------
/12RLBLockRunnerPage/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
13 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
14 | "elm-lang/http": "1.0.0 <= v < 2.0.0",
15 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0"
16 | },
17 | "elm-version": "0.18.0 <= v < 0.19.0"
18 | }
19 |
--------------------------------------------------------------------------------
/13RLBAddRunner/completed/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
13 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
14 | "elm-lang/http": "1.0.0 <= v < 2.0.0",
15 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0"
16 | },
17 | "elm-version": "0.18.0 <= v < 0.19.0"
18 | }
19 |
--------------------------------------------------------------------------------
/10RLBLoginToken/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/14RLBWebsocket/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "NoRedInk/elm-decode-pipeline": "3.0.0 <= v < 4.0.0",
13 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
14 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
15 | "elm-lang/http": "1.0.0 <= v < 2.0.0",
16 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0",
17 | "elm-lang/websocket": "1.0.2 <= v < 2.0.0"
18 | },
19 | "elm-version": "0.18.0 <= v < 0.19.0"
20 | }
21 |
--------------------------------------------------------------------------------
/14RLBWebsocket/completed/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "NoRedInk/elm-decode-pipeline": "3.0.0 <= v < 4.0.0",
13 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
14 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
15 | "elm-lang/http": "1.0.0 <= v < 2.0.0",
16 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0",
17 | "elm-lang/websocket": "1.0.2 <= v < 2.0.0"
18 | },
19 | "elm-version": "0.18.0 <= v < 0.19.0"
20 | }
21 |
--------------------------------------------------------------------------------
/03JSON/SimpleDecoding.elm:
--------------------------------------------------------------------------------
1 | module SimpleDecoding exposing (..)
2 |
3 | import Html exposing (..)
4 | import Json.Decode exposing (..)
5 |
6 |
7 | json : String
8 | json =
9 | """
10 | {
11 | "type":"success",
12 | "value":{
13 | "id":496,
14 | "joke":"Chuck Norris doesnt wear a watch, HE decides what time it is.",
15 | "categories":[
16 | "nerdy"
17 | ]
18 | }
19 | }
20 | """
21 |
22 |
23 | decoder : Decoder String
24 | decoder =
25 | at [ "value", "joke" ] string
26 |
27 |
28 | jokeResult : Result String String
29 | jokeResult =
30 | decodeString decoder json
31 |
32 |
33 | main : Html msg
34 | main =
35 | case jokeResult of
36 | Ok joke ->
37 | text joke
38 |
39 | Err err ->
40 | text err
41 |
--------------------------------------------------------------------------------
/RLBServer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "node server.js"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "bluebird": "^3.4.1",
15 | "dotenv": "^2.0.0",
16 | "joi": "^8.0.5",
17 | "jsonwebtoken": "^6.2.0",
18 | "koa": "^1.2.0",
19 | "koa-body": "^1.4.0",
20 | "koa-cors": "0.0.16",
21 | "koa-router": "^5.4.0",
22 | "koa-websocket": "^1.1.0",
23 | "lodash": "^4.13.1",
24 | "ms": "^0.7.1",
25 | "nedb": "^1.8.0",
26 | "pubsub-js": "^1.5.3",
27 | "random-js": "^1.0.8",
28 | "yargs": "^4.8.1"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/11RLBLogout/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/13RLBAddRunner/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/14RLBWebsocket/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/12RLBLockRunnerPage/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/16RLBFilterRunner/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/13RLBAddRunner/completed/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/14RLBWebsocket/completed/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/15RLBEstimatedDistance/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Race Results
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/16RLBFilterRunner/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "NoRedInk/elm-decode-pipeline": "3.0.0 <= v < 4.0.0",
13 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
14 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
15 | "elm-lang/http": "1.0.0 <= v < 2.0.0",
16 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0",
17 | "elm-lang/websocket": "1.0.2 <= v < 2.0.0",
18 | "rluiten/elm-date-extra": "8.1.2 <= v < 9.0.0"
19 | },
20 | "elm-version": "0.18.0 <= v < 0.19.0"
21 | }
22 |
--------------------------------------------------------------------------------
/15RLBEstimatedDistance/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "summary": "helpful summary of your project, less than 80 characters",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "NoRedInk/elm-decode-pipeline": "3.0.0 <= v < 4.0.0",
13 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
14 | "elm-lang/html": "2.0.0 <= v < 3.0.0",
15 | "elm-lang/http": "1.0.0 <= v < 2.0.0",
16 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0",
17 | "elm-lang/websocket": "1.0.2 <= v < 2.0.0",
18 | "rluiten/elm-date-extra": "8.1.2 <= v < 9.0.0"
19 | },
20 | "elm-version": "0.18.0 <= v < 0.19.0"
21 | }
22 |
--------------------------------------------------------------------------------
/06Ports/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Waitlist App
2 |
3 | ### Setup
4 |
5 | Run the following setup steps
6 |
7 | 1. Run `npm install` to install the build process dependancies
8 | 2. Run `npm install gulp -g` to install the gulp executable globally
9 | 3. Run `elm package install ` to install the elm dependancies
10 |
11 | ### Setup Firebase
12 |
13 | 1. Create an account on firebase and create a new database
14 | 2. Add The following temporary rules to your firebase database
15 |
16 | ```json
17 | {
18 | "rules": {
19 | ".read": true,
20 | ".write": true
21 | }
22 | }
23 | ```
24 |
25 | 3. Update the `appfb.js` file with your new firebase API keys, found here (replace YOURFIREBASEDBHERE, then click Add Firebase to your web app) https://console.firebase.google.com/project/YOURFIREBASEDBHERE/settings/general/
26 |
27 | ### Start Build Process
28 |
29 | 1. Run `gulp` to start the build process
30 |
--------------------------------------------------------------------------------
/06Ports/completed/appfb.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | // Initialize Firebase
3 | // var config = {
4 | // apiKey: "YOURAPIKEYHERE",
5 | // authDomain: "YOURAUTHDOMAINHERE",
6 | // databaseURL: "YOURURLHERE",
7 | // storageBucket: "",
8 | // };
9 |
10 | var app = firebase.initializeApp(config);
11 | var database = app.database();
12 | var CUSTOMERREFPATH = "customers"
13 |
14 | function addCustomer(customer){
15 | var promise = database
16 | .ref(CUSTOMERREFPATH)
17 | .push(customer);
18 | return promise;
19 | }
20 |
21 | function updateCustomer(customer){
22 | var id = customer.id;
23 | var promise = database
24 | .ref(CUSTOMERREFPATH + "/" + id)
25 | .set(customer);
26 | return promise;
27 | }
28 |
29 | function deleteCustomer(customer){
30 | var id = customer.id;
31 | var promise = database
32 | .ref(CUSTOMERREFPATH + "/" + id)
33 | .remove();
34 | return promise;
35 | }
36 |
37 | function customerListener(){
38 | return database.ref(CUSTOMERREFPATH);
39 | }
40 |
--------------------------------------------------------------------------------
/06Ports/appfb.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | // Initialize Firebase
3 | // var config = {
4 | // apiKey: "YOURAPIKEYHERE",
5 | // authDomain: "YOURAUTHDOMAINHERE",
6 | // databaseURL: "YOURURLHERE",
7 | // storageBucket: "",
8 | // };
9 |
10 | alert('Add firebase config, see README.md! (then remove this)');
11 | var app = firebase.initializeApp(config);
12 | var database = app.database();
13 | var CUSTOMERREFPATH = "customers"
14 |
15 | function addCustomer(customer){
16 | var promise = database
17 | .ref(CUSTOMERREFPATH)
18 | .push(customer);
19 | return promise;
20 | }
21 |
22 | function updateCustomer(customer){
23 | var id = customer.id;
24 | var promise = database
25 | .ref(CUSTOMERREFPATH + "/" + id)
26 | .set(customer);
27 | return promise;
28 | }
29 |
30 | function deleteCustomer(customer){
31 | var id = customer.id;
32 | var promise = database
33 | .ref(CUSTOMERREFPATH + "/" + id)
34 | .remove();
35 | return promise;
36 | }
37 |
38 | function customerListener(){
39 | return database.ref(CUSTOMERREFPATH);
40 | }
41 |
--------------------------------------------------------------------------------
/RLBServer/README.md:
--------------------------------------------------------------------------------
1 | # Node Server
2 |
3 | ## Setup
4 |
5 | 1. Install Recent Version of **Nodejs** by downloading and running the installer found at https://nodejs.org/en/ or use the Node Version Manager found at https://github.com/creationix/nvm
6 | 2. Install Nodejs dependancies by keying `npm install` from within this directory
7 |
8 | ## Starting Server
9 |
10 | The server can be started by keying `node server.js`
11 |
12 | ## Where's the data stored?
13 |
14 | The runner records are saved into `local.db` file, via [nedb](https://github.com/louischatriot/nedb). You can manually edit/delete this file and restart the server.
15 |
16 | ## Where's the username and password?
17 |
18 | The app isn't doing real auth... The username and password is stored in the `user` file and it's loaded using [dotenv](https://github.com/motdotla/dotenv)
19 |
20 | ## Bugs
21 |
22 | Yes, there are bugs in the app... Covering every edge case scenario wouldn't make for a good training videos.. We'd have to go off on too many tangents (edge cases), which would be distracting from the main content.
23 |
--------------------------------------------------------------------------------
/04Websocket/server.js:
--------------------------------------------------------------------------------
1 | const WebSocketServer = require('ws').Server;
2 | const Rx = require('rx');
3 | const dateFormat = require('dateformat');
4 |
5 | const server = new WebSocketServer({ port: 5000 });
6 |
7 | server.on('connection', function connection(ws) {
8 | console.log('client connected!')
9 | const pauser = new Rx.Subject();
10 | Rx.Observable
11 | .interval( 1000 )
12 | .timeInterval()
13 | .map( x => new Date)
14 | .map( now => dateFormat(now, "h:MM:ss TT") )
15 | .pausable( pauser )
16 | .subscribe( ( time ) => {
17 | if (ws.readyState === ws.OPEN){
18 | ws.send(JSON.stringify({time}));
19 | }
20 | else if (ws.readyState === ws.CLOSED) {
21 | pauser.onNext(false);
22 | }
23 | }
24 | );
25 | ws.on('message', ( message ) => {
26 | if ( message === "start" ){
27 | pauser.onNext(true);
28 | }
29 | else if ( message === "stop" ) {
30 | pauser.onNext(false);
31 | }
32 | });
33 | ws.on('close', ( ) => {
34 | console.log('client disconnected!');
35 | })
36 |
37 | });
--------------------------------------------------------------------------------
/06Ports/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./Main.elm --output ./bundle.js';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname ,
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/01The-Elm-Architecture/LeaderBoard.elm:
--------------------------------------------------------------------------------
1 | module LeaderBoard exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { runners : List Runner
13 | , query : String
14 | }
15 |
16 |
17 | type alias Runner =
18 | { id : Int
19 | , name : String
20 | , location : String
21 | }
22 |
23 |
24 | initModel : Model
25 | initModel =
26 | { runners = []
27 | , query = ""
28 | }
29 |
30 |
31 |
32 | -- update
33 |
34 |
35 | type Msg
36 | = QueryInput String
37 |
38 |
39 | update : Msg -> Model -> Model
40 | update msg model =
41 | case msg of
42 | QueryInput query ->
43 | { model | query = query }
44 |
45 |
46 |
47 | -- view
48 |
49 |
50 | view : Model -> Html Msg
51 | view model =
52 | div []
53 | [ h3 [] [ text "Leaderboard page... So far" ]
54 | , input
55 | [ type_ "text"
56 | , onInput QueryInput
57 | , value model.query
58 | , placeholder "Search for a runner..."
59 | ]
60 | []
61 | ]
62 |
--------------------------------------------------------------------------------
/06Ports/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Ports - Customer List
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/06Ports/completed/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./Main.elm --output ./bundle.js';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname ,
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/07RLBStarter/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/08RLBNavigation/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/09RLBLogin/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js --debug';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/11RLBLogout/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js --debug';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/08RLBNavigation/completed/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/10RLBLoginToken/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js --debug';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/13RLBAddRunner/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js --debug';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/14RLBWebsocket/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js --debug';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/16RLBFilterRunner/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js --debug';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/12RLBLockRunnerPage/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js --debug';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/15RLBEstimatedDistance/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js --debug';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/13RLBAddRunner/completed/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js --debug';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/14RLBWebsocket/completed/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | http = require('http'),
5 | st = require('st'),
6 | exec = require('child_process').exec,
7 | gutil = require('gulp-util'),
8 | clear = require('clear'),
9 | counter = 0;
10 |
11 | var cmd = 'elm make ./src/Main.elm --output ./dist/bundle.js --debug';
12 | clear();
13 | gulp.task('default', ['server', 'watch', 'elm']);
14 |
15 | gulp.task('watch', function(cb) {
16 | gulp.watch('**/*.elm', ['elm']);
17 | });
18 |
19 | gulp.task('server', function(done) {
20 | gutil.log(gutil.colors.blue('Starting server at http://localhost:4000'));
21 | http.createServer(
22 | st({
23 | path: __dirname + '/dist/',
24 | index: 'index.html',
25 | cache: false
26 | })
27 | ).listen(4000, done);
28 | });
29 |
30 | gulp.task('elm', function(cb) {
31 | if (counter > 0){
32 | clear();
33 | }
34 | exec(cmd, function(err, stdout, stderr) {
35 | if (err){
36 | gutil.log(gutil.colors.red('elm make: '),gutil.colors.red(stderr));
37 | } else {
38 | gutil.log(gutil.colors.green('elm make: '), gutil.colors.green(stdout));
39 | }
40 | cb();
41 | });
42 | counter++;
43 | });
44 |
--------------------------------------------------------------------------------
/01The-Elm-Architecture/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { username : String
13 | , password : String
14 | }
15 |
16 |
17 | initModel : Model
18 | initModel =
19 | { username = ""
20 | , password = ""
21 | }
22 |
23 |
24 |
25 | -- update
26 |
27 |
28 | type Msg
29 | = UsernameInput String
30 | | PasswordInput String
31 |
32 |
33 | update : Msg -> Model -> Model
34 | update msg model =
35 | case msg of
36 | UsernameInput username ->
37 | { model | username = username }
38 |
39 | PasswordInput password ->
40 | { model | password = password }
41 |
42 |
43 |
44 | -- view
45 |
46 |
47 | view : Model -> Html Msg
48 | view model =
49 | div []
50 | [ h3 [] [ text "Login Page... So far" ]
51 | , Html.form []
52 | [ input
53 | [ type_ "text"
54 | , onInput UsernameInput
55 | , placeholder "username"
56 | ]
57 | []
58 | , input
59 | [ type_ "password"
60 | , onInput PasswordInput
61 | , placeholder "password"
62 | ]
63 | []
64 | ]
65 | ]
66 |
--------------------------------------------------------------------------------
/02Effects/Main.elm:
--------------------------------------------------------------------------------
1 | module Main exposing (..)
2 |
3 | import Html exposing (..)
4 | import Http
5 |
6 |
7 | -- model
8 |
9 |
10 | type alias Model =
11 | String
12 |
13 |
14 | initModel : Model
15 | initModel =
16 | "Finding a joke..."
17 |
18 |
19 | init : ( Model, Cmd Msg )
20 | init =
21 | ( initModel, randomJoke )
22 |
23 |
24 | randomJoke : Cmd Msg
25 | randomJoke =
26 | let
27 | url =
28 | "http://api.icndb.com/jokes/random"
29 |
30 | request =
31 | Http.getString url
32 |
33 | cmd =
34 | Http.send Joke request
35 | in
36 | cmd
37 |
38 |
39 |
40 | -- update
41 |
42 |
43 | type Msg
44 | = Joke (Result Http.Error String)
45 |
46 |
47 | update : Msg -> Model -> ( Model, Cmd Msg )
48 | update msg model =
49 | case msg of
50 | Joke (Ok joke) ->
51 | ( joke, Cmd.none )
52 |
53 | Joke (Err err) ->
54 | ( (toString err), Cmd.none )
55 |
56 |
57 |
58 | -- view
59 |
60 |
61 | view : Model -> Html Msg
62 | view model =
63 | div [] [ text model ]
64 |
65 |
66 |
67 | -- subscription
68 |
69 |
70 | subscriptions : Model -> Sub Msg
71 | subscriptions model =
72 | Sub.none
73 |
74 |
75 | main : Program Never Model Msg
76 | main =
77 | Html.program
78 | { init = init
79 | , update = update
80 | , view = view
81 | , subscriptions = subscriptions
82 | }
83 |
--------------------------------------------------------------------------------
/06Ports/completed/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Ports - Customer List
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Elm Beyond The Basics
2 | This repo is the source companion to the following course on Learning Elmlang:
3 | http://courses.knowthen.com/courses/elm-beyond-the-basics
4 |
5 | This course teaches the new [Elmlang](http://elm-lang.org/) developer who knows how to make basic apps that just run in the browser, how to make more apps.
6 |
7 | ## Updated to Elm 0.18
8 |
9 | #### Why you should take this course?
10 |
11 | Elm is an amazing language that offers many benefits like:
12 |
13 | * Zero Runtime Exceptions
14 | * Simplified Debugging
15 | * Easy Refactoring
16 | * An Amazingly helpful type system
17 | * Improved Productivity
18 | * Inherently Testable Code
19 | * Enforced Semantic Versioning
20 | * and much more...
21 |
22 | This course will teach you more advanced concepts like:
23 |
24 | * The Elm Architecture
25 | * Effects (HTTP / Websocket)
26 | * JSON Encoding and Decoding
27 | * Single Page App Navigation (Routing)
28 | * Talking to JavaScript using Ports
29 | * and much more...
30 |
31 | #### Why this course?
32 |
33 | Do you ever feel overwhelmed with new technologies? I think most of us do, there is so much change constantly happening and the pace of change seems to be increasing.
34 |
35 | What can you do to manage the learning challenges facing software developers?
36 |
37 | #### Lean learning
38 |
39 | I don't want to waste your time, so you'll learn just what you need to know as quickly as possible. You'll start this course with the end in mind. What do I mean by that? We're going to be building a web application, and you'll learn just what you need to build the app.
40 |
--------------------------------------------------------------------------------
/00Review/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { username : String
13 | , password : String
14 | }
15 |
16 |
17 | initModel : Model
18 | initModel =
19 | { username = ""
20 | , password = ""
21 | }
22 |
23 |
24 |
25 | -- update
26 |
27 |
28 | type Msg
29 | = UsernameInput String
30 | | PasswordInput String
31 |
32 |
33 | update : Msg -> Model -> Model
34 | update msg model =
35 | case msg of
36 | UsernameInput username ->
37 | { model | username = username }
38 |
39 | PasswordInput password ->
40 | { model | password = password }
41 |
42 |
43 |
44 | -- view
45 |
46 |
47 | view : Model -> Html Msg
48 | view model =
49 | div []
50 | [ h3 [] [ text "Login Page... So far" ]
51 | , Html.form []
52 | [ input
53 | [ type_ "text"
54 | , onInput UsernameInput
55 | , placeholder "username"
56 | ]
57 | []
58 | , input
59 | [ type_ "password"
60 | , onInput PasswordInput
61 | , placeholder "password"
62 | ]
63 | []
64 | , input [ type_ "submit" ]
65 | [ text "Login" ]
66 | ]
67 | ]
68 |
69 |
70 | main : Program Never Model Msg
71 | main =
72 | Html.beginnerProgram
73 | { model = initModel
74 | , update = update
75 | , view = view
76 | }
77 |
--------------------------------------------------------------------------------
/02Effects/Completed.elm:
--------------------------------------------------------------------------------
1 | module Completed exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Http
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | String
13 |
14 |
15 | initModel : Model
16 | initModel =
17 | "Finding a joke..."
18 |
19 |
20 | init : ( Model, Cmd Msg )
21 | init =
22 | ( initModel, randomJoke )
23 |
24 |
25 | randomJoke : Cmd Msg
26 | randomJoke =
27 | let
28 | url =
29 | "http://api.icndb.com/jokes/random"
30 |
31 | request =
32 | Http.getString url
33 |
34 | cmd =
35 | Http.send Joke request
36 | in
37 | cmd
38 |
39 |
40 |
41 | -- update
42 |
43 |
44 | type Msg
45 | = Joke (Result Http.Error String)
46 | | NewJoke
47 |
48 |
49 | update : Msg -> Model -> ( Model, Cmd Msg )
50 | update msg model =
51 | case msg of
52 | Joke (Ok joke) ->
53 | ( joke, Cmd.none )
54 |
55 | Joke (Err err) ->
56 | ( (toString err), Cmd.none )
57 |
58 | NewJoke ->
59 | ( "fetching joke ...", randomJoke )
60 |
61 |
62 |
63 | -- view
64 |
65 |
66 | view : Model -> Html Msg
67 | view model =
68 | div []
69 | [ button [ onClick NewJoke ] [ text "Fetch a Joke" ]
70 | , br [] []
71 | , text model
72 | ]
73 |
74 |
75 |
76 | -- subscription
77 |
78 |
79 | subscriptions : Model -> Sub Msg
80 | subscriptions model =
81 | Sub.none
82 |
83 |
84 | main : Program Never Model Msg
85 | main =
86 | Html.program
87 | { init = init
88 | , update = update
89 | , view = view
90 | , subscriptions = subscriptions
91 | }
92 |
--------------------------------------------------------------------------------
/07RLBStarter/src/Main.elm:
--------------------------------------------------------------------------------
1 | port module Main exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Attributes exposing (..)
5 |
6 |
7 | -- model
8 |
9 |
10 | type alias Model =
11 | { page : Page
12 | }
13 |
14 |
15 | type Page
16 | = NotFound
17 |
18 |
19 | initModel : Model
20 | initModel =
21 | { page = NotFound }
22 |
23 |
24 | init : ( Model, Cmd Msg )
25 | init =
26 | ( initModel, Cmd.none )
27 |
28 |
29 |
30 | -- update
31 |
32 |
33 | type Msg
34 | = Navigate Page
35 |
36 |
37 | update : Msg -> Model -> ( Model, Cmd Msg )
38 | update msg model =
39 | case msg of
40 | Navigate page ->
41 | ( { model | page = page }, Cmd.none )
42 |
43 |
44 |
45 | -- view
46 |
47 |
48 | view : Model -> Html Msg
49 | view model =
50 | let
51 | page =
52 | case model.page of
53 | NotFound ->
54 | div [ class "main" ]
55 | [ h1 []
56 | [ text "Page Not Found!" ]
57 | ]
58 | in
59 | div []
60 | [ pageHeader model
61 | , page
62 | ]
63 |
64 |
65 | pageHeader : Model -> Html Msg
66 | pageHeader model =
67 | header []
68 | [ a [ href "#/" ] [ text "Race Results" ]
69 | , ul []
70 | [ li []
71 | [ a [ href "#" ] [ text "Link" ]
72 | ]
73 | ]
74 | , ul []
75 | [ li []
76 | [ a [ href "#" ] [ text "Login" ]
77 | ]
78 | ]
79 | ]
80 |
81 |
82 |
83 | -- subscriptions
84 |
85 |
86 | subscriptions : Model -> Sub Msg
87 | subscriptions model =
88 | Sub.none
89 |
90 |
91 | main : Program Never Model Msg
92 | main =
93 | Html.program
94 | { init = init
95 | , update = update
96 | , view = view
97 | , subscriptions = subscriptions
98 | }
99 |
--------------------------------------------------------------------------------
/04Websocket/Main.elm:
--------------------------------------------------------------------------------
1 | module Main exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import WebSocket exposing (..)
6 | import Json.Decode exposing (..)
7 |
8 |
9 | -- model
10 |
11 |
12 | type alias Model =
13 | { streamTime : Bool
14 | , time : String
15 | }
16 |
17 |
18 | initModel : Model
19 | initModel =
20 | { streamTime = False
21 | , time = ""
22 | }
23 |
24 |
25 | init : ( Model, Cmd Msg )
26 | init =
27 | ( initModel, Cmd.none )
28 |
29 |
30 |
31 | -- update
32 |
33 |
34 | type Msg
35 | = ToggleStreaming
36 | | Time String
37 |
38 |
39 | update : Msg -> Model -> ( Model, Cmd Msg )
40 | update msg model =
41 | case msg of
42 | ToggleStreaming ->
43 | let
44 | newModel =
45 | { model | streamTime = not model.streamTime }
46 |
47 | msg =
48 | if newModel.streamTime then
49 | "start"
50 | else
51 | "stop"
52 |
53 | cmd =
54 | send wsUrl msg
55 | in
56 | ( newModel, cmd )
57 |
58 | Time time ->
59 | ( { model | time = time }, Cmd.none )
60 |
61 |
62 |
63 | -- view
64 |
65 |
66 | view : Model -> Html Msg
67 | view model =
68 | let
69 | toggleLabel =
70 | if model.streamTime then
71 | "Stop"
72 | else
73 | "Start"
74 | in
75 | div []
76 | [ button [ onClick ToggleStreaming ] [ text toggleLabel ]
77 | , br [] []
78 | , text model.time
79 | ]
80 |
81 |
82 |
83 | -- subscription
84 |
85 |
86 | wsUrl : String
87 | wsUrl =
88 | "ws://localhost:5000"
89 |
90 |
91 | decodeTime : String -> Msg
92 | decodeTime message =
93 | decodeString (at [ "time" ] string) message
94 | |> Result.withDefault "Error Decoding Time"
95 | |> Time
96 |
97 |
98 | subscriptions : Model -> Sub Msg
99 | subscriptions model =
100 | -- Sub.none
101 | if model.streamTime then
102 | listen wsUrl decodeTime
103 | else
104 | Sub.none
105 |
106 |
107 | main : Program Never Model Msg
108 | main =
109 | Html.program
110 | { init = init
111 | , update = update
112 | , view = view
113 | , subscriptions = subscriptions
114 | }
115 |
--------------------------------------------------------------------------------
/01The-Elm-Architecture/Main.elm:
--------------------------------------------------------------------------------
1 | module Main exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Login
7 | import LeaderBoard
8 |
9 |
10 | -- model
11 |
12 |
13 | type alias Model =
14 | { page : Page
15 | , leaderBoard : LeaderBoard.Model
16 | , login : Login.Model
17 | }
18 |
19 |
20 | initModel : Model
21 | initModel =
22 | { page = LeaderBoardPage
23 | , login = Login.initModel
24 | , leaderBoard = LeaderBoard.initModel
25 | }
26 |
27 |
28 | type Page
29 | = LeaderBoardPage
30 | | LoginPage
31 |
32 |
33 |
34 | -- update
35 |
36 |
37 | type Msg
38 | = ChangePage Page
39 | | LeaderBoardMsg LeaderBoard.Msg
40 | | LoginMsg Login.Msg
41 |
42 |
43 | update : Msg -> Model -> Model
44 | update msg model =
45 | case msg of
46 | ChangePage page ->
47 | { model
48 | | page = page
49 | }
50 |
51 | LeaderBoardMsg lbMsg ->
52 | { model
53 | | leaderBoard =
54 | LeaderBoard.update lbMsg model.leaderBoard
55 | }
56 |
57 | LoginMsg loginMsg ->
58 | { model
59 | | login =
60 | Login.update loginMsg model.login
61 | }
62 |
63 |
64 |
65 | -- view
66 |
67 |
68 | view : Model -> Html Msg
69 | view model =
70 | let
71 | page =
72 | case model.page of
73 | LeaderBoardPage ->
74 | Html.map LeaderBoardMsg
75 | (LeaderBoard.view model.leaderBoard)
76 |
77 | LoginPage ->
78 | Html.map LoginMsg
79 | (Login.view model.login)
80 | in
81 | div []
82 | [ div []
83 | [ a
84 | [ href "#"
85 | , onClick (ChangePage LeaderBoardPage)
86 | ]
87 | [ text "LeaderBoard" ]
88 | , span [] [ text " | " ]
89 | , a
90 | [ href "#"
91 | , onClick (ChangePage LoginPage)
92 | ]
93 | [ text "Login" ]
94 | ]
95 | , hr [] []
96 | , page
97 | ]
98 |
99 |
100 | main : Program Never Model Msg
101 | main =
102 | Html.beginnerProgram
103 | { model = initModel
104 | , update = update
105 | , view = view
106 | }
107 |
--------------------------------------------------------------------------------
/03JSON/Main.elm:
--------------------------------------------------------------------------------
1 | module Main exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Http
6 | import Json.Decode exposing (..)
7 | import Json.Decode.Pipeline exposing (decode, required, optional)
8 |
9 |
10 | type alias Response =
11 | { id : Int
12 | , joke : String
13 | , categories : List String
14 | }
15 |
16 |
17 |
18 | -- model
19 |
20 |
21 | type alias Model =
22 | String
23 |
24 |
25 | initModel : Model
26 | initModel =
27 | "Finding a joke..."
28 |
29 |
30 | init : ( Model, Cmd Msg )
31 | init =
32 | ( initModel, randomJoke )
33 |
34 |
35 |
36 | -- responseDecoder : Decoder Response
37 | -- responseDecoder =
38 | -- map3 Response
39 | -- (field "id" int)
40 | -- (field "joke" string)
41 | -- (field "categories" (list string))
42 | -- |> at [ "value" ]
43 |
44 |
45 | responseDecoder : Decoder Response
46 | responseDecoder =
47 | decode Response
48 | |> required "id" int
49 | |> required "joke" string
50 | |> optional "categories" (list string) []
51 | |> at [ "value" ]
52 |
53 |
54 | randomJoke : Cmd Msg
55 | randomJoke =
56 | let
57 | url =
58 | "http://api.icndb.com/jokes/random"
59 |
60 | request =
61 | -- Http.getString url
62 | Http.get url responseDecoder
63 |
64 | cmd =
65 | Http.send Joke request
66 | in
67 | cmd
68 |
69 |
70 |
71 | -- update
72 |
73 |
74 | type Msg
75 | = Joke (Result Http.Error Response)
76 | | NewJoke
77 |
78 |
79 | update : Msg -> Model -> ( Model, Cmd Msg )
80 | update msg model =
81 | case msg of
82 | Joke (Ok response) ->
83 | ( toString (response.id) ++ " " ++ response.joke, Cmd.none )
84 |
85 | Joke (Err err) ->
86 | ( (toString err), Cmd.none )
87 |
88 | NewJoke ->
89 | ( "fetching joke ...", randomJoke )
90 |
91 |
92 |
93 | -- view
94 |
95 |
96 | view : Model -> Html Msg
97 | view model =
98 | div []
99 | [ button [ onClick NewJoke ] [ text "Fetch a Joke" ]
100 | , br [] []
101 | , text model
102 | ]
103 |
104 |
105 |
106 | -- subscription
107 |
108 |
109 | subscriptions : Model -> Sub Msg
110 | subscriptions model =
111 | Sub.none
112 |
113 |
114 | main : Program Never Model Msg
115 | main =
116 | Html.program
117 | { init = init
118 | , update = update
119 | , view = view
120 | , subscriptions = subscriptions
121 | }
122 |
--------------------------------------------------------------------------------
/07RLBStarter/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { username : String
13 | , password : String
14 | , error : Maybe String
15 | }
16 |
17 |
18 | initModel : Model
19 | initModel =
20 | { username = ""
21 | , password = ""
22 | , error = Nothing
23 | }
24 |
25 |
26 | init : ( Model, Cmd Msg )
27 | init =
28 | ( initModel, Cmd.none )
29 |
30 |
31 |
32 | -- update
33 |
34 |
35 | type Msg
36 | = UsernameInput String
37 | | PasswordInput String
38 | | Submit
39 | | Error String
40 |
41 |
42 | update : Msg -> Model -> ( Model, Cmd Msg )
43 | update msg model =
44 | case msg of
45 | UsernameInput username ->
46 | ( { model | username = username }, Cmd.none )
47 |
48 | PasswordInput password ->
49 | ( { model | password = password }, Cmd.none )
50 |
51 | Submit ->
52 | ( model, Cmd.none )
53 |
54 | Error error ->
55 | ( { model | error = Just error }, Cmd.none )
56 |
57 |
58 |
59 | -- view
60 |
61 |
62 | view : Model -> Html Msg
63 | view model =
64 | div [ class "main" ]
65 | [ errorPanel model.error
66 | , loginForm model
67 | ]
68 |
69 |
70 | loginForm : Model -> Html Msg
71 | loginForm model =
72 | Html.form [ class "add-runner", onSubmit Submit ]
73 | [ fieldset []
74 | [ legend [] [ text "Login" ]
75 | , div []
76 | [ label [] [ text "User Name" ]
77 | , input
78 | [ type_ "text"
79 | , value model.username
80 | , onInput UsernameInput
81 | ]
82 | []
83 | ]
84 | , div []
85 | [ label [] [ text "Password" ]
86 | , input
87 | [ type_ "password"
88 | , value model.password
89 | , onInput PasswordInput
90 | ]
91 | []
92 | ]
93 | , div []
94 | [ label [] []
95 | , button [ type_ "submit" ] [ text "Login" ]
96 | ]
97 | ]
98 | ]
99 |
100 |
101 | errorPanel : Maybe String -> Html a
102 | errorPanel error =
103 | case error of
104 | Nothing ->
105 | text ""
106 |
107 | Just msg ->
108 | div [ class "error" ]
109 | [ text msg ]
110 |
111 |
112 | subscriptions : Model -> Sub Msg
113 | subscriptions model =
114 | Sub.none
115 |
--------------------------------------------------------------------------------
/08RLBNavigation/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { username : String
13 | , password : String
14 | , error : Maybe String
15 | }
16 |
17 |
18 | initModel : Model
19 | initModel =
20 | { username = ""
21 | , password = ""
22 | , error = Nothing
23 | }
24 |
25 |
26 | init : ( Model, Cmd Msg )
27 | init =
28 | ( initModel, Cmd.none )
29 |
30 |
31 |
32 | -- update
33 |
34 |
35 | type Msg
36 | = UsernameInput String
37 | | PasswordInput String
38 | | Submit
39 | | Error String
40 |
41 |
42 | update : Msg -> Model -> ( Model, Cmd Msg )
43 | update msg model =
44 | case msg of
45 | UsernameInput username ->
46 | ( { model | username = username }, Cmd.none )
47 |
48 | PasswordInput password ->
49 | ( { model | password = password }, Cmd.none )
50 |
51 | Submit ->
52 | ( model, Cmd.none )
53 |
54 | Error error ->
55 | ( { model | error = Just error }, Cmd.none )
56 |
57 |
58 |
59 | -- view
60 |
61 |
62 | view : Model -> Html Msg
63 | view model =
64 | div [ class "main" ]
65 | [ errorPanel model.error
66 | , loginForm model
67 | ]
68 |
69 |
70 | loginForm : Model -> Html Msg
71 | loginForm model =
72 | Html.form [ class "add-runner", onSubmit Submit ]
73 | [ fieldset []
74 | [ legend [] [ text "Login" ]
75 | , div []
76 | [ label [] [ text "User Name" ]
77 | , input
78 | [ type_ "text"
79 | , value model.username
80 | , onInput UsernameInput
81 | ]
82 | []
83 | ]
84 | , div []
85 | [ label [] [ text "Password" ]
86 | , input
87 | [ type_ "password"
88 | , value model.password
89 | , onInput PasswordInput
90 | ]
91 | []
92 | ]
93 | , div []
94 | [ label [] []
95 | , button [ type_ "submit" ] [ text "Login" ]
96 | ]
97 | ]
98 | ]
99 |
100 |
101 | errorPanel : Maybe String -> Html a
102 | errorPanel error =
103 | case error of
104 | Nothing ->
105 | text ""
106 |
107 | Just msg ->
108 | div [ class "error" ]
109 | [ text msg ]
110 |
111 |
112 | subscriptions : Model -> Sub Msg
113 | subscriptions model =
114 | Sub.none
115 |
--------------------------------------------------------------------------------
/08RLBNavigation/completed/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { username : String
13 | , password : String
14 | , error : Maybe String
15 | }
16 |
17 |
18 | initModel : Model
19 | initModel =
20 | { username = ""
21 | , password = ""
22 | , error = Nothing
23 | }
24 |
25 |
26 | init : ( Model, Cmd Msg )
27 | init =
28 | ( initModel, Cmd.none )
29 |
30 |
31 |
32 | -- update
33 |
34 |
35 | type Msg
36 | = UsernameInput String
37 | | PasswordInput String
38 | | Submit
39 | | Error String
40 |
41 |
42 | update : Msg -> Model -> ( Model, Cmd Msg )
43 | update msg model =
44 | case msg of
45 | UsernameInput username ->
46 | ( { model | username = username }, Cmd.none )
47 |
48 | PasswordInput password ->
49 | ( { model | password = password }, Cmd.none )
50 |
51 | Submit ->
52 | ( model, Cmd.none )
53 |
54 | Error error ->
55 | ( { model | error = Just error }, Cmd.none )
56 |
57 |
58 |
59 | -- view
60 |
61 |
62 | view : Model -> Html Msg
63 | view model =
64 | div [ class "main" ]
65 | [ errorPanel model.error
66 | , loginForm model
67 | ]
68 |
69 |
70 | loginForm : Model -> Html Msg
71 | loginForm model =
72 | Html.form [ class "add-runner", onSubmit Submit ]
73 | [ fieldset []
74 | [ legend [] [ text "Login" ]
75 | , div []
76 | [ label [] [ text "User Name" ]
77 | , input
78 | [ type_ "text"
79 | , value model.username
80 | , onInput UsernameInput
81 | ]
82 | []
83 | ]
84 | , div []
85 | [ label [] [ text "Password" ]
86 | , input
87 | [ type_ "password"
88 | , value model.password
89 | , onInput PasswordInput
90 | ]
91 | []
92 | ]
93 | , div []
94 | [ label [] []
95 | , button [ type_ "submit" ] [ text "Login" ]
96 | ]
97 | ]
98 | ]
99 |
100 |
101 | errorPanel : Maybe String -> Html a
102 | errorPanel error =
103 | case error of
104 | Nothing ->
105 | text ""
106 |
107 | Just msg ->
108 | div [ class "error" ]
109 | [ text msg ]
110 |
111 |
112 | subscriptions : Model -> Sub Msg
113 | subscriptions model =
114 | Sub.none
115 |
--------------------------------------------------------------------------------
/06Ports/Main.elm:
--------------------------------------------------------------------------------
1 | port module Main exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Customer =
12 | { id : String
13 | , name : String
14 | }
15 |
16 |
17 | type alias Model =
18 | { name : String
19 | , customers : List Customer
20 | , error : Maybe String
21 | , nextId : Int
22 | }
23 |
24 |
25 | initModel : Model
26 | initModel =
27 | { name = ""
28 | , customers = []
29 | , error = Nothing
30 | , nextId = 1
31 | }
32 |
33 |
34 | init : ( Model, Cmd Msg )
35 | init =
36 | ( initModel, Cmd.none )
37 |
38 |
39 |
40 | -- update
41 |
42 |
43 | type Msg
44 | = NameInput String
45 | | SaveCustomer
46 | | CustomerSaved String
47 | | CustomerAdded Customer
48 |
49 |
50 | update : Msg -> Model -> ( Model, Cmd Msg )
51 | update msg model =
52 | case msg of
53 | NameInput name ->
54 | ( { model | name = name }, Cmd.none )
55 |
56 | SaveCustomer ->
57 | ( model, addCustomer model.name )
58 |
59 | CustomerSaved key ->
60 | ( { model | name = "" }, Cmd.none )
61 |
62 | CustomerAdded customer ->
63 | let
64 | newCustomers =
65 | customer :: model.customers
66 | in
67 | ( { model | customers = newCustomers }, Cmd.none )
68 |
69 |
70 |
71 | -- view
72 |
73 |
74 | viewCustomer : Customer -> Html Msg
75 | viewCustomer customer =
76 | li []
77 | [ i [ class "remove" ] []
78 | , text customer.name
79 | ]
80 |
81 |
82 | viewCustomers : List Customer -> Html Msg
83 | viewCustomers customers =
84 | customers
85 | |> List.sortBy .id
86 | |> List.map viewCustomer
87 | |> ul []
88 |
89 |
90 | viewCustomerForm : Model -> Html Msg
91 | viewCustomerForm model =
92 | Html.form [ onSubmit SaveCustomer ]
93 | [ input [ type_ "text", onInput NameInput, value model.name ] []
94 | , text <| Maybe.withDefault "" model.error
95 | , button [ type_ "submit" ] [ text "Save" ]
96 | ]
97 |
98 |
99 | view : Model -> Html Msg
100 | view model =
101 | div []
102 | [ h1 [] [ text "Customer List" ]
103 | , viewCustomerForm model
104 | , viewCustomers model.customers
105 | ]
106 |
107 |
108 |
109 | -- subscription
110 |
111 |
112 | subscriptions : Model -> Sub Msg
113 | subscriptions model =
114 | -- Sub.none
115 | Sub.batch
116 | [ customerSaved CustomerSaved
117 | , newCustomer CustomerAdded
118 | ]
119 |
120 |
121 | port addCustomer : String -> Cmd msg
122 |
123 |
124 | port customerSaved : (String -> msg) -> Sub msg
125 |
126 |
127 | port newCustomer : (Customer -> msg) -> Sub msg
128 |
129 |
130 | main : Program Never Model Msg
131 | main =
132 | Html.program
133 | { init = init
134 | , update = update
135 | , view = view
136 | , subscriptions = subscriptions
137 | }
138 |
--------------------------------------------------------------------------------
/05Navigation/Main.elm:
--------------------------------------------------------------------------------
1 | module Main exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Navigation exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type Page
12 | = LeaderBoard
13 | | AddRunner
14 | | Login
15 | | NotFound
16 |
17 |
18 | type alias Model =
19 | { page : Page
20 | }
21 |
22 |
23 | initModel : Page -> Model
24 | initModel page =
25 | { page = page
26 | }
27 |
28 |
29 | init : Location -> ( Model, Cmd Msg )
30 | init location =
31 | let
32 | page =
33 | hashToPage location.hash
34 | in
35 | ( initModel page, Cmd.none )
36 |
37 |
38 |
39 | -- update
40 |
41 |
42 | type Msg
43 | = Navigate Page
44 | | ChangePage Page
45 |
46 |
47 | update : Msg -> Model -> ( Model, Cmd Msg )
48 | update msg model =
49 | case msg of
50 | Navigate page ->
51 | ( model, newUrl <| pageToHash page )
52 |
53 | ChangePage page ->
54 | ( { model | page = page }, Cmd.none )
55 |
56 |
57 |
58 | -- view
59 |
60 |
61 | menu : Model -> Html Msg
62 | menu model =
63 | header []
64 | [ a [ onClick (Navigate LeaderBoard) ]
65 | [ text "LeaderBoard" ]
66 | , text " | "
67 | , a [ onClick (Navigate AddRunner) ]
68 | [ text "Add Runner" ]
69 | , text " | "
70 | , a [ onClick (Navigate Login) ]
71 | [ text "Login" ]
72 | ]
73 |
74 |
75 | viewPage : String -> Html Msg
76 | viewPage pageDescription =
77 | div []
78 | [ h3 [] [ text pageDescription ]
79 | , p [] [ text <| "TODO: make " ++ pageDescription ]
80 | ]
81 |
82 |
83 | view : Model -> Html Msg
84 | view model =
85 | let
86 | page =
87 | case model.page of
88 | LeaderBoard ->
89 | viewPage "LeaderBoard Page"
90 |
91 | AddRunner ->
92 | viewPage "Add Runner Page"
93 |
94 | Login ->
95 | viewPage "Login Page"
96 |
97 | NotFound ->
98 | viewPage "Page Not Found"
99 | in
100 | div []
101 | [ menu model
102 | , hr [] []
103 | , page
104 | ]
105 |
106 |
107 |
108 | -- subscription
109 |
110 |
111 | subscriptions : Model -> Sub Msg
112 | subscriptions model =
113 | Sub.none
114 |
115 |
116 | pageToHash : Page -> String
117 | pageToHash page =
118 | case page of
119 | LeaderBoard ->
120 | "#"
121 |
122 | AddRunner ->
123 | "#add"
124 |
125 | Login ->
126 | "#login"
127 |
128 | NotFound ->
129 | "#notfound"
130 |
131 |
132 | hashToPage : String -> Page
133 | hashToPage hash =
134 | case hash of
135 | "" ->
136 | LeaderBoard
137 |
138 | "#add" ->
139 | AddRunner
140 |
141 | "#login" ->
142 | Login
143 |
144 | _ ->
145 | NotFound
146 |
147 |
148 | locationToMsg : Location -> Msg
149 | locationToMsg location =
150 | location.hash
151 | |> hashToPage
152 | |> ChangePage
153 |
154 |
155 | main : Program Never Model Msg
156 | main =
157 | Navigation.program locationToMsg
158 | { init = init
159 | , update = update
160 | , view = view
161 | , subscriptions = subscriptions
162 | }
163 |
--------------------------------------------------------------------------------
/07RLBStarter/src/LeaderBoard.elm:
--------------------------------------------------------------------------------
1 | module LeaderBoard exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { error : Maybe String
13 | , query : String
14 | , runners : List Runner
15 | , active : Bool
16 | }
17 |
18 |
19 | type alias Runner =
20 | { id : String
21 | , name : String
22 | , location : String
23 | , age : Int
24 | , bib : Int
25 | , estimatedDistance : Float
26 | , lastMarkerDistance : Float
27 | , lastMarkerTime : Float
28 | , pace : Float
29 | }
30 |
31 |
32 | tempRunners : List Runner
33 | tempRunners =
34 | [ Runner "1" "James Moore" "Turlock CA" 42 1234 0 1 1463154945381 0.125
35 | , Runner "2" "Meb Keflezighi" "Turlock CA" 41 1238 0 1 1463154945381 0.09
36 | ]
37 |
38 |
39 | initModel : Model
40 | initModel =
41 | { error = Nothing
42 | , query = ""
43 | , runners = tempRunners
44 | , active = False
45 | }
46 |
47 |
48 | init : ( Model, Cmd Msg )
49 | init =
50 | ( initModel, Cmd.none )
51 |
52 |
53 |
54 | -- update
55 |
56 |
57 | type Msg
58 | = SearchInput String
59 | | Search
60 |
61 |
62 | update : Msg -> Model -> ( Model, Cmd Msg )
63 | update msg model =
64 | case msg of
65 | SearchInput query ->
66 | ( { model | query = query }, Cmd.none )
67 |
68 | Search ->
69 | ( model, Cmd.none )
70 |
71 |
72 |
73 | -- view
74 |
75 |
76 | view : Model -> Html Msg
77 | view model =
78 | div [ class "main" ]
79 | [ errorPanel model.error
80 | , searchForm model.query
81 | , runners model
82 | ]
83 |
84 |
85 | errorPanel : Maybe String -> Html a
86 | errorPanel error =
87 | case error of
88 | Nothing ->
89 | text ""
90 |
91 | Just msg ->
92 | div [ class "error" ]
93 | [ text msg
94 | , button [ type_ "button" ] [ text "×" ]
95 | ]
96 |
97 |
98 | searchForm : String -> Html Msg
99 | searchForm query =
100 | Html.form [ onSubmit Search ]
101 | [ input
102 | [ type_ "text"
103 | , placeholder "Search for runner..."
104 | , value query
105 | , onInput SearchInput
106 | ]
107 | []
108 | , button [ type_ "submit" ] [ text "Search" ]
109 | ]
110 |
111 |
112 | runners : Model -> Html Msg
113 | runners { query, runners } =
114 | runners
115 | |> List.map runner
116 | |> tbody []
117 | |> (\r -> runnersHeader :: [ r ])
118 | |> table []
119 |
120 |
121 | runner : Runner -> Html Msg
122 | runner { name, location, age, bib, estimatedDistance } =
123 | tr []
124 | [ td [] [ text name ]
125 | , td [] [ text location ]
126 | , td [] [ text (toString age) ]
127 | , td [] [ text (toString bib) ]
128 | , td []
129 | [ text "1 mi @ 08:30AM (TODO)"
130 | ]
131 | , td [] [ text (toString estimatedDistance) ]
132 | ]
133 |
134 |
135 | runnersHeader : Html Msg
136 | runnersHeader =
137 | thead []
138 | [ tr []
139 | [ th [] [ text "Name" ]
140 | , th [] [ text "From" ]
141 | , th [] [ text "Age" ]
142 | , th [] [ text "Bib #" ]
143 | , th [] [ text "Last Marker" ]
144 | , th [] [ text "Est. Miles" ]
145 | ]
146 | ]
147 |
148 |
149 |
150 | -- subscriptions
151 |
152 |
153 | subscriptions : Model -> Sub Msg
154 | subscriptions model =
155 | Sub.none
156 |
--------------------------------------------------------------------------------
/09RLBLogin/src/LeaderBoard.elm:
--------------------------------------------------------------------------------
1 | module LeaderBoard exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { error : Maybe String
13 | , query : String
14 | , runners : List Runner
15 | , active : Bool
16 | }
17 |
18 |
19 | type alias Runner =
20 | { id : String
21 | , name : String
22 | , location : String
23 | , age : Int
24 | , bib : Int
25 | , estimatedDistance : Float
26 | , lastMarkerDistance : Float
27 | , lastMarkerTime : Float
28 | , pace : Float
29 | }
30 |
31 |
32 | tempRunners : List Runner
33 | tempRunners =
34 | [ Runner "1" "James Moore" "Turlock CA" 42 1234 0 1 1463154945381 0.125
35 | , Runner "2" "Meb Keflezighi" "Turlock CA" 41 1238 0 1 1463154945381 0.09
36 | ]
37 |
38 |
39 | initModel : Model
40 | initModel =
41 | { error = Nothing
42 | , query = ""
43 | , runners = tempRunners
44 | , active = False
45 | }
46 |
47 |
48 | init : ( Model, Cmd Msg )
49 | init =
50 | ( initModel, Cmd.none )
51 |
52 |
53 |
54 | -- update
55 |
56 |
57 | type Msg
58 | = SearchInput String
59 | | Search
60 |
61 |
62 | update : Msg -> Model -> ( Model, Cmd Msg )
63 | update msg model =
64 | case msg of
65 | SearchInput query ->
66 | ( { model | query = query }, Cmd.none )
67 |
68 | Search ->
69 | ( model, Cmd.none )
70 |
71 |
72 |
73 | -- view
74 |
75 |
76 | view : Model -> Html Msg
77 | view model =
78 | div [ class "main" ]
79 | [ errorPanel model.error
80 | , searchForm model.query
81 | , runners model
82 | ]
83 |
84 |
85 | errorPanel : Maybe String -> Html a
86 | errorPanel error =
87 | case error of
88 | Nothing ->
89 | text ""
90 |
91 | Just msg ->
92 | div [ class "error" ]
93 | [ text msg
94 | , button [ type_ "button" ] [ text "×" ]
95 | ]
96 |
97 |
98 | searchForm : String -> Html Msg
99 | searchForm query =
100 | Html.form [ onSubmit Search ]
101 | [ input
102 | [ type_ "text"
103 | , placeholder "Search for runner..."
104 | , value query
105 | , onInput SearchInput
106 | ]
107 | []
108 | , button [ type_ "submit" ] [ text "Search" ]
109 | ]
110 |
111 |
112 | runners : Model -> Html Msg
113 | runners { query, runners } =
114 | runners
115 | |> List.map runner
116 | |> tbody []
117 | |> (\r -> runnersHeader :: [ r ])
118 | |> table []
119 |
120 |
121 | runner : Runner -> Html Msg
122 | runner { name, location, age, bib, estimatedDistance } =
123 | tr []
124 | [ td [] [ text name ]
125 | , td [] [ text location ]
126 | , td [] [ text (toString age) ]
127 | , td [] [ text (toString bib) ]
128 | , td []
129 | [ text "1 mi @ 08:30AM (TODO)"
130 | ]
131 | , td [] [ text (toString estimatedDistance) ]
132 | ]
133 |
134 |
135 | runnersHeader : Html Msg
136 | runnersHeader =
137 | thead []
138 | [ tr []
139 | [ th [] [ text "Name" ]
140 | , th [] [ text "From" ]
141 | , th [] [ text "Age" ]
142 | , th [] [ text "Bib #" ]
143 | , th [] [ text "Last Marker" ]
144 | , th [] [ text "Est. Miles" ]
145 | ]
146 | ]
147 |
148 |
149 |
150 | -- subscriptions
151 |
152 |
153 | subscriptions : Model -> Sub Msg
154 | subscriptions model =
155 | Sub.none
156 |
--------------------------------------------------------------------------------
/11RLBLogout/src/LeaderBoard.elm:
--------------------------------------------------------------------------------
1 | module LeaderBoard exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { error : Maybe String
13 | , query : String
14 | , runners : List Runner
15 | , active : Bool
16 | }
17 |
18 |
19 | type alias Runner =
20 | { id : String
21 | , name : String
22 | , location : String
23 | , age : Int
24 | , bib : Int
25 | , estimatedDistance : Float
26 | , lastMarkerDistance : Float
27 | , lastMarkerTime : Float
28 | , pace : Float
29 | }
30 |
31 |
32 | tempRunners : List Runner
33 | tempRunners =
34 | [ Runner "1" "James Moore" "Turlock CA" 42 1234 0 1 1463154945381 0.125
35 | , Runner "2" "Meb Keflezighi" "Turlock CA" 41 1238 0 1 1463154945381 0.09
36 | ]
37 |
38 |
39 | initModel : Model
40 | initModel =
41 | { error = Nothing
42 | , query = ""
43 | , runners = tempRunners
44 | , active = False
45 | }
46 |
47 |
48 | init : ( Model, Cmd Msg )
49 | init =
50 | ( initModel, Cmd.none )
51 |
52 |
53 |
54 | -- update
55 |
56 |
57 | type Msg
58 | = SearchInput String
59 | | Search
60 |
61 |
62 | update : Msg -> Model -> ( Model, Cmd Msg )
63 | update msg model =
64 | case msg of
65 | SearchInput query ->
66 | ( { model | query = query }, Cmd.none )
67 |
68 | Search ->
69 | ( model, Cmd.none )
70 |
71 |
72 |
73 | -- view
74 |
75 |
76 | view : Model -> Html Msg
77 | view model =
78 | div [ class "main" ]
79 | [ errorPanel model.error
80 | , searchForm model.query
81 | , runners model
82 | ]
83 |
84 |
85 | errorPanel : Maybe String -> Html a
86 | errorPanel error =
87 | case error of
88 | Nothing ->
89 | text ""
90 |
91 | Just msg ->
92 | div [ class "error" ]
93 | [ text msg
94 | , button [ type_ "button" ] [ text "×" ]
95 | ]
96 |
97 |
98 | searchForm : String -> Html Msg
99 | searchForm query =
100 | Html.form [ onSubmit Search ]
101 | [ input
102 | [ type_ "text"
103 | , placeholder "Search for runner..."
104 | , value query
105 | , onInput SearchInput
106 | ]
107 | []
108 | , button [ type_ "submit" ] [ text "Search" ]
109 | ]
110 |
111 |
112 | runners : Model -> Html Msg
113 | runners { query, runners } =
114 | runners
115 | |> List.map runner
116 | |> tbody []
117 | |> (\r -> runnersHeader :: [ r ])
118 | |> table []
119 |
120 |
121 | runner : Runner -> Html Msg
122 | runner { name, location, age, bib, estimatedDistance } =
123 | tr []
124 | [ td [] [ text name ]
125 | , td [] [ text location ]
126 | , td [] [ text (toString age) ]
127 | , td [] [ text (toString bib) ]
128 | , td []
129 | [ text "1 mi @ 08:30AM (TODO)"
130 | ]
131 | , td [] [ text (toString estimatedDistance) ]
132 | ]
133 |
134 |
135 | runnersHeader : Html Msg
136 | runnersHeader =
137 | thead []
138 | [ tr []
139 | [ th [] [ text "Name" ]
140 | , th [] [ text "From" ]
141 | , th [] [ text "Age" ]
142 | , th [] [ text "Bib #" ]
143 | , th [] [ text "Last Marker" ]
144 | , th [] [ text "Est. Miles" ]
145 | ]
146 | ]
147 |
148 |
149 |
150 | -- subscriptions
151 |
152 |
153 | subscriptions : Model -> Sub Msg
154 | subscriptions model =
155 | Sub.none
156 |
--------------------------------------------------------------------------------
/13RLBAddRunner/src/LeaderBoard.elm:
--------------------------------------------------------------------------------
1 | module LeaderBoard exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { error : Maybe String
13 | , query : String
14 | , runners : List Runner
15 | , active : Bool
16 | }
17 |
18 |
19 | type alias Runner =
20 | { id : String
21 | , name : String
22 | , location : String
23 | , age : Int
24 | , bib : Int
25 | , estimatedDistance : Float
26 | , lastMarkerDistance : Float
27 | , lastMarkerTime : Float
28 | , pace : Float
29 | }
30 |
31 |
32 | tempRunners : List Runner
33 | tempRunners =
34 | [ Runner "1" "James Moore" "Turlock CA" 42 1234 0 1 1463154945381 0.125
35 | , Runner "2" "Meb Keflezighi" "Turlock CA" 41 1238 0 1 1463154945381 0.09
36 | ]
37 |
38 |
39 | initModel : Model
40 | initModel =
41 | { error = Nothing
42 | , query = ""
43 | , runners = tempRunners
44 | , active = False
45 | }
46 |
47 |
48 | init : ( Model, Cmd Msg )
49 | init =
50 | ( initModel, Cmd.none )
51 |
52 |
53 |
54 | -- update
55 |
56 |
57 | type Msg
58 | = SearchInput String
59 | | Search
60 |
61 |
62 | update : Msg -> Model -> ( Model, Cmd Msg )
63 | update msg model =
64 | case msg of
65 | SearchInput query ->
66 | ( { model | query = query }, Cmd.none )
67 |
68 | Search ->
69 | ( model, Cmd.none )
70 |
71 |
72 |
73 | -- view
74 |
75 |
76 | view : Model -> Html Msg
77 | view model =
78 | div [ class "main" ]
79 | [ errorPanel model.error
80 | , searchForm model.query
81 | , runners model
82 | ]
83 |
84 |
85 | errorPanel : Maybe String -> Html a
86 | errorPanel error =
87 | case error of
88 | Nothing ->
89 | text ""
90 |
91 | Just msg ->
92 | div [ class "error" ]
93 | [ text msg
94 | , button [ type_ "button" ] [ text "×" ]
95 | ]
96 |
97 |
98 | searchForm : String -> Html Msg
99 | searchForm query =
100 | Html.form [ onSubmit Search ]
101 | [ input
102 | [ type_ "text"
103 | , placeholder "Search for runner..."
104 | , value query
105 | , onInput SearchInput
106 | ]
107 | []
108 | , button [ type_ "submit" ] [ text "Search" ]
109 | ]
110 |
111 |
112 | runners : Model -> Html Msg
113 | runners { query, runners } =
114 | runners
115 | |> List.map runner
116 | |> tbody []
117 | |> (\r -> runnersHeader :: [ r ])
118 | |> table []
119 |
120 |
121 | runner : Runner -> Html Msg
122 | runner { name, location, age, bib, estimatedDistance } =
123 | tr []
124 | [ td [] [ text name ]
125 | , td [] [ text location ]
126 | , td [] [ text (toString age) ]
127 | , td [] [ text (toString bib) ]
128 | , td []
129 | [ text "1 mi @ 08:30AM (TODO)"
130 | ]
131 | , td [] [ text (toString estimatedDistance) ]
132 | ]
133 |
134 |
135 | runnersHeader : Html Msg
136 | runnersHeader =
137 | thead []
138 | [ tr []
139 | [ th [] [ text "Name" ]
140 | , th [] [ text "From" ]
141 | , th [] [ text "Age" ]
142 | , th [] [ text "Bib #" ]
143 | , th [] [ text "Last Marker" ]
144 | , th [] [ text "Est. Miles" ]
145 | ]
146 | ]
147 |
148 |
149 |
150 | -- subscriptions
151 |
152 |
153 | subscriptions : Model -> Sub Msg
154 | subscriptions model =
155 | Sub.none
156 |
--------------------------------------------------------------------------------
/08RLBNavigation/src/LeaderBoard.elm:
--------------------------------------------------------------------------------
1 | module LeaderBoard exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { error : Maybe String
13 | , query : String
14 | , runners : List Runner
15 | , active : Bool
16 | }
17 |
18 |
19 | type alias Runner =
20 | { id : String
21 | , name : String
22 | , location : String
23 | , age : Int
24 | , bib : Int
25 | , estimatedDistance : Float
26 | , lastMarkerDistance : Float
27 | , lastMarkerTime : Float
28 | , pace : Float
29 | }
30 |
31 |
32 | tempRunners : List Runner
33 | tempRunners =
34 | [ Runner "1" "James Moore" "Turlock CA" 42 1234 0 1 1463154945381 0.125
35 | , Runner "2" "Meb Keflezighi" "Turlock CA" 41 1238 0 1 1463154945381 0.09
36 | ]
37 |
38 |
39 | initModel : Model
40 | initModel =
41 | { error = Nothing
42 | , query = ""
43 | , runners = tempRunners
44 | , active = False
45 | }
46 |
47 |
48 | init : ( Model, Cmd Msg )
49 | init =
50 | ( initModel, Cmd.none )
51 |
52 |
53 |
54 | -- update
55 |
56 |
57 | type Msg
58 | = SearchInput String
59 | | Search
60 |
61 |
62 | update : Msg -> Model -> ( Model, Cmd Msg )
63 | update msg model =
64 | case msg of
65 | SearchInput query ->
66 | ( { model | query = query }, Cmd.none )
67 |
68 | Search ->
69 | ( model, Cmd.none )
70 |
71 |
72 |
73 | -- view
74 |
75 |
76 | view : Model -> Html Msg
77 | view model =
78 | div [ class "main" ]
79 | [ errorPanel model.error
80 | , searchForm model.query
81 | , runners model
82 | ]
83 |
84 |
85 | errorPanel : Maybe String -> Html a
86 | errorPanel error =
87 | case error of
88 | Nothing ->
89 | text ""
90 |
91 | Just msg ->
92 | div [ class "error" ]
93 | [ text msg
94 | , button [ type_ "button" ] [ text "×" ]
95 | ]
96 |
97 |
98 | searchForm : String -> Html Msg
99 | searchForm query =
100 | Html.form [ onSubmit Search ]
101 | [ input
102 | [ type_ "text"
103 | , placeholder "Search for runner..."
104 | , value query
105 | , onInput SearchInput
106 | ]
107 | []
108 | , button [ type_ "submit" ] [ text "Search" ]
109 | ]
110 |
111 |
112 | runners : Model -> Html Msg
113 | runners { query, runners } =
114 | runners
115 | |> List.map runner
116 | |> tbody []
117 | |> (\r -> runnersHeader :: [ r ])
118 | |> table []
119 |
120 |
121 | runner : Runner -> Html Msg
122 | runner { name, location, age, bib, estimatedDistance } =
123 | tr []
124 | [ td [] [ text name ]
125 | , td [] [ text location ]
126 | , td [] [ text (toString age) ]
127 | , td [] [ text (toString bib) ]
128 | , td []
129 | [ text "1 mi @ 08:30AM (TODO)"
130 | ]
131 | , td [] [ text (toString estimatedDistance) ]
132 | ]
133 |
134 |
135 | runnersHeader : Html Msg
136 | runnersHeader =
137 | thead []
138 | [ tr []
139 | [ th [] [ text "Name" ]
140 | , th [] [ text "From" ]
141 | , th [] [ text "Age" ]
142 | , th [] [ text "Bib #" ]
143 | , th [] [ text "Last Marker" ]
144 | , th [] [ text "Est. Miles" ]
145 | ]
146 | ]
147 |
148 |
149 |
150 | -- subscriptions
151 |
152 |
153 | subscriptions : Model -> Sub Msg
154 | subscriptions model =
155 | Sub.none
156 |
--------------------------------------------------------------------------------
/10RLBLoginToken/src/LeaderBoard.elm:
--------------------------------------------------------------------------------
1 | module LeaderBoard exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { error : Maybe String
13 | , query : String
14 | , runners : List Runner
15 | , active : Bool
16 | }
17 |
18 |
19 | type alias Runner =
20 | { id : String
21 | , name : String
22 | , location : String
23 | , age : Int
24 | , bib : Int
25 | , estimatedDistance : Float
26 | , lastMarkerDistance : Float
27 | , lastMarkerTime : Float
28 | , pace : Float
29 | }
30 |
31 |
32 | tempRunners : List Runner
33 | tempRunners =
34 | [ Runner "1" "James Moore" "Turlock CA" 42 1234 0 1 1463154945381 0.125
35 | , Runner "2" "Meb Keflezighi" "Turlock CA" 41 1238 0 1 1463154945381 0.09
36 | ]
37 |
38 |
39 | initModel : Model
40 | initModel =
41 | { error = Nothing
42 | , query = ""
43 | , runners = tempRunners
44 | , active = False
45 | }
46 |
47 |
48 | init : ( Model, Cmd Msg )
49 | init =
50 | ( initModel, Cmd.none )
51 |
52 |
53 |
54 | -- update
55 |
56 |
57 | type Msg
58 | = SearchInput String
59 | | Search
60 |
61 |
62 | update : Msg -> Model -> ( Model, Cmd Msg )
63 | update msg model =
64 | case msg of
65 | SearchInput query ->
66 | ( { model | query = query }, Cmd.none )
67 |
68 | Search ->
69 | ( model, Cmd.none )
70 |
71 |
72 |
73 | -- view
74 |
75 |
76 | view : Model -> Html Msg
77 | view model =
78 | div [ class "main" ]
79 | [ errorPanel model.error
80 | , searchForm model.query
81 | , runners model
82 | ]
83 |
84 |
85 | errorPanel : Maybe String -> Html a
86 | errorPanel error =
87 | case error of
88 | Nothing ->
89 | text ""
90 |
91 | Just msg ->
92 | div [ class "error" ]
93 | [ text msg
94 | , button [ type_ "button" ] [ text "×" ]
95 | ]
96 |
97 |
98 | searchForm : String -> Html Msg
99 | searchForm query =
100 | Html.form [ onSubmit Search ]
101 | [ input
102 | [ type_ "text"
103 | , placeholder "Search for runner..."
104 | , value query
105 | , onInput SearchInput
106 | ]
107 | []
108 | , button [ type_ "submit" ] [ text "Search" ]
109 | ]
110 |
111 |
112 | runners : Model -> Html Msg
113 | runners { query, runners } =
114 | runners
115 | |> List.map runner
116 | |> tbody []
117 | |> (\r -> runnersHeader :: [ r ])
118 | |> table []
119 |
120 |
121 | runner : Runner -> Html Msg
122 | runner { name, location, age, bib, estimatedDistance } =
123 | tr []
124 | [ td [] [ text name ]
125 | , td [] [ text location ]
126 | , td [] [ text (toString age) ]
127 | , td [] [ text (toString bib) ]
128 | , td []
129 | [ text "1 mi @ 08:30AM (TODO)"
130 | ]
131 | , td [] [ text (toString estimatedDistance) ]
132 | ]
133 |
134 |
135 | runnersHeader : Html Msg
136 | runnersHeader =
137 | thead []
138 | [ tr []
139 | [ th [] [ text "Name" ]
140 | , th [] [ text "From" ]
141 | , th [] [ text "Age" ]
142 | , th [] [ text "Bib #" ]
143 | , th [] [ text "Last Marker" ]
144 | , th [] [ text "Est. Miles" ]
145 | ]
146 | ]
147 |
148 |
149 |
150 | -- subscriptions
151 |
152 |
153 | subscriptions : Model -> Sub Msg
154 | subscriptions model =
155 | Sub.none
156 |
--------------------------------------------------------------------------------
/12RLBLockRunnerPage/src/LeaderBoard.elm:
--------------------------------------------------------------------------------
1 | module LeaderBoard exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { error : Maybe String
13 | , query : String
14 | , runners : List Runner
15 | , active : Bool
16 | }
17 |
18 |
19 | type alias Runner =
20 | { id : String
21 | , name : String
22 | , location : String
23 | , age : Int
24 | , bib : Int
25 | , estimatedDistance : Float
26 | , lastMarkerDistance : Float
27 | , lastMarkerTime : Float
28 | , pace : Float
29 | }
30 |
31 |
32 | tempRunners : List Runner
33 | tempRunners =
34 | [ Runner "1" "James Moore" "Turlock CA" 42 1234 0 1 1463154945381 0.125
35 | , Runner "2" "Meb Keflezighi" "Turlock CA" 41 1238 0 1 1463154945381 0.09
36 | ]
37 |
38 |
39 | initModel : Model
40 | initModel =
41 | { error = Nothing
42 | , query = ""
43 | , runners = tempRunners
44 | , active = False
45 | }
46 |
47 |
48 | init : ( Model, Cmd Msg )
49 | init =
50 | ( initModel, Cmd.none )
51 |
52 |
53 |
54 | -- update
55 |
56 |
57 | type Msg
58 | = SearchInput String
59 | | Search
60 |
61 |
62 | update : Msg -> Model -> ( Model, Cmd Msg )
63 | update msg model =
64 | case msg of
65 | SearchInput query ->
66 | ( { model | query = query }, Cmd.none )
67 |
68 | Search ->
69 | ( model, Cmd.none )
70 |
71 |
72 |
73 | -- view
74 |
75 |
76 | view : Model -> Html Msg
77 | view model =
78 | div [ class "main" ]
79 | [ errorPanel model.error
80 | , searchForm model.query
81 | , runners model
82 | ]
83 |
84 |
85 | errorPanel : Maybe String -> Html a
86 | errorPanel error =
87 | case error of
88 | Nothing ->
89 | text ""
90 |
91 | Just msg ->
92 | div [ class "error" ]
93 | [ text msg
94 | , button [ type_ "button" ] [ text "×" ]
95 | ]
96 |
97 |
98 | searchForm : String -> Html Msg
99 | searchForm query =
100 | Html.form [ onSubmit Search ]
101 | [ input
102 | [ type_ "text"
103 | , placeholder "Search for runner..."
104 | , value query
105 | , onInput SearchInput
106 | ]
107 | []
108 | , button [ type_ "submit" ] [ text "Search" ]
109 | ]
110 |
111 |
112 | runners : Model -> Html Msg
113 | runners { query, runners } =
114 | runners
115 | |> List.map runner
116 | |> tbody []
117 | |> (\r -> runnersHeader :: [ r ])
118 | |> table []
119 |
120 |
121 | runner : Runner -> Html Msg
122 | runner { name, location, age, bib, estimatedDistance } =
123 | tr []
124 | [ td [] [ text name ]
125 | , td [] [ text location ]
126 | , td [] [ text (toString age) ]
127 | , td [] [ text (toString bib) ]
128 | , td []
129 | [ text "1 mi @ 08:30AM (TODO)"
130 | ]
131 | , td [] [ text (toString estimatedDistance) ]
132 | ]
133 |
134 |
135 | runnersHeader : Html Msg
136 | runnersHeader =
137 | thead []
138 | [ tr []
139 | [ th [] [ text "Name" ]
140 | , th [] [ text "From" ]
141 | , th [] [ text "Age" ]
142 | , th [] [ text "Bib #" ]
143 | , th [] [ text "Last Marker" ]
144 | , th [] [ text "Est. Miles" ]
145 | ]
146 | ]
147 |
148 |
149 |
150 | -- subscriptions
151 |
152 |
153 | subscriptions : Model -> Sub Msg
154 | subscriptions model =
155 | Sub.none
156 |
--------------------------------------------------------------------------------
/13RLBAddRunner/completed/src/LeaderBoard.elm:
--------------------------------------------------------------------------------
1 | module LeaderBoard exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { error : Maybe String
13 | , query : String
14 | , runners : List Runner
15 | , active : Bool
16 | }
17 |
18 |
19 | type alias Runner =
20 | { id : String
21 | , name : String
22 | , location : String
23 | , age : Int
24 | , bib : Int
25 | , estimatedDistance : Float
26 | , lastMarkerDistance : Float
27 | , lastMarkerTime : Float
28 | , pace : Float
29 | }
30 |
31 |
32 | tempRunners : List Runner
33 | tempRunners =
34 | [ Runner "1" "James Moore" "Turlock CA" 42 1234 0 1 1463154945381 0.125
35 | , Runner "2" "Meb Keflezighi" "Turlock CA" 41 1238 0 1 1463154945381 0.09
36 | ]
37 |
38 |
39 | initModel : Model
40 | initModel =
41 | { error = Nothing
42 | , query = ""
43 | , runners = tempRunners
44 | , active = False
45 | }
46 |
47 |
48 | init : ( Model, Cmd Msg )
49 | init =
50 | ( initModel, Cmd.none )
51 |
52 |
53 |
54 | -- update
55 |
56 |
57 | type Msg
58 | = SearchInput String
59 | | Search
60 |
61 |
62 | update : Msg -> Model -> ( Model, Cmd Msg )
63 | update msg model =
64 | case msg of
65 | SearchInput query ->
66 | ( { model | query = query }, Cmd.none )
67 |
68 | Search ->
69 | ( model, Cmd.none )
70 |
71 |
72 |
73 | -- view
74 |
75 |
76 | view : Model -> Html Msg
77 | view model =
78 | div [ class "main" ]
79 | [ errorPanel model.error
80 | , searchForm model.query
81 | , runners model
82 | ]
83 |
84 |
85 | errorPanel : Maybe String -> Html a
86 | errorPanel error =
87 | case error of
88 | Nothing ->
89 | text ""
90 |
91 | Just msg ->
92 | div [ class "error" ]
93 | [ text msg
94 | , button [ type_ "button" ] [ text "×" ]
95 | ]
96 |
97 |
98 | searchForm : String -> Html Msg
99 | searchForm query =
100 | Html.form [ onSubmit Search ]
101 | [ input
102 | [ type_ "text"
103 | , placeholder "Search for runner..."
104 | , value query
105 | , onInput SearchInput
106 | ]
107 | []
108 | , button [ type_ "submit" ] [ text "Search" ]
109 | ]
110 |
111 |
112 | runners : Model -> Html Msg
113 | runners { query, runners } =
114 | runners
115 | |> List.map runner
116 | |> tbody []
117 | |> (\r -> runnersHeader :: [ r ])
118 | |> table []
119 |
120 |
121 | runner : Runner -> Html Msg
122 | runner { name, location, age, bib, estimatedDistance } =
123 | tr []
124 | [ td [] [ text name ]
125 | , td [] [ text location ]
126 | , td [] [ text (toString age) ]
127 | , td [] [ text (toString bib) ]
128 | , td []
129 | [ text "1 mi @ 08:30AM (TODO)"
130 | ]
131 | , td [] [ text (toString estimatedDistance) ]
132 | ]
133 |
134 |
135 | runnersHeader : Html Msg
136 | runnersHeader =
137 | thead []
138 | [ tr []
139 | [ th [] [ text "Name" ]
140 | , th [] [ text "From" ]
141 | , th [] [ text "Age" ]
142 | , th [] [ text "Bib #" ]
143 | , th [] [ text "Last Marker" ]
144 | , th [] [ text "Est. Miles" ]
145 | ]
146 | ]
147 |
148 |
149 |
150 | -- subscriptions
151 |
152 |
153 | subscriptions : Model -> Sub Msg
154 | subscriptions model =
155 | Sub.none
156 |
--------------------------------------------------------------------------------
/08RLBNavigation/completed/src/LeaderBoard.elm:
--------------------------------------------------------------------------------
1 | module LeaderBoard exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Model =
12 | { error : Maybe String
13 | , query : String
14 | , runners : List Runner
15 | , active : Bool
16 | }
17 |
18 |
19 | type alias Runner =
20 | { id : String
21 | , name : String
22 | , location : String
23 | , age : Int
24 | , bib : Int
25 | , estimatedDistance : Float
26 | , lastMarkerDistance : Float
27 | , lastMarkerTime : Float
28 | , pace : Float
29 | }
30 |
31 |
32 | tempRunners : List Runner
33 | tempRunners =
34 | [ Runner "1" "James Moore" "Turlock CA" 42 1234 0 1 1463154945381 0.125
35 | , Runner "2" "Meb Keflezighi" "Turlock CA" 41 1238 0 1 1463154945381 0.09
36 | ]
37 |
38 |
39 | initModel : Model
40 | initModel =
41 | { error = Nothing
42 | , query = ""
43 | , runners = tempRunners
44 | , active = False
45 | }
46 |
47 |
48 | init : ( Model, Cmd Msg )
49 | init =
50 | ( initModel, Cmd.none )
51 |
52 |
53 |
54 | -- update
55 |
56 |
57 | type Msg
58 | = SearchInput String
59 | | Search
60 |
61 |
62 | update : Msg -> Model -> ( Model, Cmd Msg )
63 | update msg model =
64 | case msg of
65 | SearchInput query ->
66 | ( { model | query = query }, Cmd.none )
67 |
68 | Search ->
69 | ( model, Cmd.none )
70 |
71 |
72 |
73 | -- view
74 |
75 |
76 | view : Model -> Html Msg
77 | view model =
78 | div [ class "main" ]
79 | [ errorPanel model.error
80 | , searchForm model.query
81 | , runners model
82 | ]
83 |
84 |
85 | errorPanel : Maybe String -> Html a
86 | errorPanel error =
87 | case error of
88 | Nothing ->
89 | text ""
90 |
91 | Just msg ->
92 | div [ class "error" ]
93 | [ text msg
94 | , button [ type_ "button" ] [ text "×" ]
95 | ]
96 |
97 |
98 | searchForm : String -> Html Msg
99 | searchForm query =
100 | Html.form [ onSubmit Search ]
101 | [ input
102 | [ type_ "text"
103 | , placeholder "Search for runner..."
104 | , value query
105 | , onInput SearchInput
106 | ]
107 | []
108 | , button [ type_ "submit" ] [ text "Search" ]
109 | ]
110 |
111 |
112 | runners : Model -> Html Msg
113 | runners { query, runners } =
114 | runners
115 | |> List.map runner
116 | |> tbody []
117 | |> (\r -> runnersHeader :: [ r ])
118 | |> table []
119 |
120 |
121 | runner : Runner -> Html Msg
122 | runner { name, location, age, bib, estimatedDistance } =
123 | tr []
124 | [ td [] [ text name ]
125 | , td [] [ text location ]
126 | , td [] [ text (toString age) ]
127 | , td [] [ text (toString bib) ]
128 | , td []
129 | [ text "1 mi @ 08:30AM (TODO)"
130 | ]
131 | , td [] [ text (toString estimatedDistance) ]
132 | ]
133 |
134 |
135 | runnersHeader : Html Msg
136 | runnersHeader =
137 | thead []
138 | [ tr []
139 | [ th [] [ text "Name" ]
140 | , th [] [ text "From" ]
141 | , th [] [ text "Age" ]
142 | , th [] [ text "Bib #" ]
143 | , th [] [ text "Last Marker" ]
144 | , th [] [ text "Est. Miles" ]
145 | ]
146 | ]
147 |
148 |
149 |
150 | -- subscriptions
151 |
152 |
153 | subscriptions : Model -> Sub Msg
154 | subscriptions model =
155 | Sub.none
156 |
--------------------------------------------------------------------------------
/06Ports/completed/Main.elm:
--------------------------------------------------------------------------------
1 | port module Main exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 |
7 |
8 | -- model
9 |
10 |
11 | type alias Customer =
12 | { id : String
13 | , name : String
14 | }
15 |
16 |
17 | type alias Model =
18 | { name : String
19 | , customers : List Customer
20 | , error : Maybe String
21 | , nextId : Int
22 | }
23 |
24 |
25 | initModel : Model
26 | initModel =
27 | { name = ""
28 | , customers = []
29 | , error = Nothing
30 | , nextId = 1
31 | }
32 |
33 |
34 | init : ( Model, Cmd Msg )
35 | init =
36 | ( initModel, Cmd.none )
37 |
38 |
39 |
40 | -- update
41 |
42 |
43 | type Msg
44 | = NameInput String
45 | | SaveCustomer
46 | | CustomerSaved String
47 | | CustomerAdded Customer
48 | | DeleteCustomer Customer
49 | | CustomerDeleted String
50 |
51 |
52 | update : Msg -> Model -> ( Model, Cmd Msg )
53 | update msg model =
54 | case msg of
55 | NameInput name ->
56 | ( { model | name = name }, Cmd.none )
57 |
58 | SaveCustomer ->
59 | ( model, addCustomer model.name )
60 |
61 | CustomerSaved key ->
62 | ( { model | name = "" }, Cmd.none )
63 |
64 | CustomerAdded customer ->
65 | let
66 | newCustomers =
67 | customer :: model.customers
68 | in
69 | ( { model | customers = newCustomers }, Cmd.none )
70 |
71 | DeleteCustomer customer ->
72 | ( model, deleteCustomer customer )
73 |
74 | CustomerDeleted id ->
75 | let
76 | newCustomers =
77 | List.filter (\customer -> customer.id /= id)
78 | model.customers
79 | in
80 | ( { model | customers = newCustomers }, Cmd.none )
81 |
82 |
83 |
84 | -- view
85 |
86 |
87 | viewCustomer : Customer -> Html Msg
88 | viewCustomer customer =
89 | li []
90 | [ i [ class "remove", onClick (DeleteCustomer customer) ] []
91 | , text customer.name
92 | ]
93 |
94 |
95 | viewCustomers : List Customer -> Html Msg
96 | viewCustomers customers =
97 | customers
98 | |> List.sortBy .id
99 | |> List.map viewCustomer
100 | |> ul []
101 |
102 |
103 | viewCustomerForm : Model -> Html Msg
104 | viewCustomerForm model =
105 | Html.form [ onSubmit SaveCustomer ]
106 | [ input [ type_ "text", onInput NameInput, value model.name ] []
107 | , text <| Maybe.withDefault "" model.error
108 | , button [ type_ "submit" ] [ text "Save" ]
109 | ]
110 |
111 |
112 | view : Model -> Html Msg
113 | view model =
114 | div []
115 | [ h1 [] [ text "Customer List" ]
116 | , viewCustomerForm model
117 | , viewCustomers model.customers
118 | ]
119 |
120 |
121 |
122 | -- subscription
123 |
124 |
125 | subscriptions : Model -> Sub Msg
126 | subscriptions model =
127 | -- Sub.none
128 | Sub.batch
129 | [ customerSaved CustomerSaved
130 | , newCustomer CustomerAdded
131 | , customerDeleted CustomerDeleted
132 | ]
133 |
134 |
135 | port addCustomer : String -> Cmd msg
136 |
137 |
138 | port customerSaved : (String -> msg) -> Sub msg
139 |
140 |
141 | port newCustomer : (Customer -> msg) -> Sub msg
142 |
143 |
144 | port deleteCustomer : Customer -> Cmd msg
145 |
146 |
147 | port customerDeleted : (String -> msg) -> Sub msg
148 |
149 |
150 | main : Program Never Model Msg
151 | main =
152 | Html.program
153 | { init = init
154 | , update = update
155 | , view = view
156 | , subscriptions = subscriptions
157 | }
158 |
--------------------------------------------------------------------------------
/08RLBNavigation/src/Main.elm:
--------------------------------------------------------------------------------
1 | port module Main exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Attributes exposing (..)
5 | import Html.Events exposing (..)
6 | import Navigation
7 | import LeaderBoard
8 |
9 |
10 | -- model
11 |
12 |
13 | type alias Model =
14 | { page : Page
15 | , leaderBoard : LeaderBoard.Model
16 | }
17 |
18 |
19 | type Page
20 | = NotFound
21 | | LeaderBoardPage
22 |
23 |
24 | init : Navigation.Location -> ( Model, Cmd Msg )
25 | init location =
26 | let
27 | page =
28 | hashToPage location.hash
29 |
30 | ( leaderboardInitModel, leaderboardCmd ) =
31 | LeaderBoard.init
32 |
33 | initModel =
34 | { page = page
35 | , leaderBoard = leaderboardInitModel
36 | }
37 |
38 | cmds =
39 | Cmd.batch
40 | [ Cmd.map LeaderBoardMsg leaderboardCmd
41 | ]
42 | in
43 | ( initModel, cmds )
44 |
45 |
46 |
47 | -- update
48 |
49 |
50 | type Msg
51 | = Navigate Page
52 | | ChangePage Page
53 | | LeaderBoardMsg LeaderBoard.Msg
54 |
55 |
56 | update : Msg -> Model -> ( Model, Cmd Msg )
57 | update msg model =
58 | case msg of
59 | Navigate page ->
60 | ( { model | page = page }, Navigation.newUrl <| pageToHash page )
61 |
62 | ChangePage page ->
63 | ( { model | page = page }, Cmd.none )
64 |
65 | LeaderBoardMsg msg ->
66 | let
67 | ( leaderBoardModel, cmd ) =
68 | LeaderBoard.update msg model.leaderBoard
69 | in
70 | ( { model | leaderBoard = leaderBoardModel }
71 | , Cmd.map LeaderBoardMsg cmd
72 | )
73 |
74 |
75 |
76 | -- view
77 |
78 |
79 | view : Model -> Html Msg
80 | view model =
81 | let
82 | page =
83 | case model.page of
84 | LeaderBoardPage ->
85 | Html.map LeaderBoardMsg
86 | (LeaderBoard.view model.leaderBoard)
87 |
88 | NotFound ->
89 | div [ class "main" ]
90 | [ h1 []
91 | [ text "Page Not Found!" ]
92 | ]
93 | in
94 | div []
95 | [ pageHeader model
96 | , page
97 | ]
98 |
99 |
100 | pageHeader : Model -> Html Msg
101 | pageHeader model =
102 | header []
103 | [ a [ onClick (Navigate LeaderBoardPage) ] [ text "Race Results" ]
104 | , ul []
105 | [ li []
106 | [ a [ href "#" ] [ text "Link" ]
107 | ]
108 | ]
109 | , ul []
110 | [ li []
111 | [ a [ href "#" ] [ text "Login" ]
112 | ]
113 | ]
114 | ]
115 |
116 |
117 |
118 | -- subscriptions
119 |
120 |
121 | subscriptions : Model -> Sub Msg
122 | subscriptions model =
123 | let
124 | leaderBoardSub =
125 | LeaderBoard.subscriptions model.leaderBoard
126 | in
127 | Sub.batch
128 | [ Sub.map LeaderBoardMsg leaderBoardSub
129 | ]
130 |
131 |
132 | hashToPage : String -> Page
133 | hashToPage hash =
134 | case hash of
135 | "#/" ->
136 | LeaderBoardPage
137 |
138 | "" ->
139 | LeaderBoardPage
140 |
141 | _ ->
142 | NotFound
143 |
144 |
145 | pageToHash : Page -> String
146 | pageToHash page =
147 | case page of
148 | LeaderBoardPage ->
149 | "#/"
150 |
151 | NotFound ->
152 | "#notfound"
153 |
154 |
155 | locationToMsg : Navigation.Location -> Msg
156 | locationToMsg location =
157 | location.hash
158 | |> hashToPage
159 | |> ChangePage
160 |
161 |
162 | main : Program Never Model Msg
163 | main =
164 | Navigation.program locationToMsg
165 | { init = init
166 | , update = update
167 | , view = view
168 | , subscriptions = subscriptions
169 | }
170 |
--------------------------------------------------------------------------------
/09RLBLogin/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Http
7 | import Json.Encode as JE
8 | import Json.Decode as JD exposing (field)
9 | import Navigation
10 |
11 |
12 | -- model
13 |
14 |
15 | type alias Model =
16 | { username : String
17 | , password : String
18 | , error : Maybe String
19 | }
20 |
21 |
22 | initModel : Model
23 | initModel =
24 | { username = ""
25 | , password = ""
26 | , error = Nothing
27 | }
28 |
29 |
30 | init : ( Model, Cmd Msg )
31 | init =
32 | ( initModel, Cmd.none )
33 |
34 |
35 |
36 | -- update
37 |
38 |
39 | type Msg
40 | = UsernameInput String
41 | | PasswordInput String
42 | | Submit
43 | | Error String
44 | | LoginResponse (Result Http.Error String)
45 |
46 |
47 | url : String
48 | url =
49 | "http://localhost:5000/authenticate"
50 |
51 |
52 | update : Msg -> Model -> ( Model, Cmd Msg, Maybe String )
53 | update msg model =
54 | case msg of
55 | UsernameInput username ->
56 | ( { model | username = username }, Cmd.none, Nothing )
57 |
58 | PasswordInput password ->
59 | ( { model | password = password }, Cmd.none, Nothing )
60 |
61 | Submit ->
62 | let
63 | body =
64 | JE.object
65 | [ ( "username", JE.string model.username )
66 | , ( "password", JE.string model.password )
67 | ]
68 | |> JE.encode 4
69 | |> Http.stringBody "application/json"
70 |
71 | decoder =
72 | field "token" JD.string
73 |
74 | request =
75 | Http.post url body decoder
76 |
77 | cmd =
78 | Http.send LoginResponse request
79 | in
80 | ( model, cmd, Nothing )
81 |
82 | Error error ->
83 | ( { model | error = Just error }, Cmd.none, Nothing )
84 |
85 | LoginResponse (Ok token) ->
86 | ( initModel, Navigation.newUrl "#/", Just token )
87 |
88 | LoginResponse (Err err) ->
89 | let
90 | errMsg =
91 | case err of
92 | Http.BadStatus resp ->
93 | case resp.status.code of
94 | 401 ->
95 | resp.body
96 |
97 | _ ->
98 | resp.status.message
99 |
100 | _ ->
101 | "Login Error!"
102 | in
103 | ( { model | error = Just errMsg }, Cmd.none, Nothing )
104 |
105 |
106 |
107 | -- view
108 |
109 |
110 | view : Model -> Html Msg
111 | view model =
112 | div [ class "main" ]
113 | [ errorPanel model.error
114 | , loginForm model
115 | ]
116 |
117 |
118 | loginForm : Model -> Html Msg
119 | loginForm model =
120 | Html.form [ class "add-runner", onSubmit Submit ]
121 | [ fieldset []
122 | [ legend [] [ text "Login" ]
123 | , div []
124 | [ label [] [ text "User Name" ]
125 | , input
126 | [ type_ "text"
127 | , value model.username
128 | , onInput UsernameInput
129 | ]
130 | []
131 | ]
132 | , div []
133 | [ label [] [ text "Password" ]
134 | , input
135 | [ type_ "password"
136 | , value model.password
137 | , onInput PasswordInput
138 | ]
139 | []
140 | ]
141 | , div []
142 | [ label [] []
143 | , button [ type_ "submit" ] [ text "Login" ]
144 | ]
145 | ]
146 | ]
147 |
148 |
149 | errorPanel : Maybe String -> Html a
150 | errorPanel error =
151 | case error of
152 | Nothing ->
153 | text ""
154 |
155 | Just msg ->
156 | div [ class "error" ]
157 | [ text msg ]
158 |
159 |
160 | subscriptions : Model -> Sub Msg
161 | subscriptions model =
162 | Sub.none
163 |
--------------------------------------------------------------------------------
/11RLBLogout/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Http
7 | import Json.Encode as JE
8 | import Json.Decode as JD exposing (field)
9 | import Navigation
10 |
11 |
12 | -- model
13 |
14 |
15 | type alias Model =
16 | { username : String
17 | , password : String
18 | , error : Maybe String
19 | }
20 |
21 |
22 | initModel : Model
23 | initModel =
24 | { username = ""
25 | , password = ""
26 | , error = Nothing
27 | }
28 |
29 |
30 | init : ( Model, Cmd Msg )
31 | init =
32 | ( initModel, Cmd.none )
33 |
34 |
35 |
36 | -- update
37 |
38 |
39 | type Msg
40 | = UsernameInput String
41 | | PasswordInput String
42 | | Submit
43 | | Error String
44 | | LoginResponse (Result Http.Error String)
45 |
46 |
47 | url : String
48 | url =
49 | "http://localhost:5000/authenticate"
50 |
51 |
52 | update : Msg -> Model -> ( Model, Cmd Msg, Maybe String )
53 | update msg model =
54 | case msg of
55 | UsernameInput username ->
56 | ( { model | username = username }, Cmd.none, Nothing )
57 |
58 | PasswordInput password ->
59 | ( { model | password = password }, Cmd.none, Nothing )
60 |
61 | Submit ->
62 | let
63 | body =
64 | JE.object
65 | [ ( "username", JE.string model.username )
66 | , ( "password", JE.string model.password )
67 | ]
68 | |> JE.encode 4
69 | |> Http.stringBody "application/json"
70 |
71 | decoder =
72 | field "token" JD.string
73 |
74 | request =
75 | Http.post url body decoder
76 |
77 | cmd =
78 | Http.send LoginResponse request
79 | in
80 | ( model, cmd, Nothing )
81 |
82 | Error error ->
83 | ( { model | error = Just error }, Cmd.none, Nothing )
84 |
85 | LoginResponse (Ok token) ->
86 | ( initModel, Navigation.newUrl "#/", Just token )
87 |
88 | LoginResponse (Err err) ->
89 | let
90 | errMsg =
91 | case err of
92 | Http.BadStatus resp ->
93 | case resp.status.code of
94 | 401 ->
95 | resp.body
96 |
97 | _ ->
98 | resp.status.message
99 |
100 | _ ->
101 | "Login Error!"
102 | in
103 | ( { model | error = Just errMsg }, Cmd.none, Nothing )
104 |
105 |
106 |
107 | -- view
108 |
109 |
110 | view : Model -> Html Msg
111 | view model =
112 | div [ class "main" ]
113 | [ errorPanel model.error
114 | , loginForm model
115 | ]
116 |
117 |
118 | loginForm : Model -> Html Msg
119 | loginForm model =
120 | Html.form [ class "add-runner", onSubmit Submit ]
121 | [ fieldset []
122 | [ legend [] [ text "Login" ]
123 | , div []
124 | [ label [] [ text "User Name" ]
125 | , input
126 | [ type_ "text"
127 | , value model.username
128 | , onInput UsernameInput
129 | ]
130 | []
131 | ]
132 | , div []
133 | [ label [] [ text "Password" ]
134 | , input
135 | [ type_ "password"
136 | , value model.password
137 | , onInput PasswordInput
138 | ]
139 | []
140 | ]
141 | , div []
142 | [ label [] []
143 | , button [ type_ "submit" ] [ text "Login" ]
144 | ]
145 | ]
146 | ]
147 |
148 |
149 | errorPanel : Maybe String -> Html a
150 | errorPanel error =
151 | case error of
152 | Nothing ->
153 | text ""
154 |
155 | Just msg ->
156 | div [ class "error" ]
157 | [ text msg ]
158 |
159 |
160 | subscriptions : Model -> Sub Msg
161 | subscriptions model =
162 | Sub.none
163 |
--------------------------------------------------------------------------------
/10RLBLoginToken/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Http
7 | import Json.Encode as JE
8 | import Json.Decode as JD exposing (field)
9 | import Navigation
10 |
11 |
12 | -- model
13 |
14 |
15 | type alias Model =
16 | { username : String
17 | , password : String
18 | , error : Maybe String
19 | }
20 |
21 |
22 | initModel : Model
23 | initModel =
24 | { username = ""
25 | , password = ""
26 | , error = Nothing
27 | }
28 |
29 |
30 | init : ( Model, Cmd Msg )
31 | init =
32 | ( initModel, Cmd.none )
33 |
34 |
35 |
36 | -- update
37 |
38 |
39 | type Msg
40 | = UsernameInput String
41 | | PasswordInput String
42 | | Submit
43 | | Error String
44 | | LoginResponse (Result Http.Error String)
45 |
46 |
47 | url : String
48 | url =
49 | "http://localhost:5000/authenticate"
50 |
51 |
52 | update : Msg -> Model -> ( Model, Cmd Msg, Maybe String )
53 | update msg model =
54 | case msg of
55 | UsernameInput username ->
56 | ( { model | username = username }, Cmd.none, Nothing )
57 |
58 | PasswordInput password ->
59 | ( { model | password = password }, Cmd.none, Nothing )
60 |
61 | Submit ->
62 | let
63 | body =
64 | JE.object
65 | [ ( "username", JE.string model.username )
66 | , ( "password", JE.string model.password )
67 | ]
68 | |> JE.encode 4
69 | |> Http.stringBody "application/json"
70 |
71 | decoder =
72 | field "token" JD.string
73 |
74 | request =
75 | Http.post url body decoder
76 |
77 | cmd =
78 | Http.send LoginResponse request
79 | in
80 | ( model, cmd, Nothing )
81 |
82 | Error error ->
83 | ( { model | error = Just error }, Cmd.none, Nothing )
84 |
85 | LoginResponse (Ok token) ->
86 | ( initModel, Navigation.newUrl "#/", Just token )
87 |
88 | LoginResponse (Err err) ->
89 | let
90 | errMsg =
91 | case err of
92 | Http.BadStatus resp ->
93 | case resp.status.code of
94 | 401 ->
95 | resp.body
96 |
97 | _ ->
98 | resp.status.message
99 |
100 | _ ->
101 | "Login Error!"
102 | in
103 | ( { model | error = Just errMsg }, Cmd.none, Nothing )
104 |
105 |
106 |
107 | -- view
108 |
109 |
110 | view : Model -> Html Msg
111 | view model =
112 | div [ class "main" ]
113 | [ errorPanel model.error
114 | , loginForm model
115 | ]
116 |
117 |
118 | loginForm : Model -> Html Msg
119 | loginForm model =
120 | Html.form [ class "add-runner", onSubmit Submit ]
121 | [ fieldset []
122 | [ legend [] [ text "Login" ]
123 | , div []
124 | [ label [] [ text "User Name" ]
125 | , input
126 | [ type_ "text"
127 | , value model.username
128 | , onInput UsernameInput
129 | ]
130 | []
131 | ]
132 | , div []
133 | [ label [] [ text "Password" ]
134 | , input
135 | [ type_ "password"
136 | , value model.password
137 | , onInput PasswordInput
138 | ]
139 | []
140 | ]
141 | , div []
142 | [ label [] []
143 | , button [ type_ "submit" ] [ text "Login" ]
144 | ]
145 | ]
146 | ]
147 |
148 |
149 | errorPanel : Maybe String -> Html a
150 | errorPanel error =
151 | case error of
152 | Nothing ->
153 | text ""
154 |
155 | Just msg ->
156 | div [ class "error" ]
157 | [ text msg ]
158 |
159 |
160 | subscriptions : Model -> Sub Msg
161 | subscriptions model =
162 | Sub.none
163 |
--------------------------------------------------------------------------------
/13RLBAddRunner/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Http
7 | import Json.Encode as JE
8 | import Json.Decode as JD exposing (field)
9 | import Navigation
10 |
11 |
12 | -- model
13 |
14 |
15 | type alias Model =
16 | { username : String
17 | , password : String
18 | , error : Maybe String
19 | }
20 |
21 |
22 | initModel : Model
23 | initModel =
24 | { username = ""
25 | , password = ""
26 | , error = Nothing
27 | }
28 |
29 |
30 | init : ( Model, Cmd Msg )
31 | init =
32 | ( initModel, Cmd.none )
33 |
34 |
35 |
36 | -- update
37 |
38 |
39 | type Msg
40 | = UsernameInput String
41 | | PasswordInput String
42 | | Submit
43 | | Error String
44 | | LoginResponse (Result Http.Error String)
45 |
46 |
47 | url : String
48 | url =
49 | "http://localhost:5000/authenticate"
50 |
51 |
52 | update : Msg -> Model -> ( Model, Cmd Msg, Maybe String )
53 | update msg model =
54 | case msg of
55 | UsernameInput username ->
56 | ( { model | username = username }, Cmd.none, Nothing )
57 |
58 | PasswordInput password ->
59 | ( { model | password = password }, Cmd.none, Nothing )
60 |
61 | Submit ->
62 | let
63 | body =
64 | JE.object
65 | [ ( "username", JE.string model.username )
66 | , ( "password", JE.string model.password )
67 | ]
68 | |> JE.encode 4
69 | |> Http.stringBody "application/json"
70 |
71 | decoder =
72 | field "token" JD.string
73 |
74 | request =
75 | Http.post url body decoder
76 |
77 | cmd =
78 | Http.send LoginResponse request
79 | in
80 | ( model, cmd, Nothing )
81 |
82 | Error error ->
83 | ( { model | error = Just error }, Cmd.none, Nothing )
84 |
85 | LoginResponse (Ok token) ->
86 | ( initModel, Navigation.newUrl "#/", Just token )
87 |
88 | LoginResponse (Err err) ->
89 | let
90 | errMsg =
91 | case err of
92 | Http.BadStatus resp ->
93 | case resp.status.code of
94 | 401 ->
95 | resp.body
96 |
97 | _ ->
98 | resp.status.message
99 |
100 | _ ->
101 | "Login Error!"
102 | in
103 | ( { model | error = Just errMsg }, Cmd.none, Nothing )
104 |
105 |
106 |
107 | -- view
108 |
109 |
110 | view : Model -> Html Msg
111 | view model =
112 | div [ class "main" ]
113 | [ errorPanel model.error
114 | , loginForm model
115 | ]
116 |
117 |
118 | loginForm : Model -> Html Msg
119 | loginForm model =
120 | Html.form [ class "add-runner", onSubmit Submit ]
121 | [ fieldset []
122 | [ legend [] [ text "Login" ]
123 | , div []
124 | [ label [] [ text "User Name" ]
125 | , input
126 | [ type_ "text"
127 | , value model.username
128 | , onInput UsernameInput
129 | ]
130 | []
131 | ]
132 | , div []
133 | [ label [] [ text "Password" ]
134 | , input
135 | [ type_ "password"
136 | , value model.password
137 | , onInput PasswordInput
138 | ]
139 | []
140 | ]
141 | , div []
142 | [ label [] []
143 | , button [ type_ "submit" ] [ text "Login" ]
144 | ]
145 | ]
146 | ]
147 |
148 |
149 | errorPanel : Maybe String -> Html a
150 | errorPanel error =
151 | case error of
152 | Nothing ->
153 | text ""
154 |
155 | Just msg ->
156 | div [ class "error" ]
157 | [ text msg ]
158 |
159 |
160 | subscriptions : Model -> Sub Msg
161 | subscriptions model =
162 | Sub.none
163 |
--------------------------------------------------------------------------------
/14RLBWebsocket/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Http
7 | import Json.Encode as JE
8 | import Json.Decode as JD exposing (field)
9 | import Navigation
10 |
11 |
12 | -- model
13 |
14 |
15 | type alias Model =
16 | { username : String
17 | , password : String
18 | , error : Maybe String
19 | }
20 |
21 |
22 | initModel : Model
23 | initModel =
24 | { username = ""
25 | , password = ""
26 | , error = Nothing
27 | }
28 |
29 |
30 | init : ( Model, Cmd Msg )
31 | init =
32 | ( initModel, Cmd.none )
33 |
34 |
35 |
36 | -- update
37 |
38 |
39 | type Msg
40 | = UsernameInput String
41 | | PasswordInput String
42 | | Submit
43 | | Error String
44 | | LoginResponse (Result Http.Error String)
45 |
46 |
47 | url : String
48 | url =
49 | "http://localhost:5000/authenticate"
50 |
51 |
52 | update : Msg -> Model -> ( Model, Cmd Msg, Maybe String )
53 | update msg model =
54 | case msg of
55 | UsernameInput username ->
56 | ( { model | username = username }, Cmd.none, Nothing )
57 |
58 | PasswordInput password ->
59 | ( { model | password = password }, Cmd.none, Nothing )
60 |
61 | Submit ->
62 | let
63 | body =
64 | JE.object
65 | [ ( "username", JE.string model.username )
66 | , ( "password", JE.string model.password )
67 | ]
68 | |> JE.encode 4
69 | |> Http.stringBody "application/json"
70 |
71 | decoder =
72 | field "token" JD.string
73 |
74 | request =
75 | Http.post url body decoder
76 |
77 | cmd =
78 | Http.send LoginResponse request
79 | in
80 | ( model, cmd, Nothing )
81 |
82 | Error error ->
83 | ( { model | error = Just error }, Cmd.none, Nothing )
84 |
85 | LoginResponse (Ok token) ->
86 | ( initModel, Navigation.newUrl "#/", Just token )
87 |
88 | LoginResponse (Err err) ->
89 | let
90 | errMsg =
91 | case err of
92 | Http.BadStatus resp ->
93 | case resp.status.code of
94 | 401 ->
95 | resp.body
96 |
97 | _ ->
98 | resp.status.message
99 |
100 | _ ->
101 | "Login Error!"
102 | in
103 | ( { model | error = Just errMsg }, Cmd.none, Nothing )
104 |
105 |
106 |
107 | -- view
108 |
109 |
110 | view : Model -> Html Msg
111 | view model =
112 | div [ class "main" ]
113 | [ errorPanel model.error
114 | , loginForm model
115 | ]
116 |
117 |
118 | loginForm : Model -> Html Msg
119 | loginForm model =
120 | Html.form [ class "add-runner", onSubmit Submit ]
121 | [ fieldset []
122 | [ legend [] [ text "Login" ]
123 | , div []
124 | [ label [] [ text "User Name" ]
125 | , input
126 | [ type_ "text"
127 | , value model.username
128 | , onInput UsernameInput
129 | ]
130 | []
131 | ]
132 | , div []
133 | [ label [] [ text "Password" ]
134 | , input
135 | [ type_ "password"
136 | , value model.password
137 | , onInput PasswordInput
138 | ]
139 | []
140 | ]
141 | , div []
142 | [ label [] []
143 | , button [ type_ "submit" ] [ text "Login" ]
144 | ]
145 | ]
146 | ]
147 |
148 |
149 | errorPanel : Maybe String -> Html a
150 | errorPanel error =
151 | case error of
152 | Nothing ->
153 | text ""
154 |
155 | Just msg ->
156 | div [ class "error" ]
157 | [ text msg ]
158 |
159 |
160 | subscriptions : Model -> Sub Msg
161 | subscriptions model =
162 | Sub.none
163 |
--------------------------------------------------------------------------------
/16RLBFilterRunner/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Http
7 | import Json.Encode as JE
8 | import Json.Decode as JD exposing (field)
9 | import Navigation
10 |
11 |
12 | -- model
13 |
14 |
15 | type alias Model =
16 | { username : String
17 | , password : String
18 | , error : Maybe String
19 | }
20 |
21 |
22 | initModel : Model
23 | initModel =
24 | { username = ""
25 | , password = ""
26 | , error = Nothing
27 | }
28 |
29 |
30 | init : ( Model, Cmd Msg )
31 | init =
32 | ( initModel, Cmd.none )
33 |
34 |
35 |
36 | -- update
37 |
38 |
39 | type Msg
40 | = UsernameInput String
41 | | PasswordInput String
42 | | Submit
43 | | Error String
44 | | LoginResponse (Result Http.Error String)
45 |
46 |
47 | url : String
48 | url =
49 | "http://localhost:5000/authenticate"
50 |
51 |
52 | update : Msg -> Model -> ( Model, Cmd Msg, Maybe String )
53 | update msg model =
54 | case msg of
55 | UsernameInput username ->
56 | ( { model | username = username }, Cmd.none, Nothing )
57 |
58 | PasswordInput password ->
59 | ( { model | password = password }, Cmd.none, Nothing )
60 |
61 | Submit ->
62 | let
63 | body =
64 | JE.object
65 | [ ( "username", JE.string model.username )
66 | , ( "password", JE.string model.password )
67 | ]
68 | |> JE.encode 4
69 | |> Http.stringBody "application/json"
70 |
71 | decoder =
72 | field "token" JD.string
73 |
74 | request =
75 | Http.post url body decoder
76 |
77 | cmd =
78 | Http.send LoginResponse request
79 | in
80 | ( model, cmd, Nothing )
81 |
82 | Error error ->
83 | ( { model | error = Just error }, Cmd.none, Nothing )
84 |
85 | LoginResponse (Ok token) ->
86 | ( initModel, Navigation.newUrl "#/", Just token )
87 |
88 | LoginResponse (Err err) ->
89 | let
90 | errMsg =
91 | case err of
92 | Http.BadStatus resp ->
93 | case resp.status.code of
94 | 401 ->
95 | resp.body
96 |
97 | _ ->
98 | resp.status.message
99 |
100 | _ ->
101 | "Login Error!"
102 | in
103 | ( { model | error = Just errMsg }, Cmd.none, Nothing )
104 |
105 |
106 |
107 | -- view
108 |
109 |
110 | view : Model -> Html Msg
111 | view model =
112 | div [ class "main" ]
113 | [ errorPanel model.error
114 | , loginForm model
115 | ]
116 |
117 |
118 | loginForm : Model -> Html Msg
119 | loginForm model =
120 | Html.form [ class "add-runner", onSubmit Submit ]
121 | [ fieldset []
122 | [ legend [] [ text "Login" ]
123 | , div []
124 | [ label [] [ text "User Name" ]
125 | , input
126 | [ type_ "text"
127 | , value model.username
128 | , onInput UsernameInput
129 | ]
130 | []
131 | ]
132 | , div []
133 | [ label [] [ text "Password" ]
134 | , input
135 | [ type_ "password"
136 | , value model.password
137 | , onInput PasswordInput
138 | ]
139 | []
140 | ]
141 | , div []
142 | [ label [] []
143 | , button [ type_ "submit" ] [ text "Login" ]
144 | ]
145 | ]
146 | ]
147 |
148 |
149 | errorPanel : Maybe String -> Html a
150 | errorPanel error =
151 | case error of
152 | Nothing ->
153 | text ""
154 |
155 | Just msg ->
156 | div [ class "error" ]
157 | [ text msg ]
158 |
159 |
160 | subscriptions : Model -> Sub Msg
161 | subscriptions model =
162 | Sub.none
163 |
--------------------------------------------------------------------------------
/12RLBLockRunnerPage/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Http
7 | import Json.Encode as JE
8 | import Json.Decode as JD exposing (field)
9 | import Navigation
10 |
11 |
12 | -- model
13 |
14 |
15 | type alias Model =
16 | { username : String
17 | , password : String
18 | , error : Maybe String
19 | }
20 |
21 |
22 | initModel : Model
23 | initModel =
24 | { username = ""
25 | , password = ""
26 | , error = Nothing
27 | }
28 |
29 |
30 | init : ( Model, Cmd Msg )
31 | init =
32 | ( initModel, Cmd.none )
33 |
34 |
35 |
36 | -- update
37 |
38 |
39 | type Msg
40 | = UsernameInput String
41 | | PasswordInput String
42 | | Submit
43 | | Error String
44 | | LoginResponse (Result Http.Error String)
45 |
46 |
47 | url : String
48 | url =
49 | "http://localhost:5000/authenticate"
50 |
51 |
52 | update : Msg -> Model -> ( Model, Cmd Msg, Maybe String )
53 | update msg model =
54 | case msg of
55 | UsernameInput username ->
56 | ( { model | username = username }, Cmd.none, Nothing )
57 |
58 | PasswordInput password ->
59 | ( { model | password = password }, Cmd.none, Nothing )
60 |
61 | Submit ->
62 | let
63 | body =
64 | JE.object
65 | [ ( "username", JE.string model.username )
66 | , ( "password", JE.string model.password )
67 | ]
68 | |> JE.encode 4
69 | |> Http.stringBody "application/json"
70 |
71 | decoder =
72 | field "token" JD.string
73 |
74 | request =
75 | Http.post url body decoder
76 |
77 | cmd =
78 | Http.send LoginResponse request
79 | in
80 | ( model, cmd, Nothing )
81 |
82 | Error error ->
83 | ( { model | error = Just error }, Cmd.none, Nothing )
84 |
85 | LoginResponse (Ok token) ->
86 | ( initModel, Navigation.newUrl "#/", Just token )
87 |
88 | LoginResponse (Err err) ->
89 | let
90 | errMsg =
91 | case err of
92 | Http.BadStatus resp ->
93 | case resp.status.code of
94 | 401 ->
95 | resp.body
96 |
97 | _ ->
98 | resp.status.message
99 |
100 | _ ->
101 | "Login Error!"
102 | in
103 | ( { model | error = Just errMsg }, Cmd.none, Nothing )
104 |
105 |
106 |
107 | -- view
108 |
109 |
110 | view : Model -> Html Msg
111 | view model =
112 | div [ class "main" ]
113 | [ errorPanel model.error
114 | , loginForm model
115 | ]
116 |
117 |
118 | loginForm : Model -> Html Msg
119 | loginForm model =
120 | Html.form [ class "add-runner", onSubmit Submit ]
121 | [ fieldset []
122 | [ legend [] [ text "Login" ]
123 | , div []
124 | [ label [] [ text "User Name" ]
125 | , input
126 | [ type_ "text"
127 | , value model.username
128 | , onInput UsernameInput
129 | ]
130 | []
131 | ]
132 | , div []
133 | [ label [] [ text "Password" ]
134 | , input
135 | [ type_ "password"
136 | , value model.password
137 | , onInput PasswordInput
138 | ]
139 | []
140 | ]
141 | , div []
142 | [ label [] []
143 | , button [ type_ "submit" ] [ text "Login" ]
144 | ]
145 | ]
146 | ]
147 |
148 |
149 | errorPanel : Maybe String -> Html a
150 | errorPanel error =
151 | case error of
152 | Nothing ->
153 | text ""
154 |
155 | Just msg ->
156 | div [ class "error" ]
157 | [ text msg ]
158 |
159 |
160 | subscriptions : Model -> Sub Msg
161 | subscriptions model =
162 | Sub.none
163 |
--------------------------------------------------------------------------------
/15RLBEstimatedDistance/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Http
7 | import Json.Encode as JE
8 | import Json.Decode as JD exposing (field)
9 | import Navigation
10 |
11 |
12 | -- model
13 |
14 |
15 | type alias Model =
16 | { username : String
17 | , password : String
18 | , error : Maybe String
19 | }
20 |
21 |
22 | initModel : Model
23 | initModel =
24 | { username = ""
25 | , password = ""
26 | , error = Nothing
27 | }
28 |
29 |
30 | init : ( Model, Cmd Msg )
31 | init =
32 | ( initModel, Cmd.none )
33 |
34 |
35 |
36 | -- update
37 |
38 |
39 | type Msg
40 | = UsernameInput String
41 | | PasswordInput String
42 | | Submit
43 | | Error String
44 | | LoginResponse (Result Http.Error String)
45 |
46 |
47 | url : String
48 | url =
49 | "http://localhost:5000/authenticate"
50 |
51 |
52 | update : Msg -> Model -> ( Model, Cmd Msg, Maybe String )
53 | update msg model =
54 | case msg of
55 | UsernameInput username ->
56 | ( { model | username = username }, Cmd.none, Nothing )
57 |
58 | PasswordInput password ->
59 | ( { model | password = password }, Cmd.none, Nothing )
60 |
61 | Submit ->
62 | let
63 | body =
64 | JE.object
65 | [ ( "username", JE.string model.username )
66 | , ( "password", JE.string model.password )
67 | ]
68 | |> JE.encode 4
69 | |> Http.stringBody "application/json"
70 |
71 | decoder =
72 | field "token" JD.string
73 |
74 | request =
75 | Http.post url body decoder
76 |
77 | cmd =
78 | Http.send LoginResponse request
79 | in
80 | ( model, cmd, Nothing )
81 |
82 | Error error ->
83 | ( { model | error = Just error }, Cmd.none, Nothing )
84 |
85 | LoginResponse (Ok token) ->
86 | ( initModel, Navigation.newUrl "#/", Just token )
87 |
88 | LoginResponse (Err err) ->
89 | let
90 | errMsg =
91 | case err of
92 | Http.BadStatus resp ->
93 | case resp.status.code of
94 | 401 ->
95 | resp.body
96 |
97 | _ ->
98 | resp.status.message
99 |
100 | _ ->
101 | "Login Error!"
102 | in
103 | ( { model | error = Just errMsg }, Cmd.none, Nothing )
104 |
105 |
106 |
107 | -- view
108 |
109 |
110 | view : Model -> Html Msg
111 | view model =
112 | div [ class "main" ]
113 | [ errorPanel model.error
114 | , loginForm model
115 | ]
116 |
117 |
118 | loginForm : Model -> Html Msg
119 | loginForm model =
120 | Html.form [ class "add-runner", onSubmit Submit ]
121 | [ fieldset []
122 | [ legend [] [ text "Login" ]
123 | , div []
124 | [ label [] [ text "User Name" ]
125 | , input
126 | [ type_ "text"
127 | , value model.username
128 | , onInput UsernameInput
129 | ]
130 | []
131 | ]
132 | , div []
133 | [ label [] [ text "Password" ]
134 | , input
135 | [ type_ "password"
136 | , value model.password
137 | , onInput PasswordInput
138 | ]
139 | []
140 | ]
141 | , div []
142 | [ label [] []
143 | , button [ type_ "submit" ] [ text "Login" ]
144 | ]
145 | ]
146 | ]
147 |
148 |
149 | errorPanel : Maybe String -> Html a
150 | errorPanel error =
151 | case error of
152 | Nothing ->
153 | text ""
154 |
155 | Just msg ->
156 | div [ class "error" ]
157 | [ text msg ]
158 |
159 |
160 | subscriptions : Model -> Sub Msg
161 | subscriptions model =
162 | Sub.none
163 |
--------------------------------------------------------------------------------
/13RLBAddRunner/completed/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Http
7 | import Json.Encode as JE
8 | import Json.Decode as JD exposing (field)
9 | import Navigation
10 |
11 |
12 | -- model
13 |
14 |
15 | type alias Model =
16 | { username : String
17 | , password : String
18 | , error : Maybe String
19 | }
20 |
21 |
22 | initModel : Model
23 | initModel =
24 | { username = ""
25 | , password = ""
26 | , error = Nothing
27 | }
28 |
29 |
30 | init : ( Model, Cmd Msg )
31 | init =
32 | ( initModel, Cmd.none )
33 |
34 |
35 |
36 | -- update
37 |
38 |
39 | type Msg
40 | = UsernameInput String
41 | | PasswordInput String
42 | | Submit
43 | | Error String
44 | | LoginResponse (Result Http.Error String)
45 |
46 |
47 | url : String
48 | url =
49 | "http://localhost:5000/authenticate"
50 |
51 |
52 | update : Msg -> Model -> ( Model, Cmd Msg, Maybe String )
53 | update msg model =
54 | case msg of
55 | UsernameInput username ->
56 | ( { model | username = username }, Cmd.none, Nothing )
57 |
58 | PasswordInput password ->
59 | ( { model | password = password }, Cmd.none, Nothing )
60 |
61 | Submit ->
62 | let
63 | body =
64 | JE.object
65 | [ ( "username", JE.string model.username )
66 | , ( "password", JE.string model.password )
67 | ]
68 | |> JE.encode 4
69 | |> Http.stringBody "application/json"
70 |
71 | decoder =
72 | field "token" JD.string
73 |
74 | request =
75 | Http.post url body decoder
76 |
77 | cmd =
78 | Http.send LoginResponse request
79 | in
80 | ( model, cmd, Nothing )
81 |
82 | Error error ->
83 | ( { model | error = Just error }, Cmd.none, Nothing )
84 |
85 | LoginResponse (Ok token) ->
86 | ( initModel, Navigation.newUrl "#/", Just token )
87 |
88 | LoginResponse (Err err) ->
89 | let
90 | errMsg =
91 | case err of
92 | Http.BadStatus resp ->
93 | case resp.status.code of
94 | 401 ->
95 | resp.body
96 |
97 | _ ->
98 | resp.status.message
99 |
100 | _ ->
101 | "Login Error!"
102 | in
103 | ( { model | error = Just errMsg }, Cmd.none, Nothing )
104 |
105 |
106 |
107 | -- view
108 |
109 |
110 | view : Model -> Html Msg
111 | view model =
112 | div [ class "main" ]
113 | [ errorPanel model.error
114 | , loginForm model
115 | ]
116 |
117 |
118 | loginForm : Model -> Html Msg
119 | loginForm model =
120 | Html.form [ class "add-runner", onSubmit Submit ]
121 | [ fieldset []
122 | [ legend [] [ text "Login" ]
123 | , div []
124 | [ label [] [ text "User Name" ]
125 | , input
126 | [ type_ "text"
127 | , value model.username
128 | , onInput UsernameInput
129 | ]
130 | []
131 | ]
132 | , div []
133 | [ label [] [ text "Password" ]
134 | , input
135 | [ type_ "password"
136 | , value model.password
137 | , onInput PasswordInput
138 | ]
139 | []
140 | ]
141 | , div []
142 | [ label [] []
143 | , button [ type_ "submit" ] [ text "Login" ]
144 | ]
145 | ]
146 | ]
147 |
148 |
149 | errorPanel : Maybe String -> Html a
150 | errorPanel error =
151 | case error of
152 | Nothing ->
153 | text ""
154 |
155 | Just msg ->
156 | div [ class "error" ]
157 | [ text msg ]
158 |
159 |
160 | subscriptions : Model -> Sub Msg
161 | subscriptions model =
162 | Sub.none
163 |
--------------------------------------------------------------------------------
/14RLBWebsocket/completed/src/Login.elm:
--------------------------------------------------------------------------------
1 | module Login exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Http
7 | import Json.Encode as JE
8 | import Json.Decode as JD exposing (field)
9 | import Navigation
10 |
11 |
12 | -- model
13 |
14 |
15 | type alias Model =
16 | { username : String
17 | , password : String
18 | , error : Maybe String
19 | }
20 |
21 |
22 | initModel : Model
23 | initModel =
24 | { username = ""
25 | , password = ""
26 | , error = Nothing
27 | }
28 |
29 |
30 | init : ( Model, Cmd Msg )
31 | init =
32 | ( initModel, Cmd.none )
33 |
34 |
35 |
36 | -- update
37 |
38 |
39 | type Msg
40 | = UsernameInput String
41 | | PasswordInput String
42 | | Submit
43 | | Error String
44 | | LoginResponse (Result Http.Error String)
45 |
46 |
47 | url : String
48 | url =
49 | "http://localhost:5000/authenticate"
50 |
51 |
52 | update : Msg -> Model -> ( Model, Cmd Msg, Maybe String )
53 | update msg model =
54 | case msg of
55 | UsernameInput username ->
56 | ( { model | username = username }, Cmd.none, Nothing )
57 |
58 | PasswordInput password ->
59 | ( { model | password = password }, Cmd.none, Nothing )
60 |
61 | Submit ->
62 | let
63 | body =
64 | JE.object
65 | [ ( "username", JE.string model.username )
66 | , ( "password", JE.string model.password )
67 | ]
68 | |> JE.encode 4
69 | |> Http.stringBody "application/json"
70 |
71 | decoder =
72 | field "token" JD.string
73 |
74 | request =
75 | Http.post url body decoder
76 |
77 | cmd =
78 | Http.send LoginResponse request
79 | in
80 | ( model, cmd, Nothing )
81 |
82 | Error error ->
83 | ( { model | error = Just error }, Cmd.none, Nothing )
84 |
85 | LoginResponse (Ok token) ->
86 | ( initModel, Navigation.newUrl "#/", Just token )
87 |
88 | LoginResponse (Err err) ->
89 | let
90 | errMsg =
91 | case err of
92 | Http.BadStatus resp ->
93 | case resp.status.code of
94 | 401 ->
95 | resp.body
96 |
97 | _ ->
98 | resp.status.message
99 |
100 | _ ->
101 | "Login Error!"
102 | in
103 | ( { model | error = Just errMsg }, Cmd.none, Nothing )
104 |
105 |
106 |
107 | -- view
108 |
109 |
110 | view : Model -> Html Msg
111 | view model =
112 | div [ class "main" ]
113 | [ errorPanel model.error
114 | , loginForm model
115 | ]
116 |
117 |
118 | loginForm : Model -> Html Msg
119 | loginForm model =
120 | Html.form [ class "add-runner", onSubmit Submit ]
121 | [ fieldset []
122 | [ legend [] [ text "Login" ]
123 | , div []
124 | [ label [] [ text "User Name" ]
125 | , input
126 | [ type_ "text"
127 | , value model.username
128 | , onInput UsernameInput
129 | ]
130 | []
131 | ]
132 | , div []
133 | [ label [] [ text "Password" ]
134 | , input
135 | [ type_ "password"
136 | , value model.password
137 | , onInput PasswordInput
138 | ]
139 | []
140 | ]
141 | , div []
142 | [ label [] []
143 | , button [ type_ "submit" ] [ text "Login" ]
144 | ]
145 | ]
146 | ]
147 |
148 |
149 | errorPanel : Maybe String -> Html a
150 | errorPanel error =
151 | case error of
152 | Nothing ->
153 | text ""
154 |
155 | Just msg ->
156 | div [ class "error" ]
157 | [ text msg ]
158 |
159 |
160 | subscriptions : Model -> Sub Msg
161 | subscriptions model =
162 | Sub.none
163 |
--------------------------------------------------------------------------------
/08RLBNavigation/src/Runner.elm:
--------------------------------------------------------------------------------
1 | module Runner exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import String
7 |
8 |
9 | -- model
10 |
11 |
12 | type alias Model =
13 | { id : String
14 | , name : String
15 | , nameError : Maybe String
16 | , location : String
17 | , locationError : Maybe String
18 | , age : String
19 | , ageError : Maybe String
20 | , bib : String
21 | , bibError : Maybe String
22 | , error : Maybe String
23 | }
24 |
25 |
26 | initModel : Model
27 | initModel =
28 | { id = ""
29 | , name = ""
30 | , nameError = Nothing
31 | , location = ""
32 | , locationError = Nothing
33 | , age = ""
34 | , ageError = Nothing
35 | , bib = ""
36 | , bibError = Nothing
37 | , error = Nothing
38 | }
39 |
40 |
41 | init : ( Model, Cmd Msg )
42 | init =
43 | ( initModel, Cmd.none )
44 |
45 |
46 |
47 | -- update
48 |
49 |
50 | type Msg
51 | = NameInput String
52 | | LocationInput String
53 | | AgeInput String
54 | | BibInput String
55 | | Save
56 |
57 |
58 | update : Msg -> Model -> ( Model, Cmd Msg )
59 | update msg model =
60 | case msg of
61 | NameInput name ->
62 | ( { model
63 | | name = name
64 | , nameError = Nothing
65 | }
66 | , Cmd.none
67 | )
68 |
69 | LocationInput location ->
70 | ( { model
71 | | location = location
72 | , locationError = Nothing
73 | }
74 | , Cmd.none
75 | )
76 |
77 | AgeInput age ->
78 | ageInput model age
79 |
80 | BibInput bib ->
81 | bibInput model bib
82 |
83 | Save ->
84 | ( model, Cmd.none )
85 |
86 |
87 | ageInput : Model -> String -> ( Model, Cmd Msg )
88 | ageInput model age =
89 | let
90 | ageInt =
91 | age
92 | |> String.toInt
93 | |> Result.withDefault 0
94 |
95 | ageError =
96 | if ageInt <= 0 then
97 | Just "Must Enter a Positive Number"
98 | else
99 | Nothing
100 | in
101 | ( { model | age = age, ageError = ageError }, Cmd.none )
102 |
103 |
104 | bibInput : Model -> String -> ( Model, Cmd Msg )
105 | bibInput model bib =
106 | let
107 | bibInt =
108 | bib
109 | |> String.toInt
110 | |> Result.withDefault 0
111 |
112 | bibError =
113 | if bibInt <= 0 then
114 | Just "Must Enter a Positive Number"
115 | else
116 | Nothing
117 | in
118 | ( { model | bib = bib, bibError = bibError }, Cmd.none )
119 |
120 |
121 |
122 | -- view
123 |
124 |
125 | view : Model -> Html Msg
126 | view model =
127 | div [ class "main" ]
128 | [ errorPanel model.error
129 | , viewForm model
130 | ]
131 |
132 |
133 | errorPanel : Maybe String -> Html a
134 | errorPanel error =
135 | case error of
136 | Nothing ->
137 | text ""
138 |
139 | Just msg ->
140 | div [ class "error" ]
141 | [ text msg
142 | ]
143 |
144 |
145 | viewForm : Model -> Html Msg
146 | viewForm model =
147 | Html.form [ class "add-runner", onSubmit Save ]
148 | [ fieldset []
149 | [ legend [] [ text "Add / Edit Runner" ]
150 | , div []
151 | [ label [] [ text "Name" ]
152 | , input
153 | [ type_ "text"
154 | , value model.name
155 | , onInput NameInput
156 | ]
157 | []
158 | , span [] [ text <| Maybe.withDefault "" model.nameError ]
159 | ]
160 | , div []
161 | [ label [] [ text "Location" ]
162 | , input
163 | [ type_ "text"
164 | , value model.location
165 | , onInput LocationInput
166 | ]
167 | []
168 | , span [] [ text <| Maybe.withDefault "" model.locationError ]
169 | ]
170 | , div []
171 | [ label [] [ text "Age" ]
172 | , input
173 | [ type_ "text"
174 | , value model.age
175 | , onInput AgeInput
176 | ]
177 | []
178 | , span [] [ text <| Maybe.withDefault "" model.ageError ]
179 | ]
180 | , div []
181 | [ label [] [ text "Bib #" ]
182 | , input
183 | [ type_ "text"
184 | , value model.bib
185 | , onInput BibInput
186 | ]
187 | []
188 | , span [] [ text <| Maybe.withDefault "" model.bibError ]
189 | ]
190 | , div []
191 | [ label [] []
192 | , button [ type_ "submit" ] [ text "Save" ]
193 | ]
194 | ]
195 | ]
196 |
--------------------------------------------------------------------------------
/07RLBStarter/src/Runner.elm:
--------------------------------------------------------------------------------
1 | module Runner exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import String
7 |
8 |
9 | -- model
10 |
11 |
12 | type alias Model =
13 | { id : String
14 | , name : String
15 | , nameError : Maybe String
16 | , location : String
17 | , locationError : Maybe String
18 | , age : String
19 | , ageError : Maybe String
20 | , bib : String
21 | , bibError : Maybe String
22 | , error : Maybe String
23 | }
24 |
25 |
26 | initModel : Model
27 | initModel =
28 | { id = ""
29 | , name = ""
30 | , nameError = Nothing
31 | , location = ""
32 | , locationError = Nothing
33 | , age = ""
34 | , ageError = Nothing
35 | , bib = ""
36 | , bibError = Nothing
37 | , error = Nothing
38 | }
39 |
40 |
41 | init : ( Model, Cmd Msg )
42 | init =
43 | ( initModel, Cmd.none )
44 |
45 |
46 |
47 | -- update
48 |
49 |
50 | type Msg
51 | = NameInput String
52 | | LocationInput String
53 | | AgeInput String
54 | | BibInput String
55 | | Save
56 |
57 |
58 | update : Msg -> Model -> ( Model, Cmd Msg )
59 | update msg model =
60 | case msg of
61 | NameInput name ->
62 | ( { model
63 | | name = name
64 | , nameError = Nothing
65 | }
66 | , Cmd.none
67 | )
68 |
69 | LocationInput location ->
70 | ( { model
71 | | location = location
72 | , locationError = Nothing
73 | }
74 | , Cmd.none
75 | )
76 |
77 | AgeInput age ->
78 | ageInput model age
79 |
80 | BibInput bib ->
81 | bibInput model bib
82 |
83 | Save ->
84 | ( model, Cmd.none )
85 |
86 |
87 | ageInput : Model -> String -> ( Model, Cmd Msg )
88 | ageInput model age =
89 | let
90 | ageInt =
91 | age
92 | |> String.toInt
93 | |> Result.withDefault 0
94 |
95 | ageError =
96 | if ageInt <= 0 then
97 | Just "Must Enter a Positive Number"
98 | else
99 | Nothing
100 | in
101 | ( { model | age = age, ageError = ageError }, Cmd.none )
102 |
103 |
104 | bibInput : Model -> String -> ( Model, Cmd Msg )
105 | bibInput model bib =
106 | let
107 | bibInt =
108 | bib
109 | |> String.toInt
110 | |> Result.withDefault 0
111 |
112 | bibError =
113 | if bibInt <= 0 then
114 | Just "Must Enter a Positive Number"
115 | else
116 | Nothing
117 | in
118 | ( { model | bib = bib, bibError = bibError }, Cmd.none )
119 |
120 |
121 |
122 | -- view
123 |
124 |
125 | view : Model -> Html Msg
126 | view model =
127 | div [ class "main" ]
128 | [ errorPanel model.error
129 | , viewForm model
130 | ]
131 |
132 |
133 | errorPanel : Maybe String -> Html a
134 | errorPanel error =
135 | case error of
136 | Nothing ->
137 | text ""
138 |
139 | Just msg ->
140 | div [ class "error" ]
141 | [ text msg
142 | ]
143 |
144 |
145 | viewForm : Model -> Html Msg
146 | viewForm model =
147 | Html.form [ class "add-runner", onSubmit Save ]
148 | [ fieldset []
149 | [ legend [] [ text "Add / Edit Runner" ]
150 | , div []
151 | [ label [] [ text "Name" ]
152 | , input
153 | [ type_ "text"
154 | , value model.name
155 | , onInput NameInput
156 | ]
157 | []
158 | , span [] [ text <| Maybe.withDefault "" model.nameError ]
159 | ]
160 | , div []
161 | [ label [] [ text "Location" ]
162 | , input
163 | [ type_ "text"
164 | , value model.location
165 | , onInput LocationInput
166 | ]
167 | []
168 | , span [] [ text <| Maybe.withDefault "" model.locationError ]
169 | ]
170 | , div []
171 | [ label [] [ text "Age" ]
172 | , input
173 | [ type_ "text"
174 | , value model.age
175 | , onInput AgeInput
176 | ]
177 | []
178 | , span [] [ text <| Maybe.withDefault "" model.ageError ]
179 | ]
180 | , div []
181 | [ label [] [ text "Bib #" ]
182 | , input
183 | [ type_ "text"
184 | , value model.bib
185 | , onInput BibInput
186 | ]
187 | []
188 | , span [] [ text <| Maybe.withDefault "" model.bibError ]
189 | ]
190 | , div []
191 | [ label [] []
192 | , button [ type_ "submit" ] [ text "Save" ]
193 | ]
194 | ]
195 | ]
196 |
197 |
198 |
199 | -- subscriptions
200 |
201 |
202 | subscriptions : Model -> Sub Msg
203 | subscriptions model =
204 | Sub.none
205 |
--------------------------------------------------------------------------------
/09RLBLogin/src/Runner.elm:
--------------------------------------------------------------------------------
1 | module Runner exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import String
7 |
8 |
9 | -- model
10 |
11 |
12 | type alias Model =
13 | { id : String
14 | , name : String
15 | , nameError : Maybe String
16 | , location : String
17 | , locationError : Maybe String
18 | , age : String
19 | , ageError : Maybe String
20 | , bib : String
21 | , bibError : Maybe String
22 | , error : Maybe String
23 | }
24 |
25 |
26 | initModel : Model
27 | initModel =
28 | { id = ""
29 | , name = ""
30 | , nameError = Nothing
31 | , location = ""
32 | , locationError = Nothing
33 | , age = ""
34 | , ageError = Nothing
35 | , bib = ""
36 | , bibError = Nothing
37 | , error = Nothing
38 | }
39 |
40 |
41 | init : ( Model, Cmd Msg )
42 | init =
43 | ( initModel, Cmd.none )
44 |
45 |
46 |
47 | -- update
48 |
49 |
50 | type Msg
51 | = NameInput String
52 | | LocationInput String
53 | | AgeInput String
54 | | BibInput String
55 | | Save
56 |
57 |
58 | update : Msg -> Model -> ( Model, Cmd Msg )
59 | update msg model =
60 | case msg of
61 | NameInput name ->
62 | ( { model
63 | | name = name
64 | , nameError = Nothing
65 | }
66 | , Cmd.none
67 | )
68 |
69 | LocationInput location ->
70 | ( { model
71 | | location = location
72 | , locationError = Nothing
73 | }
74 | , Cmd.none
75 | )
76 |
77 | AgeInput age ->
78 | ageInput model age
79 |
80 | BibInput bib ->
81 | bibInput model bib
82 |
83 | Save ->
84 | ( model, Cmd.none )
85 |
86 |
87 | ageInput : Model -> String -> ( Model, Cmd Msg )
88 | ageInput model age =
89 | let
90 | ageInt =
91 | age
92 | |> String.toInt
93 | |> Result.withDefault 0
94 |
95 | ageError =
96 | if ageInt <= 0 then
97 | Just "Must Enter a Positive Number"
98 | else
99 | Nothing
100 | in
101 | ( { model | age = age, ageError = ageError }, Cmd.none )
102 |
103 |
104 | bibInput : Model -> String -> ( Model, Cmd Msg )
105 | bibInput model bib =
106 | let
107 | bibInt =
108 | bib
109 | |> String.toInt
110 | |> Result.withDefault 0
111 |
112 | bibError =
113 | if bibInt <= 0 then
114 | Just "Must Enter a Positive Number"
115 | else
116 | Nothing
117 | in
118 | ( { model | bib = bib, bibError = bibError }, Cmd.none )
119 |
120 |
121 |
122 | -- view
123 |
124 |
125 | view : Model -> Html Msg
126 | view model =
127 | div [ class "main" ]
128 | [ errorPanel model.error
129 | , viewForm model
130 | ]
131 |
132 |
133 | errorPanel : Maybe String -> Html a
134 | errorPanel error =
135 | case error of
136 | Nothing ->
137 | text ""
138 |
139 | Just msg ->
140 | div [ class "error" ]
141 | [ text msg
142 | ]
143 |
144 |
145 | viewForm : Model -> Html Msg
146 | viewForm model =
147 | Html.form [ class "add-runner", onSubmit Save ]
148 | [ fieldset []
149 | [ legend [] [ text "Add / Edit Runner" ]
150 | , div []
151 | [ label [] [ text "Name" ]
152 | , input
153 | [ type_ "text"
154 | , value model.name
155 | , onInput NameInput
156 | ]
157 | []
158 | , span [] [ text <| Maybe.withDefault "" model.nameError ]
159 | ]
160 | , div []
161 | [ label [] [ text "Location" ]
162 | , input
163 | [ type_ "text"
164 | , value model.location
165 | , onInput LocationInput
166 | ]
167 | []
168 | , span [] [ text <| Maybe.withDefault "" model.locationError ]
169 | ]
170 | , div []
171 | [ label [] [ text "Age" ]
172 | , input
173 | [ type_ "text"
174 | , value model.age
175 | , onInput AgeInput
176 | ]
177 | []
178 | , span [] [ text <| Maybe.withDefault "" model.ageError ]
179 | ]
180 | , div []
181 | [ label [] [ text "Bib #" ]
182 | , input
183 | [ type_ "text"
184 | , value model.bib
185 | , onInput BibInput
186 | ]
187 | []
188 | , span [] [ text <| Maybe.withDefault "" model.bibError ]
189 | ]
190 | , div []
191 | [ label [] []
192 | , button [ type_ "submit" ] [ text "Save" ]
193 | ]
194 | ]
195 | ]
196 |
197 |
198 |
199 | -- subscriptions
200 |
201 |
202 | subscriptions : Model -> Sub Msg
203 | subscriptions model =
204 | Sub.none
205 |
--------------------------------------------------------------------------------
/11RLBLogout/src/Runner.elm:
--------------------------------------------------------------------------------
1 | module Runner exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import String
7 |
8 |
9 | -- model
10 |
11 |
12 | type alias Model =
13 | { id : String
14 | , name : String
15 | , nameError : Maybe String
16 | , location : String
17 | , locationError : Maybe String
18 | , age : String
19 | , ageError : Maybe String
20 | , bib : String
21 | , bibError : Maybe String
22 | , error : Maybe String
23 | }
24 |
25 |
26 | initModel : Model
27 | initModel =
28 | { id = ""
29 | , name = ""
30 | , nameError = Nothing
31 | , location = ""
32 | , locationError = Nothing
33 | , age = ""
34 | , ageError = Nothing
35 | , bib = ""
36 | , bibError = Nothing
37 | , error = Nothing
38 | }
39 |
40 |
41 | init : ( Model, Cmd Msg )
42 | init =
43 | ( initModel, Cmd.none )
44 |
45 |
46 |
47 | -- update
48 |
49 |
50 | type Msg
51 | = NameInput String
52 | | LocationInput String
53 | | AgeInput String
54 | | BibInput String
55 | | Save
56 |
57 |
58 | update : Msg -> Model -> ( Model, Cmd Msg )
59 | update msg model =
60 | case msg of
61 | NameInput name ->
62 | ( { model
63 | | name = name
64 | , nameError = Nothing
65 | }
66 | , Cmd.none
67 | )
68 |
69 | LocationInput location ->
70 | ( { model
71 | | location = location
72 | , locationError = Nothing
73 | }
74 | , Cmd.none
75 | )
76 |
77 | AgeInput age ->
78 | ageInput model age
79 |
80 | BibInput bib ->
81 | bibInput model bib
82 |
83 | Save ->
84 | ( model, Cmd.none )
85 |
86 |
87 | ageInput : Model -> String -> ( Model, Cmd Msg )
88 | ageInput model age =
89 | let
90 | ageInt =
91 | age
92 | |> String.toInt
93 | |> Result.withDefault 0
94 |
95 | ageError =
96 | if ageInt <= 0 then
97 | Just "Must Enter a Positive Number"
98 | else
99 | Nothing
100 | in
101 | ( { model | age = age, ageError = ageError }, Cmd.none )
102 |
103 |
104 | bibInput : Model -> String -> ( Model, Cmd Msg )
105 | bibInput model bib =
106 | let
107 | bibInt =
108 | bib
109 | |> String.toInt
110 | |> Result.withDefault 0
111 |
112 | bibError =
113 | if bibInt <= 0 then
114 | Just "Must Enter a Positive Number"
115 | else
116 | Nothing
117 | in
118 | ( { model | bib = bib, bibError = bibError }, Cmd.none )
119 |
120 |
121 |
122 | -- view
123 |
124 |
125 | view : Model -> Html Msg
126 | view model =
127 | div [ class "main" ]
128 | [ errorPanel model.error
129 | , viewForm model
130 | ]
131 |
132 |
133 | errorPanel : Maybe String -> Html a
134 | errorPanel error =
135 | case error of
136 | Nothing ->
137 | text ""
138 |
139 | Just msg ->
140 | div [ class "error" ]
141 | [ text msg
142 | ]
143 |
144 |
145 | viewForm : Model -> Html Msg
146 | viewForm model =
147 | Html.form [ class "add-runner", onSubmit Save ]
148 | [ fieldset []
149 | [ legend [] [ text "Add / Edit Runner" ]
150 | , div []
151 | [ label [] [ text "Name" ]
152 | , input
153 | [ type_ "text"
154 | , value model.name
155 | , onInput NameInput
156 | ]
157 | []
158 | , span [] [ text <| Maybe.withDefault "" model.nameError ]
159 | ]
160 | , div []
161 | [ label [] [ text "Location" ]
162 | , input
163 | [ type_ "text"
164 | , value model.location
165 | , onInput LocationInput
166 | ]
167 | []
168 | , span [] [ text <| Maybe.withDefault "" model.locationError ]
169 | ]
170 | , div []
171 | [ label [] [ text "Age" ]
172 | , input
173 | [ type_ "text"
174 | , value model.age
175 | , onInput AgeInput
176 | ]
177 | []
178 | , span [] [ text <| Maybe.withDefault "" model.ageError ]
179 | ]
180 | , div []
181 | [ label [] [ text "Bib #" ]
182 | , input
183 | [ type_ "text"
184 | , value model.bib
185 | , onInput BibInput
186 | ]
187 | []
188 | , span [] [ text <| Maybe.withDefault "" model.bibError ]
189 | ]
190 | , div []
191 | [ label [] []
192 | , button [ type_ "submit" ] [ text "Save" ]
193 | ]
194 | ]
195 | ]
196 |
197 |
198 |
199 | -- subscriptions
200 |
201 |
202 | subscriptions : Model -> Sub Msg
203 | subscriptions model =
204 | Sub.none
205 |
--------------------------------------------------------------------------------
/10RLBLoginToken/src/Runner.elm:
--------------------------------------------------------------------------------
1 | module Runner exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import String
7 |
8 |
9 | -- model
10 |
11 |
12 | type alias Model =
13 | { id : String
14 | , name : String
15 | , nameError : Maybe String
16 | , location : String
17 | , locationError : Maybe String
18 | , age : String
19 | , ageError : Maybe String
20 | , bib : String
21 | , bibError : Maybe String
22 | , error : Maybe String
23 | }
24 |
25 |
26 | initModel : Model
27 | initModel =
28 | { id = ""
29 | , name = ""
30 | , nameError = Nothing
31 | , location = ""
32 | , locationError = Nothing
33 | , age = ""
34 | , ageError = Nothing
35 | , bib = ""
36 | , bibError = Nothing
37 | , error = Nothing
38 | }
39 |
40 |
41 | init : ( Model, Cmd Msg )
42 | init =
43 | ( initModel, Cmd.none )
44 |
45 |
46 |
47 | -- update
48 |
49 |
50 | type Msg
51 | = NameInput String
52 | | LocationInput String
53 | | AgeInput String
54 | | BibInput String
55 | | Save
56 |
57 |
58 | update : Msg -> Model -> ( Model, Cmd Msg )
59 | update msg model =
60 | case msg of
61 | NameInput name ->
62 | ( { model
63 | | name = name
64 | , nameError = Nothing
65 | }
66 | , Cmd.none
67 | )
68 |
69 | LocationInput location ->
70 | ( { model
71 | | location = location
72 | , locationError = Nothing
73 | }
74 | , Cmd.none
75 | )
76 |
77 | AgeInput age ->
78 | ageInput model age
79 |
80 | BibInput bib ->
81 | bibInput model bib
82 |
83 | Save ->
84 | ( model, Cmd.none )
85 |
86 |
87 | ageInput : Model -> String -> ( Model, Cmd Msg )
88 | ageInput model age =
89 | let
90 | ageInt =
91 | age
92 | |> String.toInt
93 | |> Result.withDefault 0
94 |
95 | ageError =
96 | if ageInt <= 0 then
97 | Just "Must Enter a Positive Number"
98 | else
99 | Nothing
100 | in
101 | ( { model | age = age, ageError = ageError }, Cmd.none )
102 |
103 |
104 | bibInput : Model -> String -> ( Model, Cmd Msg )
105 | bibInput model bib =
106 | let
107 | bibInt =
108 | bib
109 | |> String.toInt
110 | |> Result.withDefault 0
111 |
112 | bibError =
113 | if bibInt <= 0 then
114 | Just "Must Enter a Positive Number"
115 | else
116 | Nothing
117 | in
118 | ( { model | bib = bib, bibError = bibError }, Cmd.none )
119 |
120 |
121 |
122 | -- view
123 |
124 |
125 | view : Model -> Html Msg
126 | view model =
127 | div [ class "main" ]
128 | [ errorPanel model.error
129 | , viewForm model
130 | ]
131 |
132 |
133 | errorPanel : Maybe String -> Html a
134 | errorPanel error =
135 | case error of
136 | Nothing ->
137 | text ""
138 |
139 | Just msg ->
140 | div [ class "error" ]
141 | [ text msg
142 | ]
143 |
144 |
145 | viewForm : Model -> Html Msg
146 | viewForm model =
147 | Html.form [ class "add-runner", onSubmit Save ]
148 | [ fieldset []
149 | [ legend [] [ text "Add / Edit Runner" ]
150 | , div []
151 | [ label [] [ text "Name" ]
152 | , input
153 | [ type_ "text"
154 | , value model.name
155 | , onInput NameInput
156 | ]
157 | []
158 | , span [] [ text <| Maybe.withDefault "" model.nameError ]
159 | ]
160 | , div []
161 | [ label [] [ text "Location" ]
162 | , input
163 | [ type_ "text"
164 | , value model.location
165 | , onInput LocationInput
166 | ]
167 | []
168 | , span [] [ text <| Maybe.withDefault "" model.locationError ]
169 | ]
170 | , div []
171 | [ label [] [ text "Age" ]
172 | , input
173 | [ type_ "text"
174 | , value model.age
175 | , onInput AgeInput
176 | ]
177 | []
178 | , span [] [ text <| Maybe.withDefault "" model.ageError ]
179 | ]
180 | , div []
181 | [ label [] [ text "Bib #" ]
182 | , input
183 | [ type_ "text"
184 | , value model.bib
185 | , onInput BibInput
186 | ]
187 | []
188 | , span [] [ text <| Maybe.withDefault "" model.bibError ]
189 | ]
190 | , div []
191 | [ label [] []
192 | , button [ type_ "submit" ] [ text "Save" ]
193 | ]
194 | ]
195 | ]
196 |
197 |
198 |
199 | -- subscriptions
200 |
201 |
202 | subscriptions : Model -> Sub Msg
203 | subscriptions model =
204 | Sub.none
205 |
--------------------------------------------------------------------------------
/12RLBLockRunnerPage/src/Runner.elm:
--------------------------------------------------------------------------------
1 | module Runner exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import String
7 |
8 |
9 | -- model
10 |
11 |
12 | type alias Model =
13 | { id : String
14 | , name : String
15 | , nameError : Maybe String
16 | , location : String
17 | , locationError : Maybe String
18 | , age : String
19 | , ageError : Maybe String
20 | , bib : String
21 | , bibError : Maybe String
22 | , error : Maybe String
23 | }
24 |
25 |
26 | initModel : Model
27 | initModel =
28 | { id = ""
29 | , name = ""
30 | , nameError = Nothing
31 | , location = ""
32 | , locationError = Nothing
33 | , age = ""
34 | , ageError = Nothing
35 | , bib = ""
36 | , bibError = Nothing
37 | , error = Nothing
38 | }
39 |
40 |
41 | init : ( Model, Cmd Msg )
42 | init =
43 | ( initModel, Cmd.none )
44 |
45 |
46 |
47 | -- update
48 |
49 |
50 | type Msg
51 | = NameInput String
52 | | LocationInput String
53 | | AgeInput String
54 | | BibInput String
55 | | Save
56 |
57 |
58 | update : Msg -> Model -> ( Model, Cmd Msg )
59 | update msg model =
60 | case msg of
61 | NameInput name ->
62 | ( { model
63 | | name = name
64 | , nameError = Nothing
65 | }
66 | , Cmd.none
67 | )
68 |
69 | LocationInput location ->
70 | ( { model
71 | | location = location
72 | , locationError = Nothing
73 | }
74 | , Cmd.none
75 | )
76 |
77 | AgeInput age ->
78 | ageInput model age
79 |
80 | BibInput bib ->
81 | bibInput model bib
82 |
83 | Save ->
84 | ( model, Cmd.none )
85 |
86 |
87 | ageInput : Model -> String -> ( Model, Cmd Msg )
88 | ageInput model age =
89 | let
90 | ageInt =
91 | age
92 | |> String.toInt
93 | |> Result.withDefault 0
94 |
95 | ageError =
96 | if ageInt <= 0 then
97 | Just "Must Enter a Positive Number"
98 | else
99 | Nothing
100 | in
101 | ( { model | age = age, ageError = ageError }, Cmd.none )
102 |
103 |
104 | bibInput : Model -> String -> ( Model, Cmd Msg )
105 | bibInput model bib =
106 | let
107 | bibInt =
108 | bib
109 | |> String.toInt
110 | |> Result.withDefault 0
111 |
112 | bibError =
113 | if bibInt <= 0 then
114 | Just "Must Enter a Positive Number"
115 | else
116 | Nothing
117 | in
118 | ( { model | bib = bib, bibError = bibError }, Cmd.none )
119 |
120 |
121 |
122 | -- view
123 |
124 |
125 | view : Model -> Html Msg
126 | view model =
127 | div [ class "main" ]
128 | [ errorPanel model.error
129 | , viewForm model
130 | ]
131 |
132 |
133 | errorPanel : Maybe String -> Html a
134 | errorPanel error =
135 | case error of
136 | Nothing ->
137 | text ""
138 |
139 | Just msg ->
140 | div [ class "error" ]
141 | [ text msg
142 | ]
143 |
144 |
145 | viewForm : Model -> Html Msg
146 | viewForm model =
147 | Html.form [ class "add-runner", onSubmit Save ]
148 | [ fieldset []
149 | [ legend [] [ text "Add / Edit Runner" ]
150 | , div []
151 | [ label [] [ text "Name" ]
152 | , input
153 | [ type_ "text"
154 | , value model.name
155 | , onInput NameInput
156 | ]
157 | []
158 | , span [] [ text <| Maybe.withDefault "" model.nameError ]
159 | ]
160 | , div []
161 | [ label [] [ text "Location" ]
162 | , input
163 | [ type_ "text"
164 | , value model.location
165 | , onInput LocationInput
166 | ]
167 | []
168 | , span [] [ text <| Maybe.withDefault "" model.locationError ]
169 | ]
170 | , div []
171 | [ label [] [ text "Age" ]
172 | , input
173 | [ type_ "text"
174 | , value model.age
175 | , onInput AgeInput
176 | ]
177 | []
178 | , span [] [ text <| Maybe.withDefault "" model.ageError ]
179 | ]
180 | , div []
181 | [ label [] [ text "Bib #" ]
182 | , input
183 | [ type_ "text"
184 | , value model.bib
185 | , onInput BibInput
186 | ]
187 | []
188 | , span [] [ text <| Maybe.withDefault "" model.bibError ]
189 | ]
190 | , div []
191 | [ label [] []
192 | , button [ type_ "submit" ] [ text "Save" ]
193 | ]
194 | ]
195 | ]
196 |
197 |
198 |
199 | -- subscriptions
200 |
201 |
202 | subscriptions : Model -> Sub Msg
203 | subscriptions model =
204 | Sub.none
205 |
--------------------------------------------------------------------------------
/08RLBNavigation/completed/src/Runner.elm:
--------------------------------------------------------------------------------
1 | module Runner exposing (..)
2 |
3 | import Html exposing (..)
4 | import Html.Events exposing (..)
5 | import Html.Attributes exposing (..)
6 | import String
7 |
8 |
9 | -- model
10 |
11 |
12 | type alias Model =
13 | { id : String
14 | , name : String
15 | , nameError : Maybe String
16 | , location : String
17 | , locationError : Maybe String
18 | , age : String
19 | , ageError : Maybe String
20 | , bib : String
21 | , bibError : Maybe String
22 | , error : Maybe String
23 | }
24 |
25 |
26 | initModel : Model
27 | initModel =
28 | { id = ""
29 | , name = ""
30 | , nameError = Nothing
31 | , location = ""
32 | , locationError = Nothing
33 | , age = ""
34 | , ageError = Nothing
35 | , bib = ""
36 | , bibError = Nothing
37 | , error = Nothing
38 | }
39 |
40 |
41 | init : ( Model, Cmd Msg )
42 | init =
43 | ( initModel, Cmd.none )
44 |
45 |
46 |
47 | -- update
48 |
49 |
50 | type Msg
51 | = NameInput String
52 | | LocationInput String
53 | | AgeInput String
54 | | BibInput String
55 | | Save
56 |
57 |
58 | update : Msg -> Model -> ( Model, Cmd Msg )
59 | update msg model =
60 | case msg of
61 | NameInput name ->
62 | ( { model
63 | | name = name
64 | , nameError = Nothing
65 | }
66 | , Cmd.none
67 | )
68 |
69 | LocationInput location ->
70 | ( { model
71 | | location = location
72 | , locationError = Nothing
73 | }
74 | , Cmd.none
75 | )
76 |
77 | AgeInput age ->
78 | ageInput model age
79 |
80 | BibInput bib ->
81 | bibInput model bib
82 |
83 | Save ->
84 | ( model, Cmd.none )
85 |
86 |
87 | ageInput : Model -> String -> ( Model, Cmd Msg )
88 | ageInput model age =
89 | let
90 | ageInt =
91 | age
92 | |> String.toInt
93 | |> Result.withDefault 0
94 |
95 | ageError =
96 | if ageInt <= 0 then
97 | Just "Must Enter a Positive Number"
98 | else
99 | Nothing
100 | in
101 | ( { model | age = age, ageError = ageError }, Cmd.none )
102 |
103 |
104 | bibInput : Model -> String -> ( Model, Cmd Msg )
105 | bibInput model bib =
106 | let
107 | bibInt =
108 | bib
109 | |> String.toInt
110 | |> Result.withDefault 0
111 |
112 | bibError =
113 | if bibInt <= 0 then
114 | Just "Must Enter a Positive Number"
115 | else
116 | Nothing
117 | in
118 | ( { model | bib = bib, bibError = bibError }, Cmd.none )
119 |
120 |
121 |
122 | -- view
123 |
124 |
125 | view : Model -> Html Msg
126 | view model =
127 | div [ class "main" ]
128 | [ errorPanel model.error
129 | , viewForm model
130 | ]
131 |
132 |
133 | errorPanel : Maybe String -> Html a
134 | errorPanel error =
135 | case error of
136 | Nothing ->
137 | text ""
138 |
139 | Just msg ->
140 | div [ class "error" ]
141 | [ text msg
142 | ]
143 |
144 |
145 | viewForm : Model -> Html Msg
146 | viewForm model =
147 | Html.form [ class "add-runner", onSubmit Save ]
148 | [ fieldset []
149 | [ legend [] [ text "Add / Edit Runner" ]
150 | , div []
151 | [ label [] [ text "Name" ]
152 | , input
153 | [ type_ "text"
154 | , value model.name
155 | , onInput NameInput
156 | ]
157 | []
158 | , span [] [ text <| Maybe.withDefault "" model.nameError ]
159 | ]
160 | , div []
161 | [ label [] [ text "Location" ]
162 | , input
163 | [ type_ "text"
164 | , value model.location
165 | , onInput LocationInput
166 | ]
167 | []
168 | , span [] [ text <| Maybe.withDefault "" model.locationError ]
169 | ]
170 | , div []
171 | [ label [] [ text "Age" ]
172 | , input
173 | [ type_ "text"
174 | , value model.age
175 | , onInput AgeInput
176 | ]
177 | []
178 | , span [] [ text <| Maybe.withDefault "" model.ageError ]
179 | ]
180 | , div []
181 | [ label [] [ text "Bib #" ]
182 | , input
183 | [ type_ "text"
184 | , value model.bib
185 | , onInput BibInput
186 | ]
187 | []
188 | , span [] [ text <| Maybe.withDefault "" model.bibError ]
189 | ]
190 | , div []
191 | [ label [] []
192 | , button [ type_ "submit" ] [ text "Save" ]
193 | ]
194 | ]
195 | ]
196 |
197 |
198 |
199 | -- subscriptions
200 |
201 |
202 | subscriptions : Model -> Sub Msg
203 | subscriptions model =
204 | Sub.none
205 |
--------------------------------------------------------------------------------