@@ -2,41 +2,68 @@ module Statebox.Console where
22
33import Prelude
44import Data.Either (either )
5+ import Data.Generic.Rep
56import Data.Lens
67import Data.Lens.Record (prop )
78import Data.Symbol (SProxy (..))
89import Data.Foldable (fold , foldMap )
10+ import Data.Map as Map
11+ import Data.Map (Map )
912import Data.Maybe (Maybe (..), maybe , fromMaybe )
13+ import Data.Tuple.Nested ((/\))
1014import Effect.Aff.Class (class MonadAff )
1115import Effect.Console (log )
1216import Halogen as H
1317import Halogen (ComponentHTML )
14- import Halogen.HTML (HTML , p , text , br , span , div , ul , li , h2 , h3 , table , tr , th , td )
18+ import Halogen.HTML (HTML , p , text , br , span , div , ul , li , h2 , h3 , table , tr , th , td , button )
19+ import Halogen.HTML.Events (onClick , onValueInput )
1520import Halogen.Query.HalogenM (HalogenM )
1621
1722import Statebox.Console.DAO as DAO
23+ import View.Model (Project (..), ProjectId )
1824
1925import Stripe as Stripe
2026
2127import Debug.Trace (spy )
2228
29+ -- TODO
30+ fakeCustomerId = " TODO"
31+
2332-- ------------------------------------------------------------------------------
2433
2534type State =
26- { customer :: Maybe Stripe.Customer
35+ { route :: Route
36+ , customer :: Maybe Stripe.Customer
2737 , paymentMethods :: Array Stripe.PaymentMethod
2838 , subscriptions :: Array Stripe.Subscription
2939 , plans :: Array Stripe.PlanWithExpandedProduct
3040 , accounts :: Array { invoices :: Array Stripe.Invoice
3141 }
3242 , status :: AppStatus
43+ , projects :: Map ProjectId Project
3344 }
3445
3546_accounts = prop (SProxy :: SProxy " accounts" )
3647_invoices = prop (SProxy :: SProxy " invoices" )
3748
3849-- ------------------------------------------------------------------------------
3950
51+ data Route
52+ = Home
53+ | Projects
54+ | ProjectR ProjectId
55+ | APIKeys
56+ | Invoices Stripe.CustomerId
57+ | Account
58+ | Subscription
59+ | Plan
60+
61+ derive instance eqRoute :: Eq Route
62+ derive instance ordRoute :: Ord Route
63+ derive instance genericRoute :: Generic Route _
64+
65+ -- ------------------------------------------------------------------------------
66+
4067data AppStatus = Ok | ErrorStatus String
4168
4269derive instance eqAppStatus :: Eq AppStatus
@@ -48,9 +75,12 @@ instance showAppStatus :: Show AppStatus where
4875
4976type Input = State
5077
51- data Action = FetchStuff
78+ data Action
79+ = SelectRoute Route
80+ | FetchStuff
5281
53- data Query a = DoAction Action a
82+ data Query a
83+ = DoAction Action a
5484
5585type ChildSlots = ()
5686
@@ -66,12 +96,16 @@ mkInitialState :: Input -> State
6696mkInitialState input = input
6797
6898handleQuery = case _ of
69- ( DoAction x next) -> do
99+ DoAction x next -> do
70100 handleAction x
71101 pure (Just next)
72102
73103handleAction :: ∀ m . MonadAff m => Action -> HalogenM State Action ChildSlots Void m Unit
74104handleAction = case _ of
105+
106+ SelectRoute newRoute -> do
107+ H .modify_ \state -> state { route = newRoute }
108+
75109 FetchStuff -> do
76110 H .liftEffect $ log " handling action FetchStuff..."
77111
@@ -117,19 +151,74 @@ handleAction = case _ of
117151render :: ∀ m . MonadAff m => State -> ComponentHTML Action ChildSlots m
118152render state =
119153 div []
120- [ p [] [ text $ if state.status == Ok then " " else " status: " <> show state.status ]
121- , h2 [] [ text " Customer" ]
122- , div [] (maybe [] (pure <<< customerHtml) state.customer)
123- , h3 [] [ text " Customer's payment methods" ]
124- , div [] (state.paymentMethods <#> paymentMethodHtml)
125- , h2 [] [ text " Subscriptions" ]
126- , div [] (state.subscriptions <#> subscriptionHtml)
127- , h2 [] [ text " Plans" ]
128- , div [] (state.plans <#> planWithExpandedProductHtml)
129- , h2 [] [ text " Invoices" ]
130- , div [] (state.accounts <#> \account -> invoiceSummaries account.invoices)
154+ [ navMenuHtml state
155+ , contentHtml state
156+ , p [] [ text $ if state.status == Ok then " " else " status: " <> show state.status ]
131157 ]
132158
159+ navMenuHtml :: ∀ m . MonadAff m => State -> ComponentHTML Action ChildSlots m
160+ navMenuHtml state =
161+ div []
162+ [ button [ onClick \e -> Just $ SelectRoute $ Home ] [ text " Home" ]
163+ , button [ onClick \e -> Just $ SelectRoute $ Projects ] [ text " Projects" ]
164+ , button [ onClick \e -> Just $ SelectRoute $ Account ] [ text " Billing Accounts" ]
165+ , button [ onClick \e -> Just $ SelectRoute $ APIKeys ] [ text " API Keys" ]
166+ , button [ onClick \e -> Just $ SelectRoute $ Invoices fakeCustomerId ] [ text " Invoices" ]
167+ , button [ onClick \e -> Just $ SelectRoute $ Subscription ] [ text " Subscriptions" ]
168+ , button [ onClick \e -> Just $ SelectRoute $ Plan ] [ text " Plans" ]
169+ ]
170+
171+ contentHtml :: ∀ m . MonadAff m => State -> ComponentHTML Action ChildSlots m
172+ contentHtml state = case state.route of
173+ Home ->
174+ div []
175+ [ h2 [] [ text " Statebox Cloud Admin Console" ]
176+ , text " Welcome!"
177+ ]
178+ Projects ->
179+ div [] $
180+ [ h2 [] [ text " Projects" ]
181+ , div [] $ Map .toUnfoldable state.projects <#>
182+ (\(projectId /\ project) -> button [ onClick \e -> Just $ SelectRoute $ ProjectR projectId ] [ text project.name ])
183+ ]
184+ APIKeys ->
185+ div [] $
186+ [ h2 [] [ text " API keys" ]
187+ , p [] [ text " * Create" ]
188+ , p [] [ text " * Deprecate" ]
189+ , p [] [ text " * Assign to a root" ]
190+ ]
191+ ProjectR projectId ->
192+ div []
193+ [ h2 [] [ text $ " Project " <> show projectId ]
194+ , h3 [] [ text $ " API keys" ]
195+ , h3 [] [ text $ " Roots" ]
196+ ]
197+ Account ->
198+ div []
199+ [ h2 [] [ text " Customer" ]
200+ , div [] (maybe [] (pure <<< customerHtml) state.customer)
201+ , h3 [] [ text " Customer's payment methods" ]
202+ , div [] (state.paymentMethods <#> paymentMethodHtml)
203+ ]
204+ Subscription ->
205+ div []
206+ [ h2 [] [ text " Subscriptions" ]
207+ , div [] (state.subscriptions <#> subscriptionHtml)
208+ ]
209+ Invoices x ->
210+ div []
211+ [ h2 [] [ text " Invoices" ]
212+ , div [] (state.accounts <#> \account -> invoiceSummaries account.invoices)
213+ ]
214+ Plan ->
215+ div []
216+ [ h2 [] [ text " Plans" ]
217+ , div [] (state.plans <#> planWithExpandedProductHtml)
218+ ]
219+
220+ -- ------------------------------------------------------------------------------
221+
133222invoiceSummaries :: ∀ m . MonadAff m => Array Stripe.Invoice -> ComponentHTML Action ChildSlots m
134223invoiceSummaries invoices =
135224 table [] (invoices <#> invoiceSummaryLineHtml)
0 commit comments