@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
|
@@ -2,11 +2,11 @@ import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
|
2
2
|
import { useMemo as t } from "react";
|
|
3
3
|
import { ArrowUp as n, DollarSign as r, FileText as i, Receipt as a, TrendingUp as o, Wallet 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,
|
|
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 _, PagePurpose as v, Separator as y } from "@burdenoff/fe-libs/ui";
|
|
6
6
|
//#region src/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.tsx
|
|
7
|
-
function
|
|
8
|
-
let { employees:
|
|
9
|
-
let e =
|
|
7
|
+
function b() {
|
|
8
|
+
let { employees: b, departments: x, payrollRecords: S, invoices: C, projects: w } = e(), T = t(() => {
|
|
9
|
+
let e = S.reduce((e, t) => {
|
|
10
10
|
let n = new Date(t.payDate).toLocaleString("en-US", { month: "short" }), r = e[n] || {
|
|
11
11
|
gross: 0,
|
|
12
12
|
net: 0,
|
|
@@ -18,38 +18,38 @@ function _() {
|
|
|
18
18
|
month: e,
|
|
19
19
|
...t
|
|
20
20
|
})).slice(-6);
|
|
21
|
-
}, [
|
|
21
|
+
}, [S]), E = t(() => [
|
|
22
22
|
{
|
|
23
23
|
category: "Payroll",
|
|
24
|
-
amount:
|
|
25
|
-
budget:
|
|
24
|
+
amount: S.reduce((e, t) => e + t.grossPay, 0),
|
|
25
|
+
budget: x.reduce((e, t) => e + t.budget * .7, 0),
|
|
26
26
|
icon: s
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
29
|
category: "Benefits",
|
|
30
|
-
amount:
|
|
31
|
-
budget:
|
|
30
|
+
amount: S.reduce((e, t) => e + t.deductions * .4, 0),
|
|
31
|
+
budget: x.reduce((e, t) => e + t.budget * .15, 0),
|
|
32
32
|
icon: a
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
category: "Recruitment",
|
|
36
|
-
amount:
|
|
37
|
-
budget:
|
|
36
|
+
amount: C.reduce((e, t) => e + (t.status === "paid" ? t.amount * .15 : 0), 0),
|
|
37
|
+
budget: x.reduce((e, t) => e + t.budget * .1, 0),
|
|
38
38
|
icon: i
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
category: "Training",
|
|
42
|
-
amount:
|
|
43
|
-
budget:
|
|
42
|
+
amount: w.reduce((e, t) => e + t.spent * .08, 0),
|
|
43
|
+
budget: x.reduce((e, t) => e + t.budget * .08, 0),
|
|
44
44
|
icon: o
|
|
45
45
|
}
|
|
46
46
|
], [
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
]),
|
|
52
|
-
let t =
|
|
47
|
+
x,
|
|
48
|
+
C,
|
|
49
|
+
S,
|
|
50
|
+
w
|
|
51
|
+
]), D = b.reduce((e, t) => e + t.salary, 0), O = Math.round(D / 12), k = C.reduce((e, t) => e + t.amount, 0), A = C.filter((e) => e.status === "paid").reduce((e, t) => e + t.amount, 0), j = w.reduce((e, t) => e + t.budget, 0), M = w.reduce((e, t) => e + t.spent, 0), N = Math.max(1, ...T.map((e) => e.gross)), P = x.map((e) => {
|
|
52
|
+
let t = b.filter((t) => t.department === e.name), n = t.reduce((e, t) => e + t.salary, 0);
|
|
53
53
|
return {
|
|
54
54
|
name: e.name,
|
|
55
55
|
salary: n,
|
|
@@ -62,94 +62,118 @@ function _() {
|
|
|
62
62
|
children: [
|
|
63
63
|
/* @__PURE__ */ c("div", {
|
|
64
64
|
className: "flex items-center justify-between",
|
|
65
|
-
children: /* @__PURE__ */ l("div", { children: [
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
children: /* @__PURE__ */ l("div", { children: [
|
|
66
|
+
/* @__PURE__ */ c("h1", {
|
|
67
|
+
className: "text-2xl font-semibold",
|
|
68
|
+
children: /* @__PURE__ */ c(_, { children: "Financial Analytics" })
|
|
69
|
+
}),
|
|
70
|
+
/* @__PURE__ */ c("p", {
|
|
71
|
+
className: "text-sm text-text-secondary",
|
|
72
|
+
children: "Workforce financial metrics and cost analysis"
|
|
73
|
+
}),
|
|
74
|
+
/* @__PURE__ */ c(v, {
|
|
75
|
+
className: "mt-1",
|
|
76
|
+
children: "Understand the money side of your workforce — payroll, project budgets, and spend trends — so you can plan headcount and control costs with confidence."
|
|
77
|
+
})
|
|
78
|
+
] })
|
|
72
79
|
}),
|
|
73
80
|
/* @__PURE__ */ l("div", {
|
|
74
81
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
|
|
75
82
|
children: [
|
|
76
|
-
/* @__PURE__ */ l(
|
|
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: [
|
|
102
|
-
"
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
83
|
+
/* @__PURE__ */ l(g, {
|
|
84
|
+
treatment: "glass",
|
|
85
|
+
glow: !0,
|
|
86
|
+
className: "border-border-seam",
|
|
87
|
+
children: [/* @__PURE__ */ l(m, {
|
|
88
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
89
|
+
children: [/* @__PURE__ */ c(h, {
|
|
90
|
+
className: "text-sm font-medium",
|
|
91
|
+
children: "Monthly Payroll"
|
|
92
|
+
}), /* @__PURE__ */ c(r, { className: "h-4 w-4 text-text-secondary" })]
|
|
93
|
+
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
|
|
94
|
+
className: "text-2xl font-bold tabular-nums",
|
|
95
|
+
children: [
|
|
96
|
+
"$",
|
|
97
|
+
(O / 1e3).toFixed(0),
|
|
98
|
+
"K"
|
|
99
|
+
]
|
|
100
|
+
}), /* @__PURE__ */ l("div", {
|
|
101
|
+
className: "flex items-center text-xs text-status-warning-text",
|
|
102
|
+
children: [/* @__PURE__ */ c(n, { className: "h-3 w-3 mr-1" }), "+2.1% from last month"]
|
|
103
|
+
})] })]
|
|
104
|
+
}),
|
|
105
|
+
/* @__PURE__ */ l(g, {
|
|
106
|
+
treatment: "metric",
|
|
107
|
+
className: "border-border-seam",
|
|
108
|
+
children: [/* @__PURE__ */ l(m, {
|
|
109
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
110
|
+
children: [/* @__PURE__ */ c(h, {
|
|
111
|
+
className: "text-sm font-medium",
|
|
112
|
+
children: "Annual Salary Cost"
|
|
113
|
+
}), /* @__PURE__ */ c(s, { className: "h-4 w-4 text-text-secondary" })]
|
|
114
|
+
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
|
|
115
|
+
className: "text-2xl font-bold tabular-nums",
|
|
116
|
+
children: [
|
|
117
|
+
"$",
|
|
118
|
+
(D / 1e6).toFixed(1),
|
|
119
|
+
"M"
|
|
120
|
+
]
|
|
121
|
+
}), /* @__PURE__ */ l("p", {
|
|
122
|
+
className: "text-xs text-text-secondary",
|
|
123
|
+
children: [b.length, " employees"]
|
|
124
|
+
})] })]
|
|
125
|
+
}),
|
|
126
|
+
/* @__PURE__ */ l(g, {
|
|
127
|
+
treatment: "metric",
|
|
128
|
+
className: "border-border-seam",
|
|
129
|
+
children: [/* @__PURE__ */ l(m, {
|
|
130
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
131
|
+
children: [/* @__PURE__ */ c(h, {
|
|
132
|
+
className: "text-sm font-medium",
|
|
133
|
+
children: "Total Invoiced"
|
|
134
|
+
}), /* @__PURE__ */ c(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
135
|
+
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
|
|
136
|
+
className: "text-2xl font-bold tabular-nums",
|
|
137
|
+
children: [
|
|
138
|
+
"$",
|
|
139
|
+
(k / 1e3).toFixed(1),
|
|
140
|
+
"K"
|
|
141
|
+
]
|
|
142
|
+
}), /* @__PURE__ */ l("p", {
|
|
143
|
+
className: "text-xs text-text-secondary",
|
|
144
|
+
children: [
|
|
145
|
+
"$",
|
|
146
|
+
(A / 1e3).toFixed(1),
|
|
147
|
+
"K collected"
|
|
148
|
+
]
|
|
149
|
+
})] })]
|
|
150
|
+
}),
|
|
151
|
+
/* @__PURE__ */ l(g, {
|
|
152
|
+
treatment: "metric",
|
|
153
|
+
className: "border-border-seam",
|
|
154
|
+
children: [/* @__PURE__ */ l(m, {
|
|
155
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
156
|
+
children: [/* @__PURE__ */ c(h, {
|
|
157
|
+
className: "text-sm font-medium",
|
|
158
|
+
children: "Project Budget"
|
|
159
|
+
}), /* @__PURE__ */ c(o, { className: "h-4 w-4 text-text-secondary" })]
|
|
160
|
+
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
|
|
161
|
+
className: "text-2xl font-bold tabular-nums",
|
|
162
|
+
children: [
|
|
163
|
+
"$",
|
|
164
|
+
(j / 1e6).toFixed(1),
|
|
165
|
+
"M"
|
|
166
|
+
]
|
|
167
|
+
}), /* @__PURE__ */ l("p", {
|
|
168
|
+
className: "text-xs text-text-secondary",
|
|
169
|
+
children: [Math.round(M / j * 100), "% utilized"]
|
|
170
|
+
})] })]
|
|
171
|
+
})
|
|
148
172
|
]
|
|
149
173
|
}),
|
|
150
174
|
/* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Payroll Trend" }), /* @__PURE__ */ c(p, { children: "Monthly gross payroll over the last 6 months" })] }), /* @__PURE__ */ l(f, {
|
|
151
175
|
className: "space-y-3",
|
|
152
|
-
children: [
|
|
176
|
+
children: [T.map((e) => /* @__PURE__ */ l("div", {
|
|
153
177
|
className: "flex items-center gap-3",
|
|
154
178
|
children: [
|
|
155
179
|
/* @__PURE__ */ c("span", {
|
|
@@ -160,10 +184,10 @@ function _() {
|
|
|
160
184
|
className: "flex-1 h-5 bg-bg-sunken rounded overflow-hidden flex",
|
|
161
185
|
children: [/* @__PURE__ */ c("div", {
|
|
162
186
|
className: "h-5 bg-action-primary-bg",
|
|
163
|
-
style: { width: `${Math.round(e.net /
|
|
187
|
+
style: { width: `${Math.round(e.net / N * 100)}%` }
|
|
164
188
|
}), /* @__PURE__ */ c("div", {
|
|
165
189
|
className: "h-5 bg-action-primary-bg/30",
|
|
166
|
-
style: { width: `${Math.round(e.deductions /
|
|
190
|
+
style: { width: `${Math.round(e.deductions / N * 100)}%` }
|
|
167
191
|
})]
|
|
168
192
|
}),
|
|
169
193
|
/* @__PURE__ */ l("span", {
|
|
@@ -190,7 +214,7 @@ function _() {
|
|
|
190
214
|
className: "grid gap-4 md:grid-cols-2",
|
|
191
215
|
children: [/* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Budget vs Actual" }), /* @__PURE__ */ c(p, { children: "Monthly expense tracking by category" })] }), /* @__PURE__ */ c(f, {
|
|
192
216
|
className: "space-y-4",
|
|
193
|
-
children:
|
|
217
|
+
children: E.map((e) => {
|
|
194
218
|
let t = Math.round(e.amount / e.budget * 100);
|
|
195
219
|
return /* @__PURE__ */ l("div", {
|
|
196
220
|
className: "space-y-1",
|
|
@@ -211,7 +235,7 @@ function _() {
|
|
|
211
235
|
/* @__PURE__ */ c("div", {
|
|
212
236
|
className: "h-3 bg-bg-sunken rounded overflow-hidden",
|
|
213
237
|
children: /* @__PURE__ */ c("div", {
|
|
214
|
-
className: `h-3 rounded ${t > 95 ? "bg-
|
|
238
|
+
className: `h-3 rounded ${t > 95 ? "bg-status-error-text" : t > 80 ? "bg-status-warning-text" : "bg-status-success-text"}`,
|
|
215
239
|
style: { width: `${t}%` }
|
|
216
240
|
})
|
|
217
241
|
}),
|
|
@@ -224,7 +248,7 @@ function _() {
|
|
|
224
248
|
})
|
|
225
249
|
})] }), /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Outstanding Invoices" }), /* @__PURE__ */ c(p, { children: "Invoices requiring attention" })] }), /* @__PURE__ */ c(f, {
|
|
226
250
|
className: "space-y-3",
|
|
227
|
-
children:
|
|
251
|
+
children: C.map((e) => /* @__PURE__ */ l("div", {
|
|
228
252
|
className: "flex items-center justify-between rounded border p-3",
|
|
229
253
|
children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
|
|
230
254
|
className: "text-sm font-medium",
|
|
@@ -269,7 +293,7 @@ function _() {
|
|
|
269
293
|
})
|
|
270
294
|
]
|
|
271
295
|
}),
|
|
272
|
-
|
|
296
|
+
P.sort((e, t) => t.salary - e.salary).map((e) => /* @__PURE__ */ l("div", {
|
|
273
297
|
className: "grid grid-cols-5 gap-2 py-2 border-b last:border-0 text-sm",
|
|
274
298
|
children: [
|
|
275
299
|
/* @__PURE__ */ c("span", {
|
|
@@ -306,20 +330,20 @@ function _() {
|
|
|
306
330
|
})
|
|
307
331
|
]
|
|
308
332
|
}, e.name)),
|
|
309
|
-
/* @__PURE__ */ c(
|
|
333
|
+
/* @__PURE__ */ c(y, { className: "my-2" }),
|
|
310
334
|
/* @__PURE__ */ l("div", {
|
|
311
335
|
className: "grid grid-cols-5 gap-2 text-sm font-bold",
|
|
312
336
|
children: [
|
|
313
337
|
/* @__PURE__ */ c("span", { children: "Total" }),
|
|
314
338
|
/* @__PURE__ */ c("span", {
|
|
315
339
|
className: "text-right",
|
|
316
|
-
children:
|
|
340
|
+
children: b.length
|
|
317
341
|
}),
|
|
318
342
|
/* @__PURE__ */ l("span", {
|
|
319
343
|
className: "text-right",
|
|
320
344
|
children: [
|
|
321
345
|
"$",
|
|
322
|
-
(
|
|
346
|
+
(D / 1e6).toFixed(1),
|
|
323
347
|
"M"
|
|
324
348
|
]
|
|
325
349
|
}),
|
|
@@ -327,7 +351,7 @@ function _() {
|
|
|
327
351
|
className: "text-right",
|
|
328
352
|
children: [
|
|
329
353
|
"$",
|
|
330
|
-
(
|
|
354
|
+
(x.reduce((e, t) => e + t.budget, 0) / 1e6).toFixed(1),
|
|
331
355
|
"M"
|
|
332
356
|
]
|
|
333
357
|
}),
|
|
@@ -339,6 +363,6 @@ function _() {
|
|
|
339
363
|
});
|
|
340
364
|
}
|
|
341
365
|
//#endregion
|
|
342
|
-
export {
|
|
366
|
+
export { b as AnalyticsFinancialAnalyticsPagePage };
|
|
343
367
|
|
|
344
368
|
//# sourceMappingURL=AnalyticsFinancialAnalyticsPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyticsFinancialAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowUp, DollarSign, FileText, Receipt, TrendingUp, Wallet } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function AnalyticsFinancialAnalyticsPagePage() {\n const { employees, departments, payrollRecords, invoices, projects } = useCrewFoundryStore();\n\n const monthlyPayrollTrend = useMemo(() => {\n const byPeriod = payrollRecords.reduce<\n Record<string, { gross: number; net: number; deductions: number }>\n >((acc, record) => {\n const month = new Date(record.payDate).toLocaleString('en-US', { month: 'short' });\n const current = acc[month] || { gross: 0, net: 0, deductions: 0 };\n current.gross += record.grossPay;\n current.net += record.netPay;\n current.deductions += record.deductions;\n acc[month] = current;\n return acc;\n }, {});\n return Object.entries(byPeriod)\n .map(([month, value]) => ({ month, ...value }))\n .slice(-6);\n }, [payrollRecords]);\n\n const expenseCategories = useMemo(\n () => [\n {\n category: 'Payroll',\n amount: payrollRecords.reduce((sum, record) => sum + record.grossPay, 0),\n budget: departments.reduce((sum, department) => sum + department.budget * 0.7, 0),\n icon: Wallet,\n },\n {\n category: 'Benefits',\n amount: payrollRecords.reduce((sum, record) => sum + record.deductions * 0.4, 0),\n budget: departments.reduce((sum, department) => sum + department.budget * 0.15, 0),\n icon: Receipt,\n },\n {\n category: 'Recruitment',\n amount: invoices.reduce(\n (sum, invoice) => sum + (invoice.status === 'paid' ? invoice.amount * 0.15 : 0),\n 0\n ),\n budget: departments.reduce((sum, department) => sum + department.budget * 0.1, 0),\n icon: FileText,\n },\n {\n category: 'Training',\n amount: projects.reduce((sum, project) => sum + project.spent * 0.08, 0),\n budget: departments.reduce((sum, department) => sum + department.budget * 0.08, 0),\n icon: TrendingUp,\n },\n ],\n [departments, invoices, payrollRecords, projects]\n );\n\n const totalPayroll = employees.reduce((sum, e) => sum + e.salary, 0);\n const monthlyPayroll = Math.round(totalPayroll / 12);\n const totalInvoiced = invoices.reduce((sum, inv) => sum + inv.amount, 0);\n const paidInvoices = invoices\n .filter((i) => i.status === 'paid')\n .reduce((s, i) => s + i.amount, 0);\n const totalProjectBudget = projects.reduce((s, p) => s + p.budget, 0);\n const totalProjectSpent = projects.reduce((s, p) => s + p.spent, 0);\n\n const maxPayroll = Math.max(1, ...monthlyPayrollTrend.map((m) => m.gross));\n\n const deptCost = departments.map((d) => {\n const deptEmps = employees.filter((e) => e.department === d.name);\n const totalSal = deptEmps.reduce((s, e) => s + e.salary, 0);\n return { name: d.name, salary: totalSal, budget: d.budget, headcount: deptEmps.length };\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\">Financial Analytics</h1>\n <p className=\"text-sm text-text-secondary\">\n Workforce financial metrics and cost analysis\n </p>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Monthly Payroll</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${(monthlyPayroll / 1000).toFixed(0)}K</div>\n <div className=\"flex items-center text-xs text-yellow-600\">\n <ArrowUp className=\"h-3 w-3 mr-1\" />\n +2.1% from last month\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\">Annual Salary Cost</CardTitle>\n <Wallet className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${(totalPayroll / 1000000).toFixed(1)}M</div>\n <p className=\"text-xs text-text-secondary\">{employees.length} employees</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\">Total Invoiced</CardTitle>\n <FileText className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${(totalInvoiced / 1000).toFixed(1)}K</div>\n <p className=\"text-xs text-text-secondary\">\n ${(paidInvoices / 1000).toFixed(1)}K collected\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\">Project Budget</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${(totalProjectBudget / 1000000).toFixed(1)}M</div>\n <p className=\"text-xs text-text-secondary\">\n {Math.round((totalProjectSpent / totalProjectBudget) * 100)}% utilized\n </p>\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Payroll Trend</CardTitle>\n <CardDescription>Monthly gross payroll over the last 6 months</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {monthlyPayrollTrend.map((m) => (\n <div key={m.month} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-sm text-text-secondary\">{m.month}</span>\n <div className=\"flex-1 h-5 bg-bg-sunken rounded overflow-hidden flex\">\n <div\n className=\"h-5 bg-action-primary-bg\"\n style={{ width: `${Math.round((m.net / maxPayroll) * 100)}%` }}\n />\n <div\n className=\"h-5 bg-action-primary-bg/30\"\n style={{ width: `${Math.round((m.deductions / maxPayroll) * 100)}%` }}\n />\n </div>\n <span className=\"text-sm font-medium w-20 text-right\">\n ${(m.gross / 1000000).toFixed(2)}M\n </span>\n </div>\n ))}\n <div className=\"flex items-center gap-4 mt-2 text-xs text-text-secondary\">\n <div className=\"flex items-center gap-1\">\n <div className=\"h-3 w-3 bg-action-primary-bg rounded\" />\n <span>Net Pay</span>\n </div>\n <div className=\"flex items-center gap-1\">\n <div className=\"h-3 w-3 bg-action-primary-bg/30 rounded\" />\n <span>Deductions</span>\n </div>\n </div>\n </CardContent>\n </Card>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>Budget vs Actual</CardTitle>\n <CardDescription>Monthly expense tracking by category</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {expenseCategories.map((cat) => {\n const pct = Math.round((cat.amount / cat.budget) * 100);\n return (\n <div key={cat.category} className=\"space-y-1\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"font-medium\">{cat.category}</span>\n <span>\n ${(cat.amount / 1000).toFixed(0)}K / ${(cat.budget / 1000).toFixed(0)}K\n </span>\n </div>\n <div className=\"h-3 bg-bg-sunken rounded overflow-hidden\">\n <div\n className={`h-3 rounded ${pct > 95 ? 'bg-red-500' : pct > 80 ? 'bg-yellow-500' : 'bg-green-500'}`}\n style={{ width: `${pct}%` }}\n />\n </div>\n <p className=\"text-xs text-text-secondary text-right\">{pct}% utilized</p>\n </div>\n );\n })}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Outstanding Invoices</CardTitle>\n <CardDescription>Invoices requiring attention</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {invoices.map((inv) => (\n <div key={inv.id} className=\"flex items-center justify-between rounded border p-3\">\n <div>\n <p className=\"text-sm font-medium\">{inv.number}</p>\n <p className=\"text-xs text-text-secondary\">{inv.clientName}</p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm font-medium\">${inv.amount.toLocaleString()}</p>\n <Badge\n variant={\n inv.status === 'paid'\n ? 'default'\n : inv.status === 'overdue'\n ? 'destructive'\n : 'secondary'\n }\n className=\"text-[10px]\"\n >\n {inv.status}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Department Cost Analysis</CardTitle>\n <CardDescription>Total salary cost and budget allocation by department</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-5 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Department</span>\n <span className=\"text-right\">Headcount</span>\n <span className=\"text-right\">Total Salary</span>\n <span className=\"text-right\">Dept Budget</span>\n <span className=\"text-right\">Salary/Budget %</span>\n </div>\n {deptCost\n .sort((a, b) => b.salary - a.salary)\n .map((d) => (\n <div\n key={d.name}\n className=\"grid grid-cols-5 gap-2 py-2 border-b last:border-0 text-sm\"\n >\n <span className=\"font-medium\">{d.name}</span>\n <span className=\"text-right\">{d.headcount}</span>\n <span className=\"text-right\">${(d.salary / 1000).toFixed(0)}K</span>\n <span className=\"text-right\">${(d.budget / 1000000).toFixed(1)}M</span>\n <span className=\"text-right\">\n <Badge\n variant={d.salary / d.budget > 0.5 ? 'destructive' : 'default'}\n className=\"text-[10px]\"\n >\n {Math.round((d.salary / d.budget) * 100)}%\n </Badge>\n </span>\n </div>\n ))}\n <Separator className=\"my-2\" />\n <div className=\"grid grid-cols-5 gap-2 text-sm font-bold\">\n <span>Total</span>\n <span className=\"text-right\">{employees.length}</span>\n <span className=\"text-right\">${(totalPayroll / 1000000).toFixed(1)}M</span>\n <span className=\"text-right\">\n ${(departments.reduce((s, d) => s + d.budget, 0) / 1000000).toFixed(1)}M\n </span>\n <span />\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AnalyticsFinancialAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowUp, DollarSign, FileText, Receipt, TrendingUp, Wallet } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function AnalyticsFinancialAnalyticsPagePage() {\n const { employees, departments, payrollRecords, invoices, projects } = useCrewFoundryStore();\n\n const monthlyPayrollTrend = useMemo(() => {\n const byPeriod = payrollRecords.reduce<\n Record<string, { gross: number; net: number; deductions: number }>\n >((acc, record) => {\n const month = new Date(record.payDate).toLocaleString('en-US', { month: 'short' });\n const current = acc[month] || { gross: 0, net: 0, deductions: 0 };\n current.gross += record.grossPay;\n current.net += record.netPay;\n current.deductions += record.deductions;\n acc[month] = current;\n return acc;\n }, {});\n return Object.entries(byPeriod)\n .map(([month, value]) => ({ month, ...value }))\n .slice(-6);\n }, [payrollRecords]);\n\n const expenseCategories = useMemo(\n () => [\n {\n category: 'Payroll',\n amount: payrollRecords.reduce((sum, record) => sum + record.grossPay, 0),\n budget: departments.reduce((sum, department) => sum + department.budget * 0.7, 0),\n icon: Wallet,\n },\n {\n category: 'Benefits',\n amount: payrollRecords.reduce((sum, record) => sum + record.deductions * 0.4, 0),\n budget: departments.reduce((sum, department) => sum + department.budget * 0.15, 0),\n icon: Receipt,\n },\n {\n category: 'Recruitment',\n amount: invoices.reduce(\n (sum, invoice) => sum + (invoice.status === 'paid' ? invoice.amount * 0.15 : 0),\n 0\n ),\n budget: departments.reduce((sum, department) => sum + department.budget * 0.1, 0),\n icon: FileText,\n },\n {\n category: 'Training',\n amount: projects.reduce((sum, project) => sum + project.spent * 0.08, 0),\n budget: departments.reduce((sum, department) => sum + department.budget * 0.08, 0),\n icon: TrendingUp,\n },\n ],\n [departments, invoices, payrollRecords, projects]\n );\n\n const totalPayroll = employees.reduce((sum, e) => sum + e.salary, 0);\n const monthlyPayroll = Math.round(totalPayroll / 12);\n const totalInvoiced = invoices.reduce((sum, inv) => sum + inv.amount, 0);\n const paidInvoices = invoices\n .filter((i) => i.status === 'paid')\n .reduce((s, i) => s + i.amount, 0);\n const totalProjectBudget = projects.reduce((s, p) => s + p.budget, 0);\n const totalProjectSpent = projects.reduce((s, p) => s + p.spent, 0);\n\n const maxPayroll = Math.max(1, ...monthlyPayrollTrend.map((m) => m.gross));\n\n const deptCost = departments.map((d) => {\n const deptEmps = employees.filter((e) => e.department === d.name);\n const totalSal = deptEmps.reduce((s, e) => s + e.salary, 0);\n return { name: d.name, salary: totalSal, budget: d.budget, headcount: deptEmps.length };\n });\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Financial Analytics</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Workforce financial metrics and cost analysis\n </p>\n <PagePurpose className=\"mt-1\">Understand the money side of your workforce — payroll, project budgets, and spend trends — so you can plan headcount and control costs with confidence.</PagePurpose>\n </div>\n </div>\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\">Monthly Payroll</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(monthlyPayroll / 1000).toFixed(0)}K\n </div>\n <div className=\"flex items-center text-xs text-status-warning-text\">\n <ArrowUp className=\"h-3 w-3 mr-1\" />\n +2.1% from last month\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\">Annual Salary Cost</CardTitle>\n <Wallet className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalPayroll / 1000000).toFixed(1)}M\n </div>\n <p className=\"text-xs text-text-secondary\">{employees.length} employees</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\">Total Invoiced</CardTitle>\n <FileText className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalInvoiced / 1000).toFixed(1)}K\n </div>\n <p className=\"text-xs text-text-secondary\">\n ${(paidInvoices / 1000).toFixed(1)}K collected\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\">Project Budget</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalProjectBudget / 1000000).toFixed(1)}M\n </div>\n <p className=\"text-xs text-text-secondary\">\n {Math.round((totalProjectSpent / totalProjectBudget) * 100)}% utilized\n </p>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Payroll Trend</CardTitle>\n <CardDescription>Monthly gross payroll over the last 6 months</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {monthlyPayrollTrend.map((m) => (\n <div key={m.month} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-sm text-text-secondary\">{m.month}</span>\n <div className=\"flex-1 h-5 bg-bg-sunken rounded overflow-hidden flex\">\n <div\n className=\"h-5 bg-action-primary-bg\"\n style={{ width: `${Math.round((m.net / maxPayroll) * 100)}%` }}\n />\n <div\n className=\"h-5 bg-action-primary-bg/30\"\n style={{ width: `${Math.round((m.deductions / maxPayroll) * 100)}%` }}\n />\n </div>\n <span className=\"text-sm font-medium w-20 text-right\">\n ${(m.gross / 1000000).toFixed(2)}M\n </span>\n </div>\n ))}\n <div className=\"flex items-center gap-4 mt-2 text-xs text-text-secondary\">\n <div className=\"flex items-center gap-1\">\n <div className=\"h-3 w-3 bg-action-primary-bg rounded\" />\n <span>Net Pay</span>\n </div>\n <div className=\"flex items-center gap-1\">\n <div className=\"h-3 w-3 bg-action-primary-bg/30 rounded\" />\n <span>Deductions</span>\n </div>\n </div>\n </CardContent>\n </Card>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>Budget vs Actual</CardTitle>\n <CardDescription>Monthly expense tracking by category</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {expenseCategories.map((cat) => {\n const pct = Math.round((cat.amount / cat.budget) * 100);\n return (\n <div key={cat.category} className=\"space-y-1\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"font-medium\">{cat.category}</span>\n <span>\n ${(cat.amount / 1000).toFixed(0)}K / ${(cat.budget / 1000).toFixed(0)}K\n </span>\n </div>\n <div className=\"h-3 bg-bg-sunken rounded overflow-hidden\">\n <div\n className={`h-3 rounded ${pct > 95 ? 'bg-status-error-text' : pct > 80 ? 'bg-status-warning-text' : 'bg-status-success-text'}`}\n style={{ width: `${pct}%` }}\n />\n </div>\n <p className=\"text-xs text-text-secondary text-right\">{pct}% utilized</p>\n </div>\n );\n })}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Outstanding Invoices</CardTitle>\n <CardDescription>Invoices requiring attention</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {invoices.map((inv) => (\n <div key={inv.id} className=\"flex items-center justify-between rounded border p-3\">\n <div>\n <p className=\"text-sm font-medium\">{inv.number}</p>\n <p className=\"text-xs text-text-secondary\">{inv.clientName}</p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm font-medium\">${inv.amount.toLocaleString()}</p>\n <Badge\n variant={\n inv.status === 'paid'\n ? 'default'\n : inv.status === 'overdue'\n ? 'destructive'\n : 'secondary'\n }\n className=\"text-[10px]\"\n >\n {inv.status}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Department Cost Analysis</CardTitle>\n <CardDescription>Total salary cost and budget allocation by department</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-5 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Department</span>\n <span className=\"text-right\">Headcount</span>\n <span className=\"text-right\">Total Salary</span>\n <span className=\"text-right\">Dept Budget</span>\n <span className=\"text-right\">Salary/Budget %</span>\n </div>\n {deptCost\n .sort((a, b) => b.salary - a.salary)\n .map((d) => (\n <div\n key={d.name}\n className=\"grid grid-cols-5 gap-2 py-2 border-b last:border-0 text-sm\"\n >\n <span className=\"font-medium\">{d.name}</span>\n <span className=\"text-right\">{d.headcount}</span>\n <span className=\"text-right\">${(d.salary / 1000).toFixed(0)}K</span>\n <span className=\"text-right\">${(d.budget / 1000000).toFixed(1)}M</span>\n <span className=\"text-right\">\n <Badge\n variant={d.salary / d.budget > 0.5 ? 'destructive' : 'default'}\n className=\"text-[10px]\"\n >\n {Math.round((d.salary / d.budget) * 100)}%\n </Badge>\n </span>\n </div>\n ))}\n <Separator className=\"my-2\" />\n <div className=\"grid grid-cols-5 gap-2 text-sm font-bold\">\n <span>Total</span>\n <span className=\"text-right\">{employees.length}</span>\n <span className=\"text-right\">${(totalPayroll / 1000000).toFixed(1)}M</span>\n <span className=\"text-right\">\n ${(departments.reduce((s, d) => s + d.budget, 0) / 1000000).toFixed(1)}M\n </span>\n <span />\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|