@burdenoff/microfe-crewfoundry 2026.608.1 → 2026.625.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/pages/AdminAdminPagePage.js +94 -78
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +112 -96
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +101 -85
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +131 -115
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +116 -100
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +15 -15
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +63 -51
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +16 -16
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +26 -26
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +28 -28
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +10 -10
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +71 -59
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +59 -47
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +77 -61
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +40 -40
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +13 -13
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +102 -86
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +173 -139
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +59 -59
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +113 -97
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +45 -45
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +85 -69
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +23 -23
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +40 -40
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +59 -47
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +52 -48
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +31 -26
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +61 -49
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +83 -67
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +90 -74
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +90 -74
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +83 -67
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +54 -42
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +16 -16
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +39 -35
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +24 -24
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +14 -14
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +81 -65
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +73 -57
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +28 -28
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +12 -12
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +75 -59
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +57 -45
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +71 -59
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +48 -48
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +44 -43
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +58 -46
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +16 -16
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +23 -23
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +9 -9
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +43 -39
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +31 -27
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +59 -47
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +13 -13
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +66 -50
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +18 -18
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +74 -62
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +21 -21
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +47 -43
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +20 -20
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +58 -46
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +38 -34
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +14 -14
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +67 -67
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +16 -16
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/package.json +2 -2
|
@@ -2,11 +2,11 @@ import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
|
2
2
|
import { useMemo as t } from "react";
|
|
3
3
|
import { Award as n, BarChart3 as r, Clock as i, MapPin as a, Star as o, TrendingUp as s, UserCheck as c } from "lucide-react";
|
|
4
4
|
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
5
|
-
import { Badge as d, Card as f, CardContent as p, CardDescription as m, CardHeader as h, CardTitle as g } from "@burdenoff/fe-libs/ui";
|
|
5
|
+
import { Badge as d, Card as f, CardContent as p, CardDescription as m, CardHeader as h, CardTitle as g, GlassCard as _, GradientText as v } from "@burdenoff/fe-libs/ui";
|
|
6
6
|
//#region src/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.tsx
|
|
7
|
-
function
|
|
8
|
-
let { employees:
|
|
9
|
-
let e = Math.max(
|
|
7
|
+
function y() {
|
|
8
|
+
let { employees: y, departments: b } = e(), x = t(() => {
|
|
9
|
+
let e = Math.max(y.length, 1), t = (e) => Math.max(0, ((/* @__PURE__ */ new Date("2026-03-01")).getTime() - new Date(e).getTime()) / (1e3 * 60 * 60 * 24 * 365));
|
|
10
10
|
return [
|
|
11
11
|
{
|
|
12
12
|
range: "< 1 year",
|
|
@@ -34,7 +34,7 @@ function _() {
|
|
|
34
34
|
max: Infinity
|
|
35
35
|
}
|
|
36
36
|
].map((n) => {
|
|
37
|
-
let r =
|
|
37
|
+
let r = y.filter((e) => {
|
|
38
38
|
let r = t(e.startDate);
|
|
39
39
|
return r >= n.min && r < n.max;
|
|
40
40
|
}).length;
|
|
@@ -44,14 +44,14 @@ function _() {
|
|
|
44
44
|
percentage: Math.round(r / e * 100)
|
|
45
45
|
};
|
|
46
46
|
});
|
|
47
|
-
}, [
|
|
48
|
-
let e =
|
|
49
|
-
let t =
|
|
47
|
+
}, [y]), S = t(() => {
|
|
48
|
+
let e = b.map((e) => {
|
|
49
|
+
let t = y.filter((t) => t.department === e.name), n = t.length > 0 ? t.reduce((e, t) => e + t.performanceScore, 0) / t.length : 0;
|
|
50
50
|
return {
|
|
51
51
|
department: e.name,
|
|
52
52
|
score: n
|
|
53
53
|
};
|
|
54
|
-
}), t =
|
|
54
|
+
}), t = y.length > 0 ? y.reduce((e, t) => e + t.performanceScore, 0) / y.length : 0, n = y.length > 0 ? Math.min(5, Math.max(3, y.reduce((e, t) => e + t.salary, 0) / y.length / 3e4)) : 0;
|
|
55
55
|
return [
|
|
56
56
|
{
|
|
57
57
|
driver: "Workforce Performance",
|
|
@@ -84,15 +84,15 @@ function _() {
|
|
|
84
84
|
trend: "+0.4"
|
|
85
85
|
}
|
|
86
86
|
];
|
|
87
|
-
}, [
|
|
88
|
-
let t =
|
|
87
|
+
}, [b, y]), C = (y.reduce((e, t) => e + t.performanceScore, 0) / y.length).toFixed(1), w = Math.round(y.reduce((e, t) => e + t.salary, 0) / y.length), T = y.filter((e) => e.status === "active").length, E = y.filter((e) => e.status === "on_leave").length, D = b.map((e) => {
|
|
88
|
+
let t = y.filter((t) => t.department === e.name), n = t.length > 0 ? (t.reduce((e, t) => e + t.performanceScore, 0) / t.length).toFixed(1) : "0", r = t.length > 0 ? Math.round(t.reduce((e, t) => e + t.salary, 0) / t.length) : 0;
|
|
89
89
|
return {
|
|
90
90
|
name: e.name,
|
|
91
91
|
headcount: t.length,
|
|
92
92
|
avgScore: n,
|
|
93
93
|
avgSalary: r
|
|
94
94
|
};
|
|
95
|
-
}),
|
|
95
|
+
}), O = y.reduce((e, t) => (e[t.location] = (e[t.location] || 0) + 1, e), {});
|
|
96
96
|
return /* @__PURE__ */ u("div", {
|
|
97
97
|
className: "space-y-6 p-6",
|
|
98
98
|
children: [
|
|
@@ -100,73 +100,89 @@ function _() {
|
|
|
100
100
|
className: "flex items-center justify-between",
|
|
101
101
|
children: /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("h1", {
|
|
102
102
|
className: "text-2xl font-semibold",
|
|
103
|
-
children: "Employee Analytics"
|
|
103
|
+
children: /* @__PURE__ */ l(v, { children: "Employee Analytics" })
|
|
104
104
|
}), /* @__PURE__ */ l("p", {
|
|
105
|
-
className: "text-sm text-
|
|
105
|
+
className: "text-sm text-text-secondary",
|
|
106
106
|
children: "Deep-dive into employee performance, engagement, and demographics"
|
|
107
107
|
})] })
|
|
108
108
|
}),
|
|
109
109
|
/* @__PURE__ */ u("div", {
|
|
110
110
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
|
|
111
111
|
children: [
|
|
112
|
-
/* @__PURE__ */ u(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
className: "
|
|
149
|
-
children:
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
className: "
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
112
|
+
/* @__PURE__ */ u(_, {
|
|
113
|
+
treatment: "metric",
|
|
114
|
+
className: "border-border-seam",
|
|
115
|
+
children: [/* @__PURE__ */ u(h, {
|
|
116
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
117
|
+
children: [/* @__PURE__ */ l(g, {
|
|
118
|
+
className: "text-sm font-medium",
|
|
119
|
+
children: "Active Employees"
|
|
120
|
+
}), /* @__PURE__ */ l(c, { className: "h-4 w-4 text-text-secondary" })]
|
|
121
|
+
}), /* @__PURE__ */ u(p, { children: [/* @__PURE__ */ l("div", {
|
|
122
|
+
className: "text-2xl font-bold tabular-nums",
|
|
123
|
+
children: T
|
|
124
|
+
}), /* @__PURE__ */ u("p", {
|
|
125
|
+
className: "text-xs text-text-secondary",
|
|
126
|
+
children: [E, " currently on leave"]
|
|
127
|
+
})] })]
|
|
128
|
+
}),
|
|
129
|
+
/* @__PURE__ */ u(_, {
|
|
130
|
+
treatment: "metric",
|
|
131
|
+
className: "border-border-seam",
|
|
132
|
+
children: [/* @__PURE__ */ u(h, {
|
|
133
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
134
|
+
children: [/* @__PURE__ */ l(g, {
|
|
135
|
+
className: "text-sm font-medium",
|
|
136
|
+
children: "Avg Performance"
|
|
137
|
+
}), /* @__PURE__ */ l(o, { className: "h-4 w-4 text-text-secondary" })]
|
|
138
|
+
}), /* @__PURE__ */ u(p, { children: [/* @__PURE__ */ u("div", {
|
|
139
|
+
className: "text-2xl font-bold tabular-nums",
|
|
140
|
+
children: [C, "/5.0"]
|
|
141
|
+
}), /* @__PURE__ */ u("div", {
|
|
142
|
+
className: "flex items-center text-xs text-status-success-text",
|
|
143
|
+
children: [/* @__PURE__ */ l(s, { className: "h-3 w-3 mr-1" }), "+0.2 from last quarter"]
|
|
144
|
+
})] })]
|
|
145
|
+
}),
|
|
146
|
+
/* @__PURE__ */ u(_, {
|
|
147
|
+
treatment: "metric",
|
|
148
|
+
className: "border-border-seam",
|
|
149
|
+
children: [/* @__PURE__ */ u(h, {
|
|
150
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
151
|
+
children: [/* @__PURE__ */ l(g, {
|
|
152
|
+
className: "text-sm font-medium",
|
|
153
|
+
children: "Avg Compensation"
|
|
154
|
+
}), /* @__PURE__ */ l(r, { className: "h-4 w-4 text-text-secondary" })]
|
|
155
|
+
}), /* @__PURE__ */ u(p, { children: [/* @__PURE__ */ u("div", {
|
|
156
|
+
className: "text-2xl font-bold tabular-nums",
|
|
157
|
+
children: ["$", w.toLocaleString()]
|
|
158
|
+
}), /* @__PURE__ */ l("p", {
|
|
159
|
+
className: "text-xs text-text-secondary",
|
|
160
|
+
children: "Across all departments"
|
|
161
|
+
})] })]
|
|
162
|
+
}),
|
|
163
|
+
/* @__PURE__ */ u(_, {
|
|
164
|
+
treatment: "metric",
|
|
165
|
+
className: "border-border-seam",
|
|
166
|
+
children: [/* @__PURE__ */ u(h, {
|
|
167
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
168
|
+
children: [/* @__PURE__ */ l(g, {
|
|
169
|
+
className: "text-sm font-medium",
|
|
170
|
+
children: "Avg Tenure"
|
|
171
|
+
}), /* @__PURE__ */ l(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
172
|
+
}), /* @__PURE__ */ u(p, { children: [/* @__PURE__ */ l("div", {
|
|
173
|
+
className: "text-2xl font-bold tabular-nums",
|
|
174
|
+
children: "2.4 yrs"
|
|
175
|
+
}), /* @__PURE__ */ l("p", {
|
|
176
|
+
className: "text-xs text-text-secondary",
|
|
177
|
+
children: "Median: 2.1 years"
|
|
178
|
+
})] })]
|
|
179
|
+
})
|
|
164
180
|
]
|
|
165
181
|
}),
|
|
166
182
|
/* @__PURE__ */ u("div", {
|
|
167
183
|
className: "grid gap-4 md:grid-cols-2",
|
|
168
184
|
children: [/* @__PURE__ */ u(f, { children: [/* @__PURE__ */ u(h, { children: [/* @__PURE__ */ l(g, { children: "Department Performance" }), /* @__PURE__ */ l(m, { children: "Average performance score and compensation by department" })] }), /* @__PURE__ */ u(p, { children: [/* @__PURE__ */ u("div", {
|
|
169
|
-
className: "grid grid-cols-4 gap-2 text-xs font-medium text-
|
|
185
|
+
className: "grid grid-cols-4 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2",
|
|
170
186
|
children: [
|
|
171
187
|
/* @__PURE__ */ l("span", { children: "Department" }),
|
|
172
188
|
/* @__PURE__ */ l("span", {
|
|
@@ -182,7 +198,7 @@ function _() {
|
|
|
182
198
|
children: "Avg Salary"
|
|
183
199
|
})
|
|
184
200
|
]
|
|
185
|
-
}),
|
|
201
|
+
}), D.sort((e, t) => Number(t.avgScore) - Number(e.avgScore)).map((e) => /* @__PURE__ */ u("div", {
|
|
186
202
|
className: "grid grid-cols-4 gap-2 py-2 border-b last:border-0 text-sm",
|
|
187
203
|
children: [
|
|
188
204
|
/* @__PURE__ */ l("span", {
|
|
@@ -207,7 +223,7 @@ function _() {
|
|
|
207
223
|
]
|
|
208
224
|
}, e.name))] })] }), /* @__PURE__ */ u(f, { children: [/* @__PURE__ */ u(h, { children: [/* @__PURE__ */ l(g, { children: "Engagement Drivers" }), /* @__PURE__ */ l(m, { children: "Employee satisfaction by category" })] }), /* @__PURE__ */ l(p, {
|
|
209
225
|
className: "space-y-4",
|
|
210
|
-
children:
|
|
226
|
+
children: S.sort((e, t) => t.score - e.score).map((e) => /* @__PURE__ */ u("div", {
|
|
211
227
|
className: "space-y-1",
|
|
212
228
|
children: [/* @__PURE__ */ u("div", {
|
|
213
229
|
className: "flex justify-between text-sm",
|
|
@@ -217,14 +233,14 @@ function _() {
|
|
|
217
233
|
className: "font-medium",
|
|
218
234
|
children: [e.score, "/5"]
|
|
219
235
|
}), /* @__PURE__ */ l("span", {
|
|
220
|
-
className: "text-xs text-
|
|
236
|
+
className: "text-xs text-status-success-text",
|
|
221
237
|
children: e.trend
|
|
222
238
|
})]
|
|
223
239
|
})]
|
|
224
240
|
}), /* @__PURE__ */ l("div", {
|
|
225
|
-
className: "h-2 bg-
|
|
241
|
+
className: "h-2 bg-bg-sunken rounded overflow-hidden",
|
|
226
242
|
children: /* @__PURE__ */ l("div", {
|
|
227
|
-
className: `h-2 rounded ${e.score >= 4.5 ? "bg-
|
|
243
|
+
className: `h-2 rounded ${e.score >= 4.5 ? "bg-status-success-text" : e.score >= 4 ? "bg-status-info-text" : "bg-status-warning-text"}`,
|
|
228
244
|
style: { width: `${e.score / 5 * 100}%` }
|
|
229
245
|
})
|
|
230
246
|
})]
|
|
@@ -238,17 +254,17 @@ function _() {
|
|
|
238
254
|
children: [/* @__PURE__ */ l(i, { className: "h-4 w-4" }), "Tenure Distribution"]
|
|
239
255
|
}) }), /* @__PURE__ */ l(p, {
|
|
240
256
|
className: "space-y-3",
|
|
241
|
-
children:
|
|
257
|
+
children: x.map((e) => /* @__PURE__ */ u("div", {
|
|
242
258
|
className: "flex items-center gap-3",
|
|
243
259
|
children: [
|
|
244
260
|
/* @__PURE__ */ l("span", {
|
|
245
|
-
className: "w-20 text-sm text-
|
|
261
|
+
className: "w-20 text-sm text-text-secondary",
|
|
246
262
|
children: e.range
|
|
247
263
|
}),
|
|
248
264
|
/* @__PURE__ */ l("div", {
|
|
249
|
-
className: "flex-1 h-4 bg-
|
|
265
|
+
className: "flex-1 h-4 bg-bg-sunken rounded overflow-hidden",
|
|
250
266
|
children: /* @__PURE__ */ l("div", {
|
|
251
|
-
className: "h-4 bg-primary/70 rounded",
|
|
267
|
+
className: "h-4 bg-action-primary-bg/70 rounded",
|
|
252
268
|
style: { width: `${e.percentage}%` }
|
|
253
269
|
})
|
|
254
270
|
}),
|
|
@@ -257,7 +273,7 @@ function _() {
|
|
|
257
273
|
children: e.count
|
|
258
274
|
}),
|
|
259
275
|
/* @__PURE__ */ u("span", {
|
|
260
|
-
className: "text-xs text-
|
|
276
|
+
className: "text-xs text-text-secondary w-10 text-right",
|
|
261
277
|
children: [e.percentage, "%"]
|
|
262
278
|
})
|
|
263
279
|
]
|
|
@@ -267,7 +283,7 @@ function _() {
|
|
|
267
283
|
children: [/* @__PURE__ */ l(a, { className: "h-4 w-4" }), "Location Distribution"]
|
|
268
284
|
}) }), /* @__PURE__ */ l(p, {
|
|
269
285
|
className: "space-y-3",
|
|
270
|
-
children: Object.entries(
|
|
286
|
+
children: Object.entries(O).sort(([, e], [, t]) => t - e).map(([e, t]) => /* @__PURE__ */ u("div", {
|
|
271
287
|
className: "flex items-center justify-between py-1",
|
|
272
288
|
children: [/* @__PURE__ */ l("span", {
|
|
273
289
|
className: "text-sm",
|
|
@@ -280,7 +296,7 @@ function _() {
|
|
|
280
296
|
}), /* @__PURE__ */ u(d, {
|
|
281
297
|
variant: "outline",
|
|
282
298
|
className: "text-[10px]",
|
|
283
|
-
children: [Math.round(t /
|
|
299
|
+
children: [Math.round(t / y.length * 100), "%"]
|
|
284
300
|
})]
|
|
285
301
|
})]
|
|
286
302
|
}, e))
|
|
@@ -288,7 +304,7 @@ function _() {
|
|
|
288
304
|
}),
|
|
289
305
|
/* @__PURE__ */ u(f, { children: [/* @__PURE__ */ l(h, { children: /* @__PURE__ */ u(g, {
|
|
290
306
|
className: "flex items-center gap-2",
|
|
291
|
-
children: [/* @__PURE__ */ l(n, { className: "h-4 w-4 text-
|
|
307
|
+
children: [/* @__PURE__ */ l(n, { className: "h-4 w-4 text-status-warning-text" }), "Key Insights"]
|
|
292
308
|
}) }), /* @__PURE__ */ l(p, { children: /* @__PURE__ */ u("div", {
|
|
293
309
|
className: "grid gap-3 md:grid-cols-3",
|
|
294
310
|
children: [
|
|
@@ -298,11 +314,11 @@ function _() {
|
|
|
298
314
|
className: "text-sm font-medium",
|
|
299
315
|
children: "Highest Performance"
|
|
300
316
|
}), /* @__PURE__ */ u("p", {
|
|
301
|
-
className: "text-xs text-
|
|
317
|
+
className: "text-xs text-text-secondary mt-1",
|
|
302
318
|
children: [
|
|
303
319
|
"Engineering department leads with avg score of",
|
|
304
320
|
" ",
|
|
305
|
-
|
|
321
|
+
D.find((e) => e.name === "Engineering")?.avgScore || "N/A"
|
|
306
322
|
]
|
|
307
323
|
})]
|
|
308
324
|
}),
|
|
@@ -312,7 +328,7 @@ function _() {
|
|
|
312
328
|
className: "text-sm font-medium",
|
|
313
329
|
children: "Retention Risk"
|
|
314
330
|
}), /* @__PURE__ */ l("p", {
|
|
315
|
-
className: "text-xs text-
|
|
331
|
+
className: "text-xs text-text-secondary mt-1",
|
|
316
332
|
children: "12 employees flagged as flight risk based on engagement signals"
|
|
317
333
|
})]
|
|
318
334
|
}),
|
|
@@ -322,7 +338,7 @@ function _() {
|
|
|
322
338
|
className: "text-sm font-medium",
|
|
323
339
|
children: "Compensation Gap"
|
|
324
340
|
}), /* @__PURE__ */ l("p", {
|
|
325
|
-
className: "text-xs text-
|
|
341
|
+
className: "text-xs text-text-secondary mt-1",
|
|
326
342
|
children: "3 departments below market median, review recommended in Q2"
|
|
327
343
|
})]
|
|
328
344
|
})
|
|
@@ -332,6 +348,6 @@ function _() {
|
|
|
332
348
|
});
|
|
333
349
|
}
|
|
334
350
|
//#endregion
|
|
335
|
-
export {
|
|
351
|
+
export { y as AnalyticsEmployeeAnalyticsPagePage };
|
|
336
352
|
|
|
337
353
|
//# sourceMappingURL=AnalyticsEmployeeAnalyticsPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyticsEmployeeAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { Award, BarChart3, Clock, MapPin, Star, TrendingUp, UserCheck } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function AnalyticsEmployeeAnalyticsPagePage() {\n const { employees, departments } = useCrewFoundryStore();\n\n const tenureDistribution = useMemo(() => {\n const total = Math.max(employees.length, 1);\n const getYears = (startDate: string) =>\n Math.max(\n 0,\n (new Date('2026-03-01').getTime() - new Date(startDate).getTime()) /\n (1000 * 60 * 60 * 24 * 365)\n );\n const buckets = [\n { range: '< 1 year', min: 0, max: 1 },\n { range: '1-2 years', min: 1, max: 2 },\n { range: '2-3 years', min: 2, max: 3 },\n { range: '3-4 years', min: 3, max: 4 },\n { range: '4+ years', min: 4, max: Infinity },\n ];\n return buckets.map((bucket) => {\n const count = employees.filter((employee) => {\n const years = getYears(employee.startDate);\n return years >= bucket.min && years < bucket.max;\n }).length;\n return { range: bucket.range, count, percentage: Math.round((count / total) * 100) };\n });\n }, [employees]);\n\n const engagementDrivers = useMemo(() => {\n const byDept = departments.map((department) => {\n const deptEmployees = employees.filter((employee) => employee.department === department.name);\n const score =\n deptEmployees.length > 0\n ? deptEmployees.reduce((sum, employee) => sum + employee.performanceScore, 0) /\n deptEmployees.length\n : 0;\n return { department: department.name, score };\n });\n\n const avgScore =\n employees.length > 0\n ? employees.reduce((sum, employee) => sum + employee.performanceScore, 0) / employees.length\n : 0;\n\n const compScore =\n employees.length > 0\n ? Math.min(\n 5,\n Math.max(\n 3,\n employees.reduce((sum, employee) => sum + employee.salary, 0) /\n employees.length /\n 30000\n )\n )\n : 0;\n\n return [\n { driver: 'Workforce Performance', score: Number(avgScore.toFixed(1)), trend: '+0.2' },\n {\n driver: 'Career Growth',\n score: Number(\n (\n byDept.reduce((sum, entry) => sum + (entry.score > avgScore ? 4.6 : 4.0), 0) /\n Math.max(byDept.length, 1)\n ).toFixed(1)\n ),\n trend: '+0.1',\n },\n { driver: 'Compensation', score: Number(compScore.toFixed(1)), trend: '+0.2' },\n {\n driver: 'Management Quality',\n score: Number(\n (\n byDept.reduce((sum, entry) => sum + Math.min(5, entry.score + 0.4), 0) /\n Math.max(byDept.length, 1)\n ).toFixed(1)\n ),\n trend: '+0.3',\n },\n {\n driver: 'Company Culture',\n score: Number(Math.min(5, avgScore + 0.5).toFixed(1)),\n trend: '+0.2',\n },\n {\n driver: 'Learning Opportunities',\n score: Number(Math.min(5, avgScore + 0.3).toFixed(1)),\n trend: '+0.4',\n },\n ];\n }, [departments, employees]);\n\n const avgPerformance = (\n employees.reduce((sum, e) => sum + e.performanceScore, 0) / employees.length\n ).toFixed(1);\n const avgSalary = Math.round(employees.reduce((sum, e) => sum + e.salary, 0) / employees.length);\n const activeCount = employees.filter((e) => e.status === 'active').length;\n const onLeaveCount = employees.filter((e) => e.status === 'on_leave').length;\n\n const deptPerformance = departments.map((dept) => {\n const deptEmps = employees.filter((e) => e.department === dept.name);\n const avgScore =\n deptEmps.length > 0\n ? (deptEmps.reduce((s, e) => s + e.performanceScore, 0) / deptEmps.length).toFixed(1)\n : '0';\n const avgSal =\n deptEmps.length > 0\n ? Math.round(deptEmps.reduce((s, e) => s + e.salary, 0) / deptEmps.length)\n : 0;\n return { name: dept.name, headcount: deptEmps.length, avgScore, avgSalary: avgSal };\n });\n\n const locationBreakdown = employees.reduce<Record<string, number>>((acc, e) => {\n acc[e.location] = (acc[e.location] || 0) + 1;\n return acc;\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\">Employee Analytics</h1>\n <p className=\"text-sm text-muted-foreground\">\n Deep-dive into employee performance, engagement, and demographics\n </p>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Active Employees</CardTitle>\n <UserCheck className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{activeCount}</div>\n <p className=\"text-xs text-muted-foreground\">{onLeaveCount} currently on leave</p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Avg Performance</CardTitle>\n <Star className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{avgPerformance}/5.0</div>\n <div className=\"flex items-center text-xs text-green-600\">\n <TrendingUp className=\"h-3 w-3 mr-1\" />\n +0.2 from last quarter\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Avg Compensation</CardTitle>\n <BarChart3 className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${avgSalary.toLocaleString()}</div>\n <p className=\"text-xs text-muted-foreground\">Across all departments</p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Avg Tenure</CardTitle>\n <Clock className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">2.4 yrs</div>\n <p className=\"text-xs text-muted-foreground\">Median: 2.1 years</p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>Department Performance</CardTitle>\n <CardDescription>\n Average performance score and compensation by department\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-4 gap-2 text-xs font-medium text-muted-foreground border-b pb-2 mb-2\">\n <span>Department</span>\n <span className=\"text-right\">Headcount</span>\n <span className=\"text-right\">Avg Score</span>\n <span className=\"text-right\">Avg Salary</span>\n </div>\n {deptPerformance\n .sort((a, b) => Number(b.avgScore) - Number(a.avgScore))\n .map((dept) => (\n <div\n key={dept.name}\n className=\"grid grid-cols-4 gap-2 py-2 border-b last:border-0 text-sm\"\n >\n <span className=\"font-medium\">{dept.name}</span>\n <span className=\"text-right\">{dept.headcount}</span>\n <div className=\"text-right\">\n <Badge variant={Number(dept.avgScore) >= 4.5 ? 'default' : 'secondary'}>\n {dept.avgScore}\n </Badge>\n </div>\n <span className=\"text-right\">${dept.avgSalary.toLocaleString()}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Engagement Drivers</CardTitle>\n <CardDescription>Employee satisfaction by category</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {engagementDrivers\n .sort((a, b) => b.score - a.score)\n .map((driver) => (\n <div key={driver.driver} className=\"space-y-1\">\n <div className=\"flex justify-between text-sm\">\n <span>{driver.driver}</span>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">{driver.score}/5</span>\n <span className=\"text-xs text-green-600\">{driver.trend}</span>\n </div>\n </div>\n <div className=\"h-2 bg-muted rounded overflow-hidden\">\n <div\n className={`h-2 rounded ${driver.score >= 4.5 ? 'bg-green-500' : driver.score >= 4 ? 'bg-blue-500' : 'bg-yellow-500'}`}\n style={{ width: `${(driver.score / 5) * 100}%` }}\n />\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Clock className=\"h-4 w-4\" />\n Tenure Distribution\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {tenureDistribution.map((t) => (\n <div key={t.range} className=\"flex items-center gap-3\">\n <span className=\"w-20 text-sm text-muted-foreground\">{t.range}</span>\n <div className=\"flex-1 h-4 bg-muted rounded overflow-hidden\">\n <div\n className=\"h-4 bg-primary/70 rounded\"\n style={{ width: `${t.percentage}%` }}\n />\n </div>\n <span className=\"text-sm font-medium w-10 text-right\">{t.count}</span>\n <span className=\"text-xs text-muted-foreground w-10 text-right\">\n {t.percentage}%\n </span>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <MapPin className=\"h-4 w-4\" />\n Location Distribution\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {Object.entries(locationBreakdown)\n .sort(([, a], [, b]) => b - a)\n .map(([loc, count]) => (\n <div key={loc} className=\"flex items-center justify-between py-1\">\n <span className=\"text-sm\">{loc}</span>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium\">{count}</span>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {Math.round((count / employees.length) * 100)}%\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Award className=\"h-4 w-4 text-yellow-500\" />\n Key Insights\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid gap-3 md:grid-cols-3\">\n <div className=\"rounded border p-3\">\n <p className=\"text-sm font-medium\">Highest Performance</p>\n <p className=\"text-xs text-muted-foreground mt-1\">\n Engineering department leads with avg score of{' '}\n {deptPerformance.find((d) => d.name === 'Engineering')?.avgScore || 'N/A'}\n </p>\n </div>\n <div className=\"rounded border p-3\">\n <p className=\"text-sm font-medium\">Retention Risk</p>\n <p className=\"text-xs text-muted-foreground mt-1\">\n 12 employees flagged as flight risk based on engagement signals\n </p>\n </div>\n <div className=\"rounded border p-3\">\n <p className=\"text-sm font-medium\">Compensation Gap</p>\n <p className=\"text-xs text-muted-foreground mt-1\">\n 3 departments below market median, review recommended in Q2\n </p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AnalyticsEmployeeAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n} from '@burdenoff/fe-libs/ui';\nimport { Award, BarChart3, Clock, MapPin, Star, TrendingUp, UserCheck } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function AnalyticsEmployeeAnalyticsPagePage() {\n const { employees, departments } = useCrewFoundryStore();\n\n const tenureDistribution = useMemo(() => {\n const total = Math.max(employees.length, 1);\n const getYears = (startDate: string) =>\n Math.max(\n 0,\n (new Date('2026-03-01').getTime() - new Date(startDate).getTime()) /\n (1000 * 60 * 60 * 24 * 365)\n );\n const buckets = [\n { range: '< 1 year', min: 0, max: 1 },\n { range: '1-2 years', min: 1, max: 2 },\n { range: '2-3 years', min: 2, max: 3 },\n { range: '3-4 years', min: 3, max: 4 },\n { range: '4+ years', min: 4, max: Infinity },\n ];\n return buckets.map((bucket) => {\n const count = employees.filter((employee) => {\n const years = getYears(employee.startDate);\n return years >= bucket.min && years < bucket.max;\n }).length;\n return { range: bucket.range, count, percentage: Math.round((count / total) * 100) };\n });\n }, [employees]);\n\n const engagementDrivers = useMemo(() => {\n const byDept = departments.map((department) => {\n const deptEmployees = employees.filter((employee) => employee.department === department.name);\n const score =\n deptEmployees.length > 0\n ? deptEmployees.reduce((sum, employee) => sum + employee.performanceScore, 0) /\n deptEmployees.length\n : 0;\n return { department: department.name, score };\n });\n\n const avgScore =\n employees.length > 0\n ? employees.reduce((sum, employee) => sum + employee.performanceScore, 0) / employees.length\n : 0;\n\n const compScore =\n employees.length > 0\n ? Math.min(\n 5,\n Math.max(\n 3,\n employees.reduce((sum, employee) => sum + employee.salary, 0) /\n employees.length /\n 30000\n )\n )\n : 0;\n\n return [\n { driver: 'Workforce Performance', score: Number(avgScore.toFixed(1)), trend: '+0.2' },\n {\n driver: 'Career Growth',\n score: Number(\n (\n byDept.reduce((sum, entry) => sum + (entry.score > avgScore ? 4.6 : 4.0), 0) /\n Math.max(byDept.length, 1)\n ).toFixed(1)\n ),\n trend: '+0.1',\n },\n { driver: 'Compensation', score: Number(compScore.toFixed(1)), trend: '+0.2' },\n {\n driver: 'Management Quality',\n score: Number(\n (\n byDept.reduce((sum, entry) => sum + Math.min(5, entry.score + 0.4), 0) /\n Math.max(byDept.length, 1)\n ).toFixed(1)\n ),\n trend: '+0.3',\n },\n {\n driver: 'Company Culture',\n score: Number(Math.min(5, avgScore + 0.5).toFixed(1)),\n trend: '+0.2',\n },\n {\n driver: 'Learning Opportunities',\n score: Number(Math.min(5, avgScore + 0.3).toFixed(1)),\n trend: '+0.4',\n },\n ];\n }, [departments, employees]);\n\n const avgPerformance = (\n employees.reduce((sum, e) => sum + e.performanceScore, 0) / employees.length\n ).toFixed(1);\n const avgSalary = Math.round(employees.reduce((sum, e) => sum + e.salary, 0) / employees.length);\n const activeCount = employees.filter((e) => e.status === 'active').length;\n const onLeaveCount = employees.filter((e) => e.status === 'on_leave').length;\n\n const deptPerformance = departments.map((dept) => {\n const deptEmps = employees.filter((e) => e.department === dept.name);\n const avgScore =\n deptEmps.length > 0\n ? (deptEmps.reduce((s, e) => s + e.performanceScore, 0) / deptEmps.length).toFixed(1)\n : '0';\n const avgSal =\n deptEmps.length > 0\n ? Math.round(deptEmps.reduce((s, e) => s + e.salary, 0) / deptEmps.length)\n : 0;\n return { name: dept.name, headcount: deptEmps.length, avgScore, avgSalary: avgSal };\n });\n\n const locationBreakdown = employees.reduce<Record<string, number>>((acc, e) => {\n acc[e.location] = (acc[e.location] || 0) + 1;\n return acc;\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 Analytics</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Deep-dive into employee performance, engagement, and demographics\n </p>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\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 Employees</CardTitle>\n <UserCheck className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{activeCount}</div>\n <p className=\"text-xs text-text-secondary\">{onLeaveCount} currently on leave</p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Avg Performance</CardTitle>\n <Star className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{avgPerformance}/5.0</div>\n <div className=\"flex items-center text-xs text-status-success-text\">\n <TrendingUp className=\"h-3 w-3 mr-1\" />\n +0.2 from last quarter\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Avg Compensation</CardTitle>\n <BarChart3 className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${avgSalary.toLocaleString()}</div>\n <p className=\"text-xs text-text-secondary\">Across all departments</p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Avg Tenure</CardTitle>\n <Clock className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">2.4 yrs</div>\n <p className=\"text-xs text-text-secondary\">Median: 2.1 years</p>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>Department Performance</CardTitle>\n <CardDescription>\n Average performance score and compensation by department\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-4 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Department</span>\n <span className=\"text-right\">Headcount</span>\n <span className=\"text-right\">Avg Score</span>\n <span className=\"text-right\">Avg Salary</span>\n </div>\n {deptPerformance\n .sort((a, b) => Number(b.avgScore) - Number(a.avgScore))\n .map((dept) => (\n <div\n key={dept.name}\n className=\"grid grid-cols-4 gap-2 py-2 border-b last:border-0 text-sm\"\n >\n <span className=\"font-medium\">{dept.name}</span>\n <span className=\"text-right\">{dept.headcount}</span>\n <div className=\"text-right\">\n <Badge variant={Number(dept.avgScore) >= 4.5 ? 'default' : 'secondary'}>\n {dept.avgScore}\n </Badge>\n </div>\n <span className=\"text-right\">${dept.avgSalary.toLocaleString()}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Engagement Drivers</CardTitle>\n <CardDescription>Employee satisfaction by category</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {engagementDrivers\n .sort((a, b) => b.score - a.score)\n .map((driver) => (\n <div key={driver.driver} className=\"space-y-1\">\n <div className=\"flex justify-between text-sm\">\n <span>{driver.driver}</span>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">{driver.score}/5</span>\n <span className=\"text-xs text-status-success-text\">{driver.trend}</span>\n </div>\n </div>\n <div className=\"h-2 bg-bg-sunken rounded overflow-hidden\">\n <div\n className={`h-2 rounded ${driver.score >= 4.5 ? 'bg-status-success-text' : driver.score >= 4 ? 'bg-status-info-text' : 'bg-status-warning-text'}`}\n style={{ width: `${(driver.score / 5) * 100}%` }}\n />\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Clock className=\"h-4 w-4\" />\n Tenure Distribution\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {tenureDistribution.map((t) => (\n <div key={t.range} className=\"flex items-center gap-3\">\n <span className=\"w-20 text-sm text-text-secondary\">{t.range}</span>\n <div className=\"flex-1 h-4 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-4 bg-action-primary-bg/70 rounded\"\n style={{ width: `${t.percentage}%` }}\n />\n </div>\n <span className=\"text-sm font-medium w-10 text-right\">{t.count}</span>\n <span className=\"text-xs text-text-secondary w-10 text-right\">{t.percentage}%</span>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <MapPin className=\"h-4 w-4\" />\n Location Distribution\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {Object.entries(locationBreakdown)\n .sort(([, a], [, b]) => b - a)\n .map(([loc, count]) => (\n <div key={loc} className=\"flex items-center justify-between py-1\">\n <span className=\"text-sm\">{loc}</span>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium\">{count}</span>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {Math.round((count / employees.length) * 100)}%\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Award className=\"h-4 w-4 text-status-warning-text\" />\n Key Insights\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid gap-3 md:grid-cols-3\">\n <div className=\"rounded border p-3\">\n <p className=\"text-sm font-medium\">Highest Performance</p>\n <p className=\"text-xs text-text-secondary mt-1\">\n Engineering department leads with avg score of{' '}\n {deptPerformance.find((d) => d.name === 'Engineering')?.avgScore || 'N/A'}\n </p>\n </div>\n <div className=\"rounded border p-3\">\n <p className=\"text-sm font-medium\">Retention Risk</p>\n <p className=\"text-xs text-text-secondary mt-1\">\n 12 employees flagged as flight risk based on engagement signals\n </p>\n </div>\n <div className=\"rounded border p-3\">\n <p className=\"text-sm font-medium\">Compensation Gap</p>\n <p className=\"text-xs text-text-secondary mt-1\">\n 3 departments below market median, review recommended in Q2\n </p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|