@burdenoff/microfe-crewfoundry 2026.704.6 → 2026.707.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.
Files changed (150) hide show
  1. package/dist/crewfoundry/CrewFoundryRoutes.js +51 -43
  2. package/dist/crewfoundry/CrewFoundryRoutes.js.map +1 -1
  3. package/dist/crewfoundry/components/forms/formValues.js +5 -2
  4. package/dist/crewfoundry/components/forms/formValues.js.map +1 -1
  5. package/dist/crewfoundry/components/viz/AllocationBar.js +68 -0
  6. package/dist/crewfoundry/components/viz/AllocationBar.js.map +1 -0
  7. package/dist/crewfoundry/components/viz/AreaChart.js +102 -0
  8. package/dist/crewfoundry/components/viz/AreaChart.js.map +1 -0
  9. package/dist/crewfoundry/components/viz/AvatarStack.js +36 -0
  10. package/dist/crewfoundry/components/viz/AvatarStack.js.map +1 -0
  11. package/dist/crewfoundry/components/viz/BarChart.js +83 -0
  12. package/dist/crewfoundry/components/viz/BarChart.js.map +1 -0
  13. package/dist/crewfoundry/components/viz/CertificateCard.js +118 -0
  14. package/dist/crewfoundry/components/viz/CertificateCard.js.map +1 -0
  15. package/dist/crewfoundry/components/viz/DonutChart.js +109 -0
  16. package/dist/crewfoundry/components/viz/DonutChart.js.map +1 -0
  17. package/dist/crewfoundry/components/viz/HBarFunnel.js +54 -0
  18. package/dist/crewfoundry/components/viz/HBarFunnel.js.map +1 -0
  19. package/dist/crewfoundry/components/viz/Heatmap.js +91 -0
  20. package/dist/crewfoundry/components/viz/Heatmap.js.map +1 -0
  21. package/dist/crewfoundry/components/viz/KanbanBoard.js +50 -0
  22. package/dist/crewfoundry/components/viz/KanbanBoard.js.map +1 -0
  23. package/dist/crewfoundry/components/viz/LineChart.js +123 -0
  24. package/dist/crewfoundry/components/viz/LineChart.js.map +1 -0
  25. package/dist/crewfoundry/components/viz/OrgTree.js +83 -0
  26. package/dist/crewfoundry/components/viz/OrgTree.js.map +1 -0
  27. package/dist/crewfoundry/components/viz/PathSteps.js +68 -0
  28. package/dist/crewfoundry/components/viz/PathSteps.js.map +1 -0
  29. package/dist/crewfoundry/components/viz/ProgressRing.js +68 -0
  30. package/dist/crewfoundry/components/viz/ProgressRing.js.map +1 -0
  31. package/dist/crewfoundry/components/viz/RatingStars.js +51 -0
  32. package/dist/crewfoundry/components/viz/RatingStars.js.map +1 -0
  33. package/dist/crewfoundry/components/viz/SegmentedTabs.js +69 -0
  34. package/dist/crewfoundry/components/viz/SegmentedTabs.js.map +1 -0
  35. package/dist/crewfoundry/components/viz/SkillBar.js +3 -0
  36. package/dist/crewfoundry/components/viz/Sparkline.js +74 -0
  37. package/dist/crewfoundry/components/viz/Sparkline.js.map +1 -0
  38. package/dist/crewfoundry/components/viz/StatCard.js +60 -0
  39. package/dist/crewfoundry/components/viz/StatCard.js.map +1 -0
  40. package/dist/crewfoundry/components/viz/StepProgress.js +3 -0
  41. package/dist/crewfoundry/components/viz/Timeline.js +66 -0
  42. package/dist/crewfoundry/components/viz/Timeline.js.map +1 -0
  43. package/dist/crewfoundry/components/viz/index.js +23 -0
  44. package/dist/crewfoundry/components/viz/lib/Avatar.js +30 -0
  45. package/dist/crewfoundry/components/viz/lib/Avatar.js.map +1 -0
  46. package/dist/crewfoundry/components/viz/lib/CartesianFrame.js +119 -0
  47. package/dist/crewfoundry/components/viz/lib/CartesianFrame.js.map +1 -0
  48. package/dist/crewfoundry/components/viz/lib/ResponsiveSvg.js +35 -0
  49. package/dist/crewfoundry/components/viz/lib/ResponsiveSvg.js.map +1 -0
  50. package/dist/crewfoundry/components/viz/lib/format.js +21 -0
  51. package/dist/crewfoundry/components/viz/lib/format.js.map +1 -0
  52. package/dist/crewfoundry/components/viz/lib/geometry.js +69 -0
  53. package/dist/crewfoundry/components/viz/lib/geometry.js.map +1 -0
  54. package/dist/crewfoundry/components/viz/lib/hooks.js +39 -0
  55. package/dist/crewfoundry/components/viz/lib/hooks.js.map +1 -0
  56. package/dist/crewfoundry/components/viz/lib/palette.js +27 -0
  57. package/dist/crewfoundry/components/viz/lib/palette.js.map +1 -0
  58. package/dist/crewfoundry/lib/analytics.js +323 -0
  59. package/dist/crewfoundry/lib/analytics.js.map +1 -0
  60. package/dist/crewfoundry/lib/companyFinance.js +16 -0
  61. package/dist/crewfoundry/lib/companyFinance.js.map +1 -0
  62. package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +226 -283
  63. package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
  64. package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +107 -120
  65. package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
  66. package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +122 -162
  67. package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
  68. package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +121 -158
  69. package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
  70. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +316 -211
  71. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
  72. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +75 -27
  73. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
  74. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +167 -165
  75. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
  76. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +168 -109
  77. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
  78. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +401 -290
  79. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
  80. package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +0 -41
  81. package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
  82. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +84 -75
  83. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
  84. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +368 -174
  85. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
  86. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +236 -201
  87. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
  88. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +369 -196
  89. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
  90. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +269 -270
  91. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
  92. package/dist/crewfoundry/pages/HiringJobsPagePage.js +210 -110
  93. package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
  94. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +216 -178
  95. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
  96. package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.js +385 -0
  97. package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.js.map +1 -0
  98. package/dist/crewfoundry/pages/HrEmployeesPagePage.js +189 -130
  99. package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
  100. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +397 -241
  101. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
  102. package/dist/crewfoundry/pages/HrPayrollPagePage.js +262 -147
  103. package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
  104. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +345 -167
  105. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
  106. package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +98 -24
  107. package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
  108. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +1 -1
  109. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
  110. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +289 -108
  111. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
  112. package/dist/crewfoundry/pages/LearningCoursesPagePage.js +221 -114
  113. package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
  114. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +134 -135
  115. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
  116. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +148 -97
  117. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
  118. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +264 -157
  119. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
  120. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +85 -93
  121. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
  122. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +211 -122
  123. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
  124. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +94 -54
  125. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
  126. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +289 -140
  127. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
  128. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +169 -79
  129. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
  130. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +296 -125
  131. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
  132. package/dist/crewfoundry/pages/ProjectsResourcingPagePage.js +187 -0
  133. package/dist/crewfoundry/pages/ProjectsResourcingPagePage.js.map +1 -0
  134. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +140 -78
  135. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
  136. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +93 -43
  137. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
  138. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +250 -98
  139. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
  140. package/dist/crewfoundry/store/crewfoundryStore.js +142 -184
  141. package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
  142. package/dist/crewfoundry/utils/cn.js +10 -0
  143. package/dist/crewfoundry/utils/cn.js.map +1 -0
  144. package/dist/crewfoundry/utils/courseProgress.js +46 -0
  145. package/dist/crewfoundry/utils/courseProgress.js.map +1 -0
  146. package/dist/node_modules/clsx/dist/clsx.js +18 -0
  147. package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
  148. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
  149. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  150. package/package.json +1 -1
