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:
parent
3c8f552597
commit
4fdc91b1f5
@ -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 }
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
|
Loading…
Reference in New Issue
Block a user