@burdenoff/microfe-crewfoundry 2026.704.5 → 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 (155) 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 +252 -249
  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 +35 -31
  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 +136 -133
  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/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
  119. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +85 -93
  120. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
  121. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +211 -122
  122. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
  123. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +94 -54
  124. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
  125. package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +28 -25
  126. package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
  127. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +290 -138
  128. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
  129. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +169 -79
  130. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
  131. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
  132. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +65 -61
  133. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
  134. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +296 -125
  135. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
  136. package/dist/crewfoundry/pages/ProjectsResourcingPagePage.js +187 -0
  137. package/dist/crewfoundry/pages/ProjectsResourcingPagePage.js.map +1 -0
  138. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +142 -76
  139. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
  140. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +93 -43
  141. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
  142. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
  143. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +250 -98
  144. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
  145. package/dist/crewfoundry/store/crewfoundryStore.js +1 -1
  146. package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
  147. package/dist/crewfoundry/utils/cn.js +10 -0
  148. package/dist/crewfoundry/utils/cn.js.map +1 -0
  149. package/dist/crewfoundry/utils/courseProgress.js +46 -0
  150. package/dist/crewfoundry/utils/courseProgress.js.map +1 -0
  151. package/dist/node_modules/clsx/dist/clsx.js +18 -0
  152. package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
  153. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
  154. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  155. package/package.json +1 -1
@@ -1,14 +1,18 @@
1
1
  import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
2
2
  import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
3
- import { FormModal as n, useFormModal as r } from "../components/forms/FormModal.js";
4
- import { ConfirmDialog as i } from "../components/forms/ConfirmDialog.js";
5
- import { getNumber as a, getText as o, newClientId as s } from "../components/forms/formValues.js";
6
- import { useState as c } from "react";
7
- import { Building2 as l, DollarSign as u, MapPin as d, Pencil as f, Plus as p, Trash2 as m, Users as h } from "lucide-react";
8
- import { jsx as g, jsxs as _ } from "react/jsx-runtime";
9
- import { Badge as v, Button as y, Card as b, CardContent as x, CardDescription as S, CardHeader as C, CardTitle as w, GlassCard as T, GradientText as E, PagePurpose as D, Separator as O } from "@burdenoff/fe-libs/ui";
3
+ import { StatCard as n } from "../components/viz/StatCard.js";
4
+ import { OrgTree as r } from "../components/viz/OrgTree.js";
5
+ import { AvatarStack as i } from "../components/viz/AvatarStack.js";
6
+ import "../components/viz/index.js";
7
+ import { FormModal as a, useFormModal as o } from "../components/forms/FormModal.js";
8
+ import { ConfirmDialog as s } from "../components/forms/ConfirmDialog.js";
9
+ import { getNumber as c, getText as l, newClientId as u } from "../components/forms/formValues.js";
10
+ import { useCallback as d, useMemo as f, useState as p } from "react";
11
+ import { Building2 as m, DollarSign as h, MapPin as g, Network as _, Pencil as v, Plus as y, Trash2 as b, Users as x } from "lucide-react";
12
+ import { jsx as S, jsxs as C } from "react/jsx-runtime";
13
+ import { Badge as w, Button as T, Card as E, CardContent as D, CardHeader as O, CardTitle as k, GlassCard as A, GradientText as j, PagePurpose as M } from "@burdenoff/fe-libs/ui";
10
14
  //#region src/crewfoundry/pages/HrDepartmentsPagePage.tsx
