Fix the broken modals.

[?]
Feb 13, 2021, 3:14 AM
XGMFJUERL5G2AX5H3UY27YAAUNO27BH36WM2PGMGXDZAVURWNVBAC

Dependencies

  • [2] RUAQYIXI Add Landkit styles to billing creation
  • [3] 46PUXHTY Implement project invitations.
  • [4] JXG3FCXY Upgrade ps + halogen versions.
  • [5] DAPLYXHY Successfully rendering QR codes sometimes.
  • [6] I4W76IFV Render recaptcha explicitly.
  • [7] N6FG4EW6 Working bootstrap modal! Only a little FFI.
  • [8] VTZT2ILU Wire up billing navigation.
  • [9] YBLHJFCN Implement billing modal.
  • [10] V54JCKJX Payment request creation.
  • [11] 5R2Z7FSX Initial rendering for signup controls.
  • [12] EA5BFM5G Split Login component into its own module.
  • [13] T2DN23M7 Factor out billing create component.
  • [14] 3PFXXJTL WIP
  • [15] QU5FW67R Add project selection to time tracker.
  • [16] U7YAT2ZK Add error reporting to signup form.
  • [17] WRPIYG3E Use project listing functionality to check for whether we have a cookie.
  • [18] GLQSD33Y Use mock capability for overview init.
  • [19] 4GOBY5NQ WIP on modals.
  • [20] Z5KNL332 Add skeleton of project overview HTML.
  • [21] KET5QGQP Add billable list (in-progress)
  • [22] KKJSBWO6 Add createPaymentRequestHandler
  • [23] NAFJ6RB3 Minor module reorg.
  • [24] I5MPORH4 Autofill signup form from query string parameters.
  • [25] RV7ZIULZ Update overview to have access to the real project detail capability.
  • [26] RSF6UAJK Break out api module for timeline.
  • [27] 7TQPQW3N Begin adding parsing for project detail.
  • [28] ANDJ6GEY Add billing component skeleton.
  • [29] QAC2QJ32 Add project overview page to client.
  • [30] BPIQKEXE gussify
  • [31] AKM2VYBL Fix errors with project ID persistence.
  • [32] VNZ4VRO6 Fix the invitation codes bug.
  • [33] QH4UB73N Format with purty.

