Fix the broken modals.
[?]
Feb 13, 2021, 3:14 AM
XGMFJUERL5G2AX5H3UY27YAAUNO27BH36WM2PGMGXDZAVURWNVBACDependencies
- [2]
RUAQYIXIAdd Landkit styles to billing creation - [3]
46PUXHTYImplement project invitations. - [4]
JXG3FCXYUpgrade ps + halogen versions. - [5]
DAPLYXHYSuccessfully rendering QR codes sometimes. - [6]
I4W76IFVRender recaptcha explicitly. - [7]
N6FG4EW6Working bootstrap modal! Only a little FFI. - [8]
VTZT2ILUWire up billing navigation. - [9]
YBLHJFCNImplement billing modal. - [10]
V54JCKJXPayment request creation. - [11]
5R2Z7FSXInitial rendering for signup controls. - [12]
EA5BFM5GSplit Login component into its own module. - [13]
T2DN23M7Factor out billing create component. - [14]
3PFXXJTLWIP - [15]
QU5FW67RAdd project selection to time tracker. - [16]
U7YAT2ZKAdd error reporting to signup form. - [17]
WRPIYG3EUse project listing functionality to check for whether we have a cookie. - [18]
GLQSD33YUse mock capability for overview init. - [19]
4GOBY5NQWIP on modals. - [20]
Z5KNL332Add skeleton of project overview HTML. - [21]
KET5QGQPAdd billable list (in-progress) - [22]
KKJSBWO6Add createPaymentRequestHandler - [23]
NAFJ6RB3Minor module reorg. - [24]
I5MPORH4Autofill signup form from query string parameters. - [25]
RV7ZIULZUpdate overview to have access to the real project detail capability. - [26]
RSF6UAJKBreak out api module for timeline. - [27]
7TQPQW3NBegin adding parsing for project detail. - [28]
ANDJ6GEYAdd billing component skeleton. - [29]
QAC2QJ32Add project overview page to client. - [30]
BPIQKEXEgussify - [31]
AKM2VYBLFix errors with project ID persistence. - [32]
VNZ4VRO6Fix the invitation codes bug. - [33]
QH4UB73NFormat with purty.
Change contents
- file deletion: Modals.purs
module Aftok.Modals whereimport Prelude ((<>), negate)import DOM.HTML.Indexed.ButtonType (ButtonType(..))import Halogen.HTML as HHimport Halogen.HTML.Properties as Pimport Halogen.HTML.Properties.ARIA as ARIAimport Aftok.HTML.Classes as Cimport Aftok.HTML.Properties as APmodalButton :: forall action slots m. String -> String -> Maybe action -> H.ComponentHTML action slots mmodalButton 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 mmodalWithSave 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 mmodalWithClose 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 Eimport Halogen as Himport Data.Maybe (Maybe(..)) - edit in client/src/Aftok/Billing/Create.purs at line 8
import Aftok.Modals as Modals - edit in client/src/Aftok/Billing/Create.purs at line 24
import DOM.HTML.Indexed.ButtonType (ButtonType(..)) - edit in client/src/Aftok/Billing/Create.purs at line 30
import Halogen.HTML.Properties.ARIA as ARIA - replacement in client/src/Aftok/Billing/Create.purs at line 33
= NameField= PidField| NameField - replacement in client/src/Aftok/Billing/Create.purs at line 55
{ projectId :: ProjectId{ projectId :: Maybe ProjectId - replacement in client/src/Aftok/Billing/Create.purs at line 67
type Input = ProjectIddata Query a= OpenModal ProjectId a - replacement in client/src/Aftok/Billing/Create.purs at line 70
type Output = Tuple BillableId Billabledata Output= BillableCreated BillableId - replacement in client/src/Aftok/Billing/Create.purs at line 74
= ProjectChanged ProjectId| SetName String= SetName String - replacement in client/src/Aftok/Billing/Create.purs at line 83
| SaveBillable| Save| Close - replacement in client/src/Aftok/Billing/Create.purs at line 87
= forall query. H.Slot query Output id= H.Slot Query Output id - edit in client/src/Aftok/Billing/Create.purs at line 92
modalId :: StringmodalId = "createBillable" - replacement in client/src/Aftok/Billing/Create.purs at line 97
forall query m.forall input m. - replacement in client/src/Aftok/Billing/Create.purs at line 101
H.Component HH.HTML query Input Output mH.Component HH.HTML Query input Output m - replacement in client/src/Aftok/Billing/Create.purs at line 104
{ initialState{ initialState: const initialState - replacement in client/src/Aftok/Billing/Create.purs at line 106
, eval:H.mkEval$ H.defaultEval{ handleAction = eval, receive = Just <<< ProjectChanged}, eval: H.mkEval$ H.defaultEval{ handleAction = handleAction, handleQuery = handleQuery} - replacement in client/src/Aftok/Billing/Create.purs at line 113
initialState :: Input -> CStateinitialState input ={ projectId: inputinitialState :: CStateinitialState ={ 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)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 == RTMonthlythen maybe "" show st.recurrenceValueelse ""), P.min 1.0, P.max 12.0, E.onValueInput (Just <<< SetRecurrenceMonths), 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 == RTWeeklythen maybe "" show st.recurrenceValueelse ""), P.min 1.0, P.max 12.0, E.onValueInput (Just <<< SetRecurrenceWeeks)], 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), 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 == RTMonthlythen maybe "" show st.recurrenceValueelse ""), 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 == RTWeeklythen maybe "" show st.recurrenceValueelse ""), 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
, 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, 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
[ HH.text "ZEC" ] ]], 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), 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)[ 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
[ HH.text "Create billable"]] - replacement in client/src/Aftok/Billing/Create.purs at line 324
formGroup :: forall i a. CState -> Array Field -> Array (HH.HTML i a) -> HH.HTML i aformGroup 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 aformGroup st fields body =HH.div[ P.classes [C.formGroup] ](body <> (fieldError st =<< fields)) - edit in client/src/Aftok/Billing/Create.purs at line 359
PidField -> err "No project id found; please report an error" - replacement in client/src/Aftok/Billing/Create.purs at line 370
err str = [ HH.div_ [ HH.span [ P.classes (ClassName <$> [ "badge", "badge-danger-soft" ]) ] [ HH.text str ] ] ]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 _ ofOpenModal pid a -> doH.modify_ (\_ -> initialState { projectId = Just pid })lift $ system.toggleModal modalId ModalFFI.ShowModalpure (Just a) - replacement in client/src/Aftok/Billing/Create.purs at line 384
eval :: forall slots. Action -> H.HalogenM CState Action slots Output m Uniteval = case _ ofProjectChanged pid ->H.modify_ (_ { projectId = pid })handleAction :: forall slots. Action -> H.HalogenM CState Action slots Output m UnithandleAction = case _ of - replacement in client/src/Aftok/Billing/Create.purs at line 420
SaveBillable -> doSave -> dopidV <- V <<< note [PidField] <$> H.gets (_.projectId) - replacement in client/src/Aftok/Billing/Create.purs at line 425
msgV <- V <<< note [MessageField] <$> H.gets (_.message)msgV <- V <<< note [MessageField] <$> H.gets (_.message) - replacement in client/src/Aftok/Billing/Create.purs at line 454
case toEither reqV ofLeft errors -> doH.modify_ (_ { fieldErrors = errors })Right billable -> dopid <- H.gets (_.projectId)case toEither (Tuple <$> pidV <*> reqV) ofRight (Tuple pid billable) -> do - replacement in client/src/Aftok/Billing/Create.purs at line 459
H.raise (Tuple bid billable)lift $ system.toggleModal "createBillable" ModalFFI.HideModalLeft errs ->H.raise (BillableCreated bid)handleAction CloseLeft errs -> do - edit in client/src/Aftok/Billing/Create.purs at line 463
Left errors -> doH.modify_ (_ { fieldErrors = errors })Close -> doH.modify_ (const initialState) -- wipe the state for safetylift $ system.toggleModal modalId ModalFFI.HideModal - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 5
-- import Control.Monad.State.Class (get) - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 8
import Data.Newtype (unwrap)import Data.Symbol (SProxy(..)) - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 10
import Data.Traversable (traverse_)import Data.Unfoldable as U - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 12
import DOM.HTML.Indexed.ButtonType (ButtonType(..)) - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 18
import Aftok.Types (System, ProjectId)import Aftok.HTML.Classes as Cimport Aftok.Modals as Modalsimport Aftok.Modals.ModalFFI as ModalFFIimport Halogen.HTML.Properties.ARIA as ARIA - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 23
, PaymentRequest'(..) - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 28
import Aftok.Components.Zip321QR as Zip321QRimport Aftok.HTML.Classes as Cimport Aftok.Modals.ModalFFI as ModalFFIimport Aftok.Types (System, ProjectId) - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 34
= NameRequired= PidFieldNotSet - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 36
| NameRequired - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 42
{ projectId :: ProjectId{ projectId :: Maybe ProjectId - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 47
, mode :: Mode - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 50
type Input = ProjectIddata Mode= Form| QrScan Zip321Request - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 55
= SetProjectId ProjectId a| SetBillableId BillableId a= OpenModal ProjectId BillableId a - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 57
type Output = PaymentRequest - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 58
= ProjectChanged ProjectId| SetName String= SetName String - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 61
| Close - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 64
= H.Slot Query Output id= forall output. H.Slot Query output idtype Slots= ( requestQR :: Zip321QR.Slot Unit)_requestQR = SProxy :: SProxy "requestQR" - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 84
forall m.forall input output m. - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 88
H.Component HH.HTML Query Input Output mH.Component HH.HTML Query input output m - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 91
{ initialState{ initialState: const initialState - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 98
, receive = Just <<< ProjectChanged - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 101
initialState :: Input -> CStateinitialState input ={ projectId: inputinitialState :: CStateinitialState ={ 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 : [], name: Nothing, description: Nothing, fieldErrors: [], mode: Form - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 111
render :: forall slots. CState -> H.ComponentHTML Action slots mrender :: 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)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
, HH.div[ P.classes [C.modalBody] ]case st.mode ofForm ->[ requestForm st ]QrScan req ->[ HH.slot _requestQR unit (Zip321QR.component system) req (const Nothing) ], HH.div[ P.classes [C.modalFooter] ] $case st.mode ofForm ->[ 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)]]]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
], 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
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
BillableIdNotSet -> err "The billable id is missing. Close this dialog and try again." - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 224
handleQuery :: forall slots a. Query a -> H.HalogenM CState Action slots Output m (Maybe a)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
SetProjectId pid a -> doH.modify_ (_ { projectId = pid, billableId = Nothing, name = Nothing, description = Nothing })pure (Just a)SetBillableId bid a -> doH.modify_ (_ { billableId = Just bid })OpenModal pid bid a -> doH.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
handleAction :: forall slots. Action -> H.HalogenM CState Action slots Output m UnithandleAction :: forall slots. Action -> H.HalogenM CState Action slots output m Unit - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 233
ProjectChanged pid ->H.modify_ (_ { projectId = pid, billableId = Nothing, name = Nothing, description = Nothing }) - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 238
pidV <- V <<< note [PidFieldNotSet] <$> H.gets (_.projectId) - replacement in client/src/Aftok/Billing/PaymentRequest.purs at line 243
breqV = Tuple <$> bidV <*> reqVcase toEither breqV ofLeft errors -> doH.modify_ (_ { fieldErrors = errors })Right (Tuple bid reqMeta) -> dopid <- H.gets (_.projectId)case toEither (Tuple <$> pidV <*> (Tuple <$> bidV <*> reqV)) ofRight (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 -> doH.raise contentH.modify_ (_ { billableId = Nothing, name = Nothing, description = Nothing, fieldErrors = [] })lift $ system.toggleModal "createPaymentRequest" ModalFFI.HideModalRight (PaymentRequest req) -> doH.modify_ (_ { mode = QrScan $ Zip321Request req.native_request.zip321_request }) - edit in client/src/Aftok/Billing/PaymentRequest.purs at line 251
Left errors -> doH.modify_ (_ { fieldErrors = errors })Close -> doH.modify_ (const initialState) -- wipe the state for safetylift $ 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 Zip321Requesttype 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 adata QrAction= QrInit| QrClosetype QrSlot id= H.Slot QrQuery Unit idqrModalId :: StringqrModalId = "paymentRequestQR"qrcomponent ::forall m output.Monad m =>System m ->H.Component HH.HTML QrQuery QrInput output mqrcomponent system =H.mkComponent{ initialState, render, eval:H.mkEval$ H.defaultEval{ handleAction = handleAction, handleQuery = handleQuery, initialize = Just QrInit}}whereinitialState :: QrInput -> QrStateinitialState input ={ req: input, dataUrl: Nothing }render :: forall slots. QrState -> H.ComponentHTML QrAction slots mrender 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 _ ofQrRender r a -> dodataUrl <- lift $ renderQR rH.modify_ (_ { req = Just r, dataUrl = Just dataUrl })pure (Just a)handleAction :: forall slots. QrAction -> H.HalogenM QrState QrAction slots output m UnithandleAction = case _ ofQrInit -> doreq <- H.gets (_.req)lift $ traverse_ renderQR reqQrClose ->H.modify_ (_ { req = Nothing, dataUrl = Nothing })renderQR :: Zip321Request -> m StringrenderQR (Zip321Request r) =system.renderQR { value: r, size: 300 } - replacement in client/src/Aftok/Billing.purs at line 28
import Aftok.Api.Types (APIError(..), Zip321Request(..))import Aftok.Api.Types (APIError(..)) - edit in client/src/Aftok/Billing.purs at line 35
, PaymentRequest'(..) - edit in client/src/Aftok/Billing.purs at line 40
import Aftok.Modals as Modalsimport Aftok.Modals.ModalFFI as ModalFFI - replacement in client/src/Aftok/Billing.purs at line 54
| BillableCreated (Tuple BillableId Billable)| CreatePaymentRequest BillableId| PaymentRequestCreated (PaymentRequest)| OpenBillableModal ProjectId| BillableCreated BillableId| OpenPaymentRequestModal ProjectId BillableId - edit in client/src/Aftok/Billing.purs at line 65
, showPaymentRequest :: PaymentRequest.QrSlot Unit - edit in client/src/Aftok/Billing.purs at line 70
_showPaymentRequest = SProxy :: SProxy "showPaymentRequest" - replacement in client/src/Aftok/Billing.purs at line 128
[ renderBillableList st.billables[ renderBillableList (unwrap p).projectId st.billables - replacement in client/src/Aftok/Billing.purs at line 131
[ Modals.modalButton "createBillable" "Create billable" Nothing][ 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
(unwrap p).projectIdunit - replacement in client/src/Aftok/Billing.purs at line 144
(Just <<< BillableCreated)(\(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).projectIdNothing(Just <<< PaymentRequestCreated), system.portal_showPaymentRequest - edit in client/src/Aftok/Billing.purs at line 150
(PaymentRequest.qrcomponent system) - edit in client/src/Aftok/Billing.purs at line 151
Nothing - replacement in client/src/Aftok/Billing.purs at line 158
renderBillableList :: Array (Tuple BillableId Billable) -> H.ComponentHTML BillingAction Slots mrenderBillableList billables =renderBillableList :: ProjectId -> Array (Tuple BillableId Billable) -> H.ComponentHTML BillingAction Slots mrenderBillableList pid billables = - replacement in client/src/Aftok/Billing.purs at line 188
, E.onClick (\_ -> Just $ CreatePaymentRequest bid), E.onClick (\_ -> Just $ OpenPaymentRequestModal pid bid) - replacement in client/src/Aftok/Billing.purs at line 190
[ HH.text "New Payment Request" ][ HH.text "New payment request" ] - edit in client/src/Aftok/Billing.purs at line 215
OpenBillableModal pid -> dovoid $ 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.ShowModalPaymentRequestCreated (PaymentRequest req) -> dolift $ system.toggleModal PaymentRequest.modalId ModalFFI.HideModallift $ system.toggleModal PaymentRequest.qrModalId ModalFFI.ShowModallet req' = Zip321Request req.native_request.zip321_request_ <- H.query _showPaymentRequest unit $ H.tell (PaymentRequest.QrRender req')pure unitOpenPaymentRequestModal pid bid -> dovoid $ H.query _createPaymentRequest unit $ H.tell (PaymentRequest.OpenModal pid bid) - file addition: Components[4.1]
- file addition: Zip321QR.purs[0.16219]
module Aftok.Components.Zip321QR whereimport Preludeimport Control.Monad.Trans.Class (lift)import Data.Maybe (Maybe(..))import Data.Newtype (unwrap)import Data.Unfoldable as Uimport Halogen as Himport Halogen.HTML.Core (ClassName(..))import Halogen.HTML as HHimport Halogen.HTML.Properties as Pimport Aftok.Types (System)import Aftok.Api.Types (Zip321Request)type Input = Zip321Requesttype CState ={ req :: Zip321Request, dataUrl :: Maybe String}data Action= QrInittype Slot id= forall query. H.Slot query Unit idcomponent ::forall m output query.Monad m =>System m ->H.Component HH.HTML query Input output mcomponent system =H.mkComponent{ initialState, render, eval:H.mkEval$ H.defaultEval{ handleAction = handleAction, initialize = Just QrInit}}whereinitialState :: Input -> CStateinitialState input ={ req: input, dataUrl: Nothing }render :: forall slots. CState -> H.ComponentHTML Action slots mrender 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 UnithandleAction = case _ ofQrInit -> doreq <- 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
{ recoveryType :: CommsType, recoveryEmail :: Maybe String, recoveryZAddr :: Maybe String{ channel :: CommsType, email :: Maybe String, zaddr :: Maybe String - replacement in client/src/Aftok/HTML/Forms.purs at line 66
commsField setEmail setZAddr st errs = case st.recoveryType ofcommsField setEmail setZAddr st errs = case st.channel of - replacement in client/src/Aftok/HTML/Forms.purs at line 68
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)]]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
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)]]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
- edit in client/src/Aftok/Overview.purs at line 22
import DOM.HTML.Indexed.ButtonType (ButtonType(..)) - edit in client/src/Aftok/Overview.purs at line 26
import Halogen.HTML.Events as E - replacement in client/src/Aftok/Overview.purs at line 28
import Aftok.Billing.PaymentRequest as PaymentRequestimport Aftok.Modals as Modalsimport Aftok.Modals.ModalFFI as ModalFFIimport Aftok.HTML.Classes as C - replacement in client/src/Aftok/Overview.purs at line 32
import Aftok.Api.Types (APIError, Zip321Request)import Aftok.Api.Types (APIError) - replacement in client/src/Aftok/Overview.purs at line 58
| Invite Invitation| InvitationCreated (Maybe Zip321Request)| Invite ProjectId - edit in client/src/Aftok/Overview.purs at line 66
, inviteQRModal :: PaymentRequest.QrSlot Unit - edit in client/src/Aftok/Overview.purs at line 70
_inviteQRModal = SProxy :: SProxy "inviteQRModal" - replacement in client/src/Aftok/Overview.purs at line 170
[ Modals.modalButton Invite.modalId "Invite a collaborator" Nothing][ 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
project.projectIdunit - replacement in client/src/Aftok/Overview.purs at line 183
(Just <<< InvitationCreated), system.portal_inviteQRModalunit(PaymentRequest.qrcomponent system)NothingNothing(const Nothing)](const Nothing)] - replacement in client/src/Aftok/Overview.purs at line 224
Invite _ -> dopure unitInvite pid -> dovoid <<< H.query _invitationModal unit $ H.tell (Invite.OpenModal pid) - edit in client/src/Aftok/Overview.purs at line 233
InvitationCreated req -> dolift $ system.toggleModal Invite.modalId ModalFFI.HideModallift $ system.toggleModal PaymentRequest.qrModalId ModalFFI.ShowModaltraverse_ (\r -> H.query _inviteQRModal unit $ H.tell (PaymentRequest.QrRender r)) reqpure unit - edit in client/src/Aftok/Projects/Invite.purs at line 10
import Data.Symbol (SProxy(..))import Data.Tuple (Tuple(..)) - edit in client/src/Aftok/Projects/Invite.purs at line 14
import DOM.HTML.Indexed.ButtonType (ButtonType(..)) - edit in client/src/Aftok/Projects/Invite.purs at line 20
import Halogen.HTML.Properties.ARIA as ARIA - edit in client/src/Aftok/Projects/Invite.purs at line 25
import Aftok.Components.Zip321QR as Zip321QR - edit in client/src/Aftok/Projects/Invite.purs at line 28
import Aftok.Modals as Modals - replacement in client/src/Aftok/Projects/Invite.purs at line 32
= NameField= PidField| NameField - edit in client/src/Aftok/Projects/Invite.purs at line 40
data Query a= OpenModal ProjectId adata Mode= Form| QrScan Zip321Request - replacement in client/src/Aftok/Projects/Invite.purs at line 48
{ projectId :: ProjectId{ projectId :: Maybe ProjectId - replacement in client/src/Aftok/Projects/Invite.purs at line 51
, recoveryType :: CommsType, recoveryEmail :: Maybe String, recoveryZAddr :: Maybe String, channel :: CommsType, email :: Maybe String, zaddr :: Maybe String - edit in client/src/Aftok/Projects/Invite.purs at line 55
, mode :: Mode - edit in client/src/Aftok/Projects/Invite.purs at line 57
type Input = ProjectIdtype Output = Maybe Zip321Request - replacement in client/src/Aftok/Projects/Invite.purs at line 59
= ProjectChanged ProjectId| SetGreetName String= SetGreetName String - edit in client/src/Aftok/Projects/Invite.purs at line 65
| Close - replacement in client/src/Aftok/Projects/Invite.purs at line 68
= forall query. H.Slot query Output id= forall output. H.Slot Query output idtype Slots= ( inviteQR :: Zip321QR.Slot Unit) - edit in client/src/Aftok/Projects/Invite.purs at line 74
_inviteQR = SProxy :: SProxy "inviteQR" - replacement in client/src/Aftok/Projects/Invite.purs at line 85
forall query m.forall input output m. - replacement in client/src/Aftok/Projects/Invite.purs at line 89
H.Component HH.HTML query Input Output mH.Component HH.HTML Query input output m - replacement in client/src/Aftok/Projects/Invite.purs at line 92
{ initialState{ initialState: const initialState - replacement in client/src/Aftok/Projects/Invite.purs at line 97
{ handleAction = eval, receive = Just <<< ProjectChanged{ handleAction = handleAction, handleQuery = handleQuery - replacement in client/src/Aftok/Projects/Invite.purs at line 102
initialState :: Input -> CStateinitialState input ={ projectId: inputinitialState :: CStateinitialState ={ projectId: Nothing - replacement in client/src/Aftok/Projects/Invite.purs at line 107
, recoveryType: EmailComms, recoveryEmail: Nothing, recoveryZAddr: Nothing, fieldErrors : [], channel: ZcashComms, email: Nothing, zaddr: Nothing, fieldErrors: [], mode: Form - replacement in client/src/Aftok/Projects/Invite.purs at line 114
render :: forall slots. CState -> H.ComponentHTML Action slots mrender :: CState -> H.ComponentHTML Action Slots m - replacement in client/src/Aftok/Projects/Invite.purs at line 116
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)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
, HH.div[ P.classes [C.modalBody] ]case st.mode ofForm ->[ inviteForm st ]QrScan req ->[ HH.slot _inviteQR unit (Zip321QR.component system) req (const Nothing) ], HH.div[ P.classes [C.modalFooter] ] $case st.mode ofForm ->[ 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
, 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)]]]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
, commsSwitch SetCommsType st.recoveryType, commsField SetEmail SetZAddr st $ case _ ofEmailComms -> fieldError st EmailFieldZcashComms -> fieldError st ZAddrField], 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
, commsSwitch SetCommsType st.channel, commsField SetEmail SetZAddr st $ case _ ofEmailComms -> fieldError st EmailFieldZcashComms -> fieldError st ZAddrField - edit in client/src/Aftok/Projects/Invite.purs at line 221
PidField -> err "No project id found; please report an error" - replacement in client/src/Aftok/Projects/Invite.purs at line 223
EmailField -> err "The email field is when email comms are selected"ZAddrField -> err "Not a valid Zcash shielded address."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
setZAddr addr = dozres <- lift $ caps.checkZAddr addrH.modify_ (_ { recoveryZAddr = Just addr })case zres ofAcc.ZAddrCheckValid ->H.modify_ (\st -> st { fieldErrors = filter (_ /= ZAddrField) st.fieldErrors, recoveryType = ZcashComms })Acc.ZAddrCheckInvalid ->H.modify_ (\st -> st { fieldErrors = st.fieldErrors <> [ZAddrField] })-- 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 _ ofOpenModal pid a -> doH.modify_ (\_ -> initialState { projectId = Just pid })lift $ system.toggleModal modalId ModalFFI.ShowModalpure (Just a) - replacement in client/src/Aftok/Projects/Invite.purs at line 237
-- eval :: forall slots. Action -> H.HalogenM CState Action slots Output m Uniteval = case _ ofProjectChanged 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 -> donameV <- V <<< note [NameField] <$> H.gets (_.greetName)message <- H.gets (_.message)addrType <- H.gets (_.recoveryType)addrV <-case addrType ofEmailComms -> 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<*> addrVcase toEither reqV ofLeft errors -> doH.modify_ (_ { fieldErrors = errors })Right invitation -> dopid <- H.gets (_.projectId)res <- lift $ caps.createInvitation pid invitationcase res ofRight result -> doH.raise resultlift $ system.toggleModal modalId ModalFFI.HideModalLeft errs ->lift $ system.error (show errs)handleAction :: forall slots. Action -> H.HalogenM CState Action slots output m UnithandleAction = case _ ofSetGreetName 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 -> dolet setZAddr addr' = dozres <- lift $ caps.checkZAddr addr'H.modify_ (_ { zaddr = Just addr' })case zres ofAcc.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 -> dopidV <- V <<< note [PidField] <$> H.gets (_.projectId)nameV <- V <<< note [NameField] <$> H.gets (_.greetName)message <- H.gets (_.message)channel <- H.gets (_.channel)addrV <-case channel ofEmailComms -> 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<*> addrVcase toEither (Tuple <$> pidV <*> reqV) ofRight (Tuple pid invitation) -> dores <- lift $ caps.createInvitation pid invitationcase res ofRight (Just req) -> H.modify_ (_ { mode = QrScan req })Right Nothing -> handleAction CloseLeft errs -> lift $ system.error (show errs)Left errors -> doH.modify_ (_ { fieldErrors = errors })Close -> doH.modify_ (const initialState) -- wipe the state for safetylift $ system.toggleModal modalId ModalFFI.HideModal - replacement in client/src/Aftok/Signup.purs at line 65
, recoveryType :: CommsType, recoveryEmail :: Maybe String, recoveryZAddr :: Maybe String, channel :: CommsType, email :: Maybe String, zaddr :: Maybe String - replacement in client/src/Aftok/Signup.purs at line 121
, recoveryType: EmailComms, recoveryEmail: Nothing, recoveryZAddr: Nothing, channel: EmailComms, email: Nothing, zaddr: Nothing - replacement in client/src/Aftok/Signup.purs at line 191
, commsSwitch SetRecoveryType st.recoveryType, commsSwitch SetRecoveryType st.channel - replacement in client/src/Aftok/Signup.purs at line 229
H.modify_ (_ { recoveryZAddr = Just addr })H.modify_ (_ { zaddr = Just addr }) - replacement in client/src/Aftok/Signup.purs at line 232
H.modify_ (\st -> st { signupErrors = M.delete ZAddrField st.signupErrors, recoveryType = ZcashComms })H.modify_ (\st -> st { signupErrors = M.delete ZAddrField st.signupErrors, channel = ZcashComms }) - replacement in client/src/Aftok/Signup.purs at line 273
H.modify_ (_ { recoveryType = t })H.modify_ (_ { channel = t }) - replacement in client/src/Aftok/Signup.purs at line 275
H.modify_ (_ { recoveryEmail = Just email })H.modify_ (_ { email = Just email }) - replacement in client/src/Aftok/Signup.purs at line 284
recType <- H.gets (_.recoveryType)recType <- H.gets (_.channel) - replacement in client/src/Aftok/Signup.purs at line 288
recoveryType <- H.gets (_.recoveryType)recoveryV <- case recoveryType ofEmailComms -> V <<< note [ EmailRequired ] <<< map Acc.RecoverByEmail <$> H.gets (_.recoveryEmail)ZcashComms -> V <<< note [ ZAddrRequired ] <<< map Acc.RecoverByZAddr <$> H.gets (_.recoveryZAddr)channel <- H.gets (_.channel)recoveryV <- case channel ofEmailComms -> V <<< note [ EmailRequired ] <<< map Acc.RecoverByEmail <$> H.gets (_.email)ZcashComms -> V <<< note [ ZAddrRequired ] <<< map Acc.RecoverByZAddr <$> H.gets (_.zaddr)