1
1
mirror of https://github.com/aelve/guide.git synced 2024-11-24 05:45:11 +03:00

Add category/{id} endpoint

and handle its data
This commit is contained in:
Jens Krause 2017-09-08 17:53:33 +02:00
parent 3c8f552597
commit 4fdc91b1f5
No known key found for this signature in database
GPG Key ID: 3B2FAFBCEFA5906D
5 changed files with 87 additions and 20 deletions

View File

@ -2,14 +2,66 @@ module Guide.CategoryDetail.Events where
import Prelude
import Data.Array ((:))
import Data.Either (Either(..))
import Data.Maybe (Maybe(..))
import Guide.Api.Types (CCategoryDetail, CUid)
import Guide.CategoryDetail.Routes (Route(..))
import Guide.CategoryDetail.State (State(..))
import Guide.Common.Api (ApiError, getCategory)
import Guide.Common.Types (AppEffects, CategoryName)
import Network.RemoteData (RemoteData(..), isNotAsked)
import Pux (EffModel, noEffects)
import Guide.CategoryDetail.Routes (Route)
import Guide.CategoryDetail.State (State(..))
import Guide.Common.Types (AppEffects)
data Event = PageView Route
data Event
= PageView Route
| RequestCategory CategoryName (CUid String)
-- TODO: ^ Use `CUid Category` instead of `CUid String` as second type parameter
-- if we have found a way to bridge `Uid a` properly from `Haskell` to `PS`
| ReceiveCategory (Either ApiError CCategoryDetail)
foldp :: ∀ fx. Event -> State -> EffModel State Event (AppEffects fx)
foldp (PageView route) (State st) = noEffects $ State st { route = route, loaded = true }
foldp (RequestCategory catName catId) (State state) =
{ state:
State $ state { category = Loading
}
, effects:
[ getCategory catName catId >>= pure <<< Just <<< ReceiveCategory
]
}
foldp (ReceiveCategory (Right cat)) (State state) = noEffects $
State $
state { loaded = true
, category = Success cat
}
foldp (ReceiveCategory (Left error)) (State state) = noEffects $
State $
state { loaded = true
, errors = (show error) : state.errors
, category = Failure error
}
foldp (PageView route) (State state) =
routeEffects route (State $ state { route = route })
routeEffects :: forall eff. Route -> State -> EffModel State Event (AppEffects eff)
routeEffects (CategoryDetail catName catId) (State state) =
{ state:
State $ state { loaded = false
}
, effects: [
-- fetch a category only once
if isNotAsked state.category then
pure <<< Just $ RequestCategory catName catId
else
pure Nothing
]
}
routeEffects (NotFound url) (State state) = noEffects $
State $ state { loaded = true }

View File

@ -1,17 +1,18 @@
module Guide.CategoryDetail.State where
import Data.Generic (class Generic, gShow)
import Data.Maybe (Maybe(..))
import Data.Newtype (class Newtype)
import Data.Show (class Show)
import Guide.Api.Types (CCategoryDetail)
import Guide.CategoryDetail.Routes (Route, match)
import Guide.Common.Api (ApiError)
import Network.RemoteData (RemoteData(..))
newtype State = State
{ title :: String
, route :: Route
, category :: Maybe CCategoryDetail
, errors :: Array String
, category :: RemoteData ApiError CCategoryDetail
, loaded :: Boolean
}
@ -24,6 +25,7 @@ init :: String -> State
init url = State
{ title: "CategoryDetail page" -- TODO (sectore): Change title
, route: match url
, category: Nothing
, errors: []
, category: NotAsked
, loaded: false
}

View File

@ -19,8 +19,6 @@ data Event =
| ReceiveCategories (Either ApiError CCategories)
foldp :: forall eff. Event -> State -> EffModel State Event (AppEffects eff)
foldp (PageView route) (State st) =
routeEffects route (State $ st { route = route })
foldp (GetCategories catName) (State st) =
{ state: State $ st { categories = Loading
@ -43,6 +41,9 @@ foldp (ReceiveCategories (Left error)) s@(State st) = noEffects $
, categories = Failure error
}
foldp (PageView route) (State st) =
routeEffects route (State $ st { route = route })
routeEffects :: forall eff. Route -> State -> EffModel State Event (AppEffects eff)
routeEffects (CategoryOverview catName) s@(State st) =
{ state:

View File

@ -3,17 +3,18 @@ module Guide.CategoryOverview.View.CategoryOverview where
import Prelude
import Data.Foldable (for_)
import Data.Generic (gShow)
import Guide.Api.Types (CategoryInfo(..))
import Data.Lens ((^.))
import Guide.Api.Types (CategoryInfo(..), _CUid)
import Guide.CategoryOverview.Events (Event)
import Guide.CategoryOverview.State (State(..))
import Guide.Common.Routes (categoryDetailUrl)
import Guide.Common.Types (CCategories)
import Network.RemoteData (RemoteData(..))
import Pux.DOM.Events (onClick) as P
import Pux.DOM.HTML (HTML) as P
import Pux.DOM.HTML.Attributes (key) as P
import Text.Smolder.HTML (div, h1, h2, h3, a, ul, li) as S
import Text.Smolder.Markup ((#!), (!))
import Text.Smolder.HTML (div, h1, h2, a, ul, li) as S
import Text.Smolder.HTML.Attributes (href) as S
import Text.Smolder.Markup ((!))
import Text.Smolder.Markup (text) as S
view :: State -> P.HTML Event
@ -32,8 +33,12 @@ catsView st@(State state) cats =
$ for_ cats (catView st)
catView :: State -> CategoryInfo -> P.HTML Event
catView _ (CategoryInfo cat) =
catView (State state) (CategoryInfo cat) =
let url = categoryDetailUrl state.categoryName cat.categoryInfoUid in
S.li
! P.key (gShow cat.categoryInfoUid) $ do
S.h2
! P.key (cat.categoryInfoUid ^. _CUid) $ do
S.a
! S.href url
$ S.text cat.categoryInfoTitle
S.h2
$ S.text url

View File

@ -9,6 +9,7 @@ import Data.Either (Either(..), either)
import Data.Foreign (Foreign, unsafeFromForeign)
import Data.Generic (class Generic, gShow)
import Data.Newtype (class Newtype)
import Guide.Api.Types (CCategoryDetail, CUid(..))
import Guide.Common.Types (CCategories, CategoryName)
import IsomorphicFetch (FETCH, get, json)
@ -35,3 +36,9 @@ getCategories _ = do
response <- get $ endpoint <> "/categories"
json' <- json response
pure $ either (Left <<< ApiError) pure $ decodeJson json'
getCategory :: forall eff. CategoryName -> (CUid String) -> Aff (fetch :: FETCH | eff) (Either ApiError CCategoryDetail)
getCategory _ (CUid catId) = do
response <- get $ endpoint <> "/category/" <> catId
json' <- json response
pure $ either (Left <<< ApiError) pure $ decodeJson json'