@wealthx/shadcn 1.2.1 → 1.3.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.
Files changed (247) hide show
  1. package/.turbo/turbo-build.log +203 -150
  2. package/CHANGELOG.md +29 -0
  3. package/dist/{chunk-4Y6R4WEC.mjs → chunk-2A5RRQGG.mjs} +9 -22
  4. package/dist/{chunk-TS2ZX2VS.mjs → chunk-2UM72RJ7.mjs} +11 -15
  5. package/dist/{chunk-A56YQQHG.mjs → chunk-3NCUZIFP.mjs} +2 -2
  6. package/dist/chunk-3OYFOX3X.mjs +79 -0
  7. package/dist/{chunk-RP3SQYA3.mjs → chunk-3TTACBDP.mjs} +9 -4
  8. package/dist/chunk-4GAWMKMI.mjs +710 -0
  9. package/dist/{chunk-SYOD63OZ.mjs → chunk-5FQIKDKP.mjs} +6 -6
  10. package/dist/{chunk-K3JYD4IU.mjs → chunk-5IS7G74I.mjs} +11 -4
  11. package/dist/chunk-6AW4KJHE.mjs +235 -0
  12. package/dist/chunk-6CR5N2JW.mjs +302 -0
  13. package/dist/{chunk-XIRTEFKH.mjs → chunk-6DZEXFNB.mjs} +36 -8
  14. package/dist/chunk-6O6KD7CE.mjs +271 -0
  15. package/dist/chunk-7PV3IWCN.mjs +33 -0
  16. package/dist/{chunk-SPJ5KXW7.mjs → chunk-7S5AESZO.mjs} +5 -5
  17. package/dist/{chunk-RYCLWMZ7.mjs → chunk-ABFDMHOR.mjs} +9 -7
  18. package/dist/{chunk-SWGT756Z.mjs → chunk-AMQZRHEZ.mjs} +10 -4
  19. package/dist/{chunk-WOEHFRGB.mjs → chunk-BDYZCBRT.mjs} +4 -4
  20. package/dist/{chunk-WAZD7NFU.mjs → chunk-BKNFWEH2.mjs} +6 -6
  21. package/dist/{chunk-CLIN5525.mjs → chunk-C7CQJNMR.mjs} +1 -1
  22. package/dist/{chunk-D4ILTPOG.mjs → chunk-CFMQP5QS.mjs} +5 -4
  23. package/dist/{chunk-VPBN3WOO.mjs → chunk-DGHAXJBN.mjs} +9 -7
  24. package/dist/chunk-DOEO3CDL.mjs +27 -0
  25. package/dist/{chunk-KUDCQ4FI.mjs → chunk-DUJTAXMH.mjs} +9 -4
  26. package/dist/{chunk-GGM2UYGG.mjs → chunk-EBXQWIYG.mjs} +10 -4
  27. package/dist/{chunk-PMB3A7V3.mjs → chunk-EI5F6FMT.mjs} +1 -1
  28. package/dist/chunk-EWRB4PAD.mjs +468 -0
  29. package/dist/chunk-FAKPBKLT.mjs +253 -0
  30. package/dist/chunk-FNQXOAYJ.mjs +169 -0
  31. package/dist/{chunk-4CX4SBRO.mjs → chunk-GHC7LLUX.mjs} +14 -5
  32. package/dist/chunk-HBZLGDIN.mjs +507 -0
  33. package/dist/{chunk-SIZMLSRU.mjs → chunk-HISNT2MG.mjs} +8 -6
  34. package/dist/{chunk-PR6V5XKM.mjs → chunk-HVY6KCCF.mjs} +7 -4
  35. package/dist/chunk-I3RZS7V2.mjs +136 -0
  36. package/dist/chunk-IAE3F7DR.mjs +1962 -0
  37. package/dist/{chunk-ZRO5JO3H.mjs → chunk-IHMFS7NZ.mjs} +81 -84
  38. package/dist/{chunk-PCPLO5HT.mjs → chunk-IOJRDS6V.mjs} +96 -14
  39. package/dist/{chunk-LHYCMLVA.mjs → chunk-JKGDCQTZ.mjs} +11 -4
  40. package/dist/{chunk-H45TKD34.mjs → chunk-JMHR3YGZ.mjs} +1 -1
  41. package/dist/{chunk-4MN6UQHG.mjs → chunk-K5A5L6T2.mjs} +17 -39
  42. package/dist/{chunk-CSDO6VBW.mjs → chunk-LBMRIB3G.mjs} +10 -10
  43. package/dist/chunk-LV35NGVG.mjs +272 -0
  44. package/dist/{chunk-FZIXGLMV.mjs → chunk-M3FV7LOK.mjs} +5 -12
  45. package/dist/{chunk-FMAXJ2SI.mjs → chunk-MBON7YRJ.mjs} +1 -1
  46. package/dist/chunk-MIZQHHUO.mjs +441 -0
  47. package/dist/chunk-MN5NYQCL.mjs +29 -0
  48. package/dist/chunk-NL3ZO62D.mjs +31 -0
  49. package/dist/{chunk-Q76O3RIQ.mjs → chunk-NMOI6CQD.mjs} +1 -1
  50. package/dist/{chunk-P6AM5V7O.mjs → chunk-OODBHKG7.mjs} +1 -1
  51. package/dist/chunk-PBL4OQV2.mjs +283 -0
  52. package/dist/{chunk-3WMX6KWS.mjs → chunk-PU4YZQXV.mjs} +11 -12
  53. package/dist/chunk-QMY3AZJH.mjs +80 -0
  54. package/dist/{chunk-BL3DXM2X.mjs → chunk-QZ4RE6NA.mjs} +11 -4
  55. package/dist/{chunk-VACKZOMY.mjs → chunk-R3VSPKNP.mjs} +3 -3
  56. package/dist/{chunk-OPNQAVVH.mjs → chunk-RJI6GKVF.mjs} +8 -6
  57. package/dist/{chunk-WG6JGJXB.mjs → chunk-T4BJLT57.mjs} +1 -1
  58. package/dist/chunk-U4NDAF2P.mjs +207 -0
  59. package/dist/{chunk-DOH3EHX7.mjs → chunk-U5X52X37.mjs} +1 -1
  60. package/dist/chunk-UMTOX62O.mjs +415 -0
  61. package/dist/{chunk-7MMXNK3C.mjs → chunk-VLARHE5V.mjs} +8 -6
  62. package/dist/{chunk-2I5S2AMY.mjs → chunk-XREGSKX3.mjs} +2 -2
  63. package/dist/{chunk-JNQORUPP.mjs → chunk-YJG55G2H.mjs} +14 -11
  64. package/dist/chunk-ZC45IGZO.mjs +388 -0
  65. package/dist/components/ui/add-column-modal.js +42 -14
  66. package/dist/components/ui/add-column-modal.mjs +4 -4
  67. package/dist/components/ui/add-lead-modal.js +42 -11
  68. package/dist/components/ui/add-lead-modal.mjs +3 -3
  69. package/dist/components/ui/advisor-card.js +497 -0
  70. package/dist/components/ui/advisor-card.mjs +13 -0
  71. package/dist/components/ui/ai-assistant-drawer.js +11 -10
  72. package/dist/components/ui/ai-assistant-drawer.mjs +3 -3
  73. package/dist/components/ui/alert-dialog.js +2 -2
  74. package/dist/components/ui/alert-dialog.mjs +2 -2
  75. package/dist/components/ui/appointment-action-dialogs.js +1160 -0
  76. package/dist/components/ui/appointment-action-dialogs.mjs +23 -0
  77. package/dist/components/ui/appointment-availability-settings.js +1590 -0
  78. package/dist/components/ui/appointment-availability-settings.mjs +23 -0
  79. package/dist/components/ui/appointment-book-dialog.js +1744 -0
  80. package/dist/components/ui/appointment-book-dialog.mjs +27 -0
  81. package/dist/components/ui/appointment-calendar-view.js +833 -0
  82. package/dist/components/ui/appointment-calendar-view.mjs +14 -0
  83. package/dist/components/ui/appointment-detail-sheet.js +1517 -0
  84. package/dist/components/ui/appointment-detail-sheet.mjs +24 -0
  85. package/dist/components/ui/appointment-gmail-connect.js +467 -0
  86. package/dist/components/ui/appointment-gmail-connect.mjs +14 -0
  87. package/dist/components/ui/appointment-mini-card.js +345 -0
  88. package/dist/components/ui/appointment-mini-card.mjs +11 -0
  89. package/dist/components/ui/appointment-time-slot-picker.js +311 -0
  90. package/dist/components/ui/appointment-time-slot-picker.mjs +13 -0
  91. package/dist/components/ui/appointment-upcoming-card.js +1268 -0
  92. package/dist/components/ui/appointment-upcoming-card.mjs +21 -0
  93. package/dist/components/ui/backoffice-alert-history-chart.js +11 -5
  94. package/dist/components/ui/backoffice-alert-history-chart.mjs +5 -4
  95. package/dist/components/ui/backoffice-alerts-chart.js +786 -0
  96. package/dist/components/ui/backoffice-alerts-chart.mjs +19 -0
  97. package/dist/components/ui/backoffice-connections-chart.js +817 -0
  98. package/dist/components/ui/backoffice-connections-chart.mjs +19 -0
  99. package/dist/components/ui/backoffice-contact-history-chart.js +11 -5
  100. package/dist/components/ui/backoffice-contact-history-chart.mjs +5 -4
  101. package/dist/components/ui/badge.js +6 -6
  102. package/dist/components/ui/badge.mjs +1 -1
  103. package/dist/components/ui/borrowing-capacity-line-chart.js +30 -21
  104. package/dist/components/ui/borrowing-capacity-line-chart.mjs +5 -4
  105. package/dist/components/ui/button.js +2 -2
  106. package/dist/components/ui/button.mjs +1 -1
  107. package/dist/components/ui/calendar.js +2 -2
  108. package/dist/components/ui/calendar.mjs +2 -2
  109. package/dist/components/ui/card.js +1 -1
  110. package/dist/components/ui/card.mjs +1 -1
  111. package/dist/components/ui/cash-balance-line-chart.js +31 -23
  112. package/dist/components/ui/cash-balance-line-chart.mjs +5 -4
  113. package/dist/components/ui/cashflow-bar-chart.js +12 -5
  114. package/dist/components/ui/cashflow-bar-chart.mjs +5 -4
  115. package/dist/components/ui/chip.js +97 -18
  116. package/dist/components/ui/chip.mjs +3 -2
  117. package/dist/components/ui/color-picker.js +547 -0
  118. package/dist/components/ui/color-picker.mjs +24 -0
  119. package/dist/components/ui/data-table.js +182 -129
  120. package/dist/components/ui/data-table.mjs +3 -2
  121. package/dist/components/ui/date-picker.js +48 -27
  122. package/dist/components/ui/date-picker.mjs +4 -3
  123. package/dist/components/ui/dialog.js +37 -9
  124. package/dist/components/ui/dialog.mjs +2 -2
  125. package/dist/components/ui/expense-bar-chart.js +12 -5
  126. package/dist/components/ui/expense-bar-chart.mjs +5 -4
  127. package/dist/components/ui/field.mjs +2 -2
  128. package/dist/components/ui/financial-cards.js +322 -155
  129. package/dist/components/ui/financial-cards.mjs +5 -3
  130. package/dist/components/ui/financial-drawers.js +2 -2
  131. package/dist/components/ui/financial-drawers.mjs +3 -3
  132. package/dist/components/ui/financial-sections.js +14 -10
  133. package/dist/components/ui/financial-sections.mjs +6 -5
  134. package/dist/components/ui/form-primitives.js +4 -4
  135. package/dist/components/ui/form-primitives.mjs +3 -3
  136. package/dist/components/ui/income-bar-chart.js +12 -5
  137. package/dist/components/ui/income-bar-chart.mjs +5 -4
  138. package/dist/components/ui/input-group.js +2 -2
  139. package/dist/components/ui/input-group.mjs +2 -2
  140. package/dist/components/ui/kanban-column.js +52 -44
  141. package/dist/components/ui/kanban-column.mjs +7 -5
  142. package/dist/components/ui/opportunity-card.js +52 -44
  143. package/dist/components/ui/opportunity-card.mjs +6 -4
  144. package/dist/components/ui/opportunity-edit-modals.js +1371 -1267
  145. package/dist/components/ui/opportunity-edit-modals.mjs +10 -10
  146. package/dist/components/ui/opportunity-summary-tab.js +2748 -2161
  147. package/dist/components/ui/opportunity-summary-tab.mjs +16 -16
  148. package/dist/components/ui/page-header.js +92 -0
  149. package/dist/components/ui/page-header.mjs +8 -0
  150. package/dist/components/ui/page-top-bar.js +88 -0
  151. package/dist/components/ui/page-top-bar.mjs +8 -0
  152. package/dist/components/ui/pagination.js +303 -19
  153. package/dist/components/ui/pagination.mjs +11 -4
  154. package/dist/components/ui/pipeline-board.js +209 -195
  155. package/dist/components/ui/pipeline-board.mjs +10 -8
  156. package/dist/components/ui/pipeline-dialogs.js +118 -69
  157. package/dist/components/ui/pipeline-dialogs.mjs +8 -7
  158. package/dist/components/ui/pipeline-primitives.js +6 -6
  159. package/dist/components/ui/pipeline-primitives.mjs +2 -2
  160. package/dist/components/ui/property-cashflow-doughnut-chart.js +14 -12
  161. package/dist/components/ui/property-cashflow-doughnut-chart.mjs +5 -4
  162. package/dist/components/ui/property-debt-equity-doughnut-chart.js +14 -12
  163. package/dist/components/ui/property-debt-equity-doughnut-chart.mjs +5 -4
  164. package/dist/components/ui/property-mobile-estimate-line-chart.js +16 -14
  165. package/dist/components/ui/property-mobile-estimate-line-chart.mjs +5 -4
  166. package/dist/components/ui/sidebar-nav.js +679 -0
  167. package/dist/components/ui/sidebar-nav.mjs +14 -0
  168. package/dist/components/ui/stage-timeline.js +6 -6
  169. package/dist/components/ui/stage-timeline.mjs +3 -3
  170. package/dist/components/ui/stepper.js +283 -0
  171. package/dist/components/ui/stepper.mjs +18 -0
  172. package/dist/components/ui/toggle-group.js +4 -4
  173. package/dist/components/ui/toggle-group.mjs +2 -2
  174. package/dist/components/ui/toggle.js +4 -4
  175. package/dist/components/ui/toggle.mjs +1 -1
  176. package/dist/components/ui/transactions-expense-categories-doughnut-chart.js +18 -16
  177. package/dist/components/ui/transactions-expense-categories-doughnut-chart.mjs +5 -4
  178. package/dist/components/ui/transactions-income-expense-bar-chart.js +28 -12
  179. package/dist/components/ui/transactions-income-expense-bar-chart.mjs +5 -4
  180. package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.js +18 -16
  181. package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.mjs +5 -4
  182. package/dist/index.js +12927 -8522
  183. package/dist/index.mjs +288 -190
  184. package/dist/lib/typography.js +10 -10
  185. package/dist/lib/typography.mjs +1 -1
  186. package/dist/styles.css +1 -1
  187. package/package.json +86 -1
  188. package/src/components/index.tsx +146 -0
  189. package/src/components/ui/add-column-modal.tsx +7 -7
  190. package/src/components/ui/add-lead-modal.tsx +6 -3
  191. package/src/components/ui/advisor-card.tsx +227 -0
  192. package/src/components/ui/ai-assistant-drawer.tsx +4 -3
  193. package/src/components/ui/appointment-action-dialogs.tsx +297 -0
  194. package/src/components/ui/appointment-availability-settings.tsx +645 -0
  195. package/src/components/ui/appointment-book-dialog.tsx +618 -0
  196. package/src/components/ui/appointment-calendar-view.tsx +510 -0
  197. package/src/components/ui/appointment-detail-sheet.tsx +415 -0
  198. package/src/components/ui/appointment-gmail-connect.tsx +188 -0
  199. package/src/components/ui/appointment-mini-card.tsx +104 -0
  200. package/src/components/ui/appointment-time-slot-picker.tsx +123 -0
  201. package/src/components/ui/appointment-upcoming-card.tsx +635 -0
  202. package/src/components/ui/backoffice-alert-history-chart.tsx +10 -2
  203. package/src/components/ui/backoffice-alerts-chart.tsx +312 -0
  204. package/src/components/ui/backoffice-connections-chart.tsx +339 -0
  205. package/src/components/ui/backoffice-contact-history-chart.tsx +10 -2
  206. package/src/components/ui/badge.tsx +12 -6
  207. package/src/components/ui/borrowing-capacity-line-chart.tsx +4 -11
  208. package/src/components/ui/button.tsx +2 -2
  209. package/src/components/ui/card.tsx +1 -1
  210. package/src/components/ui/cash-balance-line-chart.tsx +4 -23
  211. package/src/components/ui/cashflow-bar-chart.tsx +9 -2
  212. package/src/components/ui/chart-shared.tsx +4 -11
  213. package/src/components/ui/chip.tsx +23 -19
  214. package/src/components/ui/color-picker.tsx +309 -0
  215. package/src/components/ui/data-table.tsx +117 -83
  216. package/src/components/ui/date-picker.tsx +42 -37
  217. package/src/components/ui/dialog.tsx +72 -6
  218. package/src/components/ui/expense-bar-chart.tsx +11 -2
  219. package/src/components/ui/financial-cards.tsx +99 -10
  220. package/src/components/ui/income-bar-chart.tsx +11 -2
  221. package/src/components/ui/opportunity-card.tsx +10 -39
  222. package/src/components/ui/opportunity-edit-modals.tsx +98 -36
  223. package/src/components/ui/opportunity-summary-tab.tsx +548 -232
  224. package/src/components/ui/page-header.tsx +57 -0
  225. package/src/components/ui/page-top-bar.tsx +48 -0
  226. package/src/components/ui/pagination.tsx +171 -22
  227. package/src/components/ui/pipeline-board.tsx +12 -5
  228. package/src/components/ui/property-cashflow-doughnut-chart.tsx +3 -1
  229. package/src/components/ui/property-debt-equity-doughnut-chart.tsx +3 -1
  230. package/src/components/ui/property-mobile-estimate-line-chart.tsx +3 -1
  231. package/src/components/ui/sidebar-nav.tsx +516 -0
  232. package/src/components/ui/stepper.tsx +347 -0
  233. package/src/components/ui/toggle.tsx +4 -4
  234. package/src/components/ui/transactions-expense-categories-doughnut-chart.tsx +3 -1
  235. package/src/components/ui/transactions-income-expense-bar-chart.tsx +12 -9
  236. package/src/components/ui/transactions-liabilities-breakdown-doughnut-chart.tsx +3 -1
  237. package/src/lib/format-currency.ts +44 -0
  238. package/src/lib/format-date.ts +50 -0
  239. package/src/lib/opportunity-constants.ts +12 -0
  240. package/src/lib/typography.ts +11 -11
  241. package/src/styles/globals.css +36 -34
  242. package/src/styles/styles-css.ts +1 -1
  243. package/tsup.config.ts +17 -0
  244. package/dist/chunk-PG6K5XEC.mjs +0 -475
  245. package/dist/chunk-WA6O6EUR.mjs +0 -1885
  246. package/dist/chunk-WNGWBVLV.mjs +0 -148
  247. package/dist/{chunk-LLVQKSU3.mjs → chunk-GD4BJDJR.mjs} +3 -3
