Factor out billing create component.

[?]
Feb 3, 2021, 2:23 AM
T2DN23M7W53UMRV46SKDP6UDMCZB7VG2J772LXKMAJNL6NA62MKAC

Dependencies

  • [2] 27H4DECZ Add billing create API call.
  • [3] WRPIYG3E Use project listing functionality to check for whether we have a cookie.
  • [4] SAESJLLY Initial experiments in hash routing.
  • [5] QMEYU4MW Add display for prior intervals.
  • [6] NAFJ6RB3 Minor module reorg.
  • [7] PPW6ROC5 Render project data
  • [8] ANDJ6GEY Add billing component skeleton.
  • [9] O2BZOX7M Add signup form, captcha check.
  • [10] VTZT2ILU Wire up billing navigation.
  • [11] NJNMO72S Add zcash.com submodule and update client to modern halogen.
  • [*] EA5BFM5G Split Login component into its own module.

Change contents

  • replacement in client/spago.dhall at line 2
    [3.294970][3.294970:295116](),[3.295116][3.2:20](),[3.20][3.157:173](),[3.295116][3.157:173](),[3.173][3.376:389](),[3.295116][3.376:389](),[3.389][3.128:147](),[3.147][3.389:405](),[3.389][3.389:405](),[3.405][3.2:17](),[3.17][3.293:336](),[3.17][3.295116:295122](),[3.336][3.295116:295122](),[3.405][3.295116:295122](),[3.295116][3.295116:295122]()
    , dependencies =
    [ "console"
    , "effect"
    , "halogen"
    , "psci-support"
    , "affjax"
    , "halogen-css"
    , "argonaut-codecs"
    , "rationals"
    , "routing"
    , "uuid"
    , "validation"
    , "js-date"
    , "format"
    , "formatters"
    , "fixed-precision"
    ]
    [3.294970]
    [3.295122]
    , dependencies =
    [ "affjax"
    , "argonaut-codecs"
    , "console"
    , "effect"
    , "fixed-precision"
    , "format"
    , "formatters"
    , "halogen"
    , "halogen-css"
    , "halogen-formless"
    , "js-date"
    , "psci-support"
    , "rationals"
    , "routing"
    , "uuid"
    , "validation"
    ]
  • replacement in client/src/Aftok/Api/Billing.purs at line 22
    [3.704][3.704:755]()
    -- import Data.Time.Duration (Hours(..), Days(..))
    [3.704]
    [2.315]
    import Data.Time.Duration (Hours(..), Days(..))
  • replacement in client/src/Aftok/Api/Billing.purs at line 80
    [3.497][3.497:554]()
    , gracePeriod :: Duration
    , expiryPeriod :: Duration
    [3.497]
    [3.1670]
    , gracePeriod :: Hours
    , expiryPeriod :: Hours
  • edit in client/src/Aftok/Api/Types.purs at line 18
    [3.6328]
    newtype Stored i t = Stored
    { dbid :: i
    , value :: t
    }
  • file addition: Billing (d--r------)
    [13.1]
  • file addition: Create.purs (----------)
    [0.454]
    module Aftok.Billing.Create where
    import Prelude
    import Control.Monad.Trans.Class (lift)
    -- import Data.DateTime (DateTime, date)
    import Data.Either (Either(..))
    import Data.Foldable (all)
    import Data.Maybe (Maybe(..))
    -- import Data.Unfoldable as U
    import Data.Time.Duration (Hours(..))
    import Data.Traversable (traverse)
    import Data.Tuple (Tuple)
    import Effect.Aff (Aff)
    -- import Effect.Class (liftEffect)
    -- import Effect.Now (nowDateTime)
    import Halogen as H
    import Halogen.HTML.Core (ClassName(..))
    import Halogen.HTML as HH
    import Halogen.HTML.Events as E
    import Halogen.HTML.Properties as P
    import Aftok.ProjectList as ProjectList
    import Aftok.Types (System, ProjectId)
    import Aftok.Api.Types (APIError(..))
    import Aftok.Api.Project (Project)
    import Aftok.Api.Billing
    ( BillableId
    , Billable
    , PaymentRequestId
    , PaymentRequest
    , createBillable
    , listProjectBillables
    , listUnpaidPaymentRequests
    )
    data RType
    = RTAnnual
    | RTMonthly
    | RTWeekly
    | RTOneTime
    type CState =
    { projectId :: ProjectId
    , name :: Maybe String
    , description :: Maybe String
    , message :: Maybe String
    , recurrenceType :: Maybe RType
    , recurrenceValue :: Maybe Int
    , amount :: Maybe Number
    , gracePeriod :: Maybe Hours
    , requestExpiry :: Maybe Hours
    }
    data Query a
    = Tell a
    type Input = ProjectId
    type Output = Tuple BillableId Billable
    data Action
    = ProjectChanged ProjectId
    | SetName String
    | SetDesc String
    | SetMessage String
    | SetRecurrenceType RType
    | SetRecurrenceDuration Number
    | SetBillingAmount Number
    type Slot id
    = H.Slot Query Output id
    type Capability (m :: Type -> Type)
    = { createBillable :: ProjectId -> Billable -> m (Either APIError BillableId)
    }
    component ::
    forall m.
    Monad m =>
    System m ->
    Capability m ->
    H.Component HH.HTML Query Input Output m
    component system caps =
    H.mkComponent
    { initialState
    , render
    , eval:
    H.mkEval
    $ H.defaultEval
    { handleAction = eval
    , receive = Just <<< ProjectChanged
    }
    }
    where
    initialState :: Input -> CState
    initialState input =
    { projectId: input
    , name : Nothing
    , description : Nothing
    , message : Nothing
    , recurrenceType : Nothing
    , recurrenceValue : Nothing
    , amount : Nothing
    , gracePeriod : Nothing
    , requestExpiry : Nothing
    }
    render :: forall slots. CState -> H.ComponentHTML Action slots m
    render st =
    HH.div
    [ P.classes (ClassName <$> ["card-body"]) ]
    [ HH.form_
    [
    HH.div
    [ P.classes (ClassName <$> ["form-group"]) ]
    [ HH.label [ P.for "billableName" ] [ HH.text "Bill Name:" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes (ClassName <$> [ "form-control" ])
    , P.id_ "billableName"
    , P.placeholder "A name for the product or service you want to bill for"
    , P.required true
    , P.autofocus true
    , E.onValueInput (Just <<< SetName)
    ]
    , HH.label [ P.for "billableDesc" ] [ HH.text "Bill Description:" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes (ClassName <$> [ "form-control" ])
    , P.id_ "billableDesc"
    , P.placeholder "Description of the product or service"
    , P.required true
    , P.autofocus true
    , E.onValueInput (Just <<< SetDesc)
    ]
    ]
    ]
    ]
    eval :: forall slots. Action -> H.HalogenM CState Action slots Output m Unit
    eval = case _ of
    ProjectChanged pid ->
    H.modify_ (_ { projectId = pid })
    SetName name -> pure unit
    SetDesc desc -> pure unit
    SetMessage msg -> pure unit
    SetRecurrenceType rtype -> pure unit
    SetRecurrenceDuration dur -> pure unit
    SetBillingAmount amt -> pure unit
  • edit in client/src/Aftok/Billing.purs at line 12
    [3.3072]
    [3.3072]
    import Data.Time.Duration (Hours(..))
  • edit in client/src/Aftok/Billing.purs at line 21
    [3.3315]
    [3.3315]
    import Halogen.HTML.Events as E
  • edit in client/src/Aftok/Billing.purs at line 23
    [3.3351]
    [3.3351]
    import Aftok.Billing.Create as Create
  • edit in client/src/Aftok/Billing.purs at line 51
    [3.4022]
    [3.4022]
    | BillableCreated (Tuple BillableId Billable)
  • edit in client/src/Aftok/Billing.purs at line 58
    [3.4143]
    [3.4143]
    , createBillable :: Create.Slot Unit
  • edit in client/src/Aftok/Billing.purs at line 62
    [3.4196]
    [3.4196]
    _createBillable = SProxy :: SProxy "createBillable"
  • replacement in client/src/Aftok/Billing.purs at line 65
    [3.4233][3.4233:4313]()
    = { createBillable :: ProjectId -> Billable -> m (Either APIError BillableId)
    [3.4233]
    [3.4313]
    = { createBillable :: Create.Capability m
  • edit in client/src/Aftok/Billing.purs at line 70
    [3.4536]
    [3.4536]
  • replacement in client/src/Aftok/Billing.purs at line 120
    [3.6127][3.6127:6162]()
    [ billingDetail st ]
    [3.6127]
    [3.6162]
    case st.selectedProject of
    Just p ->
    [ HH.slot
    _createBillable
    unit
    (Create.component system caps.createBillable)
    (unwrap p).projectId
    (Just <<< BillableCreated)
    ]
    Nothing -> []
  • edit in client/src/Aftok/Billing.purs at line 135
    [3.6183][3.6183:6300]()
    billingDetail :: BillingState -> H.ComponentHTML BillingAction Slots m
    billingDetail st = do
    HH.div [] []
  • edit in client/src/Aftok/Billing.purs at line 152
    [3.7093]
    [3.7093]
    BillableCreated _ ->
    pure unit
  • replacement in client/src/Aftok/Billing.purs at line 157
    [3.7142][3.7142:7177]()
    { createBillable: createBillable
    [3.7142]
    [3.7177]
    { createBillable: { createBillable: createBillable }
  • replacement in client/src/Aftok/Billing.purs at line 164
    [3.7336][3.7336:7386]()
    { createBillable: \_ _ -> pure $ Left Forbidden
    [3.7336]
    [3.7386]
    { createBillable: { createBillable: \_ _ -> pure $ Left Forbidden }
  • edit in client/src/Aftok/Billing.purs at line 168
    [3.7503][3.7503:7504]()