@burdenoff/microfe-crewfoundry 2026.529.1 → 2026.624.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 +15 -15
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +15 -15
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +17 -17
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +19 -19
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +16 -16
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +5 -5
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +7 -7
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +7 -7
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +7 -7
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +7 -7
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +3 -3
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +8 -8
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +8 -8
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +14 -14
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +10 -10
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +4 -4
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +17 -17
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +19 -19
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +17 -17
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +12 -12
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +12 -12
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +11 -11
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +7 -7
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +7 -7
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +13 -13
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +7 -7
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +10 -10
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +9 -9
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +13 -13
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +10 -10
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +9 -9
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +3 -3
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +2 -2
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +11 -11
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +7 -7
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +4 -4
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +9 -9
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +10 -10
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +11 -11
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +5 -5
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +7 -7
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +3 -3
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +7 -7
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +11 -11
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +11 -11
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +6 -6
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +6 -6
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +7 -7
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +2 -2
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +15 -15
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +10 -10
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +5 -5
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +6 -6
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +6 -6
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +4 -4
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +4 -4
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +15 -15
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +4 -4
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +8 -8
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +14 -14
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +6 -6
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +20 -20
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +3 -3
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -100,7 +100,7 @@ function x() {
|
|
|
100
100
|
className: "text-2xl font-semibold",
|
|
101
101
|
children: "Administration"
|
|
102
102
|
}), /* @__PURE__ */ d("p", {
|
|
103
|
-
className: "text-sm text-
|
|
103
|
+
className: "text-sm text-text-secondary",
|
|
104
104
|
children: "System administration and access management"
|
|
105
105
|
})] }), /* @__PURE__ */ f("div", {
|
|
106
106
|
className: "flex gap-2",
|
|
@@ -122,12 +122,12 @@ function x() {
|
|
|
122
122
|
children: [/* @__PURE__ */ d(y, {
|
|
123
123
|
className: "text-sm font-medium",
|
|
124
124
|
children: "Total Users"
|
|
125
|
-
}), /* @__PURE__ */ d(l, { className: "h-4 w-4 text-
|
|
125
|
+
}), /* @__PURE__ */ d(l, { className: "h-4 w-4 text-text-secondary" })]
|
|
126
126
|
}), /* @__PURE__ */ f(g, { children: [/* @__PURE__ */ d("div", {
|
|
127
127
|
className: "text-2xl font-bold",
|
|
128
128
|
children: x.length
|
|
129
129
|
}), /* @__PURE__ */ f("p", {
|
|
130
|
-
className: "text-xs text-
|
|
130
|
+
className: "text-xs text-text-secondary",
|
|
131
131
|
children: [S.length, " departments"]
|
|
132
132
|
})] })] }),
|
|
133
133
|
/* @__PURE__ */ f(h, { children: [/* @__PURE__ */ f(v, {
|
|
@@ -135,12 +135,12 @@ function x() {
|
|
|
135
135
|
children: [/* @__PURE__ */ d(y, {
|
|
136
136
|
className: "text-sm font-medium",
|
|
137
137
|
children: "Active Sessions"
|
|
138
|
-
}), /* @__PURE__ */ d(o, { className: "h-4 w-4 text-
|
|
138
|
+
}), /* @__PURE__ */ d(o, { className: "h-4 w-4 text-text-secondary" })]
|
|
139
139
|
}), /* @__PURE__ */ f(g, { children: [/* @__PURE__ */ d("div", {
|
|
140
140
|
className: "text-2xl font-bold",
|
|
141
141
|
children: Math.round(x.length * .76)
|
|
142
142
|
}), /* @__PURE__ */ d("p", {
|
|
143
|
-
className: "text-xs text-
|
|
143
|
+
className: "text-xs text-text-secondary",
|
|
144
144
|
children: "Estimated from active workforce"
|
|
145
145
|
})] })] }),
|
|
146
146
|
/* @__PURE__ */ f(h, { children: [/* @__PURE__ */ f(v, {
|
|
@@ -148,12 +148,12 @@ function x() {
|
|
|
148
148
|
children: [/* @__PURE__ */ d(y, {
|
|
149
149
|
className: "text-sm font-medium",
|
|
150
150
|
children: "System Uptime"
|
|
151
|
-
}), /* @__PURE__ */ d(s, { className: "h-4 w-4 text-
|
|
151
|
+
}), /* @__PURE__ */ d(s, { className: "h-4 w-4 text-text-secondary" })]
|
|
152
152
|
}), /* @__PURE__ */ f(g, { children: [/* @__PURE__ */ d("div", {
|
|
153
153
|
className: "text-2xl font-bold",
|
|
154
154
|
children: "99.95%"
|
|
155
155
|
}), /* @__PURE__ */ d("p", {
|
|
156
|
-
className: "text-xs text-
|
|
156
|
+
className: "text-xs text-text-secondary",
|
|
157
157
|
children: "Rolling platform uptime"
|
|
158
158
|
})] })] }),
|
|
159
159
|
/* @__PURE__ */ f(h, { children: [/* @__PURE__ */ f(v, {
|
|
@@ -161,7 +161,7 @@ function x() {
|
|
|
161
161
|
children: [/* @__PURE__ */ d(y, {
|
|
162
162
|
className: "text-sm font-medium",
|
|
163
163
|
children: "Security Score"
|
|
164
|
-
}), /* @__PURE__ */ d(c, { className: "h-4 w-4 text-
|
|
164
|
+
}), /* @__PURE__ */ d(c, { className: "h-4 w-4 text-text-secondary" })]
|
|
165
165
|
}), /* @__PURE__ */ f(g, { children: [/* @__PURE__ */ f("div", {
|
|
166
166
|
className: "text-2xl font-bold",
|
|
167
167
|
children: [k, "/100"]
|
|
@@ -179,14 +179,14 @@ function x() {
|
|
|
179
179
|
className: "flex items-center justify-between rounded border p-3",
|
|
180
180
|
children: [/* @__PURE__ */ f("div", {
|
|
181
181
|
className: "flex items-center gap-3",
|
|
182
|
-
children: [/* @__PURE__ */ d(e.icon, { className: "h-4 w-4 text-
|
|
182
|
+
children: [/* @__PURE__ */ d(e.icon, { className: "h-4 w-4 text-text-secondary" }), /* @__PURE__ */ d("span", {
|
|
183
183
|
className: "text-sm font-medium",
|
|
184
184
|
children: e.name
|
|
185
185
|
})]
|
|
186
186
|
}), /* @__PURE__ */ f("div", {
|
|
187
187
|
className: "flex items-center gap-3",
|
|
188
188
|
children: [/* @__PURE__ */ d("span", {
|
|
189
|
-
className: "text-xs text-
|
|
189
|
+
className: "text-xs text-text-secondary",
|
|
190
190
|
children: e.uptime
|
|
191
191
|
}), /* @__PURE__ */ d(p, {
|
|
192
192
|
variant: e.status === "operational" ? "default" : "destructive",
|
|
@@ -196,7 +196,7 @@ function x() {
|
|
|
196
196
|
})]
|
|
197
197
|
}, e.name))
|
|
198
198
|
})] }), /* @__PURE__ */ f(h, { children: [/* @__PURE__ */ f(v, { children: [/* @__PURE__ */ d(y, { children: "User Roles" }), /* @__PURE__ */ d(_, { children: "Role distribution and permissions" })] }), /* @__PURE__ */ f(g, { children: [/* @__PURE__ */ f("div", {
|
|
199
|
-
className: "mb-2 grid grid-cols-3 gap-2 border-b pb-2 text-xs font-medium text-
|
|
199
|
+
className: "mb-2 grid grid-cols-3 gap-2 border-b pb-2 text-xs font-medium text-text-secondary",
|
|
200
200
|
children: [
|
|
201
201
|
/* @__PURE__ */ d("span", { children: "Role" }),
|
|
202
202
|
/* @__PURE__ */ d("span", {
|
|
@@ -217,14 +217,14 @@ function x() {
|
|
|
217
217
|
children: e.count
|
|
218
218
|
}),
|
|
219
219
|
/* @__PURE__ */ d("span", {
|
|
220
|
-
className: "truncate text-xs text-
|
|
220
|
+
className: "truncate text-xs text-text-secondary",
|
|
221
221
|
children: e.permissions
|
|
222
222
|
})
|
|
223
223
|
]
|
|
224
224
|
}, e.role))] })] })]
|
|
225
225
|
}),
|
|
226
226
|
/* @__PURE__ */ f(h, { children: [/* @__PURE__ */ f(v, { children: [/* @__PURE__ */ d(y, { children: "Recent Audit Log" }), /* @__PURE__ */ d(_, { children: "System activity and security events" })] }), /* @__PURE__ */ f(g, { children: [/* @__PURE__ */ f("div", {
|
|
227
|
-
className: "mb-2 grid grid-cols-5 gap-2 border-b pb-2 text-xs font-medium text-
|
|
227
|
+
className: "mb-2 grid grid-cols-5 gap-2 border-b pb-2 text-xs font-medium text-text-secondary",
|
|
228
228
|
children: [
|
|
229
229
|
/* @__PURE__ */ d("span", { children: "Action" }),
|
|
230
230
|
/* @__PURE__ */ d("span", { children: "Actor" }),
|
|
@@ -240,11 +240,11 @@ function x() {
|
|
|
240
240
|
children: e.action
|
|
241
241
|
}),
|
|
242
242
|
/* @__PURE__ */ d("span", {
|
|
243
|
-
className: "text-
|
|
243
|
+
className: "text-text-secondary",
|
|
244
244
|
children: e.actor
|
|
245
245
|
}),
|
|
246
246
|
/* @__PURE__ */ d("span", {
|
|
247
|
-
className: "truncate text-
|
|
247
|
+
className: "truncate text-text-secondary",
|
|
248
248
|
children: e.target
|
|
249
249
|
}),
|
|
250
250
|
/* @__PURE__ */ d("span", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminAdminPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/AdminAdminPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Activity,\n Database,\n Globe,\n Lock,\n Monitor,\n Server,\n Shield,\n Users,\n Wrench,\n} from 'lucide-react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype SystemModule = {\n name: string;\n status: 'operational' | 'degraded';\n uptime: string;\n icon: typeof Lock;\n};\n\ntype AuditLog = {\n action: string;\n actor: string;\n target: string;\n timestamp: string;\n severity: 'low' | 'medium' | 'high';\n};\n\ntype UserRole = {\n role: string;\n count: number;\n permissions: string;\n};\n\nconst isoDateTime = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toLocaleString('en-US', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n });\n};\n\nexport function AdminAdminPagePage() {\n const { employees, departments, notifications, payrollRecords, jobPostings } =\n useCrewFoundryStore();\n\n const systemModules = useMemo<SystemModule[]>(() => {\n const hasWarning = notifications.some((notification) => notification.type === 'warning');\n const hasError = notifications.some((notification) => notification.type === 'error');\n\n return [\n { name: 'Authentication', status: 'operational', uptime: '99.98%', icon: Lock },\n { name: 'Employee Directory', status: 'operational', uptime: '99.95%', icon: Users },\n {\n name: 'Payroll Engine',\n status: payrollRecords.some((record) => record.status === 'failed')\n ? 'degraded'\n : 'operational',\n uptime: '99.91%',\n icon: Database,\n },\n { name: 'Recruitment ATS', status: 'operational', uptime: '99.94%', icon: Globe },\n {\n name: 'Analytics Pipeline',\n status: hasWarning || hasError ? 'degraded' : 'operational',\n uptime: hasWarning || hasError ? '98.70%' : '99.96%',\n icon: Activity,\n },\n {\n name: 'Notification Service',\n status: hasError ? 'degraded' : 'operational',\n uptime: '99.97%',\n icon: Monitor,\n },\n ];\n }, [notifications, payrollRecords]);\n\n const recentAuditLogs = useMemo<AuditLog[]>(() => {\n return notifications.slice(0, 12).map((notification, index) => ({\n action:\n notification.type === 'error'\n ? 'Incident detected'\n : notification.type === 'warning'\n ? 'Policy alert generated'\n : 'Operational event recorded',\n actor: employees[index % Math.max(employees.length, 1)]\n ? `${employees[index % employees.length].firstName} ${employees[index % employees.length].lastName}`\n : 'System',\n target: notification.title,\n timestamp: isoDateTime(notification.createdAt),\n severity:\n notification.type === 'error' ? 'high' : notification.type === 'warning' ? 'medium' : 'low',\n }));\n }, [employees, notifications]);\n\n const userRoles = useMemo<UserRole[]>(() => {\n const managers = employees.filter((employee) =>\n employee.position.toLowerCase().includes('manager')\n ).length;\n const leads = employees.filter((employee) =>\n employee.position.toLowerCase().includes('lead')\n ).length;\n const recruiters = jobPostings.filter((posting) => posting.status === 'active').length;\n return [\n { role: 'Super Admin', count: 2, permissions: 'Full access' },\n {\n role: 'HR Manager',\n count: Math.max(1, managers),\n permissions: 'Employee, payroll, leave management',\n },\n {\n role: 'Hiring Manager',\n count: Math.max(1, recruiters),\n permissions: 'Job postings, candidates, interviews',\n },\n {\n role: 'Department Lead',\n count: Math.max(1, leads),\n permissions: 'Team management, reports',\n },\n {\n role: 'Employee',\n count: Math.max(0, employees.length - managers - leads),\n permissions: 'Self-service, directory, learning',\n },\n ];\n }, [employees, jobPostings]);\n\n const securityScore = Math.round(\n (systemModules.filter((module) => module.status === 'operational').length /\n Math.max(systemModules.length, 1)) *\n 100\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\">Administration</h1>\n <p className=\"text-sm text-muted-foreground\">\n System administration and access management\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <Wrench className=\"mr-1 h-4 w-4\" />\n System Settings\n </Button>\n <Button size=\"sm\">\n <Shield className=\"mr-1 h-4 w-4\" />\n Security\n </Button>\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\">Total Users</CardTitle>\n <Users className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{employees.length}</div>\n <p className=\"text-xs text-muted-foreground\">{departments.length} 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\">Active Sessions</CardTitle>\n <Monitor className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{Math.round(employees.length * 0.76)}</div>\n <p className=\"text-xs text-muted-foreground\">Estimated from active workforce</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\">System Uptime</CardTitle>\n <Server className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">99.95%</div>\n <p className=\"text-xs text-muted-foreground\">Rolling platform uptime</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\">Security Score</CardTitle>\n <Shield className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{securityScore}/100</div>\n <p className=\"text-xs text-green-600\">Derived from module health checks</p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>System Status</CardTitle>\n <CardDescription>Module health and uptime</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {systemModules.map((module) => (\n <div\n key={module.name}\n className=\"flex items-center justify-between rounded border p-3\"\n >\n <div className=\"flex items-center gap-3\">\n <module.icon className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-sm font-medium\">{module.name}</span>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-xs text-muted-foreground\">{module.uptime}</span>\n <Badge\n variant={module.status === 'operational' ? 'default' : 'destructive'}\n className=\"text-[10px]\"\n >\n {module.status}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>User Roles</CardTitle>\n <CardDescription>Role distribution and permissions</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-2 grid grid-cols-3 gap-2 border-b pb-2 text-xs font-medium text-muted-foreground\">\n <span>Role</span>\n <span className=\"text-right\">Users</span>\n <span>Permissions</span>\n </div>\n {userRoles.map((role) => (\n <div\n key={role.role}\n className=\"grid grid-cols-3 gap-2 border-b py-2 text-sm last:border-0\"\n >\n <span className=\"font-medium\">{role.role}</span>\n <span className=\"text-right\">{role.count}</span>\n <span className=\"truncate text-xs text-muted-foreground\">{role.permissions}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Recent Audit Log</CardTitle>\n <CardDescription>System activity and security events</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-2 grid grid-cols-5 gap-2 border-b pb-2 text-xs font-medium text-muted-foreground\">\n <span>Action</span>\n <span>Actor</span>\n <span>Target</span>\n <span>Timestamp</span>\n <span>Severity</span>\n </div>\n {recentAuditLogs.map((log, index) => (\n <div\n key={`${log.action}-${index}`}\n className=\"grid grid-cols-5 gap-2 border-b py-2 text-sm last:border-0\"\n >\n <span className=\"font-medium\">{log.action}</span>\n <span className=\"text-muted-foreground\">{log.actor}</span>\n <span className=\"truncate text-muted-foreground\">{log.target}</span>\n <span className=\"text-xs\">{log.timestamp}</span>\n <Badge\n variant={\n log.severity === 'high'\n ? 'destructive'\n : log.severity === 'medium'\n ? 'secondary'\n : 'outline'\n }\n className=\"w-fit text-[10px]\"\n >\n {log.severity}\n </Badge>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AdminAdminPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/AdminAdminPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Activity,\n Database,\n Globe,\n Lock,\n Monitor,\n Server,\n Shield,\n Users,\n Wrench,\n} from 'lucide-react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype SystemModule = {\n name: string;\n status: 'operational' | 'degraded';\n uptime: string;\n icon: typeof Lock;\n};\n\ntype AuditLog = {\n action: string;\n actor: string;\n target: string;\n timestamp: string;\n severity: 'low' | 'medium' | 'high';\n};\n\ntype UserRole = {\n role: string;\n count: number;\n permissions: string;\n};\n\nconst isoDateTime = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toLocaleString('en-US', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n });\n};\n\nexport function AdminAdminPagePage() {\n const { employees, departments, notifications, payrollRecords, jobPostings } =\n useCrewFoundryStore();\n\n const systemModules = useMemo<SystemModule[]>(() => {\n const hasWarning = notifications.some((notification) => notification.type === 'warning');\n const hasError = notifications.some((notification) => notification.type === 'error');\n\n return [\n { name: 'Authentication', status: 'operational', uptime: '99.98%', icon: Lock },\n { name: 'Employee Directory', status: 'operational', uptime: '99.95%', icon: Users },\n {\n name: 'Payroll Engine',\n status: payrollRecords.some((record) => record.status === 'failed')\n ? 'degraded'\n : 'operational',\n uptime: '99.91%',\n icon: Database,\n },\n { name: 'Recruitment ATS', status: 'operational', uptime: '99.94%', icon: Globe },\n {\n name: 'Analytics Pipeline',\n status: hasWarning || hasError ? 'degraded' : 'operational',\n uptime: hasWarning || hasError ? '98.70%' : '99.96%',\n icon: Activity,\n },\n {\n name: 'Notification Service',\n status: hasError ? 'degraded' : 'operational',\n uptime: '99.97%',\n icon: Monitor,\n },\n ];\n }, [notifications, payrollRecords]);\n\n const recentAuditLogs = useMemo<AuditLog[]>(() => {\n return notifications.slice(0, 12).map((notification, index) => ({\n action:\n notification.type === 'error'\n ? 'Incident detected'\n : notification.type === 'warning'\n ? 'Policy alert generated'\n : 'Operational event recorded',\n actor: employees[index % Math.max(employees.length, 1)]\n ? `${employees[index % employees.length].firstName} ${employees[index % employees.length].lastName}`\n : 'System',\n target: notification.title,\n timestamp: isoDateTime(notification.createdAt),\n severity:\n notification.type === 'error' ? 'high' : notification.type === 'warning' ? 'medium' : 'low',\n }));\n }, [employees, notifications]);\n\n const userRoles = useMemo<UserRole[]>(() => {\n const managers = employees.filter((employee) =>\n employee.position.toLowerCase().includes('manager')\n ).length;\n const leads = employees.filter((employee) =>\n employee.position.toLowerCase().includes('lead')\n ).length;\n const recruiters = jobPostings.filter((posting) => posting.status === 'active').length;\n return [\n { role: 'Super Admin', count: 2, permissions: 'Full access' },\n {\n role: 'HR Manager',\n count: Math.max(1, managers),\n permissions: 'Employee, payroll, leave management',\n },\n {\n role: 'Hiring Manager',\n count: Math.max(1, recruiters),\n permissions: 'Job postings, candidates, interviews',\n },\n {\n role: 'Department Lead',\n count: Math.max(1, leads),\n permissions: 'Team management, reports',\n },\n {\n role: 'Employee',\n count: Math.max(0, employees.length - managers - leads),\n permissions: 'Self-service, directory, learning',\n },\n ];\n }, [employees, jobPostings]);\n\n const securityScore = Math.round(\n (systemModules.filter((module) => module.status === 'operational').length /\n Math.max(systemModules.length, 1)) *\n 100\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\">Administration</h1>\n <p className=\"text-sm text-text-secondary\">\n System administration and access management\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <Wrench className=\"mr-1 h-4 w-4\" />\n System Settings\n </Button>\n <Button size=\"sm\">\n <Shield className=\"mr-1 h-4 w-4\" />\n Security\n </Button>\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\">Total Users</CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{employees.length}</div>\n <p className=\"text-xs text-text-secondary\">{departments.length} 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\">Active Sessions</CardTitle>\n <Monitor className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{Math.round(employees.length * 0.76)}</div>\n <p className=\"text-xs text-text-secondary\">Estimated from active workforce</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\">System Uptime</CardTitle>\n <Server className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">99.95%</div>\n <p className=\"text-xs text-text-secondary\">Rolling platform uptime</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\">Security Score</CardTitle>\n <Shield className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{securityScore}/100</div>\n <p className=\"text-xs text-green-600\">Derived from module health checks</p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>System Status</CardTitle>\n <CardDescription>Module health and uptime</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {systemModules.map((module) => (\n <div\n key={module.name}\n className=\"flex items-center justify-between rounded border p-3\"\n >\n <div className=\"flex items-center gap-3\">\n <module.icon className=\"h-4 w-4 text-text-secondary\" />\n <span className=\"text-sm font-medium\">{module.name}</span>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-xs text-text-secondary\">{module.uptime}</span>\n <Badge\n variant={module.status === 'operational' ? 'default' : 'destructive'}\n className=\"text-[10px]\"\n >\n {module.status}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>User Roles</CardTitle>\n <CardDescription>Role distribution and permissions</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-2 grid grid-cols-3 gap-2 border-b pb-2 text-xs font-medium text-text-secondary\">\n <span>Role</span>\n <span className=\"text-right\">Users</span>\n <span>Permissions</span>\n </div>\n {userRoles.map((role) => (\n <div\n key={role.role}\n className=\"grid grid-cols-3 gap-2 border-b py-2 text-sm last:border-0\"\n >\n <span className=\"font-medium\">{role.role}</span>\n <span className=\"text-right\">{role.count}</span>\n <span className=\"truncate text-xs text-text-secondary\">{role.permissions}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Recent Audit Log</CardTitle>\n <CardDescription>System activity and security events</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-2 grid grid-cols-5 gap-2 border-b pb-2 text-xs font-medium text-text-secondary\">\n <span>Action</span>\n <span>Actor</span>\n <span>Target</span>\n <span>Timestamp</span>\n <span>Severity</span>\n </div>\n {recentAuditLogs.map((log, index) => (\n <div\n key={`${log.action}-${index}`}\n className=\"grid grid-cols-5 gap-2 border-b py-2 text-sm last:border-0\"\n >\n <span className=\"font-medium\">{log.action}</span>\n <span className=\"text-text-secondary\">{log.actor}</span>\n <span className=\"truncate text-text-secondary\">{log.target}</span>\n <span className=\"text-xs\">{log.timestamp}</span>\n <Badge\n variant={\n log.severity === 'high'\n ? 'destructive'\n : log.severity === 'medium'\n ? 'secondary'\n : 'outline'\n }\n className=\"w-fit text-[10px]\"\n >\n {log.severity}\n </Badge>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -62,7 +62,7 @@ function x() {
|
|
|
62
62
|
className: "text-2xl font-semibold",
|
|
63
63
|
children: "Workforce Analytics"
|
|
64
64
|
}), /* @__PURE__ */ c("p", {
|
|
65
|
-
className: "text-sm text-
|
|
65
|
+
className: "text-sm text-text-secondary",
|
|
66
66
|
children: "Comprehensive analytics across all HR domains"
|
|
67
67
|
})] }), /* @__PURE__ */ l(d, {
|
|
68
68
|
variant: "outline",
|
|
@@ -78,7 +78,7 @@ function x() {
|
|
|
78
78
|
children: [/* @__PURE__ */ c(g, {
|
|
79
79
|
className: "text-sm font-medium",
|
|
80
80
|
children: "Total Workforce"
|
|
81
|
-
}), /* @__PURE__ */ c(s, { className: "h-4 w-4 text-
|
|
81
|
+
}), /* @__PURE__ */ c(s, { className: "h-4 w-4 text-text-secondary" })]
|
|
82
82
|
}), /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ c("div", {
|
|
83
83
|
className: "text-2xl font-bold",
|
|
84
84
|
children: x.length
|
|
@@ -91,12 +91,12 @@ function x() {
|
|
|
91
91
|
children: [/* @__PURE__ */ c(g, {
|
|
92
92
|
className: "text-sm font-medium",
|
|
93
93
|
children: "Active Departments"
|
|
94
|
-
}), /* @__PURE__ */ c(a, { className: "h-4 w-4 text-
|
|
94
|
+
}), /* @__PURE__ */ c(a, { className: "h-4 w-4 text-text-secondary" })]
|
|
95
95
|
}), /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ c("div", {
|
|
96
96
|
className: "text-2xl font-bold",
|
|
97
97
|
children: S.length
|
|
98
98
|
}), /* @__PURE__ */ c("p", {
|
|
99
|
-
className: "text-xs text-
|
|
99
|
+
className: "text-xs text-text-secondary",
|
|
100
100
|
children: "All departments tracked"
|
|
101
101
|
})] })] }),
|
|
102
102
|
/* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l(h, {
|
|
@@ -104,12 +104,12 @@ function x() {
|
|
|
104
104
|
children: [/* @__PURE__ */ c(g, {
|
|
105
105
|
className: "text-sm font-medium",
|
|
106
106
|
children: "Active Projects"
|
|
107
|
-
}), /* @__PURE__ */ c(n, { className: "h-4 w-4 text-
|
|
107
|
+
}), /* @__PURE__ */ c(n, { className: "h-4 w-4 text-text-secondary" })]
|
|
108
108
|
}), /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ c("div", {
|
|
109
109
|
className: "text-2xl font-bold",
|
|
110
110
|
children: T.filter((e) => e.status === "active").length
|
|
111
111
|
}), /* @__PURE__ */ l("p", {
|
|
112
|
-
className: "text-xs text-
|
|
112
|
+
className: "text-xs text-text-secondary",
|
|
113
113
|
children: [T.filter((e) => e.status === "completed").length, " completed"]
|
|
114
114
|
})] })] }),
|
|
115
115
|
/* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l(h, {
|
|
@@ -117,12 +117,12 @@ function x() {
|
|
|
117
117
|
children: [/* @__PURE__ */ c(g, {
|
|
118
118
|
className: "text-sm font-medium",
|
|
119
119
|
children: "Hiring Pipeline"
|
|
120
|
-
}), /* @__PURE__ */ c(r, { className: "h-4 w-4 text-
|
|
120
|
+
}), /* @__PURE__ */ c(r, { className: "h-4 w-4 text-text-secondary" })]
|
|
121
121
|
}), /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ c("div", {
|
|
122
122
|
className: "text-2xl font-bold",
|
|
123
123
|
children: w.length
|
|
124
124
|
}), /* @__PURE__ */ c("p", {
|
|
125
|
-
className: "text-xs text-
|
|
125
|
+
className: "text-xs text-text-secondary",
|
|
126
126
|
children: "candidates in pipeline"
|
|
127
127
|
})] })] })
|
|
128
128
|
]
|
|
@@ -153,13 +153,13 @@ function x() {
|
|
|
153
153
|
className: "flex items-center gap-3",
|
|
154
154
|
children: [
|
|
155
155
|
/* @__PURE__ */ c("span", {
|
|
156
|
-
className: "w-10 text-sm text-
|
|
156
|
+
className: "w-10 text-sm text-text-secondary",
|
|
157
157
|
children: e.month
|
|
158
158
|
}),
|
|
159
159
|
/* @__PURE__ */ c("div", {
|
|
160
|
-
className: "h-5 flex-1 overflow-hidden rounded bg-
|
|
160
|
+
className: "h-5 flex-1 overflow-hidden rounded bg-bg-sunken",
|
|
161
161
|
children: /* @__PURE__ */ c("div", {
|
|
162
|
-
className: "h-5 rounded bg-primary",
|
|
162
|
+
className: "h-5 rounded bg-action-primary-bg",
|
|
163
163
|
style: { width: `${Math.round(e.headcount / k * 100)}%` }
|
|
164
164
|
})
|
|
165
165
|
}),
|
|
@@ -200,7 +200,7 @@ function x() {
|
|
|
200
200
|
children: e.stage
|
|
201
201
|
}),
|
|
202
202
|
/* @__PURE__ */ c("div", {
|
|
203
|
-
className: "h-6 flex-1 overflow-hidden rounded bg-
|
|
203
|
+
className: "h-6 flex-1 overflow-hidden rounded bg-bg-sunken",
|
|
204
204
|
children: /* @__PURE__ */ c("div", {
|
|
205
205
|
className: `h-6 rounded ${e.color}`,
|
|
206
206
|
style: { width: `${Math.max(Math.round(e.count / j * 100), 5)}%` }
|
|
@@ -218,7 +218,7 @@ function x() {
|
|
|
218
218
|
value: "departments",
|
|
219
219
|
className: "space-y-4",
|
|
220
220
|
children: /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l(h, { children: [/* @__PURE__ */ c(g, { children: "Department Breakdown" }), /* @__PURE__ */ c(m, { children: "Headcount and budget by department" })] }), /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ l("div", {
|
|
221
|
-
className: "mb-2 grid grid-cols-4 gap-2 border-b pb-2 text-xs font-medium text-
|
|
221
|
+
className: "mb-2 grid grid-cols-4 gap-2 border-b pb-2 text-xs font-medium text-text-secondary",
|
|
222
222
|
children: [
|
|
223
223
|
/* @__PURE__ */ c("span", { children: "Department" }),
|
|
224
224
|
/* @__PURE__ */ c("span", {
|
|
@@ -251,9 +251,9 @@ function x() {
|
|
|
251
251
|
]
|
|
252
252
|
}),
|
|
253
253
|
/* @__PURE__ */ c("div", {
|
|
254
|
-
className: "h-3 overflow-hidden rounded bg-
|
|
254
|
+
className: "h-3 overflow-hidden rounded bg-bg-sunken",
|
|
255
255
|
children: /* @__PURE__ */ c("div", {
|
|
256
|
-
className: "h-3 rounded bg-primary/70",
|
|
256
|
+
className: "h-3 rounded bg-action-primary-bg/70",
|
|
257
257
|
style: { width: `${Math.round(e.count / O * 100)}%` }
|
|
258
258
|
})
|
|
259
259
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyticsAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/AnalyticsAnalyticsPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Activity, BarChart3, Calendar, PieChart, TrendingUp, Users } from 'lucide-react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype MonthlyMetric = {\n month: string;\n headcount: number;\n hires: number;\n exits: number;\n openRoles: number;\n};\n\ntype FunnelStage = {\n stage: string;\n count: number;\n color: string;\n};\n\nexport function AnalyticsAnalyticsPagePage() {\n const { employees, departments, jobPostings, candidates, projects } = useCrewFoundryStore();\n\n const monthlyMetrics = useMemo<MonthlyMetric[]>(() => {\n const sortedEmployees = [...employees].sort((a, b) => a.startDate.localeCompare(b.startDate));\n const months = sortedEmployees.slice(-6).map((employee, index) => {\n const month = new Date(employee.startDate).toLocaleString('en-US', { month: 'short' });\n const hires = sortedEmployees.filter(\n (item) =>\n new Date(item.startDate).toLocaleString('en-US', { month: 'short' }) === month &&\n item.status === 'active'\n ).length;\n const exits = sortedEmployees.filter(\n (item) =>\n new Date(item.startDate).toLocaleString('en-US', { month: 'short' }) === month &&\n item.status === 'terminated'\n ).length;\n return {\n month,\n headcount: Math.max(1, sortedEmployees.length - (5 - index) * 2),\n hires,\n exits,\n openRoles: Math.max(\n 0,\n jobPostings.filter((posting) => posting.status === 'active').length - index\n ),\n };\n });\n return months.length > 0 ? months : [];\n }, [employees, jobPostings]);\n\n const deptDistribution = departments.map((department) => ({\n name: department.name,\n count: department.employeeCount,\n budget: department.budget,\n }));\n\n const maxDeptCount = Math.max(1, ...deptDistribution.map((department) => department.count));\n const maxMetric = Math.max(1, ...monthlyMetrics.map((metric) => metric.headcount));\n\n const hiringFunnel = useMemo<FunnelStage[]>(\n () => [\n {\n stage: 'Applications',\n count: jobPostings.reduce((sum, posting) => sum + posting.applicants, 0),\n color: 'bg-blue-500',\n },\n {\n stage: 'Screening',\n count: candidates.filter((candidate) => candidate.status === 'screening').length,\n color: 'bg-indigo-500',\n },\n {\n stage: 'Interview',\n count: candidates.filter((candidate) => candidate.status === 'interview').length,\n color: 'bg-purple-500',\n },\n {\n stage: 'Assessment',\n count: candidates.filter((candidate) => candidate.status === 'assessment').length,\n color: 'bg-pink-500',\n },\n {\n stage: 'Offer',\n count: candidates.filter((candidate) => candidate.status === 'offer').length,\n color: 'bg-orange-500',\n },\n {\n stage: 'Hired',\n count: candidates.filter((candidate) => candidate.status === 'hired').length,\n color: 'bg-green-500',\n },\n ],\n [candidates, jobPostings]\n );\n\n const maxFunnel = Math.max(1, ...hiringFunnel.map((stage) => stage.count));\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\">Workforce Analytics</h1>\n <p className=\"text-sm text-muted-foreground\">\n Comprehensive analytics across all HR domains\n </p>\n </div>\n <Button variant=\"outline\" size=\"sm\">\n <Calendar className=\"mr-2 h-4 w-4\" />\n Rolling 6 Months\n </Button>\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\">Total Workforce</CardTitle>\n <Users className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{employees.length}</div>\n <div className=\"flex items-center text-xs text-green-600\">\n <TrendingUp className=\"mr-1 h-3 w-3\" />\n Live headcount data\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\">Active Departments</CardTitle>\n <PieChart className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{departments.length}</div>\n <p className=\"text-xs text-muted-foreground\">All departments tracked</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\">Active Projects</CardTitle>\n <Activity className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {projects.filter((project) => project.status === 'active').length}\n </div>\n <p className=\"text-xs text-muted-foreground\">\n {projects.filter((project) => project.status === 'completed').length} completed\n </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\">Hiring Pipeline</CardTitle>\n <BarChart3 className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{candidates.length}</div>\n <p className=\"text-xs text-muted-foreground\">candidates in pipeline</p>\n </CardContent>\n </Card>\n </div>\n\n <Tabs defaultValue=\"overview\">\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n <TabsTrigger value=\"hiring\">Hiring Funnel</TabsTrigger>\n <TabsTrigger value=\"departments\">Departments</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\" className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle>Workforce Growth Trend</CardTitle>\n <CardDescription>Monthly headcount and hiring activity</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {monthlyMetrics.map((metric) => (\n <div\n key={`${metric.month}-${metric.headcount}`}\n className=\"flex items-center gap-3\"\n >\n <span className=\"w-10 text-sm text-muted-foreground\">{metric.month}</span>\n <div className=\"h-5 flex-1 overflow-hidden rounded bg-muted\">\n <div\n className=\"h-5 rounded bg-primary\"\n style={{ width: `${Math.round((metric.headcount / maxMetric) * 100)}%` }}\n />\n </div>\n <span className=\"w-10 text-right text-sm font-medium\">{metric.headcount}</span>\n <div className=\"flex w-32 justify-end gap-1\">\n <Badge variant=\"default\" className=\"text-[10px]\">\n +{metric.hires} hired\n </Badge>\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {metric.openRoles} open\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"hiring\" className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle>Hiring Funnel</CardTitle>\n <CardDescription>Candidate pipeline stages</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {hiringFunnel.map((stage) => (\n <div key={stage.stage} className=\"flex items-center gap-3\">\n <span className=\"w-28 text-sm font-medium\">{stage.stage}</span>\n <div className=\"h-6 flex-1 overflow-hidden rounded bg-muted\">\n <div\n className={`h-6 rounded ${stage.color}`}\n style={{\n width: `${Math.max(Math.round((stage.count / maxFunnel) * 100), 5)}%`,\n }}\n />\n </div>\n <span className=\"w-10 text-right text-sm font-bold\">{stage.count}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"departments\" className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle>Department Breakdown</CardTitle>\n <CardDescription>Headcount and budget by department</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-2 grid grid-cols-4 gap-2 border-b pb-2 text-xs font-medium text-muted-foreground\">\n <span>Department</span>\n <span className=\"text-right\">Headcount</span>\n <span className=\"text-right\">Budget</span>\n <span>Distribution</span>\n </div>\n {deptDistribution\n .sort((a, b) => b.count - a.count)\n .map((department) => (\n <div\n key={department.name}\n className=\"grid grid-cols-4 items-center gap-2 border-b py-2 text-sm last:border-0\"\n >\n <span className=\"font-medium\">{department.name}</span>\n <span className=\"text-right\">{department.count}</span>\n <span className=\"text-right\">${(department.budget / 1000000).toFixed(1)}M</span>\n <div className=\"h-3 overflow-hidden rounded bg-muted\">\n <div\n className=\"h-3 rounded bg-primary/70\"\n style={{ width: `${Math.round((department.count / maxDeptCount) * 100)}%` }}\n />\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AnalyticsAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/AnalyticsAnalyticsPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Activity, BarChart3, Calendar, PieChart, TrendingUp, Users } from 'lucide-react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype MonthlyMetric = {\n month: string;\n headcount: number;\n hires: number;\n exits: number;\n openRoles: number;\n};\n\ntype FunnelStage = {\n stage: string;\n count: number;\n color: string;\n};\n\nexport function AnalyticsAnalyticsPagePage() {\n const { employees, departments, jobPostings, candidates, projects } = useCrewFoundryStore();\n\n const monthlyMetrics = useMemo<MonthlyMetric[]>(() => {\n const sortedEmployees = [...employees].sort((a, b) => a.startDate.localeCompare(b.startDate));\n const months = sortedEmployees.slice(-6).map((employee, index) => {\n const month = new Date(employee.startDate).toLocaleString('en-US', { month: 'short' });\n const hires = sortedEmployees.filter(\n (item) =>\n new Date(item.startDate).toLocaleString('en-US', { month: 'short' }) === month &&\n item.status === 'active'\n ).length;\n const exits = sortedEmployees.filter(\n (item) =>\n new Date(item.startDate).toLocaleString('en-US', { month: 'short' }) === month &&\n item.status === 'terminated'\n ).length;\n return {\n month,\n headcount: Math.max(1, sortedEmployees.length - (5 - index) * 2),\n hires,\n exits,\n openRoles: Math.max(\n 0,\n jobPostings.filter((posting) => posting.status === 'active').length - index\n ),\n };\n });\n return months.length > 0 ? months : [];\n }, [employees, jobPostings]);\n\n const deptDistribution = departments.map((department) => ({\n name: department.name,\n count: department.employeeCount,\n budget: department.budget,\n }));\n\n const maxDeptCount = Math.max(1, ...deptDistribution.map((department) => department.count));\n const maxMetric = Math.max(1, ...monthlyMetrics.map((metric) => metric.headcount));\n\n const hiringFunnel = useMemo<FunnelStage[]>(\n () => [\n {\n stage: 'Applications',\n count: jobPostings.reduce((sum, posting) => sum + posting.applicants, 0),\n color: 'bg-blue-500',\n },\n {\n stage: 'Screening',\n count: candidates.filter((candidate) => candidate.status === 'screening').length,\n color: 'bg-indigo-500',\n },\n {\n stage: 'Interview',\n count: candidates.filter((candidate) => candidate.status === 'interview').length,\n color: 'bg-purple-500',\n },\n {\n stage: 'Assessment',\n count: candidates.filter((candidate) => candidate.status === 'assessment').length,\n color: 'bg-pink-500',\n },\n {\n stage: 'Offer',\n count: candidates.filter((candidate) => candidate.status === 'offer').length,\n color: 'bg-orange-500',\n },\n {\n stage: 'Hired',\n count: candidates.filter((candidate) => candidate.status === 'hired').length,\n color: 'bg-green-500',\n },\n ],\n [candidates, jobPostings]\n );\n\n const maxFunnel = Math.max(1, ...hiringFunnel.map((stage) => stage.count));\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\">Workforce Analytics</h1>\n <p className=\"text-sm text-text-secondary\">\n Comprehensive analytics across all HR domains\n </p>\n </div>\n <Button variant=\"outline\" size=\"sm\">\n <Calendar className=\"mr-2 h-4 w-4\" />\n Rolling 6 Months\n </Button>\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\">Total Workforce</CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{employees.length}</div>\n <div className=\"flex items-center text-xs text-green-600\">\n <TrendingUp className=\"mr-1 h-3 w-3\" />\n Live headcount data\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\">Active Departments</CardTitle>\n <PieChart className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{departments.length}</div>\n <p className=\"text-xs text-text-secondary\">All departments tracked</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\">Active Projects</CardTitle>\n <Activity className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {projects.filter((project) => project.status === 'active').length}\n </div>\n <p className=\"text-xs text-text-secondary\">\n {projects.filter((project) => project.status === 'completed').length} completed\n </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\">Hiring Pipeline</CardTitle>\n <BarChart3 className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{candidates.length}</div>\n <p className=\"text-xs text-text-secondary\">candidates in pipeline</p>\n </CardContent>\n </Card>\n </div>\n\n <Tabs defaultValue=\"overview\">\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n <TabsTrigger value=\"hiring\">Hiring Funnel</TabsTrigger>\n <TabsTrigger value=\"departments\">Departments</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\" className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle>Workforce Growth Trend</CardTitle>\n <CardDescription>Monthly headcount and hiring activity</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {monthlyMetrics.map((metric) => (\n <div\n key={`${metric.month}-${metric.headcount}`}\n className=\"flex items-center gap-3\"\n >\n <span className=\"w-10 text-sm text-text-secondary\">{metric.month}</span>\n <div className=\"h-5 flex-1 overflow-hidden rounded bg-bg-sunken\">\n <div\n className=\"h-5 rounded bg-action-primary-bg\"\n style={{ width: `${Math.round((metric.headcount / maxMetric) * 100)}%` }}\n />\n </div>\n <span className=\"w-10 text-right text-sm font-medium\">{metric.headcount}</span>\n <div className=\"flex w-32 justify-end gap-1\">\n <Badge variant=\"default\" className=\"text-[10px]\">\n +{metric.hires} hired\n </Badge>\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {metric.openRoles} open\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"hiring\" className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle>Hiring Funnel</CardTitle>\n <CardDescription>Candidate pipeline stages</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {hiringFunnel.map((stage) => (\n <div key={stage.stage} className=\"flex items-center gap-3\">\n <span className=\"w-28 text-sm font-medium\">{stage.stage}</span>\n <div className=\"h-6 flex-1 overflow-hidden rounded bg-bg-sunken\">\n <div\n className={`h-6 rounded ${stage.color}`}\n style={{\n width: `${Math.max(Math.round((stage.count / maxFunnel) * 100), 5)}%`,\n }}\n />\n </div>\n <span className=\"w-10 text-right text-sm font-bold\">{stage.count}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"departments\" className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle>Department Breakdown</CardTitle>\n <CardDescription>Headcount and budget by department</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-2 grid grid-cols-4 gap-2 border-b pb-2 text-xs font-medium text-text-secondary\">\n <span>Department</span>\n <span className=\"text-right\">Headcount</span>\n <span className=\"text-right\">Budget</span>\n <span>Distribution</span>\n </div>\n {deptDistribution\n .sort((a, b) => b.count - a.count)\n .map((department) => (\n <div\n key={department.name}\n className=\"grid grid-cols-4 items-center gap-2 border-b py-2 text-sm last:border-0\"\n >\n <span className=\"font-medium\">{department.name}</span>\n <span className=\"text-right\">{department.count}</span>\n <span className=\"text-right\">${(department.budget / 1000000).toFixed(1)}M</span>\n <div className=\"h-3 overflow-hidden rounded bg-bg-sunken\">\n <div\n className=\"h-3 rounded bg-action-primary-bg/70\"\n style={{ width: `${Math.round((department.count / maxDeptCount) * 100)}%` }}\n />\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -102,7 +102,7 @@ function _() {
|
|
|
102
102
|
className: "text-2xl font-semibold",
|
|
103
103
|
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
|
}),
|
|
@@ -114,12 +114,12 @@ function _() {
|
|
|
114
114
|
children: [/* @__PURE__ */ l(g, {
|
|
115
115
|
className: "text-sm font-medium",
|
|
116
116
|
children: "Active Employees"
|
|
117
|
-
}), /* @__PURE__ */ l(c, { className: "h-4 w-4 text-
|
|
117
|
+
}), /* @__PURE__ */ l(c, { className: "h-4 w-4 text-text-secondary" })]
|
|
118
118
|
}), /* @__PURE__ */ u(p, { children: [/* @__PURE__ */ l("div", {
|
|
119
119
|
className: "text-2xl font-bold",
|
|
120
120
|
children: C
|
|
121
121
|
}), /* @__PURE__ */ u("p", {
|
|
122
|
-
className: "text-xs text-
|
|
122
|
+
className: "text-xs text-text-secondary",
|
|
123
123
|
children: [w, " currently on leave"]
|
|
124
124
|
})] })] }),
|
|
125
125
|
/* @__PURE__ */ u(f, { children: [/* @__PURE__ */ u(h, {
|
|
@@ -127,7 +127,7 @@ function _() {
|
|
|
127
127
|
children: [/* @__PURE__ */ l(g, {
|
|
128
128
|
className: "text-sm font-medium",
|
|
129
129
|
children: "Avg Performance"
|
|
130
|
-
}), /* @__PURE__ */ l(o, { className: "h-4 w-4 text-
|
|
130
|
+
}), /* @__PURE__ */ l(o, { className: "h-4 w-4 text-text-secondary" })]
|
|
131
131
|
}), /* @__PURE__ */ u(p, { children: [/* @__PURE__ */ u("div", {
|
|
132
132
|
className: "text-2xl font-bold",
|
|
133
133
|
children: [x, "/5.0"]
|
|
@@ -140,12 +140,12 @@ function _() {
|
|
|
140
140
|
children: [/* @__PURE__ */ l(g, {
|
|
141
141
|
className: "text-sm font-medium",
|
|
142
142
|
children: "Avg Compensation"
|
|
143
|
-
}), /* @__PURE__ */ l(r, { className: "h-4 w-4 text-
|
|
143
|
+
}), /* @__PURE__ */ l(r, { className: "h-4 w-4 text-text-secondary" })]
|
|
144
144
|
}), /* @__PURE__ */ u(p, { children: [/* @__PURE__ */ u("div", {
|
|
145
145
|
className: "text-2xl font-bold",
|
|
146
146
|
children: ["$", S.toLocaleString()]
|
|
147
147
|
}), /* @__PURE__ */ l("p", {
|
|
148
|
-
className: "text-xs text-
|
|
148
|
+
className: "text-xs text-text-secondary",
|
|
149
149
|
children: "Across all departments"
|
|
150
150
|
})] })] }),
|
|
151
151
|
/* @__PURE__ */ u(f, { children: [/* @__PURE__ */ u(h, {
|
|
@@ -153,12 +153,12 @@ function _() {
|
|
|
153
153
|
children: [/* @__PURE__ */ l(g, {
|
|
154
154
|
className: "text-sm font-medium",
|
|
155
155
|
children: "Avg Tenure"
|
|
156
|
-
}), /* @__PURE__ */ l(i, { className: "h-4 w-4 text-
|
|
156
|
+
}), /* @__PURE__ */ l(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
157
157
|
}), /* @__PURE__ */ u(p, { children: [/* @__PURE__ */ l("div", {
|
|
158
158
|
className: "text-2xl font-bold",
|
|
159
159
|
children: "2.4 yrs"
|
|
160
160
|
}), /* @__PURE__ */ l("p", {
|
|
161
|
-
className: "text-xs text-
|
|
161
|
+
className: "text-xs text-text-secondary",
|
|
162
162
|
children: "Median: 2.1 years"
|
|
163
163
|
})] })] })
|
|
164
164
|
]
|
|
@@ -166,7 +166,7 @@ function _() {
|
|
|
166
166
|
/* @__PURE__ */ u("div", {
|
|
167
167
|
className: "grid gap-4 md:grid-cols-2",
|
|
168
168
|
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-
|
|
169
|
+
className: "grid grid-cols-4 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2",
|
|
170
170
|
children: [
|
|
171
171
|
/* @__PURE__ */ l("span", { children: "Department" }),
|
|
172
172
|
/* @__PURE__ */ l("span", {
|
|
@@ -222,7 +222,7 @@ function _() {
|
|
|
222
222
|
})]
|
|
223
223
|
})]
|
|
224
224
|
}), /* @__PURE__ */ l("div", {
|
|
225
|
-
className: "h-2 bg-
|
|
225
|
+
className: "h-2 bg-bg-sunken rounded overflow-hidden",
|
|
226
226
|
children: /* @__PURE__ */ l("div", {
|
|
227
227
|
className: `h-2 rounded ${e.score >= 4.5 ? "bg-green-500" : e.score >= 4 ? "bg-blue-500" : "bg-yellow-500"}`,
|
|
228
228
|
style: { width: `${e.score / 5 * 100}%` }
|
|
@@ -242,13 +242,13 @@ function _() {
|
|
|
242
242
|
className: "flex items-center gap-3",
|
|
243
243
|
children: [
|
|
244
244
|
/* @__PURE__ */ l("span", {
|
|
245
|
-
className: "w-20 text-sm text-
|
|
245
|
+
className: "w-20 text-sm text-text-secondary",
|
|
246
246
|
children: e.range
|
|
247
247
|
}),
|
|
248
248
|
/* @__PURE__ */ l("div", {
|
|
249
|
-
className: "flex-1 h-4 bg-
|
|
249
|
+
className: "flex-1 h-4 bg-bg-sunken rounded overflow-hidden",
|
|
250
250
|
children: /* @__PURE__ */ l("div", {
|
|
251
|
-
className: "h-4 bg-primary/70 rounded",
|
|
251
|
+
className: "h-4 bg-action-primary-bg/70 rounded",
|
|
252
252
|
style: { width: `${e.percentage}%` }
|
|
253
253
|
})
|
|
254
254
|
}),
|
|
@@ -257,7 +257,7 @@ function _() {
|
|
|
257
257
|
children: e.count
|
|
258
258
|
}),
|
|
259
259
|
/* @__PURE__ */ u("span", {
|
|
260
|
-
className: "text-xs text-
|
|
260
|
+
className: "text-xs text-text-secondary w-10 text-right",
|
|
261
261
|
children: [e.percentage, "%"]
|
|
262
262
|
})
|
|
263
263
|
]
|
|
@@ -298,7 +298,7 @@ function _() {
|
|
|
298
298
|
className: "text-sm font-medium",
|
|
299
299
|
children: "Highest Performance"
|
|
300
300
|
}), /* @__PURE__ */ u("p", {
|
|
301
|
-
className: "text-xs text-
|
|
301
|
+
className: "text-xs text-text-secondary mt-1",
|
|
302
302
|
children: [
|
|
303
303
|
"Engineering department leads with avg score of",
|
|
304
304
|
" ",
|
|
@@ -312,7 +312,7 @@ function _() {
|
|
|
312
312
|
className: "text-sm font-medium",
|
|
313
313
|
children: "Retention Risk"
|
|
314
314
|
}), /* @__PURE__ */ l("p", {
|
|
315
|
-
className: "text-xs text-
|
|
315
|
+
className: "text-xs text-text-secondary mt-1",
|
|
316
316
|
children: "12 employees flagged as flight risk based on engagement signals"
|
|
317
317
|
})]
|
|
318
318
|
}),
|
|
@@ -322,7 +322,7 @@ function _() {
|
|
|
322
322
|
className: "text-sm font-medium",
|
|
323
323
|
children: "Compensation Gap"
|
|
324
324
|
}), /* @__PURE__ */ l("p", {
|
|
325
|
-
className: "text-xs text-
|
|
325
|
+
className: "text-xs text-text-secondary mt-1",
|
|
326
326
|
children: "3 departments below market median, review recommended in Q2"
|
|
327
327
|
})]
|
|
328
328
|
})
|