xesite/frontend/src/BlogIndex.purs

85 lines
2.4 KiB
Plaintext
Raw Normal View History

2016-12-14 07:11:20 +00:00
module App.BlogIndex where
import Control.Monad.Aff (attempt)
import Data.Argonaut (class DecodeJson, decodeJson, (.?))
import Data.Either (Either(Left, Right), either)
import DOM (DOM)
import Network.HTTP.Affjax (AJAX, get)
import Prelude (($), bind, map, const, show, (<>), pure, (<<<))
import Pux (EffModel, noEffects)
import Pux.Html (Html, br, div, h1, ol, li, button, text, span, p)
2016-12-14 14:20:25 +00:00
import Pux.Html.Attributes (key, className, id_)
2016-12-14 07:11:20 +00:00
import Pux.Html.Events (onClick)
2016-12-14 14:20:25 +00:00
import Pux.Router (link)
2016-12-14 07:11:20 +00:00
data Action = RequestPosts
| ReceivePosts (Either String Posts)
type State =
{ posts :: Posts
, status :: String }
data Post = Post
{ title :: String
, link :: String
, summary :: String
, date :: String }
type Posts = Array Post
instance decodeJsonPost :: DecodeJson Post where
decodeJson json = do
obj <- decodeJson json
title <- obj .? "title"
link <- obj .? "link"
summ <- obj .? "summary"
date <- obj .? "date"
pure $ Post { title: title, link: link, summary: summ, date: date }
init :: State
init =
{ posts: []
, status: "Loading..." }
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" }
update RequestPosts state =
{ state: state { status = "Fetching posts..." }
, effects: [ do
res <- attempt $ get "/api/blog/posts"
let decode r = decodeJson r.response :: Either String Posts
let posts = either (Left <<< show) decode res
pure $ ReceivePosts posts
]
}
post :: Post -> Html Action
post (Post state) =
div
2016-12-14 14:20:25 +00:00
[ className "col s6" ]
2016-12-14 07:11:20 +00:00
[ div
2016-12-14 14:20:25 +00:00
[ className "card pink lighten-4" ]
2016-12-14 07:11:20 +00:00
[ div
[ className "card-content black-text" ]
[ span [ className "card-title" ] [ text state.title ]
, br [] []
, p [] [ text ("Posted on: " <> state.date) ]
, span [] [ text state.summary ]
]
2016-12-14 14:20:25 +00:00
, div
[ className "card-action pink" ]
[ link state.link [] [ text "Read More" ] ]
2016-12-14 07:11:20 +00:00
]
]
view :: State -> Html Action
view state =
div
[]
[ h1 [] [ text state.status ]
2016-12-14 14:20:25 +00:00
, button [ onClick (const RequestPosts), id_ "requestbutton", className "hidden" ] [ text "Fetch posts" ]
2016-12-14 07:11:20 +00:00
, div [ className "row" ] $ map post state.posts ]