@wealthx/shadcn 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +360 -180
- package/CHANGELOG.md +12 -0
- package/dist/chunk-2A53WPEC.mjs +182 -0
- package/dist/{chunk-SIVYAI3M.mjs → chunk-2LLFNGJZ.mjs} +15 -15
- package/dist/chunk-2QNOPXMQ.mjs +360 -0
- package/dist/{chunk-K5QV4TT6.mjs → chunk-2WCIORP7.mjs} +29 -4
- package/dist/{chunk-5NF6T2RS.mjs → chunk-3AREQTZU.mjs} +8 -8
- package/dist/{chunk-2EM2FRU6.mjs → chunk-3WGFIFP6.mjs} +5 -5
- package/dist/{chunk-K4KOD3KR.mjs → chunk-42NEC57Y.mjs} +44 -25
- package/dist/{chunk-FL6DZFJK.mjs → chunk-46Q4335I.mjs} +121 -39
- package/dist/chunk-4DO3WM7V.mjs +48 -0
- package/dist/chunk-5FHBC6DY.mjs +68 -0
- package/dist/chunk-5SAYZ4CI.mjs +40 -0
- package/dist/chunk-5WMFKQZ6.mjs +180 -0
- package/dist/chunk-623YVI5O.mjs +43 -0
- package/dist/{chunk-SFH2NJEJ.mjs → chunk-6OSULDEO.mjs} +3 -3
- package/dist/{chunk-UALR6JGV.mjs → chunk-6SR4K5T5.mjs} +1 -1
- package/dist/{chunk-D2NSIIXG.mjs → chunk-7KT5HPYM.mjs} +11 -11
- package/dist/chunk-A6ER36CW.mjs +456 -0
- package/dist/{chunk-QX7IFQSF.mjs → chunk-AHKHVBWR.mjs} +4 -4
- package/dist/chunk-AHSCWXYJ.mjs +113 -0
- package/dist/{chunk-7GWRPXHD.mjs → chunk-AL6GOL2Y.mjs} +1 -1
- package/dist/{chunk-OIKBW2QD.mjs → chunk-AUEUTZIC.mjs} +13 -13
- package/dist/{chunk-FYPSTTEJ.mjs → chunk-B7DD3ODQ.mjs} +1 -1
- package/dist/{chunk-TLAWKTSA.mjs → chunk-BD3DWDT4.mjs} +3 -3
- package/dist/{chunk-S2FKV4M5.mjs → chunk-BDESHD25.mjs} +4 -4
- package/dist/{chunk-OKTJFDPN.mjs → chunk-BFB3UH7V.mjs} +2 -2
- package/dist/{chunk-DGNHGNYH.mjs → chunk-C6SWS7OW.mjs} +1 -1
- package/dist/chunk-CDVG7SFT.mjs +271 -0
- package/dist/chunk-CUSHAIUL.mjs +109 -0
- package/dist/{chunk-QXKGOMUX.mjs → chunk-CW32WTZU.mjs} +4 -4
- package/dist/{chunk-SET2ANTY.mjs → chunk-D447W45Z.mjs} +3 -3
- package/dist/{chunk-RCAOCHWA.mjs → chunk-DFL5CV75.mjs} +18 -18
- package/dist/chunk-DYSVJ473.mjs +162 -0
- package/dist/chunk-E3PQDBYI.mjs +288 -0
- package/dist/chunk-EMYBNPIA.mjs +83 -0
- package/dist/chunk-EUYPMDQG.mjs +348 -0
- package/dist/{chunk-XYPW2XA5.mjs → chunk-EW72FINW.mjs} +11 -11
- package/dist/chunk-F24U4QQQ.mjs +234 -0
- package/dist/{chunk-VB5M6OZQ.mjs → chunk-F4O2YPXJ.mjs} +1 -1
- package/dist/chunk-FFXTQTB4.mjs +84 -0
- package/dist/{chunk-ZOWL2L5J.mjs → chunk-FYUSF5KO.mjs} +5 -1
- package/dist/{chunk-FTPBQVQ6.mjs → chunk-GNER6MCO.mjs} +1 -1
- package/dist/{chunk-2D3HQPFN.mjs → chunk-HF4FUBCY.mjs} +5 -5
- package/dist/{chunk-RSUIPKGX.mjs → chunk-HNDTLT5X.mjs} +1 -1
- package/dist/{chunk-N6Q5IPKT.mjs → chunk-HO6S3ECM.mjs} +46 -18
- package/dist/{chunk-L4NSRQ3T.mjs → chunk-HROG643K.mjs} +1 -1
- package/dist/chunk-I2EKKSEF.mjs +148 -0
- package/dist/{chunk-QTRSCVQ3.mjs → chunk-I3UDLWQ7.mjs} +1 -1
- package/dist/{chunk-AE7MASLF.mjs → chunk-IQGKOT7A.mjs} +9 -6
- package/dist/chunk-IXR4BQSQ.mjs +290 -0
- package/dist/{chunk-4MM7LHM5.mjs → chunk-J5NW5NCT.mjs} +1 -1
- package/dist/{chunk-OLKMCXAR.mjs → chunk-JTG5R5YV.mjs} +24 -24
- package/dist/chunk-JUBUN65Q.mjs +106 -0
- package/dist/chunk-K7TWMLLW.mjs +520 -0
- package/dist/{chunk-BOW7U26Y.mjs → chunk-K7WSRWOU.mjs} +4 -4
- package/dist/{chunk-NTYQWVLI.mjs → chunk-KAD26MCC.mjs} +1 -1
- package/dist/{chunk-KCWNDYPZ.mjs → chunk-KB7MZMED.mjs} +4 -4
- package/dist/chunk-KCKYGQVQ.mjs +61 -0
- package/dist/{chunk-VY5NEUP7.mjs → chunk-KLJLDNCA.mjs} +1 -1
- package/dist/chunk-LLAGF6BA.mjs +49 -0
- package/dist/{chunk-G27TSQLQ.mjs → chunk-M4LTX3MH.mjs} +1 -1
- package/dist/{chunk-YIZHS72Z.mjs → chunk-MHHA7QGO.mjs} +94 -54
- package/dist/{chunk-P2N2PEFY.mjs → chunk-NCUH54IZ.mjs} +4 -4
- package/dist/{chunk-PNRUH7JY.mjs → chunk-OECGKCVF.mjs} +5 -5
- package/dist/{chunk-YE67AALL.mjs → chunk-OL65UQHQ.mjs} +10 -10
- package/dist/{chunk-LQULK2E3.mjs → chunk-OYBIUEGE.mjs} +1 -1
- package/dist/{chunk-LR6LHDP3.mjs → chunk-PGR53HMH.mjs} +7 -7
- package/dist/chunk-PUJ42INK.mjs +141 -0
- package/dist/{chunk-M4VYX2PV.mjs → chunk-PV3Y7QGK.mjs} +2 -2
- package/dist/{chunk-UJZ4UHWI.mjs → chunk-PV7PNA6K.mjs} +4 -4
- package/dist/{chunk-6HIOM2HL.mjs → chunk-Q35PNFJ7.mjs} +1 -1
- package/dist/{chunk-JZY6TNIS.mjs → chunk-Q5SGEIJV.mjs} +27 -27
- package/dist/{chunk-ZFCDYW6N.mjs → chunk-QAX6HCUH.mjs} +1 -1
- package/dist/chunk-QHJDGB54.mjs +135 -0
- package/dist/chunk-QQSOZQOC.mjs +27 -0
- package/dist/chunk-RUX3OLVZ.mjs +59 -0
- package/dist/{chunk-QOJ2DQD6.mjs → chunk-S4CTM3UE.mjs} +5 -0
- package/dist/{chunk-ZEDMKQK2.mjs → chunk-TAX3KL66.mjs} +1 -1
- package/dist/chunk-TC43SMIN.mjs +133 -0
- package/dist/chunk-TGVXRD53.mjs +174 -0
- package/dist/{chunk-K5VHK7CM.mjs → chunk-TLYSVRSK.mjs} +12 -12
- package/dist/{chunk-YCWLFG27.mjs → chunk-TOIVHWNC.mjs} +1 -1
- package/dist/chunk-TXUBGKB7.mjs +160 -0
- package/dist/chunk-UEREFDAE.mjs +75 -0
- package/dist/chunk-UTCQN6XU.mjs +123 -0
- package/dist/{chunk-37AE3OM5.mjs → chunk-V4CUTCHS.mjs} +4 -4
- package/dist/{chunk-THVO2N47.mjs → chunk-VFH632TB.mjs} +9 -9
- package/dist/{chunk-3ERBUVHC.mjs → chunk-VJ3GC7W3.mjs} +95 -49
- package/dist/{chunk-V6XGXYCJ.mjs → chunk-VLELWBEW.mjs} +4 -4
- package/dist/{chunk-FEZKMUCF.mjs → chunk-WDTXHLYM.mjs} +1 -1
- package/dist/chunk-WUA546RX.mjs +129 -0
- package/dist/chunk-XHGISOX5.mjs +257 -0
- package/dist/chunk-XIY5DJXI.mjs +168 -0
- package/dist/{chunk-TOWTPLRC.mjs → chunk-XN37434W.mjs} +8 -8
- package/dist/{chunk-KLTACJ2G.mjs → chunk-XTWAJWCQ.mjs} +1 -1
- package/dist/chunk-Y24TXIFJ.mjs +518 -0
- package/dist/{chunk-DMXYRCHM.mjs → chunk-Y6UM3VTN.mjs} +4 -4
- package/dist/components/ui/about-you-form.js +1120 -0
- package/dist/components/ui/about-you-form.mjs +323 -0
- package/dist/components/ui/account-list-carousel.js +304 -0
- package/dist/components/ui/account-list-carousel.mjs +11 -0
- package/dist/components/ui/add-column-modal.js +1 -1
- package/dist/components/ui/add-column-modal.mjs +6 -6
- package/dist/components/ui/add-lead-modal.js +2 -2
- package/dist/components/ui/add-lead-modal.mjs +6 -6
- package/dist/components/ui/advisor-card.mjs +2 -2
- package/dist/components/ui/agent-evaluation-toast.js +299 -0
- package/dist/components/ui/agent-evaluation-toast.mjs +12 -0
- package/dist/components/ui/ai-assistant-drawer.mjs +5 -5
- package/dist/components/ui/ai-builder.js +3 -3
- package/dist/components/ui/ai-builder.mjs +5 -5
- package/dist/components/ui/ai-conversations.js +2 -2
- package/dist/components/ui/ai-conversations.mjs +11 -11
- package/dist/components/ui/alert-dialog.mjs +3 -3
- package/dist/components/ui/applicant-document-checklist.js +346 -0
- package/dist/components/ui/applicant-document-checklist.mjs +10 -0
- package/dist/components/ui/applicant-expenses-section.js +455 -0
- package/dist/components/ui/applicant-expenses-section.mjs +220 -0
- package/dist/components/ui/applicant-navigation-bar.js +309 -0
- package/dist/components/ui/applicant-navigation-bar.mjs +87 -0
- package/dist/components/ui/applicant-switcher.js +268 -0
- package/dist/components/ui/applicant-switcher.mjs +46 -0
- package/dist/components/ui/application-mobile-layout.js +88 -0
- package/dist/components/ui/application-mobile-layout.mjs +8 -0
- package/dist/components/ui/appointment-action-dialogs.js +1 -1
- package/dist/components/ui/appointment-action-dialogs.mjs +10 -10
- package/dist/components/ui/appointment-availability-settings.js +78 -31
- package/dist/components/ui/appointment-availability-settings.mjs +12 -10
- package/dist/components/ui/appointment-book-dialog.js +137 -58
- package/dist/components/ui/appointment-book-dialog.mjs +14 -14
- package/dist/components/ui/appointment-calendar-view.js +1 -1
- package/dist/components/ui/appointment-calendar-view.mjs +4 -4
- package/dist/components/ui/appointment-detail-sheet.js +38 -11
- package/dist/components/ui/appointment-detail-sheet.mjs +13 -13
- package/dist/components/ui/appointment-gmail-connect.mjs +2 -2
- package/dist/components/ui/appointment-time-slot-picker.mjs +2 -2
- package/dist/components/ui/appointment-upcoming-card.js +1 -1
- package/dist/components/ui/appointment-upcoming-card.mjs +10 -10
- package/dist/components/ui/asset-accordion.js +506 -0
- package/dist/components/ui/asset-accordion.mjs +202 -0
- package/dist/components/ui/assets-liabilities-side-card.js +328 -0
- package/dist/components/ui/assets-liabilities-side-card.mjs +127 -0
- package/dist/components/ui/auth-page-layout.js +3 -3
- package/dist/components/ui/auth-page-layout.mjs +1 -1
- package/dist/components/ui/backoffice-alert-history-chart.mjs +4 -4
- package/dist/components/ui/backoffice-alert-matching-chart.js +786 -0
- package/dist/components/ui/backoffice-alert-matching-chart.mjs +19 -0
- package/dist/components/ui/backoffice-alerts-chart.mjs +4 -4
- package/dist/components/ui/backoffice-connections-chart.mjs +4 -4
- package/dist/components/ui/backoffice-contact-history-chart.mjs +4 -4
- package/dist/components/ui/backoffice-contact-matching-chart.js +803 -0
- package/dist/components/ui/backoffice-contact-matching-chart.mjs +19 -0
- package/dist/components/ui/backoffice-signup-steps.js +1673 -0
- package/dist/components/ui/backoffice-signup-steps.mjs +36 -0
- package/dist/components/ui/bank-statement-document-table.js +467 -0
- package/dist/components/ui/bank-statement-document-table.mjs +12 -0
- package/dist/components/ui/bank-statement-generate-dialog.js +1517 -0
- package/dist/components/ui/bank-statement-generate-dialog.mjs +27 -0
- package/dist/components/ui/bank-statement-pdf-viewer.js +525 -0
- package/dist/components/ui/bank-statement-pdf-viewer.mjs +14 -0
- package/dist/components/ui/banking-accounts-connect.js +336 -0
- package/dist/components/ui/banking-accounts-connect.mjs +114 -0
- package/dist/components/ui/borrowing-capacity-atoms.js +382 -0
- package/dist/components/ui/borrowing-capacity-atoms.mjs +17 -0
- package/dist/components/ui/borrowing-capacity-card.js +835 -0
- package/dist/components/ui/borrowing-capacity-card.mjs +89 -0
- package/dist/components/ui/borrowing-capacity-line-chart.mjs +4 -4
- package/dist/components/ui/broker-info-panel.js +281 -0
- package/dist/components/ui/broker-info-panel.mjs +59 -0
- package/dist/components/ui/calculator-input-item.js +101 -0
- package/dist/components/ui/calculator-input-item.mjs +8 -0
- package/dist/components/ui/calculator-section.js +743 -0
- package/dist/components/ui/calculator-section.mjs +220 -0
- package/dist/components/ui/calendar.mjs +2 -2
- package/dist/components/ui/cash-balance-line-chart.mjs +5 -5
- package/dist/components/ui/cashflow-bar-chart.mjs +4 -4
- package/dist/components/ui/category-edit-dialog.js +737 -0
- package/dist/components/ui/category-edit-dialog.mjs +16 -0
- package/dist/components/ui/chat-widget.mjs +3 -3
- package/dist/components/ui/color-picker.mjs +4 -4
- package/dist/components/ui/connect-bank-step.js +511 -0
- package/dist/components/ui/connect-bank-step.mjs +287 -0
- package/dist/components/ui/contact-alert-dialog.js +1405 -0
- package/dist/components/ui/contact-alert-dialog.mjs +27 -0
- package/dist/components/ui/create-contact-modal.js +1028 -0
- package/dist/components/ui/create-contact-modal.mjs +21 -0
- package/dist/components/ui/csv-import-modal.js +583 -0
- package/dist/components/ui/csv-import-modal.mjs +14 -0
- package/dist/components/ui/currency-input.js +439 -0
- package/dist/components/ui/currency-input.mjs +13 -0
- package/dist/components/ui/dashboard-expense-categories.js +355 -0
- package/dist/components/ui/dashboard-expense-categories.mjs +186 -0
- package/dist/components/ui/dashboard-transactions-table.js +1083 -0
- package/dist/components/ui/dashboard-transactions-table.mjs +177 -0
- package/dist/components/ui/data-table.mjs +6 -6
- package/dist/components/ui/date-picker.mjs +6 -6
- package/dist/components/ui/debt-accordion.js +523 -0
- package/dist/components/ui/debt-accordion.mjs +219 -0
- package/dist/components/ui/delete-contact-component.js +479 -0
- package/dist/components/ui/delete-contact-component.mjs +14 -0
- package/dist/components/ui/dialog.js +1 -1
- package/dist/components/ui/dialog.mjs +3 -3
- package/dist/components/ui/document-checklist-template.mjs +4 -4
- package/dist/components/ui/drawer.mjs +3 -3
- package/dist/components/ui/dropdown-menu.mjs +3 -3
- package/dist/components/ui/dynamic-tabs.js +274 -0
- package/dist/components/ui/dynamic-tabs.mjs +116 -0
- package/dist/components/ui/editable-money-item.js +306 -0
- package/dist/components/ui/editable-money-item.mjs +12 -0
- package/dist/components/ui/expense-bar-chart.mjs +4 -4
- package/dist/components/ui/expense-detail-item.js +506 -0
- package/dist/components/ui/expense-detail-item.mjs +15 -0
- package/dist/components/ui/expense-work-details.js +1259 -0
- package/dist/components/ui/expense-work-details.mjs +175 -0
- package/dist/components/ui/field.mjs +2 -2
- package/dist/components/ui/file-preview-dialog.js +704 -0
- package/dist/components/ui/file-preview-dialog.mjs +17 -0
- package/dist/components/ui/financial-cards.mjs +2 -2
- package/dist/components/ui/financial-drawers.js +1 -1
- package/dist/components/ui/financial-drawers.mjs +5 -5
- package/dist/components/ui/financial-sections.mjs +4 -4
- package/dist/components/ui/form-primitives.mjs +2 -2
- package/dist/components/ui/frontend-signup-steps.js +1239 -0
- package/dist/components/ui/frontend-signup-steps.mjs +38 -0
- package/dist/components/ui/income-bar-chart.mjs +4 -4
- package/dist/components/ui/income-sources-card.js +269 -0
- package/dist/components/ui/income-sources-card.mjs +100 -0
- package/dist/components/ui/income-summary-component.js +361 -0
- package/dist/components/ui/income-summary-component.mjs +84 -0
- package/dist/components/ui/income-work-details.js +1663 -0
- package/dist/components/ui/income-work-details.mjs +28 -0
- package/dist/components/ui/incoming-outgoings-card.js +218 -0
- package/dist/components/ui/incoming-outgoings-card.mjs +82 -0
- package/dist/components/ui/interest-rate-input.js +442 -0
- package/dist/components/ui/interest-rate-input.mjs +90 -0
- package/dist/components/ui/interest-rate-section.js +337 -0
- package/dist/components/ui/interest-rate-section.mjs +84 -0
- package/dist/components/ui/interest-rate-used.js +202 -0
- package/dist/components/ui/interest-rate-used.mjs +62 -0
- package/dist/components/ui/kanban-column.js +338 -160
- package/dist/components/ui/kanban-column.mjs +13 -11
- package/dist/components/ui/loan-applicant-information.js +336 -0
- package/dist/components/ui/loan-applicant-information.mjs +59 -0
- package/dist/components/ui/loan-applicant-invite.js +319 -0
- package/dist/components/ui/loan-applicant-invite.mjs +68 -0
- package/dist/components/ui/loan-application-badge.js +236 -0
- package/dist/components/ui/loan-application-badge.mjs +10 -0
- package/dist/components/ui/loan-application-cards.js +356 -0
- package/dist/components/ui/loan-application-cards.mjs +110 -0
- package/dist/components/ui/loan-entry-shell.js +104 -0
- package/dist/components/ui/loan-entry-shell.mjs +8 -0
- package/dist/components/ui/loan-financials.js +410 -0
- package/dist/components/ui/loan-financials.mjs +76 -0
- package/dist/components/ui/loan-option-card.js +102 -0
- package/dist/components/ui/loan-option-card.mjs +41 -0
- package/dist/components/ui/loan-option-group.js +288 -0
- package/dist/components/ui/loan-option-group.mjs +10 -0
- package/dist/components/ui/loan-steps.js +1121 -0
- package/dist/components/ui/loan-steps.mjs +509 -0
- package/dist/components/ui/loan-wizard-shell.js +452 -0
- package/dist/components/ui/loan-wizard-shell.mjs +11 -0
- package/dist/components/ui/money-input-with-slider.js +210 -0
- package/dist/components/ui/money-input-with-slider.mjs +10 -0
- package/dist/components/ui/money-item-with-color-indicator.js +314 -0
- package/dist/components/ui/money-item-with-color-indicator.mjs +20 -0
- package/dist/components/ui/opportunity-card.js +235 -97
- package/dist/components/ui/opportunity-card.mjs +11 -9
- package/dist/components/ui/opportunity-edit-modals.js +1 -1
- package/dist/components/ui/opportunity-edit-modals.mjs +15 -15
- package/dist/components/ui/opportunity-summary-tab.js +1 -1
- package/dist/components/ui/opportunity-summary-tab.mjs +19 -19
- package/dist/components/ui/pagination.mjs +4 -4
- package/dist/components/ui/password-strength-tooltip.mjs +4 -4
- package/dist/components/ui/pipeline-board.js +358 -176
- package/dist/components/ui/pipeline-board.mjs +16 -14
- package/dist/components/ui/pipeline-chart.mjs +3 -3
- package/dist/components/ui/pipeline-dialogs.js +1 -1
- package/dist/components/ui/pipeline-dialogs.mjs +9 -9
- package/dist/components/ui/pipeline-primitives.js +75 -8
- package/dist/components/ui/pipeline-primitives.mjs +3 -2
- package/dist/components/ui/popover.mjs +3 -3
- package/dist/components/ui/property-asset-card.js +428 -0
- package/dist/components/ui/property-asset-card.mjs +156 -0
- package/dist/components/ui/property-cashflow-doughnut-chart.mjs +4 -4
- package/dist/components/ui/property-debt-equity-doughnut-chart.mjs +4 -4
- package/dist/components/ui/property-list-carousel.js +295 -0
- package/dist/components/ui/property-list-carousel.mjs +11 -0
- package/dist/components/ui/property-mobile-estimate-line-chart.mjs +4 -4
- package/dist/components/ui/property-report-dialog.js +1148 -0
- package/dist/components/ui/property-report-dialog.mjs +25 -0
- package/dist/components/ui/resource-center.js +748 -0
- package/dist/components/ui/resource-center.mjs +24 -0
- package/dist/components/ui/review-alerts-dialog.js +569 -0
- package/dist/components/ui/review-alerts-dialog.mjs +15 -0
- package/dist/components/ui/savings-goal-modal.js +1148 -0
- package/dist/components/ui/savings-goal-modal.mjs +160 -0
- package/dist/components/ui/scenario-drawer.js +791 -0
- package/dist/components/ui/scenario-drawer.mjs +294 -0
- package/dist/components/ui/scenario-item.js +256 -0
- package/dist/components/ui/scenario-item.mjs +11 -0
- package/dist/components/ui/scenario-list.js +507 -0
- package/dist/components/ui/scenario-list.mjs +100 -0
- package/dist/components/ui/select.mjs +3 -3
- package/dist/components/ui/share-details-dialog.js +636 -0
- package/dist/components/ui/share-details-dialog.mjs +19 -0
- package/dist/components/ui/sheet.mjs +3 -3
- package/dist/components/ui/sidebar-nav.mjs +5 -5
- package/dist/components/ui/signup-form-primitives.js +770 -0
- package/dist/components/ui/signup-form-primitives.mjs +25 -0
- package/dist/components/ui/signup-shell.js +338 -0
- package/dist/components/ui/signup-shell.mjs +13 -0
- package/dist/components/ui/stage-timeline.js +103 -33
- package/dist/components/ui/stage-timeline.mjs +5 -4
- package/dist/components/ui/submission-confirmation-card.js +284 -0
- package/dist/components/ui/submission-confirmation-card.mjs +62 -0
- package/dist/components/ui/tooltip.mjs +3 -3
- package/dist/components/ui/top-three-product.js +374 -0
- package/dist/components/ui/top-three-product.mjs +129 -0
- package/dist/components/ui/transactions-expense-categories-doughnut-chart.mjs +4 -4
- package/dist/components/ui/transactions-income-expense-bar-chart.mjs +5 -5
- package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.mjs +4 -4
- package/dist/components/ui/transactions-summary-block.js +95 -0
- package/dist/components/ui/transactions-summary-block.mjs +34 -0
- package/dist/components/ui/two-fa-setup-form.mjs +3 -3
- package/dist/index.js +9430 -4573
- package/dist/index.mjs +404 -251
- package/dist/lib/colors.js +6 -0
- package/dist/lib/colors.mjs +3 -1
- package/dist/lib/theme-provider.mjs +2 -2
- package/dist/styles.css +1 -1
- package/package.json +366 -2
- package/src/components/index.tsx +223 -0
- package/src/components/ui/about-you-form.tsx +397 -0
- package/src/components/ui/account-list-carousel.tsx +87 -0
- package/src/components/ui/add-lead-modal.tsx +1 -1
- package/src/components/ui/agent-evaluation-toast.tsx +191 -0
- package/src/components/ui/ai-builder.tsx +3 -5
- package/src/components/ui/ai-conversations.tsx +1 -1
- package/src/components/ui/applicant-document-checklist.tsx +175 -0
- package/src/components/ui/applicant-expenses-section.tsx +260 -0
- package/src/components/ui/applicant-navigation-bar.tsx +104 -0
- package/src/components/ui/applicant-switcher.tsx +54 -0
- package/src/components/ui/application-mobile-layout.tsx +34 -0
- package/src/components/ui/appointment-availability-settings.tsx +115 -23
- package/src/components/ui/appointment-book-dialog.tsx +406 -259
- package/src/components/ui/appointment-calendar-view.tsx +4 -1
- package/src/components/ui/appointment-detail-sheet.tsx +59 -24
- package/src/components/ui/appointment-time-slot-picker.tsx +5 -1
- package/src/components/ui/asset-accordion.tsx +241 -0
- package/src/components/ui/assets-liabilities-side-card.tsx +157 -0
- package/src/components/ui/auth-page-layout.tsx +3 -3
- package/src/components/ui/backoffice-alert-matching-chart.tsx +320 -0
- package/src/components/ui/backoffice-contact-matching-chart.tsx +341 -0
- package/src/components/ui/backoffice-signup-steps.tsx +615 -0
- package/src/components/ui/bank-statement-document-table.tsx +222 -0
- package/src/components/ui/bank-statement-generate-dialog.tsx +435 -0
- package/src/components/ui/bank-statement-pdf-viewer.tsx +241 -0
- package/src/components/ui/banking-accounts-connect.tsx +187 -0
- package/src/components/ui/borrowing-capacity-atoms.tsx +228 -0
- package/src/components/ui/borrowing-capacity-card.tsx +155 -0
- package/src/components/ui/broker-info-panel.tsx +94 -0
- package/src/components/ui/calculator-input-item.tsx +49 -0
- package/src/components/ui/calculator-section.tsx +275 -0
- package/src/components/ui/category-edit-dialog.tsx +300 -0
- package/src/components/ui/connect-bank-step.tsx +379 -0
- package/src/components/ui/contact-alert-dialog.tsx +710 -0
- package/src/components/ui/create-contact-modal.tsx +237 -0
- package/src/components/ui/csv-import-modal.tsx +153 -0
- package/src/components/ui/currency-input.tsx +104 -0
- package/src/components/ui/dashboard-expense-categories.tsx +262 -0
- package/src/components/ui/dashboard-transactions-table.tsx +241 -0
- package/src/components/ui/debt-accordion.tsx +254 -0
- package/src/components/ui/delete-contact-component.tsx +87 -0
- package/src/components/ui/dialog.tsx +2 -2
- package/src/components/ui/dynamic-tabs.tsx +149 -0
- package/src/components/ui/editable-money-item.tsx +176 -0
- package/src/components/ui/expense-detail-item.tsx +216 -0
- package/src/components/ui/expense-work-details.tsx +229 -0
- package/src/components/ui/file-preview-dialog.tsx +292 -0
- package/src/components/ui/financial-drawers.tsx +1 -1
- package/src/components/ui/frontend-signup-steps.tsx +548 -0
- package/src/components/ui/income-sources-card.tsx +143 -0
- package/src/components/ui/income-summary-component.tsx +120 -0
- package/src/components/ui/income-work-details.tsx +429 -0
- package/src/components/ui/incoming-outgoings-card.tsx +111 -0
- package/src/components/ui/interest-rate-input.tsx +111 -0
- package/src/components/ui/interest-rate-section.tsx +158 -0
- package/src/components/ui/interest-rate-used.tsx +82 -0
- package/src/components/ui/kanban-column.tsx +53 -2
- package/src/components/ui/loan-applicant-information.tsx +64 -0
- package/src/components/ui/loan-applicant-invite.tsx +67 -0
- package/src/components/ui/loan-application-badge.tsx +70 -0
- package/src/components/ui/loan-application-cards.tsx +152 -0
- package/src/components/ui/loan-entry-shell.tsx +86 -0
- package/src/components/ui/loan-financials.tsx +77 -0
- package/src/components/ui/loan-option-card.tsx +62 -0
- package/src/components/ui/loan-option-group.tsx +106 -0
- package/src/components/ui/loan-steps.tsx +630 -0
- package/src/components/ui/loan-wizard-shell.tsx +235 -0
- package/src/components/ui/money-input-with-slider.tsx +77 -0
- package/src/components/ui/money-item-with-color-indicator.tsx +30 -0
- package/src/components/ui/opportunity-card.tsx +46 -18
- package/src/components/ui/pipeline-board.tsx +13 -0
- package/src/components/ui/pipeline-primitives.tsx +28 -0
- package/src/components/ui/property-asset-card.tsx +221 -0
- package/src/components/ui/property-list-carousel.tsx +73 -0
- package/src/components/ui/property-report-dialog.tsx +355 -0
- package/src/components/ui/resource-center.tsx +539 -0
- package/src/components/ui/review-alerts-dialog.tsx +163 -0
- package/src/components/ui/savings-goal-modal.tsx +169 -0
- package/src/components/ui/scenario-drawer.tsx +358 -0
- package/src/components/ui/scenario-item.tsx +141 -0
- package/src/components/ui/scenario-list.tsx +150 -0
- package/src/components/ui/share-details-dialog.tsx +238 -0
- package/src/components/ui/signup-form-primitives.tsx +212 -0
- package/src/components/ui/signup-shell.tsx +180 -0
- package/src/components/ui/stage-timeline.tsx +11 -0
- package/src/components/ui/submission-confirmation-card.tsx +68 -0
- package/src/components/ui/top-three-product.tsx +207 -0
- package/src/components/ui/transactions-summary-block.tsx +59 -0
- package/src/lib/colors.ts +12 -0
- package/src/lib/format-date.ts +2 -2
- package/src/styles/styles-css.ts +1 -1
- package/tsup.config.ts +77 -1
- package/dist/{chunk-5VOTTIXF.mjs → chunk-FRT3S72S.mjs} +3 -3
- package/dist/{chunk-7BTFGCFC.mjs → chunk-MUV4EGDW.mjs} +3 -3
- package/dist/{chunk-57ZXILTS.mjs → chunk-MXP2RX2V.mjs} +3 -3
- package/dist/{chunk-ZKWXDQDG.mjs → chunk-VCDGLN25.mjs} +3 -3
- package/dist/{chunk-FLL633WS.mjs → chunk-ZXEUBBHJ.mjs} +3 -3
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { Check, Search } from "lucide-react";
|
|
3
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "./dialog";
|
|
4
|
+
import {
|
|
5
|
+
Accordion,
|
|
6
|
+
AccordionContent,
|
|
7
|
+
AccordionItem,
|
|
8
|
+
AccordionTrigger,
|
|
9
|
+
} from "./accordion";
|
|
10
|
+
import { Input } from "./input";
|
|
11
|
+
import { Switch } from "./switch";
|
|
12
|
+
import { Button } from "./button";
|
|
13
|
+
import { cn } from "@/lib/utils";
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Types
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
export interface CategoryChild {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
icon?: React.ReactNode;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface CategoryItem {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
icon?: React.ReactNode;
|
|
29
|
+
subCategories?: CategoryChild[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface CategoryEditDialogProps {
|
|
33
|
+
open: boolean;
|
|
34
|
+
onOpenChange: (open: boolean) => void;
|
|
35
|
+
/** Transaction description shown as subtitle in the dialog header */
|
|
36
|
+
transactionDescription?: string;
|
|
37
|
+
/** Currently assigned category ID — pre-selects and auto-expands the matching parent */
|
|
38
|
+
currentCategoryId?: string;
|
|
39
|
+
/** Full category tree to display */
|
|
40
|
+
categories: CategoryItem[];
|
|
41
|
+
/** Called on Save — receives the chosen category ID and the "apply to future" toggle state */
|
|
42
|
+
onSave: (categoryId: string, applyToFuture: boolean) => void;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Internal sub-components
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
function ItemIcon({
|
|
50
|
+
icon,
|
|
51
|
+
active,
|
|
52
|
+
}: {
|
|
53
|
+
icon?: React.ReactNode;
|
|
54
|
+
active: boolean;
|
|
55
|
+
}) {
|
|
56
|
+
if (!icon) return null;
|
|
57
|
+
return (
|
|
58
|
+
<span
|
|
59
|
+
className={cn(
|
|
60
|
+
"shrink-0",
|
|
61
|
+
active ? "text-primary" : "text-muted-foreground",
|
|
62
|
+
)}
|
|
63
|
+
>
|
|
64
|
+
{icon}
|
|
65
|
+
</span>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function CategoryRow({
|
|
70
|
+
name,
|
|
71
|
+
icon,
|
|
72
|
+
isSelected,
|
|
73
|
+
indent = false,
|
|
74
|
+
onClick,
|
|
75
|
+
}: {
|
|
76
|
+
name: string;
|
|
77
|
+
icon?: React.ReactNode;
|
|
78
|
+
isSelected: boolean;
|
|
79
|
+
indent?: boolean;
|
|
80
|
+
onClick: () => void;
|
|
81
|
+
}) {
|
|
82
|
+
return (
|
|
83
|
+
<button
|
|
84
|
+
type="button"
|
|
85
|
+
onClick={onClick}
|
|
86
|
+
className={cn(
|
|
87
|
+
"flex w-full items-center gap-2 text-left text-body-small transition-colors hover:bg-muted",
|
|
88
|
+
indent ? "py-2 pl-9 pr-4" : "px-4 py-2.5",
|
|
89
|
+
isSelected && "bg-primary/10",
|
|
90
|
+
)}
|
|
91
|
+
>
|
|
92
|
+
<ItemIcon icon={icon} active={isSelected} />
|
|
93
|
+
<span className="flex-1">{name}</span>
|
|
94
|
+
{isSelected && <Check className="size-3.5 shrink-0 text-primary" />}
|
|
95
|
+
</button>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// Component
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
|
|
103
|
+
export function CategoryEditDialog({
|
|
104
|
+
open,
|
|
105
|
+
onOpenChange,
|
|
106
|
+
transactionDescription,
|
|
107
|
+
currentCategoryId,
|
|
108
|
+
categories,
|
|
109
|
+
onSave,
|
|
110
|
+
}: CategoryEditDialogProps) {
|
|
111
|
+
const [search, setSearch] = useState("");
|
|
112
|
+
const [selected, setSelected] = useState(currentCategoryId ?? "");
|
|
113
|
+
const [applyToFuture, setApplyToFuture] = useState(false);
|
|
114
|
+
const [openItem, setOpenItem] = useState<string>("");
|
|
115
|
+
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
if (!open) return;
|
|
118
|
+
setSelected(currentCategoryId ?? "");
|
|
119
|
+
setSearch("");
|
|
120
|
+
setApplyToFuture(false);
|
|
121
|
+
const parent = categories.find(
|
|
122
|
+
(c) =>
|
|
123
|
+
c.id === currentCategoryId ||
|
|
124
|
+
c.subCategories?.some((s) => s.id === currentCategoryId),
|
|
125
|
+
);
|
|
126
|
+
setOpenItem(parent?.id ?? "");
|
|
127
|
+
}, [open, currentCategoryId, categories]);
|
|
128
|
+
|
|
129
|
+
const q = search.toLowerCase();
|
|
130
|
+
|
|
131
|
+
const filtered = categories.filter(
|
|
132
|
+
(c) =>
|
|
133
|
+
!q ||
|
|
134
|
+
c.name.toLowerCase().includes(q) ||
|
|
135
|
+
c.subCategories?.some((s) => s.name.toLowerCase().includes(q)),
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
140
|
+
<DialogContent size="sm" className="gap-0 p-0">
|
|
141
|
+
<DialogHeader className="px-5 pt-5 pb-3">
|
|
142
|
+
<DialogTitle>Change Category</DialogTitle>
|
|
143
|
+
{transactionDescription && (
|
|
144
|
+
<p className="truncate text-caption text-muted-foreground">
|
|
145
|
+
{transactionDescription}
|
|
146
|
+
</p>
|
|
147
|
+
)}
|
|
148
|
+
</DialogHeader>
|
|
149
|
+
|
|
150
|
+
{/* Search */}
|
|
151
|
+
<div className="px-4 pb-3">
|
|
152
|
+
<div className="relative">
|
|
153
|
+
<Search className="absolute left-3 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
|
|
154
|
+
<Input
|
|
155
|
+
placeholder="Search categories…"
|
|
156
|
+
value={search}
|
|
157
|
+
onChange={(e) => setSearch(e.target.value)}
|
|
158
|
+
className="h-8 pl-8 text-body-small"
|
|
159
|
+
/>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
{/* Category list */}
|
|
164
|
+
<div className="max-h-64 overflow-y-auto border-y border-border">
|
|
165
|
+
{filtered.length === 0 ? (
|
|
166
|
+
<p className="py-8 text-center text-caption text-muted-foreground">
|
|
167
|
+
No categories found
|
|
168
|
+
</p>
|
|
169
|
+
) : q ? (
|
|
170
|
+
// Search mode — flat list, no animation
|
|
171
|
+
filtered.map((cat) => {
|
|
172
|
+
const hasChildren = (cat.subCategories?.length ?? 0) > 0;
|
|
173
|
+
const matchingChildren = cat.subCategories?.filter((s) =>
|
|
174
|
+
s.name.toLowerCase().includes(q),
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<div key={cat.id}>
|
|
179
|
+
{(!hasChildren || cat.name.toLowerCase().includes(q)) &&
|
|
180
|
+
(hasChildren ? (
|
|
181
|
+
// Non-selectable group header
|
|
182
|
+
<div className="flex items-center gap-2 px-4 py-2.5 text-body-small">
|
|
183
|
+
<ItemIcon icon={cat.icon} active={false} />
|
|
184
|
+
<span className="flex-1 text-muted-foreground">
|
|
185
|
+
{cat.name}
|
|
186
|
+
</span>
|
|
187
|
+
</div>
|
|
188
|
+
) : (
|
|
189
|
+
<CategoryRow
|
|
190
|
+
name={cat.name}
|
|
191
|
+
icon={cat.icon}
|
|
192
|
+
isSelected={selected === cat.id}
|
|
193
|
+
onClick={() => setSelected(cat.id)}
|
|
194
|
+
/>
|
|
195
|
+
))}
|
|
196
|
+
{matchingChildren?.map((sub) => (
|
|
197
|
+
<CategoryRow
|
|
198
|
+
key={sub.id}
|
|
199
|
+
name={sub.name}
|
|
200
|
+
icon={sub.icon}
|
|
201
|
+
isSelected={selected === sub.id}
|
|
202
|
+
indent
|
|
203
|
+
onClick={() => setSelected(sub.id)}
|
|
204
|
+
/>
|
|
205
|
+
))}
|
|
206
|
+
</div>
|
|
207
|
+
);
|
|
208
|
+
})
|
|
209
|
+
) : (
|
|
210
|
+
// Browse mode — accordion with animated expand/collapse
|
|
211
|
+
<Accordion
|
|
212
|
+
type="single"
|
|
213
|
+
collapsible
|
|
214
|
+
value={openItem}
|
|
215
|
+
onValueChange={(v) => setOpenItem(v ?? "")}
|
|
216
|
+
>
|
|
217
|
+
{filtered.map((cat) => {
|
|
218
|
+
if ((cat.subCategories?.length ?? 0) > 0) {
|
|
219
|
+
return (
|
|
220
|
+
<AccordionItem
|
|
221
|
+
key={cat.id}
|
|
222
|
+
value={cat.id}
|
|
223
|
+
className="border-b border-border last:border-0"
|
|
224
|
+
>
|
|
225
|
+
<AccordionTrigger className="gap-2 px-4 py-2.5 text-body-small hover:bg-muted hover:no-underline [&>svg:last-child]:size-3.5 [&>svg:last-child]:text-muted-foreground">
|
|
226
|
+
<ItemIcon icon={cat.icon} active={false} />
|
|
227
|
+
<span className="flex-1 text-left">{cat.name}</span>
|
|
228
|
+
</AccordionTrigger>
|
|
229
|
+
<AccordionContent className="p-0 text-current">
|
|
230
|
+
{cat.subCategories!.map((sub) => (
|
|
231
|
+
<CategoryRow
|
|
232
|
+
key={sub.id}
|
|
233
|
+
name={sub.name}
|
|
234
|
+
icon={sub.icon}
|
|
235
|
+
isSelected={selected === sub.id}
|
|
236
|
+
indent
|
|
237
|
+
onClick={() => setSelected(sub.id)}
|
|
238
|
+
/>
|
|
239
|
+
))}
|
|
240
|
+
</AccordionContent>
|
|
241
|
+
</AccordionItem>
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return (
|
|
246
|
+
<div
|
|
247
|
+
key={cat.id}
|
|
248
|
+
className="border-b border-border last:border-0"
|
|
249
|
+
>
|
|
250
|
+
<CategoryRow
|
|
251
|
+
name={cat.name}
|
|
252
|
+
icon={cat.icon}
|
|
253
|
+
isSelected={selected === cat.id}
|
|
254
|
+
onClick={() => setSelected(cat.id)}
|
|
255
|
+
/>
|
|
256
|
+
</div>
|
|
257
|
+
);
|
|
258
|
+
})}
|
|
259
|
+
</Accordion>
|
|
260
|
+
)}
|
|
261
|
+
</div>
|
|
262
|
+
|
|
263
|
+
{/* Apply to future toggle */}
|
|
264
|
+
<div className="flex items-center justify-between gap-3 px-4 py-3">
|
|
265
|
+
<label className="text-caption text-muted-foreground">
|
|
266
|
+
Apply to all future transactions from this merchant
|
|
267
|
+
</label>
|
|
268
|
+
<Switch
|
|
269
|
+
checked={applyToFuture}
|
|
270
|
+
onCheckedChange={setApplyToFuture}
|
|
271
|
+
className="shrink-0"
|
|
272
|
+
/>
|
|
273
|
+
</div>
|
|
274
|
+
|
|
275
|
+
{/* Actions */}
|
|
276
|
+
<div className="flex gap-2 px-4 pb-4">
|
|
277
|
+
<Button
|
|
278
|
+
variant="outline"
|
|
279
|
+
size="sm"
|
|
280
|
+
className="flex-1"
|
|
281
|
+
onClick={() => onOpenChange(false)}
|
|
282
|
+
>
|
|
283
|
+
Cancel
|
|
284
|
+
</Button>
|
|
285
|
+
<Button
|
|
286
|
+
size="sm"
|
|
287
|
+
className="flex-1"
|
|
288
|
+
disabled={!selected || selected === currentCategoryId}
|
|
289
|
+
onClick={() => {
|
|
290
|
+
onSave(selected, applyToFuture);
|
|
291
|
+
onOpenChange(false);
|
|
292
|
+
}}
|
|
293
|
+
>
|
|
294
|
+
Save
|
|
295
|
+
</Button>
|
|
296
|
+
</div>
|
|
297
|
+
</DialogContent>
|
|
298
|
+
</Dialog>
|
|
299
|
+
);
|
|
300
|
+
}
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { CreditCard, KeyRound, ShieldCheck } from "lucide-react";
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
import { Button } from "@/components/ui/button";
|
|
5
|
+
|
|
6
|
+
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
export type ConnectBankApplicant = {
|
|
9
|
+
name: string;
|
|
10
|
+
email?: string;
|
|
11
|
+
isMain?: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type BankTile = {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
/** Optional logo URL. Falls back to abbreviated name. */
|
|
18
|
+
logoUrl?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Default AU banks shown in the connect grid (matches Figma design).
|
|
23
|
+
* logoUrl values are relative paths served from the Storybook public directory.
|
|
24
|
+
* In production, override `banks` prop with CDN-hosted URLs.
|
|
25
|
+
*/
|
|
26
|
+
export const DEFAULT_BANKS: BankTile[] = [
|
|
27
|
+
{ id: "commonwealth", name: "CommBank", logoUrl: "/banks/commbank.png" },
|
|
28
|
+
{ id: "nab", name: "NAB", logoUrl: "/banks/nab.png" },
|
|
29
|
+
{ id: "anz", name: "ANZ", logoUrl: "/banks/anz.png" },
|
|
30
|
+
{
|
|
31
|
+
id: "bank-australia",
|
|
32
|
+
name: "Bank Australia",
|
|
33
|
+
logoUrl: "/banks/bank-australia.png",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "regional-australia-bank",
|
|
37
|
+
name: "Regional Australia Bank",
|
|
38
|
+
logoUrl: "/banks/regional-australia-bank.png",
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
export type SecurityItem = {
|
|
43
|
+
text: string;
|
|
44
|
+
icon?: React.ReactNode;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const DEFAULT_SECURITY_ITEMS: SecurityItem[] = [
|
|
48
|
+
{
|
|
49
|
+
text: "Bank grade 256-bit SSL encryption",
|
|
50
|
+
icon: <ShieldCheck className="size-5" />,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
text: "We never save your bank login credentials in the app",
|
|
54
|
+
icon: <KeyRound className="size-5" />,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
text: "We cannot make transactions on your behalf",
|
|
58
|
+
icon: <CreditCard className="size-5" />,
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
export type ConnectBankStepProps = {
|
|
63
|
+
applicant: ConnectBankApplicant;
|
|
64
|
+
/** Whether the current user has been granted banking access for this applicant. */
|
|
65
|
+
allowToAccessBanking?: boolean;
|
|
66
|
+
/** Featured banks to show as individual tiles. Defaults to 5 AU banks. A
|
|
67
|
+
* "Connect Your Bank +" tile is always appended as the 6th cell. */
|
|
68
|
+
banks?: BankTile[];
|
|
69
|
+
/** Called when a specific bank tile OR the generic "Connect Your Bank +" is clicked. */
|
|
70
|
+
onConnect?: (bank?: BankTile) => void;
|
|
71
|
+
onManualAdd?: () => void;
|
|
72
|
+
onSendRequest?: () => void;
|
|
73
|
+
onPrev?: () => void;
|
|
74
|
+
hideManualAdd?: boolean;
|
|
75
|
+
hideNavigation?: boolean;
|
|
76
|
+
hideCdrBanner?: boolean;
|
|
77
|
+
/** Security/trust items shown below the CDR banner. Defaults to 3 standard AU Open Banking items. */
|
|
78
|
+
securityItems?: SecurityItem[];
|
|
79
|
+
/** URL for the Consumer Data Right logo. Falls back to an inline SVG placeholder. */
|
|
80
|
+
cdrLogoUrl?: string;
|
|
81
|
+
/** URL for the Australian Government crest. Falls back to an inline SVG placeholder. */
|
|
82
|
+
govLogoUrl?: string;
|
|
83
|
+
className?: string;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// ─── Component ────────────────────────────────────────────────────────────────
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* ConnectBankStep — prompts the applicant to connect their bank accounts
|
|
90
|
+
* via Open Banking (Basiq).
|
|
91
|
+
*
|
|
92
|
+
* States:
|
|
93
|
+
* - `allowToAccessBanking=true` — shows CDR section + featured bank grid
|
|
94
|
+
* + "Connect Your Bank +" + "Or Add manually"
|
|
95
|
+
* - `allowToAccessBanking=false` — shows "Send join invitation" CTA only
|
|
96
|
+
* (used for co-applicants who haven't yet granted access)
|
|
97
|
+
*
|
|
98
|
+
* Mirrors `ConnectBankStep` + `ConnectBankSection` + `BankConnectBanner`
|
|
99
|
+
* from the frontend app.
|
|
100
|
+
*
|
|
101
|
+
* Figma: WealthX-Backoffice---Mobile-App — node 19308:52803
|
|
102
|
+
*/
|
|
103
|
+
export function ConnectBankStep({
|
|
104
|
+
applicant,
|
|
105
|
+
allowToAccessBanking = false,
|
|
106
|
+
banks = DEFAULT_BANKS,
|
|
107
|
+
onConnect,
|
|
108
|
+
onManualAdd,
|
|
109
|
+
onSendRequest,
|
|
110
|
+
onPrev,
|
|
111
|
+
hideManualAdd = false,
|
|
112
|
+
hideNavigation = false,
|
|
113
|
+
hideCdrBanner = false,
|
|
114
|
+
securityItems = DEFAULT_SECURITY_ITEMS,
|
|
115
|
+
cdrLogoUrl,
|
|
116
|
+
govLogoUrl,
|
|
117
|
+
className,
|
|
118
|
+
}: ConnectBankStepProps) {
|
|
119
|
+
const name = applicant.name || "applicant";
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<div className={cn("flex flex-col gap-6 font-sans", className)}>
|
|
123
|
+
{/* Heading — h1, dynamic applicant name */}
|
|
124
|
+
<h2 className="text-h1 text-foreground">
|
|
125
|
+
Connect {name}'s Bank Accounts
|
|
126
|
+
</h2>
|
|
127
|
+
|
|
128
|
+
<p className="text-body-large text-foreground">
|
|
129
|
+
Connect bank accounts & speed up your application by 20 mins.
|
|
130
|
+
</p>
|
|
131
|
+
|
|
132
|
+
{/* CDR trust section */}
|
|
133
|
+
{!hideCdrBanner && (
|
|
134
|
+
<div className="flex flex-col gap-3">
|
|
135
|
+
<div className="flex items-center gap-6">
|
|
136
|
+
<CdrLogo logoUrl={cdrLogoUrl} />
|
|
137
|
+
<AustralianGovLogo logoUrl={govLogoUrl} />
|
|
138
|
+
</div>
|
|
139
|
+
<p className="text-body-medium text-muted-foreground">
|
|
140
|
+
We are powered by Open Banking, the safest and most secure way to
|
|
141
|
+
share your information with trusted advisers. Learn more at{" "}
|
|
142
|
+
<a
|
|
143
|
+
href="https://www.cdr.gov.au/"
|
|
144
|
+
target="_blank"
|
|
145
|
+
rel="noopener noreferrer"
|
|
146
|
+
className="text-primary hover:underline"
|
|
147
|
+
>
|
|
148
|
+
https://www.cdr.gov.au/
|
|
149
|
+
</a>
|
|
150
|
+
</p>
|
|
151
|
+
|
|
152
|
+
{/* Security items */}
|
|
153
|
+
{securityItems.length > 0 && (
|
|
154
|
+
<div className="flex flex-col gap-2">
|
|
155
|
+
{securityItems.map((item, i) => (
|
|
156
|
+
<div
|
|
157
|
+
key={i}
|
|
158
|
+
className="flex items-center justify-between border border-primary bg-secondary/10 px-4 py-3"
|
|
159
|
+
>
|
|
160
|
+
<span className="text-body-medium text-foreground">
|
|
161
|
+
{item.text}
|
|
162
|
+
</span>
|
|
163
|
+
{item.icon && (
|
|
164
|
+
<span className="ml-3 shrink-0 text-primary">
|
|
165
|
+
{item.icon}
|
|
166
|
+
</span>
|
|
167
|
+
)}
|
|
168
|
+
</div>
|
|
169
|
+
))}
|
|
170
|
+
</div>
|
|
171
|
+
)}
|
|
172
|
+
</div>
|
|
173
|
+
)}
|
|
174
|
+
|
|
175
|
+
{allowToAccessBanking ? (
|
|
176
|
+
<>
|
|
177
|
+
{/* Bank connect section */}
|
|
178
|
+
<div className="flex flex-col gap-3">
|
|
179
|
+
{/* h2 (28px / 600) */}
|
|
180
|
+
<h3 className="text-h2 text-foreground">Connect Bank Account</h3>
|
|
181
|
+
|
|
182
|
+
{/* Bank grid: featured banks + generic "Connect Your Bank +" */}
|
|
183
|
+
<div className="grid grid-cols-3 border-l border-t border-border">
|
|
184
|
+
{banks.map((bank) => (
|
|
185
|
+
<button
|
|
186
|
+
key={bank.id}
|
|
187
|
+
type="button"
|
|
188
|
+
onClick={() => onConnect?.(bank)}
|
|
189
|
+
className="flex h-[71px] items-center justify-center border-b border-r border-border bg-background p-3 transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring"
|
|
190
|
+
>
|
|
191
|
+
{bank.logoUrl ? (
|
|
192
|
+
<img
|
|
193
|
+
src={bank.logoUrl}
|
|
194
|
+
alt={bank.name}
|
|
195
|
+
className="max-h-10 w-auto object-contain"
|
|
196
|
+
/>
|
|
197
|
+
) : (
|
|
198
|
+
// Text fallback when no logo — 14px bold per Figma tile spec
|
|
199
|
+
<span className="text-body-small font-bold text-foreground">
|
|
200
|
+
{bank.name}
|
|
201
|
+
</span>
|
|
202
|
+
)}
|
|
203
|
+
</button>
|
|
204
|
+
))}
|
|
205
|
+
|
|
206
|
+
{/* Generic "Connect Your Bank +" tile — 14px bold per Figma */}
|
|
207
|
+
<button
|
|
208
|
+
type="button"
|
|
209
|
+
onClick={() => onConnect?.()}
|
|
210
|
+
className="flex h-[71px] items-center justify-center gap-1.5 border-b border-r border-border bg-background p-3 transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring"
|
|
211
|
+
>
|
|
212
|
+
<span className="text-body-small font-bold text-foreground">
|
|
213
|
+
Connect Your Bank +
|
|
214
|
+
</span>
|
|
215
|
+
</button>
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
|
|
219
|
+
{/* Divider */}
|
|
220
|
+
<hr className="border-border" />
|
|
221
|
+
|
|
222
|
+
{/* Or Add manually — display-medium (48px desktop → 32px mobile) per Figma */}
|
|
223
|
+
{!hideManualAdd && (
|
|
224
|
+
<div className="flex flex-col gap-3">
|
|
225
|
+
{/* h2 (28px / 600) */}
|
|
226
|
+
<h3 className="text-h2 text-foreground">Or Add manually</h3>
|
|
227
|
+
<Button
|
|
228
|
+
variant="outline"
|
|
229
|
+
className="w-fit gap-1.5"
|
|
230
|
+
onClick={onManualAdd}
|
|
231
|
+
>
|
|
232
|
+
Start form
|
|
233
|
+
<ChevronRightIcon className="size-4" />
|
|
234
|
+
</Button>
|
|
235
|
+
</div>
|
|
236
|
+
)}
|
|
237
|
+
</>
|
|
238
|
+
) : (
|
|
239
|
+
/* Co-applicant — no access yet */
|
|
240
|
+
<Button className="w-full" onClick={onSendRequest}>
|
|
241
|
+
Send join invitation to {name}
|
|
242
|
+
</Button>
|
|
243
|
+
)}
|
|
244
|
+
|
|
245
|
+
{/* Navigation */}
|
|
246
|
+
{!hideNavigation && (
|
|
247
|
+
<div className="pt-2">
|
|
248
|
+
<Button variant="outline" onClick={onPrev}>
|
|
249
|
+
<ChevronLeftIcon className="mr-1 size-4" />
|
|
250
|
+
Previous
|
|
251
|
+
</Button>
|
|
252
|
+
</div>
|
|
253
|
+
)}
|
|
254
|
+
</div>
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// ─── CDR / Gov logos ──────────────────────────────────────────────────────────
|
|
259
|
+
|
|
260
|
+
/** Consumer Data Right logo — uses real image when `logoUrl` is provided, falls back to SVG placeholder */
|
|
261
|
+
function CdrLogo({ logoUrl }: { logoUrl?: string }) {
|
|
262
|
+
if (logoUrl) {
|
|
263
|
+
return (
|
|
264
|
+
<img
|
|
265
|
+
src={logoUrl}
|
|
266
|
+
alt="Consumer Data Right"
|
|
267
|
+
className="h-[76px] w-auto object-contain"
|
|
268
|
+
/>
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
return (
|
|
272
|
+
<div className="flex items-center gap-2">
|
|
273
|
+
<svg
|
|
274
|
+
width="48"
|
|
275
|
+
height="48"
|
|
276
|
+
viewBox="0 0 48 48"
|
|
277
|
+
fill="none"
|
|
278
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
279
|
+
aria-label="Consumer Data Right"
|
|
280
|
+
>
|
|
281
|
+
<circle cx="24" cy="24" r="22" stroke="#0057A8" strokeWidth="2" />
|
|
282
|
+
<circle cx="24" cy="24" r="14" stroke="#0057A8" strokeWidth="2" />
|
|
283
|
+
<circle cx="24" cy="24" r="6" fill="#0057A8" />
|
|
284
|
+
<circle cx="24" cy="6" r="3" fill="#0057A8" />
|
|
285
|
+
<circle cx="24" cy="42" r="3" fill="#0057A8" />
|
|
286
|
+
<circle cx="6" cy="24" r="3" fill="#0057A8" />
|
|
287
|
+
<circle cx="42" cy="24" r="3" fill="#0057A8" />
|
|
288
|
+
</svg>
|
|
289
|
+
<div className="flex flex-col leading-tight">
|
|
290
|
+
<span className="text-[11px] font-bold text-[#0057A8]">Consumer</span>
|
|
291
|
+
<span className="text-[11px] font-bold text-[#0057A8]">Data Right</span>
|
|
292
|
+
</div>
|
|
293
|
+
</div>
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** Australian Government crest — uses real image when `logoUrl` is provided, falls back to SVG placeholder */
|
|
298
|
+
function AustralianGovLogo({ logoUrl }: { logoUrl?: string }) {
|
|
299
|
+
if (logoUrl) {
|
|
300
|
+
return (
|
|
301
|
+
<img
|
|
302
|
+
src={logoUrl}
|
|
303
|
+
alt="Australian Government"
|
|
304
|
+
className="h-[70px] w-auto object-contain"
|
|
305
|
+
/>
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
return (
|
|
309
|
+
<div className="flex flex-col items-center gap-0.5">
|
|
310
|
+
{/* Simplified coat of arms silhouette */}
|
|
311
|
+
<svg
|
|
312
|
+
width="40"
|
|
313
|
+
height="36"
|
|
314
|
+
viewBox="0 0 40 36"
|
|
315
|
+
fill="none"
|
|
316
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
317
|
+
aria-label="Australian Government"
|
|
318
|
+
>
|
|
319
|
+
<ellipse
|
|
320
|
+
cx="20"
|
|
321
|
+
cy="22"
|
|
322
|
+
rx="14"
|
|
323
|
+
ry="10"
|
|
324
|
+
stroke="#333"
|
|
325
|
+
strokeWidth="1.5"
|
|
326
|
+
/>
|
|
327
|
+
<circle cx="20" cy="10" r="6" stroke="#333" strokeWidth="1.5" />
|
|
328
|
+
<path
|
|
329
|
+
d="M14 18 Q20 8 26 18"
|
|
330
|
+
stroke="#333"
|
|
331
|
+
strokeWidth="1.5"
|
|
332
|
+
fill="none"
|
|
333
|
+
/>
|
|
334
|
+
<line x1="10" y1="28" x2="30" y2="28" stroke="#333" strokeWidth="1.5" />
|
|
335
|
+
</svg>
|
|
336
|
+
<span className="text-[10px] font-semibold text-foreground">
|
|
337
|
+
Australian Government
|
|
338
|
+
</span>
|
|
339
|
+
</div>
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// ─── Icons ────────────────────────────────────────────────────────────────────
|
|
344
|
+
|
|
345
|
+
function ChevronLeftIcon({ className }: { className?: string }) {
|
|
346
|
+
return (
|
|
347
|
+
<svg
|
|
348
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
349
|
+
viewBox="0 0 24 24"
|
|
350
|
+
fill="none"
|
|
351
|
+
stroke="currentColor"
|
|
352
|
+
strokeWidth={2}
|
|
353
|
+
strokeLinecap="round"
|
|
354
|
+
strokeLinejoin="round"
|
|
355
|
+
className={className}
|
|
356
|
+
aria-hidden="true"
|
|
357
|
+
>
|
|
358
|
+
<path d="m15 18-6-6 6-6" />
|
|
359
|
+
</svg>
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function ChevronRightIcon({ className }: { className?: string }) {
|
|
364
|
+
return (
|
|
365
|
+
<svg
|
|
366
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
367
|
+
viewBox="0 0 24 24"
|
|
368
|
+
fill="none"
|
|
369
|
+
stroke="currentColor"
|
|
370
|
+
strokeWidth={2}
|
|
371
|
+
strokeLinecap="round"
|
|
372
|
+
strokeLinejoin="round"
|
|
373
|
+
className={className}
|
|
374
|
+
aria-hidden="true"
|
|
375
|
+
>
|
|
376
|
+
<path d="m9 18 6-6-6-6" />
|
|
377
|
+
</svg>
|
|
378
|
+
);
|
|
379
|
+
}
|