@wealthx/shadcn 1.4.1 → 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 +6 -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,155 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
import {
|
|
4
|
+
BorrowCapacityItem,
|
|
5
|
+
StatisticItem,
|
|
6
|
+
LoanToValueRatio,
|
|
7
|
+
} from "./borrowing-capacity-atoms";
|
|
8
|
+
import { BorrowingCapacityLineChart } from "./borrowing-capacity-line-chart";
|
|
9
|
+
import type { BorrowingCapacitySeries } from "./borrowing-capacity-line-chart";
|
|
10
|
+
import { Skeleton } from "./skeleton";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Main content organism for the Borrowing Capacity page.
|
|
14
|
+
*
|
|
15
|
+
* Composes (top-to-bottom):
|
|
16
|
+
* - `BorrowingCapacityLineChart` — full-width chart with KPI header
|
|
17
|
+
* - Key metrics grid — flexible list of `BorrowCapacityItem` fields
|
|
18
|
+
* - LVR panel (optional) — `LoanToValueRatio` pinned to the right of metrics
|
|
19
|
+
* - Statistics row — up to 3 `StatisticItem` trend blocks
|
|
20
|
+
*
|
|
21
|
+
* All values are pre-formatted strings / cents — business logic stays in the
|
|
22
|
+
* app layer. Pass `isLoading` to switch every section into skeleton state.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export interface BorrowingCapacityCardField {
|
|
26
|
+
/** e.g. "Purchase Price" */
|
|
27
|
+
label: string;
|
|
28
|
+
/** Optional secondary descriptor, e.g. "80% LVR" */
|
|
29
|
+
subLabel?: string;
|
|
30
|
+
/** Pre-formatted value, e.g. "$750,000" */
|
|
31
|
+
value: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface BorrowingCapacityCardStatistic {
|
|
35
|
+
/** Number of months to look back (e.g. 3, 6, 12) */
|
|
36
|
+
loopBackMonths: number;
|
|
37
|
+
/** Absolute dollar change over the period */
|
|
38
|
+
amountChange: number;
|
|
39
|
+
/** Percentage change — positive = up, negative = down, 0 = flat */
|
|
40
|
+
amountChangePercentage: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface BorrowingCapacityCardProps {
|
|
44
|
+
// ── Chart ─────────────────────────────────────────────────────────────────
|
|
45
|
+
/** Data series to render in the line chart */
|
|
46
|
+
chartSeries?: BorrowingCapacitySeries[] | null;
|
|
47
|
+
/** Current borrowing capacity in AUD cents — shown as KPI in the chart header */
|
|
48
|
+
kpiValueCents?: number;
|
|
49
|
+
|
|
50
|
+
// ── Key metrics ───────────────────────────────────────────────────────────
|
|
51
|
+
/** Ordered result fields rendered in a responsive grid (max 4 per row) */
|
|
52
|
+
fields?: BorrowingCapacityCardField[];
|
|
53
|
+
|
|
54
|
+
// ── LVR ───────────────────────────────────────────────────────────────────
|
|
55
|
+
/** LVR as a whole number percentage (0–100). Omit to hide the LVR panel. */
|
|
56
|
+
lvr?: number;
|
|
57
|
+
debtAmount?: number;
|
|
58
|
+
equityAmount?: number;
|
|
59
|
+
|
|
60
|
+
// ── Statistics ────────────────────────────────────────────────────────────
|
|
61
|
+
/** Trend blocks shown below the metrics (typically 3 periods: 3, 6, 12 mo) */
|
|
62
|
+
statistics?: BorrowingCapacityCardStatistic[];
|
|
63
|
+
|
|
64
|
+
// ── State ─────────────────────────────────────────────────────────────────
|
|
65
|
+
/** Show skeleton loading state across every section */
|
|
66
|
+
isLoading?: boolean;
|
|
67
|
+
|
|
68
|
+
className?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function BorrowingCapacityCard({
|
|
72
|
+
chartSeries,
|
|
73
|
+
kpiValueCents,
|
|
74
|
+
fields,
|
|
75
|
+
lvr,
|
|
76
|
+
debtAmount,
|
|
77
|
+
equityAmount,
|
|
78
|
+
statistics,
|
|
79
|
+
isLoading = false,
|
|
80
|
+
className,
|
|
81
|
+
}: BorrowingCapacityCardProps) {
|
|
82
|
+
const hasFields = (fields?.length ?? 0) > 0;
|
|
83
|
+
const hasLvr = lvr !== undefined;
|
|
84
|
+
const hasStats = (statistics?.length ?? 0) > 0;
|
|
85
|
+
const showMetricsRow = isLoading || hasFields || hasLvr;
|
|
86
|
+
const showStatsRow = isLoading || hasStats;
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<div className={cn("flex flex-col border border-border", className)}>
|
|
90
|
+
{/* Chart — border stripped so the organism border acts as the card edge */}
|
|
91
|
+
<BorrowingCapacityLineChart
|
|
92
|
+
series={chartSeries}
|
|
93
|
+
kpiValue={kpiValueCents}
|
|
94
|
+
isLoading={isLoading}
|
|
95
|
+
className="border-0 shadow-none"
|
|
96
|
+
/>
|
|
97
|
+
|
|
98
|
+
{/* Key metrics + optional LVR panel */}
|
|
99
|
+
{showMetricsRow && (
|
|
100
|
+
<div className="flex items-stretch border-t border-border">
|
|
101
|
+
<div className="grid flex-1 grid-cols-4 gap-x-6 gap-y-4 p-4">
|
|
102
|
+
{isLoading
|
|
103
|
+
? Array.from({ length: fields?.length ?? 4 }).map((_, i) => (
|
|
104
|
+
<div key={i} className="flex flex-col gap-1.5">
|
|
105
|
+
<Skeleton className="h-10 w-full" />
|
|
106
|
+
<Skeleton className="h-6 w-28" />
|
|
107
|
+
</div>
|
|
108
|
+
))
|
|
109
|
+
: fields?.map((field, i) => (
|
|
110
|
+
<BorrowCapacityItem
|
|
111
|
+
key={i}
|
|
112
|
+
title={field.label}
|
|
113
|
+
subTitle={field.subLabel}
|
|
114
|
+
value={field.value}
|
|
115
|
+
/>
|
|
116
|
+
))}
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
{/* LVR — right-pinned column, w-48 keeps Debt/Equity on one line */}
|
|
120
|
+
{(isLoading || hasLvr) && (
|
|
121
|
+
<div className="flex w-48 shrink-0 items-center border-l border-border p-4">
|
|
122
|
+
{isLoading ? (
|
|
123
|
+
<div className="flex w-full flex-col items-center gap-2">
|
|
124
|
+
<Skeleton className="h-10 w-14" />
|
|
125
|
+
<Skeleton className="h-2 w-full" />
|
|
126
|
+
<Skeleton className="h-4 w-full" />
|
|
127
|
+
</div>
|
|
128
|
+
) : (
|
|
129
|
+
<LoanToValueRatio
|
|
130
|
+
lvr={lvr!}
|
|
131
|
+
debtAmount={debtAmount}
|
|
132
|
+
equityAmount={equityAmount}
|
|
133
|
+
className="w-full"
|
|
134
|
+
/>
|
|
135
|
+
)}
|
|
136
|
+
</div>
|
|
137
|
+
)}
|
|
138
|
+
</div>
|
|
139
|
+
)}
|
|
140
|
+
|
|
141
|
+
{/* Statistics row */}
|
|
142
|
+
{showStatsRow && (
|
|
143
|
+
<div className="flex gap-3 border-t border-border p-4">
|
|
144
|
+
{isLoading
|
|
145
|
+
? Array.from({ length: statistics?.length ?? 3 }).map((_, i) => (
|
|
146
|
+
<Skeleton key={i} className="h-16 flex-1" />
|
|
147
|
+
))
|
|
148
|
+
: statistics?.map((stat, i) => (
|
|
149
|
+
<StatisticItem key={i} {...stat} className="flex-1" />
|
|
150
|
+
))}
|
|
151
|
+
</div>
|
|
152
|
+
)}
|
|
153
|
+
</div>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
import { Button } from "./button";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Sidebar panel showing the assigned advisor's name and a chat CTA.
|
|
7
|
+
*
|
|
8
|
+
* Two states:
|
|
9
|
+
* - **Assigned** (`brokerName` provided): displays name, role, and a
|
|
10
|
+
* "Chat with your advisor" button.
|
|
11
|
+
* - **Unassigned** (no `brokerName`): displays a CTA to send a broker request.
|
|
12
|
+
*
|
|
13
|
+
* In both states the heading "Contact your advisor for a clear picture" is shown.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
export type BrokerRole = "mortgage-broker" | "financial-planner";
|
|
19
|
+
|
|
20
|
+
export interface BrokerInfoPanelProps {
|
|
21
|
+
/** Assigned broker's full name. Omit to show the unassigned state. */
|
|
22
|
+
brokerName?: string;
|
|
23
|
+
/** Role label shown next to the name. Defaults to "mortgage-broker". */
|
|
24
|
+
brokerRole?: BrokerRole;
|
|
25
|
+
/**
|
|
26
|
+
* Broker's contact phone number.
|
|
27
|
+
* @deprecated Kept for API compatibility; no longer displayed.
|
|
28
|
+
*/
|
|
29
|
+
brokerPhone?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Broker's contact email address.
|
|
32
|
+
* @deprecated Kept for API compatibility; no longer displayed.
|
|
33
|
+
*/
|
|
34
|
+
brokerEmail?: string;
|
|
35
|
+
/** Called when the user clicks "Chat with your advisor" (assigned state) */
|
|
36
|
+
onChat?: () => void;
|
|
37
|
+
/** Called when the user clicks "Send Broker Request" (unassigned state only) */
|
|
38
|
+
onRequestBroker?: () => void;
|
|
39
|
+
className?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
const ROLE_LABELS: Record<BrokerRole, string> = {
|
|
45
|
+
"mortgage-broker": "Mortgage Broker",
|
|
46
|
+
"financial-planner": "Financial Planner",
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// ─── Component ────────────────────────────────────────────────────────────────
|
|
50
|
+
|
|
51
|
+
export function BrokerInfoPanel({
|
|
52
|
+
brokerName,
|
|
53
|
+
brokerRole = "mortgage-broker",
|
|
54
|
+
onChat,
|
|
55
|
+
onRequestBroker,
|
|
56
|
+
className,
|
|
57
|
+
}: BrokerInfoPanelProps) {
|
|
58
|
+
return (
|
|
59
|
+
<div
|
|
60
|
+
className={cn(
|
|
61
|
+
"flex w-full flex-col items-end gap-2 border-b border-border px-6 py-4",
|
|
62
|
+
className,
|
|
63
|
+
)}
|
|
64
|
+
>
|
|
65
|
+
<p className="text-sm font-semibold text-foreground">
|
|
66
|
+
Contact your advisor for a{" "}
|
|
67
|
+
<span className="text-primary">clear picture</span>
|
|
68
|
+
</p>
|
|
69
|
+
|
|
70
|
+
{brokerName ? (
|
|
71
|
+
<>
|
|
72
|
+
<div className="flex flex-wrap items-center gap-2 text-sm font-bold leading-tight text-foreground">
|
|
73
|
+
<span>{brokerName}</span>
|
|
74
|
+
<span className="text-muted-foreground">|</span>
|
|
75
|
+
<span className="font-normal">{ROLE_LABELS[brokerRole]}</span>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<Button variant="outline" size="sm" className="mt-1" onClick={onChat}>
|
|
79
|
+
Chat with your advisor
|
|
80
|
+
</Button>
|
|
81
|
+
</>
|
|
82
|
+
) : (
|
|
83
|
+
<Button
|
|
84
|
+
variant="outline"
|
|
85
|
+
size="sm"
|
|
86
|
+
className="mt-2"
|
|
87
|
+
onClick={onRequestBroker}
|
|
88
|
+
>
|
|
89
|
+
Send Broker Request
|
|
90
|
+
</Button>
|
|
91
|
+
)}
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Pencil } from "lucide-react";
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A compact row showing a label and pre-formatted value with an optional
|
|
7
|
+
* pencil edit trigger. Used inside accordion income/expense groups in the
|
|
8
|
+
* Borrowing Capacity Calculator panel (e.g. "Avg Income Per Month").
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface CalculatorInputItemProps {
|
|
12
|
+
/** Row label (e.g. "Avg Income Per Month") */
|
|
13
|
+
label: string;
|
|
14
|
+
/** Pre-formatted value string (e.g. "$8,500") */
|
|
15
|
+
value: string;
|
|
16
|
+
/** Called when the pencil button is clicked */
|
|
17
|
+
onEdit?: () => void;
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function CalculatorInputItem({
|
|
22
|
+
label,
|
|
23
|
+
value,
|
|
24
|
+
onEdit,
|
|
25
|
+
className,
|
|
26
|
+
}: CalculatorInputItemProps) {
|
|
27
|
+
return (
|
|
28
|
+
<div
|
|
29
|
+
className={cn("flex items-center justify-between gap-3 py-2", className)}
|
|
30
|
+
>
|
|
31
|
+
<span className="truncate text-sm text-muted-foreground">{label}</span>
|
|
32
|
+
<div className="flex shrink-0 items-center gap-1">
|
|
33
|
+
<span className="text-base font-semibold tabular-nums text-foreground">
|
|
34
|
+
{value}
|
|
35
|
+
</span>
|
|
36
|
+
{onEdit && (
|
|
37
|
+
<button
|
|
38
|
+
type="button"
|
|
39
|
+
aria-label="Edit value"
|
|
40
|
+
onClick={onEdit}
|
|
41
|
+
className="p-1 text-muted-foreground transition-colors hover:text-foreground"
|
|
42
|
+
>
|
|
43
|
+
<Pencil size={14} />
|
|
44
|
+
</button>
|
|
45
|
+
)}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
import { colorMixSwatch } from "@/lib/colors";
|
|
4
|
+
import { Button } from "./button";
|
|
5
|
+
import { EditableMoneyItem } from "./editable-money-item";
|
|
6
|
+
import { CalculatorInputItem } from "./calculator-input-item";
|
|
7
|
+
import {
|
|
8
|
+
Accordion,
|
|
9
|
+
AccordionContent,
|
|
10
|
+
AccordionItem,
|
|
11
|
+
AccordionTrigger,
|
|
12
|
+
} from "./accordion";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Right-panel organism for the Borrowing Capacity page.
|
|
16
|
+
*
|
|
17
|
+
* Composes:
|
|
18
|
+
* - Collapsible income accordion with editable sub-items
|
|
19
|
+
* - Expense rows (editable + read-only) separated by dividers
|
|
20
|
+
* - Stacked proportional bar visualising income vs expenses
|
|
21
|
+
* - Apply footer button
|
|
22
|
+
*
|
|
23
|
+
* All values are pre-formatted strings — business logic stays in the app layer.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const INCOME_COLOR = "#39FD99";
|
|
27
|
+
const SURPLUS_COLOR = "#C65AFF";
|
|
28
|
+
const EXPENSES_COLOR = "#9B9EA1";
|
|
29
|
+
const DEBT_COLOR = "#162029";
|
|
30
|
+
// Distinct opacities let viewers distinguish HEM row from debt row sharing the same hue
|
|
31
|
+
const HEM_FILL_OPACITY = 0.7;
|
|
32
|
+
const DEBT_FILL_OPACITY = 0.8;
|
|
33
|
+
|
|
34
|
+
export interface CalculatorIncomeItem {
|
|
35
|
+
key: string;
|
|
36
|
+
/** e.g. "Avg Income Per Month" */
|
|
37
|
+
label: string;
|
|
38
|
+
/** Pre-formatted e.g. "$8,500" */
|
|
39
|
+
value: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface CalculatorSectionProps {
|
|
43
|
+
// ── Income accordion ─────────────────────────────────
|
|
44
|
+
/** Formatted total of all income sources, e.g. "$12,500" */
|
|
45
|
+
incomeTotalFormatted: string;
|
|
46
|
+
/** Individual income line items shown when accordion is open */
|
|
47
|
+
incomeItems: CalculatorIncomeItem[];
|
|
48
|
+
/** Initial open/closed state of the accordion (uncontrolled after mount) */
|
|
49
|
+
defaultIncomeExpanded?: boolean;
|
|
50
|
+
onIncomeExpandChange?: (open: boolean) => void;
|
|
51
|
+
/** Called with the item key when a pencil button is clicked */
|
|
52
|
+
onIncomeItemEdit?: (key: string) => void;
|
|
53
|
+
|
|
54
|
+
// ── Expense rows ──────────────────────────────────────
|
|
55
|
+
currentExpensesValue: string;
|
|
56
|
+
currentExpensesTooltip?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Raw number — enables inline editing directly in the row.
|
|
59
|
+
* Must be paired with `onCurrentExpensesChange`.
|
|
60
|
+
*/
|
|
61
|
+
currentExpenses?: number;
|
|
62
|
+
onCurrentExpensesChange?: (value: number) => void;
|
|
63
|
+
/** Fallback: called when pencil is clicked (no inline edit) */
|
|
64
|
+
onCurrentExpensesEdit?: () => void;
|
|
65
|
+
|
|
66
|
+
optimisedEstimateValue: string;
|
|
67
|
+
optimisedEstimateTooltip?: string;
|
|
68
|
+
|
|
69
|
+
debtRepaymentsValue: string;
|
|
70
|
+
/**
|
|
71
|
+
* Raw number — enables inline editing directly in the row.
|
|
72
|
+
* Must be paired with `onDebtRepaymentsChange`.
|
|
73
|
+
*/
|
|
74
|
+
debtRepayments?: number;
|
|
75
|
+
onDebtRepaymentsChange?: (value: number) => void;
|
|
76
|
+
/** Fallback: called when pencil is clicked (no inline edit) */
|
|
77
|
+
onDebtRepaymentsEdit?: () => void;
|
|
78
|
+
|
|
79
|
+
surplusIncomeValue: string;
|
|
80
|
+
|
|
81
|
+
// ── Bar proportions (0–100) ───────────────────────────
|
|
82
|
+
surplusPercent: number;
|
|
83
|
+
currentExpensesPercent: number;
|
|
84
|
+
debtRepaymentsPercent: number;
|
|
85
|
+
|
|
86
|
+
// ── Footer ────────────────────────────────────────────
|
|
87
|
+
/** Enables the Save button */
|
|
88
|
+
hasChanges?: boolean;
|
|
89
|
+
/** Shows loading state on the Save button */
|
|
90
|
+
isSaving?: boolean;
|
|
91
|
+
onSave?: () => void;
|
|
92
|
+
|
|
93
|
+
className?: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function RowDivider() {
|
|
97
|
+
return <div className="border-t border-border" />;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function CalculatorSection({
|
|
101
|
+
incomeTotalFormatted,
|
|
102
|
+
incomeItems,
|
|
103
|
+
defaultIncomeExpanded = false,
|
|
104
|
+
onIncomeExpandChange,
|
|
105
|
+
onIncomeItemEdit,
|
|
106
|
+
currentExpensesValue,
|
|
107
|
+
currentExpensesTooltip,
|
|
108
|
+
currentExpenses,
|
|
109
|
+
onCurrentExpensesChange,
|
|
110
|
+
onCurrentExpensesEdit,
|
|
111
|
+
optimisedEstimateValue,
|
|
112
|
+
optimisedEstimateTooltip,
|
|
113
|
+
debtRepaymentsValue,
|
|
114
|
+
debtRepayments,
|
|
115
|
+
onDebtRepaymentsChange,
|
|
116
|
+
onDebtRepaymentsEdit,
|
|
117
|
+
surplusIncomeValue,
|
|
118
|
+
surplusPercent,
|
|
119
|
+
currentExpensesPercent,
|
|
120
|
+
debtRepaymentsPercent,
|
|
121
|
+
hasChanges = false,
|
|
122
|
+
isSaving = false,
|
|
123
|
+
onSave,
|
|
124
|
+
className,
|
|
125
|
+
}: CalculatorSectionProps) {
|
|
126
|
+
const [accordionValue, setAccordionValue] = React.useState<string[]>(
|
|
127
|
+
defaultIncomeExpanded ? ["income"] : [],
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<div className={cn("flex flex-col gap-4 p-4", className)}>
|
|
132
|
+
<p className="text-center text-base font-bold text-foreground">
|
|
133
|
+
Calculator Used
|
|
134
|
+
</p>
|
|
135
|
+
|
|
136
|
+
<div className="flex flex-col">
|
|
137
|
+
<Accordion
|
|
138
|
+
value={accordionValue}
|
|
139
|
+
onValueChange={(vals: string[]) => {
|
|
140
|
+
setAccordionValue(vals);
|
|
141
|
+
onIncomeExpandChange?.(vals.includes("income"));
|
|
142
|
+
}}
|
|
143
|
+
>
|
|
144
|
+
<AccordionItem value="income" className="border-b-0">
|
|
145
|
+
<AccordionTrigger className="px-0 py-0 hover:no-underline hover:bg-transparent">
|
|
146
|
+
<div className="flex min-w-0 flex-1 items-center gap-2 py-2">
|
|
147
|
+
<span
|
|
148
|
+
aria-hidden
|
|
149
|
+
className="h-5 w-5 shrink-0 border"
|
|
150
|
+
style={{
|
|
151
|
+
borderColor: INCOME_COLOR,
|
|
152
|
+
backgroundColor: colorMixSwatch(INCOME_COLOR),
|
|
153
|
+
}}
|
|
154
|
+
/>
|
|
155
|
+
<span className="truncate text-sm text-foreground">
|
|
156
|
+
After tax income
|
|
157
|
+
</span>
|
|
158
|
+
</div>
|
|
159
|
+
<span className="mr-2 text-base font-semibold tabular-nums text-foreground">
|
|
160
|
+
{incomeTotalFormatted}
|
|
161
|
+
</span>
|
|
162
|
+
</AccordionTrigger>
|
|
163
|
+
<AccordionContent className="pb-0">
|
|
164
|
+
<div className="flex flex-col pl-7">
|
|
165
|
+
{incomeItems.map((item, idx) => (
|
|
166
|
+
<React.Fragment key={item.key}>
|
|
167
|
+
{idx > 0 && <RowDivider />}
|
|
168
|
+
<CalculatorInputItem
|
|
169
|
+
label={item.label}
|
|
170
|
+
value={item.value}
|
|
171
|
+
onEdit={
|
|
172
|
+
onIncomeItemEdit
|
|
173
|
+
? () => onIncomeItemEdit(item.key)
|
|
174
|
+
: undefined
|
|
175
|
+
}
|
|
176
|
+
/>
|
|
177
|
+
</React.Fragment>
|
|
178
|
+
))}
|
|
179
|
+
</div>
|
|
180
|
+
</AccordionContent>
|
|
181
|
+
</AccordionItem>
|
|
182
|
+
</Accordion>
|
|
183
|
+
|
|
184
|
+
<RowDivider />
|
|
185
|
+
|
|
186
|
+
<EditableMoneyItem
|
|
187
|
+
label="Current Expenses"
|
|
188
|
+
value={currentExpensesValue}
|
|
189
|
+
color={EXPENSES_COLOR}
|
|
190
|
+
tooltip={currentExpensesTooltip}
|
|
191
|
+
numericValue={currentExpenses}
|
|
192
|
+
onValueChange={onCurrentExpensesChange}
|
|
193
|
+
onEdit={onCurrentExpensesChange ? undefined : onCurrentExpensesEdit}
|
|
194
|
+
/>
|
|
195
|
+
|
|
196
|
+
<RowDivider />
|
|
197
|
+
|
|
198
|
+
<EditableMoneyItem
|
|
199
|
+
label="Optimised Estimate (HEM)"
|
|
200
|
+
value={optimisedEstimateValue}
|
|
201
|
+
color={DEBT_COLOR}
|
|
202
|
+
fillOpacity={HEM_FILL_OPACITY}
|
|
203
|
+
tooltip={optimisedEstimateTooltip}
|
|
204
|
+
/>
|
|
205
|
+
|
|
206
|
+
<RowDivider />
|
|
207
|
+
|
|
208
|
+
<EditableMoneyItem
|
|
209
|
+
label="Debt Repayments"
|
|
210
|
+
value={debtRepaymentsValue}
|
|
211
|
+
color={DEBT_COLOR}
|
|
212
|
+
fillOpacity={DEBT_FILL_OPACITY}
|
|
213
|
+
numericValue={debtRepayments}
|
|
214
|
+
onValueChange={onDebtRepaymentsChange}
|
|
215
|
+
onEdit={onDebtRepaymentsChange ? undefined : onDebtRepaymentsEdit}
|
|
216
|
+
/>
|
|
217
|
+
|
|
218
|
+
<RowDivider />
|
|
219
|
+
|
|
220
|
+
<EditableMoneyItem
|
|
221
|
+
label="Surplus Income"
|
|
222
|
+
value={surplusIncomeValue}
|
|
223
|
+
color={SURPLUS_COLOR}
|
|
224
|
+
/>
|
|
225
|
+
</div>
|
|
226
|
+
|
|
227
|
+
<div className="flex flex-col gap-1">
|
|
228
|
+
<div
|
|
229
|
+
className="h-5 w-full border"
|
|
230
|
+
style={{
|
|
231
|
+
borderColor: INCOME_COLOR,
|
|
232
|
+
backgroundColor: colorMixSwatch(INCOME_COLOR),
|
|
233
|
+
}}
|
|
234
|
+
aria-hidden
|
|
235
|
+
/>
|
|
236
|
+
<div className="flex h-5 gap-0.5" aria-hidden>
|
|
237
|
+
<div
|
|
238
|
+
className="shrink-0 border"
|
|
239
|
+
style={{
|
|
240
|
+
width: `${surplusPercent}%`,
|
|
241
|
+
borderColor: SURPLUS_COLOR,
|
|
242
|
+
backgroundColor: colorMixSwatch(SURPLUS_COLOR),
|
|
243
|
+
}}
|
|
244
|
+
/>
|
|
245
|
+
<div
|
|
246
|
+
className="shrink-0 border"
|
|
247
|
+
style={{
|
|
248
|
+
width: `${currentExpensesPercent}%`,
|
|
249
|
+
borderColor: EXPENSES_COLOR,
|
|
250
|
+
backgroundColor: colorMixSwatch(EXPENSES_COLOR),
|
|
251
|
+
}}
|
|
252
|
+
/>
|
|
253
|
+
<div
|
|
254
|
+
className="shrink-0 border"
|
|
255
|
+
style={{
|
|
256
|
+
width: `${debtRepaymentsPercent}%`,
|
|
257
|
+
borderColor: DEBT_COLOR,
|
|
258
|
+
backgroundColor: colorMixSwatch(DEBT_COLOR, DEBT_FILL_OPACITY),
|
|
259
|
+
}}
|
|
260
|
+
/>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
|
|
264
|
+
<div className="flex justify-end">
|
|
265
|
+
<Button
|
|
266
|
+
variant="outline-secondary"
|
|
267
|
+
disabled={!hasChanges || isSaving}
|
|
268
|
+
onClick={onSave}
|
|
269
|
+
>
|
|
270
|
+
{isSaving ? "Saving…" : "Apply"}
|
|
271
|
+
</Button>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
);
|
|
275
|
+
}
|