aboutsummaryrefslogtreecommitdiff
path: root/frontend/src
diff options
context:
space:
mode:
authorChristine Dodrill <me@christine.website>2016-12-14 11:54:17 -0800
committerChristine Dodrill <me@christine.website>2016-12-14 11:54:17 -0800
commit81206835d5ddb8760086085d758b049f73ea0801 (patch)
treeb1a26f35e5c5a8c60bf620438fc3a5c424e2f113 /frontend/src
parent4a52f5006bc8c1e63d68c2bad04c7e3f33a6e11d (diff)
downloadxesite-81206835d5ddb8760086085d758b049f73ea0801.tar.xz
xesite-81206835d5ddb8760086085d758b049f73ea0801.zip
frontend: render blog posts
Diffstat (limited to 'frontend/src')
-rw-r--r--frontend/src/BlogEntry.js9
-rw-r--r--frontend/src/BlogEntry.purs79
-rw-r--r--frontend/src/BlogIndex.purs9
-rw-r--r--frontend/src/Layout.purs15
-rw-r--r--frontend/src/Main.purs2
-rw-r--r--frontend/src/Routes.purs2
6 files changed, 109 insertions, 7 deletions
diff --git a/frontend/src/BlogEntry.js b/frontend/src/BlogEntry.js
new file mode 100644
index 0000000..f464cf2
--- /dev/null
+++ b/frontend/src/BlogEntry.js
@@ -0,0 +1,9 @@
+// Module App.BlogEntry
+
+exports.mdify = function(id) {
+ var converter = new showdown.Converter()
+ elem = document.getElementById(id);
+ md = elem.innerHTML;
+ elem.innerHTML = converter.makeHtml(md);
+ return "done :)";
+}
diff --git a/frontend/src/BlogEntry.purs b/frontend/src/BlogEntry.purs
new file mode 100644
index 0000000..c104a78
--- /dev/null
+++ b/frontend/src/BlogEntry.purs
@@ -0,0 +1,79 @@
+module App.BlogEntry where
+
+import Control.Monad.Aff (attempt)
+import DOM (DOM)
+import Data.Argonaut (class DecodeJson, decodeJson, (.?))
+import Data.Either (Either(..), either)
+import Data.Maybe (Maybe(..))
+import Network.HTTP.Affjax (AJAX, get)
+import Prelude (bind, pure, show, ($), (<>), (<<<))
+import Pux (EffModel, noEffects)
+import Pux.Html (Html, div, h1, h2, p, text)
+import Pux.Html.Attributes (id_)
+
+data Action = RequestPost
+ | ReceivePost (Either String Post)
+ | RenderPost
+
+type State =
+ { status :: String
+ , hack :: String
+ , id :: Maybe Int
+ , post :: Post
+ , name :: String }
+
+data Post = Post
+ { title :: String
+ , body :: String
+ , date :: String }
+
+instance decodeJsonPost :: DecodeJson Post where
+ decodeJson json = do
+ obj <- decodeJson json
+ title <- obj .? "title"
+ body <- obj .? "body"
+ date <- obj .? "date"
+ pure $ Post { title: title, body: body, date: date }
+
+init :: State
+init =
+ { status: "Loading..."
+ , hack: ""
+ , post: Post
+ { title: ""
+ , body: ""
+ , date: "" }
+ , name: ""
+ , id: Nothing }
+
+update :: Action -> State -> EffModel State Action (ajax :: AJAX, dom :: DOM)
+update (ReceivePost (Left err)) state =
+ noEffects $ state { id = Nothing, status = err }
+update (ReceivePost (Right post)) state =
+ { state: state { status = "", id = Just 1, post = post }
+ , effects: [ pure $ RenderPost ]
+ }
+update RequestPost state =
+ { state: state
+ , effects: [ do
+ res <- attempt $ get ("/api/blog/post?name=" <> state.name)
+ let decode r = decodeJson r.response :: Either String Post
+ let post = either (Left <<< show) decode res
+ pure $ ReceivePost post
+ ]
+ }
+update RenderPost state =
+ noEffects $ state { hack = mdify "blogpost" }
+
+view :: State -> Html Action
+view { id: id, status: status, post: (Post post) } =
+ case id of
+ Nothing -> div [] []
+ (Just _) ->
+ div []
+ [ h1 [] [ text status ]
+ , div []
+ [ p [ id_ "blogpost" ] [ text post.body ] ]
+ ]
+
+foreign import mdify :: String -> String
diff --git a/frontend/src/BlogIndex.purs b/frontend/src/BlogIndex.purs
index d1b19f6..a52e6bd 100644
--- a/frontend/src/BlogIndex.purs
+++ b/frontend/src/BlogIndex.purs
@@ -39,15 +39,15 @@ instance decodeJsonPost :: DecodeJson Post where
init :: State
init =
{ posts: []
- , status: "Loading..." }
+ , status: "" }
update :: Action -> State -> EffModel State Action (ajax :: AJAX, dom :: DOM)
update (ReceivePosts (Left err)) state =
noEffects $ state { status = ("error: " <> err) }
update (ReceivePosts (Right posts)) state =
- noEffects $ state { posts = posts, status = "Posts" }
+ noEffects $ state { posts = posts, status = "" }
update RequestPosts state =
- { state: state { status = "Fetching posts..." }
+ { state: state { status = "Loading..." }
, effects: [ do
res <- attempt $ get "/api/blog/posts"
let decode r = decodeJson r.response :: Either String Posts
@@ -79,5 +79,6 @@ view :: State -> Html Action
view state =
div
[]
- [ h1 [] [ text state.status ]
+ [ h1 [] [ text "Posts" ]
+ , p [] [ text state.status ]
, div [ className "row" ] $ map post state.posts ]
diff --git a/frontend/src/Layout.purs b/frontend/src/Layout.purs
index 86b2496..96d056a 100644
--- a/frontend/src/Layout.purs
+++ b/frontend/src/Layout.purs
@@ -1,8 +1,10 @@
module App.Layout where
+import App.BlogEntry as BlogEntry
import App.BlogIndex as BlogIndex
import App.Counter as Counter
import App.Routes (Route(..))
+import Control.Monad.RWS (state)
import DOM (DOM)
import Network.HTTP.Affjax (AJAX)
import Prelude (($), (#), map, pure)
@@ -14,29 +16,37 @@ import Pux.Router (link)
data Action
= Child (Counter.Action)
| BIChild (BlogIndex.Action)
+ | BEChild (BlogEntry.Action)
| PageView Route
type State =
{ route :: Route
, count :: Counter.State
- , bistate :: BlogIndex.State }
+ , bistate :: BlogIndex.State
+ , bestate :: BlogEntry.State }
init :: State
init =
{ route: NotFound
, count: Counter.init
- , bistate: BlogIndex.init }
+ , bistate: BlogIndex.init
+ , bestate: BlogEntry.init }
update :: Action -> State -> EffModel State Action (ajax :: AJAX, dom :: DOM)
update (PageView route) state = routeEffects route $ state { route = route }
update (BIChild action) state = BlogIndex.update action state.bistate
# mapState (state { bistate = _ })
# mapEffects BIChild
+update (BEChild action) state = BlogEntry.update action state.bestate
+ # mapState (state { bestate = _ })
+ # mapEffects BEChild
update (Child action) state = noEffects $ state { count = Counter.update action state.count }
routeEffects :: Route -> State -> EffModel State Action (dom :: DOM, ajax :: AJAX)
routeEffects BlogIndex state = { state: state
, effects: [ pure BlogIndex.RequestPosts ] } # mapEffects BIChild
+routeEffects (BlogPost page) state = { state: state { bestate = BlogEntry.init { name = page } }
+ , effects: [ pure BlogEntry.RequestPost ] } # mapEffects BEChild
routeEffects _ state = noEffects $ state
view :: State -> Html Action
@@ -71,4 +81,5 @@ page NotFound _ = h1 [] [ text "not found" ]
page Home state = map Child $ Counter.view state.count
page Resume state = h1 [] [ text "Christine Dodrill" ]
page BlogIndex state = map BIChild $ BlogIndex.view state.bistate
+page (BlogPost _) state = map BEChild $ BlogEntry.view state.bestate
page _ _ = h1 [] [ text "not implemented yet" ]
diff --git a/frontend/src/Main.purs b/frontend/src/Main.purs
index c7106b4..5f42a8a 100644
--- a/frontend/src/Main.purs
+++ b/frontend/src/Main.purs
@@ -7,7 +7,7 @@ import Control.Monad.Eff (Eff)
import DOM (DOM)
import Network.HTTP.Affjax (AJAX)
import Prelude (bind, pure)
-import Pux (App, Config, CoreEffects, fromSimple, renderToDOM, start)
+import Pux (App, Config, CoreEffects, renderToDOM, start)
import Pux.Devtool (Action, start) as Pux.Devtool
import Pux.Router (sampleUrl)
import Signal ((~>))
diff --git a/frontend/src/Routes.purs b/frontend/src/Routes.purs
index 08ae9e5..111d0d7 100644
--- a/frontend/src/Routes.purs
+++ b/frontend/src/Routes.purs
@@ -19,3 +19,5 @@ match url = fromMaybe NotFound $ router url $
Home <$ end
<|>
BlogIndex <$ lit "blog" <* end
+ <|>
+ BlogPost <$> (lit "blog" *> str) <* end