@burdenoff/microfe-crewfoundry 2026.704.6 → 2026.704.7

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 (148) 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/HiringApplicationsPagePage.js +84 -75
  81. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
  82. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +368 -174
  83. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
  84. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +236 -201
  85. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
  86. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +369 -196
  87. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
  88. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +269 -270
  89. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
  90. package/dist/crewfoundry/pages/HiringJobsPagePage.js +210 -110
  91. package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
  92. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +216 -178
  93. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
  94. package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.js +385 -0
  95. package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.js.map +1 -0
  96. package/dist/crewfoundry/pages/HrEmployeesPagePage.js +189 -130
  97. package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
  98. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +397 -241
  99. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
  100. package/dist/crewfoundry/pages/HrPayrollPagePage.js +262 -147
  101. package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
  102. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +345 -167
  103. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
  104. package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +98 -24
  105. package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
  106. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +1 -1
  107. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
  108. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +289 -108
  109. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
  110. package/dist/crewfoundry/pages/LearningCoursesPagePage.js +221 -114
  111. package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
  112. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +134 -135
  113. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
  114. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +148 -97
  115. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
  116. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +264 -157
  117. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
  118. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +85 -93
  119. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
  120. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +211 -122
  121. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
  122. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +94 -54
  123. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
  124. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +289 -140
  125. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
  126. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +169 -79
  127. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
  128. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +296 -125
  129. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
  130. package/dist/crewfoundry/pages/ProjectsResourcingPagePage.js +187 -0
  131. package/dist/crewfoundry/pages/ProjectsResourcingPagePage.js.map +1 -0
  132. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +140 -78
  133. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
  134. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +93 -43
  135. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
  136. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +250 -98
  137. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
  138. package/dist/crewfoundry/store/crewfoundryStore.js +1 -1
  139. package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
  140. package/dist/crewfoundry/utils/cn.js +10 -0
  141. package/dist/crewfoundry/utils/cn.js.map +1 -0
  142. package/dist/crewfoundry/utils/courseProgress.js +46 -0
  143. package/dist/crewfoundry/utils/courseProgress.js.map +1 -0
  144. package/dist/node_modules/clsx/dist/clsx.js +18 -0
  145. package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
  146. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
  147. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  148. package/package.json +1 -1
@@ -1,14 +1,17 @@
1
1
  import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
2
2
  import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
3
- import { useMemo as n } from "react";
4
- import { DollarSign as r, FileText as i, Receipt as a, TrendingUp as o, Wallet as s } from "lucide-react";
5
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
6
- import { Badge as u, Card as d, CardContent as f, CardDescription as p, CardHeader as m, CardTitle as h, GlassCard as g, GradientText as _, IllustratedEmptyState as v, PagePurpose as y, Pagination as b, ResponsiveTable as x, Separator as S } from "@burdenoff/fe-libs/ui";
7
- import { usePagination as C } from "@burdenoff/fe-libs/shared/hooks";
3
+ import { LineChart as n } from "../components/viz/LineChart.js";
4
+ import { DonutChart as r } from "../components/viz/DonutChart.js";
5
+ import "../components/viz/index.js";
6
+ import { useMemo as i } from "react";
7
+ import { DollarSign as a, FileText as o, Receipt as s, TrendingUp as c, Wallet as l } from "lucide-react";
8
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
9
+ import { Badge as f, Card as p, CardContent as m, CardDescription as h, CardHeader as g, CardTitle as _, GlassCard as v, GradientText as y, IllustratedEmptyState as b, PagePurpose as x, Pagination as S, ResponsiveTable as C, Separator as w } from "@burdenoff/fe-libs/ui";
10
+ import { usePagination as T } from "@burdenoff/fe-libs/shared/hooks";
8
11
  //#region src/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.tsx
