@wealthx/shadcn 1.4.1 → 1.5.1
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 +356 -176
- 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 +367 -3
- 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,87 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
import { formatCurrency } from "@/lib/format-currency";
|
|
4
|
+
import { Button } from "./button";
|
|
5
|
+
import { Plus } from "lucide-react";
|
|
6
|
+
|
|
7
|
+
export type AccountCarouselType = "bankAccount" | "credit" | "propertyLoan";
|
|
8
|
+
|
|
9
|
+
export interface AccountCarouselItem {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
/** Institution name (e.g. "Commonwealth Bank") */
|
|
13
|
+
institution: string;
|
|
14
|
+
balance: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface AccountListCarouselProps {
|
|
18
|
+
accounts: AccountCarouselItem[];
|
|
19
|
+
type: AccountCarouselType;
|
|
20
|
+
/** When provided, shows an "Add Account" button at the end (hidden for propertyLoan) */
|
|
21
|
+
onAddAccount?: () => void;
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function AccountCard({
|
|
26
|
+
item,
|
|
27
|
+
isCombined,
|
|
28
|
+
}: {
|
|
29
|
+
item: { name: string; institution?: string; balance: number };
|
|
30
|
+
isCombined?: boolean;
|
|
31
|
+
}) {
|
|
32
|
+
return (
|
|
33
|
+
<div className="flex shrink-0 flex-col gap-1.5 border border-border p-3 w-36">
|
|
34
|
+
<p className="text-xs text-muted-foreground truncate">
|
|
35
|
+
{isCombined ? "All accounts" : item.institution}
|
|
36
|
+
</p>
|
|
37
|
+
<p className="text-sm font-medium text-foreground truncate">
|
|
38
|
+
{item.name}
|
|
39
|
+
</p>
|
|
40
|
+
<p className="text-sm font-semibold tabular-nums text-foreground">
|
|
41
|
+
{formatCurrency(item.balance)}
|
|
42
|
+
</p>
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function AccountListCarousel({
|
|
48
|
+
accounts,
|
|
49
|
+
type,
|
|
50
|
+
onAddAccount,
|
|
51
|
+
className,
|
|
52
|
+
}: AccountListCarouselProps) {
|
|
53
|
+
const combinedBalance = accounts.reduce((sum, a) => sum + a.balance, 0);
|
|
54
|
+
const showCombined = type === "bankAccount" && accounts.length > 0;
|
|
55
|
+
const showAddButton = type !== "propertyLoan" && onAddAccount;
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<div
|
|
59
|
+
className={cn(
|
|
60
|
+
"flex gap-2 overflow-x-auto pb-1 scrollbar-none",
|
|
61
|
+
className,
|
|
62
|
+
)}
|
|
63
|
+
>
|
|
64
|
+
{showCombined && (
|
|
65
|
+
<AccountCard
|
|
66
|
+
item={{ name: "Combined", balance: combinedBalance }}
|
|
67
|
+
isCombined
|
|
68
|
+
/>
|
|
69
|
+
)}
|
|
70
|
+
|
|
71
|
+
{accounts.map((account) => (
|
|
72
|
+
<AccountCard key={account.id} item={account} />
|
|
73
|
+
))}
|
|
74
|
+
|
|
75
|
+
{showAddButton && (
|
|
76
|
+
<Button
|
|
77
|
+
variant="outline"
|
|
78
|
+
onClick={onAddAccount}
|
|
79
|
+
className="shrink-0 h-auto w-36 flex-col gap-1.5 border-dashed p-3 text-muted-foreground"
|
|
80
|
+
>
|
|
81
|
+
<Plus className="h-4 w-4" />
|
|
82
|
+
<span className="text-xs">Add Account</span>
|
|
83
|
+
</Button>
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
@@ -99,7 +99,7 @@ export function AddLeadModal({
|
|
|
99
99
|
|
|
100
100
|
return (
|
|
101
101
|
<Dialog open={open} onOpenChange={isSubmitting ? undefined : onOpenChange}>
|
|
102
|
-
<DialogContent size="2xl"
|
|
102
|
+
<DialogContent size="2xl" className={className}>
|
|
103
103
|
<DialogHeader>
|
|
104
104
|
<DialogTitle>Add Lead</DialogTitle>
|
|
105
105
|
</DialogHeader>
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Bot, CheckCircle2, AlertTriangle, XCircle } from "lucide-react";
|
|
3
|
+
import { toast } from "sonner";
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
import { Badge } from "@/components/ui/badge";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* AgentEvaluationToast — WealthX DS (L3 Molecule)
|
|
9
|
+
*
|
|
10
|
+
* Displays an agent's self-evaluation result after a task is assigned in the
|
|
11
|
+
* AI pipeline stage flow. The agent reasons against the task description +
|
|
12
|
+
* expectation and returns a confidence percentage plus a result:
|
|
13
|
+
* - **Accepted** (≥70%) — agent has all inputs and will proceed autonomously
|
|
14
|
+
* - **Partial** (40–69%) — agent will attempt but flagged uncertainty; may need
|
|
15
|
+
* broker review when done
|
|
16
|
+
* - **Declined** (<40%) — agent lacks required context; task stays with broker
|
|
17
|
+
*
|
|
18
|
+
* ### Usage — as a Sonner toast
|
|
19
|
+
* ```tsx
|
|
20
|
+
* import { showAgentEvaluationToast } from "@wealthx/shadcn/agent-evaluation-toast";
|
|
21
|
+
*
|
|
22
|
+
* showAgentEvaluationToast({
|
|
23
|
+
* agentName: "Ledger Agent",
|
|
24
|
+
* taskName: "Run serviceability check",
|
|
25
|
+
* confidence: 84,
|
|
26
|
+
* result: "accepted",
|
|
27
|
+
* reasoning: "I have all required inputs to complete this task.",
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* ### Usage — as a standalone card (stories / inline display)
|
|
32
|
+
* ```tsx
|
|
33
|
+
* import { AgentEvaluationCard } from "@wealthx/shadcn/agent-evaluation-toast";
|
|
34
|
+
*
|
|
35
|
+
* <AgentEvaluationCard
|
|
36
|
+
* agentName="Ledger Agent"
|
|
37
|
+
* taskName="Run serviceability check"
|
|
38
|
+
* confidence={84}
|
|
39
|
+
* result="accepted"
|
|
40
|
+
* reasoning="I have all required inputs to complete this task."
|
|
41
|
+
* />
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Types
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
export type AgentEvaluationResult = "accepted" | "partial" | "declined";
|
|
50
|
+
|
|
51
|
+
export interface AgentEvaluationData {
|
|
52
|
+
agentName: string;
|
|
53
|
+
taskName: string;
|
|
54
|
+
/** Agent confidence — 0 to 100. */
|
|
55
|
+
confidence: number;
|
|
56
|
+
result: AgentEvaluationResult;
|
|
57
|
+
/** Brief agent reasoning shown below the headline. */
|
|
58
|
+
reasoning: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Helpers
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
const RESULT_CONFIG: Record<
|
|
66
|
+
AgentEvaluationResult,
|
|
67
|
+
{
|
|
68
|
+
label: string;
|
|
69
|
+
icon: React.ElementType;
|
|
70
|
+
badgeClass: string;
|
|
71
|
+
borderClass: string;
|
|
72
|
+
}
|
|
73
|
+
> = {
|
|
74
|
+
accepted: {
|
|
75
|
+
label: "Accepted",
|
|
76
|
+
icon: CheckCircle2,
|
|
77
|
+
badgeClass: "border-success/40 bg-success/10 text-success-text gap-1",
|
|
78
|
+
borderClass: "border-success/30",
|
|
79
|
+
},
|
|
80
|
+
partial: {
|
|
81
|
+
label: "Partial match",
|
|
82
|
+
icon: AlertTriangle,
|
|
83
|
+
badgeClass: "border-warning/40 bg-warning/10 text-warning-text gap-1",
|
|
84
|
+
borderClass: "border-warning/30",
|
|
85
|
+
},
|
|
86
|
+
declined: {
|
|
87
|
+
label: "Declined",
|
|
88
|
+
icon: XCircle,
|
|
89
|
+
badgeClass:
|
|
90
|
+
"border-destructive/40 bg-destructive/10 text-destructive-text gap-1",
|
|
91
|
+
borderClass: "border-destructive/30",
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// AgentEvaluationCard (standalone / inline)
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
|
|
99
|
+
export interface AgentEvaluationCardProps extends AgentEvaluationData {
|
|
100
|
+
className?: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function AgentEvaluationCard({
|
|
104
|
+
agentName,
|
|
105
|
+
taskName,
|
|
106
|
+
confidence,
|
|
107
|
+
result,
|
|
108
|
+
reasoning,
|
|
109
|
+
className,
|
|
110
|
+
}: AgentEvaluationCardProps) {
|
|
111
|
+
const cfg = RESULT_CONFIG[result];
|
|
112
|
+
const Icon = cfg.icon;
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<div
|
|
116
|
+
className={cn(
|
|
117
|
+
"flex flex-col gap-2 rounded border bg-card p-3 text-sm shadow-sm",
|
|
118
|
+
cfg.borderClass,
|
|
119
|
+
className,
|
|
120
|
+
)}
|
|
121
|
+
>
|
|
122
|
+
{/* Header row */}
|
|
123
|
+
<div className="flex items-start justify-between gap-3">
|
|
124
|
+
<div className="flex items-center gap-2 min-w-0">
|
|
125
|
+
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded border bg-muted">
|
|
126
|
+
<Bot className="size-3.5 text-muted-foreground" />
|
|
127
|
+
</span>
|
|
128
|
+
<div className="min-w-0">
|
|
129
|
+
<p className="truncate font-medium text-foreground leading-tight">
|
|
130
|
+
{agentName}
|
|
131
|
+
</p>
|
|
132
|
+
<p className="truncate text-xs text-muted-foreground">
|
|
133
|
+
evaluated “{taskName}”
|
|
134
|
+
</p>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
<Badge
|
|
138
|
+
variant="outline"
|
|
139
|
+
className={cn("shrink-0 text-[11px]", cfg.badgeClass)}
|
|
140
|
+
>
|
|
141
|
+
<Icon className="size-3" />
|
|
142
|
+
{cfg.label}
|
|
143
|
+
</Badge>
|
|
144
|
+
</div>
|
|
145
|
+
|
|
146
|
+
{/* Confidence bar */}
|
|
147
|
+
<div className="flex items-center gap-2">
|
|
148
|
+
<div className="h-1.5 flex-1 overflow-hidden rounded-full bg-muted">
|
|
149
|
+
<div
|
|
150
|
+
className={cn(
|
|
151
|
+
"h-full rounded-full transition-all",
|
|
152
|
+
result === "accepted"
|
|
153
|
+
? "bg-success"
|
|
154
|
+
: result === "partial"
|
|
155
|
+
? "bg-warning"
|
|
156
|
+
: "bg-destructive",
|
|
157
|
+
)}
|
|
158
|
+
style={{ width: `${confidence}%` }}
|
|
159
|
+
/>
|
|
160
|
+
</div>
|
|
161
|
+
<span className="shrink-0 text-xs font-medium text-foreground tabular-nums">
|
|
162
|
+
{confidence}%
|
|
163
|
+
</span>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
{/* Reasoning */}
|
|
167
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
168
|
+
“{reasoning}”
|
|
169
|
+
</p>
|
|
170
|
+
</div>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
// showAgentEvaluationToast (Sonner integration)
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Fire a Sonner toast showing the agent's evaluation result.
|
|
180
|
+
* Requires `<Toaster />` to be mounted in the app.
|
|
181
|
+
*/
|
|
182
|
+
export function showAgentEvaluationToast(data: AgentEvaluationData): void {
|
|
183
|
+
toast.custom(
|
|
184
|
+
() => (
|
|
185
|
+
<div className="w-[360px]">
|
|
186
|
+
<AgentEvaluationCard {...data} />
|
|
187
|
+
</div>
|
|
188
|
+
),
|
|
189
|
+
{ duration: 6000 },
|
|
190
|
+
);
|
|
191
|
+
}
|
|
@@ -150,9 +150,7 @@ export function AgentCard({
|
|
|
150
150
|
|
|
151
151
|
<div className="flex flex-col gap-2">
|
|
152
152
|
{infoBadge && (
|
|
153
|
-
<p className="bg-info/10 text-info px-2 py-1 text-xs">
|
|
154
|
-
{infoBadge}
|
|
155
|
-
</p>
|
|
153
|
+
<p className="bg-info/10 text-info px-2 py-1 text-xs">{infoBadge}</p>
|
|
156
154
|
)}
|
|
157
155
|
{tags.length > 0 && (
|
|
158
156
|
<div className="flex flex-wrap gap-1">
|
|
@@ -187,7 +185,7 @@ export function AgentMenuModal({
|
|
|
187
185
|
}: AgentMenuModalProps) {
|
|
188
186
|
return (
|
|
189
187
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
190
|
-
<DialogContent className="max-w-lg"
|
|
188
|
+
<DialogContent className="max-w-lg">
|
|
191
189
|
<DialogHeader>
|
|
192
190
|
<DialogTitle>{agentTitle}</DialogTitle>
|
|
193
191
|
<DialogDescription>{description}</DialogDescription>
|
|
@@ -383,7 +381,7 @@ export function ServiceConfigurationModal({
|
|
|
383
381
|
}: ServiceConfigurationModalProps) {
|
|
384
382
|
return (
|
|
385
383
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
386
|
-
<DialogContent className="max-w-md"
|
|
384
|
+
<DialogContent className="max-w-md">
|
|
387
385
|
{isConnected ? (
|
|
388
386
|
<>
|
|
389
387
|
<DialogHeader>
|
|
@@ -1601,7 +1601,7 @@ export function AiConvAssignAdvisorDialog({
|
|
|
1601
1601
|
|
|
1602
1602
|
return (
|
|
1603
1603
|
<Dialog open={open} onOpenChange={handleOpenChange}>
|
|
1604
|
-
<DialogContent
|
|
1604
|
+
<DialogContent>
|
|
1605
1605
|
<DialogHeader>
|
|
1606
1606
|
<DialogTitle>Assign to advisor</DialogTitle>
|
|
1607
1607
|
<DialogDescription>
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { CheckCircle2, Circle, Upload } from "lucide-react";
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
import { Button } from "@/components/ui/button";
|
|
5
|
+
|
|
6
|
+
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
export type DocumentChecklistItemStatus =
|
|
9
|
+
| "pending"
|
|
10
|
+
| "uploaded"
|
|
11
|
+
| "not-required";
|
|
12
|
+
|
|
13
|
+
export type DocumentChecklistItem = {
|
|
14
|
+
id: string;
|
|
15
|
+
/** Document category label — e.g. "Bank Statements", "Income Verification" */
|
|
16
|
+
category: string;
|
|
17
|
+
/** Filename of the uploaded file, if any */
|
|
18
|
+
fileName?: string;
|
|
19
|
+
/** Upload status */
|
|
20
|
+
status: DocumentChecklistItemStatus;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type ApplicantDocumentChecklistProps = {
|
|
24
|
+
/** Applicant label shown above the list */
|
|
25
|
+
applicantName?: string;
|
|
26
|
+
/** List of document requirements */
|
|
27
|
+
items: DocumentChecklistItem[];
|
|
28
|
+
/** Called when the applicant selects a file for an item */
|
|
29
|
+
onUpload?: (itemId: string, file: File) => void;
|
|
30
|
+
/** Called when the applicant removes an uploaded file */
|
|
31
|
+
onRemove?: (itemId: string) => void;
|
|
32
|
+
className?: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// ─── Internal helpers ─────────────────────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
type StatusIconProps = { status: DocumentChecklistItemStatus };
|
|
38
|
+
|
|
39
|
+
function StatusIcon({ status }: StatusIconProps) {
|
|
40
|
+
if (status === "uploaded") {
|
|
41
|
+
return <CheckCircle2 className="size-5 shrink-0 text-primary" />;
|
|
42
|
+
}
|
|
43
|
+
return <Circle className="size-5 shrink-0 text-muted-foreground" />;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ─── Component ────────────────────────────────────────────────────────────────
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* ApplicantDocumentChecklist — applicant-facing document upload list.
|
|
50
|
+
*
|
|
51
|
+
* Shows a checklist of required document categories. Each row has a status
|
|
52
|
+
* icon, category label, and an upload button. Once a file is uploaded the row
|
|
53
|
+
* shows the filename and a Remove action.
|
|
54
|
+
*
|
|
55
|
+
* Figma: WealthX-Backoffice---Mobile-App (loan wizard — Supporting Documents tab)
|
|
56
|
+
*/
|
|
57
|
+
export function ApplicantDocumentChecklist({
|
|
58
|
+
applicantName,
|
|
59
|
+
items,
|
|
60
|
+
onUpload,
|
|
61
|
+
onRemove,
|
|
62
|
+
className,
|
|
63
|
+
}: ApplicantDocumentChecklistProps) {
|
|
64
|
+
const inputRefs = React.useRef<Record<string, HTMLInputElement | null>>({});
|
|
65
|
+
|
|
66
|
+
function handleFileChange(
|
|
67
|
+
itemId: string,
|
|
68
|
+
e: React.ChangeEvent<HTMLInputElement>,
|
|
69
|
+
) {
|
|
70
|
+
const file = e.target.files?.[0];
|
|
71
|
+
if (file) onUpload?.(itemId, file);
|
|
72
|
+
// Reset so re-selecting the same file fires onChange again
|
|
73
|
+
e.target.value = "";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const { uploadedCount, totalRequired } = React.useMemo(() => {
|
|
77
|
+
let uploaded = 0;
|
|
78
|
+
let required = 0;
|
|
79
|
+
for (const i of items) {
|
|
80
|
+
if (i.status !== "not-required") required++;
|
|
81
|
+
if (i.status === "uploaded") uploaded++;
|
|
82
|
+
}
|
|
83
|
+
return { uploadedCount: uploaded, totalRequired: required };
|
|
84
|
+
}, [items]);
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<div className={cn("flex flex-col gap-6 font-sans", className)}>
|
|
88
|
+
<div className="flex flex-col gap-1">
|
|
89
|
+
{applicantName && (
|
|
90
|
+
<p className="text-sm text-muted-foreground">{applicantName}</p>
|
|
91
|
+
)}
|
|
92
|
+
<p className="text-sm font-medium text-foreground">
|
|
93
|
+
{uploadedCount} of {totalRequired} documents uploaded
|
|
94
|
+
</p>
|
|
95
|
+
<div className="h-1.5 w-full bg-muted">
|
|
96
|
+
<div
|
|
97
|
+
className="h-full bg-primary transition-all"
|
|
98
|
+
style={{
|
|
99
|
+
width:
|
|
100
|
+
totalRequired > 0
|
|
101
|
+
? `${Math.round((uploadedCount / totalRequired) * 100)}%`
|
|
102
|
+
: "0%",
|
|
103
|
+
}}
|
|
104
|
+
/>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<div className="flex flex-col divide-y divide-border border border-border">
|
|
109
|
+
{items.map((item) => (
|
|
110
|
+
<div key={item.id} className="flex items-center gap-3 px-4 py-3">
|
|
111
|
+
<StatusIcon status={item.status} />
|
|
112
|
+
|
|
113
|
+
<div className="flex min-w-0 flex-1 flex-col gap-0.5">
|
|
114
|
+
<span
|
|
115
|
+
className={cn(
|
|
116
|
+
"text-sm font-medium",
|
|
117
|
+
item.status === "uploaded"
|
|
118
|
+
? "text-foreground"
|
|
119
|
+
: "text-muted-foreground",
|
|
120
|
+
)}
|
|
121
|
+
>
|
|
122
|
+
{item.category}
|
|
123
|
+
</span>
|
|
124
|
+
{item.fileName && (
|
|
125
|
+
<span className="truncate text-xs text-muted-foreground">
|
|
126
|
+
{item.fileName}
|
|
127
|
+
</span>
|
|
128
|
+
)}
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div className="flex shrink-0 items-center gap-2">
|
|
132
|
+
{item.status === "uploaded" ? (
|
|
133
|
+
<Button
|
|
134
|
+
type="button"
|
|
135
|
+
variant="ghost"
|
|
136
|
+
size="sm"
|
|
137
|
+
className="text-xs text-destructive hover:text-destructive"
|
|
138
|
+
onClick={() => onRemove?.(item.id)}
|
|
139
|
+
>
|
|
140
|
+
Remove
|
|
141
|
+
</Button>
|
|
142
|
+
) : (
|
|
143
|
+
<>
|
|
144
|
+
<Button
|
|
145
|
+
type="button"
|
|
146
|
+
variant="outline"
|
|
147
|
+
size="sm"
|
|
148
|
+
className="gap-1.5 text-xs"
|
|
149
|
+
onClick={() => inputRefs.current[item.id]?.click()}
|
|
150
|
+
>
|
|
151
|
+
<Upload className="size-3.5" />
|
|
152
|
+
Upload
|
|
153
|
+
</Button>
|
|
154
|
+
<input
|
|
155
|
+
ref={(el) => {
|
|
156
|
+
inputRefs.current[item.id] = el;
|
|
157
|
+
}}
|
|
158
|
+
type="file"
|
|
159
|
+
accept=".pdf,.jpg,.jpeg,.png"
|
|
160
|
+
className="sr-only"
|
|
161
|
+
onChange={(e) => handleFileChange(item.id, e)}
|
|
162
|
+
/>
|
|
163
|
+
</>
|
|
164
|
+
)}
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
))}
|
|
168
|
+
</div>
|
|
169
|
+
|
|
170
|
+
<p className="text-xs text-muted-foreground">
|
|
171
|
+
Accepted formats: PDF, JPG, PNG. Max 10 MB per file.
|
|
172
|
+
</p>
|
|
173
|
+
</div>
|
|
174
|
+
);
|
|
175
|
+
}
|