Switched to Elm / Suave
It's like F# on the client side - sweet!
This commit is contained in:
26
src/wwwroot/App.elm
Normal file
26
src/wwwroot/App.elm
Normal file
@@ -0,0 +1,26 @@
|
||||
module App exposing (..)
|
||||
|
||||
import Messages exposing (..)
|
||||
import Models exposing (Model, initialModel)
|
||||
import Navigation exposing (Location)
|
||||
import Routing exposing (Route(..), parseLocation)
|
||||
import Update exposing (update)
|
||||
import View exposing (view)
|
||||
|
||||
|
||||
init : Location -> (Model, Cmd Msg)
|
||||
init location =
|
||||
let
|
||||
currentRoute = Home --parseLocation location
|
||||
in
|
||||
(initialModel currentRoute, Cmd.none)
|
||||
|
||||
|
||||
main : Program Never Model Msg
|
||||
main =
|
||||
Navigation.program OnLocationChange
|
||||
{ init = init
|
||||
, view = view
|
||||
, update = update
|
||||
, subscriptions = \_ -> Sub.none
|
||||
}
|
||||
19
src/wwwroot/Home/Public.elm
Normal file
19
src/wwwroot/Home/Public.elm
Normal file
@@ -0,0 +1,19 @@
|
||||
module Home.Public exposing (view)
|
||||
|
||||
import Html exposing (Html, p, text)
|
||||
import Messages exposing (Msg(..))
|
||||
import Models exposing (Model)
|
||||
import Utils.View exposing (fullRow)
|
||||
|
||||
|
||||
view : Model -> List (Html Msg)
|
||||
view model =
|
||||
let
|
||||
paragraphs =
|
||||
[ " "
|
||||
, "myPrayerJournal is a place where individuals can record their prayer requests, record that they prayed for them, update them as God moves in the situation, and record a final answer received on that request. It will also allow individuals to review their answered prayers."
|
||||
, "This site is currently in very limited alpha, as it is being developed with a core group of test users. If this is something you are interested in using, check back around mid-November 2016 to check on the development progress."
|
||||
]
|
||||
|> List.map (\para -> p [] [ text para ])
|
||||
in
|
||||
[ fullRow paragraphs ]
|
||||
9
src/wwwroot/Messages.elm
Normal file
9
src/wwwroot/Messages.elm
Normal file
@@ -0,0 +1,9 @@
|
||||
module Messages exposing (..)
|
||||
|
||||
import Navigation exposing (Location)
|
||||
|
||||
|
||||
type Msg
|
||||
= OnLocationChange Location
|
||||
| NavTo String
|
||||
| UpdateTitle String
|
||||
16
src/wwwroot/Models.elm
Normal file
16
src/wwwroot/Models.elm
Normal file
@@ -0,0 +1,16 @@
|
||||
module Models exposing (..)
|
||||
|
||||
import Routing exposing (Route(..))
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ route : Route
|
||||
, title : String
|
||||
}
|
||||
|
||||
|
||||
initialModel : Route -> Model
|
||||
initialModel route =
|
||||
{ route = route
|
||||
, title = "Index"
|
||||
}
|
||||
31
src/wwwroot/Routing.elm
Normal file
31
src/wwwroot/Routing.elm
Normal file
@@ -0,0 +1,31 @@
|
||||
module Routing exposing (..)
|
||||
|
||||
import Navigation exposing (Location)
|
||||
import UrlParser exposing (..)
|
||||
|
||||
|
||||
type Route
|
||||
= Home
|
||||
| ChangePassword
|
||||
| LogOff
|
||||
| LogOn
|
||||
| NotFound
|
||||
|
||||
|
||||
findRoute : Parser (Route -> a) a
|
||||
findRoute =
|
||||
oneOf
|
||||
[ map Home top
|
||||
, map LogOn (s "user" </> s "log-on")
|
||||
, map LogOff (s "user" </> s "log-off")
|
||||
, map ChangePassword (s "user" </> s "password" </> s "change")
|
||||
]
|
||||
|
||||
|
||||
parseLocation : Location -> Route
|
||||
parseLocation location =
|
||||
case (parsePath findRoute location) of
|
||||
Just route ->
|
||||
route
|
||||
Nothing ->
|
||||
NotFound
|
||||
21
src/wwwroot/Update.elm
Normal file
21
src/wwwroot/Update.elm
Normal file
@@ -0,0 +1,21 @@
|
||||
module Update exposing (..)
|
||||
|
||||
import Models exposing (Model)
|
||||
import Messages exposing (Msg(..))
|
||||
import Navigation exposing (newUrl)
|
||||
import Routing exposing (parseLocation)
|
||||
import Utils.View exposing (documentTitle)
|
||||
|
||||
|
||||
update : Msg -> Model -> (Model, Cmd Msg)
|
||||
update msg model =
|
||||
case msg of
|
||||
OnLocationChange location ->
|
||||
let
|
||||
newRoute = parseLocation location
|
||||
in
|
||||
({model | route = newRoute}, Cmd.none)
|
||||
NavTo url ->
|
||||
(model, newUrl url)
|
||||
UpdateTitle newTitle ->
|
||||
(model, documentTitle newTitle)
|
||||
47
src/wwwroot/Utils/View.elm
Normal file
47
src/wwwroot/Utils/View.elm
Normal file
@@ -0,0 +1,47 @@
|
||||
port module Utils.View exposing (..)
|
||||
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (class, href, style, title)
|
||||
import Html.Events exposing (defaultOptions, onWithOptions)
|
||||
import Json.Decode as Json
|
||||
import Messages exposing (Msg(..))
|
||||
|
||||
|
||||
-- Set the document title
|
||||
port documentTitle : String -> Cmd a
|
||||
|
||||
|
||||
-- Wrap the given content in a row
|
||||
row : List (Html Msg) -> Html Msg
|
||||
row columns =
|
||||
div [ class "row "] columns
|
||||
|
||||
|
||||
-- Display the given content in a full row
|
||||
fullRow : List (Html Msg) -> Html Msg
|
||||
fullRow content =
|
||||
row
|
||||
[ div
|
||||
[ class "col-xs-12" ]
|
||||
content
|
||||
]
|
||||
|
||||
|
||||
-- Create a navigation link
|
||||
navLink : String -> String -> List (Attribute Msg) -> Html Msg
|
||||
navLink url linkText attrs =
|
||||
let
|
||||
attributes =
|
||||
List.concat
|
||||
[
|
||||
[ title linkText
|
||||
, onWithOptions
|
||||
"click" { defaultOptions | preventDefault = True }
|
||||
<| Json.succeed
|
||||
<| NavTo url
|
||||
, href url
|
||||
]
|
||||
, attrs
|
||||
]
|
||||
in
|
||||
a attributes [ text linkText ]
|
||||
104
src/wwwroot/View.elm
Normal file
104
src/wwwroot/View.elm
Normal file
@@ -0,0 +1,104 @@
|
||||
module View exposing (view)
|
||||
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (attribute, class)
|
||||
import Messages exposing (Msg(..))
|
||||
import Models exposing (..)
|
||||
import Routing exposing (Route(..))
|
||||
import Utils.View exposing (documentTitle, navLink)
|
||||
|
||||
import Home.Public
|
||||
|
||||
|
||||
-- Layout functions
|
||||
|
||||
navigation : List (Html Msg)
|
||||
navigation =
|
||||
[ navLink "/user/password/change" "Change Your Password" []
|
||||
, navLink "/user/log-off" "Log Off" []
|
||||
, navLink "/user/log-on" "Log On" []
|
||||
]
|
||||
|> List.map (\anchor -> li [] [ anchor ])
|
||||
|
||||
|
||||
pageHeader : Html Msg
|
||||
pageHeader =
|
||||
div
|
||||
[ class "navbar navbar-inverse navbar-fixed-top" ]
|
||||
[ div
|
||||
[ class "container" ]
|
||||
[ div
|
||||
[ class "navbar-header" ]
|
||||
[ button
|
||||
[ class "navbar-toggle"
|
||||
, attribute "data-toggle" "collapse"
|
||||
, attribute "data-target" ".navbar-collapse"
|
||||
]
|
||||
[ span [ class "sr-only" ] [ text "Toggle navigation" ]
|
||||
, span [ class "icon-bar" ] []
|
||||
, span [ class "icon-bar" ] []
|
||||
, span [ class "icon-bar" ] []
|
||||
]
|
||||
, navLink "/" "myPrayerJournal" [ class "navbar-brand" ]
|
||||
]
|
||||
, div
|
||||
[ class "navbar-collapse collapse" ]
|
||||
[ ul
|
||||
[ class "nav navbar-nav navbar-right" ]
|
||||
navigation
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
pageTitle : String -> Html Msg
|
||||
pageTitle title =
|
||||
let
|
||||
x = documentTitle <| title ++ " | myPrayerJournal"
|
||||
in
|
||||
h2 [ class "page-title" ] [ text title ]
|
||||
|
||||
|
||||
pageFooter : Html Msg
|
||||
pageFooter =
|
||||
footer
|
||||
[ class "mpj-footer" ]
|
||||
[ p
|
||||
[ class "text-right" ]
|
||||
[ text "myPrayerJournal v0.8.1" ]
|
||||
]
|
||||
|
||||
|
||||
layout : Model -> String -> List (Html Msg) -> Html Msg
|
||||
layout model pgTitle contents =
|
||||
let
|
||||
pageContent =
|
||||
[ [ pageTitle pgTitle ]
|
||||
, contents
|
||||
, [ pageFooter ]
|
||||
]
|
||||
|> List.concat
|
||||
in
|
||||
div []
|
||||
[ pageHeader
|
||||
, div
|
||||
[ class "container body-content" ]
|
||||
pageContent
|
||||
]
|
||||
|
||||
|
||||
-- View functions
|
||||
|
||||
view : Model -> Html Msg
|
||||
view model =
|
||||
case model.route of
|
||||
ChangePassword ->
|
||||
layout model "Change Your Password" [ text "password change page goes here" ]
|
||||
Home ->
|
||||
layout model "Welcome" (Home.Public.view model)
|
||||
LogOff ->
|
||||
layout model "Log Off" [ text "Log off page goes hwere" ]
|
||||
LogOn ->
|
||||
layout model "Log On" [ text "Log On page goes here" ]
|
||||
NotFound ->
|
||||
layout model "Page Not Found" [ text "404, dude" ]
|
||||
10330
src/wwwroot/app.js
Normal file
10330
src/wwwroot/app.js
Normal file
File diff suppressed because it is too large
Load Diff
35
src/wwwroot/content/styles.css
Normal file
35
src/wwwroot/content/styles.css
Normal file
@@ -0,0 +1,35 @@
|
||||
body {
|
||||
padding-top: 50px;
|
||||
padding-bottom: 20px;
|
||||
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
|
||||
}
|
||||
|
||||
/* Wrapping element */
|
||||
/* Set some basic padding to keep content from hitting the edges */
|
||||
.body-content {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
.material-icons.md-18 {
|
||||
font-size: 18px;
|
||||
}
|
||||
.material-icons.md-24 {
|
||||
font-size: 24px;
|
||||
}
|
||||
.material-icons.md-36 {
|
||||
font-size: 36px;
|
||||
}
|
||||
.material-icons.md-48 {
|
||||
font-size: 48px;
|
||||
}
|
||||
.material-icons {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.mpj-page-title {
|
||||
border-bottom: solid 1px lightgray;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.mpj-footer {
|
||||
border-top: solid 1px lightgray;
|
||||
margin-top: 20px;
|
||||
}
|
||||
24
src/wwwroot/index.html
Normal file
24
src/wwwroot/index.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>myPrayerJournal</title>
|
||||
<base href="/">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/content/styles.css">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||
<script src="/app.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script>
|
||||
var app = Elm.App.embed(document.getElementById('app'))
|
||||
app.ports.documentTitle.subscribe(function (title)
|
||||
{
|
||||
alert("Setting title to " + title)
|
||||
document.title = title
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user