@burdenoff/microfe-crewfoundry 2026.626.1 → 2026.703.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 (82) hide show
  1. package/dist/crewfoundry/components/forms/ConfirmDialog.js +43 -0
  2. package/dist/crewfoundry/components/forms/ConfirmDialog.js.map +1 -0
  3. package/dist/crewfoundry/components/forms/FormModal.js +220 -0
  4. package/dist/crewfoundry/components/forms/FormModal.js.map +1 -0
  5. package/dist/crewfoundry/components/forms/formValues.js +20 -0
  6. package/dist/crewfoundry/components/forms/formValues.js.map +1 -0
  7. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +255 -65
  8. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
  9. package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +28 -17
  10. package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
  11. package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +57 -53
  12. package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
  13. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +32 -23
  14. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
  15. package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +44 -29
  16. package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
  17. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +183 -57
  18. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
  19. package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
  20. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +214 -92
  21. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
  22. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +165 -131
  23. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
  24. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +163 -133
  25. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
  26. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +269 -54
  27. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
  28. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +225 -78
  29. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
  30. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +213 -59
  31. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
  32. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +287 -90
  33. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
  34. package/dist/crewfoundry/pages/HiringJobsPagePage.js +49 -47
  35. package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
  36. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +166 -59
  37. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
  38. package/dist/crewfoundry/pages/HrEmployeesPagePage.js +274 -83
  39. package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
  40. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +198 -88
  41. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
  42. package/dist/crewfoundry/pages/HrPayrollPagePage.js +216 -88
  43. package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
  44. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +216 -66
  45. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
  46. package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +6 -7
  47. package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
  48. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +83 -68
  49. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
  50. package/dist/crewfoundry/pages/LearningCoursesPagePage.js +167 -46
  51. package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
  52. package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
  53. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +75 -55
  54. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
  55. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +152 -79
  56. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
  57. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +75 -63
  58. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
  59. package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +3 -1
  60. package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
  61. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
  62. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +235 -87
  63. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
  64. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +199 -86
  65. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
  66. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
  67. package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +21 -40
  68. package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
  69. package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +117 -45
  70. package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
  71. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +249 -90
  72. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
  73. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +47 -45
  74. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
  75. package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
  76. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +262 -133
  77. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
  78. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +144 -77
  79. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
  80. package/dist/crewfoundry/store/crewfoundryStore.js +306 -51
  81. package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
  82. package/package.json +1 -1
@@ -1,215 +1,343 @@
1
1
  import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
2
- import { useState as t } from "react";
3
- import { CheckCircle as n, Clock as r, DollarSign as i, Download as a, Play as o, TrendingUp as s } from "lucide-react";
4
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
5
- import { Badge as u, Button as d, Card as f, CardContent as p, CardDescription as m, CardHeader as h, CardTitle as g, GlassCard as _, GradientText as v, PagePurpose as y, Separator as b } from "@burdenoff/fe-libs/ui";
2
+ import { FormModal as t, useFormModal as n } from "../components/forms/FormModal.js";
3
+ import { getNumber as r, getText as i, newClientId as a } from "../components/forms/formValues.js";
4
+ import { useMemo as o, useState as s } from "react";
5
+ import { CheckCircle as c, Clock as l, DollarSign as u, Download as d, Plus as f, TrendingUp as p } from "lucide-react";
6
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
7
+ import { Badge as g, Button as _, Card as v, CardContent as y, CardDescription as b, CardHeader as x, CardTitle as S, GlassCard as C, GradientText as w, PagePurpose as T, Separator as E } from "@burdenoff/fe-libs/ui";
8
+ import { useGlobalUi as D } from "@burdenoff/fe-libs/shared/providers/shell";
6
9
  //#region src/crewfoundry/pages/HrPayrollPagePage.tsx
