@burdenoff/microfe-crewfoundry 2026.704.6 → 2026.707.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/crewfoundry/CrewFoundryRoutes.js +51 -43
- package/dist/crewfoundry/CrewFoundryRoutes.js.map +1 -1
- package/dist/crewfoundry/components/forms/formValues.js +5 -2
- package/dist/crewfoundry/components/forms/formValues.js.map +1 -1
- package/dist/crewfoundry/components/viz/AllocationBar.js +68 -0
- package/dist/crewfoundry/components/viz/AllocationBar.js.map +1 -0
- package/dist/crewfoundry/components/viz/AreaChart.js +102 -0
- package/dist/crewfoundry/components/viz/AreaChart.js.map +1 -0
- package/dist/crewfoundry/components/viz/AvatarStack.js +36 -0
- package/dist/crewfoundry/components/viz/AvatarStack.js.map +1 -0
- package/dist/crewfoundry/components/viz/BarChart.js +83 -0
- package/dist/crewfoundry/components/viz/BarChart.js.map +1 -0
- package/dist/crewfoundry/components/viz/CertificateCard.js +118 -0
- package/dist/crewfoundry/components/viz/CertificateCard.js.map +1 -0
- package/dist/crewfoundry/components/viz/DonutChart.js +109 -0
- package/dist/crewfoundry/components/viz/DonutChart.js.map +1 -0
- package/dist/crewfoundry/components/viz/HBarFunnel.js +54 -0
- package/dist/crewfoundry/components/viz/HBarFunnel.js.map +1 -0
- package/dist/crewfoundry/components/viz/Heatmap.js +91 -0
- package/dist/crewfoundry/components/viz/Heatmap.js.map +1 -0
- package/dist/crewfoundry/components/viz/KanbanBoard.js +50 -0
- package/dist/crewfoundry/components/viz/KanbanBoard.js.map +1 -0
- package/dist/crewfoundry/components/viz/LineChart.js +123 -0
- package/dist/crewfoundry/components/viz/LineChart.js.map +1 -0
- package/dist/crewfoundry/components/viz/OrgTree.js +83 -0
- package/dist/crewfoundry/components/viz/OrgTree.js.map +1 -0
- package/dist/crewfoundry/components/viz/PathSteps.js +68 -0
- package/dist/crewfoundry/components/viz/PathSteps.js.map +1 -0
- package/dist/crewfoundry/components/viz/ProgressRing.js +68 -0
- package/dist/crewfoundry/components/viz/ProgressRing.js.map +1 -0
- package/dist/crewfoundry/components/viz/RatingStars.js +51 -0
- package/dist/crewfoundry/components/viz/RatingStars.js.map +1 -0
- package/dist/crewfoundry/components/viz/SegmentedTabs.js +69 -0
- package/dist/crewfoundry/components/viz/SegmentedTabs.js.map +1 -0
- package/dist/crewfoundry/components/viz/SkillBar.js +3 -0
- package/dist/crewfoundry/components/viz/Sparkline.js +74 -0
- package/dist/crewfoundry/components/viz/Sparkline.js.map +1 -0
- package/dist/crewfoundry/components/viz/StatCard.js +60 -0
- package/dist/crewfoundry/components/viz/StatCard.js.map +1 -0
- package/dist/crewfoundry/components/viz/StepProgress.js +3 -0
- package/dist/crewfoundry/components/viz/Timeline.js +66 -0
- package/dist/crewfoundry/components/viz/Timeline.js.map +1 -0
- package/dist/crewfoundry/components/viz/index.js +23 -0
- package/dist/crewfoundry/components/viz/lib/Avatar.js +30 -0
- package/dist/crewfoundry/components/viz/lib/Avatar.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/CartesianFrame.js +119 -0
- package/dist/crewfoundry/components/viz/lib/CartesianFrame.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/ResponsiveSvg.js +35 -0
- package/dist/crewfoundry/components/viz/lib/ResponsiveSvg.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/format.js +21 -0
- package/dist/crewfoundry/components/viz/lib/format.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/geometry.js +69 -0
- package/dist/crewfoundry/components/viz/lib/geometry.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/hooks.js +39 -0
- package/dist/crewfoundry/components/viz/lib/hooks.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/palette.js +27 -0
- package/dist/crewfoundry/components/viz/lib/palette.js.map +1 -0
- package/dist/crewfoundry/lib/analytics.js +323 -0
- package/dist/crewfoundry/lib/analytics.js.map +1 -0
- package/dist/crewfoundry/lib/companyFinance.js +16 -0
- package/dist/crewfoundry/lib/companyFinance.js.map +1 -0
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +226 -283
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +107 -120
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +122 -162
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +121 -158
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +316 -211
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +75 -27
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +167 -165
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +168 -109
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +401 -290
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +0 -41
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +84 -75
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +368 -174
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +236 -201
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +369 -196
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +269 -270
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +210 -110
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +216 -178
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.js +385 -0
- package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.js.map +1 -0
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +189 -130
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +397 -241
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +262 -147
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +345 -167
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +98 -24
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +289 -108
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +221 -114
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +134 -135
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +148 -97
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +264 -157
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +85 -93
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +211 -122
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +94 -54
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +289 -140
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +169 -79
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +296 -125
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsResourcingPagePage.js +187 -0
- package/dist/crewfoundry/pages/ProjectsResourcingPagePage.js.map +1 -0
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +140 -78
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +93 -43
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +250 -98
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +142 -184
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/dist/crewfoundry/utils/cn.js +10 -0
- package/dist/crewfoundry/utils/cn.js.map +1 -0
- package/dist/crewfoundry/utils/courseProgress.js +46 -0
- package/dist/crewfoundry/utils/courseProgress.js.map +1 -0
- package/dist/node_modules/clsx/dist/clsx.js +18 -0
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { AvatarStack as t } from "../components/viz/AvatarStack.js";
|
|
3
|
+
import { SegmentedTabs as n } from "../components/viz/SegmentedTabs.js";
|
|
4
|
+
import "../components/viz/index.js";
|
|
5
|
+
import { FormModal as r, useFormModal as i } from "../components/forms/FormModal.js";
|
|
6
|
+
import { ConfirmDialog as a } from "../components/forms/ConfirmDialog.js";
|
|
7
|
+
import { getNumber as o, getTags as ee, getText as s, newClientId as c } from "../components/forms/formValues.js";
|
|
8
|
+
import { useState as l } from "react";
|
|
9
|
+
import { MapPin as te, Pencil as ne, Plus as re, Search as ie, Star as u, Trash2 as d, UserCheck as f, Users as p } from "lucide-react";
|
|
10
|
+
import { useNavigate as m } from "react-router-dom";
|
|
7
11
|
import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
8
|
-
import { Badge as
|
|
9
|
-
import { usePagination as
|
|
12
|
+
import { Badge as ae, Button as v, Card as oe, CardContent as y, CardHeader as b, CardTitle as x, GlassCard as S, GradientText as se, IllustratedEmptyState as ce, Input as le, PagePurpose as ue, Pagination as C, ResponsiveTable as w, Select as T, SelectContent as E, SelectItem as D, SelectTrigger as O, SelectValue as k } from "@burdenoff/fe-libs/ui";
|
|
13
|
+
import { usePagination as A } from "@burdenoff/fe-libs/shared/hooks";
|
|
10
14
|
//#region src/crewfoundry/pages/HrEmployeesPagePage.tsx
|
|
11
|
-
var
|
|
15
|
+
var j = [
|
|
12
16
|
{
|
|
13
17
|
name: "firstName",
|
|
14
18
|
label: "First name",
|
|
@@ -116,8 +120,15 @@ var F = [
|
|
|
116
120
|
name: "performanceScore",
|
|
117
121
|
label: "Performance score (0-5)",
|
|
118
122
|
type: "number"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: "skills",
|
|
126
|
+
label: "Skills",
|
|
127
|
+
type: "tags",
|
|
128
|
+
colSpan: 2,
|
|
129
|
+
placeholder: "Add a skill and press Enter"
|
|
119
130
|
}
|
|
120
|
-
],
|
|
131
|
+
], M = (e) => ({
|
|
121
132
|
firstName: e.firstName,
|
|
122
133
|
lastName: e.lastName,
|
|
123
134
|
email: e.email,
|
|
@@ -129,17 +140,20 @@ var F = [
|
|
|
129
140
|
status: e.status,
|
|
130
141
|
salary: e.salary,
|
|
131
142
|
startDate: e.startDate.slice(0, 10),
|
|
132
|
-
performanceScore: e.performanceScore
|
|
143
|
+
performanceScore: e.performanceScore,
|
|
144
|
+
skills: e.skills
|
|
133
145
|
});
|
|
134
|
-
function
|
|
135
|
-
let { employees:
|
|
136
|
-
let t = `${e.firstName} ${e.lastName} ${e.email} ${e.position}`.toLowerCase().includes(
|
|
137
|
-
return t && n;
|
|
138
|
-
}),
|
|
139
|
-
|
|
140
|
-
},
|
|
141
|
-
|
|
142
|
-
},
|
|
146
|
+
function N() {
|
|
147
|
+
let N = m(), { employees: P, addEmployee: F, updateEmployee: I, removeEmployee: L } = e(), [R, de] = l(""), [z, B] = l("all"), [V, H] = l("all"), U = i(), [W, G] = l(null), { page: fe, pageSize: K, offset: q, setPage: J } = A({ initialPageSize: 25 }), Y = [...new Set(P.map((e) => e.department))], X = P.filter((e) => e.status === "active").length, Z = P.filter((e) => e.status === "on_leave").length, Q = P.filter((e) => {
|
|
148
|
+
let t = `${e.firstName} ${e.lastName} ${e.email} ${e.position}`.toLowerCase().includes(R.toLowerCase()), n = z === "all" || e.department === z, r = V === "all" || e.status === V;
|
|
149
|
+
return t && n && r;
|
|
150
|
+
}), pe = Q.slice(q, q + K), me = (e) => {
|
|
151
|
+
de(e), J(1);
|
|
152
|
+
}, he = (e) => {
|
|
153
|
+
B(e), J(1);
|
|
154
|
+
}, ge = (e) => {
|
|
155
|
+
H(e), J(1);
|
|
156
|
+
}, _e = P.length > 0 ? (P.reduce((e, t) => e + t.performanceScore, 0) / P.length).toFixed(1) : "0.0", $ = U.context, ve = (e) => N(`../hr/employee-profile-page?id=${encodeURIComponent(e.id)}`);
|
|
143
157
|
return /* @__PURE__ */ _("div", {
|
|
144
158
|
className: "space-y-6 p-6",
|
|
145
159
|
children: [
|
|
@@ -148,136 +162,172 @@ function L() {
|
|
|
148
162
|
children: [/* @__PURE__ */ _("div", { children: [
|
|
149
163
|
/* @__PURE__ */ g("h1", {
|
|
150
164
|
className: "text-2xl font-semibold",
|
|
151
|
-
children: /* @__PURE__ */ g(
|
|
165
|
+
children: /* @__PURE__ */ g(se, { children: "Employee Directory" })
|
|
152
166
|
}),
|
|
153
167
|
/* @__PURE__ */ _("p", {
|
|
154
168
|
className: "text-sm text-text-secondary",
|
|
155
169
|
children: [
|
|
156
|
-
|
|
170
|
+
P.length,
|
|
157
171
|
" employees across ",
|
|
158
|
-
|
|
172
|
+
Y.length,
|
|
159
173
|
" departments"
|
|
160
174
|
]
|
|
161
175
|
}),
|
|
162
|
-
/* @__PURE__ */ g(
|
|
176
|
+
/* @__PURE__ */ g(ue, {
|
|
163
177
|
className: "mt-1",
|
|
164
178
|
children: "Your complete employee directory — search, filter, and review everyone on the team along with their role, department, and status."
|
|
165
179
|
})
|
|
166
|
-
] }), /* @__PURE__ */ _(
|
|
180
|
+
] }), /* @__PURE__ */ _(v, {
|
|
167
181
|
size: "sm",
|
|
168
|
-
onClick: () =>
|
|
169
|
-
children: [/* @__PURE__ */ g(
|
|
182
|
+
onClick: () => U.openModal(),
|
|
183
|
+
children: [/* @__PURE__ */ g(re, { className: "h-4 w-4 mr-1" }), "Add Employee"]
|
|
170
184
|
})]
|
|
171
185
|
}),
|
|
172
186
|
/* @__PURE__ */ _("div", {
|
|
173
187
|
className: "grid gap-4 md:grid-cols-4",
|
|
174
188
|
children: [
|
|
175
|
-
/* @__PURE__ */ _(
|
|
189
|
+
/* @__PURE__ */ _(S, {
|
|
176
190
|
treatment: "glass",
|
|
177
191
|
glow: !0,
|
|
178
192
|
className: "border-border-seam",
|
|
179
|
-
children: [/* @__PURE__ */ _(
|
|
193
|
+
children: [/* @__PURE__ */ _(b, {
|
|
180
194
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
181
|
-
children: [/* @__PURE__ */ g(
|
|
195
|
+
children: [/* @__PURE__ */ g(x, {
|
|
182
196
|
className: "text-sm font-medium",
|
|
183
197
|
children: "Total"
|
|
184
|
-
}), /* @__PURE__ */ g(
|
|
185
|
-
}), /* @__PURE__ */ g(
|
|
198
|
+
}), /* @__PURE__ */ g(p, { className: "h-4 w-4 text-text-secondary" })]
|
|
199
|
+
}), /* @__PURE__ */ g(y, { children: /* @__PURE__ */ g("div", {
|
|
186
200
|
className: "text-2xl font-bold tabular-nums",
|
|
187
|
-
children:
|
|
201
|
+
children: P.length
|
|
188
202
|
}) })]
|
|
189
203
|
}),
|
|
190
|
-
/* @__PURE__ */ _(
|
|
204
|
+
/* @__PURE__ */ _(S, {
|
|
191
205
|
treatment: "metric",
|
|
192
206
|
className: "border-border-seam",
|
|
193
|
-
children: [/* @__PURE__ */ _(
|
|
207
|
+
children: [/* @__PURE__ */ _(b, {
|
|
194
208
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
195
|
-
children: [/* @__PURE__ */ g(
|
|
209
|
+
children: [/* @__PURE__ */ g(x, {
|
|
196
210
|
className: "text-sm font-medium",
|
|
197
211
|
children: "Active"
|
|
198
|
-
}), /* @__PURE__ */ g(
|
|
199
|
-
}), /* @__PURE__ */ g(
|
|
212
|
+
}), /* @__PURE__ */ g(f, { className: "h-4 w-4 text-status-success-text" })]
|
|
213
|
+
}), /* @__PURE__ */ g(y, { children: /* @__PURE__ */ g("div", {
|
|
200
214
|
className: "text-2xl font-bold tabular-nums",
|
|
201
|
-
children:
|
|
215
|
+
children: X
|
|
202
216
|
}) })]
|
|
203
217
|
}),
|
|
204
|
-
/* @__PURE__ */ _(
|
|
218
|
+
/* @__PURE__ */ _(S, {
|
|
205
219
|
treatment: "metric",
|
|
206
220
|
className: "border-border-seam",
|
|
207
|
-
children: [/* @__PURE__ */ _(
|
|
221
|
+
children: [/* @__PURE__ */ _(b, {
|
|
208
222
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
209
|
-
children: [/* @__PURE__ */ g(
|
|
223
|
+
children: [/* @__PURE__ */ g(x, {
|
|
210
224
|
className: "text-sm font-medium",
|
|
211
225
|
children: "On Leave"
|
|
212
|
-
}), /* @__PURE__ */ g(
|
|
213
|
-
}), /* @__PURE__ */ g(
|
|
226
|
+
}), /* @__PURE__ */ g(p, { className: "h-4 w-4 text-status-warning-text" })]
|
|
227
|
+
}), /* @__PURE__ */ g(y, { children: /* @__PURE__ */ g("div", {
|
|
214
228
|
className: "text-2xl font-bold tabular-nums",
|
|
215
|
-
children:
|
|
229
|
+
children: Z
|
|
216
230
|
}) })]
|
|
217
231
|
}),
|
|
218
|
-
/* @__PURE__ */ _(
|
|
232
|
+
/* @__PURE__ */ _(S, {
|
|
219
233
|
treatment: "metric",
|
|
220
234
|
className: "border-border-seam",
|
|
221
|
-
children: [/* @__PURE__ */ _(
|
|
235
|
+
children: [/* @__PURE__ */ _(b, {
|
|
222
236
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
223
|
-
children: [/* @__PURE__ */ g(
|
|
237
|
+
children: [/* @__PURE__ */ g(x, {
|
|
224
238
|
className: "text-sm font-medium",
|
|
225
239
|
children: "Avg Rating"
|
|
226
|
-
}), /* @__PURE__ */ g(
|
|
227
|
-
}), /* @__PURE__ */ g(
|
|
240
|
+
}), /* @__PURE__ */ g(u, { className: "h-4 w-4 text-status-warning-text" })]
|
|
241
|
+
}), /* @__PURE__ */ g(y, { children: /* @__PURE__ */ g("div", {
|
|
228
242
|
className: "text-2xl font-bold tabular-nums",
|
|
229
|
-
children:
|
|
243
|
+
children: _e
|
|
230
244
|
}) })]
|
|
231
245
|
})
|
|
232
246
|
]
|
|
233
247
|
}),
|
|
234
248
|
/* @__PURE__ */ _("div", {
|
|
235
|
-
className: "flex flex-col gap-3
|
|
236
|
-
children: [/* @__PURE__ */
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
249
|
+
className: "flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between",
|
|
250
|
+
children: [/* @__PURE__ */ g(n, {
|
|
251
|
+
"aria-label": "Filter by status",
|
|
252
|
+
value: V,
|
|
253
|
+
onChange: ge,
|
|
254
|
+
tabs: [
|
|
255
|
+
{
|
|
256
|
+
id: "all",
|
|
257
|
+
label: "All",
|
|
258
|
+
count: P.length
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
id: "active",
|
|
262
|
+
label: "Active",
|
|
263
|
+
count: X
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
id: "on_leave",
|
|
267
|
+
label: "On Leave",
|
|
268
|
+
count: Z
|
|
269
|
+
}
|
|
270
|
+
]
|
|
271
|
+
}), /* @__PURE__ */ _("div", {
|
|
272
|
+
className: "flex flex-col gap-3 sm:flex-row",
|
|
273
|
+
children: [/* @__PURE__ */ _("div", {
|
|
274
|
+
className: "relative flex-1 sm:max-w-sm",
|
|
275
|
+
children: [/* @__PURE__ */ g(ie, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ g(le, {
|
|
276
|
+
placeholder: "Search employees...",
|
|
277
|
+
className: "pl-9",
|
|
278
|
+
value: R,
|
|
279
|
+
onChange: (e) => me(e.target.value)
|
|
280
|
+
})]
|
|
281
|
+
}), /* @__PURE__ */ _(T, {
|
|
282
|
+
value: z,
|
|
283
|
+
onValueChange: he,
|
|
284
|
+
children: [/* @__PURE__ */ g(O, {
|
|
285
|
+
className: "w-full sm:w-56",
|
|
286
|
+
"aria-label": "Filter by department",
|
|
287
|
+
children: /* @__PURE__ */ g(k, { placeholder: "All departments" })
|
|
288
|
+
}), /* @__PURE__ */ _(E, { children: [/* @__PURE__ */ g(D, {
|
|
289
|
+
value: "all",
|
|
290
|
+
children: "All departments"
|
|
291
|
+
}), Y.map((e) => /* @__PURE__ */ g(D, {
|
|
292
|
+
value: e,
|
|
293
|
+
children: e
|
|
294
|
+
}, e))] })]
|
|
243
295
|
})]
|
|
244
|
-
}), /* @__PURE__ */ _(k, {
|
|
245
|
-
value: H,
|
|
246
|
-
onValueChange: oe,
|
|
247
|
-
children: [/* @__PURE__ */ g(M, {
|
|
248
|
-
className: "w-full sm:w-56",
|
|
249
|
-
"aria-label": "Filter by department",
|
|
250
|
-
children: /* @__PURE__ */ g(N, { placeholder: "All departments" })
|
|
251
|
-
}), /* @__PURE__ */ _(A, { children: [/* @__PURE__ */ g(j, {
|
|
252
|
-
value: "all",
|
|
253
|
-
children: "All departments"
|
|
254
|
-
}), Z.map((e) => /* @__PURE__ */ g(j, {
|
|
255
|
-
value: e,
|
|
256
|
-
children: e
|
|
257
|
-
}, e))] })]
|
|
258
296
|
})]
|
|
259
297
|
}),
|
|
260
|
-
/* @__PURE__ */ g(
|
|
298
|
+
/* @__PURE__ */ g(oe, { children: /* @__PURE__ */ _(y, {
|
|
261
299
|
className: "space-y-4 p-4",
|
|
262
|
-
children: [/* @__PURE__ */ g(
|
|
263
|
-
data:
|
|
300
|
+
children: [/* @__PURE__ */ g(w, {
|
|
301
|
+
data: pe,
|
|
264
302
|
rowKey: (e) => e.id,
|
|
265
303
|
columns: [
|
|
266
304
|
{
|
|
267
305
|
key: "name",
|
|
268
|
-
header: "
|
|
306
|
+
header: "Employee",
|
|
269
307
|
priority: "primary",
|
|
270
|
-
cell: (e) => /* @__PURE__ */ _("div", {
|
|
271
|
-
className: "
|
|
272
|
-
children: [
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
308
|
+
cell: (e) => /* @__PURE__ */ _("div", {
|
|
309
|
+
className: "flex items-center gap-3",
|
|
310
|
+
children: [/* @__PURE__ */ g(t, {
|
|
311
|
+
people: [{
|
|
312
|
+
name: `${e.firstName} ${e.lastName}`,
|
|
313
|
+
avatarUrl: e.avatar
|
|
314
|
+
}],
|
|
315
|
+
size: 36
|
|
316
|
+
}), /* @__PURE__ */ _("div", {
|
|
317
|
+
className: "min-w-0",
|
|
318
|
+
children: [/* @__PURE__ */ _("p", {
|
|
319
|
+
className: "truncate font-medium",
|
|
320
|
+
children: [
|
|
321
|
+
e.firstName,
|
|
322
|
+
" ",
|
|
323
|
+
e.lastName
|
|
324
|
+
]
|
|
325
|
+
}), /* @__PURE__ */ g("p", {
|
|
326
|
+
className: "truncate text-xs text-text-secondary",
|
|
327
|
+
children: e.email
|
|
328
|
+
})]
|
|
329
|
+
})]
|
|
330
|
+
})
|
|
281
331
|
},
|
|
282
332
|
{
|
|
283
333
|
key: "position",
|
|
@@ -297,7 +347,7 @@ function L() {
|
|
|
297
347
|
header: "Location",
|
|
298
348
|
cell: (e) => /* @__PURE__ */ _("div", {
|
|
299
349
|
className: "flex items-center gap-1 text-text-secondary",
|
|
300
|
-
children: [/* @__PURE__ */ g(
|
|
350
|
+
children: [/* @__PURE__ */ g(te, { className: "h-3 w-3" }), /* @__PURE__ */ g("span", {
|
|
301
351
|
className: "truncate text-xs",
|
|
302
352
|
children: e.location
|
|
303
353
|
})]
|
|
@@ -312,98 +362,107 @@ function L() {
|
|
|
312
362
|
},
|
|
313
363
|
{
|
|
314
364
|
key: "rating",
|
|
315
|
-
header: "
|
|
316
|
-
cell: (e) =>
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
365
|
+
header: "Performance",
|
|
366
|
+
cell: (e) => {
|
|
367
|
+
let t = e.performanceScore >= 4 ? "text-status-success-text" : e.performanceScore >= 3 ? "text-status-warning-text" : "text-status-error-text";
|
|
368
|
+
return /* @__PURE__ */ _("div", {
|
|
369
|
+
className: "flex items-center gap-1.5",
|
|
370
|
+
children: [/* @__PURE__ */ g("span", {
|
|
371
|
+
className: `font-semibold tabular-nums ${t}`,
|
|
372
|
+
children: e.performanceScore.toFixed(1)
|
|
373
|
+
}), /* @__PURE__ */ g(u, { className: `h-3.5 w-3.5 fill-current ${t}` })]
|
|
374
|
+
});
|
|
375
|
+
}
|
|
320
376
|
},
|
|
321
377
|
{
|
|
322
378
|
key: "status",
|
|
323
379
|
header: "Status",
|
|
324
|
-
cell: (e) => /* @__PURE__ */ g(
|
|
380
|
+
cell: (e) => /* @__PURE__ */ g(ae, {
|
|
325
381
|
variant: e.status === "active" ? "default" : e.status === "on_leave" ? "secondary" : "destructive",
|
|
326
382
|
className: "text-[10px]",
|
|
327
383
|
children: e.status.replace("_", " ")
|
|
328
384
|
})
|
|
329
385
|
}
|
|
330
386
|
],
|
|
331
|
-
|
|
387
|
+
onRowClick: (e) => ve(e),
|
|
388
|
+
rowActions: (e) => /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g(v, {
|
|
332
389
|
variant: "ghost",
|
|
333
390
|
size: "sm",
|
|
334
391
|
className: "h-8 w-8 p-0",
|
|
335
392
|
"aria-label": `Edit ${e.firstName} ${e.lastName}`,
|
|
336
|
-
onClick: () =>
|
|
337
|
-
children: /* @__PURE__ */ g(
|
|
338
|
-
}), /* @__PURE__ */ g(
|
|
393
|
+
onClick: () => U.openModal(e),
|
|
394
|
+
children: /* @__PURE__ */ g(ne, { className: "h-4 w-4" })
|
|
395
|
+
}), /* @__PURE__ */ g(v, {
|
|
339
396
|
variant: "ghost",
|
|
340
397
|
size: "sm",
|
|
341
398
|
className: "h-8 w-8 p-0",
|
|
342
399
|
"aria-label": `Delete ${e.firstName} ${e.lastName}`,
|
|
343
|
-
onClick: () =>
|
|
344
|
-
children: /* @__PURE__ */ g(
|
|
400
|
+
onClick: () => G(e),
|
|
401
|
+
children: /* @__PURE__ */ g(d, { className: "h-4 w-4 text-status-error-text" })
|
|
345
402
|
})] }),
|
|
346
403
|
emptyState: /* @__PURE__ */ g("div", {
|
|
347
404
|
className: "p-6",
|
|
348
|
-
children: /* @__PURE__ */ g(
|
|
405
|
+
children: /* @__PURE__ */ g(ce, {
|
|
349
406
|
illustration: "empty-people",
|
|
350
407
|
title: "No employees match",
|
|
351
408
|
description: "Try a different search term or department filter."
|
|
352
409
|
})
|
|
353
410
|
})
|
|
354
|
-
}), Q.length >
|
|
355
|
-
page:
|
|
356
|
-
pageSize:
|
|
411
|
+
}), Q.length > K && /* @__PURE__ */ g(C, {
|
|
412
|
+
page: fe,
|
|
413
|
+
pageSize: K,
|
|
357
414
|
totalItems: Q.length,
|
|
358
|
-
onPageChange:
|
|
415
|
+
onPageChange: J
|
|
359
416
|
})]
|
|
360
417
|
}) }),
|
|
361
|
-
/* @__PURE__ */ g(
|
|
362
|
-
open:
|
|
363
|
-
onOpenChange:
|
|
418
|
+
/* @__PURE__ */ g(r, {
|
|
419
|
+
open: U.open,
|
|
420
|
+
onOpenChange: U.onOpenChange,
|
|
364
421
|
title: $ ? "Edit employee" : "Add employee",
|
|
365
422
|
description: $ ? "Update this team member’s profile details." : "Add a new team member to your directory.",
|
|
366
|
-
fields:
|
|
367
|
-
initialValues: $ ?
|
|
423
|
+
fields: j,
|
|
424
|
+
initialValues: $ ? M($) : void 0,
|
|
368
425
|
submitLabel: $ ? "Save changes" : "Add employee",
|
|
369
426
|
onSubmit: async (e) => {
|
|
370
427
|
let t = {
|
|
371
|
-
id: $?.id ??
|
|
372
|
-
firstName:
|
|
373
|
-
lastName:
|
|
374
|
-
email:
|
|
375
|
-
department:
|
|
376
|
-
position:
|
|
377
|
-
status:
|
|
378
|
-
type:
|
|
379
|
-
salary:
|
|
380
|
-
startDate:
|
|
381
|
-
location:
|
|
382
|
-
phone:
|
|
383
|
-
performanceScore:
|
|
428
|
+
id: $?.id ?? c(),
|
|
429
|
+
firstName: s(e, "firstName"),
|
|
430
|
+
lastName: s(e, "lastName"),
|
|
431
|
+
email: s(e, "email"),
|
|
432
|
+
department: s(e, "department"),
|
|
433
|
+
position: s(e, "position"),
|
|
434
|
+
status: s(e, "status"),
|
|
435
|
+
type: s(e, "type"),
|
|
436
|
+
salary: o(e, "salary"),
|
|
437
|
+
startDate: s(e, "startDate"),
|
|
438
|
+
location: s(e, "location"),
|
|
439
|
+
phone: s(e, "phone"),
|
|
440
|
+
performanceScore: o(e, "performanceScore"),
|
|
441
|
+
skills: ee(e, "skills"),
|
|
442
|
+
terminationDate: $?.terminationDate,
|
|
384
443
|
managerId: $?.managerId,
|
|
385
444
|
avatar: $?.avatar
|
|
386
445
|
};
|
|
387
|
-
$ ? await
|
|
446
|
+
$ ? await I($.id, t) : await F(t);
|
|
388
447
|
}
|
|
389
448
|
}),
|
|
390
|
-
/* @__PURE__ */ g(
|
|
391
|
-
open:
|
|
449
|
+
/* @__PURE__ */ g(a, {
|
|
450
|
+
open: W !== null,
|
|
392
451
|
onOpenChange: (e) => {
|
|
393
|
-
e ||
|
|
452
|
+
e || G(null);
|
|
394
453
|
},
|
|
395
454
|
title: "Delete employee?",
|
|
396
|
-
description:
|
|
455
|
+
description: W ? `${W.firstName} ${W.lastName} will be removed from the directory. This cannot be undone.` : void 0,
|
|
397
456
|
confirmLabel: "Delete",
|
|
398
457
|
destructive: !0,
|
|
399
458
|
onConfirm: async () => {
|
|
400
|
-
|
|
459
|
+
W && (await L(W.id), G(null));
|
|
401
460
|
}
|
|
402
461
|
})
|
|
403
462
|
]
|
|
404
463
|
});
|
|
405
464
|
}
|
|
406
465
|
//#endregion
|
|
407
|
-
export {
|
|
466
|
+
export { N as HrEmployeesPagePage };
|
|
408
467
|
|
|
409
468
|
//# sourceMappingURL=HrEmployeesPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HrEmployeesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HrEmployeesPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n Pagination,\n ResponsiveTable,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { MapPin, Pencil, Plus, Search, Star, Trash2, UserCheck, Users } from 'lucide-react';\nimport { useCrewFoundryStore, type Employee } 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';\n\nconst EMPLOYEE_FIELDS: FieldConfig[] = [\n { name: 'firstName', label: 'First name', type: 'text', required: true },\n { name: 'lastName', label: 'Last name', type: 'text', required: true },\n { name: 'email', label: 'Email', type: 'email', required: true, colSpan: 2 },\n { name: 'position', label: 'Position', type: 'text', required: true },\n { name: 'department', label: 'Department', type: 'text', required: true },\n { name: 'location', label: 'Location', type: 'text', required: true },\n { name: 'phone', label: 'Phone', type: 'text', required: true },\n {\n name: 'type',\n label: 'Employment type',\n type: 'select',\n required: true,\n options: [\n { label: 'Full time', value: 'full_time' },\n { label: 'Part time', value: 'part_time' },\n { label: 'Contract', value: 'contract' },\n { label: 'Intern', value: 'intern' },\n ],\n },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n required: true,\n options: [\n { label: 'Active', value: 'active' },\n { label: 'Inactive', value: 'inactive' },\n { label: 'On leave', value: 'on_leave' },\n { label: 'Terminated', value: 'terminated' },\n ],\n },\n { name: 'salary', label: 'Annual salary', type: 'number', required: true },\n { name: 'startDate', label: 'Start date', type: 'date', required: true },\n { name: 'performanceScore', label: 'Performance score (0-5)', type: 'number' },\n];\n\nconst toFormValues = (employee: Employee): FormValues => ({\n firstName: employee.firstName,\n lastName: employee.lastName,\n email: employee.email,\n position: employee.position,\n department: employee.department,\n location: employee.location,\n phone: employee.phone,\n type: employee.type,\n status: employee.status,\n salary: employee.salary,\n startDate: employee.startDate.slice(0, 10),\n performanceScore: employee.performanceScore,\n});\n\nexport function HrEmployeesPagePage() {\n const { employees, addEmployee, updateEmployee, removeEmployee } = useCrewFoundryStore();\n const [search, setSearch] = useState('');\n const [filterDept, setFilterDept] = useState<string>('all');\n const form = useFormModal<Employee>();\n const [deleting, setDeleting] = useState<Employee | null>(null);\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 25 });\n\n const departments = [...new Set(employees.map((e) => e.department))];\n const filtered = employees.filter((e) => {\n const matchSearch = `${e.firstName} ${e.lastName} ${e.email} ${e.position}`\n .toLowerCase()\n .includes(search.toLowerCase());\n const matchDept = filterDept === 'all' || e.department === filterDept;\n return matchSearch && matchDept;\n });\n const pageItems = filtered.slice(offset, offset + pageSize);\n\n const handleSearchChange = (value: string) => {\n setSearch(value);\n setPage(1);\n };\n const handleDeptChange = (value: string) => {\n setFilterDept(value);\n setPage(1);\n };\n\n const activeCount = employees.filter((e) => e.status === 'active').length;\n const onLeaveCount = employees.filter((e) => e.status === 'on_leave').length;\n const avgRating =\n employees.length > 0\n ? (employees.reduce((s, e) => s + e.performanceScore, 0) / employees.length).toFixed(1)\n : '0.0';\n\n const editing = form.context;\n\n const handleSubmit = async (values: FormValues) => {\n const payload: Employee = {\n id: editing?.id ?? newClientId(),\n firstName: getText(values, 'firstName'),\n lastName: getText(values, 'lastName'),\n email: getText(values, 'email'),\n department: getText(values, 'department'),\n position: getText(values, 'position'),\n status: getText(values, 'status') as Employee['status'],\n type: getText(values, 'type') as Employee['type'],\n salary: getNumber(values, 'salary'),\n startDate: getText(values, 'startDate'),\n location: getText(values, 'location'),\n phone: getText(values, 'phone'),\n performanceScore: getNumber(values, 'performanceScore'),\n managerId: editing?.managerId,\n avatar: editing?.avatar,\n };\n if (editing) {\n await updateEmployee(editing.id, payload);\n } else {\n await addEmployee(payload);\n }\n };\n\n const columns: ResponsiveTableColumn<Employee>[] = [\n {\n key: 'name',\n header: 'Name',\n priority: 'primary',\n cell: (emp) => (\n <div>\n <p className=\"font-medium\">\n {emp.firstName} {emp.lastName}\n </p>\n <p className=\"text-xs text-text-secondary\">{emp.email}</p>\n </div>\n ),\n },\n {\n key: 'position',\n header: 'Position',\n cell: (emp) => <span className=\"text-text-secondary\">{emp.position}</span>,\n },\n {\n key: 'department',\n header: 'Department',\n cell: (emp) => <span>{emp.department}</span>,\n },\n {\n key: 'location',\n header: 'Location',\n cell: (emp) => (\n <div className=\"flex items-center gap-1 text-text-secondary\">\n <MapPin className=\"h-3 w-3\" />\n <span className=\"truncate text-xs\">{emp.location}</span>\n </div>\n ),\n },\n {\n key: 'salary',\n header: 'Salary',\n headerClassName: 'text-right',\n cellClassName: 'md:text-right',\n cell: (emp) => <span>${emp.salary.toLocaleString()}</span>,\n },\n {\n key: 'rating',\n header: 'Rating',\n cell: (emp) => (\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n <span>{emp.performanceScore}</span>\n </div>\n ),\n },\n {\n key: 'status',\n header: 'Status',\n cell: (emp) => (\n <Badge\n variant={\n emp.status === 'active'\n ? 'default'\n : emp.status === 'on_leave'\n ? 'secondary'\n : 'destructive'\n }\n className=\"text-[10px]\"\n >\n {emp.status.replace('_', ' ')}\n </Badge>\n ),\n },\n ];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Employee Directory</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {employees.length} employees across {departments.length} departments\n </p>\n <PagePurpose className=\"mt-1\">\n Your complete employee directory — search, filter, and review everyone on the team along\n with their role, department, and status.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => form.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Employee\n </Button>\n </div>\n\n <div className=\"grid gap-4 md: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</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 </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\">Active</CardTitle>\n <UserCheck className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{activeCount}</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\">On Leave</CardTitle>\n <Users className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{onLeaveCount}</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 Rating</CardTitle>\n <Star className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{avgRating}</div>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"flex flex-col gap-3 sm:flex-row\">\n <div className=\"relative flex-1 sm:max-w-sm\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder=\"Search employees...\"\n className=\"pl-9\"\n value={search}\n onChange={(e) => handleSearchChange(e.target.value)}\n />\n </div>\n <Select value={filterDept} onValueChange={handleDeptChange}>\n <SelectTrigger className=\"w-full sm:w-56\" aria-label=\"Filter by department\">\n <SelectValue placeholder=\"All departments\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All departments</SelectItem>\n {departments.map((dept) => (\n <SelectItem key={dept} value={dept}>\n {dept}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <Card>\n <CardContent className=\"space-y-4 p-4\">\n <ResponsiveTable<Employee>\n data={pageItems}\n rowKey={(emp) => emp.id}\n columns={columns}\n rowActions={(emp) => (\n <>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n aria-label={`Edit ${emp.firstName} ${emp.lastName}`}\n onClick={() => form.openModal(emp)}\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 ${emp.firstName} ${emp.lastName}`}\n onClick={() => setDeleting(emp)}\n >\n <Trash2 className=\"h-4 w-4 text-status-error-text\" />\n </Button>\n </>\n )}\n emptyState={\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title=\"No employees match\"\n description=\"Try a different search term or department filter.\"\n />\n </div>\n }\n />\n {filtered.length > pageSize && (\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={filtered.length}\n onPageChange={setPage}\n />\n )}\n </CardContent>\n </Card>\n\n <FormModal\n open={form.open}\n onOpenChange={form.onOpenChange}\n title={editing ? 'Edit employee' : 'Add employee'}\n description={\n editing\n ? 'Update this team member’s profile details.'\n : 'Add a new team member to your directory.'\n }\n fields={EMPLOYEE_FIELDS}\n initialValues={editing ? toFormValues(editing) : undefined}\n submitLabel={editing ? 'Save changes' : 'Add employee'}\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 employee?\"\n description={\n deleting\n ? `${deleting.firstName} ${deleting.lastName} will be removed from the directory. This cannot be undone.`\n : undefined\n }\n confirmLabel=\"Delete\"\n destructive\n onConfirm={async () => {\n if (deleting) {\n await removeEmployee(deleting.id);\n setDeleting(null);\n }\n }}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"HrEmployeesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HrEmployeesPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n Pagination,\n ResponsiveTable,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { MapPin, Pencil, Plus, Search, Star, Trash2, UserCheck, Users } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore, type Employee } from '../store/crewfoundryStore';\nimport { AvatarStack, SegmentedTabs } 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, getTags, getText, newClientId } from '../components/forms/formValues';\n\nconst EMPLOYEE_FIELDS: FieldConfig[] = [\n { name: 'firstName', label: 'First name', type: 'text', required: true },\n { name: 'lastName', label: 'Last name', type: 'text', required: true },\n { name: 'email', label: 'Email', type: 'email', required: true, colSpan: 2 },\n { name: 'position', label: 'Position', type: 'text', required: true },\n { name: 'department', label: 'Department', type: 'text', required: true },\n { name: 'location', label: 'Location', type: 'text', required: true },\n { name: 'phone', label: 'Phone', type: 'text', required: true },\n {\n name: 'type',\n label: 'Employment type',\n type: 'select',\n required: true,\n options: [\n { label: 'Full time', value: 'full_time' },\n { label: 'Part time', value: 'part_time' },\n { label: 'Contract', value: 'contract' },\n { label: 'Intern', value: 'intern' },\n ],\n },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n required: true,\n options: [\n { label: 'Active', value: 'active' },\n { label: 'Inactive', value: 'inactive' },\n { label: 'On leave', value: 'on_leave' },\n { label: 'Terminated', value: 'terminated' },\n ],\n },\n { name: 'salary', label: 'Annual salary', type: 'number', required: true },\n { name: 'startDate', label: 'Start date', type: 'date', required: true },\n { name: 'performanceScore', label: 'Performance score (0-5)', type: 'number' },\n {\n name: 'skills',\n label: 'Skills',\n type: 'tags',\n colSpan: 2,\n placeholder: 'Add a skill and press Enter',\n },\n];\n\nconst toFormValues = (employee: Employee): FormValues => ({\n firstName: employee.firstName,\n lastName: employee.lastName,\n email: employee.email,\n position: employee.position,\n department: employee.department,\n location: employee.location,\n phone: employee.phone,\n type: employee.type,\n status: employee.status,\n salary: employee.salary,\n startDate: employee.startDate.slice(0, 10),\n performanceScore: employee.performanceScore,\n skills: employee.skills,\n});\n\nexport function HrEmployeesPagePage() {\n const navigate = useNavigate();\n const { employees, addEmployee, updateEmployee, removeEmployee } = useCrewFoundryStore();\n const [search, setSearch] = useState('');\n const [filterDept, setFilterDept] = useState<string>('all');\n const [filterStatus, setFilterStatus] = useState<'all' | 'active' | 'on_leave'>('all');\n const form = useFormModal<Employee>();\n const [deleting, setDeleting] = useState<Employee | null>(null);\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 25 });\n\n const departments = [...new Set(employees.map((e) => e.department))];\n const activeCount = employees.filter((e) => e.status === 'active').length;\n const onLeaveCount = employees.filter((e) => e.status === 'on_leave').length;\n\n const filtered = employees.filter((e) => {\n const matchSearch = `${e.firstName} ${e.lastName} ${e.email} ${e.position}`\n .toLowerCase()\n .includes(search.toLowerCase());\n const matchDept = filterDept === 'all' || e.department === filterDept;\n const matchStatus = filterStatus === 'all' || e.status === filterStatus;\n return matchSearch && matchDept && matchStatus;\n });\n const pageItems = filtered.slice(offset, offset + pageSize);\n\n const handleSearchChange = (value: string) => {\n setSearch(value);\n setPage(1);\n };\n const handleDeptChange = (value: string) => {\n setFilterDept(value);\n setPage(1);\n };\n const handleStatusChange = (value: string) => {\n setFilterStatus(value as 'all' | 'active' | 'on_leave');\n setPage(1);\n };\n const avgRating =\n employees.length > 0\n ? (employees.reduce((s, e) => s + e.performanceScore, 0) / employees.length).toFixed(1)\n : '0.0';\n\n const editing = form.context;\n\n const openProfile = (employee: Employee) =>\n navigate(`../hr/employee-profile-page?id=${encodeURIComponent(employee.id)}`);\n\n const handleSubmit = async (values: FormValues) => {\n const payload: Employee = {\n id: editing?.id ?? newClientId(),\n firstName: getText(values, 'firstName'),\n lastName: getText(values, 'lastName'),\n email: getText(values, 'email'),\n department: getText(values, 'department'),\n position: getText(values, 'position'),\n status: getText(values, 'status') as Employee['status'],\n type: getText(values, 'type') as Employee['type'],\n salary: getNumber(values, 'salary'),\n startDate: getText(values, 'startDate'),\n location: getText(values, 'location'),\n phone: getText(values, 'phone'),\n performanceScore: getNumber(values, 'performanceScore'),\n skills: getTags(values, 'skills'),\n // Preserve the exit date on edit (there is no exit-date input here); new\n // employees have none. The store mapper passes it through when present.\n terminationDate: editing?.terminationDate,\n managerId: editing?.managerId,\n avatar: editing?.avatar,\n };\n if (editing) {\n await updateEmployee(editing.id, payload);\n } else {\n await addEmployee(payload);\n }\n };\n\n const columns: ResponsiveTableColumn<Employee>[] = [\n {\n key: 'name',\n header: 'Employee',\n priority: 'primary',\n cell: (emp) => (\n <div className=\"flex items-center gap-3\">\n <AvatarStack\n people={[{ name: `${emp.firstName} ${emp.lastName}`, avatarUrl: emp.avatar }]}\n size={36}\n />\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium\">\n {emp.firstName} {emp.lastName}\n </p>\n <p className=\"truncate text-xs text-text-secondary\">{emp.email}</p>\n </div>\n </div>\n ),\n },\n {\n key: 'position',\n header: 'Position',\n cell: (emp) => <span className=\"text-text-secondary\">{emp.position}</span>,\n },\n {\n key: 'department',\n header: 'Department',\n cell: (emp) => <span>{emp.department}</span>,\n },\n {\n key: 'location',\n header: 'Location',\n cell: (emp) => (\n <div className=\"flex items-center gap-1 text-text-secondary\">\n <MapPin className=\"h-3 w-3\" />\n <span className=\"truncate text-xs\">{emp.location}</span>\n </div>\n ),\n },\n {\n key: 'salary',\n header: 'Salary',\n headerClassName: 'text-right',\n cellClassName: 'md:text-right',\n cell: (emp) => <span>${emp.salary.toLocaleString()}</span>,\n },\n {\n key: 'rating',\n header: 'Performance',\n cell: (emp) => {\n const tone =\n emp.performanceScore >= 4\n ? 'text-status-success-text'\n : emp.performanceScore >= 3\n ? 'text-status-warning-text'\n : 'text-status-error-text';\n return (\n <div className=\"flex items-center gap-1.5\">\n <span className={`font-semibold tabular-nums ${tone}`}>\n {emp.performanceScore.toFixed(1)}\n </span>\n <Star className={`h-3.5 w-3.5 fill-current ${tone}`} />\n </div>\n );\n },\n },\n {\n key: 'status',\n header: 'Status',\n cell: (emp) => (\n <Badge\n variant={\n emp.status === 'active'\n ? 'default'\n : emp.status === 'on_leave'\n ? 'secondary'\n : 'destructive'\n }\n className=\"text-[10px]\"\n >\n {emp.status.replace('_', ' ')}\n </Badge>\n ),\n },\n ];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Employee Directory</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {employees.length} employees across {departments.length} departments\n </p>\n <PagePurpose className=\"mt-1\">\n Your complete employee directory — search, filter, and review everyone on the team along\n with their role, department, and status.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => form.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Employee\n </Button>\n </div>\n\n <div className=\"grid gap-4 md: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</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 </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\">Active</CardTitle>\n <UserCheck className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{activeCount}</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\">On Leave</CardTitle>\n <Users className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{onLeaveCount}</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 Rating</CardTitle>\n <Star className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{avgRating}</div>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <SegmentedTabs\n aria-label=\"Filter by status\"\n value={filterStatus}\n onChange={handleStatusChange}\n tabs={[\n { id: 'all', label: 'All', count: employees.length },\n { id: 'active', label: 'Active', count: activeCount },\n { id: 'on_leave', label: 'On Leave', count: onLeaveCount },\n ]}\n />\n <div className=\"flex flex-col gap-3 sm:flex-row\">\n <div className=\"relative flex-1 sm:max-w-sm\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder=\"Search employees...\"\n className=\"pl-9\"\n value={search}\n onChange={(e) => handleSearchChange(e.target.value)}\n />\n </div>\n <Select value={filterDept} onValueChange={handleDeptChange}>\n <SelectTrigger className=\"w-full sm:w-56\" aria-label=\"Filter by department\">\n <SelectValue placeholder=\"All departments\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All departments</SelectItem>\n {departments.map((dept) => (\n <SelectItem key={dept} value={dept}>\n {dept}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <Card>\n <CardContent className=\"space-y-4 p-4\">\n <ResponsiveTable<Employee>\n data={pageItems}\n rowKey={(emp) => emp.id}\n columns={columns}\n onRowClick={(emp) => openProfile(emp)}\n rowActions={(emp) => (\n <>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n aria-label={`Edit ${emp.firstName} ${emp.lastName}`}\n onClick={() => form.openModal(emp)}\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 ${emp.firstName} ${emp.lastName}`}\n onClick={() => setDeleting(emp)}\n >\n <Trash2 className=\"h-4 w-4 text-status-error-text\" />\n </Button>\n </>\n )}\n emptyState={\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title=\"No employees match\"\n description=\"Try a different search term or department filter.\"\n />\n </div>\n }\n />\n {filtered.length > pageSize && (\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={filtered.length}\n onPageChange={setPage}\n />\n )}\n </CardContent>\n </Card>\n\n <FormModal\n open={form.open}\n onOpenChange={form.onOpenChange}\n title={editing ? 'Edit employee' : 'Add employee'}\n description={\n editing\n ? 'Update this team member’s profile details.'\n : 'Add a new team member to your directory.'\n }\n fields={EMPLOYEE_FIELDS}\n initialValues={editing ? toFormValues(editing) : undefined}\n submitLabel={editing ? 'Save changes' : 'Add employee'}\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 employee?\"\n description={\n deleting\n ? `${deleting.firstName} ${deleting.lastName} will be removed from the directory. This cannot be undone.`\n : undefined\n }\n confirmLabel=\"Delete\"\n destructive\n onConfirm={async () => {\n if (deleting) {\n await removeEmployee(deleting.id);\n setDeleting(null);\n }\n }}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|