@burdenoff/microfe-crewfoundry 2026.703.2 → 2026.704.2

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 (130) hide show
  1. package/dist/crewfoundry/components/forms/FormModal.js.map +1 -1
  2. package/dist/crewfoundry/pages/AdminAdminPagePage.js +117 -164
  3. package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
  4. package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +99 -82
  5. package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
  6. package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +160 -192
  7. package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
  8. package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +238 -231
  9. package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
  10. package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +196 -166
  11. package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
  12. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
  13. package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +45 -147
  14. package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
  15. package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +20 -11
  16. package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
  17. package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +45 -152
  18. package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
  19. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +50 -138
  20. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
  21. package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +149 -67
  22. package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
  23. package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +50 -201
  24. package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
  25. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +205 -136
  26. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
  27. package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +25 -31
  28. package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
  29. package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +118 -104
  30. package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
  31. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +117 -58
  32. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
  33. package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +90 -94
  34. package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
  35. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +210 -191
  36. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
  37. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +213 -180
  38. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
  39. package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +133 -264
  40. package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
  41. package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +279 -212
  42. package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
  43. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +131 -105
  44. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
  45. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +167 -148
  46. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
  47. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +3 -3
  48. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
  49. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +13 -5
  50. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
  51. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +151 -152
  52. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
  53. package/dist/crewfoundry/pages/HiringJobsPagePage.js +38 -21
  54. package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
  55. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +3 -3
  56. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
  57. package/dist/crewfoundry/pages/HrEmployeesPagePage.js +134 -127
  58. package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
  59. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +163 -132
  60. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
  61. package/dist/crewfoundry/pages/HrPayrollPagePage.js +202 -160
  62. package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
  63. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +104 -91
  64. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
  65. package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +29 -147
  66. package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
  67. package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +22 -106
  68. package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
  69. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +74 -74
  70. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
  71. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +101 -97
  72. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
  73. package/dist/crewfoundry/pages/LearningCoursesPagePage.js +64 -47
  74. package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
  75. package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +111 -121
  76. package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
  77. package/dist/crewfoundry/pages/LearningLearningPagePage.js +131 -110
  78. package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
  79. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +65 -64
  80. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
  81. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +58 -43
  82. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
  83. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +66 -82
  84. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
  85. package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +38 -88
  86. package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
  87. package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +59 -65
  88. package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
  89. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +209 -323
  90. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
  91. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +175 -220
  92. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
  93. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +74 -59
  94. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
  95. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +96 -80
  96. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
  97. package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +28 -100
  98. package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
  99. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +27 -20
  100. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
  101. package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +73 -73
  102. package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
  103. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +62 -56
  104. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
  105. package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +40 -138
  106. package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
  107. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +126 -93
  108. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
  109. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +99 -77
  110. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
  111. package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
  112. package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +73 -74
  113. package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
  114. package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +1 -1
  115. package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
  116. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +122 -122
  117. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
  118. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +130 -113
  119. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
  120. package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +68 -59
  121. package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
  122. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +73 -62
  123. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
  124. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +82 -58
  125. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
  126. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +153 -153
  127. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
  128. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +63 -48
  129. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
  130. package/package.json +1 -1
@@ -2,52 +2,43 @@ import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
2
2
  import { useMemo as t } from "react";
3
3
  import { BarChart3 as n, DollarSign as r, Target as i, TrendingDown as a, TrendingUp as o, Users as s } from "lucide-react";