11
- var k = [
15
+ var N = (e) => `${e.firstName} ${e.lastName}`.trim(), P = [
12
16
  {
13
17
  name: "name",
14
18
  label: "Department name",
@@ -47,227 +51,261 @@ var k = [
47
51
  value: "restructuring"
48
52
  }]
49
53
  }
50
- ], A = (e) => ({
54
+ ], F = (e) => ({
51
55
  name: e.name,
52
56
  headName: e.headName,
53
57
  location: e.location,
54
58
  budget: e.budget,
55
59
  status: e.status
56
60
  });
57
- function j() {
58
- let { departments: j, employees: M, addDepartment: N, updateDepartment: P, removeDepartment: F } = e(), I = r(), [L, R] = c(null), z = j.reduce((e, t) => e + t.budget, 0), B = j.reduce((e, t) => e + t.employeeCount, 0), V = I.context;
59
- return /* @__PURE__ */ _("div", {
61
+ function I() {
62
+ let { departments: I, employees: L, teams: R, addDepartment: z, updateDepartment: B, removeDepartment: V } = e(), H = o(), [U, W] = p(null), G = I.reduce((e, t) => e + t.budget, 0), K = I.reduce((e, t) => e + t.employeeCount, 0), q = H.context, J = d((e) => L.find((t) => t.id === e.headId) || L.find((t) => N(t) === e.headName), [L]), Y = f(() => {
63
+ if (I.length === 0) return null;
64
+ let e = L.find((e) => !e.managerId && /chief|ceo|founder|president|head of company/i.test(e.position)), t = I.map((e) => {
65
+ let t = J(e), n = R.filter((t) => t.department === e.name), r;
66
+ return r = n.length > 0 ? n.slice(0, 4).map((e) => ({
67
+ id: e.id,
68
+ name: e.name,
69
+ role: `${e.memberCount} member${e.memberCount === 1 ? "" : "s"}`
70
+ })) : L.filter((n) => n.department === e.name && n.id !== t?.id).slice(0, 3).map((e) => ({
71
+ id: e.id,
72
+ name: N(e),
73
+ role: e.position,
74
+ avatarUrl: e.avatar
75
+ })), {
76
+ id: e.id,
77
+ name: e.name,
78
+ role: e.headName ? `${e.headName}, Head` : "Department",
79
+ avatarUrl: t?.avatar,
80
+ children: r
81
+ };
82
+ });
83
+ return {
84
+ id: e?.id ?? "org-root",
85
+ name: e ? N(e) : "Organization",
86
+ role: e?.position ?? "Company",
87
+ avatarUrl: e?.avatar,
88
+ children: t
89
+ };
90
+ }, [
91
+ I,
92
+ L,
93
+ R,
94
+ J
95
+ ]);
96
+ return /* @__PURE__ */ C("div", {
60
97
  className: "space-y-6 p-6",
61
98
  children: [
62
- /* @__PURE__ */ _("div", {
99
+ /* @__PURE__ */ C("div", {
63
100
  className: "flex items-center justify-between",
64
- children: [/* @__PURE__ */ _("div", { children: [
65
- /* @__PURE__ */ g("h1", {
101
+ children: [/* @__PURE__ */ C("div", { children: [
102
+ /* @__PURE__ */ S("h1", {
66
103
  className: "text-2xl font-semibold",
67
- children: /* @__PURE__ */ g(E, { children: "Departments" })
104
+ children: /* @__PURE__ */ S(j, { children: "Departments" })
68
105
  }),
69
- /* @__PURE__ */ g("p", {
106
+ /* @__PURE__ */ S("p", {
70
107
  className: "text-sm text-text-secondary",
71
108
  children: "Organizational structure and department management"
72
109
  }),
73
- /* @__PURE__ */ g(D, {
110
+ /* @__PURE__ */ S(M, {
74
111
  className: "mt-1",
75
112
  children: "Organize your company into departments — set up structure, assign heads, and see how headcount is distributed across the org."
76
113
  })
77
- ] }), /* @__PURE__ */ _(y, {
114
+ ] }), /* @__PURE__ */ C(T, {
78
115
  size: "sm",
79
- onClick: () => I.openModal(),
80
- children: [/* @__PURE__ */ g(p, { className: "h-4 w-4 mr-1" }), "Add Department"]
116
+ onClick: () => H.openModal(),
117
+ children: [/* @__PURE__ */ S(y, { className: "h-4 w-4 mr-1" }), "Add Department"]
81
118
  })]
82
119
  }),
83
- /* @__PURE__ */ _("div", {
120
+ /* @__PURE__ */ C("div", {
84
121
  className: "grid gap-4 md:grid-cols-3",
85
122
  children: [
86
- /* @__PURE__ */ _(T, {
87
- treatment: "glass",
88
- glow: !0,
89
- className: "border-border-seam",
90
- children: [/* @__PURE__ */ _(C, {
91
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
92
- children: [/* @__PURE__ */ g(w, {
93
- className: "text-sm font-medium",
94
- children: "Total Departments"
95
- }), /* @__PURE__ */ g(l, { className: "h-4 w-4 text-text-secondary" })]
96
- }), /* @__PURE__ */ g(x, { children: /* @__PURE__ */ g("div", {
97
- className: "text-2xl font-bold tabular-nums",
98
- children: j.length
99
- }) })]
123
+ /* @__PURE__ */ S(n, {
124
+ label: "Total Departments",
125
+ value: I.length,
126
+ icon: /* @__PURE__ */ S(m, { className: "h-4 w-4" })
100
127
  }),
101
- /* @__PURE__ */ _(T, {
102
- treatment: "metric",
103
- className: "border-border-seam",
104
- children: [/* @__PURE__ */ _(C, {
105
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
106
- children: [/* @__PURE__ */ g(w, {
107
- className: "text-sm font-medium",
108
- children: "Total Headcount"
109
- }), /* @__PURE__ */ g(h, { className: "h-4 w-4 text-text-secondary" })]
110
- }), /* @__PURE__ */ g(x, { children: /* @__PURE__ */ g("div", {
111
- className: "text-2xl font-bold tabular-nums",
112
- children: B
113
- }) })]
128
+ /* @__PURE__ */ S(n, {
129
+ label: "Total Headcount",
130
+ value: K,
131
+ icon: /* @__PURE__ */ S(x, { className: "h-4 w-4" })
114
132
  }),
115
- /* @__PURE__ */ _(T, {
116
- treatment: "metric",
117
- className: "border-border-seam",
118
- children: [/* @__PURE__ */ _(C, {
119
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
120
- children: [/* @__PURE__ */ g(w, {
121
- className: "text-sm font-medium",
122
- children: "Total Budget"
123
- }), /* @__PURE__ */ g(u, { className: "h-4 w-4 text-text-secondary" })]
124
- }), /* @__PURE__ */ g(x, { children: /* @__PURE__ */ _("div", {
125
- className: "text-2xl font-bold tabular-nums",
126
- children: [
127
- "$",
128
- (z / 1e6).toFixed(1),
129
- "M"
130
- ]
131
- }) })]
133
+ /* @__PURE__ */ S(n, {
134
+ label: "Total Budget",
135
+ value: `$${(G / 1e6).toFixed(1)}M`,
136
+ icon: /* @__PURE__ */ S(h, { className: "h-4 w-4" })
132
137
  })
133
138
  ]
134
139
  }),
135
- /* @__PURE__ */ g("div", {
136
- className: "grid gap-4 md:grid-cols-2",
137
- children: j.map((e) => {
138
- let n = M.filter((t) => t.department === e.name), r = n.length > 0 ? Math.round(n.reduce((e, t) => e + t.salary, 0) / n.length) : 0, i = n.length > 0 ? (n.reduce((e, t) => e + t.performanceScore, 0) / n.length).toFixed(1) : "0";
139
- return /* @__PURE__ */ _(b, { children: [/* @__PURE__ */ _(C, { children: [/* @__PURE__ */ _("div", {
140
- className: "flex items-center justify-between",
141
- children: [/* @__PURE__ */ g(w, {
142
- className: "text-lg",
143
- children: e.name
144
- }), /* @__PURE__ */ _("div", {
145
- className: "flex items-center gap-1",
140
+ /* @__PURE__ */ S("div", {
141
+ className: "grid gap-4 md:grid-cols-2 xl:grid-cols-3",
142
+ children: I.map((e) => {
143
+ let n = L.filter((t) => t.department === e.name), r = e.employeeCount || n.length, a = n.length > 0 ? Math.round(n.reduce((e, t) => e + t.salary, 0) / n.length) : 0, o = n.length > 0 ? n.reduce((e, t) => e + t.performanceScore, 0) / n.length : 0, s = Math.round(o / 5 * 100), c = J(e), l = s >= 80 ? "bg-status-success-text" : s >= 60 ? "bg-status-warning-text" : "bg-status-error-text";
144
+ return /* @__PURE__ */ C(A, {
145
+ treatment: "glass",
146
+ className: "border-border-seam",
147
+ children: [/* @__PURE__ */ S(O, { children: /* @__PURE__ */ C("div", {
148
+ className: "flex items-start justify-between gap-2",
149
+ children: [/* @__PURE__ */ C("div", {
150
+ className: "min-w-0",
151
+ children: [/* @__PURE__ */ S(k, {
152
+ className: "truncate text-lg",
153
+ children: e.name
154
+ }), /* @__PURE__ */ C("div", {
155
+ className: "mt-2 flex items-center gap-2",
156
+ children: [/* @__PURE__ */ S(i, {
157
+ people: [{
158
+ name: e.headName || "Unassigned",
159
+ avatarUrl: c?.avatar
160
+ }],
161
+ size: 28
162
+ }), /* @__PURE__ */ C("span", {
163
+ className: "truncate text-sm text-text-secondary",
164
+ children: [/* @__PURE__ */ S("span", {
165
+ className: "font-medium text-text-primary",
166
+ children: e.headName
167
+ }), e.headName ? ", Head" : "No head assigned"]
168
+ })]
169
+ })]
170
+ }), /* @__PURE__ */ C("div", {
171
+ className: "flex items-center gap-1",
172
+ children: [
173
+ /* @__PURE__ */ S(w, {
174
+ variant: e.status === "active" ? "default" : "secondary",
175
+ children: t(e.status)
176
+ }),
177
+ /* @__PURE__ */ S(T, {
178
+ variant: "ghost",
179
+ size: "sm",
180
+ className: "h-8 w-8 p-0",
181
+ "aria-label": `Edit ${e.name}`,
182
+ onClick: () => H.openModal(e),
183
+ children: /* @__PURE__ */ S(v, { className: "h-4 w-4" })
184
+ }),
185
+ /* @__PURE__ */ S(T, {
186
+ variant: "ghost",
187
+ size: "sm",
188
+ className: "h-8 w-8 p-0",
189
+ "aria-label": `Delete ${e.name}`,
190
+ onClick: () => W(e),
191
+ children: /* @__PURE__ */ S(b, { className: "h-4 w-4 text-status-error-text" })
192
+ })
193
+ ]
194
+ })]
195
+ }) }), /* @__PURE__ */ C(D, {
196
+ className: "space-y-4",
146
197
  children: [
147
- /* @__PURE__ */ g(v, {
148
- variant: e.status === "active" ? "default" : "secondary",
149
- children: t(e.status)
198
+ /* @__PURE__ */ C("div", {
199
+ className: "flex items-end justify-between gap-3",
200
+ children: [/* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("p", {
201
+ className: "text-3xl font-bold leading-none tabular-nums",
202
+ children: r
203
+ }), /* @__PURE__ */ S("p", {
204
+ className: "mt-1 text-xs text-text-secondary",
205
+ children: "Employees"
206
+ })] }), /* @__PURE__ */ C("div", {
207
+ className: "text-right",
208
+ children: [/* @__PURE__ */ C("p", {
209
+ className: "text-lg font-semibold tabular-nums",
210
+ children: [
211
+ "$",
212
+ (e.budget / 1e6).toFixed(1),
213
+ "M"
214
+ ]
215
+ }), /* @__PURE__ */ S("p", {
216
+ className: "text-xs text-text-secondary",
217
+ children: "Annual budget"
218
+ })]
219
+ })]
220
+ }),
221
+ /* @__PURE__ */ C("div", {
222
+ className: "space-y-1",
223
+ children: [/* @__PURE__ */ C("div", {
224
+ className: "flex items-center justify-between text-xs text-text-secondary",
225
+ children: [/* @__PURE__ */ S("span", { children: "Avg performance" }), /* @__PURE__ */ C("span", {
226
+ className: "font-medium text-text-primary tabular-nums",
227
+ children: [s, "%"]
228
+ })]
229
+ }), /* @__PURE__ */ S("div", {
230
+ className: "h-2 overflow-hidden rounded-full bg-bg-sunken",
231
+ children: /* @__PURE__ */ S("div", {
232
+ className: `h-2 rounded-full ${l}`,
233
+ style: { width: `${s}%` }
234
+ })
235
+ })]
150
236
  }),
151
- /* @__PURE__ */ g(y, {
152
- variant: "ghost",
153
- size: "sm",
154
- className: "h-8 w-8 p-0",
155
- "aria-label": `Edit ${e.name}`,
156
- onClick: () => I.openModal(e),
157
- children: /* @__PURE__ */ g(f, { className: "h-4 w-4" })
237
+ /* @__PURE__ */ C("div", {
238
+ className: "flex items-center justify-between text-xs text-text-secondary",
239
+ children: [/* @__PURE__ */ C("span", {
240
+ className: "flex items-center gap-1",
241
+ children: [/* @__PURE__ */ S(g, { className: "h-3 w-3" }), e.location]
242
+ }), /* @__PURE__ */ C("span", { children: [
243
+ "Cost/Head:",
244
+ " ",
245
+ r > 0 ? `$${Math.round(e.budget / r / 1e3)}K` : "—"
246
+ ] })]
158
247
  }),
159
- /* @__PURE__ */ g(y, {
160
- variant: "ghost",
161
- size: "sm",
162
- className: "h-8 w-8 p-0",
163
- "aria-label": `Delete ${e.name}`,
164
- onClick: () => R(e),
165
- children: /* @__PURE__ */ g(m, { className: "h-4 w-4 text-status-error-text" })
248
+ a > 0 && /* @__PURE__ */ C("p", {
249
+ className: "text-xs text-text-secondary",
250
+ children: ["Avg salary ", /* @__PURE__ */ C("span", {
251
+ className: "font-medium text-text-primary",
252
+ children: ["$", a.toLocaleString()]
253
+ })]
166
254
  })
167
255
  ]
168
256
  })]
169
- }), /* @__PURE__ */ _(S, {
170
- className: "flex items-center gap-1",
171
- children: [/* @__PURE__ */ g(d, { className: "h-3 w-3" }), e.location]
172
- })] }), /* @__PURE__ */ _(x, { children: [
173
- /* @__PURE__ */ _("div", {
174
- className: "grid grid-cols-2 gap-4 mb-4",
175
- children: [
176
- /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("p", {
177
- className: "text-xs text-text-secondary",
178
- children: "Department Head"
179
- }), /* @__PURE__ */ g("p", {
180
- className: "text-sm font-medium",
181
- children: e.headName
182
- })] }),
183
- /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("p", {
184
- className: "text-xs text-text-secondary",
185
- children: "Headcount"
186
- }), /* @__PURE__ */ _("p", {
187
- className: "text-sm font-medium",
188
- children: [e.employeeCount, " employees"]
189
- })] }),
190
- /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("p", {
191
- className: "text-xs text-text-secondary",
192
- children: "Annual Budget"
193
- }), /* @__PURE__ */ _("p", {
194
- className: "text-sm font-medium",
195
- children: [
196
- "$",
197
- (e.budget / 1e6).toFixed(1),
198
- "M"
199
- ]
200
- })] }),
201
- /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("p", {
202
- className: "text-xs text-text-secondary",
203
- children: "Avg Salary"
204
- }), /* @__PURE__ */ _("p", {
205
- className: "text-sm font-medium",
206
- children: ["$", r.toLocaleString()]
207
- })] })
208
- ]
209
- }),
210
- /* @__PURE__ */ g(O, { className: "mb-3" }),
211
- /* @__PURE__ */ _("div", {
212
- className: "flex items-center justify-between text-xs",
213
- children: [/* @__PURE__ */ _("span", {
214
- className: "text-text-secondary",
215
- children: [
216
- "Avg Performance: ",
217
- i,
218
- "/5"
219
- ]
220
- }), /* @__PURE__ */ _("span", {
221
- className: "text-text-secondary",
222
- children: [
223
- "Cost/Head:",
224
- " ",
225
- e.employeeCount > 0 ? `$${Math.round(e.budget / e.employeeCount / 1e3)}K` : "—"
226
- ]
227
- })]
228
- })
229
- ] })] }, e.id);
257
+ }, e.id);
230
258
  })
231
259
  }),
232
- /* @__PURE__ */ g(n, {
233
- open: I.open,
234
- onOpenChange: I.onOpenChange,
235
- title: V ? "Edit department" : "Add department",
236
- description: V ? "Update this department’s details." : "Create a new department in your organization.",
237
- fields: k,
238
- initialValues: V ? A(V) : void 0,
239
- submitLabel: V ? "Save changes" : "Add department",
260
+ Y && /* @__PURE__ */ C(E, { children: [/* @__PURE__ */ S(O, { children: /* @__PURE__ */ C(k, {
261
+ className: "flex items-center gap-2 text-lg",
262
+ children: [/* @__PURE__ */ S(_, { className: "h-4 w-4 text-text-secondary" }), "Org structure"]
263
+ }) }), /* @__PURE__ */ S(D, { children: /* @__PURE__ */ S("div", {
264
+ className: "overflow-x-auto pb-2",
265
+ children: /* @__PURE__ */ S("div", {
266
+ className: "min-w-fit",
267
+ children: /* @__PURE__ */ S(r, { root: Y })
268
+ })
269
+ }) })] }),
270
+ /* @__PURE__ */ S(a, {
271
+ open: H.open,
272
+ onOpenChange: H.onOpenChange,
273
+ title: q ? "Edit department" : "Add department",
274
+ description: q ? "Update this department’s details." : "Create a new department in your organization.",
275
+ fields: P,
276
+ initialValues: q ? F(q) : void 0,
277
+ submitLabel: q ? "Save changes" : "Add department",
240
278
  onSubmit: async (e) => {
241
279
  let t = {
242
- id: V?.id ?? s(),
243
- name: o(e, "name"),
244
- headId: V?.headId ?? "",
245
- headName: o(e, "headName"),
246
- employeeCount: V?.employeeCount ?? 0,
247
- budget: a(e, "budget"),
248
- location: o(e, "location"),
249
- status: o(e, "status")
280
+ id: q?.id ?? u(),
281
+ name: l(e, "name"),
282
+ headId: q?.headId ?? "",
283
+ headName: l(e, "headName"),
284
+ employeeCount: q?.employeeCount ?? 0,
285
+ budget: c(e, "budget"),
286
+ location: l(e, "location"),
287
+ status: l(e, "status")
250
288
  };
251
- V ? await P(V.id, t) : await N(t);
289
+ q ? await B(q.id, t) : await z(t);
252
290
  }
253
291
  }),
254
- /* @__PURE__ */ g(i, {
255
- open: L !== null,
292
+ /* @__PURE__ */ S(s, {
293
+ open: U !== null,
256
294
  onOpenChange: (e) => {
257
- e || R(null);
295
+ e || W(null);
258
296
  },
259
297
  title: "Delete department?",
260
- description: L ? `${L.name} will be removed. This cannot be undone.` : void 0,
298
+ description: U ? `${U.name} will be removed. This cannot be undone.` : void 0,
261
299
  confirmLabel: "Delete",
262
300
  destructive: !0,
263
301
  onConfirm: async () => {
264
- L && (await F(L.id), R(null));
302
+ U && (await V(U.id), W(null));
265
303
  }
266
304
  })
267
305
  ]
268
306
  });
269
307
  }
270
308
  //#endregion
271
- export { j as HrDepartmentsPagePage };
309
+ export { I as HrDepartmentsPagePage };
272
310
 
273
311
  //# sourceMappingURL=HrDepartmentsPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HrDepartmentsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HrDepartmentsPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport { Building2, DollarSign, MapPin, Pencil, Plus, Trash2, Users } from 'lucide-react';\nimport { useCrewFoundryStore, type Department } from '../store/crewfoundryStore';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { ConfirmDialog } from '../components/forms/ConfirmDialog';\nimport { getNumber, getText, newClientId } from '../components/forms/formValues';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nconst DEPARTMENT_FIELDS: FieldConfig[] = [\n { name: 'name', label: 'Department name', type: 'text', required: true, colSpan: 2 },\n { name: 'headName', label: 'Department head', type: 'text', required: true },\n { name: 'location', label: 'Location', type: 'text', required: true },\n { name: 'budget', label: 'Annual budget', type: 'number', required: true },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n required: true,\n options: [\n { label: 'Active', value: 'active' },\n { label: 'Restructuring', value: 'restructuring' },\n ],\n },\n];\n\nconst toFormValues = (department: Department): FormValues => ({\n name: department.name,\n headName: department.headName,\n location: department.location,\n budget: department.budget,\n status: department.status,\n});\n\nexport function HrDepartmentsPagePage() {\n const { departments, employees, addDepartment, updateDepartment, removeDepartment } =\n useCrewFoundryStore();\n const form = useFormModal<Department>();\n const [deleting, setDeleting] = useState<Department | null>(null);\n\n const totalBudget = departments.reduce((s, d) => s + d.budget, 0);\n const totalHeadcount = departments.reduce((s, d) => s + d.employeeCount, 0);\n\n const editing = form.context;\n\n const handleSubmit = async (values: FormValues) => {\n const payload: Department = {\n id: editing?.id ?? newClientId(),\n name: getText(values, 'name'),\n headId: editing?.headId ?? '',\n headName: getText(values, 'headName'),\n employeeCount: editing?.employeeCount ?? 0,\n budget: getNumber(values, 'budget'),\n location: getText(values, 'location'),\n status: getText(values, 'status') as Department['status'],\n };\n if (editing) {\n await updateDepartment(editing.id, payload);\n } else {\n await addDepartment(payload);\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>Departments</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Organizational structure and department management\n </p>\n <PagePurpose className=\"mt-1\">\n Organize your company into departments — set up structure, assign heads, and see how\n headcount is distributed across the org.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => form.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Department\n </Button>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\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 Departments</CardTitle>\n <Building2 className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{departments.length}</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\">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\">{totalHeadcount}</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\">Total Budget</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 ${(totalBudget / 1000000).toFixed(1)}M\n </div>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n {departments.map((dept) => {\n const deptEmps = employees.filter((e) => e.department === dept.name);\n const avgSalary =\n deptEmps.length > 0\n ? Math.round(deptEmps.reduce((s, e) => s + e.salary, 0) / deptEmps.length)\n : 0;\n const avgPerf =\n deptEmps.length > 0\n ? (deptEmps.reduce((s, e) => s + e.performanceScore, 0) / deptEmps.length).toFixed(1)\n : '0';\n\n return (\n <Card key={dept.id}>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-lg\">{dept.name}</CardTitle>\n <div className=\"flex items-center gap-1\">\n <Badge variant={dept.status === 'active' ? 'default' : 'secondary'}>\n {formatEnumLabel(dept.status)}\n </Badge>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n aria-label={`Edit ${dept.name}`}\n onClick={() => form.openModal(dept)}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n aria-label={`Delete ${dept.name}`}\n onClick={() => setDeleting(dept)}\n >\n <Trash2 className=\"h-4 w-4 text-status-error-text\" />\n </Button>\n </div>\n </div>\n <CardDescription className=\"flex items-center gap-1\">\n <MapPin className=\"h-3 w-3\" />\n {dept.location}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 gap-4 mb-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Department Head</p>\n <p className=\"text-sm font-medium\">{dept.headName}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Headcount</p>\n <p className=\"text-sm font-medium\">{dept.employeeCount} employees</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Annual Budget</p>\n <p className=\"text-sm font-medium\">${(dept.budget / 1000000).toFixed(1)}M</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Avg Salary</p>\n <p className=\"text-sm font-medium\">${avgSalary.toLocaleString()}</p>\n </div>\n </div>\n <Separator className=\"mb-3\" />\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"text-text-secondary\">Avg Performance: {avgPerf}/5</span>\n <span className=\"text-text-secondary\">\n Cost/Head:{' '}\n {dept.employeeCount > 0\n ? `$${Math.round(dept.budget / dept.employeeCount / 1000)}K`\n : '—'}\n </span>\n </div>\n </CardContent>\n </Card>\n );\n })}\n </div>\n\n <FormModal\n open={form.open}\n onOpenChange={form.onOpenChange}\n title={editing ? 'Edit department' : 'Add department'}\n description={\n editing\n ? 'Update this department’s details.'\n : 'Create a new department in your organization.'\n }\n fields={DEPARTMENT_FIELDS}\n initialValues={editing ? toFormValues(editing) : undefined}\n submitLabel={editing ? 'Save changes' : 'Add department'}\n onSubmit={handleSubmit}\n />\n\n <ConfirmDialog\n open={deleting !== null}\n onOpenChange={(open) => {\n if (!open) {\n setDeleting(null);\n }\n }}\n title=\"Delete department?\"\n description={\n deleting ? `${deleting.name} will be removed. This cannot be undone.` : undefined\n }\n confirmLabel=\"Delete\"\n destructive\n onConfirm={async () => {\n if (deleting) {\n await removeDepartment(deleting.id);\n setDeleting(null);\n }\n }}\n />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"HrDepartmentsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HrDepartmentsPagePage.tsx"],"sourcesContent":["import { useCallback, useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Building2, DollarSign, MapPin, Network, Pencil, Plus, Trash2, Users } from 'lucide-react';\nimport {\n useCrewFoundryStore,\n type Department,\n type Employee,\n} from '../store/crewfoundryStore';\nimport { AvatarStack, OrgTree, StatCard, type OrgNode } from '../components/viz';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { ConfirmDialog } from '../components/forms/ConfirmDialog';\nimport { getNumber, getText, newClientId } from '../components/forms/formValues';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nconst fullName = (employee: Employee): string => `${employee.firstName} ${employee.lastName}`.trim();\n\nconst DEPARTMENT_FIELDS: FieldConfig[] = [\n { name: 'name', label: 'Department name', type: 'text', required: true, colSpan: 2 },\n { name: 'headName', label: 'Department head', type: 'text', required: true },\n { name: 'location', label: 'Location', type: 'text', required: true },\n { name: 'budget', label: 'Annual budget', type: 'number', required: true },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n required: true,\n options: [\n { label: 'Active', value: 'active' },\n { label: 'Restructuring', value: 'restructuring' },\n ],\n },\n];\n\nconst toFormValues = (department: Department): FormValues => ({\n name: department.name,\n headName: department.headName,\n location: department.location,\n budget: department.budget,\n status: department.status,\n});\n\nexport function HrDepartmentsPagePage() {\n const { departments, employees, teams, addDepartment, updateDepartment, removeDepartment } =\n useCrewFoundryStore();\n const form = useFormModal<Department>();\n const [deleting, setDeleting] = useState<Department | null>(null);\n\n const totalBudget = departments.reduce((s, d) => s + d.budget, 0);\n const totalHeadcount = departments.reduce((s, d) => s + d.employeeCount, 0);\n\n const editing = form.context;\n\n // Resolve a department's head to a real employee (by id first, then by name) so\n // we can show a real avatar rather than a text-only name.\n const headOf = useCallback(\n (department: Department): Employee | undefined =>\n employees.find((e) => e.id === department.headId) ||\n employees.find((e) => fullName(e) === department.headName),\n [employees]\n );\n\n // Org structure: a real hierarchy derived from the roster + departments + teams.\n // Root = a top-of-org employee (CEO / founder / chief with no manager) when one\n // exists, else a generic company node. Each department hangs off the root with\n // its head; each department's children are its real teams (or a sample of its\n // real employees when the department has no teams).\n const orgRoot = useMemo<OrgNode | null>(() => {\n if (departments.length === 0) {\n return null;\n }\n const topLeader = employees.find(\n (e) => !e.managerId && /chief|ceo|founder|president|head of company/i.test(e.position)\n );\n\n const deptNodes: OrgNode[] = departments.map((department) => {\n const head = headOf(department);\n const deptTeams = teams.filter((team) => team.department === department.name);\n let children: OrgNode[];\n if (deptTeams.length > 0) {\n children = deptTeams.slice(0, 4).map((team) => ({\n id: team.id,\n name: team.name,\n role: `${team.memberCount} member${team.memberCount === 1 ? '' : 's'}`,\n }));\n } else {\n children = employees\n .filter((e) => e.department === department.name && e.id !== head?.id)\n .slice(0, 3)\n .map((e) => ({ id: e.id, name: fullName(e), role: e.position, avatarUrl: e.avatar }));\n }\n return {\n id: department.id,\n name: department.name,\n role: department.headName ? `${department.headName}, Head` : 'Department',\n avatarUrl: head?.avatar,\n children,\n };\n });\n\n return {\n id: topLeader?.id ?? 'org-root',\n name: topLeader ? fullName(topLeader) : 'Organization',\n role: topLeader?.position ?? 'Company',\n avatarUrl: topLeader?.avatar,\n children: deptNodes,\n };\n }, [departments, employees, teams, headOf]);\n\n const handleSubmit = async (values: FormValues) => {\n const payload: Department = {\n id: editing?.id ?? newClientId(),\n name: getText(values, 'name'),\n headId: editing?.headId ?? '',\n headName: getText(values, 'headName'),\n employeeCount: editing?.employeeCount ?? 0,\n budget: getNumber(values, 'budget'),\n location: getText(values, 'location'),\n status: getText(values, 'status') as Department['status'],\n };\n if (editing) {\n await updateDepartment(editing.id, payload);\n } else {\n await addDepartment(payload);\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>Departments</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Organizational structure and department management\n </p>\n <PagePurpose className=\"mt-1\">\n Organize your company into departments — set up structure, assign heads, and see how\n headcount is distributed across the org.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => form.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Department\n </Button>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <StatCard\n label=\"Total Departments\"\n value={departments.length}\n icon={<Building2 className=\"h-4 w-4\" />}\n />\n <StatCard\n label=\"Total Headcount\"\n value={totalHeadcount}\n icon={<Users className=\"h-4 w-4\" />}\n />\n <StatCard\n label=\"Total Budget\"\n value={`$${(totalBudget / 1000000).toFixed(1)}M`}\n icon={<DollarSign className=\"h-4 w-4\" />}\n />\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {departments.map((dept) => {\n const deptEmps = employees.filter((e) => e.department === dept.name);\n const headcount = dept.employeeCount || deptEmps.length;\n const avgSalary =\n deptEmps.length > 0\n ? Math.round(deptEmps.reduce((s, e) => s + e.salary, 0) / deptEmps.length)\n : 0;\n const avgPerfValue =\n deptEmps.length > 0\n ? deptEmps.reduce((s, e) => s + e.performanceScore, 0) / deptEmps.length\n : 0;\n // Progress bar = real average performance for the department, on a 0–100\n // scale (score out of 5). A clearly-labeled, computed metric — no fabrication.\n const perfPct = Math.round((avgPerfValue / 5) * 100);\n const head = headOf(dept);\n const perfTone =\n perfPct >= 80\n ? 'bg-status-success-text'\n : perfPct >= 60\n ? 'bg-status-warning-text'\n : 'bg-status-error-text';\n\n return (\n <GlassCard key={dept.id} treatment=\"glass\" className=\"border-border-seam\">\n <CardHeader>\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <CardTitle className=\"truncate text-lg\">{dept.name}</CardTitle>\n <div className=\"mt-2 flex items-center gap-2\">\n <AvatarStack\n people={[{ name: dept.headName || 'Unassigned', avatarUrl: head?.avatar }]}\n size={28}\n />\n <span className=\"truncate text-sm text-text-secondary\">\n <span className=\"font-medium text-text-primary\">{dept.headName}</span>\n {dept.headName ? ', Head' : 'No head assigned'}\n </span>\n </div>\n </div>\n <div className=\"flex items-center gap-1\">\n <Badge variant={dept.status === 'active' ? 'default' : 'secondary'}>\n {formatEnumLabel(dept.status)}\n </Badge>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n aria-label={`Edit ${dept.name}`}\n onClick={() => form.openModal(dept)}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n aria-label={`Delete ${dept.name}`}\n onClick={() => setDeleting(dept)}\n >\n <Trash2 className=\"h-4 w-4 text-status-error-text\" />\n </Button>\n </div>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"flex items-end justify-between gap-3\">\n <div>\n <p className=\"text-3xl font-bold leading-none tabular-nums\">{headcount}</p>\n <p className=\"mt-1 text-xs text-text-secondary\">Employees</p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-lg font-semibold tabular-nums\">\n ${(dept.budget / 1000000).toFixed(1)}M\n </p>\n <p className=\"text-xs text-text-secondary\">Annual budget</p>\n </div>\n </div>\n\n <div className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-xs text-text-secondary\">\n <span>Avg performance</span>\n <span className=\"font-medium text-text-primary tabular-nums\">{perfPct}%</span>\n </div>\n <div className=\"h-2 overflow-hidden rounded-full bg-bg-sunken\">\n <div className={`h-2 rounded-full ${perfTone}`} style={{ width: `${perfPct}%` }} />\n </div>\n </div>\n\n <div className=\"flex items-center justify-between text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <MapPin className=\"h-3 w-3\" />\n {dept.location}\n </span>\n <span>\n Cost/Head:{' '}\n {headcount > 0\n ? `$${Math.round(dept.budget / headcount / 1000)}K`\n : '—'}\n </span>\n </div>\n {avgSalary > 0 && (\n <p className=\"text-xs text-text-secondary\">\n Avg salary <span className=\"font-medium text-text-primary\">${avgSalary.toLocaleString()}</span>\n </p>\n )}\n </CardContent>\n </GlassCard>\n );\n })}\n </div>\n\n {orgRoot && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-lg\">\n <Network className=\"h-4 w-4 text-text-secondary\" />\n Org structure\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"overflow-x-auto pb-2\">\n <div className=\"min-w-fit\">\n <OrgTree root={orgRoot} />\n </div>\n </div>\n </CardContent>\n </Card>\n )}\n\n <FormModal\n open={form.open}\n onOpenChange={form.onOpenChange}\n title={editing ? 'Edit department' : 'Add department'}\n description={\n editing\n ? 'Update this department’s details.'\n : 'Create a new department in your organization.'\n }\n fields={DEPARTMENT_FIELDS}\n initialValues={editing ? toFormValues(editing) : undefined}\n submitLabel={editing ? 'Save changes' : 'Add department'}\n onSubmit={handleSubmit}\n />\n\n <ConfirmDialog\n open={deleting !== null}\n onOpenChange={(open) => {\n if (!open) {\n setDeleting(null);\n }\n }}\n title=\"Delete department?\"\n description={\n deleting ? `${deleting.name} will be removed. This cannot be undone.` : undefined\n }\n confirmLabel=\"Delete\"\n destructive\n onConfirm={async () => {\n if (deleting) {\n await removeDepartment(deleting.id);\n setDeleting(null);\n }\n }}\n />\n </div>\n );\n}\n"],"mappings":"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"}