9
- function w() {
10
- let { employees: w, departments: T, payrollRecords: E, invoices: D, projects: O } = e(), k = n(() => {
11
- let e = E.reduce((e, t) => {
12
+ function E() {
13
+ let { employees: E, departments: D, payrollRecords: O, invoices: k, projects: A } = e(), j = i(() => {
14
+ let e = O.reduce((e, t) => {
12
15
  let n = new Date(t.payDate).toLocaleString("en-US", { month: "short" }), r = e[n] || {
13
16
  gross: 0,
14
17
  net: 0,
@@ -20,27 +23,27 @@ function w() {
20
23
  month: e,
21
24
  ...t
22
25
  })).slice(-6);
23
- }, [E]), A = n(() => {
26
+ }, [O]), M = i(() => {
24
27
  let e = [
25
28
  {
26
29
  category: "Gross Payroll",
27
- amount: E.reduce((e, t) => e + t.grossPay, 0),
28
- icon: s
30
+ amount: O.reduce((e, t) => e + t.grossPay, 0),
31
+ icon: l
29
32
  },
30
33
  {
31
34
  category: "Deductions",
32
- amount: E.reduce((e, t) => e + t.deductions, 0),
33
- icon: a
35
+ amount: O.reduce((e, t) => e + t.deductions, 0),
36
+ icon: s
34
37
  },
35
38
  {
36
39
  category: "Project Spend",
37
- amount: O.reduce((e, t) => e + t.spent, 0),
38
- icon: o
40
+ amount: A.reduce((e, t) => e + t.spent, 0),
41
+ icon: c
39
42
  },
40
43
  {
41
44
  category: "Collected Invoices",
42
- amount: D.filter((e) => e.status === "paid").reduce((e, t) => e + t.amount, 0),
43
- icon: i
45
+ amount: k.filter((e) => e.status === "paid").reduce((e, t) => e + t.amount, 0),
46
+ icon: o
44
47
  }
45
48
  ], t = e.reduce((e, t) => e + t.amount, 0) || 1;
46
49
  return e.map((e) => ({
@@ -48,247 +51,204 @@ function w() {
48
51
  percentage: Math.round(e.amount / t * 100)
49
52
  }));
50
53
  }, [
51
- D,
52
- E,
53
- O
54
- ]), j = w.reduce((e, t) => e + t.salary, 0), M = Math.round(j / 12), N = D.reduce((e, t) => e + t.amount, 0), P = D.filter((e) => e.status === "paid").reduce((e, t) => e + t.amount, 0), F = O.reduce((e, t) => e + t.budget, 0), I = O.reduce((e, t) => e + t.spent, 0), L = Math.max(1, ...k.map((e) => e.gross)), R = F > 0 ? Math.round(I / F * 100) : 0, z = [...T.map((e) => {
55
- let t = w.filter((t) => t.department === e.name), n = t.reduce((e, t) => e + t.salary, 0);
54
+ k,
55
+ O,
56
+ A
57
+ ]), N = E.reduce((e, t) => e + t.salary, 0), P = Math.round(N / 12), F = k.reduce((e, t) => e + t.amount, 0), I = k.filter((e) => e.status === "paid").reduce((e, t) => e + t.amount, 0), L = A.reduce((e, t) => e + t.budget, 0), R = A.reduce((e, t) => e + t.spent, 0), z = j.map((e) => ({
58
+ label: e.month,
59
+ value: e.gross
60
+ })), B = j.map((e) => e.net), V = M.filter((e) => e.amount > 0).map((e) => ({
61
+ label: e.category,
62
+ value: e.amount
63
+ })), H = L > 0 ? Math.round(R / L * 100) : 0, U = [...D.map((e) => {
64
+ let t = E.filter((t) => t.department === e.name), n = t.reduce((e, t) => e + t.salary, 0);
56
65
  return {
57
66
  name: e.name,
58
67
  salary: n,
59
68
  budget: e.budget,
60
69
  headcount: t.length
61
70
  };
62
- })].sort((e, t) => t.salary - e.salary), B = T.reduce((e, t) => e + t.budget, 0), V = [...D].filter((e) => e.status !== "paid").sort((e, t) => e.dueDate.localeCompare(t.dueDate)), { page: H, pageSize: U, offset: W, setPage: G } = C({ initialPageSize: 6 }), K = V.slice(W, W + U);
63
- return /* @__PURE__ */ l("div", {
71
+ })].sort((e, t) => t.salary - e.salary), W = D.reduce((e, t) => e + t.budget, 0), G = [...k].filter((e) => e.status !== "paid").sort((e, t) => e.dueDate.localeCompare(t.dueDate)), { page: K, pageSize: q, offset: J, setPage: Y } = T({ initialPageSize: 6 }), X = G.slice(J, J + q);
72
+ return /* @__PURE__ */ d("div", {
64
73
  className: "space-y-6 p-6",
65
74
  children: [
66
- /* @__PURE__ */ c("div", {
75
+ /* @__PURE__ */ u("div", {
67
76
  className: "flex items-center justify-between",
68
- children: /* @__PURE__ */ l("div", { children: [
69
- /* @__PURE__ */ c("h1", {
77
+ children: /* @__PURE__ */ d("div", { children: [
78
+ /* @__PURE__ */ u("h1", {
70
79
  className: "text-2xl font-semibold",
71
- children: /* @__PURE__ */ c(_, { children: "Financial Analytics" })
80
+ children: /* @__PURE__ */ u(y, { children: "Financial Analytics" })
72
81
  }),
73
- /* @__PURE__ */ c("p", {
82
+ /* @__PURE__ */ u("p", {
74
83
  className: "text-sm text-text-secondary",
75
84
  children: "Workforce financial metrics and cost analysis"
76
85
  }),
77
- /* @__PURE__ */ c(y, {
86
+ /* @__PURE__ */ u(x, {
78
87
  className: "mt-1",
79
88
  children: "Understand the money side of your workforce — payroll, project budgets, and spend trends — so you can plan headcount and control costs with confidence."
80
89
  })
81
90
  ] })
82
91
  }),
83
- /* @__PURE__ */ l("div", {
92
+ /* @__PURE__ */ d("div", {
84
93
  className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
85
94
  children: [
86
- /* @__PURE__ */ l(g, {
95
+ /* @__PURE__ */ d(v, {
87
96
  treatment: "glass",
88
97
  glow: !0,
89
98
  className: "border-border-seam",
90
- children: [/* @__PURE__ */ l(m, {
99
+ children: [/* @__PURE__ */ d(g, {
91
100
  className: "flex flex-row items-center justify-between space-y-0 pb-2",
92
- children: [/* @__PURE__ */ c(h, {
101
+ children: [/* @__PURE__ */ u(_, {
93
102
  className: "text-sm font-medium",
94
103
  children: "Monthly Payroll"
95
- }), /* @__PURE__ */ c(r, { className: "h-4 w-4 text-text-secondary" })]
96
- }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
104
+ }), /* @__PURE__ */ u(a, { className: "h-4 w-4 text-text-secondary" })]
105
+ }), /* @__PURE__ */ d(m, { children: [/* @__PURE__ */ d("div", {
97
106
  className: "text-2xl font-bold tabular-nums",
98
107
  children: [
99
108
  "$",
100
- (M / 1e3).toFixed(0),
109
+ (P / 1e3).toFixed(0),
101
110
  "K"
102
111
  ]
103
- }), /* @__PURE__ */ c("p", {
112
+ }), /* @__PURE__ */ u("p", {
104
113
  className: "text-xs text-text-secondary",
105
114
  children: "Annual salary ÷ 12 months"
106
115
  })] })]
107
116
  }),
108
- /* @__PURE__ */ l(g, {
117
+ /* @__PURE__ */ d(v, {
109
118
  treatment: "metric",
110
119
  className: "border-border-seam",
111
- children: [/* @__PURE__ */ l(m, {
120
+ children: [/* @__PURE__ */ d(g, {
112
121
  className: "flex flex-row items-center justify-between space-y-0 pb-2",
113
- children: [/* @__PURE__ */ c(h, {
122
+ children: [/* @__PURE__ */ u(_, {
114
123
  className: "text-sm font-medium",
115
124
  children: "Annual Salary Cost"
116
- }), /* @__PURE__ */ c(s, { className: "h-4 w-4 text-text-secondary" })]
117
- }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
125
+ }), /* @__PURE__ */ u(l, { className: "h-4 w-4 text-text-secondary" })]
126
+ }), /* @__PURE__ */ d(m, { children: [/* @__PURE__ */ d("div", {
118
127
  className: "text-2xl font-bold tabular-nums",
119
128
  children: [
120
129
  "$",
121
- (j / 1e6).toFixed(1),
130
+ (N / 1e6).toFixed(1),
122
131
  "M"
123
132
  ]
124
- }), /* @__PURE__ */ l("p", {
133
+ }), /* @__PURE__ */ d("p", {
125
134
  className: "text-xs text-text-secondary",
126
- children: [w.length, " employees"]
135
+ children: [E.length, " employees"]
127
136
  })] })]
128
137
  }),
129
- /* @__PURE__ */ l(g, {
138
+ /* @__PURE__ */ d(v, {
130
139
  treatment: "metric",
131
140
  className: "border-border-seam",
132
- children: [/* @__PURE__ */ l(m, {
141
+ children: [/* @__PURE__ */ d(g, {
133
142
  className: "flex flex-row items-center justify-between space-y-0 pb-2",
134
- children: [/* @__PURE__ */ c(h, {
143
+ children: [/* @__PURE__ */ u(_, {
135
144
  className: "text-sm font-medium",
136
145
  children: "Total Invoiced"
137
- }), /* @__PURE__ */ c(i, { className: "h-4 w-4 text-text-secondary" })]
138
- }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
146
+ }), /* @__PURE__ */ u(o, { className: "h-4 w-4 text-text-secondary" })]
147
+ }), /* @__PURE__ */ d(m, { children: [/* @__PURE__ */ d("div", {
139
148
  className: "text-2xl font-bold tabular-nums",
140
149
  children: [
141
150
  "$",
142
- (N / 1e3).toFixed(1),
151
+ (F / 1e3).toFixed(1),
143
152
  "K"
144
153
  ]
145
- }), /* @__PURE__ */ l("p", {
154
+ }), /* @__PURE__ */ d("p", {
146
155
  className: "text-xs text-text-secondary",
147
156
  children: [
148
157
  "$",
149
- (P / 1e3).toFixed(1),
158
+ (I / 1e3).toFixed(1),
150
159
  "K collected"
151
160
  ]
152
161
  })] })]
153
162
  }),
154
- /* @__PURE__ */ l(g, {
163
+ /* @__PURE__ */ d(v, {
155
164
  treatment: "metric",
156
165
  className: "border-border-seam",
157
- children: [/* @__PURE__ */ l(m, {
166
+ children: [/* @__PURE__ */ d(g, {
158
167
  className: "flex flex-row items-center justify-between space-y-0 pb-2",
159
- children: [/* @__PURE__ */ c(h, {
168
+ children: [/* @__PURE__ */ u(_, {
160
169
  className: "text-sm font-medium",
161
170
  children: "Project Budget"
162
- }), /* @__PURE__ */ c(o, { className: "h-4 w-4 text-text-secondary" })]
163
- }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
171
+ }), /* @__PURE__ */ u(c, { className: "h-4 w-4 text-text-secondary" })]
172
+ }), /* @__PURE__ */ d(m, { children: [/* @__PURE__ */ d("div", {
164
173
  className: "text-2xl font-bold tabular-nums",
165
174
  children: [
166
175
  "$",
167
- (F / 1e6).toFixed(1),
176
+ (L / 1e6).toFixed(1),
168
177
  "M"
169
178
  ]
170
- }), /* @__PURE__ */ l("p", {
179
+ }), /* @__PURE__ */ d("p", {
171
180
  className: "text-xs text-text-secondary",
172
- children: [R, "% utilized"]
181
+ children: [H, "% utilized"]
173
182
  })] })]
174
183
  })
175
184
  ]
176
185
  }),
177
- /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Payroll Trend" }), /* @__PURE__ */ c(p, { children: "Monthly gross payroll over the last 6 months" })] }), /* @__PURE__ */ l(f, {
178
- className: "space-y-3",
179
- children: [k.map((e) => /* @__PURE__ */ l("div", {
180
- className: "flex items-center gap-3",
181
- children: [
182
- /* @__PURE__ */ c("span", {
183
- className: "w-10 text-sm text-text-secondary",
184
- children: e.month
185
- }),
186
- /* @__PURE__ */ l("div", {
187
- className: "flex-1 h-5 bg-bg-sunken rounded overflow-hidden flex",
188
- children: [/* @__PURE__ */ c("div", {
189
- className: "h-5 bg-action-primary-bg",
190
- style: { width: `${Math.round(e.net / L * 100)}%` }
191
- }), /* @__PURE__ */ c("div", {
192
- className: "h-5 bg-action-primary-bg/30",
193
- style: { width: `${Math.round(e.deductions / L * 100)}%` }
194
- })]
195
- }),
196
- /* @__PURE__ */ l("span", {
197
- className: "text-sm font-medium w-20 text-right",
198
- children: [
199
- "$",
200
- (e.gross / 1e6).toFixed(2),
201
- "M"
202
- ]
203
- })
204
- ]
205
- }, e.month)), /* @__PURE__ */ l("div", {
206
- className: "flex items-center gap-4 mt-2 text-xs text-text-secondary",
207
- children: [/* @__PURE__ */ l("div", {
208
- className: "flex items-center gap-1",
209
- children: [/* @__PURE__ */ c("div", { className: "h-3 w-3 bg-action-primary-bg rounded" }), /* @__PURE__ */ c("span", { children: "Net Pay" })]
210
- }), /* @__PURE__ */ l("div", {
211
- className: "flex items-center gap-1",
212
- children: [/* @__PURE__ */ c("div", { className: "h-3 w-3 bg-action-primary-bg/30 rounded" }), /* @__PURE__ */ c("span", { children: "Deductions" })]
213
- })]
214
- })]
215
- })] }),
216
- /* @__PURE__ */ l("div", {
186
+ /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ d(g, { children: [/* @__PURE__ */ u(_, { children: "Payroll Trend" }), /* @__PURE__ */ u(h, { children: "Monthly gross payroll over the last 6 months" })] }), /* @__PURE__ */ u(m, { children: z.length > 0 ? /* @__PURE__ */ u(n, {
187
+ series: z,
188
+ compare: B,
189
+ seriesLabel: "Gross pay",
190
+ compareLabel: "Net pay",
191
+ height: 220,
192
+ valueFormatter: (e) => `$${(e / 1e3).toFixed(0)}K`
193
+ }) : /* @__PURE__ */ u("p", {
194
+ className: "py-6 text-center text-sm text-text-secondary",
195
+ children: "No payroll records yet."
196
+ }) })] }),
197
+ /* @__PURE__ */ d("div", {
217
198
  className: "grid gap-4 md:grid-cols-2",
218
- children: [/* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Spend by Category" }), /* @__PURE__ */ c(p, { children: "Share of tracked workforce spend" })] }), /* @__PURE__ */ c(f, {
219
- className: "space-y-4",
220
- children: A.map((e) => /* @__PURE__ */ l("div", {
221
- className: "space-y-1",
222
- children: [
223
- /* @__PURE__ */ l("div", {
224
- className: "flex justify-between text-sm",
225
- children: [/* @__PURE__ */ l("span", {
226
- className: "flex items-center gap-2 font-medium",
227
- children: [/* @__PURE__ */ c(e.icon, { className: "h-4 w-4 text-text-secondary" }), e.category]
228
- }), /* @__PURE__ */ l("span", { children: [
229
- "$",
230
- (e.amount / 1e3).toFixed(0),
231
- "K"
232
- ] })]
233
- }),
234
- /* @__PURE__ */ c("div", {
235
- className: "h-3 bg-bg-sunken rounded overflow-hidden",
236
- children: /* @__PURE__ */ c("div", {
237
- className: "h-3 rounded bg-action-primary-bg",
238
- style: { width: `${e.percentage}%` }
239
- })
240
- }),
241
- /* @__PURE__ */ l("p", {
242
- className: "text-xs text-text-secondary text-right",
243
- children: [e.percentage, "% of spend"]
244
- })
245
- ]
246
- }, e.category))
247
- })] }), /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Outstanding Invoices" }), /* @__PURE__ */ c(p, { children: "Unpaid invoices requiring attention" })] }), /* @__PURE__ */ l(f, {
199
+ children: [/* @__PURE__ */ d(p, { children: [/* @__PURE__ */ d(g, { children: [/* @__PURE__ */ u(_, { children: "Spend by Category" }), /* @__PURE__ */ u(h, { children: "Share of tracked workforce spend" })] }), /* @__PURE__ */ u(m, { children: V.length > 0 ? /* @__PURE__ */ u(r, {
200
+ segments: V,
201
+ centerLabel: `$${(V.reduce((e, t) => e + t.value, 0) / 1e3).toFixed(0)}K`,
202
+ centerCaption: "Total spend",
203
+ valueFormatter: (e) => `$${(e / 1e3).toFixed(0)}K`
204
+ }) : /* @__PURE__ */ u("p", {
205
+ className: "py-6 text-center text-sm text-text-secondary",
206
+ children: "No tracked spend yet."
207
+ }) })] }), /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ d(g, { children: [/* @__PURE__ */ u(_, { children: "Outstanding Invoices" }), /* @__PURE__ */ u(h, { children: "Unpaid invoices requiring attention" })] }), /* @__PURE__ */ d(m, {
248
208
  className: "space-y-3",
249
209
  children: [
250
- V.length === 0 && /* @__PURE__ */ c(v, {
210
+ G.length === 0 && /* @__PURE__ */ u(b, {
251
211
  illustration: "empty-data",
252
212
  title: "No outstanding invoices",
253
213
  description: "Every invoice has been paid. New unpaid invoices will appear here."
254
214
  }),
255
- K.map((e) => /* @__PURE__ */ l("div", {
215
+ X.map((e) => /* @__PURE__ */ d("div", {
256
216
  className: "flex items-center justify-between rounded border p-3",
257
- children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
217
+ children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
258
218
  className: "text-sm font-medium",
259
219
  children: e.number
260
- }), /* @__PURE__ */ c("p", {
220
+ }), /* @__PURE__ */ u("p", {
261
221
  className: "text-xs text-text-secondary",
262
222
  children: e.clientName
263
- })] }), /* @__PURE__ */ l("div", {
223
+ })] }), /* @__PURE__ */ d("div", {
264
224
  className: "text-right",
265
- children: [/* @__PURE__ */ l("p", {
225
+ children: [/* @__PURE__ */ d("p", {
266
226
  className: "text-sm font-medium",
267
227
  children: ["$", e.amount.toLocaleString()]
268
- }), /* @__PURE__ */ c(u, {
228
+ }), /* @__PURE__ */ u(f, {
269
229
  variant: e.status === "overdue" ? "destructive" : "secondary",
270
230
  className: "text-[10px]",
271
231
  children: t(e.status)
272
232
  })]
273
233
  })]
274
234
  }, e.id)),
275
- V.length > U && /* @__PURE__ */ c(b, {
276
- page: H,
277
- pageSize: U,
278
- totalItems: V.length,
279
- onPageChange: G
235
+ G.length > q && /* @__PURE__ */ u(S, {
236
+ page: K,
237
+ pageSize: q,
238
+ totalItems: G.length,
239
+ onPageChange: Y
280
240
  })
281
241
  ]
282
242
  })] })]
283
243
  }),
284
- /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Department Cost Analysis" }), /* @__PURE__ */ c(p, { children: "Total salary cost and budget allocation by department" })] }), /* @__PURE__ */ l(f, { children: [
285
- /* @__PURE__ */ c(x, {
244
+ /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ d(g, { children: [/* @__PURE__ */ u(_, { children: "Department Cost Analysis" }), /* @__PURE__ */ u(h, { children: "Total salary cost and budget allocation by department" })] }), /* @__PURE__ */ d(m, { children: [
245
+ /* @__PURE__ */ u(C, {
286
246
  columns: [
287
247
  {
288
248
  key: "name",
289
249
  header: "Department",
290
250
  priority: "primary",
291
- cell: (e) => /* @__PURE__ */ c("span", {
251
+ cell: (e) => /* @__PURE__ */ u("span", {
292
252
  className: "font-medium",
293
253
  children: e.name
294
254
  })
@@ -297,7 +257,7 @@ function w() {
297
257
  key: "headcount",
298
258
  header: "Headcount",
299
259
  priority: "secondary",
300
- cell: (e) => /* @__PURE__ */ c("span", {
260
+ cell: (e) => /* @__PURE__ */ u("span", {
301
261
  className: "md:block md:text-right",
302
262
  children: e.headcount
303
263
  })
@@ -306,7 +266,7 @@ function w() {
306
266
  key: "salary",
307
267
  header: "Total Salary",
308
268
  priority: "secondary",
309
- cell: (e) => /* @__PURE__ */ l("span", {
269
+ cell: (e) => /* @__PURE__ */ d("span", {
310
270
  className: "md:block md:text-right",
311
271
  children: [
312
272
  "$",
@@ -319,7 +279,7 @@ function w() {
319
279
  key: "budget",
320
280
  header: "Dept Budget",
321
281
  priority: "secondary",
322
- cell: (e) => /* @__PURE__ */ l("span", {
282
+ cell: (e) => /* @__PURE__ */ d("span", {
323
283
  className: "md:block md:text-right",
324
284
  children: [
325
285
  "$",
@@ -334,9 +294,9 @@ function w() {
334
294
  priority: "primary",
335
295
  cell: (e) => {
336
296
  let t = e.budget > 0 ? Math.round(e.salary / e.budget * 100) : 0;
337
- return /* @__PURE__ */ c("span", {
297
+ return /* @__PURE__ */ u("span", {
338
298
  className: "md:block md:text-right",
339
- children: /* @__PURE__ */ l(u, {
299
+ children: /* @__PURE__ */ d(f, {
340
300
  variant: t > 50 ? "destructive" : "default",
341
301
  className: "text-[10px]",
342
302
  children: [t, "%"]
@@ -345,23 +305,23 @@ function w() {
345
305
  }
346
306
  }
347
307
  ],
348
- data: z,
308
+ data: U,
349
309
  rowKey: (e) => e.name
350
310
  }),
351
- /* @__PURE__ */ c(S, { className: "my-3" }),
352
- /* @__PURE__ */ l("div", {
311
+ /* @__PURE__ */ u(w, { className: "my-3" }),
312
+ /* @__PURE__ */ d("div", {
353
313
  className: "flex flex-wrap items-center justify-between gap-2 text-sm font-bold",
354
314
  children: [
355
- /* @__PURE__ */ c("span", { children: "Total" }),
356
- /* @__PURE__ */ l("span", { children: [w.length, " employees"] }),
357
- /* @__PURE__ */ l("span", { children: [
315
+ /* @__PURE__ */ u("span", { children: "Total" }),
316
+ /* @__PURE__ */ d("span", { children: [E.length, " employees"] }),
317
+ /* @__PURE__ */ d("span", { children: [
358
318
  "$",
359
- (j / 1e6).toFixed(1),
319
+ (N / 1e6).toFixed(1),
360
320
  "M salary"
361
321
  ] }),
362
- /* @__PURE__ */ l("span", { children: [
322
+ /* @__PURE__ */ d("span", { children: [
363
323
  "$",
364
- (B / 1e6).toFixed(1),
324
+ (W / 1e6).toFixed(1),
365
325
  "M budget"
366
326
  ] })
367
327
  ]
@@ -371,6 +331,6 @@ function w() {
371
331
  });
372
332
  }
373
333
  //#endregion
374
- export { w as AnalyticsFinancialAnalyticsPagePage };
334
+ export { E as AnalyticsFinancialAnalyticsPagePage };
375
335
 
376
336
  //# sourceMappingURL=AnalyticsFinancialAnalyticsPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsFinancialAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n Pagination,\n ResponsiveTable,\n type ResponsiveTableColumn,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { DollarSign, FileText, Receipt, TrendingUp, Wallet } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\ntype DeptCostRow = {\n name: string;\n salary: number;\n budget: number;\n headcount: number;\n};\n\nexport function AnalyticsFinancialAnalyticsPagePage() {\n const { employees, departments, payrollRecords, invoices, projects } = useCrewFoundryStore();\n\n const monthlyPayrollTrend = useMemo(() => {\n const byPeriod = payrollRecords.reduce<\n Record<string, { gross: number; net: number; deductions: number }>\n >((acc, record) => {\n const month = new Date(record.payDate).toLocaleString('en-US', { month: 'short' });\n const current = acc[month] || { gross: 0, net: 0, deductions: 0 };\n current.gross += record.grossPay;\n current.net += record.netPay;\n current.deductions += record.deductions;\n acc[month] = current;\n return acc;\n }, {});\n return Object.entries(byPeriod)\n .map(([month, value]) => ({ month, ...value }))\n .slice(-6);\n }, [payrollRecords]);\n\n // Real spend lines only (no invented budget coefficients).\n const spendByCategory = useMemo(() => {\n const items = [\n {\n category: 'Gross Payroll',\n amount: payrollRecords.reduce((sum, record) => sum + record.grossPay, 0),\n icon: Wallet,\n },\n {\n category: 'Deductions',\n amount: payrollRecords.reduce((sum, record) => sum + record.deductions, 0),\n icon: Receipt,\n },\n {\n category: 'Project Spend',\n amount: projects.reduce((sum, project) => sum + project.spent, 0),\n icon: TrendingUp,\n },\n {\n category: 'Collected Invoices',\n amount: invoices\n .filter((invoice) => invoice.status === 'paid')\n .reduce((sum, invoice) => sum + invoice.amount, 0),\n icon: FileText,\n },\n ];\n const total = items.reduce((sum, item) => sum + item.amount, 0) || 1;\n return items.map((item) => ({ ...item, percentage: Math.round((item.amount / total) * 100) }));\n }, [invoices, payrollRecords, projects]);\n\n const totalPayroll = employees.reduce((sum, e) => sum + e.salary, 0);\n const monthlyPayroll = Math.round(totalPayroll / 12);\n const totalInvoiced = invoices.reduce((sum, inv) => sum + inv.amount, 0);\n const paidInvoices = invoices\n .filter((i) => i.status === 'paid')\n .reduce((s, i) => s + i.amount, 0);\n const totalProjectBudget = projects.reduce((s, p) => s + p.budget, 0);\n const totalProjectSpent = projects.reduce((s, p) => s + p.spent, 0);\n\n const maxPayroll = Math.max(1, ...monthlyPayrollTrend.map((m) => m.gross));\n const projectUtilization =\n totalProjectBudget > 0 ? Math.round((totalProjectSpent / totalProjectBudget) * 100) : 0;\n\n const deptCost: DeptCostRow[] = departments.map((d) => {\n const deptEmps = employees.filter((e) => e.department === d.name);\n const totalSal = deptEmps.reduce((s, e) => s + e.salary, 0);\n return { name: d.name, salary: totalSal, budget: d.budget, headcount: deptEmps.length };\n });\n const sortedDeptCost = [...deptCost].sort((a, b) => b.salary - a.salary);\n const totalDeptBudget = departments.reduce((s, d) => s + d.budget, 0);\n\n // Outstanding invoices = anything not fully paid, matching the card title.\n const outstandingInvoices = [...invoices]\n .filter((invoice) => invoice.status !== 'paid')\n .sort((a, b) => a.dueDate.localeCompare(b.dueDate));\n const {\n page: invoicePage,\n pageSize: invoicePageSize,\n offset: invoiceOffset,\n setPage: setInvoicePage,\n } = usePagination({ initialPageSize: 6 });\n const invoicePageItems = outstandingInvoices.slice(\n invoiceOffset,\n invoiceOffset + invoicePageSize\n );\n\n const deptCostColumns: ResponsiveTableColumn<DeptCostRow>[] = [\n {\n key: 'name',\n header: 'Department',\n priority: 'primary',\n cell: (d) => <span className=\"font-medium\">{d.name}</span>,\n },\n {\n key: 'headcount',\n header: 'Headcount',\n priority: 'secondary',\n cell: (d) => <span className=\"md:block md:text-right\">{d.headcount}</span>,\n },\n {\n key: 'salary',\n header: 'Total Salary',\n priority: 'secondary',\n cell: (d) => <span className=\"md:block md:text-right\">${(d.salary / 1000).toFixed(0)}K</span>,\n },\n {\n key: 'budget',\n header: 'Dept Budget',\n priority: 'secondary',\n cell: (d) => (\n <span className=\"md:block md:text-right\">${(d.budget / 1000000).toFixed(1)}M</span>\n ),\n },\n {\n key: 'ratio',\n header: 'Salary/Budget %',\n priority: 'primary',\n cell: (d) => {\n const ratio = d.budget > 0 ? Math.round((d.salary / d.budget) * 100) : 0;\n return (\n <span className=\"md:block md:text-right\">\n <Badge variant={ratio > 50 ? 'destructive' : 'default'} className=\"text-[10px]\">\n {ratio}%\n </Badge>\n </span>\n );\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>Financial Analytics</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Workforce financial metrics and cost analysis\n </p>\n <PagePurpose className=\"mt-1\">\n Understand the money side of your workforce — payroll, project budgets, and spend trends\n — so you can plan headcount and control costs with confidence.\n </PagePurpose>\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\">Monthly 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\">\n ${(monthlyPayroll / 1000).toFixed(0)}K\n </div>\n <p className=\"text-xs text-text-secondary\">Annual salary ÷ 12 months</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\">Annual Salary Cost</CardTitle>\n <Wallet className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalPayroll / 1000000).toFixed(1)}M\n </div>\n <p className=\"text-xs text-text-secondary\">{employees.length} employees</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\">Total Invoiced</CardTitle>\n <FileText className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalInvoiced / 1000).toFixed(1)}K\n </div>\n <p className=\"text-xs text-text-secondary\">\n ${(paidInvoices / 1000).toFixed(1)}K collected\n </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\">Project Budget</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalProjectBudget / 1000000).toFixed(1)}M\n </div>\n <p className=\"text-xs text-text-secondary\">{projectUtilization}% utilized</p>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Payroll Trend</CardTitle>\n <CardDescription>Monthly gross payroll over the last 6 months</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {monthlyPayrollTrend.map((m) => (\n <div key={m.month} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-sm text-text-secondary\">{m.month}</span>\n <div className=\"flex-1 h-5 bg-bg-sunken rounded overflow-hidden flex\">\n <div\n className=\"h-5 bg-action-primary-bg\"\n style={{ width: `${Math.round((m.net / maxPayroll) * 100)}%` }}\n />\n <div\n className=\"h-5 bg-action-primary-bg/30\"\n style={{ width: `${Math.round((m.deductions / maxPayroll) * 100)}%` }}\n />\n </div>\n <span className=\"text-sm font-medium w-20 text-right\">\n ${(m.gross / 1000000).toFixed(2)}M\n </span>\n </div>\n ))}\n <div className=\"flex items-center gap-4 mt-2 text-xs text-text-secondary\">\n <div className=\"flex items-center gap-1\">\n <div className=\"h-3 w-3 bg-action-primary-bg rounded\" />\n <span>Net Pay</span>\n </div>\n <div className=\"flex items-center gap-1\">\n <div className=\"h-3 w-3 bg-action-primary-bg/30 rounded\" />\n <span>Deductions</span>\n </div>\n </div>\n </CardContent>\n </Card>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>Spend by Category</CardTitle>\n <CardDescription>Share of tracked workforce spend</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {spendByCategory.map((cat) => (\n <div key={cat.category} className=\"space-y-1\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"flex items-center gap-2 font-medium\">\n <cat.icon className=\"h-4 w-4 text-text-secondary\" />\n {cat.category}\n </span>\n <span>${(cat.amount / 1000).toFixed(0)}K</span>\n </div>\n <div className=\"h-3 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-3 rounded bg-action-primary-bg\"\n style={{ width: `${cat.percentage}%` }}\n />\n </div>\n <p className=\"text-xs text-text-secondary text-right\">{cat.percentage}% of spend</p>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Outstanding Invoices</CardTitle>\n <CardDescription>Unpaid invoices requiring attention</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {outstandingInvoices.length === 0 && (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No outstanding invoices\"\n description=\"Every invoice has been paid. New unpaid invoices will appear here.\"\n />\n )}\n {invoicePageItems.map((inv) => (\n <div key={inv.id} className=\"flex items-center justify-between rounded border p-3\">\n <div>\n <p className=\"text-sm font-medium\">{inv.number}</p>\n <p className=\"text-xs text-text-secondary\">{inv.clientName}</p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm font-medium\">${inv.amount.toLocaleString()}</p>\n <Badge\n variant={inv.status === 'overdue' ? 'destructive' : 'secondary'}\n className=\"text-[10px]\"\n >\n {formatEnumLabel(inv.status)}\n </Badge>\n </div>\n </div>\n ))}\n {outstandingInvoices.length > invoicePageSize && (\n <Pagination\n page={invoicePage}\n pageSize={invoicePageSize}\n totalItems={outstandingInvoices.length}\n onPageChange={setInvoicePage}\n />\n )}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Department Cost Analysis</CardTitle>\n <CardDescription>Total salary cost and budget allocation by department</CardDescription>\n </CardHeader>\n <CardContent>\n <ResponsiveTable columns={deptCostColumns} data={sortedDeptCost} rowKey={(d) => d.name} />\n <Separator className=\"my-3\" />\n <div className=\"flex flex-wrap items-center justify-between gap-2 text-sm font-bold\">\n <span>Total</span>\n <span>{employees.length} employees</span>\n <span>${(totalPayroll / 1000000).toFixed(1)}M salary</span>\n <span>${(totalDeptBudget / 1000000).toFixed(1)}M budget</span>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AnalyticsFinancialAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n Pagination,\n ResponsiveTable,\n type ResponsiveTableColumn,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { DollarSign, FileText, Receipt, TrendingUp, Wallet } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\nimport { DonutChart, LineChart } from '../components/viz';\nimport type { LabeledValue, Segment } from '../components/viz';\n\ntype DeptCostRow = {\n name: string;\n salary: number;\n budget: number;\n headcount: number;\n};\n\nexport function AnalyticsFinancialAnalyticsPagePage() {\n const { employees, departments, payrollRecords, invoices, projects } = useCrewFoundryStore();\n\n const monthlyPayrollTrend = useMemo(() => {\n const byPeriod = payrollRecords.reduce<\n Record<string, { gross: number; net: number; deductions: number }>\n >((acc, record) => {\n const month = new Date(record.payDate).toLocaleString('en-US', { month: 'short' });\n const current = acc[month] || { gross: 0, net: 0, deductions: 0 };\n current.gross += record.grossPay;\n current.net += record.netPay;\n current.deductions += record.deductions;\n acc[month] = current;\n return acc;\n }, {});\n return Object.entries(byPeriod)\n .map(([month, value]) => ({ month, ...value }))\n .slice(-6);\n }, [payrollRecords]);\n\n // Real spend lines only (no invented budget coefficients).\n const spendByCategory = useMemo(() => {\n const items = [\n {\n category: 'Gross Payroll',\n amount: payrollRecords.reduce((sum, record) => sum + record.grossPay, 0),\n icon: Wallet,\n },\n {\n category: 'Deductions',\n amount: payrollRecords.reduce((sum, record) => sum + record.deductions, 0),\n icon: Receipt,\n },\n {\n category: 'Project Spend',\n amount: projects.reduce((sum, project) => sum + project.spent, 0),\n icon: TrendingUp,\n },\n {\n category: 'Collected Invoices',\n amount: invoices\n .filter((invoice) => invoice.status === 'paid')\n .reduce((sum, invoice) => sum + invoice.amount, 0),\n icon: FileText,\n },\n ];\n const total = items.reduce((sum, item) => sum + item.amount, 0) || 1;\n return items.map((item) => ({ ...item, percentage: Math.round((item.amount / total) * 100) }));\n }, [invoices, payrollRecords, projects]);\n\n const totalPayroll = employees.reduce((sum, e) => sum + e.salary, 0);\n const monthlyPayroll = Math.round(totalPayroll / 12);\n const totalInvoiced = invoices.reduce((sum, inv) => sum + inv.amount, 0);\n const paidInvoices = invoices\n .filter((i) => i.status === 'paid')\n .reduce((s, i) => s + i.amount, 0);\n const totalProjectBudget = projects.reduce((s, p) => s + p.budget, 0);\n const totalProjectSpent = projects.reduce((s, p) => s + p.spent, 0);\n\n const grossSeries: LabeledValue[] = monthlyPayrollTrend.map((m) => ({\n label: m.month,\n value: m.gross,\n }));\n const netCompare = monthlyPayrollTrend.map((m) => m.net);\n const spendSegments: Segment[] = spendByCategory\n .filter((category) => category.amount > 0)\n .map((category) => ({ label: category.category, value: category.amount }));\n const projectUtilization =\n totalProjectBudget > 0 ? Math.round((totalProjectSpent / totalProjectBudget) * 100) : 0;\n\n const deptCost: DeptCostRow[] = departments.map((d) => {\n const deptEmps = employees.filter((e) => e.department === d.name);\n const totalSal = deptEmps.reduce((s, e) => s + e.salary, 0);\n return { name: d.name, salary: totalSal, budget: d.budget, headcount: deptEmps.length };\n });\n const sortedDeptCost = [...deptCost].sort((a, b) => b.salary - a.salary);\n const totalDeptBudget = departments.reduce((s, d) => s + d.budget, 0);\n\n // Outstanding invoices = anything not fully paid, matching the card title.\n const outstandingInvoices = [...invoices]\n .filter((invoice) => invoice.status !== 'paid')\n .sort((a, b) => a.dueDate.localeCompare(b.dueDate));\n const {\n page: invoicePage,\n pageSize: invoicePageSize,\n offset: invoiceOffset,\n setPage: setInvoicePage,\n } = usePagination({ initialPageSize: 6 });\n const invoicePageItems = outstandingInvoices.slice(\n invoiceOffset,\n invoiceOffset + invoicePageSize\n );\n\n const deptCostColumns: ResponsiveTableColumn<DeptCostRow>[] = [\n {\n key: 'name',\n header: 'Department',\n priority: 'primary',\n cell: (d) => <span className=\"font-medium\">{d.name}</span>,\n },\n {\n key: 'headcount',\n header: 'Headcount',\n priority: 'secondary',\n cell: (d) => <span className=\"md:block md:text-right\">{d.headcount}</span>,\n },\n {\n key: 'salary',\n header: 'Total Salary',\n priority: 'secondary',\n cell: (d) => <span className=\"md:block md:text-right\">${(d.salary / 1000).toFixed(0)}K</span>,\n },\n {\n key: 'budget',\n header: 'Dept Budget',\n priority: 'secondary',\n cell: (d) => (\n <span className=\"md:block md:text-right\">${(d.budget / 1000000).toFixed(1)}M</span>\n ),\n },\n {\n key: 'ratio',\n header: 'Salary/Budget %',\n priority: 'primary',\n cell: (d) => {\n const ratio = d.budget > 0 ? Math.round((d.salary / d.budget) * 100) : 0;\n return (\n <span className=\"md:block md:text-right\">\n <Badge variant={ratio > 50 ? 'destructive' : 'default'} className=\"text-[10px]\">\n {ratio}%\n </Badge>\n </span>\n );\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>Financial Analytics</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Workforce financial metrics and cost analysis\n </p>\n <PagePurpose className=\"mt-1\">\n Understand the money side of your workforce — payroll, project budgets, and spend trends\n — so you can plan headcount and control costs with confidence.\n </PagePurpose>\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\">Monthly 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\">\n ${(monthlyPayroll / 1000).toFixed(0)}K\n </div>\n <p className=\"text-xs text-text-secondary\">Annual salary ÷ 12 months</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\">Annual Salary Cost</CardTitle>\n <Wallet className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalPayroll / 1000000).toFixed(1)}M\n </div>\n <p className=\"text-xs text-text-secondary\">{employees.length} employees</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\">Total Invoiced</CardTitle>\n <FileText className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalInvoiced / 1000).toFixed(1)}K\n </div>\n <p className=\"text-xs text-text-secondary\">\n ${(paidInvoices / 1000).toFixed(1)}K collected\n </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\">Project Budget</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalProjectBudget / 1000000).toFixed(1)}M\n </div>\n <p className=\"text-xs text-text-secondary\">{projectUtilization}% utilized</p>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Payroll Trend</CardTitle>\n <CardDescription>Monthly gross payroll over the last 6 months</CardDescription>\n </CardHeader>\n <CardContent>\n {grossSeries.length > 0 ? (\n <LineChart\n series={grossSeries}\n compare={netCompare}\n seriesLabel=\"Gross pay\"\n compareLabel=\"Net pay\"\n height={220}\n valueFormatter={(value) => `$${(value / 1000).toFixed(0)}K`}\n />\n ) : (\n <p className=\"py-6 text-center text-sm text-text-secondary\">\n No payroll records yet.\n </p>\n )}\n </CardContent>\n </Card>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>Spend by Category</CardTitle>\n <CardDescription>Share of tracked workforce spend</CardDescription>\n </CardHeader>\n <CardContent>\n {spendSegments.length > 0 ? (\n <DonutChart\n segments={spendSegments}\n centerLabel={`$${(spendSegments.reduce((sum, s) => sum + s.value, 0) / 1000).toFixed(0)}K`}\n centerCaption=\"Total spend\"\n valueFormatter={(value) => `$${(value / 1000).toFixed(0)}K`}\n />\n ) : (\n <p className=\"py-6 text-center text-sm text-text-secondary\">\n No tracked spend yet.\n </p>\n )}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Outstanding Invoices</CardTitle>\n <CardDescription>Unpaid invoices requiring attention</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {outstandingInvoices.length === 0 && (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No outstanding invoices\"\n description=\"Every invoice has been paid. New unpaid invoices will appear here.\"\n />\n )}\n {invoicePageItems.map((inv) => (\n <div key={inv.id} className=\"flex items-center justify-between rounded border p-3\">\n <div>\n <p className=\"text-sm font-medium\">{inv.number}</p>\n <p className=\"text-xs text-text-secondary\">{inv.clientName}</p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm font-medium\">${inv.amount.toLocaleString()}</p>\n <Badge\n variant={inv.status === 'overdue' ? 'destructive' : 'secondary'}\n className=\"text-[10px]\"\n >\n {formatEnumLabel(inv.status)}\n </Badge>\n </div>\n </div>\n ))}\n {outstandingInvoices.length > invoicePageSize && (\n <Pagination\n page={invoicePage}\n pageSize={invoicePageSize}\n totalItems={outstandingInvoices.length}\n onPageChange={setInvoicePage}\n />\n )}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Department Cost Analysis</CardTitle>\n <CardDescription>Total salary cost and budget allocation by department</CardDescription>\n </CardHeader>\n <CardContent>\n <ResponsiveTable columns={deptCostColumns} data={sortedDeptCost} rowKey={(d) => d.name} />\n <Separator className=\"my-3\" />\n <div className=\"flex flex-wrap items-center justify-between gap-2 text-sm font-bold\">\n <span>Total</span>\n <span>{employees.length} employees</span>\n <span>${(totalPayroll / 1000000).toFixed(1)}M salary</span>\n <span>${(totalDeptBudget / 1000000).toFixed(1)}M budget</span>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}