4
4
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
5
- import { Badge as u, Card as d, CardContent as f, CardDescription as p, CardHeader as m, CardTitle as h, GlassCard as g, GradientText as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
5
+ import { Badge as u, Card as d, CardContent as f, CardDescription as p, CardHeader as m, CardTitle as h, GlassCard as g, GradientText as _, PagePurpose as v, ResponsiveTable as y } from "@burdenoff/fe-libs/ui";
6
6
  //#region src/crewfoundry/pages/DashboardAnalyticsPagePage.tsx
7
- function y() {
8
- let { employees: y, departments: b, jobPostings: x, payrollRecords: S, projects: C } = e(), w = t(() => {
9
- let e = [...y].sort((e, t) => e.startDate.localeCompare(t.startDate));
10
- return e.slice(-6).map((t, n) => {
11
- let r = new Date(t.startDate).toLocaleString("en-US", { month: "short" });
7
+ function b() {
8
+ let { employees: b, departments: x, jobPostings: S, payrollRecords: C, projects: w } = e(), T = t(() => {
9
+ if (b.length === 0) return [];
10
+ let e = (e) => {
11
+ let t = new Date(e);
12
+ return `${t.getFullYear()}-${String(t.getMonth()).padStart(2, "0")}`;
13
+ };
14
+ return Array.from(new Set(b.map((t) => e(t.startDate)))).sort().slice(-6).map((t) => {
15
+ let [n, r] = t.split("-").map(Number), i = new Date(n, r + 1, 0).getTime(), a = new Date(n, r, 1).toLocaleString("en-US", {
16
+ month: "short",
17
+ year: "2-digit"
18
+ }), o = b.filter((e) => new Date(e.startDate).getTime() <= i && e.status !== "terminated").length;
12
19
  return {
13
- month: r,
14
- hires: e.filter((e) => new Date(e.startDate).toLocaleString("en-US", { month: "short" }) === r && e.status === "active").length,
15
- attrition: e.filter((e) => new Date(e.startDate).toLocaleString("en-US", { month: "short" }) === r && e.status === "terminated").length,
16
- headcount: Math.max(1, e.length - (5 - n))
20
+ month: a,
21
+ hires: b.filter((n) => e(n.startDate) === t).length,
22
+ attrition: b.filter((n) => n.status === "terminated" && e(n.startDate) === t).length,
23
+ headcount: o
17
24
  };
18
25
  });
19
- }, [y]), T = Math.max(1, ...w.map((e) => e.headcount)), E = S.reduce((e, t) => e + t.netPay, 0), D = Math.round(y.reduce((e, t) => e + t.salary, 0) / Math.max(y.length, 1)), O = x.filter((e) => e.status === "active").length, k = y.reduce((e, t) => {
26
+ }, [b]), E = Math.max(1, ...T.map((e) => e.headcount)), D = C.reduce((e, t) => e + t.netPay, 0), O = Math.round(b.reduce((e, t) => e + t.salary, 0) / Math.max(b.length, 1)), k = S.filter((e) => e.status === "active").length, A = b.reduce((e, t) => {
20
27
  let n = t.type.replace("_", " ");
21
28
  return e[n] = (e[n] || 0) + 1, e;
22
- }, {}), A = t(() => {
23
- let e = [
24
- {
25
- category: "Payroll",
26
- amount: E
27
- },
28
- {
29
- category: "Recruitment",
30
- amount: x.reduce((e, t) => e + t.applicants * 120, 0)
31
- },
32
- {
33
- category: "Project Delivery",
34
- amount: C.reduce((e, t) => e + t.spent, 0)
35
- },
36
- {
37
- category: "Department Ops",
38
- amount: b.reduce((e, t) => e + t.budget * .03, 0)
39
- }
40
- ], t = e.reduce((e, t) => e + t.amount, 0) || 1;
29
+ }, {}), j = t(() => {
30
+ let e = [{
31
+ category: "Net Payroll",
32
+ amount: D
33
+ }, {
34
+ category: "Project Delivery",
35
+ amount: w.reduce((e, t) => e + t.spent, 0)
36
+ }], t = e.reduce((e, t) => e + t.amount, 0) || 1;
41
37
  return e.map((e) => ({
42
38
  ...e,
43
39
  percentage: Math.round(e.amount / t * 100)
44
40
  }));
45
- }, [
46
- b,
47
- x,
48
- C,
49
- E
50
- ]);
41
+ }, [w, D]);
51
42
  return /* @__PURE__ */ l("div", {
52
43
  className: "space-y-6 p-6",
53
44
  children: [
@@ -80,7 +71,7 @@ function y() {
80
71
  }), /* @__PURE__ */ c(s, { className: "h-4 w-4 text-text-secondary" })]
81
72
  }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ c("div", {
82
73
  className: "text-2xl font-bold tabular-nums",
83
- children: y.length
74
+ children: b.length
84
75
  }), /* @__PURE__ */ l("div", {
85
76
  className: "flex items-center text-xs text-status-success-text",
86
77
  children: [/* @__PURE__ */ c(o, { className: "mr-1 h-3 w-3" }), "Live workforce count"]
@@ -97,7 +88,7 @@ function y() {
97
88
  }), /* @__PURE__ */ c(r, { className: "h-4 w-4 text-text-secondary" })]
98
89
  }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
99
90
  className: "text-2xl font-bold tabular-nums",
100
- children: ["$", D.toLocaleString()]
91
+ children: ["$", O.toLocaleString()]
101
92
  }), /* @__PURE__ */ l("div", {
102
93
  className: "flex items-center text-xs text-status-success-text",
103
94
  children: [/* @__PURE__ */ c(o, { className: "mr-1 h-3 w-3" }), "Updated from employee records"]
@@ -114,7 +105,7 @@ function y() {
114
105
  }), /* @__PURE__ */ c(a, { className: "h-4 w-4 text-text-secondary" })]
115
106
  }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
116
107
  className: "text-2xl font-bold tabular-nums",
117
- children: [Math.round(y.filter((e) => e.status === "terminated").length / Math.max(y.length, 1) * 100), "%"]
108
+ children: [Math.round(b.filter((e) => e.status === "terminated").length / Math.max(b.length, 1) * 100), "%"]
118
109
  }), /* @__PURE__ */ l("div", {
119
110
  className: "flex items-center text-xs text-status-success-text",
120
111
  children: [/* @__PURE__ */ c(a, { className: "mr-1 h-3 w-3" }), "Calculated from status mix"]
@@ -131,7 +122,7 @@ function y() {
131
122
  }), /* @__PURE__ */ c(i, { className: "h-4 w-4 text-text-secondary" })]