@@ -1,12 +1,17 @@
1
1
  import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
2
2
  import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
3
- import { FormModal as n, useFormModal as r } from "../components/forms/FormModal.js";
4
- import { CheckCircle2 as i, Pencil as a, Plus as o } from "lucide-react";
5
- import { jsx as s, jsxs as c } from "react/jsx-runtime";
6
- import { Badge as l, Button as u, CardContent as d, GlassCard as f, GradientText as p, IllustratedEmptyState as m, PagePurpose as h, Pagination as g, ResponsiveTable as _ } from "@burdenoff/fe-libs/ui";
7
- import { usePagination as v } from "@burdenoff/fe-libs/shared/hooks";
3
+ import { AreaChart as n } from "../components/viz/AreaChart.js";
4
+ import { StatCard as r } from "../components/viz/StatCard.js";
5
+ import "../components/viz/index.js";
6
+ import { revenueTrend as i } from "../lib/analytics.js";
7
+ import { FormModal as ee, useFormModal as a } from "../components/forms/FormModal.js";
8
+ import { useState as o } from "react";
9
+ import { CheckCircle2 as s, MoreHorizontal as c, Pencil as l, Plus as u, Trash2 as d } from "lucide-react";
10
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
11
+ import { AlertDialog as m, AlertDialogAction as te, AlertDialogCancel as ne, AlertDialogContent as re, AlertDialogDescription as h, AlertDialogFooter as g, AlertDialogHeader as _, AlertDialogTitle as v, Badge as ie, Button as y, CardContent as ae, CardHeader as oe, CardTitle as b, DropdownMenu as x, DropdownMenuContent as S, DropdownMenuItem as C, DropdownMenuSeparator as w, DropdownMenuTrigger as T, GlassCard as E, GradientText as D, IllustratedEmptyState as O, PagePurpose as k, Pagination as A, ResponsiveTable as j } from "@burdenoff/fe-libs/ui";
12
+ import { usePagination as M } from "@burdenoff/fe-libs/shared/hooks";
8
13
  //#region src/crewfoundry/pages/PaymentsInvoicesPagePage.tsx