7
- function x() {
8
- let { payrollRecords: x, employees: S } = e(), [C, w] = t("January 2026"), T = x.filter((e) => e.period === C), E = T.reduce((e, t) => e + t.grossPay, 0);
9
- T.reduce((e, t) => e + t.deductions, 0);
10
- let D = T.reduce((e, t) => e + t.netPay, 0), O = T.filter((e) => e.status === "paid").length, k = T.filter((e) => e.status === "processing").length, A = [...new Set(x.map((e) => e.period))];
11
- return /* @__PURE__ */ l("div", {
10
+ var O = [
11
+ {
12
+ label: "Draft",
13
+ value: "draft"
14
+ },
15
+ {
16
+ label: "Processing",
17
+ value: "processing"
18
+ },
19
+ {
20
+ label: "Approved",
21
+ value: "approved"
22
+ },
23
+ {
24
+ label: "Paid",
25
+ value: "paid"
26
+ },
27
+ {
28
+ label: "Failed",
29
+ value: "failed"
30
+ }
31
+ ];
32
+ function k() {
33
+ let { payrollRecords: k, employees: A, addPayrollRecord: j, updatePayrollRecord: M } = e(), { showToast: N } = D(), [P, F] = s("January 2026"), I = n(), L = o(() => A.map((e) => ({
34
+ label: `${e.firstName} ${e.lastName}`,
35
+ value: e.id
36
+ })), [A]), R = o(() => [
37
+ {
38
+ name: "employeeId",
39
+ label: "Employee",
40
+ type: "select",
41
+ required: !0,
42
+ options: L,
43
+ colSpan: 2
44
+ },
45
+ {
46
+ name: "period",
47
+ label: "Pay period",
48
+ type: "text",
49
+ required: !0,
50
+ placeholder: "e.g. February 2026"
51
+ },
52
+ {
53
+ name: "paymentMethod",
54
+ label: "Payment method",
55
+ type: "text",
56
+ required: !0,
57
+ placeholder: "e.g. Bank Transfer"
58
+ },
59
+ {
60
+ name: "grossPay",
61
+ label: "Gross pay",
62
+ type: "number",
63
+ required: !0
64
+ },
65
+ {
66
+ name: "deductions",
67
+ label: "Deductions",
68
+ type: "number",
69
+ required: !0
70
+ },
71
+ {
72
+ name: "netPay",
73
+ label: "Net pay (auto if blank)",
74
+ type: "number"
75
+ },
76
+ {
77
+ name: "payDate",
78
+ label: "Pay date",
79
+ type: "date"
80
+ },
81
+ {
82
+ name: "status",
83
+ label: "Status",
84
+ type: "select",
85
+ options: O
86
+ }
87
+ ], [L]), z = k.filter((e) => e.period === P), B = z.reduce((e, t) => e + t.grossPay, 0), V = z.reduce((e, t) => e + t.netPay, 0), H = z.filter((e) => e.status === "paid").length, U = z.filter((e) => e.status === "processing").length, W = [...new Set(k.map((e) => e.period))], G = async (e) => {
88
+ let t = i(e, "employeeId"), n = A.find((e) => e.id === t), o = r(e, "grossPay"), s = r(e, "deductions"), c = r(e, "netPay");
89
+ await j({
90
+ id: a(),
91
+ employeeId: t,
92
+ employeeName: n ? `${n.firstName} ${n.lastName}` : "",
93
+ department: n?.department ?? "",
94
+ period: i(e, "period"),
95
+ grossPay: o,
96
+ deductions: s,
97
+ netPay: c > 0 ? c : Math.max(o - s, 0),
98
+ status: i(e, "status") || "draft",
99
+ payDate: i(e, "payDate"),
100
+ paymentMethod: i(e, "paymentMethod")
101
+ });
102
+ }, K = async (e) => {
103
+ try {
104
+ await M(e.id, {
105
+ status: "paid",
106
+ payDate: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
107
+ });
108
+ } catch (e) {
109
+ N(e instanceof Error ? e.message : "Unable to update payroll record", "error");
110
+ }
111
+ };
112
+ return /* @__PURE__ */ h("div", {
12
113
  className: "space-y-6 p-6",
13
114
  children: [
14
- /* @__PURE__ */ l("div", {
115
+ /* @__PURE__ */ h("div", {
15
116
  className: "flex items-center justify-between",
16
- children: [/* @__PURE__ */ l("div", { children: [
17
- /* @__PURE__ */ c("h1", {
117
+ children: [/* @__PURE__ */ h("div", { children: [
118
+ /* @__PURE__ */ m("h1", {
18
119
  className: "text-2xl font-semibold",
19
- children: /* @__PURE__ */ c(v, { children: "Payroll Management" })
120
+ children: /* @__PURE__ */ m(w, { children: "Payroll Management" })
20
121
  }),
21
- /* @__PURE__ */ c("p", {
122
+ /* @__PURE__ */ m("p", {
22
123
  className: "text-sm text-text-secondary",
23
124
  children: "Process and manage employee payroll"
24
125
  }),
25
- /* @__PURE__ */ c(y, {
126
+ /* @__PURE__ */ m(T, {
26
127
  className: "mt-1",
27
128
  children: "Run and review payroll — track salaries, deductions, and pay runs so your team gets paid accurately and on time."
28
129
  })
29
- ] }), /* @__PURE__ */ l("div", {
130
+ ] }), /* @__PURE__ */ h("div", {
30
131
  className: "flex gap-2",
31
- children: [/* @__PURE__ */ l(d, {
132
+ children: [/* @__PURE__ */ h(_, {
32
133
  variant: "outline",
33
134
  size: "sm",
34
- children: [/* @__PURE__ */ c(a, { className: "h-4 w-4 mr-1" }), "Export"]
35
- }), /* @__PURE__ */ l(d, {
135
+ disabled: !0,
136
+ "aria-label": "Export payroll (coming soon)",
137
+ title: "Payroll export is coming soon",
138
+ children: [
139
+ /* @__PURE__ */ m(d, { className: "h-4 w-4 mr-1" }),
140
+ "Export",
141
+ /* @__PURE__ */ m(g, {
142
+ variant: "secondary",
143
+ className: "ml-1 text-[9px]",
144
+ children: "Soon"
145
+ })
146
+ ]
147
+ }), /* @__PURE__ */ h(_, {
36
148
  size: "sm",
37
- children: [/* @__PURE__ */ c(o, { className: "h-4 w-4 mr-1" }), "Run Payroll"]
149
+ onClick: () => I.openModal(),
150
+ children: [/* @__PURE__ */ m(f, { className: "h-4 w-4 mr-1" }), "Add Record"]
38
151
  })]
39
152
  })]
40
153
  }),
41
- /* @__PURE__ */ l("div", {
154
+ /* @__PURE__ */ h("div", {
42
155
  className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
43
156
  children: [
44
- /* @__PURE__ */ l(_, {
157
+ /* @__PURE__ */ h(C, {
45
158
  treatment: "glass",
46
159
  glow: !0,
47
160
  className: "border-border-seam",
48
- children: [/* @__PURE__ */ l(h, {
161
+ children: [/* @__PURE__ */ h(x, {
49
162
  className: "flex flex-row items-center justify-between space-y-0 pb-2",
50
- children: [/* @__PURE__ */ c(g, {
163
+ children: [/* @__PURE__ */ m(S, {
51
164
  className: "text-sm font-medium",
52
165
  children: "Gross Payroll"
53
- }), /* @__PURE__ */ c(i, { className: "h-4 w-4 text-text-secondary" })]
54
- }), /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ l("div", {
166
+ }), /* @__PURE__ */ m(u, { className: "h-4 w-4 text-text-secondary" })]
167
+ }), /* @__PURE__ */ h(y, { children: [/* @__PURE__ */ h("div", {
55
168
  className: "text-2xl font-bold tabular-nums",
56
- children: ["$", E.toLocaleString()]
57
- }), /* @__PURE__ */ c("p", {
169
+ children: ["$", B.toLocaleString()]
170
+ }), /* @__PURE__ */ m("p", {
58
171
  className: "text-xs text-text-secondary",
59
- children: C
172
+ children: P
60
173
  })] })]
61
174
  }),
62
- /* @__PURE__ */ l(_, {
175
+ /* @__PURE__ */ h(C, {
63
176
  treatment: "metric",
64
177
  className: "border-border-seam",
65
- children: [/* @__PURE__ */ l(h, {
178
+ children: [/* @__PURE__ */ h(x, {
66
179
  className: "flex flex-row items-center justify-between space-y-0 pb-2",
67
- children: [/* @__PURE__ */ c(g, {
180
+ children: [/* @__PURE__ */ m(S, {
68
181
  className: "text-sm font-medium",
69
182
  children: "Net Payroll"
70
- }), /* @__PURE__ */ c(s, { className: "h-4 w-4 text-text-secondary" })]
71
- }), /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ l("div", {
183
+ }), /* @__PURE__ */ m(p, { className: "h-4 w-4 text-text-secondary" })]
184
+ }), /* @__PURE__ */ h(y, { children: [/* @__PURE__ */ h("div", {
72
185
  className: "text-2xl font-bold tabular-nums",
73
- children: ["$", D.toLocaleString()]
74
- }), /* @__PURE__ */ c("p", {
186
+ children: ["$", V.toLocaleString()]
187
+ }), /* @__PURE__ */ m("p", {
75
188
  className: "text-xs text-text-secondary",
76
189
  children: "After deductions"
77
190
  })] })]
78
191
  }),
79
- /* @__PURE__ */ l(_, {
192
+ /* @__PURE__ */ h(C, {
80
193
  treatment: "metric",
81
194
  className: "border-border-seam",
82
- children: [/* @__PURE__ */ l(h, {
195
+ children: [/* @__PURE__ */ h(x, {
83
196
  className: "flex flex-row items-center justify-between space-y-0 pb-2",
84
- children: [/* @__PURE__ */ c(g, {
197
+ children: [/* @__PURE__ */ m(S, {
85
198
  className: "text-sm font-medium",
86
199
  children: "Paid"
87
- }), /* @__PURE__ */ c(n, { className: "h-4 w-4 text-status-success-text" })]
88
- }), /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ c("div", {
200
+ }), /* @__PURE__ */ m(c, { className: "h-4 w-4 text-status-success-text" })]
201
+ }), /* @__PURE__ */ h(y, { children: [/* @__PURE__ */ m("div", {
89
202
  className: "text-2xl font-bold tabular-nums",
90
- children: O
91
- }), /* @__PURE__ */ c("p", {
203
+ children: H
204
+ }), /* @__PURE__ */ m("p", {
92
205
  className: "text-xs text-text-secondary",
93
206
  children: "employees paid"
94
207
  })] })]
95
208
  }),
96
- /* @__PURE__ */ l(_, {
209
+ /* @__PURE__ */ h(C, {
97
210
  treatment: "metric",
98
211
  className: "border-border-seam",
99
- children: [/* @__PURE__ */ l(h, {
212
+ children: [/* @__PURE__ */ h(x, {
100
213
  className: "flex flex-row items-center justify-between space-y-0 pb-2",
101
- children: [/* @__PURE__ */ c(g, {
214
+ children: [/* @__PURE__ */ m(S, {
102
215
  className: "text-sm font-medium",
103
216
  children: "Processing"
104
- }), /* @__PURE__ */ c(r, { className: "h-4 w-4 text-status-warning-text" })]
105
- }), /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ c("div", {
217
+ }), /* @__PURE__ */ m(l, { className: "h-4 w-4 text-status-warning-text" })]
218
+ }), /* @__PURE__ */ h(y, { children: [/* @__PURE__ */ m("div", {
106
219
  className: "text-2xl font-bold tabular-nums",
107
- children: k
108
- }), /* @__PURE__ */ c("p", {
220
+ children: U
221
+ }), /* @__PURE__ */ m("p", {
109
222
  className: "text-xs text-text-secondary",
110
223
  children: "in progress"
111
224
  })] })]
112
225
  })
113
226
  ]
114
227
  }),
115
- /* @__PURE__ */ c("div", {
228
+ /* @__PURE__ */ m("div", {
116
229
  className: "flex gap-2",
117
- children: A.map((e) => /* @__PURE__ */ c(d, {
118
- variant: C === e ? "default" : "outline",
230
+ children: W.map((e) => /* @__PURE__ */ m(_, {
231
+ variant: P === e ? "default" : "outline",
119
232
  size: "sm",
120
- onClick: () => w(e),
233
+ onClick: () => F(e),
121
234
  children: e
122
235
  }, e))
123
236
  }),
124
- /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l(h, { children: [/* @__PURE__ */ c(g, { children: "Payroll Records" }), /* @__PURE__ */ l(m, { children: ["Individual employee payroll details for ", C] })] }), /* @__PURE__ */ l(p, { children: [
125
- /* @__PURE__ */ l("div", {
237
+ /* @__PURE__ */ h(v, { children: [/* @__PURE__ */ h(x, { children: [/* @__PURE__ */ m(S, { children: "Payroll Records" }), /* @__PURE__ */ h(b, { children: ["Individual employee payroll details for ", P] })] }), /* @__PURE__ */ h(y, { children: [
238
+ /* @__PURE__ */ h("div", {
126
239
  className: "grid grid-cols-7 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2",
127
240
  children: [
128
- /* @__PURE__ */ c("span", { children: "Employee" }),
129
- /* @__PURE__ */ c("span", { children: "Department" }),
130
- /* @__PURE__ */ c("span", {
241
+ /* @__PURE__ */ m("span", { children: "Employee" }),
242
+ /* @__PURE__ */ m("span", { children: "Department" }),
243
+ /* @__PURE__ */ m("span", {
131
244
  className: "text-right",
132
245
  children: "Gross Pay"
133
246
  }),
134
- /* @__PURE__ */ c("span", {
247
+ /* @__PURE__ */ m("span", {
135
248
  className: "text-right",
136
249
  children: "Deductions"
137
250
  }),
138
- /* @__PURE__ */ c("span", {
251
+ /* @__PURE__ */ m("span", {
139
252
  className: "text-right",
140
253
  children: "Net Pay"
141
254
  }),
142
- /* @__PURE__ */ c("span", { children: "Payment Method" }),
143
- /* @__PURE__ */ c("span", {
255
+ /* @__PURE__ */ m("span", { children: "Payment Method" }),
256
+ /* @__PURE__ */ m("span", {
144
257
  className: "text-center",
145
258
  children: "Status"
146
259
  })
147
260
  ]
148
261
  }),
149
- x.map((e) => /* @__PURE__ */ l("div", {
262
+ k.map((e) => /* @__PURE__ */ h("div", {
150
263
  className: "grid grid-cols-7 gap-2 py-2 border-b last:border-0 text-sm",
151
264
  children: [
152
- /* @__PURE__ */ c("span", {
265
+ /* @__PURE__ */ m("span", {
153
266
  className: "font-medium",
154
267
  children: e.employeeName
155
268
  }),
156
- /* @__PURE__ */ c("span", {
269
+ /* @__PURE__ */ m("span", {
157
270
  className: "text-text-secondary",
158
271
  children: e.department
159
272
  }),
160
- /* @__PURE__ */ l("span", {
273
+ /* @__PURE__ */ h("span", {
161
274
  className: "text-right",
162
275
  children: ["$", e.grossPay.toLocaleString()]
163
276
  }),
164
- /* @__PURE__ */ l("span", {
277
+ /* @__PURE__ */ h("span", {
165
278
  className: "text-right text-status-error-text",
166
279
  children: ["-$", e.deductions.toLocaleString()]
167
280
  }),
168
- /* @__PURE__ */ l("span", {
281
+ /* @__PURE__ */ h("span", {
169
282
  className: "text-right font-medium",
170
283
  children: ["$", e.netPay.toLocaleString()]
171
284
  }),
172
- /* @__PURE__ */ c("span", {
285
+ /* @__PURE__ */ m("span", {
173
286
  className: "text-text-secondary",
174
287
  children: e.paymentMethod
175
288
  }),
176
- /* @__PURE__ */ c("div", {
177
- className: "text-center",
178
- children: /* @__PURE__ */ c(u, {
289
+ /* @__PURE__ */ h("div", {
290
+ className: "flex flex-col items-center gap-1",
291
+ children: [/* @__PURE__ */ m(g, {
179
292
  variant: e.status === "paid" ? "default" : e.status === "processing" ? "secondary" : "outline",
180
293
  className: "text-[10px]",
181
294
  children: e.status
182
- })
295
+ }), e.status !== "paid" && /* @__PURE__ */ m(_, {
296
+ variant: "ghost",
297
+ size: "sm",
298
+ className: "h-6 px-2 text-[10px]",
299
+ onClick: () => K(e),
300
+ children: "Mark paid"
301
+ })]
183
302
  })
184
303
  ]
185
304
  }, e.id)),
186
- /* @__PURE__ */ c(b, { className: "my-2" }),
187
- /* @__PURE__ */ l("div", {
305
+ /* @__PURE__ */ m(E, { className: "my-2" }),
306
+ /* @__PURE__ */ h("div", {
188
307
  className: "grid grid-cols-7 gap-2 text-sm font-bold",
189
308
  children: [
190
- /* @__PURE__ */ c("span", { children: "Total" }),
191
- /* @__PURE__ */ c("span", {}),
192
- /* @__PURE__ */ l("span", {
309
+ /* @__PURE__ */ m("span", { children: "Total" }),
310
+ /* @__PURE__ */ m("span", {}),
311
+ /* @__PURE__ */ h("span", {
193
312
  className: "text-right",
194
- children: ["$", x.reduce((e, t) => e + t.grossPay, 0).toLocaleString()]
313
+ children: ["$", k.reduce((e, t) => e + t.grossPay, 0).toLocaleString()]
195
314
  }),
196
- /* @__PURE__ */ l("span", {
315
+ /* @__PURE__ */ h("span", {
197
316
  className: "text-right text-status-error-text",
198
- children: ["-$", x.reduce((e, t) => e + t.deductions, 0).toLocaleString()]
317
+ children: ["-$", k.reduce((e, t) => e + t.deductions, 0).toLocaleString()]
199
318
  }),
200
- /* @__PURE__ */ l("span", {
319
+ /* @__PURE__ */ h("span", {
201
320
  className: "text-right",
202
- children: ["$", x.reduce((e, t) => e + t.netPay, 0).toLocaleString()]
321
+ children: ["$", k.reduce((e, t) => e + t.netPay, 0).toLocaleString()]
203
322
  }),
204
- /* @__PURE__ */ c("span", {}),
205
- /* @__PURE__ */ c("span", {})
323
+ /* @__PURE__ */ m("span", {}),
324
+ /* @__PURE__ */ m("span", {})
206
325
  ]
207
326
  })
208
- ] })] })
327
+ ] })] }),
328
+ /* @__PURE__ */ m(t, {
329
+ open: I.open,
330
+ onOpenChange: I.onOpenChange,
331
+ title: "Add payroll record",
332
+ description: "Create a payroll entry for a team member.",
333
+ fields: R,
334
+ submitLabel: "Add record",
335
+ onSubmit: G
336
+ })
209
337
  ]
210
338
  });
211
339
  }
212
340
  //#endregion
213
- export { x as HrPayrollPagePage };
341
+ export { k as HrPayrollPagePage };
214
342
 
215
343
  //# sourceMappingURL=HrPayrollPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HrPayrollPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HrPayrollPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport { CheckCircle, Clock, DollarSign, Download, FileText, Play, TrendingUp } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function HrPayrollPagePage() {\n const { payrollRecords, employees } = useCrewFoundryStore();\n const [selectedPeriod, setSelectedPeriod] = useState('January 2026');\n\n const periodRecords = payrollRecords.filter((r) => r.period === selectedPeriod);\n const totalGross = periodRecords.reduce((s, r) => s + r.grossPay, 0);\n const totalDeductions = periodRecords.reduce((s, r) => s + r.deductions, 0);\n const totalNet = periodRecords.reduce((s, r) => s + r.netPay, 0);\n const paidCount = periodRecords.filter((r) => r.status === 'paid').length;\n const processingCount = periodRecords.filter((r) => r.status === 'processing').length;\n\n const periods = [...new Set(payrollRecords.map((r) => r.period))];\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>Payroll Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Process and manage employee payroll</p>\n <PagePurpose className=\"mt-1\">Run and review payroll — track salaries, deductions, and pay runs so your team gets paid accurately and on time.</PagePurpose>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"h-4 w-4 mr-1\" />\n Export\n </Button>\n <Button size=\"sm\">\n <Play className=\"h-4 w-4 mr-1\" />\n Run Payroll\n </Button>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Gross Payroll</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${totalGross.toLocaleString()}</div>\n <p className=\"text-xs text-text-secondary\">{selectedPeriod}</p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Net Payroll</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${totalNet.toLocaleString()}</div>\n <p className=\"text-xs text-text-secondary\">After deductions</p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Paid</CardTitle>\n <CheckCircle className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{paidCount}</div>\n <p className=\"text-xs text-text-secondary\">employees paid</p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Processing</CardTitle>\n <Clock className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{processingCount}</div>\n <p className=\"text-xs text-text-secondary\">in progress</p>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"flex gap-2\">\n {periods.map((period) => (\n <Button\n key={period}\n variant={selectedPeriod === period ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedPeriod(period)}\n >\n {period}\n </Button>\n ))}\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Payroll Records</CardTitle>\n <CardDescription>\n Individual employee payroll details for {selectedPeriod}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-7 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Employee</span>\n <span>Department</span>\n <span className=\"text-right\">Gross Pay</span>\n <span className=\"text-right\">Deductions</span>\n <span className=\"text-right\">Net Pay</span>\n <span>Payment Method</span>\n <span className=\"text-center\">Status</span>\n </div>\n {payrollRecords.map((record) => (\n <div\n key={record.id}\n className=\"grid grid-cols-7 gap-2 py-2 border-b last:border-0 text-sm\"\n >\n <span className=\"font-medium\">{record.employeeName}</span>\n <span className=\"text-text-secondary\">{record.department}</span>\n <span className=\"text-right\">${record.grossPay.toLocaleString()}</span>\n <span className=\"text-right text-status-error-text\">\n -${record.deductions.toLocaleString()}\n </span>\n <span className=\"text-right font-medium\">${record.netPay.toLocaleString()}</span>\n <span className=\"text-text-secondary\">{record.paymentMethod}</span>\n <div className=\"text-center\">\n <Badge\n variant={\n record.status === 'paid'\n ? 'default'\n : record.status === 'processing'\n ? 'secondary'\n : 'outline'\n }\n className=\"text-[10px]\"\n >\n {record.status}\n </Badge>\n </div>\n </div>\n ))}\n <Separator className=\"my-2\" />\n <div className=\"grid grid-cols-7 gap-2 text-sm font-bold\">\n <span>Total</span>\n <span />\n <span className=\"text-right\">\n ${payrollRecords.reduce((s, r) => s + r.grossPay, 0).toLocaleString()}\n </span>\n <span className=\"text-right text-status-error-text\">\n -${payrollRecords.reduce((s, r) => s + r.deductions, 0).toLocaleString()}\n </span>\n <span className=\"text-right\">\n ${payrollRecords.reduce((s, r) => s + r.netPay, 0).toLocaleString()}\n </span>\n <span />\n <span />\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"HrPayrollPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HrPayrollPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { CheckCircle, Clock, DollarSign, Download, Plus, TrendingUp } from 'lucide-react';\nimport { useCrewFoundryStore, type PayrollRecord } from '../store/crewfoundryStore';\nimport { FormModal, useFormModal, type FieldConfig, type FormValues } from '../components/forms/FormModal';\nimport { getNumber, getText, newClientId } from '../components/forms/formValues';\n\nconst STATUS_OPTIONS = [\n { label: 'Draft', value: 'draft' },\n { label: 'Processing', value: 'processing' },\n { label: 'Approved', value: 'approved' },\n { label: 'Paid', value: 'paid' },\n { label: 'Failed', value: 'failed' },\n];\n\nexport function HrPayrollPagePage() {\n const { payrollRecords, employees, addPayrollRecord, updatePayrollRecord } = useCrewFoundryStore();\n const { showToast } = useGlobalUi();\n const [selectedPeriod, setSelectedPeriod] = useState('January 2026');\n const createForm = useFormModal<void>();\n\n const employeeOptions = useMemo(\n () =>\n employees.map((employee) => ({\n label: `${employee.firstName} ${employee.lastName}`,\n value: employee.id,\n })),\n [employees]\n );\n\n const payrollFields = useMemo<FieldConfig[]>(\n () => [\n {\n name: 'employeeId',\n label: 'Employee',\n type: 'select',\n required: true,\n options: employeeOptions,\n colSpan: 2,\n },\n { name: 'period', label: 'Pay period', type: 'text', required: true, placeholder: 'e.g. February 2026' },\n { name: 'paymentMethod', label: 'Payment method', type: 'text', required: true, placeholder: 'e.g. Bank Transfer' },\n { name: 'grossPay', label: 'Gross pay', type: 'number', required: true },\n { name: 'deductions', label: 'Deductions', type: 'number', required: true },\n { name: 'netPay', label: 'Net pay (auto if blank)', type: 'number' },\n { name: 'payDate', label: 'Pay date', type: 'date' },\n { name: 'status', label: 'Status', type: 'select', options: STATUS_OPTIONS },\n ],\n [employeeOptions]\n );\n\n const periodRecords = payrollRecords.filter((r) => r.period === selectedPeriod);\n const totalGross = periodRecords.reduce((s, r) => s + r.grossPay, 0);\n const totalNet = periodRecords.reduce((s, r) => s + r.netPay, 0);\n const paidCount = periodRecords.filter((r) => r.status === 'paid').length;\n const processingCount = periodRecords.filter((r) => r.status === 'processing').length;\n\n const periods = [...new Set(payrollRecords.map((r) => r.period))];\n\n const handleCreate = async (values: FormValues) => {\n const employeeId = getText(values, 'employeeId');\n const employee = employees.find((item) => item.id === employeeId);\n const grossPay = getNumber(values, 'grossPay');\n const deductions = getNumber(values, 'deductions');\n const netPayInput = getNumber(values, 'netPay');\n const payload: PayrollRecord = {\n id: newClientId(),\n employeeId,\n employeeName: employee ? `${employee.firstName} ${employee.lastName}` : '',\n department: employee?.department ?? '',\n period: getText(values, 'period'),\n grossPay,\n deductions,\n netPay: netPayInput > 0 ? netPayInput : Math.max(grossPay - deductions, 0),\n status: (getText(values, 'status') as PayrollRecord['status']) || 'draft',\n payDate: getText(values, 'payDate'),\n paymentMethod: getText(values, 'paymentMethod'),\n };\n await addPayrollRecord(payload);\n };\n\n const handleMarkPaid = async (record: PayrollRecord) => {\n try {\n await updatePayrollRecord(record.id, {\n status: 'paid',\n payDate: new Date().toISOString().slice(0, 10),\n });\n } catch (error) {\n showToast(error instanceof Error ? error.message : 'Unable to update payroll record', 'error');\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>Payroll Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Process and manage employee payroll</p>\n <PagePurpose className=\"mt-1\">Run and review payroll — track salaries, deductions, and pay runs so your team gets paid accurately and on time.</PagePurpose>\n </div>\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled\n aria-label=\"Export payroll (coming soon)\"\n title=\"Payroll export is coming soon\"\n >\n <Download className=\"h-4 w-4 mr-1\" />\n Export\n <Badge variant=\"secondary\" className=\"ml-1 text-[9px]\">\n Soon\n </Badge>\n </Button>\n <Button size=\"sm\" onClick={() => createForm.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Record\n </Button>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Gross Payroll</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${totalGross.toLocaleString()}</div>\n <p className=\"text-xs text-text-secondary\">{selectedPeriod}</p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Net Payroll</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${totalNet.toLocaleString()}</div>\n <p className=\"text-xs text-text-secondary\">After deductions</p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Paid</CardTitle>\n <CheckCircle className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{paidCount}</div>\n <p className=\"text-xs text-text-secondary\">employees paid</p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Processing</CardTitle>\n <Clock className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{processingCount}</div>\n <p className=\"text-xs text-text-secondary\">in progress</p>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"flex gap-2\">\n {periods.map((period) => (\n <Button\n key={period}\n variant={selectedPeriod === period ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedPeriod(period)}\n >\n {period}\n </Button>\n ))}\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Payroll Records</CardTitle>\n <CardDescription>\n Individual employee payroll details for {selectedPeriod}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-7 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Employee</span>\n <span>Department</span>\n <span className=\"text-right\">Gross Pay</span>\n <span className=\"text-right\">Deductions</span>\n <span className=\"text-right\">Net Pay</span>\n <span>Payment Method</span>\n <span className=\"text-center\">Status</span>\n </div>\n {payrollRecords.map((record) => (\n <div\n key={record.id}\n className=\"grid grid-cols-7 gap-2 py-2 border-b last:border-0 text-sm\"\n >\n <span className=\"font-medium\">{record.employeeName}</span>\n <span className=\"text-text-secondary\">{record.department}</span>\n <span className=\"text-right\">${record.grossPay.toLocaleString()}</span>\n <span className=\"text-right text-status-error-text\">\n -${record.deductions.toLocaleString()}\n </span>\n <span className=\"text-right font-medium\">${record.netPay.toLocaleString()}</span>\n <span className=\"text-text-secondary\">{record.paymentMethod}</span>\n <div className=\"flex flex-col items-center gap-1\">\n <Badge\n variant={\n record.status === 'paid'\n ? 'default'\n : record.status === 'processing'\n ? 'secondary'\n : 'outline'\n }\n className=\"text-[10px]\"\n >\n {record.status}\n </Badge>\n {record.status !== 'paid' && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 px-2 text-[10px]\"\n onClick={() => handleMarkPaid(record)}\n >\n Mark paid\n </Button>\n )}\n </div>\n </div>\n ))}\n <Separator className=\"my-2\" />\n <div className=\"grid grid-cols-7 gap-2 text-sm font-bold\">\n <span>Total</span>\n <span />\n <span className=\"text-right\">\n ${payrollRecords.reduce((s, r) => s + r.grossPay, 0).toLocaleString()}\n </span>\n <span className=\"text-right text-status-error-text\">\n -${payrollRecords.reduce((s, r) => s + r.deductions, 0).toLocaleString()}\n </span>\n <span className=\"text-right\">\n ${payrollRecords.reduce((s, r) => s + r.netPay, 0).toLocaleString()}\n </span>\n <span />\n <span />\n </div>\n </CardContent>\n </Card>\n\n <FormModal\n open={createForm.open}\n onOpenChange={createForm.onOpenChange}\n title=\"Add payroll record\"\n description=\"Create a payroll entry for a team member.\"\n fields={payrollFields}\n submitLabel=\"Add record\"\n onSubmit={handleCreate}\n />\n </div>\n );\n}\n"],"mappings":"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"}