Change contents

  • file deletion: Modals.purs (----------)
    [4.1][4.6394:6429](),[4.6429][4.4525:4525]()
    module Aftok.Modals where
    import Prelude ((<>), negate)
    import DOM.HTML.Indexed.ButtonType (ButtonType(..))
    import Halogen.HTML as HH
    import Halogen.HTML.Properties as P
    import Halogen.HTML.Properties.ARIA as ARIA
    import Aftok.HTML.Classes as C
    import Aftok.HTML.Properties as AP
    modalButton :: forall action slots m. String -> String -> Maybe action -> H.ComponentHTML action slots m
    modalButton target text action =
    HH.button
    [ P.classes [ C.btn, C.btnPrimary ]
    , AP.dataToggle "modal"
    , AP.dataTarget ("#" <> target)
    , P.type_ ButtonButton
    , E.onClick (\_ -> action)
    ]
    [ HH.text text ]
    modalWithSave ::
    forall action slots m.
    String ->
    String ->
    action ->
    Array (H.ComponentHTML action slots m) ->
    H.ComponentHTML action slots m
    modalWithSave modalId title submit contents =
    HH.div
    [ P.classes [ C.modal ]
    , P.id_ modalId
    , P.tabIndex (negate 1)
    , ARIA.role "dialog"
    , ARIA.labelledBy (modalId <> "Title")
    , ARIA.hidden "true"
    ]
    [ HH.div
    [ P.classes [C.modalDialog], ARIA.role "document" ]
    [ HH.div
    [ P.classes [C.modalContent] ]
    [ HH.div
    [ P.classes [C.modalHeader] ]
    [ HH.h5 [P.classes [C.modalTitle], P.id_ (modalId <>"Title") ] [HH.text title]
    , HH.button
    [ P.classes [ C.close ]
    , AP.dataDismiss "modal"
    , ARIA.label "Close"
    , P.type_ ButtonButton
    ]
    [ HH.span [ARIA.hidden "true"] [HH.text "×"]]
    ]
    , HH.div
    [ P.classes [C.modalBody] ]
    contents
    , HH.div
    [ P.classes [C.modalFooter] ]
    [ HH.button
    [ P.type_ ButtonButton
    , P.classes [ C.btn, C.btnSecondary]
    , AP.dataDismiss "modal"
    ]
    [ HH.text "Close" ]
    , HH.button
    [ P.type_ ButtonButton
    , P.classes [ C.btn, C.btnPrimary ]
    ]
    [ HH.text "Save changes"]
    ]
    ]
    ]
    ]
    modalWithClose ::
    forall action slots m.
    String ->
    String ->
    action ->
    Array (H.ComponentHTML action slots m) ->
    H.ComponentHTML action slots m
    modalWithClose modalId title action contents =
    HH.div
    [ P.classes [ C.modal ]
    , P.id_ modalId
    , P.tabIndex (negate 1)
    , ARIA.role "dialog"
    , ARIA.labelledBy (modalId <> "Title")
    , ARIA.hidden "true"
    ]
    [ HH.div
    [ P.classes [C.modalDialog], ARIA.role "document" ]
    [ HH.div
    [ P.classes [C.modalContent] ]
    [ HH.div
    [ P.classes [C.modalHeader] ]
    [ HH.h5 [P.classes [C.modalTitle], P.id_ (modalId <>"Title") ] [HH.text title]
    , HH.button
    [ P.classes [ C.close ]
    , AP.dataDismiss "modal"
    , ARIA.label "Close"
    , P.type_ ButtonButton
    ]
    [ HH.span [ARIA.hidden "true"] [HH.text "×"]]
    ]
    , HH.div
    [ P.classes [C.modalBody] ]
    contents
    , HH.div
    [ P.classes [C.modalFooter] ]
    [ HH.button
    [ P.type_ ButtonButton
    , P.classes [ C.btn, C.btnSecondary]
    , AP.dataDismiss "modal"
    ]
    [ HH.text "Close" ]
    ]
    ]
    ]
    ]
    , E.onClick (\_ -> Just action)
    , E.onClick (\_ -> Just submit)
    import Halogen.HTML.Events as E
    import Halogen as H
    import Data.Maybe (Maybe(..))
  • edit in client/src/Aftok/Billing/Create.purs at line 8
    [2.155][2.155:185]()
    import Aftok.Modals as Modals
  • edit in client/src/Aftok/Billing/Create.purs at line 24
    [4.850]
    [4.921]
    import DOM.HTML.Indexed.ButtonType (ButtonType(..))
  • edit in client/src/Aftok/Billing/Create.purs at line 30
    [4.1076]
    [4.860]
    import Halogen.HTML.Properties.ARIA as ARIA
  • replacement in client/src/Aftok/Billing/Create.purs at line 33
    [4.872][4.872:886]()
    = NameField
    [4.872]
    [4.886]
    = PidField
    | NameField
  • replacement in client/src/Aftok/Billing/Create.purs at line 55
    [4.1480][4.1480:1507]()
    { projectId :: ProjectId
    [4.1480]
    [4.1507]
    { projectId :: Maybe ProjectId
  • replacement in client/src/Aftok/Billing/Create.purs at line 67
    [4.1780][4.1780:1803]()
    type Input = ProjectId
    [4.1755]
    [4.1803]
    data Query a
    = OpenModal ProjectId a
  • replacement in client/src/Aftok/Billing/Create.purs at line 70
    [4.1804][4.1804:1844]()
    type Output = Tuple BillableId Billable
    [4.1804]
    [4.1844]
    data Output
    = BillableCreated BillableId
  • replacement in client/src/Aftok/Billing/Create.purs at line 74
    [4.1857][4.1857:1905]()
    = ProjectChanged ProjectId
    | SetName String
    [4.1857]
    [4.1905]
    = SetName String
  • replacement in client/src/Aftok/Billing/Create.purs at line 83
    [4.1374][4.536:553](),[4.2035][4.536:553]()
    | SaveBillable
    [4.1374]
    [4.2035]
    | Save
    | Close
  • replacement in client/src/Aftok/Billing/Create.purs at line 87
    [4.2049][4.5:46]()
    = forall query. H.Slot query Output id
    [4.2049]
    [4.2076]
    = H.Slot Query Output id
  • edit in client/src/Aftok/Billing/Create.purs at line 92
    [4.2199]
    [4.2199]
    modalId :: String
    modalId = "createBillable"
  • replacement in client/src/Aftok/Billing/Create.purs at line 97
    [4.2213][4.47:65]()
    forall query m.
    [4.2213]
    [4.2225]
    forall input m.
  • replacement in client/src/Aftok/Billing/Create.purs at line 101
    [4.2270][4.66:109]()
    H.Component HH.HTML query Input Output m
    [4.2270]
    [4.2313]
    H.Component HH.HTML Query input Output m
  • replacement in client/src/Aftok/Billing/Create.purs at line 104
    [4.2353][4.2353:2372]()
    { initialState
    [4.2353]
    [4.2372]
    { initialState: const initialState
  • replacement in client/src/Aftok/Billing/Create.purs at line 106
    [4.2385][4.2385:2542]()
    , eval:
    H.mkEval
    $ H.defaultEval
    { handleAction = eval
    , receive = Just <<< ProjectChanged
    }
    [4.2385]
    [4.2542]
    , eval: H.mkEval
    $ H.defaultEval
    { handleAction = handleAction
    , handleQuery = handleQuery
    }
  • replacement in client/src/Aftok/Billing/Create.purs at line 113
    [4.2556][4.2556:2636]()
    initialState :: Input -> CState
    initialState input =
    { projectId: input
    [4.2556]
    [4.2636]
    initialState :: CState
    initialState =
    { projectId: Nothing
  • replacement in client/src/Aftok/Billing/Create.purs at line 128
    [4.2927][4.2927:2941](),[4.2941][4.1433:1506](),[4.1506][4.619:636](),[4.619][4.619:636](),[4.636][4.1507:1554](),[4.1554][2.400:421](),[2.421][4.1555:1591](),[4.730][4.1555:1591](),[4.1591][2.422:461](),[2.461][4.861:882](),[4.1631][4.861:882](),[4.861][4.861:882](),[4.882][4.2067:2101](),[4.2067][4.2067:2101](),[4.2101][2.462:521](),[2.521][4.883:1003](),[4.1676][4.883:1003](),[4.2163][4.883:1003](),[4.2326][4.1004:1052]()
    render st =
    Modals.modalWithSave "createBillable" "Create Billable" SaveBillable
    [ HH.form_
    [ formGroup st
    [ NameField ]
    [ HH.label
    [ P.for "billableName"]
    [ HH.text "Product Name" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [ C.formControl, C.formControlSm ]
    , P.id_ "billableName"
    , P.placeholder "A name for the product or service you want to bill for"
    , E.onValueInput (Just <<< SetName)
    [4.2927]
    [4.2374]
    render st =
    HH.div
    [ P.classes [ C.modal ]
    , P.id_ modalId
    , P.tabIndex (negate 1)
    , ARIA.role "dialog"
    , ARIA.labelledBy (modalId <> "Title")
    , ARIA.hidden "true"
    ]
    [ HH.div
    [ P.classes [C.modalDialog], ARIA.role "document" ]
    [ HH.div
    [ P.classes [C.modalContent] ]
    [ HH.div
    [ P.classes [C.modalHeader] ]
    [ HH.h5 [P.classes [C.modalTitle], P.id_ (modalId <>"Title") ] [HH.text "Create a new billable item"]
    , HH.button
    [ P.classes [ C.close ]
    , ARIA.label "Close"
    , P.type_ ButtonButton
    , E.onClick (\_ -> Just Close)
    ]
    [ HH.span [ARIA.hidden "true"] [HH.text "×"]]
  • replacement in client/src/Aftok/Billing/Create.purs at line 152
    [4.2388][2.522:534](),[2.534][4.1690:1737](),[4.1690][4.1690:1737](),[4.1737][2.535:556](),[2.556][4.1759:1797](),[4.1759][4.1759:1797](),[4.1797][2.557:605](),[2.605][4.1217:1274](),[4.1846][4.1217:1274](),[4.1217][4.1217:1274](),[4.1274][2.606:667](),[2.667][4.1338:1445](),[4.1893][4.1338:1445](),[4.1338][4.1338:1445](),[4.1510][4.1510:1576](),[4.1576][4.1894:1956](),[4.1956][2.668:689](),[2.689][4.1978:2015](),[4.1978][4.1978:2015](),[4.2015][2.690:751](),[2.751][4.1755:1812](),[4.2077][4.1755:1812](),[4.1755][4.1755:1812](),[4.1812][2.752:811](),[2.811][4.1876:1912](),[4.1876][4.1876:1912](),[4.1912][4.2078:2296](),[4.2296][2.812:1805]()
    ]
    , formGroup st
    [ DescField ]
    [ HH.label
    [ P.for "billableDesc"]
    [ HH.text "Product Description" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [ C.formControl, C.formControlSm ]
    , P.id_ "billableDesc"
    , P.placeholder "Description of the product or service"
    , E.onValueInput (Just <<< SetDesc)
    ]
    ]
    , formGroup st
    [ MessageField ]
    [ HH.label
    [ P.for "billableMsg"]
    [ HH.text "Message to be included with bill" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [C.formControl, C.formControlSm]
    , P.id_ "billableMsg"
    , P.placeholder "Enter your message here"
    , E.onValueInput (Just <<< SetMessage)
    ]
    ]
    , formGroup st
    [MonthlyRecurrenceField, WeeklyRecurrenceField]
    [ formCheckGroup
    { id: "recurAnnual"
    , checked: (st.recurrenceType == RTAnnual)
    , labelClasses: []
    }
    (\_ -> Just (SetRecurrenceType RTAnnual))
    [ HH.text "Annual" ]
    , formCheckGroup
    { id: "recurMonthly"
    , checked: (st.recurrenceType == RTMonthly)
    , labelClasses: [C.formInline]
    }
    (\_ -> Just (SetRecurrenceType RTMonthly))
    [ HH.text "Every"
    , HH.input
    [ P.type_ P.InputNumber
    , P.classes [ C.formControl, C.formControlXs, C.formControlFlush, C.marginX2 ]
    , P.value (if st.recurrenceType == RTMonthly
    then maybe "" show st.recurrenceValue
    else "")
    , P.min 1.0
    , P.max 12.0
    , E.onValueInput (Just <<< SetRecurrenceMonths)
    [4.2388]
    [2.1805]
    , HH.div
    [ P.classes [C.modalBody] ]
    [ HH.form_
    [ formGroup st
    [ NameField ]
    [ HH.label
    [ P.for "billableName"]
    [ HH.text "Product Name" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [ C.formControl, C.formControlSm ]
    , P.id_ "billableName"
    , P.placeholder "A name for the product or service you want to bill for"
    , E.onValueInput (Just <<< SetName)
  • replacement in client/src/Aftok/Billing/Create.purs at line 167
    [2.1825][2.1825:2114](),[2.2114][4.2936:2999](),[4.2936][4.2936:2999](),[4.2999][2.2115:2210](),[2.2210][4.3824:4111](),[4.3824][4.3824:4111]()
    , HH.text "Months"]
    , formCheckGroup
    { id: "recurWeekly"
    , checked: (st.recurrenceType == RTWeekly)
    , labelClasses: [C.formInline]
    }
    (\_ -> Just (SetRecurrenceType RTWeekly))
    [ HH.text "Every"
    , HH.input
    [ P.type_ P.InputNumber
    , P.classes [ C.formControl, C.formControlXs, C.formControlFlush, C.marginX2 ]
    , P.value (if st.recurrenceType == RTWeekly
    then maybe "" show st.recurrenceValue
    else "")
    , P.min 1.0
    , P.max 12.0
    , E.onValueInput (Just <<< SetRecurrenceWeeks)
    [2.1825]
    [2.2211]
    ]
    , formGroup st
    [ DescField ]
    [ HH.label
    [ P.for "billableDesc"]
    [ HH.text "Product Description" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [ C.formControl, C.formControlSm ]
    , P.id_ "billableDesc"
    , P.placeholder "Description of the product or service"
    , E.onValueInput (Just <<< SetDesc)
    ]
    ]
    , formGroup st
    [ MessageField ]
    [ HH.label
    [ P.for "billableMsg"]
    [ HH.text "Message to be included with bill" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [C.formControl, C.formControlSm]
    , P.id_ "billableMsg"
    , P.placeholder "Enter your message here"
    , E.onValueInput (Just <<< SetMessage)
    ]
  • replacement in client/src/Aftok/Billing/Create.purs at line 194
    [2.2229][2.2229:2259](),[2.2259][4.4491:4505](),[4.4491][4.4491:4505](),[4.4505][2.2260:2504](),[2.2504][4.4505:4564](),[4.4505][4.4505:4564](),[4.4564][2.2505:2526](),[2.2526][4.4586:4626](),[4.4586][4.4586:4626](),[4.4626][2.2527:2562](),[2.2562][4.5001:5020](),[4.2113][4.5001:5020](),[4.5020][2.2563:3011]()
    , HH.text "Weeks"
    ]
    , formCheckGroup
    { id: "oneTime"
    , checked: st.recurrenceType == RTOneTime
    , labelClasses: []
    }
    (\_ -> Just (SetRecurrenceType RTOneTime))
    [ HH.text "One-Time" ]
    ]
    , formGroup st
    [AmountField]
    [ HH.label
    [ P.for "billableAmount"]
    [ HH.text "Amount" ]
    , HH.div
    [ P.classes [ ClassName "input-group", ClassName "input-group-sm" ] ]
    [ HH.input
    [ P.type_ P.InputNumber
    , P.classes [ C.formControl ]
    , P.id_ "billableAmount"
    , P.value (maybe "" (Fixed.toString <<< unwrap) st.amount)
    , P.placeholder "1.0"
    , P.min 0.0
    , E.onValueInput (Just <<< SetBillingAmount)
    [2.2229]
    [2.3011]
    , formGroup st
    [MonthlyRecurrenceField, WeeklyRecurrenceField]
    [ formCheckGroup
    { id: "recurAnnual"
    , checked: (st.recurrenceType == RTAnnual)
    , labelClasses: []
    }
    (\_ -> Just (SetRecurrenceType RTAnnual))
    [ HH.text "Annual" ]
    , formCheckGroup
    { id: "recurMonthly"
    , checked: (st.recurrenceType == RTMonthly)
    , labelClasses: [C.formInline]
    }
    (\_ -> Just (SetRecurrenceType RTMonthly))
    [ HH.text "Every"
    , HH.input
    [ P.type_ P.InputNumber
    , P.classes [ C.formControl, C.formControlXs, C.formControlFlush, C.marginX2 ]
    , P.value (if st.recurrenceType == RTMonthly
    then maybe "" show st.recurrenceValue
    else "")
    , P.min 1.0
    , P.max 12.0
    , E.onValueInput (Just <<< SetRecurrenceMonths)
    ]
    , HH.text "Months"]
    , formCheckGroup
    { id: "recurWeekly"
    , checked: (st.recurrenceType == RTWeekly)
    , labelClasses: [C.formInline]
    }
    (\_ -> Just (SetRecurrenceType RTWeekly))
    [ HH.text "Every"
    , HH.input
    [ P.type_ P.InputNumber
    , P.classes [ C.formControl, C.formControlXs, C.formControlFlush, C.marginX2 ]
    , P.value (if st.recurrenceType == RTWeekly
    then maybe "" show st.recurrenceValue
    else "")
    , P.min 1.0
    , P.max 12.0
    , E.onValueInput (Just <<< SetRecurrenceWeeks)
    ]
    , HH.text "Weeks"
  • replacement in client/src/Aftok/Billing/Create.purs at line 240
    [2.3031][2.3031:3297]()
    , HH.div
    [ P.classes [ ClassName "input-group-append"] ]
    [ HH.span
    [ P.classes [ ClassName "input-group-text" ]
    , P.style "height: auto;" -- fix bad calculated height from LandKit
    [2.3031]
    [2.3297]
    , formCheckGroup
    { id: "oneTime"
    , checked: st.recurrenceType == RTOneTime
    , labelClasses: []
    }
    (\_ -> Just (SetRecurrenceType RTOneTime))
    [ HH.text "One-Time" ]
    ]
    , formGroup st
    [AmountField]
    [ HH.label
    [ P.for "billableAmount"]
    [ HH.text "Amount" ]
    , HH.div
    [ P.classes [ ClassName "input-group", ClassName "input-group-sm" ] ]
    [ HH.input
    [ P.type_ P.InputNumber
    , P.classes [ C.formControl ]
    , P.id_ "billableAmount"
    , P.value (maybe "" (Fixed.toString <<< unwrap) st.amount)
    , P.placeholder "1.0"
    , P.min 0.0
    , E.onValueInput (Just <<< SetBillingAmount)
    ]
    , HH.div
    [ P.classes [ ClassName "input-group-append"] ]
    [ HH.span
    [ P.classes [ ClassName "input-group-text" ]
    , P.style "height: auto;" -- fix bad calculated height from LandKit
    ]
    [ HH.text "ZEC" ] ]
  • replacement in client/src/Aftok/Billing/Create.purs at line 272
    [2.3319][2.3319:3359]()
    [ HH.text "ZEC" ] ]
    [2.3319]
    [2.3359]
    ]
    , formGroup st
    [GracePeriodField]
    [ HH.label
    [ P.for "gracePeriod"]
    [ HH.text "Grace Period (Days)" ]
    , HH.input
    [ P.type_ P.InputNumber
    , P.id_ "gracePeriod"
    , P.classes [ C.formControl, C.formControlSm ]
    , P.value (maybe "" (Number.toString <<< unwrap) st.gracePeriod)
    , P.placeholder "Days until a bill is considered overdue"
    , P.min 0.0
    , E.onValueInput (Just <<< SetGracePeriod)
    ]
    ]
    , formGroup st
    [RequestExpiryField]
    [ HH.label
    [ P.for "requestExpiry"]
    [ HH.text "Request Expiry Period (Hours)" ]
    , HH.input
    [ P.type_ P.InputNumber
    , P.id_ "gracePeriod"
    , P.classes [ C.formControl, C.formControlSm ]
    , P.value (maybe "" (Number.toString <<< unwrap) st.requestExpiry)
    , P.placeholder "Hours until a payment request expires"
    , P.min 0.0
    , E.onValueInput (Just <<< SetRequestExpiry)
    ]
    ]
  • replacement in client/src/Aftok/Billing/Create.purs at line 304
    [2.3375][4.2113:2125](),[4.5174][4.2113:2125](),[4.2113][4.2113:2125](),[4.2125][4.5175:5228](),[4.5228][2.3376:3397](),[2.3397][4.5250:5287](),[4.5250][4.5250:5287](),[4.5287][2.3398:3446](),[4.1109][4.5337:5432](),[2.3446][4.5337:5432](),[4.5337][4.5337:5432](),[4.5432][2.3447:3508](),[2.3508][4.5478:5557](),[4.5478][4.5478:5557](),[4.5557][4.1110:1182](),[4.1182][4.5630:5713](),[4.5630][4.5630:5713]()
    ]
    , formGroup st
    [GracePeriodField]
    [ HH.label
    [ P.for "gracePeriod"]
    [ HH.text "Grace Period (Days)" ]
    , HH.input
    [ P.type_ P.InputNumber
    , P.id_ "gracePeriod"
    , P.classes [ C.formControl, C.formControlSm ]
    , P.value (maybe "" (Number.toString <<< unwrap) st.gracePeriod)
    , P.placeholder "Days until a bill is considered overdue"
    , P.min 0.0
    , E.onValueInput (Just <<< SetGracePeriod)
    [2.3375]
    [2.3509]
    , formGroup st [PidField] []
    ]
    , HH.div
    [ P.classes [C.modalFooter] ]
    [ HH.button
    [ P.type_ ButtonButton
    , P.classes [ C.btn, C.btnSecondary]
    , E.onClick (\_ -> Just Close)
  • replacement in client/src/Aftok/Billing/Create.purs at line 313
    [2.3525][4.5730:5796](),[4.5730][4.5730:5796](),[4.5796][2.3526:3547](),[2.3547][4.5818:5857](),[4.5818][4.5818:5857](),[4.5857][2.3548:3606](),[2.3606][4.5916:6011](),[4.5916][4.5916:6011](),[4.6011][2.3607:3668](),[2.3668][4.6057:6293](),[4.6057][4.6057:6293]()
    ]
    , formGroup st
    [RequestExpiryField]
    [ HH.label
    [ P.for "requestExpiry"]
    [ HH.text "Request Expiry Period (Hours)" ]
    , HH.input
    [ P.type_ P.InputNumber
    , P.id_ "gracePeriod"
    , P.classes [ C.formControl, C.formControlSm ]
    , P.value (maybe "" (Number.toString <<< unwrap) st.requestExpiry)
    , P.placeholder "Hours until a payment request expires"
    , P.min 0.0
    , E.onValueInput (Just <<< SetRequestExpiry)
    [2.3525]
    [2.3669]
    [ HH.text "Close" ]
    , HH.button
    [ P.type_ ButtonButton
    , P.classes [ C.btn, C.btnPrimary ]
    , E.onClick (\_ -> Just Save)
  • edit in client/src/Aftok/Billing/Create.purs at line 319
    [2.3685]
    [4.6310]
    [ HH.text "Create billable"]
    ]
  • replacement in client/src/Aftok/Billing/Create.purs at line 324
    [4.4021][2.3686:3687]()
    [4.4021]
    [2.3687]
    formGroup :: forall i a. CState -> Array Field -> Array (HH.HTML i a) -> HH.HTML i a
    formGroup st fields body =
    HH.div
    [ P.classes [C.formGroup] ]
    (body <> (fieldError st =<< fields))
  • replacement in client/src/Aftok/Billing/Create.purs at line 354
    [2.4367][4.2389:2390](),[4.4021][4.2389:2390](),[4.2390][4.6323:6410](),[4.6410][2.4368:4397](),[2.4397][4.6440:6484](),[4.6440][4.6440:6484](),[4.6484][2.4398:4440](),[4.2554][4.4021:4022](),[2.4440][4.4021:4022](),[4.6527][4.4021:4022](),[4.4021][4.4021:4022]()
    formGroup :: forall i a. CState -> Array Field -> Array (HH.HTML i a) -> HH.HTML i a
    formGroup st fields body =
    HH.div
    [ P.classes [C.formGroup] ]
    (body <> (fieldError st =<< fields))
    [2.4367]
    [4.6528]
  • edit in client/src/Aftok/Billing/Create.purs at line 359
    [4.6686]
    [4.6686]
    PidField -> err "No project id found; please report an error"
  • replacement in client/src/Aftok/Billing/Create.purs at line 370
    [4.7294][4.7294:7411]()
    err str = [ HH.div_ [ HH.span [ P.classes (ClassName <$> [ "badge", "badge-danger-soft" ]) ] [ HH.text str ] ] ]
    [4.7294]
    [4.2555]
    err str =
    [ HH.div_
    [ HH.span
    [ P.classes (ClassName <$> [ "badge", "badge-danger-soft" ]) ] [ HH.text str ] ]
    ]
    -- we use a query to initialize, since this is a modal that doesn't actually get unloaded.
    handleQuery :: forall slots a. Query a -> H.HalogenM CState Action slots Output m (Maybe a)
    handleQuery = case _ of
    OpenModal pid a -> do
    H.modify_ (\_ -> initialState { projectId = Just pid })
    lift $ system.toggleModal modalId ModalFFI.ShowModal
    pure (Just a)
  • replacement in client/src/Aftok/Billing/Create.purs at line 384
    [4.2556][4.4022:4190](),[4.4022][4.4022:4190]()
    eval :: forall slots. Action -> H.HalogenM CState Action slots Output m Unit
    eval = case _ of
    ProjectChanged pid ->
    H.modify_ (_ { projectId = pid })
    [4.2556]
    [2.4505]
    handleAction :: forall slots. Action -> H.HalogenM CState Action slots Output m Unit
    handleAction = case _ of
  • replacement in client/src/Aftok/Billing/Create.purs at line 420
    [4.8941][4.8941:8966]()
    SaveBillable -> do
    [4.8941]
    [4.8966]
    Save -> do
    pidV <- V <<< note [PidField] <$> H.gets (_.projectId)
  • replacement in client/src/Aftok/Billing/Create.purs at line 425
    [4.9093][4.9093:9158]()
    msgV <- V <<< note [MessageField] <$> H.gets (_.message)
    [4.9093]
    [4.9158]
    msgV <- V <<< note [MessageField] <$> H.gets (_.message)
  • replacement in client/src/Aftok/Billing/Create.purs at line 454
    [4.10441][4.10441:10581](),[4.10625][4.10625:10665]()
    case toEither reqV of
    Left errors -> do
    H.modify_ (_ { fieldErrors = errors })
    Right billable -> do
    pid <- H.gets (_.projectId)
    [4.10441]
    [4.10665]
    case toEither (Tuple <$> pidV <*> reqV) of
    Right (Tuple pid billable) -> do
  • replacement in client/src/Aftok/Billing/Create.purs at line 459
    [4.10778][4.10778:10901](),[4.10901][2.4756:4783]()
    H.raise (Tuple bid billable)
    lift $ system.toggleModal "createBillable" ModalFFI.HideModal
    Left errs ->
    [4.10778]
    [4.10929]
    H.raise (BillableCreated bid)
    handleAction Close
    Left errs -> do
  • edit in client/src/Aftok/Billing/Create.purs at line 463
    [4.10977]
    [4.10977]
    Left errors -> do
    H.modify_ (_ { fieldErrors = errors })
    Close -> do
    H.modify_ (const initialState) -- wipe the state for safety
    lift $ system.toggleModal modalId ModalFFI.HideModal
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 5
    [4.970][4.431:473]()
    -- import Control.Monad.State.Class (get)
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 8
    [4.152][3.1454:1483]()
    import Data.Newtype (unwrap)
    [4.152]
    [4.3584]
    import Data.Symbol (SProxy(..))
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 10
    [4.3614][4.153:189](),[4.189][4.513:541](),[4.513][4.513:541]()
    import Data.Traversable (traverse_)
    import Data.Unfoldable as U
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 12
    [4.1503]
    [4.1574]
    import DOM.HTML.Indexed.ButtonType (ButtonType(..))
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 18
    [4.1729][4.1729:1870]()
    import Aftok.Types (System, ProjectId)
    import Aftok.HTML.Classes as C
    import Aftok.Modals as Modals
    import Aftok.Modals.ModalFFI as ModalFFI
    [4.1729]
    [3.1484]
    import Halogen.HTML.Properties.ARIA as ARIA
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 23
    [4.1948]
    [4.3676]
    , PaymentRequest'(..)
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 28
    [4.2003]
    [4.2288]
    import Aftok.Components.Zip321QR as Zip321QR
    import Aftok.HTML.Classes as C
    import Aftok.Modals.ModalFFI as ModalFFI
    import Aftok.Types (System, ProjectId)
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 34
    [4.3760][4.3760:3777]()
    = NameRequired
    [4.3760]
    [4.3777]
    = PidFieldNotSet
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 36
    [4.3798]
    [4.2354]
    | NameRequired
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 42
    [4.2406][4.2406:2433]()
    { projectId :: ProjectId
    [4.2406]
    [4.3884]
    { projectId :: Maybe ProjectId
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 47
    [4.3956]
    [4.2697]
    , mode :: Mode
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 50
    [4.2702][4.190:213]()
    type Input = ProjectId
    [4.2702]
    [4.2726]
    data Mode
    = Form
    | QrScan Zip321Request
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 55
    [4.228][4.228:288]()
    = SetProjectId ProjectId a
    | SetBillableId BillableId a
    [4.228]
    [4.2750]
    = OpenModal ProjectId BillableId a
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 57
    [4.2751][4.4084:4113](),[4.4113][4.2791:2792](),[4.2791][4.2791:2792]()
    type Output = PaymentRequest
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 58
    [4.2804][4.289:337]()
    = ProjectChanged ProjectId
    | SetName String
    [4.2804]
    [4.2852]
    = SetName String
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 61
    [4.4157]
    [4.3081]
    | Close
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 64
    [4.3095][4.3095:3122]()
    = H.Slot Query Output id
    [4.3095]
    [4.3122]
    = forall output. H.Slot Query output id
    type Slots
    = ( requestQR :: Zip321QR.Slot Unit
    )
    _requestQR = SProxy :: SProxy "requestQR"
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 84
    [4.3259][4.3259:3271]()
    forall m.
    [4.3259]
    [4.3271]
    forall input output m.
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 88
    [4.3316][4.3316:3359]()
    H.Component HH.HTML Query Input Output m
    [4.3316]
    [4.3359]
    H.Component HH.HTML Query input output m
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 91
    [4.3399][4.3399:3418]()
    { initialState
    [4.3399]
    [4.3418]
    { initialState: const initialState
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 98
    [4.4444][4.338:388]()
    , receive = Just <<< ProjectChanged
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 101
    [4.3602][4.3602:3659](),[4.3659][4.389:412]()
    initialState :: Input -> CState
    initialState input =
    { projectId: input
    [4.3602]
    [4.412]
    initialState :: CState
    initialState =
    { projectId: Nothing
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 105
    [4.438][4.3682:3731](),[4.4513][4.3682:3731](),[4.3682][4.3682:3731](),[4.3901][4.3901:3924]()
    , name : Nothing
    , description : Nothing
    , fieldErrors : []
    [4.438]
    [4.3924]
    , name: Nothing
    , description: Nothing
    , fieldErrors: []
    , mode: Form
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 111
    [4.19122][4.3931:3998]()
    render :: forall slots. CState -> H.ComponentHTML Action slots m
    [4.19122]
    [4.3998]
    render :: CState -> H.ComponentHTML Action Slots m
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 113
    [4.4012][4.4514:4591](),[4.4591][4.4085:4125](),[4.4085][4.4085:4125](),[4.4125][4.4592:4714](),[4.4714][4.4247:4302](),[4.4247][4.4247:4302](),[4.4302][4.4715:4869](),[4.4869][4.439:484](),[4.484][4.4466:4514](),[4.4869][4.4466:4514](),[4.4466][4.4466:4514]()
    Modals.modalWithSave modalId "Create Payment Request" SavePaymentRequest
    [ HH.form_
    [ formGroup st
    [ NameRequired ]
    [ HH.label
    [ P.for "requestName"]
    [ HH.text "Request Name" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [ C.formControl, C.formControlSm ]
    , P.id_ "requestName"
    , P.placeholder "A name for the payment request"
    , P.value (fromMaybe "" st.name)
    , E.onValueInput (Just <<< SetName)
    [4.4012]
    [4.4514]
    HH.div
    [ P.classes [ C.modal ]
    , P.id_ modalId
    , P.tabIndex (negate 1)
    , ARIA.role "dialog"
    , ARIA.labelledBy (modalId <> "Title")
    , ARIA.hidden "true"
    ]
    [ HH.div
    [ P.classes [C.modalDialog], ARIA.role "document" ]
    [ HH.div
    [ P.classes [C.modalContent] ]
    [ HH.div
    [ P.classes [C.modalHeader] ]
    [ HH.h5 [P.classes [C.modalTitle], P.id_ (modalId <>"Title") ] [HH.text "Request a payment"]
    , HH.button
    [ P.classes [ C.close ]
    , ARIA.label "Close"
    , P.type_ ButtonButton
    , E.onClick (\_ -> Just Close)
    ]
    [ HH.span [ARIA.hidden "true"] [HH.text "×"]]
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 136
    [4.4528]
    [4.4973]
    , HH.div
    [ P.classes [C.modalBody] ]
    case st.mode of
    Form ->
    [ requestForm st ]
    QrScan req ->
    [ HH.slot _requestQR unit (Zip321QR.component system) req (const Nothing) ]
    , HH.div
    [ P.classes [C.modalFooter] ] $
    case st.mode of
    Form ->
    [ HH.button
    [ P.type_ ButtonButton
    , P.classes [ C.btn, C.btnSecondary]
    , E.onClick (\_ -> Just Close)
    ]
    [ HH.text "Close" ]
    , HH.button
    [ P.type_ ButtonButton
    , P.classes [ C.btn, C.btnPrimary ]
    , E.onClick (\_ -> Just SavePaymentRequest)
    ]
    [ HH.text "Create Request" ]
    ]
    QrScan _ ->
    [ HH.button
    [ P.type_ ButtonButton
    , P.classes [ C.btn, C.btnPrimary]
    , E.onClick (\_ -> Just Close)
    ]
    [ HH.text "Close" ]
    ]
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 171
    [4.4985][4.4985:5008](),[4.5008][4.4870:4990](),[4.4990][4.5156:5213](),[4.5156][4.5156:5213](),[4.5213][4.4991:5155](),[4.5155][4.485:539](),[4.539][4.5155:5205](),[4.5155][4.5155:5205](),[4.5205][4.8171:8187](),[4.8171][4.8171:8187]()
    , formGroup st
    [ ]
    [ HH.label
    [ P.for "requestDesc"]
    [ HH.text "Request Description" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [ C.formControl, C.formControlSm ]
    , P.id_ "requestDesc"
    , P.placeholder "Additional descriptive information"
    , P.value (fromMaybe "" st.description)
    , E.onValueInput (Just <<< SetDesc)
    ]
    [4.4985]
    [4.8360]
    ]
    ]
    requestForm st =
    HH.form_
    [ formGroup st
    [ NameRequired ]
    [ HH.label
    [ P.for "requestName"]
    [ HH.text "Request Name" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [ C.formControl, C.formControlSm ]
    , P.id_ "requestName"
    , P.placeholder "A name for the payment request"
    , P.value (fromMaybe "" st.name)
    , E.onValueInput (Just <<< SetName)
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 190
    [4.8372]
    [4.9517]
    ]
    , formGroup st
    [ ]
    [ HH.label
    [ P.for "requestDesc"]
    [ HH.text "Request Description" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [ C.formControl, C.formControlSm ]
    , P.id_ "requestDesc"
    , P.placeholder "Additional descriptive information"
    , P.value (fromMaybe "" st.description)
    , E.onValueInput (Just <<< SetDesc)
    ]
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 217
    [4.9899]
    [4.5507]
    PidFieldNotSet -> err "The project id is missing. Close this dialog and try again."
    BillableIdNotSet -> err "The billable id is missing. Close this dialog and try again."
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 220
    [4.5568][4.5568:5667]()
    BillableIdNotSet -> err "The billable id is missing. Close this dialog and try again."
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 224
    [4.10625][4.5668:5762]()
    handleQuery :: forall slots a. Query a -> H.HalogenM CState Action slots Output m (Maybe a)
    [4.10625]
    [4.5762]
    handleQuery :: forall slots a. Query a -> H.HalogenM CState Action slots output m (Maybe a)
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 226
    [4.5788][4.540:691](),[4.691][4.5788:5864](),[4.5788][4.5788:5864]()
    SetProjectId pid a -> do
    H.modify_ (_ { projectId = pid, billableId = Nothing, name = Nothing, description = Nothing })
    pure (Just a)
    SetBillableId bid a -> do
    H.modify_ (_ { billableId = Just bid })
    [4.5788]
    [4.5864]
    OpenModal pid bid a -> do
    H.modify_ (\_ -> initialState { projectId = Just pid, billableId = Just bid } )
    lift $ system.toggleModal modalId ModalFFI.ShowModal
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 231
    [4.13821][4.5885:5972]()
    handleAction :: forall slots. Action -> H.HalogenM CState Action slots Output m Unit
    [4.13821]
    [4.5972]
    handleAction :: forall slots. Action -> H.HalogenM CState Action slots output m Unit
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 233
    [4.5999][4.692:819]()
    ProjectChanged pid ->
    H.modify_ (_ { projectId = pid, billableId = Nothing, name = Nothing, description = Nothing })
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 238
    [4.6157]
    [4.6157]
    pidV <- V <<< note [PidFieldNotSet] <$> H.gets (_.projectId)
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 243
    [4.6403][4.6403:6627]()
    breqV = Tuple <$> bidV <*> reqV
    case toEither breqV of
    Left errors -> do
    H.modify_ (_ { fieldErrors = errors })
    Right (Tuple bid reqMeta) -> do
    pid <- H.gets (_.projectId)
    [4.6403]
    [4.6627]
    case toEither (Tuple <$> pidV <*> (Tuple <$> bidV <*> reqV)) of
    Right (Tuple pid (Tuple bid reqMeta)) -> do
  • replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 247
    [4.6715][4.6715:6747](),[4.6798][4.6798:6828](),[4.6828][4.820:930](),[4.930][4.6828:6910](),[4.6828][4.6828:6910]()
    Right content -> do
    H.raise content
    H.modify_ (_ { billableId = Nothing, name = Nothing, description = Nothing, fieldErrors = [] })
    lift $ system.toggleModal "createPaymentRequest" ModalFFI.HideModal
    [4.6715]
    [4.6910]
    Right (PaymentRequest req) -> do
    H.modify_ (_ { mode = QrScan $ Zip321Request req.native_request.zip321_request })
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 251
    [4.6981]
    [4.14313]
    Left errors -> do
    H.modify_ (_ { fieldErrors = errors })
    Close -> do
    H.modify_ (const initialState) -- wipe the state for safety
    lift $ system.toggleModal "createPaymentRequest" ModalFFI.HideModal
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 265
    [4.7090][4.7090:7092](),[4.7092][3.1542:1577](),[3.1577][4.578:595](),[4.578][4.578:595](),[4.595][3.1578:1609](),[3.1609][4.627:659](),[4.627][4.627:659]()
    type QrInput = Maybe Zip321Request
    type QrState =
    { req :: Maybe Zip321Request
    , dataUrl :: Maybe String
    }
  • edit in client/src/Aftok/Billing/PaymentRequest.purs at line 266
    [4.7129][4.7129:7144](),[4.7144][3.1610:1639](),[3.1639][4.7174:7201](),[4.7174][4.7174:7201](),[4.7201][4.931:943](),[4.943][4.7201:7358](),[4.7201][4.7201:7358](),[4.7358][4.660:707](),[4.707][4.7420:7702](),[4.7420][4.7420:7702](),[4.7702][4.708:806](),[4.806][4.7794:7879](),[4.7794][4.7794:7879](),[4.7879][4.944:1006](),[4.1006][4.7933:7949](),[4.7933][4.7933:7949](),[4.7949][4.807:873](),[4.873][3.1640:1804](),[4.873][4.8010:8167](),[3.1804][4.8010:8167](),[4.8010][4.8010:8167](),[4.8167][4.874:909](),[4.909][3.1805:1866](),[4.956][4.8191:8304](),[3.1866][4.8191:8304](),[4.8191][4.8191:8304](),[4.8304][4.1007:1188](),[4.986][4.14504:14505](),[4.1188][4.14504:14505](),[4.8392][4.14504:14505](),[4.14504][4.14504:14505](),[4.14505][3.1867:1983]()
    data QrQuery a
    = QrRender Zip321Request a
    data QrAction
    = QrInit
    | QrClose
    type QrSlot id
    = H.Slot QrQuery Unit id
    qrModalId :: String
    qrModalId = "paymentRequestQR"
    qrcomponent ::
    forall m output.
    Monad m =>
    System m ->
    H.Component HH.HTML QrQuery QrInput output m
    qrcomponent system =
    H.mkComponent
    { initialState
    , render
    , eval:
    H.mkEval
    $ H.defaultEval
    { handleAction = handleAction
    , handleQuery = handleQuery
    , initialize = Just QrInit
    }
    }
    where
    initialState :: QrInput -> QrState
    initialState input =
    { req: input, dataUrl: Nothing }
    render :: forall slots. QrState -> H.ComponentHTML QrAction slots m
    render st =
    Modals.modalWithClose qrModalId "Payment Request" QrClose
    [ HH.div_
    ((\url -> HH.img [P.src url]) <$> U.fromMaybe st.dataUrl)
    , HH.div_
    [ HH.span
    [ P.classes (ClassName <$> ["code", "zip321uri"]) ]
    (HH.text <<< unwrap <$> U.fromMaybe st.req)
    ]
    ]
    handleQuery :: forall slots a. QrQuery a -> H.HalogenM QrState QrAction slots output m (Maybe a)
    handleQuery = case _ of
    QrRender r a -> do
    dataUrl <- lift $ renderQR r
    H.modify_ (_ { req = Just r, dataUrl = Just dataUrl })
    pure (Just a)
    handleAction :: forall slots. QrAction -> H.HalogenM QrState QrAction slots output m Unit
    handleAction = case _ of
    QrInit -> do
    req <- H.gets (_.req)
    lift $ traverse_ renderQR req
    QrClose ->
    H.modify_ (_ { req = Nothing, dataUrl = Nothing })
    renderQR :: Zip321Request -> m String
    renderQR (Zip321Request r) =
    system.renderQR { value: r, size: 300 }
  • replacement in client/src/Aftok/Billing.purs at line 28
    [4.3430][3.1985:2042]()
    import Aftok.Api.Types (APIError(..), Zip321Request(..))
    [4.3430]
    [4.3468]
    import Aftok.Api.Types (APIError(..))
  • edit in client/src/Aftok/Billing.purs at line 35
    [4.3596][3.2043:2067]()
    , PaymentRequest'(..)
  • edit in client/src/Aftok/Billing.purs at line 40
    [4.8672][4.2636:2666](),[4.3674][4.2636:2666](),[4.2666][4.8673:8714]()
    import Aftok.Modals as Modals
    import Aftok.Modals.ModalFFI as ModalFFI
  • replacement in client/src/Aftok/Billing.purs at line 54
    [4.4022][4.4566:4614](),[4.4614][4.8759:8838]()
    | BillableCreated (Tuple BillableId Billable)
    | CreatePaymentRequest BillableId
    | PaymentRequestCreated (PaymentRequest)
    [4.4022]
    [4.4022]
    | OpenBillableModal ProjectId
    | BillableCreated BillableId
    | OpenPaymentRequestModal ProjectId BillableId
  • edit in client/src/Aftok/Billing.purs at line 65
    [4.14673][4.8839:8894]()
    , showPaymentRequest :: PaymentRequest.QrSlot Unit
  • edit in client/src/Aftok/Billing.purs at line 70
    [4.14738][4.8895:8955]()
    _showPaymentRequest = SProxy :: SProxy "showPaymentRequest"
  • replacement in client/src/Aftok/Billing.purs at line 128
    [4.4825][4.2724:2776]()
    [ renderBillableList st.billables
    [4.4825]
    [4.14739]
    [ renderBillableList (unwrap p).projectId st.billables
  • replacement in client/src/Aftok/Billing.purs at line 131
    [4.14833][4.9015:9100]()
    [ Modals.modalButton "createBillable" "Create billable" Nothing]
    [4.14833]
    [4.14911]
    [ HH.button
    [ P.classes [ C.btn, C.btnPrimary ]
    , P.type_ ButtonButton
    , E.onClick (\_ -> Just (OpenBillableModal (unwrap p).projectId))
    ]
    [ HH.text "Create billable" ]
    ]
  • replacement in client/src/Aftok/Billing.purs at line 142
    [4.15078][4.15078:15121]()
    (unwrap p).projectId
    [4.15078]
    [4.15121]
    unit
  • replacement in client/src/Aftok/Billing.purs at line 144
    [4.15151][4.15151:15200]()
    (Just <<< BillableCreated)
    [4.15151]
    [4.2223]
    (\(Create.BillableCreated bid) -> Just (BillableCreated bid))
  • edit in client/src/Aftok/Billing.purs at line 149
    [4.9228][4.1190:1233](),[4.1233][4.2433:2463](),[4.9319][4.2433:2463](),[4.2433][4.2433:2463](),[4.2463][4.9320:9451]()
    (unwrap p).projectId
    Nothing
    (Just <<< PaymentRequestCreated)
    , system.portal
    _showPaymentRequest
  • edit in client/src/Aftok/Billing.purs at line 150
    [4.9478][4.9478:9536]()
    (PaymentRequest.qrcomponent system)
  • edit in client/src/Aftok/Billing.purs at line 151
    [4.9566][4.9566:9596]()
    Nothing
  • replacement in client/src/Aftok/Billing.purs at line 158
    [4.6183][4.2851:2984]()
    renderBillableList :: Array (Tuple BillableId Billable) -> H.ComponentHTML BillingAction Slots m
    renderBillableList billables =
    [4.6183]
    [4.2984]
    renderBillableList :: ProjectId -> Array (Tuple BillableId Billable) -> H.ComponentHTML BillingAction Slots m
    renderBillableList pid billables =
  • replacement in client/src/Aftok/Billing.purs at line 188
    [4.9746][4.9746:9812]()
    , E.onClick (\_ -> Just $ CreatePaymentRequest bid)
    [4.9746]
    [4.9812]
    , E.onClick (\_ -> Just $ OpenPaymentRequestModal pid bid)
  • replacement in client/src/Aftok/Billing.purs at line 190
    [4.9828][4.9828:9876]()
    [ HH.text "New Payment Request" ]
    [4.9828]
    [4.9876]
    [ HH.text "New payment request" ]
  • edit in client/src/Aftok/Billing.purs at line 215
    [4.7093]
    [4.4049]
    OpenBillableModal pid -> do
    void $ H.query _createBillable unit $ H.tell (Create.OpenModal pid)
  • replacement in client/src/Aftok/Billing.purs at line 223
    [4.9892][4.9892:9929](),[4.9983][4.9983:10152](),[4.10152][3.2068:2123](),[3.2123][4.10258:10334](),[4.10258][4.10258:10334](),[4.10390][4.10390:10468](),[4.10468][3.2124:2277](),[3.2277][4.10553:10571](),[4.10553][4.10553:10571]()
    CreatePaymentRequest bid -> do
    _ <- H.query _createPaymentRequest unit $ H.tell (PaymentRequest.SetBillableId bid)
    lift $ system.toggleModal PaymentRequest.modalId ModalFFI.ShowModal
    PaymentRequestCreated (PaymentRequest req) -> do
    lift $ system.toggleModal PaymentRequest.modalId ModalFFI.HideModal
    lift $ system.toggleModal PaymentRequest.qrModalId ModalFFI.ShowModal
    let req' = Zip321Request req.native_request.zip321_request
    _ <- H.query _showPaymentRequest unit $ H.tell (PaymentRequest.QrRender req')
    pure unit
    [4.9892]
    [4.10571]
    OpenPaymentRequestModal pid bid -> do
    void $ H.query _createPaymentRequest unit $ H.tell (PaymentRequest.OpenModal pid bid)
  • file addition: Components (d--r------)
    [4.1]
  • file addition: Zip321QR.purs (----------)
    [0.16219]
    module Aftok.Components.Zip321QR where
    import Prelude
    import Control.Monad.Trans.Class (lift)
    import Data.Maybe (Maybe(..))
    import Data.Newtype (unwrap)
    import Data.Unfoldable as U
    import Halogen as H
    import Halogen.HTML.Core (ClassName(..))
    import Halogen.HTML as HH
    import Halogen.HTML.Properties as P
    import Aftok.Types (System)
    import Aftok.Api.Types (Zip321Request)
    type Input = Zip321Request
    type CState =
    { req :: Zip321Request
    , dataUrl :: Maybe String
    }
    data Action
    = QrInit
    type Slot id
    = forall query. H.Slot query Unit id
    component ::
    forall m output query.
    Monad m =>
    System m ->
    H.Component HH.HTML query Input output m
    component system =
    H.mkComponent
    { initialState
    , render
    , eval:
    H.mkEval
    $ H.defaultEval
    { handleAction = handleAction
    , initialize = Just QrInit
    }
    }
    where
    initialState :: Input -> CState
    initialState input =
    { req: input, dataUrl: Nothing }
    render :: forall slots. CState -> H.ComponentHTML Action slots m
    render st =
    HH.div_
    [ HH.div_
    ((\url -> HH.img [P.src url]) <$> U.fromMaybe st.dataUrl)
    , HH.div_
    [ HH.span
    [ P.classes (ClassName <$> ["code", "zip321uri"]) ]
    [HH.text <<< unwrap $ st.req]
    ]
    ]
    handleAction :: forall slots. Action -> H.HalogenM CState Action slots output m Unit
    handleAction = case _ of
    QrInit -> do
    req <- H.gets (_.req)
    uri <- lift $ system.renderQR { value: unwrap req, size: 300 }
    H.modify_ (_ { dataUrl = Just uri })
  • replacement in client/src/Aftok/HTML/Forms.purs at line 15
    [3.2686][3.2686:2784]()
    { recoveryType :: CommsType
    , recoveryEmail :: Maybe String
    , recoveryZAddr :: Maybe String
    [3.2686]
    [3.2784]
    { channel :: CommsType
    , email :: Maybe String
    , zaddr :: Maybe String
  • replacement in client/src/Aftok/HTML/Forms.purs at line 66
    [3.4446][3.4446:4509]()
    commsField setEmail setZAddr st errs = case st.recoveryType of
    [3.4446]
    [3.4509]
    commsField setEmail setZAddr st errs = case st.channel of
  • replacement in client/src/Aftok/HTML/Forms.purs at line 68
    [3.4525][3.4525:4948]()
    HH.div
    [ P.id_ "recoveryEmail" ]
    $ [ HH.label [ P.for "email" ] [ HH.text "Email Address" ]
    , HH.input
    [ P.type_ P.InputEmail
    , P.classes (ClassName <$> [ "form-control" ])
    , P.id_ "email"
    , P.placeholder "name@address.com"
    , P.value (fromMaybe "" st.recoveryEmail)
    , E.onValueInput (Just <<< setEmail)
    ]
    ]
    [3.4525]
    [3.4948]
    HH.div_ $
    [ HH.label [ P.for "email" ] [ HH.text "Email Address" ]
    , HH.input
    [ P.type_ P.InputEmail
    , P.classes (ClassName <$> [ "form-control" ])
    , P.id_ "email"
    , P.placeholder "name@address.com"
    , P.value (fromMaybe "" st.email)
    , E.onValueInput (Just <<< setEmail)
    ]
    ]
  • replacement in client/src/Aftok/HTML/Forms.purs at line 81
    [3.4990][3.4990:5718]()
    HH.div
    [ P.id_ "recoveryZAddr" ]
    $ [ HH.label
    [ P.for "zaddr" ]
    [ HH.text "Zcash Shielded Address"
    , HH.a
    [ P.attr (AttrName "data-toggle") "modal"
    , P.href "#modalAboutZAddr"
    ]
    [ HH.img [ P.src "/assets/img/icons/duotone-icons/Code/Info-circle.svg" ]
    ]
    ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes (ClassName <$> [ "form-control" ])
    , P.id_ "email"
    , P.placeholder "Enter a Zcash shielded address"
    , P.value (fromMaybe "" st.recoveryZAddr)
    , E.onValueInput (Just <<< setZAddr)
    ]
    ]
    [3.4990]
    [3.5718]
    HH.div_ $
    [ HH.label
    [ P.for "zaddr" ]
    [ HH.text "Zcash Shielded Address"
    , HH.a
    [ P.attr (AttrName "data-toggle") "modal"
    , P.href "#modalAboutZAddr"
    ]
    [ HH.img [ P.src "/assets/img/icons/duotone-icons/Code/Info-circle.svg" ]
    ]
    ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes (ClassName <$> [ "form-control" ])
    , P.id_ "email"
    , P.placeholder "Enter a Zcash shielded address"
    , P.value (fromMaybe "" st.zaddr)
    , E.onValueInput (Just <<< setZAddr)
    ]
    ]
  • edit in client/src/Aftok/HTML/Forms.purs at line 102
    [3.5743][3.5743:5744]()
  • edit in client/src/Aftok/Overview.purs at line 22
    [4.254]
    [4.1225]
    import DOM.HTML.Indexed.ButtonType (ButtonType(..))
  • edit in client/src/Aftok/Overview.purs at line 26
    [4.1414]
    [4.1483]
    import Halogen.HTML.Events as E
  • replacement in client/src/Aftok/Overview.purs at line 28
    [4.1519][3.5782:5907]()
    import Aftok.Billing.PaymentRequest as PaymentRequest
    import Aftok.Modals as Modals
    import Aftok.Modals.ModalFFI as ModalFFI
    [4.1519]
    [4.6406]
    import Aftok.HTML.Classes as C
  • replacement in client/src/Aftok/Overview.purs at line 32
    [4.315][3.5948:5997]()
    import Aftok.Api.Types (APIError, Zip321Request)
    [4.315]
    [4.3542]
    import Aftok.Api.Types (APIError)
  • replacement in client/src/Aftok/Overview.purs at line 58
    [4.2373][4.2373:2395](),[4.2395][3.5998:6042]()
    | Invite Invitation
    | InvitationCreated (Maybe Zip321Request)
    [4.2373]
    [4.2395]
    | Invite ProjectId
  • edit in client/src/Aftok/Overview.purs at line 66
    [3.6085][3.6085:6135]()
    , inviteQRModal :: PaymentRequest.QrSlot Unit
  • edit in client/src/Aftok/Overview.purs at line 70
    [3.6190][3.6190:6240]()
    _inviteQRModal = SProxy :: SProxy "inviteQRModal"
  • replacement in client/src/Aftok/Overview.purs at line 170
    [3.6495][3.6495:6582]()
    [ Modals.modalButton Invite.modalId "Invite a collaborator" Nothing]
    [3.6495]
    [3.6582]
    [ HH.button
    [ P.classes [ C.btn, C.btnPrimary ]
    , P.type_ ButtonButton
    , E.onClick (\_ -> Just (Invite project.projectId))
    ]
    [ HH.text "Invite a collaborator" ]
    ]
  • replacement in client/src/Aftok/Overview.purs at line 181
    [3.6742][3.6742:6780]()
    project.projectId
    [3.6742]
    [3.6780]
    unit
  • replacement in client/src/Aftok/Overview.purs at line 183
    [3.6808][3.6808:7110]()
    (Just <<< InvitationCreated)
    , system.portal
    _inviteQRModal
    unit
    (PaymentRequest.qrcomponent system)
    Nothing
    Nothing
    (const Nothing)
    ]
    [3.6808]
    [3.7110]
    (const Nothing)
    ]
  • replacement in client/src/Aftok/Overview.purs at line 224
    [4.627][4.11504:11543](),[4.11504][4.11504:11543]()
    Invite _ -> do
    pure unit
    [4.627]
    [4.11543]
    Invite pid -> do
    void <<< H.query _invitationModal unit $ H.tell (Invite.OpenModal pid)
  • edit in client/src/Aftok/Overview.purs at line 233
    [4.680][3.7125:7418]()
    InvitationCreated req -> do
    lift $ system.toggleModal Invite.modalId ModalFFI.HideModal
    lift $ system.toggleModal PaymentRequest.qrModalId ModalFFI.ShowModal
    traverse_ (\r -> H.query _inviteQRModal unit $ H.tell (PaymentRequest.QrRender r)) req
    pure unit
  • edit in client/src/Aftok/Projects/Invite.purs at line 10
    [3.7741]
    [3.7741]
    import Data.Symbol (SProxy(..))
    import Data.Tuple (Tuple(..))
  • edit in client/src/Aftok/Projects/Invite.purs at line 14
    [3.7816]
    [3.7816]
    import DOM.HTML.Indexed.ButtonType (ButtonType(..))
  • edit in client/src/Aftok/Projects/Invite.purs at line 20
    [3.7971]
    [3.7971]
    import Halogen.HTML.Properties.ARIA as ARIA
  • edit in client/src/Aftok/Projects/Invite.purs at line 25
    [3.8160]
    [3.8160]
    import Aftok.Components.Zip321QR as Zip321QR
  • edit in client/src/Aftok/Projects/Invite.purs at line 28
    [3.8241][3.8241:8271]()
    import Aftok.Modals as Modals
  • replacement in client/src/Aftok/Projects/Invite.purs at line 32
    [3.8363][3.8363:8377]()
    = NameField
    [3.8363]
    [3.8377]
    = PidField
    | NameField
  • edit in client/src/Aftok/Projects/Invite.purs at line 40
    [3.8483]
    [3.8483]
    data Query a
    = OpenModal ProjectId a
    data Mode
    = Form
    | QrScan Zip321Request
  • replacement in client/src/Aftok/Projects/Invite.purs at line 48
    [3.8497][3.8497:8524]()
    { projectId :: ProjectId
    [3.8497]
    [3.8524]
    { projectId :: Maybe ProjectId
  • replacement in client/src/Aftok/Projects/Invite.purs at line 51
    [3.8582][3.8582:8680]()
    , recoveryType :: CommsType
    , recoveryEmail :: Maybe String
    , recoveryZAddr :: Maybe String
    [3.8582]
    [3.8680]
    , channel :: CommsType
    , email :: Maybe String
    , zaddr :: Maybe String
  • edit in client/src/Aftok/Projects/Invite.purs at line 55
    [3.8711]
    [3.8711]
    , mode :: Mode
  • edit in client/src/Aftok/Projects/Invite.purs at line 57
    [3.8715][3.8715:8774]()
    type Input = ProjectId
    type Output = Maybe Zip321Request
  • replacement in client/src/Aftok/Projects/Invite.purs at line 59
    [3.8787][3.8787:8840]()
    = ProjectChanged ProjectId
    | SetGreetName String
    [3.8787]
    [3.8840]
    = SetGreetName String
  • edit in client/src/Aftok/Projects/Invite.purs at line 65
    [3.8950]
    [3.8950]
    | Close
  • replacement in client/src/Aftok/Projects/Invite.purs at line 68
    [3.8964][3.8964:9005]()
    = forall query. H.Slot query Output id
    [3.8964]
    [3.9005]
    = forall output. H.Slot Query output id
    type Slots
    = ( inviteQR :: Zip321QR.Slot Unit
    )
  • edit in client/src/Aftok/Projects/Invite.purs at line 74
    [3.9006]
    [3.9006]
    _inviteQR = SProxy :: SProxy "inviteQR"
  • replacement in client/src/Aftok/Projects/Invite.purs at line 85
    [3.9274][3.9274:9292]()
    forall query m.
    [3.9274]
    [3.9292]
    forall input output m.
  • replacement in client/src/Aftok/Projects/Invite.purs at line 89
    [3.9337][3.9337:9380]()
    H.Component HH.HTML query Input Output m
    [3.9337]
    [3.9380]
    H.Component HH.HTML Query input output m
  • replacement in client/src/Aftok/Projects/Invite.purs at line 92
    [3.9420][3.9420:9439]()
    { initialState
    [3.9420]
    [3.9439]
    { initialState: const initialState
  • replacement in client/src/Aftok/Projects/Invite.purs at line 97
    [3.9507][3.9507:9593]()
    { handleAction = eval
    , receive = Just <<< ProjectChanged
    [3.9507]
    [3.9593]
    { handleAction = handleAction
    , handleQuery = handleQuery
  • replacement in client/src/Aftok/Projects/Invite.purs at line 102
    [3.9623][3.9623:9703]()
    initialState :: Input -> CState
    initialState input =
    { projectId: input
    [3.9623]
    [3.9703]
    initialState :: CState
    initialState =
    { projectId: Nothing
  • replacement in client/src/Aftok/Projects/Invite.purs at line 107
    [3.9753][3.9753:9865]()
    , recoveryType: EmailComms
    , recoveryEmail: Nothing
    , recoveryZAddr: Nothing
    , fieldErrors : []
    [3.9753]
    [3.9865]
    , channel: ZcashComms
    , email: Nothing
    , zaddr: Nothing
    , fieldErrors: []
    , mode: Form
  • replacement in client/src/Aftok/Projects/Invite.purs at line 114
    [3.9872][3.9872:9939]()
    render :: forall slots. CState -> H.ComponentHTML Action slots m
    [3.9872]
    [3.9939]
    render :: CState -> H.ComponentHTML Action Slots m
  • replacement in client/src/Aftok/Projects/Invite.purs at line 116
    [3.9953][3.9953:10427]()
    Modals.modalWithSave modalId "Invite a collaborator" CreateInvitation
    [ HH.form_
    [ formGroup st
    [ NameField ]
    [ HH.label
    [ P.for "greetName"]
    [ HH.text "Name" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [ C.formControl, C.formControlSm ]
    , P.id_ "greetName"
    , P.placeholder "Who are you inviting?"
    , E.onValueInput (Just <<< SetGreetName)
    [3.9953]
    [3.10427]
    HH.div
    [ P.classes [ C.modal ]
    , P.id_ modalId
    , P.tabIndex (negate 1)
    , ARIA.role "dialog"
    , ARIA.labelledBy (modalId <> "Title")
    , ARIA.hidden "true"
    ]
    [ HH.div
    [ P.classes [C.modalDialog], ARIA.role "document" ]
    [ HH.div
    [ P.classes [C.modalContent] ]
    [ HH.div
    [ P.classes [C.modalHeader] ]
    [ HH.h5 [P.classes [C.modalTitle], P.id_ (modalId <>"Title") ] [HH.text "Invite a collaborator"]
    , HH.button
    [ P.classes [ C.close ]
    , ARIA.label "Close"
    , P.type_ ButtonButton
    , E.onClick (\_ -> Just Close)
    ]
    [ HH.span [ARIA.hidden "true"] [HH.text "×"]]
  • edit in client/src/Aftok/Projects/Invite.purs at line 139
    [3.10441]
    [3.10441]
    , HH.div
    [ P.classes [C.modalBody] ]
    case st.mode of
    Form ->
    [ inviteForm st ]
    QrScan req ->
    [ HH.slot _inviteQR unit (Zip321QR.component system) req (const Nothing) ]
    , HH.div
    [ P.classes [C.modalFooter] ] $
    case st.mode of
    Form ->
    [ HH.button
    [ P.type_ ButtonButton
    , P.classes [ C.btn, C.btnSecondary]
    , E.onClick (\_ -> Just Close)
    ]
    [ HH.text "Close" ]
    , HH.button
    [ P.type_ ButtonButton
    , P.classes [ C.btn, C.btnPrimary ]
    , E.onClick (\_ -> Just CreateInvitation)
    ]
    [ HH.text "Send invitation" ]
    ]
    QrScan _ ->
    [ HH.button
    [ P.type_ ButtonButton
    , P.classes [ C.btn, C.btnPrimary]
    , E.onClick (\_ -> Just Close)
    ]
    [ HH.text "Close" ]
    ]
  • replacement in client/src/Aftok/Projects/Invite.purs at line 174
    [3.10453][3.10453:10853]()
    , formGroup st
    [ ]
    [ HH.label
    [ P.for "message"]
    [ HH.text "Message" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [C.formControl, C.formControlSm]
    , P.id_ "message"
    , P.placeholder "Enter your message here"
    , E.onValueInput (Just <<< SetMessage)
    ]
    [3.10453]
    [3.10853]
    ]
    ]
    inviteForm st =
    HH.form_
    [ formGroup st
    [ NameField ]
    [ HH.label
    [ P.for "greetName"]
    [ HH.text "Name" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [ C.formControl, C.formControlSm ]
    , P.id_ "greetName"
    , P.placeholder "Who are you inviting?"
    , E.onValueInput (Just <<< SetGreetName)
  • replacement in client/src/Aftok/Projects/Invite.purs at line 191
    [3.10865][3.10865:11076]()
    , commsSwitch SetCommsType st.recoveryType
    , commsField SetEmail SetZAddr st $ case _ of
    EmailComms -> fieldError st EmailField
    ZcashComms -> fieldError st ZAddrField
    [3.10865]
    [3.11076]
    ]
    , formGroup st
    [ ]
    [ HH.label
    [ P.for "message"]
    [ HH.text "Message" ]
    , HH.input
    [ P.type_ P.InputText
    , P.classes [C.formControl, C.formControlSm]
    , P.id_ "message"
    , P.placeholder "Enter your message here"
    , E.onValueInput (Just <<< SetMessage)
    ]
  • edit in client/src/Aftok/Projects/Invite.purs at line 205
    [3.11086]
    [3.11086]
    , commsSwitch SetCommsType st.channel
    , commsField SetEmail SetZAddr st $ case _ of
    EmailComms -> fieldError st EmailField
    ZcashComms -> fieldError st ZAddrField
  • edit in client/src/Aftok/Projects/Invite.purs at line 221
    [3.11454]
    [3.11454]
    PidField -> err "No project id found; please report an error"
  • replacement in client/src/Aftok/Projects/Invite.purs at line 223
    [3.11512][3.11512:11661]()
    EmailField -> err "The email field is when email comms are selected"
    ZAddrField -> err "Not a valid Zcash shielded address."
    [3.11512]
    [3.11661]
    EmailField -> err "An email value is required when email comms are selected"
    ZAddrField -> err "Not a valid Zcash shielded address"
  • replacement in client/src/Aftok/Projects/Invite.purs at line 229
    [3.11804][3.11804:12186]()
    setZAddr addr = do
    zres <- lift $ caps.checkZAddr addr
    H.modify_ (_ { recoveryZAddr = Just addr })
    case zres of
    Acc.ZAddrCheckValid ->
    H.modify_ (\st -> st { fieldErrors = filter (_ /= ZAddrField) st.fieldErrors, recoveryType = ZcashComms })
    Acc.ZAddrCheckInvalid ->
    H.modify_ (\st -> st { fieldErrors = st.fieldErrors <> [ZAddrField] })
    [3.11804]
    [3.12186]
    -- we use a query to initialize, since this is a modal that doesn't actually get unloaded.
    handleQuery :: forall slots a. Query a -> H.HalogenM CState Action slots output m (Maybe a)
    handleQuery = case _ of
    OpenModal pid a -> do
    H.modify_ (\_ -> initialState { projectId = Just pid })
    lift $ system.toggleModal modalId ModalFFI.ShowModal
    pure (Just a)
  • replacement in client/src/Aftok/Projects/Invite.purs at line 237
    [3.12187][3.12187:13818]()
    -- eval :: forall slots. Action -> H.HalogenM CState Action slots Output m Unit
    eval = case _ of
    ProjectChanged pid ->
    H.modify_ (_ { projectId = pid })
    SetGreetName name ->
    H.modify_ (_ { greetName = Just name })
    SetMessage msg ->
    H.modify_ (_ { message = Just msg })
    SetCommsType t ->
    H.modify_ (_ { recoveryType = t })
    SetEmail email ->
    H.modify_ (_ { recoveryEmail = Just email })
    SetZAddr addr ->
    when (addr /= "") (setZAddr addr)
    CreateInvitation -> do
    nameV <- V <<< note [NameField] <$> H.gets (_.greetName)
    message <- H.gets (_.message)
    addrType <- H.gets (_.recoveryType)
    addrV <-
    case addrType of
    EmailComms -> map EmailCommsAddr <<< V <<< note [EmailField] <$> H.gets (_.recoveryEmail)
    ZcashComms -> map ZcashCommsAddr <<< V <<< note [ZAddrField] <$> H.gets (_.recoveryZAddr)
    let reqV :: V (Array Field) (Invitation' CommsAddress)
    reqV = { greetName: _, message: _, inviteBy: _ }
    <$> nameV
    <*> pure message
    <*> addrV
    case toEither reqV of
    Left errors -> do
    H.modify_ (_ { fieldErrors = errors })
    Right invitation -> do
    pid <- H.gets (_.projectId)
    res <- lift $ caps.createInvitation pid invitation
    case res of
    Right result -> do
    H.raise result
    lift $ system.toggleModal modalId ModalFFI.HideModal
    Left errs ->
    lift $ system.error (show errs)
    [3.12187]
    [3.13818]
    handleAction :: forall slots. Action -> H.HalogenM CState Action slots output m Unit
    handleAction = case _ of
    SetGreetName name ->
    H.modify_ (_ { greetName = Just name })
    SetMessage msg ->
    H.modify_ (_ { message = Just msg })
    SetCommsType t ->
    H.modify_ (_ { channel = t })
    SetEmail email ->
    H.modify_ (_ { email = Just email })
    SetZAddr addr -> do
    let setZAddr addr' = do
    zres <- lift $ caps.checkZAddr addr'
    H.modify_ (_ { zaddr = Just addr' })
    case zres of
    Acc.ZAddrCheckValid ->
    H.modify_ (\st -> st { fieldErrors = filter (_ /= ZAddrField) st.fieldErrors
    , channel = ZcashComms
    })
    Acc.ZAddrCheckInvalid ->
    H.modify_ (\st -> st { fieldErrors = st.fieldErrors <> [ZAddrField] })
    when (addr /= "") (setZAddr addr)
    CreateInvitation -> do
    pidV <- V <<< note [PidField] <$> H.gets (_.projectId)
    nameV <- V <<< note [NameField] <$> H.gets (_.greetName)
    message <- H.gets (_.message)
    channel <- H.gets (_.channel)
    addrV <-
    case channel of
    EmailComms -> map EmailCommsAddr <<< V <<< note [EmailField] <$> H.gets (_.email)
    ZcashComms -> map ZcashCommsAddr <<< V <<< note [ZAddrField] <$> H.gets (_.zaddr)
    let reqV :: V (Array Field) (Invitation' CommsAddress)
    reqV = { greetName: _, message: _, inviteBy: _ }
    <$> nameV
    <*> pure message
    <*> addrV
    case toEither (Tuple <$> pidV <*> reqV) of
    Right (Tuple pid invitation) -> do
    res <- lift $ caps.createInvitation pid invitation
    case res of
    Right (Just req) -> H.modify_ (_ { mode = QrScan req })
    Right Nothing -> handleAction Close
    Left errs -> lift $ system.error (show errs)
    Left errors -> do
    H.modify_ (_ { fieldErrors = errors })
    Close -> do
    H.modify_ (const initialState) -- wipe the state for safety
    lift $ system.toggleModal modalId ModalFFI.HideModal
  • replacement in client/src/Aftok/Signup.purs at line 65
    [4.14604][3.14114:14146](),[3.14146][4.14639:14711](),[4.14639][4.14639:14711]()
    , recoveryType :: CommsType
    , recoveryEmail :: Maybe String
    , recoveryZAddr :: Maybe String
    [4.14604]
    [4.1741]
    , channel :: CommsType
    , email :: Maybe String
    , zaddr :: Maybe String
  • replacement in client/src/Aftok/Signup.purs at line 121
    [4.15598][3.14178:14209](),[3.14209][4.15632:15690](),[4.15632][4.15632:15690]()
    , recoveryType: EmailComms
    , recoveryEmail: Nothing
    , recoveryZAddr: Nothing
    [4.15598]
    [4.1811]
    , channel: EmailComms
    , email: Nothing
    , zaddr: Nothing
  • replacement in client/src/Aftok/Signup.purs at line 191
    [3.14389][3.14389:14457]()
    , commsSwitch SetRecoveryType st.recoveryType
    [3.14389]
    [3.14457]
    , commsSwitch SetRecoveryType st.channel
  • replacement in client/src/Aftok/Signup.purs at line 229
    [4.2614][4.2614:2662]()
    H.modify_ (_ { recoveryZAddr = Just addr })
    [4.2614]
    [4.2662]
    H.modify_ (_ { zaddr = Just addr })
  • replacement in client/src/Aftok/Signup.purs at line 232
    [4.2709][3.14766:14878]()
    H.modify_ (\st -> st { signupErrors = M.delete ZAddrField st.signupErrors, recoveryType = ZcashComms })
    [4.2709]
    [4.2824]
    H.modify_ (\st -> st { signupErrors = M.delete ZAddrField st.signupErrors, channel = ZcashComms })
  • replacement in client/src/Aftok/Signup.purs at line 273
    [3.14905][3.14905:14946]()
    H.modify_ (_ { recoveryType = t })
    [3.14905]
    [3.14946]
    H.modify_ (_ { channel = t })
  • replacement in client/src/Aftok/Signup.purs at line 275
    [3.14977][3.14977:15028]()
    H.modify_ (_ { recoveryEmail = Just email })
    [3.14977]
    [4.15581]
    H.modify_ (_ { email = Just email })
  • replacement in client/src/Aftok/Signup.purs at line 284
    [4.21411][4.21411:21452]()
    recType <- H.gets (_.recoveryType)
    [4.21411]
    [4.21452]
    recType <- H.gets (_.channel)
  • replacement in client/src/Aftok/Signup.purs at line 288
    [4.21681][4.21681:21767](),[4.21767][3.15029:15243]()
    recoveryType <- H.gets (_.recoveryType)
    recoveryV <- case recoveryType of
    EmailComms -> V <<< note [ EmailRequired ] <<< map Acc.RecoverByEmail <$> H.gets (_.recoveryEmail)
    ZcashComms -> V <<< note [ ZAddrRequired ] <<< map Acc.RecoverByZAddr <$> H.gets (_.recoveryZAddr)
    [4.21681]
    [4.21987]
    channel <- H.gets (_.channel)
    recoveryV <- case channel of
    EmailComms -> V <<< note [ EmailRequired ] <<< map Acc.RecoverByEmail <$> H.gets (_.email)
    ZcashComms -> V <<< note [ ZAddrRequired ] <<< map Acc.RecoverByZAddr <$> H.gets (_.zaddr)