9
- var y = [
14
+ var N = [
10
15
  {
11
16
  name: "number",
12
17
  label: "Invoice number",
@@ -71,7 +76,7 @@ var y = [
71
76
  colSpan: 2,
72
77
  placeholder: "e.g. Consulting services"
73
78
  }
74
- ], b = (e) => ({
79
+ ], P = (e) => ({
75
80
  number: e.number,
76
81
  clientName: e.clientName,
77
82
  amount: e.amount,
@@ -79,7 +84,7 @@ var y = [
79
84
  issueDate: e.issueDate ? e.issueDate.slice(0, 10) : "",
80
85
  dueDate: e.dueDate ? e.dueDate.slice(0, 10) : "",
81
86
  lineItem: e.items[0]?.description ?? ""
82
- }), x = (e, t) => {
87
+ }), F = (e, t) => {
83
88
  let n = typeof e.amount == "number" ? e.amount : Number(e.amount) || 0, r = String(e.lineItem ?? "").trim() || "Services rendered";
84
89
  return {
85
90
  id: t?.id ?? crypto.randomUUID(),
@@ -94,48 +99,98 @@ var y = [
94
99
  amount: n
95
100
  }]
96
101
  };
97
- }, S = (e) => e === "paid" ? "default" : e === "overdue" ? "destructive" : e === "draft" ? "outline" : "secondary";
98
- function C() {
99
- let { invoices: C, addInvoice: w, updateInvoice: T } = e(), E = r(), { page: D, pageSize: O, offset: k, setPage: A } = v({ initialPageSize: 25 }), j = [...C].sort((e, t) => (t.issueDate ?? "").localeCompare(e.issueDate ?? "")), M = j.slice(k, k + O);
100
- return /* @__PURE__ */ c("div", {
102
+ }, I = (e) => e === "paid" ? "default" : e === "overdue" ? "destructive" : e === "draft" ? "outline" : "secondary", L = (e) => `$${Math.round(e).toLocaleString()}`;
103
+ function R() {
104
+ let { invoices: R, addInvoice: se, updateInvoice: z, removeInvoice: B } = e(), V = a(), { page: H, pageSize: U, offset: W, setPage: G } = M({ initialPageSize: 25 }), [K, q] = o(null), [J, Y] = o(!1), X = [...R].sort((e, t) => (t.issueDate ?? "").localeCompare(e.issueDate ?? "")), ce = X.slice(W, W + U), Z = R.filter((e) => e.status !== "cancelled").reduce((e, t) => e + t.amount, 0), Q = R.filter((e) => e.status === "paid").reduce((e, t) => e + t.amount, 0), le = R.filter((e) => e.status === "overdue").reduce((e, t) => e + t.amount, 0), ue = Math.max(Z - Q, 0), $ = i(R), de = async (e) => {
105
+ V.context ? await z(V.context.id, F(e, V.context)) : await se(F(e));
106
+ }, fe = async () => {
107
+ if (K) {
108
+ Y(!0);
109
+ try {
110
+ await B(K.id), q(null);
111
+ } finally {
112
+ Y(!1);
113
+ }
114
+ }
115
+ };
116
+ return /* @__PURE__ */ p("div", {
101
117
  className: "space-y-6 p-6",
102
118
  children: [
103
- /* @__PURE__ */ c("div", {
119
+ /* @__PURE__ */ p("div", {
104
120
  className: "flex items-center justify-between",
105
- children: [/* @__PURE__ */ c("div", { children: [
106
- /* @__PURE__ */ s("h1", {
121
+ children: [/* @__PURE__ */ p("div", { children: [
122
+ /* @__PURE__ */ f("h1", {
107
123
  className: "text-2xl font-semibold",
108
- children: /* @__PURE__ */ s(p, { children: "Invoices" })
124
+ children: /* @__PURE__ */ f(D, { children: "Invoices" })
109
125
  }),
110
- /* @__PURE__ */ c("p", {
126
+ /* @__PURE__ */ p("p", {
111
127
  className: "text-sm text-text-secondary",
112
- children: [C.length, " invoices"]
128
+ children: [R.length, " invoices"]
113
129
  }),
114
- /* @__PURE__ */ s(h, {
130
+ /* @__PURE__ */ f(k, {
115
131
  className: "mt-1",
116
132
  children: "Create, send, and track invoices — see what's paid, pending, or overdue so you stay on top of getting paid."
117
133
  })
118
- ] }), /* @__PURE__ */ c(u, {
134
+ ] }), /* @__PURE__ */ p(y, {
119
135
  size: "sm",
120
- onClick: () => E.openModal(),
121
- children: [/* @__PURE__ */ s(o, { className: "h-4 w-4 mr-1" }), "Create Invoice"]
136
+ onClick: () => V.openModal(),
137
+ children: [/* @__PURE__ */ f(u, { className: "h-4 w-4 mr-1" }), "Create Invoice"]
122
138
  })]
123
139
  }),
124
- /* @__PURE__ */ s(f, {
140
+ /* @__PURE__ */ p("div", {
141
+ className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-5",
142
+ children: [
143
+ /* @__PURE__ */ f(r, {
144
+ label: "Total Billed",
145
+ value: L(Z)
146
+ }),
147
+ /* @__PURE__ */ f(r, {
148
+ label: "Paid",
149
+ value: L(Q)
150
+ }),
151
+ /* @__PURE__ */ f(r, {
152
+ label: "Outstanding",
153
+ value: L(ue)
154
+ }),
155
+ /* @__PURE__ */ f(r, {
156
+ label: "Overdue",
157
+ value: /* @__PURE__ */ f("span", {
158
+ className: "text-status-error-text",
159
+ children: L(le)
160
+ })
161
+ }),
162
+ /* @__PURE__ */ p("div", {
163
+ className: "flex flex-col gap-2 rounded-[var(--radius-card)] border border-border-subtle bg-bg-surface p-5 shadow-elevation-1 sm:col-span-2 xl:col-span-1",
164
+ children: [/* @__PURE__ */ f("span", {
165
+ className: "text-sm font-medium text-text-secondary",
166
+ children: "Revenue trend"
167
+ }), $.length > 1 ? /* @__PURE__ */ f(n, {
168
+ series: $,
169
+ height: 96,
170
+ valueFormatter: (e) => L(e),
171
+ title: "Recognised revenue from paid invoices by month"
172
+ }) : /* @__PURE__ */ f("p", {
173
+ className: "flex flex-1 items-center text-xs text-text-muted",
174
+ children: "Revenue trend appears once paid invoices span more than one month."
175
+ })]
176
+ })
177
+ ]
178
+ }),
179
+ /* @__PURE__ */ p(E, {
125
180
  treatment: "glass",
126
181
  glow: !0,
127
182
  className: "border-border-seam",
128
- children: /* @__PURE__ */ c(d, {
129
- className: "p-4",
130
- children: [/* @__PURE__ */ s(_, {
131
- data: M,
183
+ children: [/* @__PURE__ */ f(oe, { children: /* @__PURE__ */ f(b, { children: "Invoices" }) }), /* @__PURE__ */ p(ae, {
184
+ className: "p-4 pt-0",
185
+ children: [/* @__PURE__ */ f(j, {
186
+ data: ce,
132
187
  rowKey: (e) => e.id,
133
188
  columns: [
134
189
  {
135
190
  key: "number",
136
191
  header: "Invoice #",
137
192
  priority: "primary",
138
- cell: (e) => /* @__PURE__ */ s("span", {
193
+ cell: (e) => /* @__PURE__ */ f("span", {
139
194
  className: "font-medium",
140
195
  children: e.number
141
196
  })
@@ -144,18 +199,27 @@ function C() {
144
199
  key: "client",
145
200
  header: "Client",
146
201
  priority: "secondary",
147
- cell: (e) => /* @__PURE__ */ s("span", {
202
+ cell: (e) => /* @__PURE__ */ f("span", {
148
203
  className: "text-text-secondary",
149
204
  children: e.clientName
150
205
  })
151
206
  },
152
207
  {
153
- key: "items",
154
- header: "Items",
208
+ key: "issueDate",
209
+ header: "Issue Date",
155
210
  priority: "hidden-on-mobile",
156
- cell: (e) => /* @__PURE__ */ s("span", {
157
- className: "text-xs text-text-secondary",
158
- children: e.items.map((e) => e.description).join(", ")
211
+ cell: (e) => /* @__PURE__ */ f("span", {
212
+ className: "text-text-secondary",
213
+ children: e.issueDate || "—"
214
+ })
215
+ },
216
+ {
217
+ key: "dueDate",
218
+ header: "Due Date",
219
+ priority: "secondary",
220
+ cell: (e) => /* @__PURE__ */ f("span", {
221
+ className: "text-text-secondary",
222
+ children: e.dueDate || "—"
159
223
  })
160
224
  },
161
225
  {
@@ -164,82 +228,108 @@ function C() {
164
228
  priority: "secondary",
165
229
  headerClassName: "text-right",
166
230
  cellClassName: "text-right",
167
- cell: (e) => /* @__PURE__ */ c("span", {
168
- className: "font-medium",
231
+ cell: (e) => /* @__PURE__ */ p("span", {
232
+ className: "font-medium tabular-nums",
169
233
  children: ["$", e.amount.toLocaleString()]
170
234
  })
171
235
  },
172
- {
173
- key: "dueDate",
174
- header: "Due Date",
175
- priority: "secondary",
176
- cell: (e) => /* @__PURE__ */ s("span", {
177
- className: "text-text-secondary",
178
- children: e.dueDate
179
- })
180
- },
181
236
  {
182
237
  key: "status",
183
238
  header: "Status",
184
239
  priority: "secondary",
185
- cell: (e) => /* @__PURE__ */ s(l, {
186
- variant: S(e.status),
240
+ cell: (e) => /* @__PURE__ */ f(ie, {
241
+ variant: I(e.status),
187
242
  className: "text-[10px]",
188
243
  children: t(e.status)
189
244
  })
190
245
  }
191
246
  ],
192
- emptyState: /* @__PURE__ */ s(m, {
247
+ emptyState: /* @__PURE__ */ f(O, {
193
248
  illustration: "empty-data",
194
249
  title: "No invoices yet",
195
250
  description: "Create your first invoice to start getting paid."
196
251
  }),
197
- rowActions: (e) => /* @__PURE__ */ c("div", {
252
+ rowActions: (e) => /* @__PURE__ */ p("div", {
198
253
  className: "flex items-center justify-end gap-1",
199
- children: [/* @__PURE__ */ s(u, {
200
- variant: "ghost",
201
- size: "sm",
202
- "aria-label": `Edit invoice ${e.number}`,
203
- onClick: () => E.openModal(e),
204
- children: /* @__PURE__ */ s(a, { className: "h-3.5 w-3.5" })
205
- }), e.status === "paid" ? /* @__PURE__ */ c("span", {
254
+ children: [e.status === "paid" ? /* @__PURE__ */ p("span", {
206
255
  className: "inline-flex items-center gap-1 text-xs text-status-success-text",
207
- children: [/* @__PURE__ */ s(i, { className: "h-3.5 w-3.5" }), "Paid"]
208
- }) : /* @__PURE__ */ c(u, {
256
+ children: [/* @__PURE__ */ f(s, { className: "h-3.5 w-3.5" }), "Paid"]
257
+ }) : /* @__PURE__ */ p(y, {
209
258
  variant: "outline",
210
259
  size: "sm",
211
260
  "aria-label": `Mark invoice ${e.number} as paid`,
212
- onClick: () => void T(e.id, { status: "paid" }),
213
- children: [/* @__PURE__ */ s(i, { className: "h-3.5 w-3.5 mr-1" }), "Mark Paid"]
214
- })]
261
+ onClick: () => void z(e.id, { status: "paid" }),
262
+ children: [/* @__PURE__ */ f(s, { className: "h-3.5 w-3.5 mr-1" }), "Mark Paid"]
263
+ }), /* @__PURE__ */ p(x, { children: [/* @__PURE__ */ f(T, {
264
+ asChild: !0,
265
+ children: /* @__PURE__ */ f(y, {
266
+ variant: "ghost",
267
+ size: "icon",
268
+ className: "h-8 w-8",
269
+ "aria-label": `More actions for invoice ${e.number}`,
270
+ children: /* @__PURE__ */ f(c, { className: "h-4 w-4" })
271
+ })
272
+ }), /* @__PURE__ */ p(S, {
273
+ align: "end",
274
+ children: [
275
+ /* @__PURE__ */ p(C, {
276
+ onSelect: () => V.openModal(e),
277
+ children: [/* @__PURE__ */ f(l, { className: "mr-2 h-4 w-4" }), "Edit"]
278
+ }),
279
+ e.status !== "paid" && /* @__PURE__ */ p(C, {
280
+ onSelect: () => void z(e.id, { status: "paid" }),
281
+ children: [/* @__PURE__ */ f(s, { className: "mr-2 h-4 w-4" }), "Mark as paid"]
282
+ }),
283
+ /* @__PURE__ */ f(w, {}),
284
+ /* @__PURE__ */ p(C, {
285
+ className: "text-status-error-text",
286
+ onSelect: () => q(e),
287
+ children: [/* @__PURE__ */ f(d, { className: "mr-2 h-4 w-4" }), "Delete"]
288
+ })
289
+ ]
290
+ })] })]
215
291
  })
216
- }), j.length > O && /* @__PURE__ */ s("div", {
292
+ }), X.length > U && /* @__PURE__ */ f("div", {
217
293
  className: "mt-4",
218
- children: /* @__PURE__ */ s(g, {
219
- page: D,
220
- pageSize: O,
221
- totalItems: j.length,
222
- onPageChange: A
294
+ children: /* @__PURE__ */ f(A, {
295
+ page: H,
296
+ pageSize: U,
297
+ totalItems: X.length,
298
+ onPageChange: G
223
299
  })
224
300
  })]
225
- })
301
+ })]
226
302
  }),
227
- /* @__PURE__ */ s(n, {
228
- open: E.open,
229
- onOpenChange: E.onOpenChange,
230
- title: E.context ? "Edit invoice" : "Create invoice",
303
+ /* @__PURE__ */ f(ee, {
304
+ open: V.open,
305
+ onOpenChange: V.onOpenChange,
306
+ title: V.context ? "Edit invoice" : "Create invoice",
231
307
  description: "Issue a new invoice to a client and track its payment status.",
232
- fields: y,
233
- initialValues: E.context ? b(E.context) : void 0,
234
- submitLabel: E.context ? "Save changes" : "Create invoice",
235
- onSubmit: async (e) => {
236
- E.context ? await T(E.context.id, x(e, E.context)) : await w(x(e));
237
- }
308
+ fields: N,
309
+ initialValues: V.context ? P(V.context) : void 0,
310
+ submitLabel: V.context ? "Save changes" : "Create invoice",
311
+ onSubmit: de
312
+ }),
313
+ /* @__PURE__ */ f(m, {
314
+ open: K !== null,
315
+ onOpenChange: (e) => {
316
+ e || q(null);
317
+ },
318
+ children: /* @__PURE__ */ p(re, { children: [/* @__PURE__ */ p(_, { children: [/* @__PURE__ */ f(v, { children: "Delete invoice?" }), /* @__PURE__ */ f(h, { children: K ? `Invoice ${K.number} will be permanently removed. This cannot be undone.` : "" })] }), /* @__PURE__ */ p(g, { children: [/* @__PURE__ */ f(ne, {
319
+ disabled: J,
320
+ children: "Cancel"
321
+ }), /* @__PURE__ */ f(te, {
322
+ onClick: (e) => {
323
+ e.preventDefault(), fe();
324
+ },
325
+ disabled: J,
326
+ children: J ? "Deleting…" : "Delete"
327
+ })] })] })
238
328
  })
239
329
  ]
240
330
  });
241
331
  }
242
332
  //#endregion
243
- export { C as PaymentsInvoicesPagePage };
333
+ export { R as PaymentsInvoicesPagePage };
244
334
 
245
335
  //# sourceMappingURL=PaymentsInvoicesPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PaymentsInvoicesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/PaymentsInvoicesPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n CardContent,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n Pagination,\n ResponsiveTable,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { CheckCircle2, Pencil, Plus } from 'lucide-react';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Invoice } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nconst INVOICE_FIELDS: FieldConfig[] = [\n {\n name: 'number',\n label: 'Invoice number',\n type: 'text',\n required: true,\n placeholder: 'INV-0001',\n },\n { name: 'clientName', label: 'Client name', type: 'text', required: true },\n { name: 'amount', label: 'Amount (USD)', type: 'number', required: true },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n options: [\n { label: 'Draft', value: 'draft' },\n { label: 'Sent', value: 'sent' },\n { label: 'Paid', value: 'paid' },\n { label: 'Overdue', value: 'overdue' },\n { label: 'Cancelled', value: 'cancelled' },\n ],\n },\n { name: 'issueDate', label: 'Issue date', type: 'date', required: true },\n { name: 'dueDate', label: 'Due date', type: 'date' },\n {\n name: 'lineItem',\n label: 'Line item description',\n type: 'text',\n colSpan: 2,\n placeholder: 'e.g. Consulting services',\n },\n];\n\nconst toInitialValues = (invoice: Invoice): FormValues => ({\n number: invoice.number,\n clientName: invoice.clientName,\n amount: invoice.amount,\n status: invoice.status,\n issueDate: invoice.issueDate ? invoice.issueDate.slice(0, 10) : '',\n dueDate: invoice.dueDate ? invoice.dueDate.slice(0, 10) : '',\n lineItem: invoice.items[0]?.description ?? '',\n});\n\nconst valuesToInvoice = (values: FormValues, base?: Invoice): Invoice => {\n const amount = typeof values.amount === 'number' ? values.amount : Number(values.amount) || 0;\n const description = String(values.lineItem ?? '').trim() || 'Services rendered';\n return {\n id: base?.id ?? crypto.randomUUID(),\n number: String(values.number ?? ''),\n clientName: String(values.clientName ?? ''),\n amount,\n status: (values.status as Invoice['status']) || 'draft',\n issueDate: String(values.issueDate ?? ''),\n dueDate: String(values.dueDate ?? ''),\n items: [{ description, amount }],\n };\n};\n\nconst statusVariant = (status: Invoice['status']) =>\n status === 'paid'\n ? 'default'\n : status === 'overdue'\n ? 'destructive'\n : status === 'draft'\n ? 'outline'\n : 'secondary';\n\nexport function PaymentsInvoicesPagePage() {\n const { invoices, addInvoice, updateInvoice } = useCrewFoundryStore();\n const modal = useFormModal<Invoice>();\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 25 });\n\n const sorted = [...invoices].sort((a, b) => (b.issueDate ?? '').localeCompare(a.issueDate ?? ''));\n const paged = sorted.slice(offset, offset + pageSize);\n\n const handleSubmit = async (values: FormValues) => {\n if (modal.context) {\n await updateInvoice(modal.context.id, valuesToInvoice(values, modal.context));\n } else {\n await addInvoice(valuesToInvoice(values));\n }\n };\n\n const columns: ResponsiveTableColumn<Invoice>[] = [\n {\n key: 'number',\n header: 'Invoice #',\n priority: 'primary',\n cell: (inv) => <span className=\"font-medium\">{inv.number}</span>,\n },\n {\n key: 'client',\n header: 'Client',\n priority: 'secondary',\n cell: (inv) => <span className=\"text-text-secondary\">{inv.clientName}</span>,\n },\n {\n key: 'items',\n header: 'Items',\n priority: 'hidden-on-mobile',\n cell: (inv) => (\n <span className=\"text-xs text-text-secondary\">\n {inv.items.map((i) => i.description).join(', ')}\n </span>\n ),\n },\n {\n key: 'amount',\n header: 'Amount',\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (inv) => <span className=\"font-medium\">${inv.amount.toLocaleString()}</span>,\n },\n {\n key: 'dueDate',\n header: 'Due Date',\n priority: 'secondary',\n cell: (inv) => <span className=\"text-text-secondary\">{inv.dueDate}</span>,\n },\n {\n key: 'status',\n header: 'Status',\n priority: 'secondary',\n cell: (inv) => (\n <Badge variant={statusVariant(inv.status)} className=\"text-[10px]\">\n {formatEnumLabel(inv.status)}\n </Badge>\n ),\n },\n ];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Invoices</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{invoices.length} invoices</p>\n <PagePurpose className=\"mt-1\">\n Create, send, and track invoices — see what&apos;s paid, pending, or overdue so you stay\n on top of getting paid.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => modal.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Create Invoice\n </Button>\n </div>\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardContent className=\"p-4\">\n <ResponsiveTable\n data={paged}\n rowKey={(inv) => inv.id}\n columns={columns}\n emptyState={\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No invoices yet\"\n description=\"Create your first invoice to start getting paid.\"\n />\n }\n rowActions={(inv) => (\n <div className=\"flex items-center justify-end gap-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label={`Edit invoice ${inv.number}`}\n onClick={() => modal.openModal(inv)}\n >\n <Pencil className=\"h-3.5 w-3.5\" />\n </Button>\n {inv.status === 'paid' ? (\n <span className=\"inline-flex items-center gap-1 text-xs text-status-success-text\">\n <CheckCircle2 className=\"h-3.5 w-3.5\" />\n Paid\n </span>\n ) : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n aria-label={`Mark invoice ${inv.number} as paid`}\n onClick={() => void updateInvoice(inv.id, { status: 'paid' })}\n >\n <CheckCircle2 className=\"h-3.5 w-3.5 mr-1\" />\n Mark Paid\n </Button>\n )}\n </div>\n )}\n />\n {sorted.length > pageSize && (\n <div className=\"mt-4\">\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={sorted.length}\n onPageChange={setPage}\n />\n </div>\n )}\n </CardContent>\n </GlassCard>\n\n <FormModal\n open={modal.open}\n onOpenChange={modal.onOpenChange}\n title={modal.context ? 'Edit invoice' : 'Create invoice'}\n description=\"Issue a new invoice to a client and track its payment status.\"\n fields={INVOICE_FIELDS}\n initialValues={modal.context ? toInitialValues(modal.context) : undefined}\n submitLabel={modal.context ? 'Save changes' : 'Create invoice'}\n onSubmit={handleSubmit}\n />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PaymentsInvoicesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/PaymentsInvoicesPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n Badge,\n Button,\n CardContent,\n CardHeader,\n CardTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n Pagination,\n ResponsiveTable,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { CheckCircle2, MoreHorizontal, Pencil, Plus, Trash2 } from 'lucide-react';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Invoice } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\nimport { AreaChart, StatCard } from '../components/viz';\nimport { revenueTrend } from '../lib/analytics';\n\nconst INVOICE_FIELDS: FieldConfig[] = [\n {\n name: 'number',\n label: 'Invoice number',\n type: 'text',\n required: true,\n placeholder: 'INV-0001',\n },\n { name: 'clientName', label: 'Client name', type: 'text', required: true },\n { name: 'amount', label: 'Amount (USD)', type: 'number', required: true },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n options: [\n { label: 'Draft', value: 'draft' },\n { label: 'Sent', value: 'sent' },\n { label: 'Paid', value: 'paid' },\n { label: 'Overdue', value: 'overdue' },\n { label: 'Cancelled', value: 'cancelled' },\n ],\n },\n { name: 'issueDate', label: 'Issue date', type: 'date', required: true },\n { name: 'dueDate', label: 'Due date', type: 'date' },\n {\n name: 'lineItem',\n label: 'Line item description',\n type: 'text',\n colSpan: 2,\n placeholder: 'e.g. Consulting services',\n },\n];\n\nconst toInitialValues = (invoice: Invoice): FormValues => ({\n number: invoice.number,\n clientName: invoice.clientName,\n amount: invoice.amount,\n status: invoice.status,\n issueDate: invoice.issueDate ? invoice.issueDate.slice(0, 10) : '',\n dueDate: invoice.dueDate ? invoice.dueDate.slice(0, 10) : '',\n lineItem: invoice.items[0]?.description ?? '',\n});\n\nconst valuesToInvoice = (values: FormValues, base?: Invoice): Invoice => {\n const amount = typeof values.amount === 'number' ? values.amount : Number(values.amount) || 0;\n const description = String(values.lineItem ?? '').trim() || 'Services rendered';\n return {\n id: base?.id ?? crypto.randomUUID(),\n number: String(values.number ?? ''),\n clientName: String(values.clientName ?? ''),\n amount,\n status: (values.status as Invoice['status']) || 'draft',\n issueDate: String(values.issueDate ?? ''),\n dueDate: String(values.dueDate ?? ''),\n items: [{ description, amount }],\n };\n};\n\nconst statusVariant = (status: Invoice['status']) =>\n status === 'paid'\n ? 'default'\n : status === 'overdue'\n ? 'destructive'\n : status === 'draft'\n ? 'outline'\n : 'secondary';\n\nconst formatMoney = (value: number): string => `$${Math.round(value).toLocaleString()}`;\n\nexport function PaymentsInvoicesPagePage() {\n const { invoices, addInvoice, updateInvoice, removeInvoice } = useCrewFoundryStore();\n const modal = useFormModal<Invoice>();\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 25 });\n const [deleteTarget, setDeleteTarget] = useState<Invoice | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const sorted = [...invoices].sort((a, b) => (b.issueDate ?? '').localeCompare(a.issueDate ?? ''));\n const paged = sorted.slice(offset, offset + pageSize);\n\n // Finance KPIs — all computed from real invoice entities.\n const totalBilled = invoices\n .filter((inv) => inv.status !== 'cancelled')\n .reduce((sum, inv) => sum + inv.amount, 0);\n const totalPaid = invoices\n .filter((inv) => inv.status === 'paid')\n .reduce((sum, inv) => sum + inv.amount, 0);\n const totalOverdue = invoices\n .filter((inv) => inv.status === 'overdue')\n .reduce((sum, inv) => sum + inv.amount, 0);\n const outstanding = Math.max(totalBilled - totalPaid, 0);\n\n const revenueSeries = revenueTrend(invoices);\n\n const handleSubmit = async (values: FormValues) => {\n if (modal.context) {\n await updateInvoice(modal.context.id, valuesToInvoice(values, modal.context));\n } else {\n await addInvoice(valuesToInvoice(values));\n }\n };\n\n const confirmDelete = async () => {\n if (!deleteTarget) {\n return;\n }\n setDeleting(true);\n try {\n await removeInvoice(deleteTarget.id);\n setDeleteTarget(null);\n } finally {\n setDeleting(false);\n }\n };\n\n const columns: ResponsiveTableColumn<Invoice>[] = [\n {\n key: 'number',\n header: 'Invoice #',\n priority: 'primary',\n cell: (inv) => <span className=\"font-medium\">{inv.number}</span>,\n },\n {\n key: 'client',\n header: 'Client',\n priority: 'secondary',\n cell: (inv) => <span className=\"text-text-secondary\">{inv.clientName}</span>,\n },\n {\n key: 'issueDate',\n header: 'Issue Date',\n priority: 'hidden-on-mobile',\n cell: (inv) => <span className=\"text-text-secondary\">{inv.issueDate || '—'}</span>,\n },\n {\n key: 'dueDate',\n header: 'Due Date',\n priority: 'secondary',\n cell: (inv) => <span className=\"text-text-secondary\">{inv.dueDate || '—'}</span>,\n },\n {\n key: 'amount',\n header: 'Amount',\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (inv) => <span className=\"font-medium tabular-nums\">${inv.amount.toLocaleString()}</span>,\n },\n {\n key: 'status',\n header: 'Status',\n priority: 'secondary',\n cell: (inv) => (\n <Badge variant={statusVariant(inv.status)} className=\"text-[10px]\">\n {formatEnumLabel(inv.status)}\n </Badge>\n ),\n },\n ];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Invoices</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{invoices.length} invoices</p>\n <PagePurpose className=\"mt-1\">\n Create, send, and track invoices — see what&apos;s paid, pending, or overdue so you stay\n on top of getting paid.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => modal.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Create Invoice\n </Button>\n </div>\n\n {/* Finance header: 4 KPI tiles + revenue-trend chart */}\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-5\">\n <StatCard label=\"Total Billed\" value={formatMoney(totalBilled)} />\n <StatCard label=\"Paid\" value={formatMoney(totalPaid)} />\n <StatCard label=\"Outstanding\" value={formatMoney(outstanding)} />\n <StatCard\n label=\"Overdue\"\n value={<span className=\"text-status-error-text\">{formatMoney(totalOverdue)}</span>}\n />\n <div className=\"flex flex-col gap-2 rounded-[var(--radius-card)] border border-border-subtle bg-bg-surface p-5 shadow-elevation-1 sm:col-span-2 xl:col-span-1\">\n <span className=\"text-sm font-medium text-text-secondary\">Revenue trend</span>\n {revenueSeries.length > 1 ? (\n <AreaChart\n series={revenueSeries}\n height={96}\n valueFormatter={(value) => formatMoney(value)}\n title=\"Recognised revenue from paid invoices by month\"\n />\n ) : (\n <p className=\"flex flex-1 items-center text-xs text-text-muted\">\n Revenue trend appears once paid invoices span more than one month.\n </p>\n )}\n </div>\n </div>\n\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>Invoices</CardTitle>\n </CardHeader>\n <CardContent className=\"p-4 pt-0\">\n <ResponsiveTable\n data={paged}\n rowKey={(inv) => inv.id}\n columns={columns}\n emptyState={\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No invoices yet\"\n description=\"Create your first invoice to start getting paid.\"\n />\n }\n rowActions={(inv) => (\n <div className=\"flex items-center justify-end gap-1\">\n {inv.status === 'paid' ? (\n <span className=\"inline-flex items-center gap-1 text-xs text-status-success-text\">\n <CheckCircle2 className=\"h-3.5 w-3.5\" />\n Paid\n </span>\n ) : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n aria-label={`Mark invoice ${inv.number} as paid`}\n onClick={() => void updateInvoice(inv.id, { status: 'paid' })}\n >\n <CheckCircle2 className=\"h-3.5 w-3.5 mr-1\" />\n Mark Paid\n </Button>\n )}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n aria-label={`More actions for invoice ${inv.number}`}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onSelect={() => modal.openModal(inv)}>\n <Pencil className=\"mr-2 h-4 w-4\" />\n Edit\n </DropdownMenuItem>\n {inv.status !== 'paid' && (\n <DropdownMenuItem\n onSelect={() => void updateInvoice(inv.id, { status: 'paid' })}\n >\n <CheckCircle2 className=\"mr-2 h-4 w-4\" />\n Mark as paid\n </DropdownMenuItem>\n )}\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"text-status-error-text\"\n onSelect={() => setDeleteTarget(inv)}\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n )}\n />\n {sorted.length > pageSize && (\n <div className=\"mt-4\">\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={sorted.length}\n onPageChange={setPage}\n />\n </div>\n )}\n </CardContent>\n </GlassCard>\n\n <FormModal\n open={modal.open}\n onOpenChange={modal.onOpenChange}\n title={modal.context ? 'Edit invoice' : 'Create invoice'}\n description=\"Issue a new invoice to a client and track its payment status.\"\n fields={INVOICE_FIELDS}\n initialValues={modal.context ? toInitialValues(modal.context) : undefined}\n submitLabel={modal.context ? 'Save changes' : 'Create invoice'}\n onSubmit={handleSubmit}\n />\n\n <AlertDialog\n open={deleteTarget !== null}\n onOpenChange={(open) => {\n if (!open) {\n setDeleteTarget(null);\n }\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete invoice?</AlertDialogTitle>\n <AlertDialogDescription>\n {deleteTarget\n ? `Invoice ${deleteTarget.number} will be permanently removed. This cannot be undone.`\n : ''}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={deleting}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={(event) => {\n event.preventDefault();\n void confirmDelete();\n }}\n disabled={deleting}\n >\n {deleting ? 'Deleting…' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n"],"mappings":"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"}