@@ -20,6 +20,7 @@ import {
20
20
  } from "lucide-react";
21
21
  import type { LucideIcon } from "lucide-react";
22
22
  import { cn } from "@/lib/utils";
23
+ import { formatDateShort } from "@/lib/format-date";
23
24
  import { Badge } from "./badge";
24
25
  import { RadioGroup, RadioGroupItem } from "./radio-group";
25
26
  import {
@@ -30,6 +31,7 @@ import {
30
31
  FinancialSubtotalBlock,
31
32
  FinancialSubtotalFrame,
32
33
  } from "./financial-primitives";
34
+ import { Button } from "./button";
33
35
 
34
36
  /**
35
37
  * Financial card molecules — WealthX DS (Level 3)
@@ -122,11 +124,12 @@ export function PropertyCard({
122
124
  >
123
125
  {/* Header row */}
124
126
  {isLinkedToBank ? (
125
- <button
127
+ <Button
126
128
  type="button"
129
+ variant="ghost"
127
130
  aria-expanded={expanded}
128
131
  onClick={() => setExpanded((prev) => !prev)}
129
- className="flex items-center gap-1.5 px-5 py-3 text-left cursor-pointer hover:opacity-85"
132
+ className="h-auto w-full justify-start gap-1.5 px-5 py-3 text-left"
130
133
  >
131
134
  <span className="text-label-medium text-foreground">{address}</span>
132
135
  {type && <Badge variant="outline">{type}</Badge>}
@@ -137,7 +140,7 @@ export function PropertyCard({
137
140
  expanded && "rotate-180",
138
141
  )}
139
142
  />
140
- </button>
143
+ </Button>
141
144
  ) : (
142
145
  <div className="flex items-center gap-1.5 px-5 py-3">
143
146
  <span className="text-label-medium text-foreground">{address}</span>
@@ -615,9 +618,17 @@ export interface AboutCardProps {
615
618
  lastName?: string;
616
619
  phone?: string;
617
620
  email?: string;
621
+ dob?: string;
618
622
  gender?: string;
619
623
  maritalStatus?: string;
624
+ numDependants?: string;
620
625
  citizenStatus?: string;
626
+ residentialAddress?: string;
627
+ residentialStatus?: string;
628
+ timeAtAddressYears?: string;
629
+ timeAtAddressMonths?: string;
630
+ driversLicence?: string;
631
+ passport?: string;
621
632
  propertyInTrust?: string;
622
633
  companyOwnership?: string;
623
634
  }
@@ -632,19 +643,38 @@ export function AboutCard({
632
643
  lastName,
633
644
  phone,
634
645
  email,
646
+ dob,
635
647
  gender,
636
648
  maritalStatus,
649
+ numDependants,
637
650
  citizenStatus,
651
+ residentialAddress,
652
+ residentialStatus,
653
+ timeAtAddressYears,
654
+ timeAtAddressMonths,
655
+ driversLicence,
656
+ passport,
638
657
  propertyInTrust,
639
658
  companyOwnership,
640
659
  }: AboutCardProps) {
641
660
  const fullName =
642
661
  [title, firstName, lastName].filter(Boolean).join(" ") || "—";
643
662
 
663
+ const timeAtAddress =
664
+ timeAtAddressYears || timeAtAddressMonths
665
+ ? [
666
+ timeAtAddressYears && `${timeAtAddressYears}yr`,
667
+ timeAtAddressMonths && `${timeAtAddressMonths}mo`,
668
+ ]
669
+ .filter(Boolean)
670
+ .join(" ")
671
+ : undefined;
672
+
644
673
  return (
645
674
  <div className="border border-border overflow-hidden">
646
675
  <div className="grid grid-cols-2 gap-x-8 gap-y-4 px-5 py-4">
647
676
  <FinancialDetailField label="Full Name" value={fullName} />
677
+ <FinancialDetailField label="Date of Birth" value={dob || "—"} />
648
678
  <FinancialDetailField label="Gender" value={gender || "—"} />
649
679
  <FinancialDetailField label="Phone" value={phone || "—"} />
650
680
  <FinancialDetailField label="Email" value={email || "—"} />
@@ -652,10 +682,30 @@ export function AboutCard({
652
682
  label="Marital Status"
653
683
  value={maritalStatus || "—"}
654
684
  />
685
+ <FinancialDetailField
686
+ label="No. of Dependants"
687
+ value={numDependants ?? "—"}
688
+ />
655
689
  <FinancialDetailField
656
690
  label="Citizenship"
657
691
  value={citizenStatus || "—"}
658
692
  />
693
+ <FinancialDetailField
694
+ label="Residential Address"
695
+ value={residentialAddress || "—"}
696
+ />
697
+ <FinancialDetailField
698
+ label="Residential Status"
699
+ value={residentialStatus || "—"}
700
+ />
701
+ {timeAtAddress && (
702
+ <FinancialDetailField label="Time at Address" value={timeAtAddress} />
703
+ )}
704
+ <FinancialDetailField
705
+ label="Driver's Licence"
706
+ value={driversLicence || "—"}
707
+ />
708
+ <FinancialDetailField label="Passport" value={passport || "—"} />
659
709
  <FinancialDetailField
660
710
  label="Property in Trust"
661
711
  value={propertyInTrust || "—"}
@@ -677,6 +727,11 @@ export interface IncomeCardItem {
677
727
  incomeType: string;
678
728
  jobTitle?: string;
679
729
  companyName?: string;
730
+ companyAddress?: string;
731
+ startDate?: string;
732
+ stillInPosition?: boolean;
733
+ endDate?: string;
734
+ companyType?: string;
680
735
  /** Pre-formatted amount + frequency e.g. "$9,500 / Monthly" */
681
736
  amountLabel: string;
682
737
  }
@@ -687,6 +742,7 @@ export interface IncomeCardProps {
687
742
  totalMonthly?: string;
688
743
  }
689
744
 
745
+
690
746
  /**
691
747
  * Display card for applicant income items.
692
748
  * Each income source renders as a bordered row with type, company, and amount.
@@ -706,16 +762,49 @@ export function IncomeCard({ items, totalMonthly }: IncomeCardProps) {
706
762
  <div
707
763
  key={i}
708
764
  className={cn(
709
- "grid grid-cols-3 gap-x-6 px-5 py-[15px]",
765
+ "flex flex-col gap-3 px-5 py-[15px]",
710
766
  i < items.length - 1 && "border-b border-border",
711
767
  )}
712
768
  >
713
- <FinancialDetailField label="Type" value={item.incomeType || "—"} />
714
- <FinancialDetailField
715
- label="Employer"
716
- value={item.companyName || item.jobTitle || "—"}
717
- />
718
- <FinancialDetailField label="Amount" value={item.amountLabel} />
769
+ {/* Primary row: Type | Job Title | Amount */}
770
+ <div className="grid grid-cols-3 gap-x-6">
771
+ <FinancialDetailField label="Type" value={item.incomeType || "—"} />
772
+ <FinancialDetailField
773
+ label="Job Title"
774
+ value={item.jobTitle || "—"}
775
+ />
776
+ <FinancialDetailField label="Amount" value={item.amountLabel} />
777
+ </div>
778
+ {/* Secondary row: Company | Start Date | Status */}
779
+ <div className="grid grid-cols-3 gap-x-6">
780
+ <FinancialDetailField
781
+ label="Company"
782
+ value={item.companyName || "—"}
783
+ />
784
+ <FinancialDetailField
785
+ label="Start Date"
786
+ value={formatDateShort(item.startDate)}
787
+ />
788
+ <FinancialDetailField
789
+ label="Status"
790
+ value={
791
+ item.stillInPosition === undefined
792
+ ? "—"
793
+ : item.stillInPosition
794
+ ? "Still in position"
795
+ : item.endDate
796
+ ? `Ended ${formatDateShort(item.endDate)}`
797
+ : "No longer in position"
798
+ }
799
+ />
800
+ </div>
801
+ {/* Company address — full width if present */}
802
+ {item.companyAddress && (
803
+ <FinancialDetailField
804
+ label="Company Address"
805
+ value={item.companyAddress}
806
+ />
807
+ )}
719
808
  </div>
720
809
  ))}
721
810
  {totalMonthly && (
@@ -30,7 +30,14 @@ import {
30
30
  type ChartGranularity,
31
31
  } from "./chart-shared";
32
32
 
33
- ChartJS.register(CategoryScale, LinearScale, BarController, BarElement, Tooltip, Legend);
33
+ ChartJS.register(
34
+ CategoryScale,
35
+ LinearScale,
36
+ BarController,
37
+ BarElement,
38
+ Tooltip,
39
+ Legend,
40
+ );
34
41
 
35
42
  // ---------------------------------------------------------------------------
36
43
  // Types
@@ -235,7 +242,9 @@ export function IncomeBarChart({
235
242
  style={{ maxWidth: width, fontFamily }}
236
243
  >
237
244
  <CardHeader className="px-3 sm:px-6">
238
- <CardTitle className="text-sm sm:text-base">{title}</CardTitle>
245
+ <CardTitle className="text-xs font-semibold uppercase tracking-wide">
246
+ {title}
247
+ </CardTitle>
239
248
  <CardAction>
240
249
  <div className="flex gap-0.5 sm:gap-1">
241
250
  {periods.map((p) => (
@@ -10,6 +10,8 @@ import {
10
10
  Bot,
11
11
  } from "lucide-react";
12
12
  import { cn } from "@/lib/utils";
13
+ import { formatCurrency } from "@/lib/format-currency";
14
+ import { formatDateShort, formatDateDayMonth } from "@/lib/format-date";
13
15
  import { Badge } from "@/components/ui/badge";
14
16
  import { Button, buttonVariants } from "@/components/ui/button";
15
17
  import { Separator } from "@/components/ui/separator";
@@ -149,36 +151,6 @@ function resolvePriority(
149
151
  return priority;
150
152
  }
151
153
 
152
- function formatAmount(amount: number): string {
153
- return new Intl.NumberFormat("en-AU", {
154
- style: "currency",
155
- currency: "AUD",
156
- maximumFractionDigits: 0,
157
- }).format(amount);
158
- }
159
-
160
- function formatDate(iso: string): string {
161
- try {
162
- return new Date(iso).toLocaleDateString("en-AU", {
163
- day: "2-digit",
164
- month: "short",
165
- year: "numeric",
166
- });
167
- } catch {
168
- return iso;
169
- }
170
- }
171
-
172
- function formatHoldDate(iso: string): string {
173
- try {
174
- return new Date(iso).toLocaleDateString("en-AU", {
175
- day: "2-digit",
176
- month: "short",
177
- });
178
- } catch {
179
- return iso;
180
- }
181
- }
182
154
 
183
155
  function formatLoanType(type: string): string {
184
156
  return type
@@ -249,7 +221,7 @@ export function OpportunityCard({
249
221
  style={{ color: "var(--color-warning-text)" }}
250
222
  >
251
223
  <Clock className="size-3 shrink-0" />
252
- On hold until {formatHoldDate(onHoldTo)}
224
+ On hold until {formatDateDayMonth(onHoldTo)}
253
225
  </div>
254
226
  )}
255
227
 
@@ -272,24 +244,23 @@ export function OpportunityCard({
272
244
  </Badge>
273
245
  )}
274
246
  <span className="text-base font-bold tabular-nums text-foreground">
275
- {formatAmount(amount)}
247
+ {formatCurrency(amount)}
276
248
  </span>
277
249
  </div>
278
250
 
279
251
  <div className="flex items-center gap-1 -mr-1 -mt-1">
280
252
  {onLaunchAssistant && (
281
- <button
253
+ <Button
282
254
  type="button"
283
- className={cn(
284
- buttonVariants({ variant: "ghost", size: "icon" }),
285
- "size-7 shrink-0",
286
- )}
255
+ variant="ghost"
256
+ size="icon"
257
+ className="size-7 shrink-0"
287
258
  onClick={onLaunchAssistant}
288
259
  aria-label="Launch AI Assistant"
289
260
  title="Launch AI Assistant"
290
261
  >
291
262
  <Bot className="size-4" />
292
- </button>
263
+ </Button>
293
264
  )}
294
265
  {hasMenu && (
295
266
  <DropdownMenu>
@@ -372,7 +343,7 @@ export function OpportunityCard({
372
343
  <div className="flex items-center justify-between">
373
344
  <span className="flex items-center gap-1.5 text-xs text-muted-foreground">
374
345
  <Calendar className="size-3 shrink-0" aria-hidden="true" />
375
- {formatDate(date)}
346
+ {formatDateShort(date)}
376
347
  </span>
377
348
 
378
349
  <span className="flex items-center gap-1.5">