@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 { BarChart3 as n, DollarSign as r, Target as i, TrendingDown as a, TrendingUp as o, Users as s } from "lucide-react";
|
|
4
4
|
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
5
|
-
import { Badge as u, Card as d, CardContent as f, CardDescription as p, CardHeader as m, CardTitle as h } from "@burdenoff/fe-libs/ui";
|
|
5
|
+
import { Badge as u, Card as d, CardContent as f, CardDescription as p, CardHeader as m, CardTitle as h, GlassCard as g, GradientText as _ } from "@burdenoff/fe-libs/ui";
|
|
6
6
|
//#region src/crewfoundry/pages/DashboardAnalyticsPagePage.tsx
|
|
7
|
-
function
|
|
8
|
-
let { employees:
|
|
9
|
-
let e = [...
|
|
7
|
+
function v() {
|
|
8
|
+
let { employees: v, departments: y, jobPostings: b, payrollRecords: x, projects: S } = e(), C = t(() => {
|
|
9
|
+
let e = [...v].sort((e, t) => e.startDate.localeCompare(t.startDate));
|
|
10
10
|
return e.slice(-6).map((t, n) => {
|
|
11
11
|
let r = new Date(t.startDate).toLocaleString("en-US", { month: "short" });
|
|
12
12
|
return {
|
|
@@ -16,26 +16,26 @@ function g() {
|
|
|
16
16
|
headcount: Math.max(1, e.length - (5 - n))
|
|
17
17
|
};
|
|
18
18
|
});
|
|
19
|
-
}, [
|
|
19
|
+
}, [v]), w = Math.max(1, ...C.map((e) => e.headcount)), T = x.reduce((e, t) => e + t.netPay, 0), E = Math.round(v.reduce((e, t) => e + t.salary, 0) / Math.max(v.length, 1)), D = b.filter((e) => e.status === "active").length, O = v.reduce((e, t) => {
|
|
20
20
|
let n = t.type.replace("_", " ");
|
|
21
21
|
return e[n] = (e[n] || 0) + 1, e;
|
|
22
|
-
}, {}),
|
|
22
|
+
}, {}), k = t(() => {
|
|
23
23
|
let e = [
|
|
24
24
|
{
|
|
25
25
|
category: "Payroll",
|
|
26
|
-
amount:
|
|
26
|
+
amount: T
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
29
|
category: "Recruitment",
|
|
30
|
-
amount:
|
|
30
|
+
amount: b.reduce((e, t) => e + t.applicants * 120, 0)
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
category: "Project Delivery",
|
|
34
|
-
amount:
|
|
34
|
+
amount: S.reduce((e, t) => e + t.spent, 0)
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
category: "Department Ops",
|
|
38
|
-
amount:
|
|
38
|
+
amount: y.reduce((e, t) => e + t.budget * .03, 0)
|
|
39
39
|
}
|
|
40
40
|
], t = e.reduce((e, t) => e + t.amount, 0) || 1;
|
|
41
41
|
return e.map((e) => ({
|
|
@@ -43,76 +43,92 @@ function g() {
|
|
|
43
43
|
percentage: Math.round(e.amount / t * 100)
|
|
44
44
|
}));
|
|
45
45
|
}, [
|
|
46
|
-
|
|
47
|
-
v,
|
|
46
|
+
y,
|
|
48
47
|
b,
|
|
49
|
-
|
|
48
|
+
S,
|
|
49
|
+
T
|
|
50
50
|
]);
|
|
51
51
|
return /* @__PURE__ */ l("div", {
|
|
52
52
|
className: "space-y-6 p-6",
|
|
53
53
|
children: [
|
|
54
54
|
/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h1", {
|
|
55
55
|
className: "text-2xl font-semibold",
|
|
56
|
-
children: "Dashboard Analytics"
|
|
56
|
+
children: /* @__PURE__ */ c(_, { children: "Dashboard Analytics" })
|
|
57
57
|
}), /* @__PURE__ */ c("p", {
|
|
58
|
-
className: "text-sm text-
|
|
58
|
+
className: "text-sm text-text-secondary",
|
|
59
59
|
children: "Workforce analytics and operational insights"
|
|
60
60
|
})] }),
|
|
61
61
|
/* @__PURE__ */ l("div", {
|
|
62
62
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
|
|
63
63
|
children: [
|
|
64
|
-
/* @__PURE__ */ l(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
className: "
|
|
101
|
-
children: [/* @__PURE__ */
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
className: "
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
64
|
+
/* @__PURE__ */ l(g, {
|
|
65
|
+
treatment: "metric",
|
|
66
|
+
className: "border-border-seam",
|
|
67
|
+
children: [/* @__PURE__ */ l(m, {
|
|
68
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
69
|
+
children: [/* @__PURE__ */ c(h, {
|
|
70
|
+
className: "text-sm font-medium",
|
|
71
|
+
children: "Total Headcount"
|
|
72
|
+
}), /* @__PURE__ */ c(s, { className: "h-4 w-4 text-text-secondary" })]
|
|
73
|
+
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ c("div", {
|
|
74
|
+
className: "text-2xl font-bold tabular-nums",
|
|
75
|
+
children: v.length
|
|
76
|
+
}), /* @__PURE__ */ l("div", {
|
|
77
|
+
className: "flex items-center text-xs text-status-success-text",
|
|
78
|
+
children: [/* @__PURE__ */ c(o, { className: "mr-1 h-3 w-3" }), "Live workforce count"]
|
|
79
|
+
})] })]
|
|
80
|
+
}),
|
|
81
|
+
/* @__PURE__ */ l(g, {
|
|
82
|
+
treatment: "metric",
|
|
83
|
+
className: "border-border-seam",
|
|
84
|
+
children: [/* @__PURE__ */ l(m, {
|
|
85
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
86
|
+
children: [/* @__PURE__ */ c(h, {
|
|
87
|
+
className: "text-sm font-medium",
|
|
88
|
+
children: "Avg Salary"
|
|
89
|
+
}), /* @__PURE__ */ c(r, { className: "h-4 w-4 text-text-secondary" })]
|
|
90
|
+
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
|
|
91
|
+
className: "text-2xl font-bold tabular-nums",
|
|
92
|
+
children: ["$", E.toLocaleString()]
|
|
93
|
+
}), /* @__PURE__ */ l("div", {
|
|
94
|
+
className: "flex items-center text-xs text-status-success-text",
|
|
95
|
+
children: [/* @__PURE__ */ c(o, { className: "mr-1 h-3 w-3" }), "Updated from employee records"]
|
|
96
|
+
})] })]
|
|
97
|
+
}),
|
|
98
|
+
/* @__PURE__ */ l(g, {
|
|
99
|
+
treatment: "metric",
|
|
100
|
+
className: "border-border-seam",
|
|
101
|
+
children: [/* @__PURE__ */ l(m, {
|
|
102
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
103
|
+
children: [/* @__PURE__ */ c(h, {
|
|
104
|
+
className: "text-sm font-medium",
|
|
105
|
+
children: "Attrition Rate"
|
|
106
|
+
}), /* @__PURE__ */ c(a, { className: "h-4 w-4 text-text-secondary" })]
|
|
107
|
+
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
|
|
108
|
+
className: "text-2xl font-bold tabular-nums",
|
|
109
|
+
children: [Math.round(v.filter((e) => e.status === "terminated").length / Math.max(v.length, 1) * 100), "%"]
|
|
110
|
+
}), /* @__PURE__ */ l("div", {
|
|
111
|
+
className: "flex items-center text-xs text-status-success-text",
|
|
112
|
+
children: [/* @__PURE__ */ c(a, { className: "mr-1 h-3 w-3" }), "Calculated from status mix"]
|
|
113
|
+
})] })]
|
|
114
|
+
}),
|
|
115
|
+
/* @__PURE__ */ l(g, {
|
|
116
|
+
treatment: "metric",
|
|
117
|
+
className: "border-border-seam",
|
|
118
|
+
children: [/* @__PURE__ */ l(m, {
|
|
119
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
120
|
+
children: [/* @__PURE__ */ c(h, {
|
|
121
|
+
className: "text-sm font-medium",
|
|
122
|
+
children: "Open Roles"
|
|
123
|
+
}), /* @__PURE__ */ c(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
124
|
+
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ c("div", {
|
|
125
|
+
className: "text-2xl font-bold tabular-nums",
|
|
126
|
+
children: D
|
|
127
|
+
}), /* @__PURE__ */ c("p", {
|
|
128
|
+
className: "text-xs text-text-secondary",
|
|
129
|
+
children: "Based on active job postings"
|
|
130
|
+
})] })]
|
|
131
|
+
})
|
|
116
132
|
]
|
|
117
133
|
}),
|
|
118
134
|
/* @__PURE__ */ l("div", {
|
|
@@ -121,18 +137,18 @@ function g() {
|
|
|
121
137
|
className: "col-span-4",
|
|
122
138
|
children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Headcount Trend" }), /* @__PURE__ */ c(p, { children: "Monthly headcount over recent months" })] }), /* @__PURE__ */ c(f, {
|
|
123
139
|
className: "space-y-3",
|
|
124
|
-
children:
|
|
140
|
+
children: C.map((e, t) => /* @__PURE__ */ l("div", {
|
|
125
141
|
className: "flex items-center gap-3",
|
|
126
142
|
children: [
|
|
127
143
|
/* @__PURE__ */ c("span", {
|
|
128
|
-
className: "w-10 text-sm text-
|
|
144
|
+
className: "w-10 text-sm text-text-secondary",
|
|
129
145
|
children: e.month
|
|
130
146
|
}),
|
|
131
147
|
/* @__PURE__ */ c("div", {
|
|
132
|
-
className: "h-4 flex-1 overflow-hidden rounded bg-
|
|
148
|
+
className: "h-4 flex-1 overflow-hidden rounded bg-bg-sunken",
|
|
133
149
|
children: /* @__PURE__ */ c("div", {
|
|
134
|
-
className: "h-4 rounded bg-primary",
|
|
135
|
-
style: { width: `${Math.round(e.headcount /
|
|
150
|
+
className: "h-4 rounded bg-action-primary-bg",
|
|
151
|
+
style: { width: `${Math.round(e.headcount / w * 100)}%` }
|
|
136
152
|
})
|
|
137
153
|
}),
|
|
138
154
|
/* @__PURE__ */ c("span", {
|
|
@@ -158,11 +174,11 @@ function g() {
|
|
|
158
174
|
className: "col-span-3",
|
|
159
175
|
children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Employee Types" }), /* @__PURE__ */ c(p, { children: "Distribution by employment type" })] }), /* @__PURE__ */ c(f, {
|
|
160
176
|
className: "space-y-4",
|
|
161
|
-
children: Object.entries(
|
|
177
|
+
children: Object.entries(O).sort(([, e], [, t]) => t - e).map(([e, t]) => /* @__PURE__ */ l("div", {
|
|
162
178
|
className: "flex items-center justify-between",
|
|
163
179
|
children: [/* @__PURE__ */ l("div", {
|
|
164
180
|
className: "flex items-center gap-2",
|
|
165
|
-
children: [/* @__PURE__ */ c(n, { className: "h-4 w-4 text-
|
|
181
|
+
children: [/* @__PURE__ */ c(n, { className: "h-4 w-4 text-text-secondary" }), /* @__PURE__ */ c("span", {
|
|
166
182
|
className: "text-sm capitalize",
|
|
167
183
|
children: e
|
|
168
184
|
})]
|
|
@@ -172,10 +188,10 @@ function g() {
|
|
|
172
188
|
className: "text-sm font-medium",
|
|
173
189
|
children: t
|
|
174
190
|
}), /* @__PURE__ */ l("span", {
|
|
175
|
-
className: "text-xs text-
|
|
191
|
+
className: "text-xs text-text-secondary",
|
|
176
192
|
children: [
|
|
177
193
|
"(",
|
|
178
|
-
Math.round(t / Math.max(
|
|
194
|
+
Math.round(t / Math.max(v.length, 1) * 100),
|
|
179
195
|
"%)"
|
|
180
196
|
]
|
|
181
197
|
})]
|
|
@@ -186,17 +202,17 @@ function g() {
|
|
|
186
202
|
}),
|
|
187
203
|
/* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Workforce Cost Breakdown" }), /* @__PURE__ */ c(p, { children: "Operational costs by category" })] }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ c("div", {
|
|
188
204
|
className: "space-y-3",
|
|
189
|
-
children:
|
|
205
|
+
children: k.map((e) => /* @__PURE__ */ l("div", {
|
|
190
206
|
className: "flex items-center gap-4",
|
|
191
207
|
children: [
|
|
192
208
|
/* @__PURE__ */ c("span", {
|
|
193
|
-
className: "w-48 text-sm text-
|
|
209
|
+
className: "w-48 text-sm text-text-secondary",
|
|
194
210
|
children: e.category
|
|
195
211
|
}),
|
|
196
212
|
/* @__PURE__ */ c("div", {
|
|
197
|
-
className: "h-3 flex-1 overflow-hidden rounded bg-
|
|
213
|
+
className: "h-3 flex-1 overflow-hidden rounded bg-bg-sunken",
|
|
198
214
|
children: /* @__PURE__ */ c("div", {
|
|
199
|
-
className: "h-3 rounded bg-primary/80",
|
|
215
|
+
className: "h-3 rounded bg-action-primary-bg/80",
|
|
200
216
|
style: { width: `${e.percentage}%` }
|
|
201
217
|
})
|
|
202
218
|
}),
|
|
@@ -209,7 +225,7 @@ function g() {
|
|
|
209
225
|
]
|
|
210
226
|
}),
|
|
211
227
|
/* @__PURE__ */ l("span", {
|
|
212
|
-
className: "w-10 text-right text-xs text-
|
|
228
|
+
className: "w-10 text-right text-xs text-text-secondary",
|
|
213
229
|
children: [e.percentage, "%"]
|
|
214
230
|
})
|
|
215
231
|
]
|
|
@@ -223,13 +239,13 @@ function g() {
|
|
|
223
239
|
className: "font-bold",
|
|
224
240
|
children: [
|
|
225
241
|
"$",
|
|
226
|
-
(
|
|
242
|
+
(k.reduce((e, t) => e + t.amount, 0) / 1e3).toFixed(0),
|
|
227
243
|
"K"
|
|
228
244
|
]
|
|
229
245
|
})]
|
|
230
246
|
})] })] }),
|
|
231
247
|
/* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Department Overview" }), /* @__PURE__ */ c(p, { children: "Key metrics by department" })] }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
|
|
232
|
-
className: "mb-2 grid grid-cols-5 gap-2 border-b pb-2 text-xs font-medium text-
|
|
248
|
+
className: "mb-2 grid grid-cols-5 gap-2 border-b pb-2 text-xs font-medium text-text-secondary",
|
|
233
249
|
children: [
|
|
234
250
|
/* @__PURE__ */ c("span", { children: "Department" }),
|
|
235
251
|
/* @__PURE__ */ c("span", { children: "Head" }),
|
|
@@ -246,7 +262,7 @@ function g() {
|
|
|
246
262
|
children: "Status"
|
|
247
263
|
})
|
|
248
264
|
]
|
|
249
|
-
}),
|
|
265
|
+
}), y.map((e) => /* @__PURE__ */ l("div", {
|
|
250
266
|
className: "grid grid-cols-5 gap-2 border-b py-2 text-sm last:border-0",
|
|
251
267
|
children: [
|
|
252
268
|
/* @__PURE__ */ c("span", {
|
|
@@ -254,7 +270,7 @@ function g() {
|
|
|
254
270
|
children: e.name
|
|
255
271
|
}),
|
|
256
272
|
/* @__PURE__ */ c("span", {
|
|
257
|
-
className: "text-
|
|
273
|
+
className: "text-text-secondary",
|
|
258
274
|
children: e.headName
|
|
259
275
|
}),
|
|
260
276
|
/* @__PURE__ */ c("span", {
|
|
@@ -282,6 +298,6 @@ function g() {
|
|
|
282
298
|
});
|
|
283
299
|
}
|
|
284
300
|
//#endregion
|
|
285
|
-
export {
|
|
301
|
+
export { v as DashboardAnalyticsPagePage };
|
|
286
302
|
|
|
287
303
|
//# sourceMappingURL=DashboardAnalyticsPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/DashboardAnalyticsPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { BarChart3, DollarSign, Target, TrendingDown, TrendingUp, Users } from 'lucide-react';\nimport {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype MonthlyTrend = {\n month: string;\n hires: number;\n attrition: number;\n headcount: number;\n};\n\ntype CostItem = {\n category: string;\n amount: number;\n percentage: number;\n};\n\nexport function DashboardAnalyticsPagePage() {\n const { employees, departments, jobPostings, payrollRecords, projects } = useCrewFoundryStore();\n\n const monthlyTrends = useMemo<MonthlyTrend[]>(() => {\n const sorted = [...employees].sort((a, b) => a.startDate.localeCompare(b.startDate));\n return sorted.slice(-6).map((employee, index) => {\n const month = new Date(employee.startDate).toLocaleString('en-US', { month: 'short' });\n const hires = sorted.filter(\n (item) =>\n new Date(item.startDate).toLocaleString('en-US', { month: 'short' }) === month &&\n item.status === 'active'\n ).length;\n const attrition = sorted.filter(\n (item) =>\n new Date(item.startDate).toLocaleString('en-US', { month: 'short' }) === month &&\n item.status === 'terminated'\n ).length;\n return {\n month,\n hires,\n attrition,\n headcount: Math.max(1, sorted.length - (5 - index)),\n };\n });\n }, [employees]);\n\n const maxTrend = Math.max(1, ...monthlyTrends.map((trend) => trend.headcount));\n\n const totalPayroll = payrollRecords.reduce((sum, record) => sum + record.netPay, 0);\n const avgSalary = Math.round(\n employees.reduce((sum, employee) => sum + employee.salary, 0) / Math.max(employees.length, 1)\n );\n const activePostings = jobPostings.filter((posting) => posting.status === 'active').length;\n\n const typeDistribution = employees.reduce<Record<string, number>>((acc, employee) => {\n const key = employee.type.replace('_', ' ');\n acc[key] = (acc[key] || 0) + 1;\n return acc;\n }, {});\n\n const costBreakdown = useMemo<CostItem[]>(() => {\n const costs: Array<{ category: string; amount: number }> = [\n { category: 'Payroll', amount: totalPayroll },\n {\n category: 'Recruitment',\n amount: jobPostings.reduce((sum, posting) => sum + posting.applicants * 120, 0),\n },\n {\n category: 'Project Delivery',\n amount: projects.reduce((sum, project) => sum + project.spent, 0),\n },\n {\n category: 'Department Ops',\n amount: departments.reduce((sum, department) => sum + department.budget * 0.03, 0),\n },\n ];\n const total = costs.reduce((sum, item) => sum + item.amount, 0) || 1;\n return costs.map((item) => ({\n ...item,\n percentage: Math.round((item.amount / total) * 100),\n }));\n }, [departments, jobPostings, projects, totalPayroll]);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Dashboard Analytics</h1>\n <p className=\"text-sm text-muted-foreground\">\n Workforce analytics and operational insights\n </p>\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 Headcount</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 workforce count\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 Salary</CardTitle>\n <DollarSign className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${avgSalary.toLocaleString()}</div>\n <div className=\"flex items-center text-xs text-green-600\">\n <TrendingUp className=\"mr-1 h-3 w-3\" />\n Updated from employee records\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\">Attrition Rate</CardTitle>\n <TrendingDown className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {Math.round(\n (employees.filter((employee) => employee.status === 'terminated').length /\n Math.max(employees.length, 1)) *\n 100\n )}\n %\n </div>\n <div className=\"flex items-center text-xs text-green-600\">\n <TrendingDown className=\"mr-1 h-3 w-3\" />\n Calculated from status mix\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\">Open Roles</CardTitle>\n <Target className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{activePostings}</div>\n <p className=\"text-xs text-muted-foreground\">Based on active job postings</p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-7\">\n <Card className=\"col-span-4\">\n <CardHeader>\n <CardTitle>Headcount Trend</CardTitle>\n <CardDescription>Monthly headcount over recent months</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {monthlyTrends.map((trend, index) => (\n <div key={`${trend.month}-${index}`} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-sm text-muted-foreground\">{trend.month}</span>\n <div className=\"h-4 flex-1 overflow-hidden rounded bg-muted\">\n <div\n className=\"h-4 rounded bg-primary\"\n style={{ width: `${Math.round((trend.headcount / maxTrend) * 100)}%` }}\n />\n </div>\n <span className=\"w-10 text-right text-sm font-medium\">{trend.headcount}</span>\n <div className=\"flex w-24 gap-1\">\n <Badge variant=\"default\" className=\"text-[10px]\">\n +{trend.hires}\n </Badge>\n <Badge variant=\"destructive\" className=\"text-[10px]\">\n -{trend.attrition}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card className=\"col-span-3\">\n <CardHeader>\n <CardTitle>Employee Types</CardTitle>\n <CardDescription>Distribution by employment type</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {Object.entries(typeDistribution)\n .sort(([, a], [, b]) => b - a)\n .map(([type, count]) => (\n <div key={type} className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <BarChart3 className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-sm capitalize\">{type}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium\">{count}</span>\n <span className=\"text-xs text-muted-foreground\">\n ({Math.round((count / Math.max(employees.length, 1)) * 100)}%)\n </span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Workforce Cost Breakdown</CardTitle>\n <CardDescription>Operational costs by category</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {costBreakdown.map((item) => (\n <div key={item.category} className=\"flex items-center gap-4\">\n <span className=\"w-48 text-sm text-muted-foreground\">{item.category}</span>\n <div className=\"h-3 flex-1 overflow-hidden rounded bg-muted\">\n <div\n className=\"h-3 rounded bg-primary/80\"\n style={{ width: `${item.percentage}%` }}\n />\n </div>\n <span className=\"w-24 text-right text-sm font-medium\">\n ${(item.amount / 1000).toFixed(0)}K\n </span>\n <span className=\"w-10 text-right text-xs text-muted-foreground\">\n {item.percentage}%\n </span>\n </div>\n ))}\n </div>\n <div className=\"mt-4 flex justify-between border-t pt-4 text-sm\">\n <span className=\"font-medium\">Total Monthly Cost</span>\n <span className=\"font-bold\">\n ${(costBreakdown.reduce((sum, item) => sum + item.amount, 0) / 1000).toFixed(0)}K\n </span>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Department Overview</CardTitle>\n <CardDescription>Key metrics by department</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-2 grid grid-cols-5 gap-2 border-b pb-2 text-xs font-medium text-muted-foreground\">\n <span>Department</span>\n <span>Head</span>\n <span className=\"text-right\">Employees</span>\n <span className=\"text-right\">Budget</span>\n <span className=\"text-right\">Status</span>\n </div>\n {departments.map((department) => (\n <div\n key={department.id}\n className=\"grid grid-cols-5 gap-2 border-b py-2 text-sm last:border-0\"\n >\n <span className=\"font-medium\">{department.name}</span>\n <span className=\"text-muted-foreground\">{department.headName}</span>\n <span className=\"text-right\">{department.employeeCount}</span>\n <span className=\"text-right\">${(department.budget / 1000000).toFixed(1)}M</span>\n <div className=\"text-right\">\n <Badge variant={department.status === 'active' ? 'default' : 'secondary'}>\n {department.status}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DashboardAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/DashboardAnalyticsPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { BarChart3, DollarSign, Target, TrendingDown, TrendingUp, Users } from 'lucide-react';\nimport {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype MonthlyTrend = {\n month: string;\n hires: number;\n attrition: number;\n headcount: number;\n};\n\ntype CostItem = {\n category: string;\n amount: number;\n percentage: number;\n};\n\nexport function DashboardAnalyticsPagePage() {\n const { employees, departments, jobPostings, payrollRecords, projects } = useCrewFoundryStore();\n\n const monthlyTrends = useMemo<MonthlyTrend[]>(() => {\n const sorted = [...employees].sort((a, b) => a.startDate.localeCompare(b.startDate));\n return sorted.slice(-6).map((employee, index) => {\n const month = new Date(employee.startDate).toLocaleString('en-US', { month: 'short' });\n const hires = sorted.filter(\n (item) =>\n new Date(item.startDate).toLocaleString('en-US', { month: 'short' }) === month &&\n item.status === 'active'\n ).length;\n const attrition = sorted.filter(\n (item) =>\n new Date(item.startDate).toLocaleString('en-US', { month: 'short' }) === month &&\n item.status === 'terminated'\n ).length;\n return {\n month,\n hires,\n attrition,\n headcount: Math.max(1, sorted.length - (5 - index)),\n };\n });\n }, [employees]);\n\n const maxTrend = Math.max(1, ...monthlyTrends.map((trend) => trend.headcount));\n\n const totalPayroll = payrollRecords.reduce((sum, record) => sum + record.netPay, 0);\n const avgSalary = Math.round(\n employees.reduce((sum, employee) => sum + employee.salary, 0) / Math.max(employees.length, 1)\n );\n const activePostings = jobPostings.filter((posting) => posting.status === 'active').length;\n\n const typeDistribution = employees.reduce<Record<string, number>>((acc, employee) => {\n const key = employee.type.replace('_', ' ');\n acc[key] = (acc[key] || 0) + 1;\n return acc;\n }, {});\n\n const costBreakdown = useMemo<CostItem[]>(() => {\n const costs: Array<{ category: string; amount: number }> = [\n { category: 'Payroll', amount: totalPayroll },\n {\n category: 'Recruitment',\n amount: jobPostings.reduce((sum, posting) => sum + posting.applicants * 120, 0),\n },\n {\n category: 'Project Delivery',\n amount: projects.reduce((sum, project) => sum + project.spent, 0),\n },\n {\n category: 'Department Ops',\n amount: departments.reduce((sum, department) => sum + department.budget * 0.03, 0),\n },\n ];\n const total = costs.reduce((sum, item) => sum + item.amount, 0) || 1;\n return costs.map((item) => ({\n ...item,\n percentage: Math.round((item.amount / total) * 100),\n }));\n }, [departments, jobPostings, projects, totalPayroll]);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Dashboard Analytics</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Workforce analytics and operational insights</p>\n </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\">Total Headcount</CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{employees.length}</div>\n <div className=\"flex items-center text-xs text-status-success-text\">\n <TrendingUp className=\"mr-1 h-3 w-3\" />\n Live workforce count\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Avg Salary</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${avgSalary.toLocaleString()}</div>\n <div className=\"flex items-center text-xs text-status-success-text\">\n <TrendingUp className=\"mr-1 h-3 w-3\" />\n Updated from employee records\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Attrition Rate</CardTitle>\n <TrendingDown className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {Math.round(\n (employees.filter((employee) => employee.status === 'terminated').length /\n Math.max(employees.length, 1)) *\n 100\n )}\n %\n </div>\n <div className=\"flex items-center text-xs text-status-success-text\">\n <TrendingDown className=\"mr-1 h-3 w-3\" />\n Calculated from status mix\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Open Roles</CardTitle>\n <Target className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{activePostings}</div>\n <p className=\"text-xs text-text-secondary\">Based on active job postings</p>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-7\">\n <Card className=\"col-span-4\">\n <CardHeader>\n <CardTitle>Headcount Trend</CardTitle>\n <CardDescription>Monthly headcount over recent months</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {monthlyTrends.map((trend, index) => (\n <div key={`${trend.month}-${index}`} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-sm text-text-secondary\">{trend.month}</span>\n <div className=\"h-4 flex-1 overflow-hidden rounded bg-bg-sunken\">\n <div\n className=\"h-4 rounded bg-action-primary-bg\"\n style={{ width: `${Math.round((trend.headcount / maxTrend) * 100)}%` }}\n />\n </div>\n <span className=\"w-10 text-right text-sm font-medium\">{trend.headcount}</span>\n <div className=\"flex w-24 gap-1\">\n <Badge variant=\"default\" className=\"text-[10px]\">\n +{trend.hires}\n </Badge>\n <Badge variant=\"destructive\" className=\"text-[10px]\">\n -{trend.attrition}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card className=\"col-span-3\">\n <CardHeader>\n <CardTitle>Employee Types</CardTitle>\n <CardDescription>Distribution by employment type</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {Object.entries(typeDistribution)\n .sort(([, a], [, b]) => b - a)\n .map(([type, count]) => (\n <div key={type} className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <BarChart3 className=\"h-4 w-4 text-text-secondary\" />\n <span className=\"text-sm capitalize\">{type}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium\">{count}</span>\n <span className=\"text-xs text-text-secondary\">\n ({Math.round((count / Math.max(employees.length, 1)) * 100)}%)\n </span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Workforce Cost Breakdown</CardTitle>\n <CardDescription>Operational costs by category</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {costBreakdown.map((item) => (\n <div key={item.category} className=\"flex items-center gap-4\">\n <span className=\"w-48 text-sm text-text-secondary\">{item.category}</span>\n <div className=\"h-3 flex-1 overflow-hidden rounded bg-bg-sunken\">\n <div\n className=\"h-3 rounded bg-action-primary-bg/80\"\n style={{ width: `${item.percentage}%` }}\n />\n </div>\n <span className=\"w-24 text-right text-sm font-medium\">\n ${(item.amount / 1000).toFixed(0)}K\n </span>\n <span className=\"w-10 text-right text-xs text-text-secondary\">\n {item.percentage}%\n </span>\n </div>\n ))}\n </div>\n <div className=\"mt-4 flex justify-between border-t pt-4 text-sm\">\n <span className=\"font-medium\">Total Monthly Cost</span>\n <span className=\"font-bold\">\n ${(costBreakdown.reduce((sum, item) => sum + item.amount, 0) / 1000).toFixed(0)}K\n </span>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Department Overview</CardTitle>\n <CardDescription>Key metrics by department</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-2 grid grid-cols-5 gap-2 border-b pb-2 text-xs font-medium text-text-secondary\">\n <span>Department</span>\n <span>Head</span>\n <span className=\"text-right\">Employees</span>\n <span className=\"text-right\">Budget</span>\n <span className=\"text-right\">Status</span>\n </div>\n {departments.map((department) => (\n <div\n key={department.id}\n className=\"grid grid-cols-5 gap-2 border-b py-2 text-sm last:border-0\"\n >\n <span className=\"font-medium\">{department.name}</span>\n <span className=\"text-text-secondary\">{department.headName}</span>\n <span className=\"text-right\">{department.employeeCount}</span>\n <span className=\"text-right\">${(department.budget / 1000000).toFixed(1)}M</span>\n <div className=\"text-right\">\n <Badge variant={department.status === 'active' ? 'default' : 'secondary'}>\n {department.status}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|