@burdenoff/microfe-crewfoundry 2026.624.1 → 2026.625.2
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 +100 -76
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +118 -94
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +105 -81
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +134 -110
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +121 -97
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +28 -15
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +74 -54
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +87 -69
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +99 -80
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +87 -68
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +31 -15
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +81 -61
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +71 -51
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +82 -58
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +46 -39
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +80 -62
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +104 -80
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +219 -151
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +183 -142
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +121 -97
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +57 -46
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +91 -67
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +112 -93
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +55 -48
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +70 -50
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +140 -97
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +101 -85
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +68 -48
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +99 -71
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +97 -73
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +100 -76
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +93 -69
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +65 -45
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +93 -75
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +117 -72
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +66 -54
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +36 -20
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +90 -66
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +81 -57
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +90 -65
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +33 -17
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +83 -59
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +68 -48
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +80 -60
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +153 -118
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +42 -37
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +67 -47
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +104 -85
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +76 -57
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +78 -60
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +138 -93
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +98 -53
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +69 -49
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +84 -65
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +76 -52
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +58 -40
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +85 -65
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +36 -29
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +108 -73
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +43 -27
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +67 -47
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +108 -63
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +83 -64
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +185 -144
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +40 -24
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,162 +1,226 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
2
|
import { useState as t } from "react";
|
|
3
3
|
import { Activity as n, Briefcase as r, Calendar as i, TrendingUp as a, Users as o } from "lucide-react";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { useNavigate as s } from "react-router-dom";
|
|
5
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
6
|
+
import { AuroraBackground as u, Badge as d, Button as f, Card as p, CardContent as m, CardDescription as h, CardHeader as g, CardTitle as _, EmphasisPanel as v, GlassCard as y, GradientText as b, IllustratedEmptyState as x, NextSteps as S, PagePurpose as C } from "@burdenoff/fe-libs/ui";
|
|
7
|
+
import { useI18n as w } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
7
8
|
//#region src/crewfoundry/pages/DashboardDashboardPagePage.tsx
|
|
8
|
-
function
|
|
9
|
-
let { t:
|
|
10
|
-
let n =
|
|
9
|
+
function T() {
|
|
10
|
+
let { t: T } = w(), E = s(), { employees: D, jobPostings: O, leaveRequests: k, notifications: A, projects: j } = e(), [M, N] = t("month"), P = (e, t) => {
|
|
11
|
+
let n = T(e);
|
|
11
12
|
return n === e ? t : n;
|
|
12
|
-
},
|
|
13
|
-
return /* @__PURE__ */
|
|
13
|
+
}, F = D.filter((e) => e.status === "active").length, I = D.filter((e) => e.status === "on_leave").length, L = O.filter((e) => e.status === "active").length, R = O.reduce((e, t) => e + t.applicants, 0), z = k.filter((e) => e.status === "pending").length, B = A.filter((e) => !e.read).length, V = j.filter((e) => e.status === "active").length, H = (D.reduce((e, t) => e + t.performanceScore, 0) / D.length).toFixed(1), U = D.reduce((e, t) => (e[t.department] = (e[t.department] || 0) + 1, e), {}), W = Math.max(...Object.values(U));
|
|
14
|
+
return /* @__PURE__ */ l("div", {
|
|
14
15
|
className: "space-y-6 p-6",
|
|
15
16
|
children: [
|
|
16
|
-
/* @__PURE__ */
|
|
17
|
-
className: "
|
|
18
|
-
children: [/* @__PURE__ */ c(
|
|
19
|
-
className: "
|
|
20
|
-
children:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
/* @__PURE__ */ l("div", {
|
|
18
|
+
className: "relative overflow-hidden rounded-xl border border-border-seam bg-gloss-card p-6",
|
|
19
|
+
children: [/* @__PURE__ */ c(u, { intensity: "subtle" }), /* @__PURE__ */ l("div", {
|
|
20
|
+
className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
|
|
21
|
+
children: [/* @__PURE__ */ l("div", { children: [
|
|
22
|
+
/* @__PURE__ */ c("h1", {
|
|
23
|
+
className: "text-2xl font-semibold",
|
|
24
|
+
children: /* @__PURE__ */ c(b, { children: P("crewfoundry.dashboard.title", "Workforce Dashboard") })
|
|
25
|
+
}),
|
|
26
|
+
/* @__PURE__ */ c("p", {
|
|
27
|
+
className: "text-sm text-text-secondary",
|
|
28
|
+
children: P("crewfoundry.dashboard.subtitle", "Overview of your organization's workforce metrics")
|
|
29
|
+
}),
|
|
30
|
+
/* @__PURE__ */ c(C, {
|
|
31
|
+
className: "mt-2",
|
|
32
|
+
children: P("crewfoundry.dashboard.purpose", "Your workforce command center — see headcount, hiring, performance, and projects at a glance, then jump straight to the area that needs your attention.")
|
|
33
|
+
})
|
|
34
|
+
] }), /* @__PURE__ */ c("div", {
|
|
35
|
+
className: "flex gap-2",
|
|
36
|
+
children: [
|
|
37
|
+
"week",
|
|
38
|
+
"month",
|
|
39
|
+
"quarter"
|
|
40
|
+
].map((e) => /* @__PURE__ */ c(f, {
|
|
41
|
+
variant: M === e ? "default" : "outline",
|
|
42
|
+
size: "sm",
|
|
43
|
+
onClick: () => N(e),
|
|
44
|
+
children: P(`crewfoundry.dashboard.period.${e}`, e.charAt(0).toUpperCase() + e.slice(1))
|
|
45
|
+
}, e))
|
|
46
|
+
})]
|
|
36
47
|
})]
|
|
37
48
|
}),
|
|
38
|
-
/* @__PURE__ */ c(
|
|
49
|
+
/* @__PURE__ */ c(S, {
|
|
50
|
+
storageKey: "crewfoundry-dashboard",
|
|
51
|
+
steps: [
|
|
52
|
+
{
|
|
53
|
+
id: "employees",
|
|
54
|
+
label: P("crewfoundry.dashboard.next.employees", "Review your team"),
|
|
55
|
+
description: P("crewfoundry.dashboard.next.employeesDesc", "Open the employee directory to see who is active and on leave."),
|
|
56
|
+
icon: /* @__PURE__ */ c(o, { className: "h-4 w-4" }),
|
|
57
|
+
onClick: () => E("../../hr/employees-page")
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "hiring",
|
|
61
|
+
label: P("crewfoundry.dashboard.next.hiring", "Post a new job"),
|
|
62
|
+
description: P("crewfoundry.dashboard.next.hiringDesc", "Create an opening to start collecting applicants."),
|
|
63
|
+
icon: /* @__PURE__ */ c(r, { className: "h-4 w-4" }),
|
|
64
|
+
onClick: () => E("../../hiring/create-job-page")
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "projects",
|
|
68
|
+
label: P("crewfoundry.dashboard.next.projects", "Check active projects"),
|
|
69
|
+
description: P("crewfoundry.dashboard.next.projectsDesc", "Track progress and budgets across in-flight work."),
|
|
70
|
+
icon: /* @__PURE__ */ c(n, { className: "h-4 w-4" }),
|
|
71
|
+
onClick: () => E("../../projects/projects-page")
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}),
|
|
75
|
+
/* @__PURE__ */ l("div", {
|
|
39
76
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
|
|
40
77
|
children: [
|
|
41
|
-
/* @__PURE__ */
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
className: "
|
|
70
|
-
children:
|
|
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
|
-
}), /* @__PURE__ */
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
78
|
+
/* @__PURE__ */ l(y, {
|
|
79
|
+
treatment: "glass",
|
|
80
|
+
glow: !0,
|
|
81
|
+
className: "border-border-seam",
|
|
82
|
+
children: [/* @__PURE__ */ l(g, {
|
|
83
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
84
|
+
children: [/* @__PURE__ */ c(_, {
|
|
85
|
+
className: "text-sm font-medium",
|
|
86
|
+
children: P("crewfoundry.dashboard.stats.totalEmployees", "Total Employees")
|
|
87
|
+
}), /* @__PURE__ */ c(o, { className: "h-4 w-4 text-text-secondary" })]
|
|
88
|
+
}), /* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c("div", {
|
|
89
|
+
className: "text-2xl font-bold tabular-nums",
|
|
90
|
+
children: D.length
|
|
91
|
+
}), /* @__PURE__ */ l("p", {
|
|
92
|
+
className: "text-xs text-text-secondary",
|
|
93
|
+
children: [
|
|
94
|
+
F,
|
|
95
|
+
" ",
|
|
96
|
+
P("crewfoundry.dashboard.stats.active", "active"),
|
|
97
|
+
", ",
|
|
98
|
+
I,
|
|
99
|
+
" ",
|
|
100
|
+
P("crewfoundry.dashboard.stats.onLeave", "on leave")
|
|
101
|
+
]
|
|
102
|
+
})] })]
|
|
103
|
+
}),
|
|
104
|
+
/* @__PURE__ */ l(y, {
|
|
105
|
+
treatment: "metric",
|
|
106
|
+
className: "border-border-seam",
|
|
107
|
+
children: [/* @__PURE__ */ l(g, {
|
|
108
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
109
|
+
children: [/* @__PURE__ */ c(_, {
|
|
110
|
+
className: "text-sm font-medium",
|
|
111
|
+
children: P("crewfoundry.dashboard.stats.openPositions", "Open Positions")
|
|
112
|
+
}), /* @__PURE__ */ c(r, { className: "h-4 w-4 text-text-secondary" })]
|
|
113
|
+
}), /* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c("div", {
|
|
114
|
+
className: "text-2xl font-bold tabular-nums",
|
|
115
|
+
children: L
|
|
116
|
+
}), /* @__PURE__ */ l("p", {
|
|
117
|
+
className: "text-xs text-text-secondary",
|
|
118
|
+
children: [
|
|
119
|
+
R,
|
|
120
|
+
" ",
|
|
121
|
+
P("crewfoundry.dashboard.stats.totalApplicants", "total applicants")
|
|
122
|
+
]
|
|
123
|
+
})] })]
|
|
124
|
+
}),
|
|
125
|
+
/* @__PURE__ */ l(y, {
|
|
126
|
+
treatment: "metric",
|
|
127
|
+
className: "border-border-seam",
|
|
128
|
+
children: [/* @__PURE__ */ l(g, {
|
|
129
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
130
|
+
children: [/* @__PURE__ */ c(_, {
|
|
131
|
+
className: "text-sm font-medium",
|
|
132
|
+
children: P("crewfoundry.dashboard.stats.avgPerformance", "Avg Performance")
|
|
133
|
+
}), /* @__PURE__ */ c(a, { className: "h-4 w-4 text-text-secondary" })]
|
|
134
|
+
}), /* @__PURE__ */ l(m, { children: [/* @__PURE__ */ l("div", {
|
|
135
|
+
className: "text-2xl font-bold tabular-nums",
|
|
136
|
+
children: [H, "/5"]
|
|
137
|
+
}), /* @__PURE__ */ c("p", {
|
|
138
|
+
className: "text-xs text-text-secondary",
|
|
139
|
+
children: P("crewfoundry.dashboard.stats.performanceTrend", "+0.2 from last quarter")
|
|
140
|
+
})] })]
|
|
141
|
+
}),
|
|
142
|
+
/* @__PURE__ */ l(y, {
|
|
143
|
+
treatment: "metric",
|
|
144
|
+
className: "border-border-seam",
|
|
145
|
+
children: [/* @__PURE__ */ l(g, {
|
|
146
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
147
|
+
children: [/* @__PURE__ */ c(_, {
|
|
148
|
+
className: "text-sm font-medium",
|
|
149
|
+
children: P("crewfoundry.dashboard.stats.activeProjects", "Active Projects")
|
|
150
|
+
}), /* @__PURE__ */ c(n, { className: "h-4 w-4 text-text-secondary" })]
|
|
151
|
+
}), /* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c("div", {
|
|
152
|
+
className: "text-2xl font-bold tabular-nums",
|
|
153
|
+
children: V
|
|
154
|
+
}), /* @__PURE__ */ l("p", {
|
|
155
|
+
className: "text-xs text-text-secondary",
|
|
156
|
+
children: [
|
|
157
|
+
z,
|
|
158
|
+
" ",
|
|
159
|
+
P("crewfoundry.dashboard.stats.pendingLeaveRequests", "pending leave requests")
|
|
160
|
+
]
|
|
161
|
+
})] })]
|
|
162
|
+
})
|
|
109
163
|
]
|
|
110
164
|
}),
|
|
111
|
-
/* @__PURE__ */
|
|
165
|
+
/* @__PURE__ */ l("div", {
|
|
112
166
|
className: "grid gap-4 md:grid-cols-7",
|
|
113
|
-
children: [/* @__PURE__ */
|
|
167
|
+
children: [/* @__PURE__ */ l(v, {
|
|
114
168
|
className: "col-span-4",
|
|
115
|
-
children: [
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
169
|
+
children: [
|
|
170
|
+
/* @__PURE__ */ c("div", {
|
|
171
|
+
className: "mb-1 text-lg font-semibold",
|
|
172
|
+
children: P("crewfoundry.dashboard.departmentHeadcount.title", "Department Headcount")
|
|
173
|
+
}),
|
|
174
|
+
/* @__PURE__ */ c("p", {
|
|
175
|
+
className: "mb-4 text-sm text-text-secondary",
|
|
176
|
+
children: P("crewfoundry.dashboard.departmentHeadcount.description", "Employee distribution across departments")
|
|
177
|
+
}),
|
|
178
|
+
/* @__PURE__ */ c("div", {
|
|
179
|
+
className: "space-y-3",
|
|
180
|
+
children: Object.entries(U).sort(([, e], [, t]) => t - e).map(([e, t]) => /* @__PURE__ */ l("div", {
|
|
181
|
+
className: "flex items-center gap-3",
|
|
182
|
+
children: [
|
|
183
|
+
/* @__PURE__ */ c("span", {
|
|
184
|
+
className: "w-24 text-sm text-text-secondary truncate",
|
|
185
|
+
children: e
|
|
186
|
+
}),
|
|
187
|
+
/* @__PURE__ */ c("div", {
|
|
188
|
+
className: "flex-1 h-4 bg-bg-sunken rounded overflow-hidden",
|
|
189
|
+
children: /* @__PURE__ */ c("div", {
|
|
190
|
+
className: "h-4 bg-action-primary-bg rounded",
|
|
191
|
+
style: { width: `${Math.round(t / W * 100)}%` }
|
|
192
|
+
})
|
|
193
|
+
}),
|
|
194
|
+
/* @__PURE__ */ c("span", {
|
|
195
|
+
className: "text-sm font-medium w-8 text-right tabular-nums",
|
|
196
|
+
children: t
|
|
129
197
|
})
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
]
|
|
136
|
-
}, e))
|
|
137
|
-
})]
|
|
138
|
-
}), /* @__PURE__ */ c(d, {
|
|
198
|
+
]
|
|
199
|
+
}, e))
|
|
200
|
+
})
|
|
201
|
+
]
|
|
202
|
+
}), /* @__PURE__ */ l(p, {
|
|
139
203
|
className: "col-span-3",
|
|
140
|
-
children: [/* @__PURE__ */
|
|
204
|
+
children: [/* @__PURE__ */ l(g, {
|
|
141
205
|
className: "flex flex-row items-center justify-between",
|
|
142
|
-
children: [/* @__PURE__ */
|
|
206
|
+
children: [/* @__PURE__ */ c(_, { children: P("crewfoundry.dashboard.notifications.title", "Recent Notifications") }), /* @__PURE__ */ l(d, {
|
|
143
207
|
variant: "secondary",
|
|
144
208
|
children: [
|
|
145
|
-
|
|
209
|
+
B,
|
|
146
210
|
" ",
|
|
147
|
-
|
|
211
|
+
P("crewfoundry.dashboard.notifications.unread", "unread")
|
|
148
212
|
]
|
|
149
213
|
})]
|
|
150
|
-
}), /* @__PURE__ */
|
|
214
|
+
}), /* @__PURE__ */ c(m, {
|
|
151
215
|
className: "space-y-4",
|
|
152
|
-
children:
|
|
216
|
+
children: A.slice(0, 5).map((e) => /* @__PURE__ */ l("div", {
|
|
153
217
|
className: "flex items-start gap-3",
|
|
154
|
-
children: [/* @__PURE__ */
|
|
218
|
+
children: [/* @__PURE__ */ c("div", { className: `mt-1 h-2 w-2 rounded-full flex-shrink-0 motion-safe:animate-vc-glow-pulse ${e.type === "success" ? "bg-status-success-text" : e.type === "warning" ? "bg-status-warning-text" : e.type === "error" ? "bg-status-error-text" : "bg-status-info-text"}` }), /* @__PURE__ */ l("div", {
|
|
155
219
|
className: "flex-1 min-w-0",
|
|
156
|
-
children: [/* @__PURE__ */
|
|
220
|
+
children: [/* @__PURE__ */ c("p", {
|
|
157
221
|
className: `text-sm ${e.read ? "text-text-secondary" : "font-medium"}`,
|
|
158
222
|
children: e.title
|
|
159
|
-
}), /* @__PURE__ */
|
|
223
|
+
}), /* @__PURE__ */ c("p", {
|
|
160
224
|
className: "text-xs text-text-secondary truncate",
|
|
161
225
|
children: e.message
|
|
162
226
|
})]
|
|
@@ -165,66 +229,70 @@ function _() {
|
|
|
165
229
|
})]
|
|
166
230
|
})]
|
|
167
231
|
}),
|
|
168
|
-
/* @__PURE__ */
|
|
232
|
+
/* @__PURE__ */ l("div", {
|
|
169
233
|
className: "grid gap-4 md:grid-cols-2",
|
|
170
|
-
children: [/* @__PURE__ */
|
|
234
|
+
children: [/* @__PURE__ */ l(p, { children: [/* @__PURE__ */ l(g, { children: [/* @__PURE__ */ c(_, { children: P("crewfoundry.dashboard.upcomingInterviews.title", "Upcoming Interviews") }), /* @__PURE__ */ c(h, { children: P("crewfoundry.dashboard.upcomingInterviews.description", "Scheduled for this week") })] }), /* @__PURE__ */ c(m, {
|
|
171
235
|
className: "space-y-3",
|
|
172
|
-
children:
|
|
236
|
+
children: j.filter((e) => e.status === "active").slice(0, 4).map((e) => /* @__PURE__ */ l("div", {
|
|
173
237
|
className: "flex items-center justify-between rounded border p-3",
|
|
174
|
-
children: [/* @__PURE__ */
|
|
238
|
+
children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
|
|
175
239
|
className: "text-sm font-medium",
|
|
176
240
|
children: e.name
|
|
177
|
-
}), /* @__PURE__ */
|
|
241
|
+
}), /* @__PURE__ */ c("p", {
|
|
178
242
|
className: "text-xs text-text-secondary",
|
|
179
243
|
children: e.teamName
|
|
180
|
-
})] }), /* @__PURE__ */
|
|
244
|
+
})] }), /* @__PURE__ */ l("div", {
|
|
181
245
|
className: "flex items-center gap-2",
|
|
182
|
-
children: [/* @__PURE__ */
|
|
246
|
+
children: [/* @__PURE__ */ c("div", {
|
|
183
247
|
className: "w-24 h-2 bg-bg-sunken rounded overflow-hidden",
|
|
184
|
-
children: /* @__PURE__ */
|
|
248
|
+
children: /* @__PURE__ */ c("div", {
|
|
185
249
|
className: "h-2 bg-action-primary-bg rounded",
|
|
186
250
|
style: { width: `${e.progress}%` }
|
|
187
251
|
})
|
|
188
|
-
}), /* @__PURE__ */
|
|
252
|
+
}), /* @__PURE__ */ l("span", {
|
|
189
253
|
className: "text-xs text-text-secondary",
|
|
190
254
|
children: [e.progress, "%"]
|
|
191
255
|
})]
|
|
192
256
|
})]
|
|
193
257
|
}, e.id))
|
|
194
|
-
})] }), /* @__PURE__ */
|
|
258
|
+
})] }), /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ l(g, { children: [/* @__PURE__ */ c(_, { children: P("crewfoundry.dashboard.leaveRequests.title", "Recent Leave Requests") }), /* @__PURE__ */ c(h, { children: P("crewfoundry.dashboard.leaveRequests.description", "Pending approval") })] }), /* @__PURE__ */ l(m, {
|
|
195
259
|
className: "space-y-3",
|
|
196
|
-
children:
|
|
260
|
+
children: [k.length === 0 && /* @__PURE__ */ c(x, {
|
|
261
|
+
illustration: "empty-data",
|
|
262
|
+
title: P("crewfoundry.dashboard.leaveRequests.emptyTitle", "No leave requests"),
|
|
263
|
+
description: P("crewfoundry.dashboard.leaveRequests.emptyDescription", "Pending leave requests will appear here.")
|
|
264
|
+
}), k.map((e) => /* @__PURE__ */ l("div", {
|
|
197
265
|
className: "flex items-center justify-between rounded border p-3",
|
|
198
|
-
children: [/* @__PURE__ */
|
|
266
|
+
children: [/* @__PURE__ */ c("div", {
|
|
199
267
|
className: "flex items-center gap-3",
|
|
200
|
-
children: /* @__PURE__ */
|
|
268
|
+
children: /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
|
|
201
269
|
className: "text-sm font-medium",
|
|
202
270
|
children: e.employeeName
|
|
203
|
-
}), /* @__PURE__ */
|
|
271
|
+
}), /* @__PURE__ */ l("div", {
|
|
204
272
|
className: "flex items-center gap-2 text-xs text-text-secondary",
|
|
205
|
-
children: [/* @__PURE__ */
|
|
273
|
+
children: [/* @__PURE__ */ c(i, { className: "h-3 w-3" }), /* @__PURE__ */ l("span", { children: [
|
|
206
274
|
e.startDate,
|
|
207
275
|
" - ",
|
|
208
276
|
e.endDate
|
|
209
277
|
] })]
|
|
210
278
|
})] })
|
|
211
|
-
}), /* @__PURE__ */
|
|
279
|
+
}), /* @__PURE__ */ l("div", {
|
|
212
280
|
className: "flex items-center gap-2",
|
|
213
|
-
children: [/* @__PURE__ */
|
|
281
|
+
children: [/* @__PURE__ */ c(d, {
|
|
214
282
|
variant: e.status === "approved" ? "default" : e.status === "pending" ? "secondary" : "destructive",
|
|
215
283
|
children: e.status
|
|
216
|
-
}), /* @__PURE__ */
|
|
284
|
+
}), /* @__PURE__ */ c(d, {
|
|
217
285
|
variant: "outline",
|
|
218
286
|
children: e.type
|
|
219
287
|
})]
|
|
220
288
|
})]
|
|
221
|
-
}, e.id))
|
|
289
|
+
}, e.id))]
|
|
222
290
|
})] })]
|
|
223
291
|
})
|
|
224
292
|
]
|
|
225
293
|
});
|
|
226
294
|
}
|
|
227
295
|
//#endregion
|
|
228
|
-
export {
|
|
296
|
+
export { T as DashboardDashboardPagePage };
|
|
229
297
|
|
|
230
298
|
//# sourceMappingURL=DashboardDashboardPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardDashboardPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/DashboardDashboardPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Activity,\n ArrowUpRight,\n Briefcase,\n Calendar,\n Clock,\n TrendingUp,\n Users,\n UserCheck,\n} from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function DashboardDashboardPagePage() {\n const { t: translate } = useI18n();\n const { employees, jobPostings, leaveRequests, notifications, projects } = useCrewFoundryStore();\n const [selectedPeriod, setSelectedPeriod] = useState<'week' | 'month' | 'quarter'>('month');\n const t = (key: string, fallback: string) => {\n const value = translate(key);\n return value === key ? fallback : value;\n };\n\n const activeEmployees = employees.filter((e) => e.status === 'active').length;\n const onLeave = employees.filter((e) => e.status === 'on_leave').length;\n const openPositions = jobPostings.filter((j) => j.status === 'active').length;\n const totalApplicants = jobPostings.reduce((sum, j) => sum + j.applicants, 0);\n const pendingLeaves = leaveRequests.filter((l) => l.status === 'pending').length;\n const unreadNotifications = notifications.filter((n) => !n.read).length;\n const activeProjects = projects.filter((p) => p.status === 'active').length;\n const avgPerformance = (\n employees.reduce((sum, e) => sum + e.performanceScore, 0) / employees.length\n ).toFixed(1);\n\n const departmentHeadcount = employees.reduce<Record<string, number>>((acc, e) => {\n acc[e.department] = (acc[e.department] || 0) + 1;\n return acc;\n }, {});\n\n const maxHeadcount = Math.max(...Object.values(departmentHeadcount));\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n {t('crewfoundry.dashboard.title', 'Workforce Dashboard')}\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {t(\n 'crewfoundry.dashboard.subtitle',\n \"Overview of your organization's workforce metrics\"\n )}\n </p>\n </div>\n <div className=\"flex gap-2\">\n {(['week', 'month', 'quarter'] as const).map((period) => (\n <Button\n key={period}\n variant={selectedPeriod === period ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedPeriod(period)}\n >\n {t(\n `crewfoundry.dashboard.period.${period}`,\n period.charAt(0).toUpperCase() + period.slice(1)\n )}\n </Button>\n ))}\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\">\n {t('crewfoundry.dashboard.stats.totalEmployees', 'Total Employees')}\n </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\">\n {activeEmployees} {t('crewfoundry.dashboard.stats.active', 'active')}, {onLeave}{' '}\n {t('crewfoundry.dashboard.stats.onLeave', 'on leave')}\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\">\n {t('crewfoundry.dashboard.stats.openPositions', 'Open Positions')}\n </CardTitle>\n <Briefcase className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{openPositions}</div>\n <p className=\"text-xs text-text-secondary\">\n {totalApplicants}{' '}\n {t('crewfoundry.dashboard.stats.totalApplicants', 'total applicants')}\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\">\n {t('crewfoundry.dashboard.stats.avgPerformance', 'Avg Performance')}\n </CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{avgPerformance}/5</div>\n <p className=\"text-xs text-text-secondary\">\n {t('crewfoundry.dashboard.stats.performanceTrend', '+0.2 from last quarter')}\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\">\n {t('crewfoundry.dashboard.stats.activeProjects', 'Active Projects')}\n </CardTitle>\n <Activity className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{activeProjects}</div>\n <p className=\"text-xs text-text-secondary\">\n {pendingLeaves}{' '}\n {t('crewfoundry.dashboard.stats.pendingLeaveRequests', 'pending leave requests')}\n </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>\n {t('crewfoundry.dashboard.departmentHeadcount.title', 'Department Headcount')}\n </CardTitle>\n <CardDescription>\n {t(\n 'crewfoundry.dashboard.departmentHeadcount.description',\n 'Employee distribution across departments'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {Object.entries(departmentHeadcount)\n .sort(([, a], [, b]) => b - a)\n .map(([dept, count]) => (\n <div key={dept} className=\"flex items-center gap-3\">\n <span className=\"w-24 text-sm text-text-secondary truncate\">{dept}</span>\n <div className=\"flex-1 h-4 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-4 bg-action-primary-bg rounded\"\n style={{ width: `${Math.round((count / maxHeadcount) * 100)}%` }}\n />\n </div>\n <span className=\"text-sm font-medium w-8 text-right\">{count}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card className=\"col-span-3\">\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <CardTitle>\n {t('crewfoundry.dashboard.notifications.title', 'Recent Notifications')}\n </CardTitle>\n <Badge variant=\"secondary\">\n {unreadNotifications} {t('crewfoundry.dashboard.notifications.unread', 'unread')}\n </Badge>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {notifications.slice(0, 5).map((notif) => (\n <div key={notif.id} className=\"flex items-start gap-3\">\n <div\n className={`mt-1 h-2 w-2 rounded-full flex-shrink-0 ${\n notif.type === 'success'\n ? 'bg-green-500'\n : notif.type === 'warning'\n ? 'bg-yellow-500'\n : notif.type === 'error'\n ? 'bg-red-500'\n : 'bg-blue-500'\n }`}\n />\n <div className=\"flex-1 min-w-0\">\n <p className={`text-sm ${notif.read ? 'text-text-secondary' : 'font-medium'}`}>\n {notif.title}\n </p>\n <p className=\"text-xs text-text-secondary truncate\">{notif.message}</p>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>\n {t('crewfoundry.dashboard.upcomingInterviews.title', 'Upcoming Interviews')}\n </CardTitle>\n <CardDescription>\n {t('crewfoundry.dashboard.upcomingInterviews.description', 'Scheduled for this week')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {projects\n .filter((p) => p.status === 'active')\n .slice(0, 4)\n .map((project) => (\n <div\n key={project.id}\n className=\"flex items-center justify-between rounded border p-3\"\n >\n <div>\n <p className=\"text-sm font-medium\">{project.name}</p>\n <p className=\"text-xs text-text-secondary\">{project.teamName}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"w-24 h-2 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-2 bg-action-primary-bg rounded\"\n style={{ width: `${project.progress}%` }}\n />\n </div>\n <span className=\"text-xs text-text-secondary\">{project.progress}%</span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>\n {t('crewfoundry.dashboard.leaveRequests.title', 'Recent Leave Requests')}\n </CardTitle>\n <CardDescription>\n {t('crewfoundry.dashboard.leaveRequests.description', 'Pending approval')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {leaveRequests.map((leave) => (\n <div key={leave.id} className=\"flex items-center justify-between rounded border p-3\">\n <div className=\"flex items-center gap-3\">\n <div>\n <p className=\"text-sm font-medium\">{leave.employeeName}</p>\n <div className=\"flex items-center gap-2 text-xs text-text-secondary\">\n <Calendar className=\"h-3 w-3\" />\n <span>\n {leave.startDate} - {leave.endDate}\n </span>\n </div>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Badge\n variant={\n leave.status === 'approved'\n ? 'default'\n : leave.status === 'pending'\n ? 'secondary'\n : 'destructive'\n }\n >\n {leave.status}\n </Badge>\n <Badge variant=\"outline\">{leave.type}</Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DashboardDashboardPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/DashboardDashboardPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n AuroraBackground,\n EmphasisPanel,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Activity,\n ArrowUpRight,\n Briefcase,\n Calendar,\n Clock,\n TrendingUp,\n Users,\n UserCheck,\n} from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function DashboardDashboardPagePage() {\n const { t: translate } = useI18n();\n const navigate = useNavigate();\n const { employees, jobPostings, leaveRequests, notifications, projects } = useCrewFoundryStore();\n const [selectedPeriod, setSelectedPeriod] = useState<'week' | 'month' | 'quarter'>('month');\n const t = (key: string, fallback: string) => {\n const value = translate(key);\n return value === key ? fallback : value;\n };\n\n const activeEmployees = employees.filter((e) => e.status === 'active').length;\n const onLeave = employees.filter((e) => e.status === 'on_leave').length;\n const openPositions = jobPostings.filter((j) => j.status === 'active').length;\n const totalApplicants = jobPostings.reduce((sum, j) => sum + j.applicants, 0);\n const pendingLeaves = leaveRequests.filter((l) => l.status === 'pending').length;\n const unreadNotifications = notifications.filter((n) => !n.read).length;\n const activeProjects = projects.filter((p) => p.status === 'active').length;\n const avgPerformance = (\n employees.reduce((sum, e) => sum + e.performanceScore, 0) / employees.length\n ).toFixed(1);\n\n const departmentHeadcount = employees.reduce<Record<string, number>>((acc, e) => {\n acc[e.department] = (acc[e.department] || 0) + 1;\n return acc;\n }, {});\n\n const maxHeadcount = Math.max(...Object.values(departmentHeadcount));\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"relative overflow-hidden rounded-xl border border-border-seam bg-gloss-card p-6\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{t('crewfoundry.dashboard.title', 'Workforce Dashboard')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {t(\n 'crewfoundry.dashboard.subtitle',\n \"Overview of your organization's workforce metrics\"\n )}\n </p>\n <PagePurpose className=\"mt-2\">\n {t(\n 'crewfoundry.dashboard.purpose',\n 'Your workforce command center — see headcount, hiring, performance, and projects at a glance, then jump straight to the area that needs your attention.'\n )}\n </PagePurpose>\n </div>\n <div className=\"flex gap-2\">\n {(['week', 'month', 'quarter'] as const).map((period) => (\n <Button\n key={period}\n variant={selectedPeriod === period ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedPeriod(period)}\n >\n {t(\n `crewfoundry.dashboard.period.${period}`,\n period.charAt(0).toUpperCase() + period.slice(1)\n )}\n </Button>\n ))}\n </div>\n </div>\n </div>\n\n <NextSteps\n storageKey=\"crewfoundry-dashboard\"\n steps={[\n {\n id: 'employees',\n label: t('crewfoundry.dashboard.next.employees', 'Review your team'),\n description: t(\n 'crewfoundry.dashboard.next.employeesDesc',\n 'Open the employee directory to see who is active and on leave.'\n ),\n icon: <Users className=\"h-4 w-4\" />,\n onClick: () => navigate('../../hr/employees-page'),\n },\n {\n id: 'hiring',\n label: t('crewfoundry.dashboard.next.hiring', 'Post a new job'),\n description: t(\n 'crewfoundry.dashboard.next.hiringDesc',\n 'Create an opening to start collecting applicants.'\n ),\n icon: <Briefcase className=\"h-4 w-4\" />,\n onClick: () => navigate('../../hiring/create-job-page'),\n },\n {\n id: 'projects',\n label: t('crewfoundry.dashboard.next.projects', 'Check active projects'),\n description: t(\n 'crewfoundry.dashboard.next.projectsDesc',\n 'Track progress and budgets across in-flight work.'\n ),\n icon: <Activity className=\"h-4 w-4\" />,\n onClick: () => navigate('../../projects/projects-page'),\n },\n ]}\n />\n\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {t('crewfoundry.dashboard.stats.totalEmployees', 'Total Employees')}\n </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 <p className=\"text-xs text-text-secondary\">\n {activeEmployees} {t('crewfoundry.dashboard.stats.active', 'active')}, {onLeave}{' '}\n {t('crewfoundry.dashboard.stats.onLeave', 'on leave')}\n </p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {t('crewfoundry.dashboard.stats.openPositions', 'Open Positions')}\n </CardTitle>\n <Briefcase className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{openPositions}</div>\n <p className=\"text-xs text-text-secondary\">\n {totalApplicants}{' '}\n {t('crewfoundry.dashboard.stats.totalApplicants', 'total applicants')}\n </p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {t('crewfoundry.dashboard.stats.avgPerformance', 'Avg Performance')}\n </CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{avgPerformance}/5</div>\n <p className=\"text-xs text-text-secondary\">\n {t('crewfoundry.dashboard.stats.performanceTrend', '+0.2 from last quarter')}\n </p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {t('crewfoundry.dashboard.stats.activeProjects', 'Active Projects')}\n </CardTitle>\n <Activity className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{activeProjects}</div>\n <p className=\"text-xs text-text-secondary\">\n {pendingLeaves}{' '}\n {t('crewfoundry.dashboard.stats.pendingLeaveRequests', 'pending leave requests')}\n </p>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-7\">\n <EmphasisPanel className=\"col-span-4\">\n <div className=\"mb-1 text-lg font-semibold\">\n {t('crewfoundry.dashboard.departmentHeadcount.title', 'Department Headcount')}\n </div>\n <p className=\"mb-4 text-sm text-text-secondary\">\n {t(\n 'crewfoundry.dashboard.departmentHeadcount.description',\n 'Employee distribution across departments'\n )}\n </p>\n <div className=\"space-y-3\">\n {Object.entries(departmentHeadcount)\n .sort(([, a], [, b]) => b - a)\n .map(([dept, count]) => (\n <div key={dept} className=\"flex items-center gap-3\">\n <span className=\"w-24 text-sm text-text-secondary truncate\">{dept}</span>\n <div className=\"flex-1 h-4 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-4 bg-action-primary-bg rounded\"\n style={{ width: `${Math.round((count / maxHeadcount) * 100)}%` }}\n />\n </div>\n <span className=\"text-sm font-medium w-8 text-right tabular-nums\">{count}</span>\n </div>\n ))}\n </div>\n </EmphasisPanel>\n\n <Card className=\"col-span-3\">\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <CardTitle>\n {t('crewfoundry.dashboard.notifications.title', 'Recent Notifications')}\n </CardTitle>\n <Badge variant=\"secondary\">\n {unreadNotifications} {t('crewfoundry.dashboard.notifications.unread', 'unread')}\n </Badge>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {notifications.slice(0, 5).map((notif) => (\n <div key={notif.id} className=\"flex items-start gap-3\">\n <div\n className={`mt-1 h-2 w-2 rounded-full flex-shrink-0 motion-safe:animate-vc-glow-pulse ${\n notif.type === 'success'\n ? 'bg-status-success-text'\n : notif.type === 'warning'\n ? 'bg-status-warning-text'\n : notif.type === 'error'\n ? 'bg-status-error-text'\n : 'bg-status-info-text'\n }`}\n />\n <div className=\"flex-1 min-w-0\">\n <p className={`text-sm ${notif.read ? 'text-text-secondary' : 'font-medium'}`}>\n {notif.title}\n </p>\n <p className=\"text-xs text-text-secondary truncate\">{notif.message}</p>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>\n {t('crewfoundry.dashboard.upcomingInterviews.title', 'Upcoming Interviews')}\n </CardTitle>\n <CardDescription>\n {t('crewfoundry.dashboard.upcomingInterviews.description', 'Scheduled for this week')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {projects\n .filter((p) => p.status === 'active')\n .slice(0, 4)\n .map((project) => (\n <div\n key={project.id}\n className=\"flex items-center justify-between rounded border p-3\"\n >\n <div>\n <p className=\"text-sm font-medium\">{project.name}</p>\n <p className=\"text-xs text-text-secondary\">{project.teamName}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"w-24 h-2 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-2 bg-action-primary-bg rounded\"\n style={{ width: `${project.progress}%` }}\n />\n </div>\n <span className=\"text-xs text-text-secondary\">{project.progress}%</span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>\n {t('crewfoundry.dashboard.leaveRequests.title', 'Recent Leave Requests')}\n </CardTitle>\n <CardDescription>\n {t('crewfoundry.dashboard.leaveRequests.description', 'Pending approval')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {leaveRequests.length === 0 && (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('crewfoundry.dashboard.leaveRequests.emptyTitle', 'No leave requests')}\n description={t(\n 'crewfoundry.dashboard.leaveRequests.emptyDescription',\n 'Pending leave requests will appear here.'\n )}\n />\n )}\n {leaveRequests.map((leave) => (\n <div key={leave.id} className=\"flex items-center justify-between rounded border p-3\">\n <div className=\"flex items-center gap-3\">\n <div>\n <p className=\"text-sm font-medium\">{leave.employeeName}</p>\n <div className=\"flex items-center gap-2 text-xs text-text-secondary\">\n <Calendar className=\"h-3 w-3\" />\n <span>\n {leave.startDate} - {leave.endDate}\n </span>\n </div>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Badge\n variant={\n leave.status === 'approved'\n ? 'default'\n : leave.status === 'pending'\n ? 'secondary'\n : 'destructive'\n }\n >\n {leave.status}\n </Badge>\n <Badge variant=\"outline\">{leave.type}</Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|