132
123
  }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ c("div", {
133
124
  className: "text-2xl font-bold tabular-nums",
134
- children: O
125
+ children: k
135
126
  }), /* @__PURE__ */ c("p", {
136
127
  className: "text-xs text-text-secondary",
137
128
  children: "Based on active job postings"
@@ -145,7 +136,7 @@ function y() {
145
136
  className: "col-span-4",
146
137
  children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Headcount Trend" }), /* @__PURE__ */ c(p, { children: "Monthly headcount over recent months" })] }), /* @__PURE__ */ c(f, {
147
138
  className: "space-y-3",
148
- children: w.map((e, t) => /* @__PURE__ */ l("div", {
139
+ children: T.map((e, t) => /* @__PURE__ */ l("div", {
149
140
  className: "flex items-center gap-3",
150
141
  children: [
151
142
  /* @__PURE__ */ c("span", {
@@ -156,7 +147,7 @@ function y() {
156
147
  className: "h-4 flex-1 overflow-hidden rounded bg-bg-sunken",
157
148
  children: /* @__PURE__ */ c("div", {
158
149
  className: "h-4 rounded bg-action-primary-bg",
159
- style: { width: `${Math.round(e.headcount / T * 100)}%` }
150
+ style: { width: `${Math.round(e.headcount / E * 100)}%` }
160
151
  })
161
152
  }),
162
153
  /* @__PURE__ */ c("span", {
@@ -182,7 +173,7 @@ function y() {
182
173
  className: "col-span-3",
183
174
  children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Employee Types" }), /* @__PURE__ */ c(p, { children: "Distribution by employment type" })] }), /* @__PURE__ */ c(f, {
184
175
  className: "space-y-4",
185
- children: Object.entries(k).sort(([, e], [, t]) => t - e).map(([e, t]) => /* @__PURE__ */ l("div", {
176
+ children: Object.entries(A).sort(([, e], [, t]) => t - e).map(([e, t]) => /* @__PURE__ */ l("div", {
186
177
  className: "flex items-center justify-between",
187
178
  children: [/* @__PURE__ */ l("div", {
188
179
  className: "flex items-center gap-2",
@@ -199,7 +190,7 @@ function y() {
199
190
  className: "text-xs text-text-secondary",
200
191
  children: [
201
192
  "(",
202
- Math.round(t / Math.max(y.length, 1) * 100),
193
+ Math.round(t / Math.max(b.length, 1) * 100),
203
194
  "%)"
204
195
  ]
205
196
  })]
@@ -210,7 +201,7 @@ function y() {
210
201
  }),
211
202
  /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Workforce Cost Breakdown" }), /* @__PURE__ */ c(p, { children: "Operational costs by category" })] }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ c("div", {
212
203
  className: "space-y-3",
213
- children: A.map((e) => /* @__PURE__ */ l("div", {
204
+ children: j.map((e) => /* @__PURE__ */ l("div", {
214
205
  className: "flex items-center gap-4",
215
206
  children: [
216
207
  /* @__PURE__ */ c("span", {
@@ -247,65 +238,70 @@ function y() {
247
238
  className: "font-bold",
248
239
  children: [
249
240
  "$",
250
- (A.reduce((e, t) => e + t.amount, 0) / 1e3).toFixed(0),
241
+ (j.reduce((e, t) => e + t.amount, 0) / 1e3).toFixed(0),
251
242
  "K"
252
243
  ]
253
244
  })]
254
245
  })] })] }),
255
- /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Department Overview" }), /* @__PURE__ */ c(p, { children: "Key metrics by department" })] }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
256
- className: "mb-2 grid grid-cols-5 gap-2 border-b pb-2 text-xs font-medium text-text-secondary",
257
- children: [
258
- /* @__PURE__ */ c("span", { children: "Department" }),
259
- /* @__PURE__ */ c("span", { children: "Head" }),
260
- /* @__PURE__ */ c("span", {
261
- className: "text-right",
262
- children: "Employees"
263
- }),
264
- /* @__PURE__ */ c("span", {
265
- className: "text-right",
266
- children: "Budget"
267
- }),
268
- /* @__PURE__ */ c("span", {
269
- className: "text-right",
270
- children: "Status"
271
- })
272
- ]
273
- }), b.map((e) => /* @__PURE__ */ l("div", {
274
- className: "grid grid-cols-5 gap-2 border-b py-2 text-sm last:border-0",
275
- children: [
276
- /* @__PURE__ */ c("span", {
277
- className: "font-medium",
278
- children: e.name
279
- }),
280
- /* @__PURE__ */ c("span", {
281
- className: "text-text-secondary",
282
- children: e.headName
283
- }),
284
- /* @__PURE__ */ c("span", {
285
- className: "text-right",
286
- children: e.employeeCount
287
- }),
288
- /* @__PURE__ */ l("span", {
289
- className: "text-right",
290
- children: [
291
- "$",
292
- (e.budget / 1e6).toFixed(1),
293
- "M"
294
- ]
295
- }),
296
- /* @__PURE__ */ c("div", {
297
- className: "text-right",
298
- children: /* @__PURE__ */ c(u, {
246
+ /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Department Overview" }), /* @__PURE__ */ c(p, { children: "Key metrics by department" })] }), /* @__PURE__ */ c(f, { children: /* @__PURE__ */ c(y, {
247
+ columns: [
248
+ {
249
+ key: "name",
250
+ header: "Department",
251
+ priority: "primary",
252
+ cell: (e) => /* @__PURE__ */ c("span", {
253
+ className: "font-medium",
254
+ children: e.name
255
+ })
256
+ },
257
+ {
258
+ key: "head",
259
+ header: "Head",
260
+ priority: "secondary",
261
+ cell: (e) => /* @__PURE__ */ c("span", {
262
+ className: "text-text-secondary",
263
+ children: e.headName
264
+ })
265
+ },
266
+ {
267
+ key: "employees",
268
+ header: "Employees",
269
+ priority: "secondary",
270
+ cell: (e) => /* @__PURE__ */ c("span", {
271
+ className: "md:block md:text-right",
272
+ children: e.employeeCount
273
+ })
274
+ },
275
+ {
276
+ key: "budget",
277
+ header: "Budget",
278
+ priority: "secondary",
279
+ cell: (e) => /* @__PURE__ */ l("span", {
280
+ className: "md:block md:text-right",
281
+ children: [
282
+ "$",
283
+ (e.budget / 1e6).toFixed(1),
284
+ "M"
285
+ ]
286
+ })
287
+ },
288
+ {
289
+ key: "status",
290
+ header: "Status",
291
+ priority: "primary",
292
+ cell: (e) => /* @__PURE__ */ c(u, {
299
293
  variant: e.status === "active" ? "default" : "secondary",
300
294
  children: e.status
301
295
  })
302
- })
303
- ]
304
- }, e.id))] })] })
296
+ }
297
+ ],
298
+ data: x,
299
+ rowKey: (e) => e.id
300
+ }) })] })
305
301
  ]
306
302
  });
307
303
  }
308
304
  //#endregion
309
- export { y as DashboardAnalyticsPagePage };
305
+ export { b as DashboardAnalyticsPagePage };
310
306
 
311
307
  //# sourceMappingURL=DashboardAnalyticsPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/DashboardAnalyticsPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { BarChart3, DollarSign, Target, TrendingDown, TrendingUp, Users } from 'lucide-react';\nimport {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype MonthlyTrend = {\n month: string;\n hires: number;\n attrition: number;\n headcount: number;\n};\n\ntype CostItem = {\n category: string;\n amount: number;\n percentage: number;\n};\n\nexport function DashboardAnalyticsPagePage() {\n const { employees, departments, jobPostings, payrollRecords, projects } = useCrewFoundryStore();\n\n const monthlyTrends = useMemo<MonthlyTrend[]>(() => {\n const sorted = [...employees].sort((a, b) => a.startDate.localeCompare(b.startDate));\n return sorted.slice(-6).map((employee, index) => {\n const month = new Date(employee.startDate).toLocaleString('en-US', { month: 'short' });\n const hires = sorted.filter(\n (item) =>\n new Date(item.startDate).toLocaleString('en-US', { month: 'short' }) === month &&\n item.status === 'active'\n ).length;\n const attrition = sorted.filter(\n (item) =>\n new Date(item.startDate).toLocaleString('en-US', { month: 'short' }) === month &&\n item.status === 'terminated'\n ).length;\n return {\n month,\n hires,\n attrition,\n headcount: Math.max(1, sorted.length - (5 - index)),\n };\n });\n }, [employees]);\n\n const maxTrend = Math.max(1, ...monthlyTrends.map((trend) => trend.headcount));\n\n const totalPayroll = payrollRecords.reduce((sum, record) => sum + record.netPay, 0);\n const avgSalary = Math.round(\n employees.reduce((sum, employee) => sum + employee.salary, 0) / Math.max(employees.length, 1)\n );\n const activePostings = jobPostings.filter((posting) => posting.status === 'active').length;\n\n const typeDistribution = employees.reduce<Record<string, number>>((acc, employee) => {\n const key = employee.type.replace('_', ' ');\n acc[key] = (acc[key] || 0) + 1;\n return acc;\n }, {});\n\n const costBreakdown = useMemo<CostItem[]>(() => {\n const costs: Array<{ category: string; amount: number }> = [\n { category: 'Payroll', amount: totalPayroll },\n {\n category: 'Recruitment',\n amount: jobPostings.reduce((sum, posting) => sum + posting.applicants * 120, 0),\n },\n {\n category: 'Project Delivery',\n amount: projects.reduce((sum, project) => sum + project.spent, 0),\n },\n {\n category: 'Department Ops',\n amount: departments.reduce((sum, department) => sum + department.budget * 0.03, 0),\n },\n ];\n const total = costs.reduce((sum, item) => sum + item.amount, 0) || 1;\n return costs.map((item) => ({\n ...item,\n percentage: Math.round((item.amount / total) * 100),\n }));\n }, [departments, jobPostings, projects, totalPayroll]);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Dashboard Analytics</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Workforce analytics and operational insights</p>\n <PagePurpose className=\"mt-1\">A consolidated analytics view across your organization — use it to monitor the metrics that matter most without digging through separate reports.</PagePurpose>\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\">Total Headcount</CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{employees.length}</div>\n <div className=\"flex items-center text-xs text-status-success-text\">\n <TrendingUp className=\"mr-1 h-3 w-3\" />\n Live workforce count\n </div>\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\">Avg Salary</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${avgSalary.toLocaleString()}</div>\n <div className=\"flex items-center text-xs text-status-success-text\">\n <TrendingUp className=\"mr-1 h-3 w-3\" />\n Updated from employee records\n </div>\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\">Attrition Rate</CardTitle>\n <TrendingDown className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {Math.round(\n (employees.filter((employee) => employee.status === 'terminated').length /\n Math.max(employees.length, 1)) *\n 100\n )}\n %\n </div>\n <div className=\"flex items-center text-xs text-status-success-text\">\n <TrendingDown className=\"mr-1 h-3 w-3\" />\n Calculated from status mix\n </div>\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\">Open Roles</CardTitle>\n <Target className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{activePostings}</div>\n <p className=\"text-xs text-text-secondary\">Based on active job postings</p>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-7\">\n <Card className=\"col-span-4\">\n <CardHeader>\n <CardTitle>Headcount Trend</CardTitle>\n <CardDescription>Monthly headcount over recent months</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {monthlyTrends.map((trend, index) => (\n <div key={`${trend.month}-${index}`} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-sm text-text-secondary\">{trend.month}</span>\n <div className=\"h-4 flex-1 overflow-hidden rounded bg-bg-sunken\">\n <div\n className=\"h-4 rounded bg-action-primary-bg\"\n style={{ width: `${Math.round((trend.headcount / maxTrend) * 100)}%` }}\n />\n </div>\n <span className=\"w-10 text-right text-sm font-medium\">{trend.headcount}</span>\n <div className=\"flex w-24 gap-1\">\n <Badge variant=\"default\" className=\"text-[10px]\">\n +{trend.hires}\n </Badge>\n <Badge variant=\"destructive\" className=\"text-[10px]\">\n -{trend.attrition}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card className=\"col-span-3\">\n <CardHeader>\n <CardTitle>Employee Types</CardTitle>\n <CardDescription>Distribution by employment type</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {Object.entries(typeDistribution)\n .sort(([, a], [, b]) => b - a)\n .map(([type, count]) => (\n <div key={type} className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <BarChart3 className=\"h-4 w-4 text-text-secondary\" />\n <span className=\"text-sm capitalize\">{type}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium\">{count}</span>\n <span className=\"text-xs text-text-secondary\">\n ({Math.round((count / Math.max(employees.length, 1)) * 100)}%)\n </span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Workforce Cost Breakdown</CardTitle>\n <CardDescription>Operational costs by category</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {costBreakdown.map((item) => (\n <div key={item.category} className=\"flex items-center gap-4\">\n <span className=\"w-48 text-sm text-text-secondary\">{item.category}</span>\n <div className=\"h-3 flex-1 overflow-hidden rounded bg-bg-sunken\">\n <div\n className=\"h-3 rounded bg-action-primary-bg/80\"\n style={{ width: `${item.percentage}%` }}\n />\n </div>\n <span className=\"w-24 text-right text-sm font-medium\">\n ${(item.amount / 1000).toFixed(0)}K\n </span>\n <span className=\"w-10 text-right text-xs text-text-secondary\">\n {item.percentage}%\n </span>\n </div>\n ))}\n </div>\n <div className=\"mt-4 flex justify-between border-t pt-4 text-sm\">\n <span className=\"font-medium\">Total Monthly Cost</span>\n <span className=\"font-bold\">\n ${(costBreakdown.reduce((sum, item) => sum + item.amount, 0) / 1000).toFixed(0)}K\n </span>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Department Overview</CardTitle>\n <CardDescription>Key metrics by department</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-2 grid grid-cols-5 gap-2 border-b pb-2 text-xs font-medium text-text-secondary\">\n <span>Department</span>\n <span>Head</span>\n <span className=\"text-right\">Employees</span>\n <span className=\"text-right\">Budget</span>\n <span className=\"text-right\">Status</span>\n </div>\n {departments.map((department) => (\n <div\n key={department.id}\n className=\"grid grid-cols-5 gap-2 border-b py-2 text-sm last:border-0\"\n >\n <span className=\"font-medium\">{department.name}</span>\n <span className=\"text-text-secondary\">{department.headName}</span>\n <span className=\"text-right\">{department.employeeCount}</span>\n <span className=\"text-right\">${(department.budget / 1000000).toFixed(1)}M</span>\n <div className=\"text-right\">\n <Badge variant={department.status === 'active' ? 'default' : 'secondary'}>\n {department.status}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DashboardAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/DashboardAnalyticsPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { BarChart3, DollarSign, Target, TrendingDown, TrendingUp, Users } from 'lucide-react';\nimport {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n ResponsiveTable,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore, type Department } from '../store/crewfoundryStore';\n\ntype MonthlyTrend = {\n month: string;\n hires: number;\n attrition: number;\n headcount: number;\n};\n\ntype CostItem = {\n category: string;\n amount: number;\n percentage: number;\n};\n\nexport function DashboardAnalyticsPagePage() {\n const { employees, departments, jobPostings, payrollRecords, projects } = useCrewFoundryStore();\n\n const monthlyTrends = useMemo<MonthlyTrend[]>(() => {\n if (employees.length === 0) {\n return [];\n }\n const monthKey = (value: string) => {\n const date = new Date(value);\n return `${date.getFullYear()}-${String(date.getMonth()).padStart(2, '0')}`;\n };\n const distinctMonths = Array.from(new Set(employees.map((item) => monthKey(item.startDate))))\n .sort()\n .slice(-6);\n return distinctMonths.map((key) => {\n const [year, month] = key.split('-').map(Number);\n const monthEnd = new Date(year, month + 1, 0).getTime();\n const label = new Date(year, month, 1).toLocaleString('en-US', {\n month: 'short',\n year: '2-digit',\n });\n // Real cumulative headcount as of the end of this month (still employed).\n const headcount = employees.filter(\n (item) => new Date(item.startDate).getTime() <= monthEnd && item.status !== 'terminated'\n ).length;\n const hires = employees.filter((item) => monthKey(item.startDate) === key).length;\n const attrition = employees.filter(\n (item) => item.status === 'terminated' && monthKey(item.startDate) === key\n ).length;\n return { month: label, hires, attrition, headcount };\n });\n }, [employees]);\n\n const maxTrend = Math.max(1, ...monthlyTrends.map((trend) => trend.headcount));\n\n const totalPayroll = payrollRecords.reduce((sum, record) => sum + record.netPay, 0);\n const avgSalary = Math.round(\n employees.reduce((sum, employee) => sum + employee.salary, 0) / Math.max(employees.length, 1)\n );\n const activePostings = jobPostings.filter((posting) => posting.status === 'active').length;\n\n const typeDistribution = employees.reduce<Record<string, number>>((acc, employee) => {\n const key = employee.type.replace('_', ' ');\n acc[key] = (acc[key] || 0) + 1;\n return acc;\n }, {});\n\n // Only real, store-backed cost lines (no invented coefficients).\n const costBreakdown = useMemo<CostItem[]>(() => {\n const costs: Array<{ category: string; amount: number }> = [\n { category: 'Net Payroll', amount: totalPayroll },\n {\n category: 'Project Delivery',\n amount: projects.reduce((sum, project) => sum + project.spent, 0),\n },\n ];\n const total = costs.reduce((sum, item) => sum + item.amount, 0) || 1;\n return costs.map((item) => ({\n ...item,\n percentage: Math.round((item.amount / total) * 100),\n }));\n }, [projects, totalPayroll]);\n\n const departmentColumns: ResponsiveTableColumn<Department>[] = [\n {\n key: 'name',\n header: 'Department',\n priority: 'primary',\n cell: (department) => <span className=\"font-medium\">{department.name}</span>,\n },\n {\n key: 'head',\n header: 'Head',\n priority: 'secondary',\n cell: (department) => <span className=\"text-text-secondary\">{department.headName}</span>,\n },\n {\n key: 'employees',\n header: 'Employees',\n priority: 'secondary',\n cell: (department) => (\n <span className=\"md:block md:text-right\">{department.employeeCount}</span>\n ),\n },\n {\n key: 'budget',\n header: 'Budget',\n priority: 'secondary',\n cell: (department) => (\n <span className=\"md:block md:text-right\">${(department.budget / 1000000).toFixed(1)}M</span>\n ),\n },\n {\n key: 'status',\n header: 'Status',\n priority: 'primary',\n cell: (department) => (\n <Badge variant={department.status === 'active' ? 'default' : 'secondary'}>\n {department.status}\n </Badge>\n ),\n },\n ];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Dashboard Analytics</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Workforce analytics and operational insights</p>\n <PagePurpose className=\"mt-1\">\n A consolidated analytics view across your organization — use it to monitor the metrics\n that matter most without digging through separate reports.\n </PagePurpose>\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\">Total Headcount</CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{employees.length}</div>\n <div className=\"flex items-center text-xs text-status-success-text\">\n <TrendingUp className=\"mr-1 h-3 w-3\" />\n Live workforce count\n </div>\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\">Avg Salary</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${avgSalary.toLocaleString()}</div>\n <div className=\"flex items-center text-xs text-status-success-text\">\n <TrendingUp className=\"mr-1 h-3 w-3\" />\n Updated from employee records\n </div>\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\">Attrition Rate</CardTitle>\n <TrendingDown className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {Math.round(\n (employees.filter((employee) => employee.status === 'terminated').length /\n Math.max(employees.length, 1)) *\n 100\n )}\n %\n </div>\n <div className=\"flex items-center text-xs text-status-success-text\">\n <TrendingDown className=\"mr-1 h-3 w-3\" />\n Calculated from status mix\n </div>\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\">Open Roles</CardTitle>\n <Target className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{activePostings}</div>\n <p className=\"text-xs text-text-secondary\">Based on active job postings</p>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-7\">\n <Card className=\"col-span-4\">\n <CardHeader>\n <CardTitle>Headcount Trend</CardTitle>\n <CardDescription>Monthly headcount over recent months</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {monthlyTrends.map((trend, index) => (\n <div key={`${trend.month}-${index}`} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-sm text-text-secondary\">{trend.month}</span>\n <div className=\"h-4 flex-1 overflow-hidden rounded bg-bg-sunken\">\n <div\n className=\"h-4 rounded bg-action-primary-bg\"\n style={{ width: `${Math.round((trend.headcount / maxTrend) * 100)}%` }}\n />\n </div>\n <span className=\"w-10 text-right text-sm font-medium\">{trend.headcount}</span>\n <div className=\"flex w-24 gap-1\">\n <Badge variant=\"default\" className=\"text-[10px]\">\n +{trend.hires}\n </Badge>\n <Badge variant=\"destructive\" className=\"text-[10px]\">\n -{trend.attrition}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card className=\"col-span-3\">\n <CardHeader>\n <CardTitle>Employee Types</CardTitle>\n <CardDescription>Distribution by employment type</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {Object.entries(typeDistribution)\n .sort(([, a], [, b]) => b - a)\n .map(([type, count]) => (\n <div key={type} className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <BarChart3 className=\"h-4 w-4 text-text-secondary\" />\n <span className=\"text-sm capitalize\">{type}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium\">{count}</span>\n <span className=\"text-xs text-text-secondary\">\n ({Math.round((count / Math.max(employees.length, 1)) * 100)}%)\n </span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Workforce Cost Breakdown</CardTitle>\n <CardDescription>Operational costs by category</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {costBreakdown.map((item) => (\n <div key={item.category} className=\"flex items-center gap-4\">\n <span className=\"w-48 text-sm text-text-secondary\">{item.category}</span>\n <div className=\"h-3 flex-1 overflow-hidden rounded bg-bg-sunken\">\n <div\n className=\"h-3 rounded bg-action-primary-bg/80\"\n style={{ width: `${item.percentage}%` }}\n />\n </div>\n <span className=\"w-24 text-right text-sm font-medium\">\n ${(item.amount / 1000).toFixed(0)}K\n </span>\n <span className=\"w-10 text-right text-xs text-text-secondary\">\n {item.percentage}%\n </span>\n </div>\n ))}\n </div>\n <div className=\"mt-4 flex justify-between border-t pt-4 text-sm\">\n <span className=\"font-medium\">Total Monthly Cost</span>\n <span className=\"font-bold\">\n ${(costBreakdown.reduce((sum, item) => sum + item.amount, 0) / 1000).toFixed(0)}K\n </span>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Department Overview</CardTitle>\n <CardDescription>Key metrics by department</CardDescription>\n </CardHeader>\n <CardContent>\n <ResponsiveTable\n columns={departmentColumns}\n data={departments}\n rowKey={(department) => department.id}\n />\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":";;;;;;AA8BA,SAAgB,IAA6B;CAC3C,IAAM,EAAE,cAAW,gBAAa,gBAAa,mBAAgB,gBAAa,GAAqB,EAEzF,IAAgB,QAA8B;AAClD,MAAI,EAAU,WAAW,EACvB,QAAO,EAAE;EAEX,IAAM,KAAY,MAAkB;GAClC,IAAM,IAAO,IAAI,KAAK,EAAM;AAC5B,UAAO,GAAG,EAAK,aAAa,CAAC,GAAG,OAAO,EAAK,UAAU,CAAC,CAAC,SAAS,GAAG,IAAI;;AAK1E,SAHuB,MAAM,KAAK,IAAI,IAAI,EAAU,KAAK,MAAS,EAAS,EAAK,UAAU,CAAC,CAAC,CAAC,CAC1F,MAAM,CACN,MAAM,GAAG,CACU,KAAK,MAAQ;GACjC,IAAM,CAAC,GAAM,KAAS,EAAI,MAAM,IAAI,CAAC,IAAI,OAAO,EAC1C,IAAW,IAAI,KAAK,GAAM,IAAQ,GAAG,EAAE,CAAC,SAAS,EACjD,IAAQ,IAAI,KAAK,GAAM,GAAO,EAAE,CAAC,eAAe,SAAS;IAC7D,OAAO;IACP,MAAM;IACP,CAAC,EAEI,IAAY,EAAU,QACzB,MAAS,IAAI,KAAK,EAAK,UAAU,CAAC,SAAS,IAAI,KAAY,EAAK,WAAW,aAC7E,CAAC;AAKF,UAAO;IAAE,OAAO;IAAO,OAJT,EAAU,QAAQ,MAAS,EAAS,EAAK,UAAU,KAAK,EAAI,CAAC;IAI7C,WAHZ,EAAU,QACzB,MAAS,EAAK,WAAW,gBAAgB,EAAS,EAAK,UAAU,KAAK,EACxE,CAAC;IACuC;IAAW;IACpD;IACD,CAAC,EAAU,CAAC,EAET,IAAW,KAAK,IAAI,GAAG,GAAG,EAAc,KAAK,MAAU,EAAM,UAAU,CAAC,EAExE,IAAe,EAAe,QAAQ,GAAK,MAAW,IAAM,EAAO,QAAQ,EAAE,EAC7E,IAAY,KAAK,MACrB,EAAU,QAAQ,GAAK,MAAa,IAAM,EAAS,QAAQ,EAAE,GAAG,KAAK,IAAI,EAAU,QAAQ,EAAE,CAC9F,EACK,IAAiB,EAAY,QAAQ,MAAY,EAAQ,WAAW,SAAS,CAAC,QAE9E,IAAmB,EAAU,QAAgC,GAAK,MAAa;EACnF,IAAM,IAAM,EAAS,KAAK,QAAQ,KAAK,IAAI;AAE3C,SADA,EAAI,MAAQ,EAAI,MAAQ,KAAK,GACtB;IACN,EAAE,CAAC,EAGA,IAAgB,QAA0B;EAC9C,IAAM,IAAqD,CACzD;GAAE,UAAU;GAAe,QAAQ;GAAc,EACjD;GACE,UAAU;GACV,QAAQ,EAAS,QAAQ,GAAK,MAAY,IAAM,EAAQ,OAAO,EAAE;GAClE,CACF,EACK,IAAQ,EAAM,QAAQ,GAAK,MAAS,IAAM,EAAK,QAAQ,EAAE,IAAI;AACnE,SAAO,EAAM,KAAK,OAAU;GAC1B,GAAG;GACH,YAAY,KAAK,MAAO,EAAK,SAAS,IAAS,IAAI;GACpD,EAAE;IACF,CAAC,GAAU,EAAa,CAAC;AA2C5B,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD,EAAA,UAAA;IACE,kBAAC,MAAD;KAAI,WAAU;eACZ,kBAAC,GAAD,EAAA,UAAc,uBAAkC,CAAA;KAC7C,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eAA8B;KAAgD,CAAA;IAC3F,kBAAC,GAAD;KAAa,WAAU;eAAO;KAGhB,CAAA;IACV,EAAA,CAAA;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MAAW,WAAU;MAAQ,MAAA;MAAK,WAAU;gBAA5C,CACE,kBAAC,GAAD;OAAY,WAAU;iBAAtB,CACE,kBAAC,GAAD;QAAW,WAAU;kBAAsB;QAA2B,CAAA,EACtE,kBAAC,GAAD,EAAO,WAAU,+BAAgC,CAAA,CACtC;UACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAmC,EAAU;OAAa,CAAA,EACzE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAY,WAAU,gBAAiB,CAAA,EAAA,uBAEnC;SACM,EAAA,CAAA,CACJ;;KACZ,kBAAC,GAAD;MAAW,WAAU;MAAS,WAAU;gBAAxC,CACE,kBAAC,GAAD;OAAY,WAAU;iBAAtB,CACE,kBAAC,GAAD;QAAW,WAAU;kBAAsB;QAAsB,CAAA,EACjE,kBAAC,GAAD,EAAY,WAAU,+BAAgC,CAAA,CAC3C;UACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CAAiD,KAAE,EAAU,gBAAgB,CAAO;UACpF,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAY,WAAU,gBAAiB,CAAA,EAAA,gCAEnC;SACM,EAAA,CAAA,CACJ;;KACZ,kBAAC,GAAD;MAAW,WAAU;MAAS,WAAU;gBAAxC,CACE,kBAAC,GAAD;OAAY,WAAU;iBAAtB,CACE,kBAAC,GAAD;QAAW,WAAU;kBAAsB;QAA0B,CAAA,EACrE,kBAAC,GAAD,EAAc,WAAU,+BAAgC,CAAA,CAC7C;UACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACG,KAAK,MACH,EAAU,QAAQ,MAAa,EAAS,WAAW,aAAa,CAAC,SAChE,KAAK,IAAI,EAAU,QAAQ,EAAE,GAC7B,IACH,EAAC,IAEE;UACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAc,WAAU,gBAAiB,CAAA,EAAA,6BAErC;SACM,EAAA,CAAA,CACJ;;KACZ,kBAAC,GAAD;MAAW,WAAU;MAAS,WAAU;gBAAxC,CACE,kBAAC,GAAD;OAAY,WAAU;iBAAtB,CACE,kBAAC,GAAD;QAAW,WAAU;kBAAsB;QAAsB,CAAA,EACjE,kBAAC,GAAD,EAAQ,WAAU,+BAAgC,CAAA,CACvC;UACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAmC;OAAqB,CAAA,EACvE,kBAAC,KAAD;OAAG,WAAU;iBAA8B;OAAgC,CAAA,CAC/D,EAAA,CAAA,CACJ;;KACR;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAM,WAAU;eAAhB,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAW,mBAA2B,CAAA,EACtC,kBAAC,GAAD,EAAA,UAAiB,wCAAsD,CAAA,CAC5D,EAAA,CAAA,EACb,kBAAC,GAAD;MAAa,WAAU;gBACpB,EAAc,KAAK,GAAO,MACzB,kBAAC,OAAD;OAAqC,WAAU;iBAA/C;QACE,kBAAC,QAAD;SAAM,WAAU;mBAAoC,EAAM;SAAa,CAAA;QACvE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,OAAD;UACE,WAAU;UACV,OAAO,EAAE,OAAO,GAAG,KAAK,MAAO,EAAM,YAAY,IAAY,IAAI,CAAC,IAAI;UACtE,CAAA;SACE,CAAA;QACN,kBAAC,QAAD;SAAM,WAAU;mBAAuC,EAAM;SAAiB,CAAA;QAC9E,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UAAO,SAAQ;UAAU,WAAU;oBAAnC,CAAiD,KAC7C,EAAM,MACF;aACR,kBAAC,GAAD;UAAO,SAAQ;UAAc,WAAU;oBAAvC,CAAqD,KACjD,EAAM,UACF;YACJ;;QACF;SAjBI,GAAG,EAAM,MAAM,GAAG,IAiBtB,CACN;MACU,CAAA,CACT;QAEP,kBAAC,GAAD;KAAM,WAAU;eAAhB,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAW,kBAA0B,CAAA,EACrC,kBAAC,GAAD,EAAA,UAAiB,mCAAiD,CAAA,CACvD,EAAA,CAAA,EACb,kBAAC,GAAD;MAAa,WAAU;gBACpB,OAAO,QAAQ,EAAiB,CAC9B,MAAM,GAAG,IAAI,GAAG,OAAO,IAAI,EAAE,CAC7B,KAAK,CAAC,GAAM,OACX,kBAAC,OAAD;OAAgB,WAAU;iBAA1B,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD,EAAW,WAAU,+BAAgC,CAAA,EACrD,kBAAC,QAAD;SAAM,WAAU;mBAAsB;SAAY,CAAA,CAC9C;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAuB;SAAa,CAAA,EACpD,kBAAC,QAAD;SAAM,WAAU;mBAAhB;UAA8C;UAC1C,KAAK,MAAO,IAAQ,KAAK,IAAI,EAAU,QAAQ,EAAE,GAAI,IAAI;UAAC;UACvD;WACH;UACF;SAXI,EAWJ,CACN;MACQ,CAAA,CACT;OACH;;GAEN,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAW,4BAAoC,CAAA,EAC/C,kBAAC,GAAD,EAAA,UAAiB,iCAA+C,CAAA,CACrD,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAc,KAAK,MAClB,kBAAC,OAAD;KAAyB,WAAU;eAAnC;MACE,kBAAC,QAAD;OAAM,WAAU;iBAAoC,EAAK;OAAgB,CAAA;MACzE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,OAAD;QACE,WAAU;QACV,OAAO,EAAE,OAAO,GAAG,EAAK,WAAW,IAAI;QACvC,CAAA;OACE,CAAA;MACN,kBAAC,QAAD;OAAM,WAAU;iBAAhB;QAAsD;SACjD,EAAK,SAAS,KAAM,QAAQ,EAAE;QAAC;QAC7B;;MACP,kBAAC,QAAD;OAAM,WAAU;iBAAhB,CACG,EAAK,YAAW,IACZ;;MACH;OAdI,EAAK,SAcT,CACN;IACE,CAAA,EACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KAAM,WAAU;eAAc;KAAyB,CAAA,EACvD,kBAAC,QAAD;KAAM,WAAU;eAAhB;MAA4B;OACvB,EAAc,QAAQ,GAAK,MAAS,IAAM,EAAK,QAAQ,EAAE,GAAG,KAAM,QAAQ,EAAE;MAAC;MAC3E;OACH;MACM,EAAA,CAAA,CACT,EAAA,CAAA;GAEP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAW,uBAA+B,CAAA,EAC1C,kBAAC,GAAD,EAAA,UAAiB,6BAA2C,CAAA,CACjD,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IACE,SAlNqD;KAC7D;MACE,KAAK;MACL,QAAQ;MACR,UAAU;MACV,OAAO,MAAe,kBAAC,QAAD;OAAM,WAAU;iBAAe,EAAW;OAAY,CAAA;MAC7E;KACD;MACE,KAAK;MACL,QAAQ;MACR,UAAU;MACV,OAAO,MAAe,kBAAC,QAAD;OAAM,WAAU;iBAAuB,EAAW;OAAgB,CAAA;MACzF;KACD;MACE,KAAK;MACL,QAAQ;MACR,UAAU;MACV,OAAO,MACL,kBAAC,QAAD;OAAM,WAAU;iBAA0B,EAAW;OAAqB,CAAA;MAE7E;KACD;MACE,KAAK;MACL,QAAQ;MACR,UAAU;MACV,OAAO,MACL,kBAAC,QAAD;OAAM,WAAU;iBAAhB;QAAyC;SAAG,EAAW,SAAS,KAAS,QAAQ,EAAE;QAAC;QAAQ;;MAE/F;KACD;MACE,KAAK;MACL,QAAQ;MACR,UAAU;MACV,OAAO,MACL,kBAAC,GAAD;OAAO,SAAS,EAAW,WAAW,WAAW,YAAY;iBAC1D,EAAW;OACN,CAAA;MAEX;KACF;IA4KS,MAAM;IACN,SAAS,MAAe,EAAW;IACnC,CAAA,EACU,CAAA,CACT,EAAA,CAAA;GACH"}