@burdenoff/microfe-crewfoundry 2026.703.2 → 2026.704.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/crewfoundry/pages/AdminAdminPagePage.js +117 -164
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +99 -82
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +160 -192
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +238 -231
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +196 -166
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +45 -147
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +20 -11
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +45 -152
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +50 -138
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +149 -67
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +50 -201
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +205 -136
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +25 -31
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +118 -104
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +117 -58
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +90 -94
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +210 -191
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +213 -180
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +133 -264
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +279 -212
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +131 -105
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +167 -148
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +3 -3
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +13 -5
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +151 -152
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +38 -21
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +3 -3
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +134 -127
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +163 -132
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +202 -160
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +104 -91
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +29 -147
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +22 -106
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +74 -74
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +101 -97
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +64 -47
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +111 -121
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +131 -110
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +65 -64
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +58 -43
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +66 -82
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +38 -88
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +59 -65
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +209 -323
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +175 -220
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +74 -59
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +96 -80
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +28 -100
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +27 -20
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +73 -73
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +62 -56
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +40 -138
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +126 -93
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +99 -77
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +73 -74
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +122 -122
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +130 -113
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +68 -59
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +73 -62
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +82 -58
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +153 -153
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +63 -48
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
2
|
import { FormModal as t, useFormModal as n } from "../components/forms/FormModal.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { useState as r } from "react";
|
|
4
|
+
import { Mail as i, Pencil as a, Plus as o, Search as s, Star as c, Trash2 as l } from "lucide-react";
|
|
5
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
6
|
+
import { AlertDialog as ee, AlertDialogAction as f, AlertDialogCancel as p, AlertDialogContent as m, AlertDialogDescription as h, AlertDialogFooter as g, AlertDialogHeader as _, AlertDialogTitle as v, AlertDialogTrigger as y, Badge as b, Button as x, CardContent as S, CardHeader as C, CardTitle as w, GlassCard as T, GradientText as E, IllustratedEmptyState as D, Input as O, PagePurpose as k, Pagination as A, Select as j, SelectContent as M, SelectItem as N, SelectTrigger as P, SelectValue as te } from "@burdenoff/fe-libs/ui";
|
|
7
|
+
import { usePagination as F } from "@burdenoff/fe-libs/shared/hooks";
|
|
6
8
|
//#region src/crewfoundry/pages/CompanyVendorManagementPagePage.tsx
|
|
7
|
-
var
|
|
9
|
+
var I = [
|
|
8
10
|
{
|
|
9
11
|
name: "name",
|
|
10
12
|
label: "Vendor name",
|
|
@@ -61,7 +63,7 @@ var O = [
|
|
|
61
63
|
label: "Rating (0-5)",
|
|
62
64
|
type: "number"
|
|
63
65
|
}
|
|
64
|
-
],
|
|
66
|
+
], L = (e) => ({
|
|
65
67
|
name: e.name,
|
|
66
68
|
category: e.category,
|
|
67
69
|
contactPerson: e.contactPerson,
|
|
@@ -70,7 +72,7 @@ var O = [
|
|
|
70
72
|
status: e.status,
|
|
71
73
|
contractValue: e.contractValue,
|
|
72
74
|
rating: e.rating
|
|
73
|
-
}),
|
|
75
|
+
}), R = (e, t) => ({
|
|
74
76
|
id: t?.id ?? crypto.randomUUID(),
|
|
75
77
|
name: String(e.name ?? ""),
|
|
76
78
|
category: String(e.category ?? ""),
|
|
@@ -81,119 +83,170 @@ var O = [
|
|
|
81
83
|
contractValue: typeof e.contractValue == "number" ? e.contractValue : Number(e.contractValue) || 0,
|
|
82
84
|
rating: typeof e.rating == "number" ? e.rating : Number(e.rating) || 0
|
|
83
85
|
});
|
|
84
|
-
function
|
|
85
|
-
let { vendors:
|
|
86
|
-
|
|
86
|
+
function z() {
|
|
87
|
+
let { vendors: z, addVendor: B, updateVendor: V, removeVendor: H } = e(), U = n(), [W, G] = r(""), [K, q] = r("all"), { page: J, pageSize: Y, offset: X, setPage: Z } = F({ initialPageSize: 12 }), Q = z.reduce((e, t) => e + t.contractValue, 0), $ = z.filter((e) => {
|
|
88
|
+
let t = `${e.name} ${e.category} ${e.contactPerson} ${e.email}`.toLowerCase().includes(W.toLowerCase()), n = K === "all" || e.status === K;
|
|
89
|
+
return t && n;
|
|
90
|
+
}), ne = $.slice(X, X + Y);
|
|
91
|
+
return /* @__PURE__ */ d("div", {
|
|
87
92
|
className: "space-y-6 p-6",
|
|
88
93
|
children: [
|
|
89
|
-
/* @__PURE__ */
|
|
94
|
+
/* @__PURE__ */ d("div", {
|
|
90
95
|
className: "flex items-center justify-between",
|
|
91
|
-
children: [/* @__PURE__ */
|
|
92
|
-
/* @__PURE__ */
|
|
96
|
+
children: [/* @__PURE__ */ d("div", { children: [
|
|
97
|
+
/* @__PURE__ */ u("h1", {
|
|
93
98
|
className: "text-2xl font-semibold",
|
|
94
|
-
children: /* @__PURE__ */
|
|
99
|
+
children: /* @__PURE__ */ u(E, { children: "Vendor Management" })
|
|
95
100
|
}),
|
|
96
|
-
/* @__PURE__ */
|
|
101
|
+
/* @__PURE__ */ d("p", {
|
|
97
102
|
className: "text-sm text-text-secondary",
|
|
98
103
|
children: [
|
|
99
|
-
|
|
104
|
+
z.length,
|
|
100
105
|
" vendors · $",
|
|
101
|
-
(
|
|
106
|
+
(Q / 1e3).toFixed(0),
|
|
102
107
|
"K total contract value"
|
|
103
108
|
]
|
|
104
109
|
}),
|
|
105
|
-
/* @__PURE__ */
|
|
110
|
+
/* @__PURE__ */ u(k, {
|
|
106
111
|
className: "mt-1",
|
|
107
112
|
children: "Track the vendors and suppliers you depend on — contracts, contacts, and status — to manage external relationships in one place."
|
|
108
113
|
})
|
|
109
|
-
] }), /* @__PURE__ */
|
|
114
|
+
] }), /* @__PURE__ */ d(x, {
|
|
110
115
|
size: "sm",
|
|
111
|
-
onClick: () =>
|
|
112
|
-
children: [/* @__PURE__ */
|
|
116
|
+
onClick: () => U.openModal(),
|
|
117
|
+
children: [/* @__PURE__ */ u(o, { className: "h-4 w-4 mr-1" }), "Add Vendor"]
|
|
113
118
|
})]
|
|
114
119
|
}),
|
|
115
|
-
/* @__PURE__ */
|
|
120
|
+
/* @__PURE__ */ d("div", {
|
|
121
|
+
className: "flex flex-col gap-2 sm:flex-row sm:items-center",
|
|
122
|
+
children: [/* @__PURE__ */ d("div", {
|
|
123
|
+
className: "relative flex-1",
|
|
124
|
+
children: [/* @__PURE__ */ u(s, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ u(O, {
|
|
125
|
+
placeholder: "Search vendors...",
|
|
126
|
+
className: "pl-9",
|
|
127
|
+
value: W,
|
|
128
|
+
onChange: (e) => {
|
|
129
|
+
G(e.target.value), Z(1);
|
|
130
|
+
}
|
|
131
|
+
})]
|
|
132
|
+
}), /* @__PURE__ */ d(j, {
|
|
133
|
+
value: K,
|
|
134
|
+
onValueChange: (e) => {
|
|
135
|
+
q(e), Z(1);
|
|
136
|
+
},
|
|
137
|
+
children: [/* @__PURE__ */ u(P, {
|
|
138
|
+
className: "w-full sm:w-40",
|
|
139
|
+
"aria-label": "Filter by status",
|
|
140
|
+
children: /* @__PURE__ */ u(te, {})
|
|
141
|
+
}), /* @__PURE__ */ d(M, { children: [
|
|
142
|
+
/* @__PURE__ */ u(N, {
|
|
143
|
+
value: "all",
|
|
144
|
+
children: "All statuses"
|
|
145
|
+
}),
|
|
146
|
+
/* @__PURE__ */ u(N, {
|
|
147
|
+
value: "active",
|
|
148
|
+
children: "Active"
|
|
149
|
+
}),
|
|
150
|
+
/* @__PURE__ */ u(N, {
|
|
151
|
+
value: "inactive",
|
|
152
|
+
children: "Inactive"
|
|
153
|
+
}),
|
|
154
|
+
/* @__PURE__ */ u(N, {
|
|
155
|
+
value: "pending",
|
|
156
|
+
children: "Pending"
|
|
157
|
+
})
|
|
158
|
+
] })]
|
|
159
|
+
})]
|
|
160
|
+
}),
|
|
161
|
+
/* @__PURE__ */ u("div", {
|
|
116
162
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
117
|
-
children:
|
|
163
|
+
children: z.length === 0 ? /* @__PURE__ */ u("div", {
|
|
118
164
|
className: "col-span-full",
|
|
119
|
-
children: /* @__PURE__ */
|
|
165
|
+
children: /* @__PURE__ */ u(D, {
|
|
120
166
|
illustration: "empty-data",
|
|
121
167
|
title: "No vendors yet",
|
|
122
168
|
description: "Add a vendor to start tracking external relationships."
|
|
123
169
|
})
|
|
124
|
-
}) :
|
|
170
|
+
}) : $.length === 0 ? /* @__PURE__ */ u("div", {
|
|
171
|
+
className: "col-span-full",
|
|
172
|
+
children: /* @__PURE__ */ u(D, {
|
|
173
|
+
illustration: "empty-search",
|
|
174
|
+
title: "No vendors match",
|
|
175
|
+
description: "Try a different search term or status filter."
|
|
176
|
+
})
|
|
177
|
+
}) : ne.map((e, t) => /* @__PURE__ */ d(T, {
|
|
125
178
|
treatment: t === 0 ? "glass" : "plain",
|
|
126
179
|
glow: t === 0,
|
|
127
|
-
children: [/* @__PURE__ */
|
|
180
|
+
children: [/* @__PURE__ */ u(C, { children: /* @__PURE__ */ d("div", {
|
|
128
181
|
className: "flex items-center justify-between",
|
|
129
|
-
children: [/* @__PURE__ */
|
|
182
|
+
children: [/* @__PURE__ */ u(w, {
|
|
130
183
|
className: "text-base",
|
|
131
184
|
children: e.name
|
|
132
|
-
}), /* @__PURE__ */
|
|
185
|
+
}), /* @__PURE__ */ d("div", {
|
|
133
186
|
className: "flex items-center gap-1",
|
|
134
187
|
children: [
|
|
135
|
-
/* @__PURE__ */
|
|
188
|
+
/* @__PURE__ */ u(b, {
|
|
136
189
|
variant: e.status === "active" ? "default" : "secondary",
|
|
137
190
|
className: "text-[10px]",
|
|
138
191
|
children: e.status
|
|
139
192
|
}),
|
|
140
|
-
/* @__PURE__ */
|
|
193
|
+
/* @__PURE__ */ u(x, {
|
|
141
194
|
variant: "ghost",
|
|
142
195
|
size: "icon",
|
|
143
196
|
"aria-label": `Edit ${e.name}`,
|
|
144
|
-
onClick: () =>
|
|
145
|
-
children: /* @__PURE__ */
|
|
197
|
+
onClick: () => U.openModal(e),
|
|
198
|
+
children: /* @__PURE__ */ u(a, { className: "h-4 w-4" })
|
|
146
199
|
}),
|
|
147
|
-
/* @__PURE__ */
|
|
200
|
+
/* @__PURE__ */ d(ee, { children: [/* @__PURE__ */ u(y, {
|
|
148
201
|
asChild: !0,
|
|
149
|
-
children: /* @__PURE__ */
|
|
202
|
+
children: /* @__PURE__ */ u(x, {
|
|
150
203
|
variant: "ghost",
|
|
151
204
|
size: "icon",
|
|
152
205
|
"aria-label": `Delete ${e.name}`,
|
|
153
|
-
children: /* @__PURE__ */
|
|
206
|
+
children: /* @__PURE__ */ u(l, { className: "h-4 w-4 text-status-error-text" })
|
|
154
207
|
})
|
|
155
|
-
}), /* @__PURE__ */
|
|
208
|
+
}), /* @__PURE__ */ d(m, { children: [/* @__PURE__ */ d(_, { children: [/* @__PURE__ */ u(v, { children: "Delete vendor?" }), /* @__PURE__ */ d(h, { children: [
|
|
156
209
|
"This removes “",
|
|
157
210
|
e.name,
|
|
158
211
|
"” from your vendor directory. This action cannot be undone."
|
|
159
|
-
] })] }), /* @__PURE__ */
|
|
160
|
-
onClick: () => void
|
|
212
|
+
] })] }), /* @__PURE__ */ d(g, { children: [/* @__PURE__ */ u(p, { children: "Cancel" }), /* @__PURE__ */ u(f, {
|
|
213
|
+
onClick: () => void H(e.id),
|
|
161
214
|
children: "Delete"
|
|
162
215
|
})] })] })] })
|
|
163
216
|
]
|
|
164
217
|
})]
|
|
165
|
-
}) }), /* @__PURE__ */
|
|
218
|
+
}) }), /* @__PURE__ */ u(S, { children: /* @__PURE__ */ d("div", {
|
|
166
219
|
className: "space-y-2",
|
|
167
220
|
children: [
|
|
168
|
-
/* @__PURE__ */
|
|
221
|
+
/* @__PURE__ */ u(b, {
|
|
169
222
|
variant: "outline",
|
|
170
223
|
className: "text-[10px]",
|
|
171
224
|
children: e.category
|
|
172
225
|
}),
|
|
173
|
-
/* @__PURE__ */
|
|
226
|
+
/* @__PURE__ */ d("div", {
|
|
174
227
|
className: "grid grid-cols-2 gap-2 mt-2",
|
|
175
|
-
children: [/* @__PURE__ */
|
|
228
|
+
children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
|
|
176
229
|
className: "text-xs text-text-secondary",
|
|
177
230
|
children: "Contact"
|
|
178
|
-
}), /* @__PURE__ */
|
|
231
|
+
}), /* @__PURE__ */ u("p", {
|
|
179
232
|
className: "text-sm",
|
|
180
233
|
children: e.contactPerson
|
|
181
|
-
})] }), /* @__PURE__ */
|
|
234
|
+
})] }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
|
|
182
235
|
className: "text-xs text-text-secondary",
|
|
183
236
|
children: "Contract Value"
|
|
184
|
-
}), /* @__PURE__ */
|
|
237
|
+
}), /* @__PURE__ */ d("p", {
|
|
185
238
|
className: "text-sm font-medium",
|
|
186
239
|
children: ["$", e.contractValue.toLocaleString()]
|
|
187
240
|
})] })]
|
|
188
241
|
}),
|
|
189
|
-
/* @__PURE__ */
|
|
242
|
+
/* @__PURE__ */ d("div", {
|
|
190
243
|
className: "flex items-center justify-between pt-2 border-t mt-2",
|
|
191
|
-
children: [/* @__PURE__ */
|
|
244
|
+
children: [/* @__PURE__ */ d("div", {
|
|
192
245
|
className: "flex items-center gap-1 text-xs text-text-secondary",
|
|
193
|
-
children: [/* @__PURE__ */
|
|
194
|
-
}), /* @__PURE__ */
|
|
246
|
+
children: [/* @__PURE__ */ u(i, { className: "h-3 w-3" }), e.email]
|
|
247
|
+
}), /* @__PURE__ */ d("div", {
|
|
195
248
|
className: "flex items-center gap-1",
|
|
196
|
-
children: [/* @__PURE__ */ c
|
|
249
|
+
children: [/* @__PURE__ */ u(c, { className: "h-3 w-3 text-status-warning-text" }), /* @__PURE__ */ u("span", {
|
|
197
250
|
className: "text-sm",
|
|
198
251
|
children: e.rating
|
|
199
252
|
})]
|
|
@@ -203,22 +256,28 @@ function j() {
|
|
|
203
256
|
}) })]
|
|
204
257
|
}, e.id))
|
|
205
258
|
}),
|
|
206
|
-
/* @__PURE__ */
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
259
|
+
$.length > Y && /* @__PURE__ */ u(A, {
|
|
260
|
+
page: J,
|
|
261
|
+
pageSize: Y,
|
|
262
|
+
totalItems: $.length,
|
|
263
|
+
onPageChange: Z
|
|
264
|
+
}),
|
|
265
|
+
/* @__PURE__ */ u(t, {
|
|
266
|
+
open: U.open,
|
|
267
|
+
onOpenChange: U.onOpenChange,
|
|
268
|
+
title: U.context ? "Edit vendor" : "Add vendor",
|
|
210
269
|
description: "Track the vendor, its contract value, and primary contact.",
|
|
211
|
-
fields:
|
|
212
|
-
initialValues:
|
|
213
|
-
submitLabel:
|
|
270
|
+
fields: I,
|
|
271
|
+
initialValues: U.context ? L(U.context) : void 0,
|
|
272
|
+
submitLabel: U.context ? "Save changes" : "Add vendor",
|
|
214
273
|
onSubmit: async (e) => {
|
|
215
|
-
|
|
274
|
+
U.context ? await V(U.context.id, R(e, U.context)) : await B(R(e));
|
|
216
275
|
}
|
|
217
276
|
})
|
|
218
277
|
]
|
|
219
278
|
});
|
|
220
279
|
}
|
|
221
280
|
//#endregion
|
|
222
|
-
export {
|
|
281
|
+
export { z as CompanyVendorManagementPagePage };
|
|
223
282
|
|
|
224
283
|
//# sourceMappingURL=CompanyVendorManagementPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompanyVendorManagementPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CompanyVendorManagementPagePage.tsx"],"sourcesContent":["import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n Badge,\n Button,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Mail, Pencil, Plus, Star, Trash2 } from 'lucide-react';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Vendor } from '../store/crewfoundryStore';\n\nconst VENDOR_FIELDS: FieldConfig[] = [\n { name: 'name', label: 'Vendor name', type: 'text', required: true },\n { name: 'category', label: 'Category', type: 'text', required: true },\n { name: 'contactPerson', label: 'Contact person', type: 'text' },\n { name: 'email', label: 'Contact email', type: 'email' },\n { name: 'phone', label: 'Phone', type: 'text' },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n options: [\n { label: 'Active', value: 'active' },\n { label: 'Inactive', value: 'inactive' },\n { label: 'Pending', value: 'pending' },\n ],\n },\n { name: 'contractValue', label: 'Contract value (USD)', type: 'number' },\n { name: 'rating', label: 'Rating (0-5)', type: 'number' },\n];\n\nconst toInitialValues = (vendor: Vendor): FormValues => ({\n name: vendor.name,\n category: vendor.category,\n contactPerson: vendor.contactPerson,\n email: vendor.email,\n phone: vendor.phone,\n status: vendor.status,\n contractValue: vendor.contractValue,\n rating: vendor.rating,\n});\n\nconst valuesToVendor = (values: FormValues, base?: Vendor): Vendor => ({\n id: base?.id ?? crypto.randomUUID(),\n name: String(values.name ?? ''),\n category: String(values.category ?? ''),\n contactPerson: String(values.contactPerson ?? ''),\n email: String(values.email ?? ''),\n phone: String(values.phone ?? ''),\n status: (values.status as Vendor['status']) || 'pending',\n contractValue:\n typeof values.contractValue === 'number'\n ? values.contractValue\n : Number(values.contractValue) || 0,\n rating: typeof values.rating === 'number' ? values.rating : Number(values.rating) || 0,\n});\n\nexport function CompanyVendorManagementPagePage() {\n const { vendors, addVendor, updateVendor, removeVendor } = useCrewFoundryStore();\n const modal = useFormModal<Vendor>();\n const totalContractValue = vendors.reduce((s, v) => s + v.contractValue, 0);\n\n const handleSubmit = async (values: FormValues) => {\n if (modal.context) {\n await updateVendor(modal.context.id, valuesToVendor(values, modal.context));\n } else {\n await addVendor(valuesToVendor(values));\n }\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>Vendor Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {vendors.length} vendors · ${(totalContractValue / 1000).toFixed(0)}K total contract\n value\n </p>\n <PagePurpose className=\"mt-1\">Track the vendors and suppliers you depend on — contracts, contacts, and status — to manage external relationships in one place.</PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => modal.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Vendor\n </Button>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {vendors.length === 0 ? (\n <div className=\"col-span-full\">\n <IllustratedEmptyState illustration=\"empty-data\" title=\"No vendors yet\" description=\"Add a vendor to start tracking external relationships.\" />\n </div>\n ) : (\n vendors.map((vendor, _idx) => (\n <GlassCard key={vendor.id} treatment={_idx === 0 ? 'glass' : 'plain'} glow={_idx === 0}>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">{vendor.name}</CardTitle>\n <div className=\"flex items-center gap-1\">\n <Badge\n variant={vendor.status === 'active' ? 'default' : 'secondary'}\n className=\"text-[10px]\"\n >\n {vendor.status}\n </Badge>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`Edit ${vendor.name}`}\n onClick={() => modal.openModal(vendor)}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" aria-label={`Delete ${vendor.name}`}>\n <Trash2 className=\"h-4 w-4 text-status-error-text\" />\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete vendor?</AlertDialogTitle>\n <AlertDialogDescription>\n This removes “{vendor.name}” from your vendor directory. This action cannot be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction onClick={() => void removeVendor(vendor.id)}>\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {vendor.category}\n </Badge>\n <div className=\"grid grid-cols-2 gap-2 mt-2\">\n <div>\n <p className=\"text-xs text-text-secondary\">Contact</p>\n <p className=\"text-sm\">{vendor.contactPerson}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Contract Value</p>\n <p className=\"text-sm font-medium\">${vendor.contractValue.toLocaleString()}</p>\n </div>\n </div>\n <div className=\"flex items-center justify-between pt-2 border-t mt-2\">\n <div className=\"flex items-center gap-1 text-xs text-text-secondary\">\n <Mail className=\"h-3 w-3\" />\n {vendor.email}\n </div>\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n <span className=\"text-sm\">{vendor.rating}</span>\n </div>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n )))}\n </div>\n\n <FormModal\n open={modal.open}\n onOpenChange={modal.onOpenChange}\n title={modal.context ? 'Edit vendor' : 'Add vendor'}\n description=\"Track the vendor, its contract value, and primary contact.\"\n fields={VENDOR_FIELDS}\n initialValues={modal.context ? toInitialValues(modal.context) : undefined}\n submitLabel={modal.context ? 'Save changes' : 'Add vendor'}\n onSubmit={handleSubmit}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;AA6BA,IAAM,IAA+B;CACnC;EAAE,MAAM;EAAQ,OAAO;EAAe,MAAM;EAAQ,UAAU;EAAM;CACpE;EAAE,MAAM;EAAY,OAAO;EAAY,MAAM;EAAQ,UAAU;EAAM;CACrE;EAAE,MAAM;EAAiB,OAAO;EAAkB,MAAM;EAAQ;CAChE;EAAE,MAAM;EAAS,OAAO;EAAiB,MAAM;EAAS;CACxD;EAAE,MAAM;EAAS,OAAO;EAAS,MAAM;EAAQ;CAC/C;EACE,MAAM;EACN,OAAO;EACP,MAAM;EACN,SAAS;GACP;IAAE,OAAO;IAAU,OAAO;IAAU;GACpC;IAAE,OAAO;IAAY,OAAO;IAAY;GACxC;IAAE,OAAO;IAAW,OAAO;IAAW;GACvC;EACF;CACD;EAAE,MAAM;EAAiB,OAAO;EAAwB,MAAM;EAAU;CACxE;EAAE,MAAM;EAAU,OAAO;EAAgB,MAAM;EAAU;CAC1D,EAEK,KAAmB,OAAgC;CACvD,MAAM,EAAO;CACb,UAAU,EAAO;CACjB,eAAe,EAAO;CACtB,OAAO,EAAO;CACd,OAAO,EAAO;CACd,QAAQ,EAAO;CACf,eAAe,EAAO;CACtB,QAAQ,EAAO;CAChB,GAEK,KAAkB,GAAoB,OAA2B;CACrE,IAAI,GAAM,MAAM,OAAO,YAAY;CACnC,MAAM,OAAO,EAAO,QAAQ,GAAG;CAC/B,UAAU,OAAO,EAAO,YAAY,GAAG;CACvC,eAAe,OAAO,EAAO,iBAAiB,GAAG;CACjD,OAAO,OAAO,EAAO,SAAS,GAAG;CACjC,OAAO,OAAO,EAAO,SAAS,GAAG;CACjC,QAAS,EAAO,UAA+B;CAC/C,eACE,OAAO,EAAO,iBAAkB,WAC5B,EAAO,gBACP,OAAO,EAAO,cAAc,IAAI;CACtC,QAAQ,OAAO,EAAO,UAAW,WAAW,EAAO,SAAS,OAAO,EAAO,OAAO,IAAI;CACtF;AAED,SAAgB,IAAkC;CAChD,IAAM,EAAE,YAAS,cAAW,iBAAc,oBAAiB,GAAqB,EAC1E,IAAQ,GAAsB,EAC9B,IAAqB,EAAQ,QAAQ,GAAG,MAAM,IAAI,EAAE,eAAe,EAAE;AAU3E,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA;KACE,kBAAC,MAAD;MAAI,WAAU;gBACZ,kBAAC,GAAD,EAAA,UAAc,qBAAgC,CAAA;MAC3C,CAAA;KACL,kBAAC,KAAD;MAAG,WAAU;gBAAb;OACG,EAAQ;OAAO;QAAc,IAAqB,KAAM,QAAQ,EAAE;OAAC;OAElE;;KACJ,kBAAC,GAAD;MAAa,WAAU;gBAAO;MAA8I,CAAA;KACxK,EAAA,CAAA,EACN,kBAAC,GAAD;KAAQ,MAAK;KAAK,eAAe,EAAM,WAAW;eAAlD,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAAA,aAE1B;OACL;;GACN,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAQ,WAAW,IAClB,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,GAAD;MAAuB,cAAa;MAAa,OAAM;MAAiB,aAAY;MAA2D,CAAA;KAC3I,CAAA,GAEN,EAAQ,KAAK,GAAQ,MACrB,kBAAC,GAAD;KAA2B,WAAW,MAAS,IAAI,UAAU;KAAS,MAAM,MAAS;eAArF,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD;OAAW,WAAU;iBAAa,EAAO;OAAiB,CAAA,EAC1D,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD;SACE,SAAS,EAAO,WAAW,WAAW,YAAY;SAClD,WAAU;mBAET,EAAO;SACF,CAAA;QACR,kBAAC,GAAD;SACE,SAAQ;SACR,MAAK;SACL,cAAY,QAAQ,EAAO;SAC3B,eAAe,EAAM,UAAU,EAAO;mBAEtC,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;SACvB,CAAA;QACT,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;SAAoB,SAAA;mBAClB,kBAAC,GAAD;UAAQ,SAAQ;UAAQ,MAAK;UAAO,cAAY,UAAU,EAAO;oBAC/D,kBAAC,GAAD,EAAQ,WAAU,kCAAmC,CAAA;UAC9C,CAAA;SACU,CAAA,EACrB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAkB,kBAAiC,CAAA,EACnD,kBAAC,GAAD,EAAA,UAAA;SAAwB;SACP,EAAO;SAAK;SACJ,EAAA,CAAA,CACP,EAAA,CAAA,EACpB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAmB,UAA0B,CAAA,EAC7C,kBAAC,GAAD;SAAmB,eAAe,KAAK,EAAa,EAAO,GAAG;mBAAE;SAE5C,CAAA,CACF,EAAA,CAAA,CACD,EAAA,CAAA,CACT,EAAA,CAAA;QACV;SACF;SACK,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD;QAAO,SAAQ;QAAU,WAAU;kBAChC,EAAO;QACF,CAAA;OACR,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;mBAA8B;SAAW,CAAA,EACtD,kBAAC,KAAD;SAAG,WAAU;mBAAW,EAAO;SAAkB,CAAA,CAC7C,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;mBAA8B;SAAkB,CAAA,EAC7D,kBAAC,KAAD;SAAG,WAAU;mBAAb,CAAmC,KAAE,EAAO,cAAc,gBAAgB,CAAK;WAC3E,EAAA,CAAA,CACF;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAC3B,EAAO,MACJ;YACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,oCAAqC,CAAA,EACrD,kBAAC,QAAD;UAAM,WAAU;oBAAW,EAAO;UAAc,CAAA,CAC5C;WACF;;OACF;SACM,CAAA,CACJ;OAtEI,EAAO,GAsEX,CACZ;IACE,CAAA;GAEN,kBAAC,GAAD;IACE,MAAM,EAAM;IACZ,cAAc,EAAM;IACpB,OAAO,EAAM,UAAU,gBAAgB;IACvC,aAAY;IACZ,QAAQ;IACR,eAAe,EAAM,UAAU,EAAgB,EAAM,QAAQ,GAAG,KAAA;IAChE,aAAa,EAAM,UAAU,iBAAiB;IAC9C,UAnHe,OAAO,MAAuB;AACjD,KAAI,EAAM,UACR,MAAM,EAAa,EAAM,QAAQ,IAAI,EAAe,GAAQ,EAAM,QAAQ,CAAC,GAE3E,MAAM,EAAU,EAAe,EAAO,CAAC;;IAgHrC,CAAA;GACE"}
|
|
1
|
+
{"version":3,"file":"CompanyVendorManagementPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CompanyVendorManagementPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n Badge,\n Button,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n Pagination,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { Mail, Pencil, Plus, Search, Star, Trash2 } from 'lucide-react';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Vendor } from '../store/crewfoundryStore';\n\nconst VENDOR_FIELDS: FieldConfig[] = [\n { name: 'name', label: 'Vendor name', type: 'text', required: true },\n { name: 'category', label: 'Category', type: 'text', required: true },\n { name: 'contactPerson', label: 'Contact person', type: 'text' },\n { name: 'email', label: 'Contact email', type: 'email' },\n { name: 'phone', label: 'Phone', type: 'text' },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n options: [\n { label: 'Active', value: 'active' },\n { label: 'Inactive', value: 'inactive' },\n { label: 'Pending', value: 'pending' },\n ],\n },\n { name: 'contractValue', label: 'Contract value (USD)', type: 'number' },\n { name: 'rating', label: 'Rating (0-5)', type: 'number' },\n];\n\nconst toInitialValues = (vendor: Vendor): FormValues => ({\n name: vendor.name,\n category: vendor.category,\n contactPerson: vendor.contactPerson,\n email: vendor.email,\n phone: vendor.phone,\n status: vendor.status,\n contractValue: vendor.contractValue,\n rating: vendor.rating,\n});\n\nconst valuesToVendor = (values: FormValues, base?: Vendor): Vendor => ({\n id: base?.id ?? crypto.randomUUID(),\n name: String(values.name ?? ''),\n category: String(values.category ?? ''),\n contactPerson: String(values.contactPerson ?? ''),\n email: String(values.email ?? ''),\n phone: String(values.phone ?? ''),\n status: (values.status as Vendor['status']) || 'pending',\n contractValue:\n typeof values.contractValue === 'number'\n ? values.contractValue\n : Number(values.contractValue) || 0,\n rating: typeof values.rating === 'number' ? values.rating : Number(values.rating) || 0,\n});\n\nexport function CompanyVendorManagementPagePage() {\n const { vendors, addVendor, updateVendor, removeVendor } = useCrewFoundryStore();\n const modal = useFormModal<Vendor>();\n const [search, setSearch] = useState('');\n const [filterStatus, setFilterStatus] = useState<string>('all');\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 12 });\n const totalContractValue = vendors.reduce((s, v) => s + v.contractValue, 0);\n\n const filtered = vendors.filter((v) => {\n const matchSearch = `${v.name} ${v.category} ${v.contactPerson} ${v.email}`\n .toLowerCase()\n .includes(search.toLowerCase());\n const matchStatus = filterStatus === 'all' || v.status === filterStatus;\n return matchSearch && matchStatus;\n });\n const paged = filtered.slice(offset, offset + pageSize);\n\n const handleSubmit = async (values: FormValues) => {\n if (modal.context) {\n await updateVendor(modal.context.id, valuesToVendor(values, modal.context));\n } else {\n await addVendor(valuesToVendor(values));\n }\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>Vendor Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {vendors.length} vendors · ${(totalContractValue / 1000).toFixed(0)}K total contract\n value\n </p>\n <PagePurpose className=\"mt-1\">Track the vendors and suppliers you depend on — contracts, contacts, and status — to manage external relationships in one place.</PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => modal.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Vendor\n </Button>\n </div>\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search vendors...\"\n className=\"pl-9\"\n value={search}\n onChange={(event) => {\n setSearch(event.target.value);\n setPage(1);\n }}\n />\n </div>\n <Select\n value={filterStatus}\n onValueChange={(value) => {\n setFilterStatus(value);\n setPage(1);\n }}\n >\n <SelectTrigger className=\"w-full sm:w-40\" aria-label=\"Filter by status\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All statuses</SelectItem>\n <SelectItem value=\"active\">Active</SelectItem>\n <SelectItem value=\"inactive\">Inactive</SelectItem>\n <SelectItem value=\"pending\">Pending</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {vendors.length === 0 ? (\n <div className=\"col-span-full\">\n <IllustratedEmptyState illustration=\"empty-data\" title=\"No vendors yet\" description=\"Add a vendor to start tracking external relationships.\" />\n </div>\n ) : filtered.length === 0 ? (\n <div className=\"col-span-full\">\n <IllustratedEmptyState illustration=\"empty-search\" title=\"No vendors match\" description=\"Try a different search term or status filter.\" />\n </div>\n ) : (\n paged.map((vendor, _idx) => (\n <GlassCard key={vendor.id} treatment={_idx === 0 ? 'glass' : 'plain'} glow={_idx === 0}>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">{vendor.name}</CardTitle>\n <div className=\"flex items-center gap-1\">\n <Badge\n variant={vendor.status === 'active' ? 'default' : 'secondary'}\n className=\"text-[10px]\"\n >\n {vendor.status}\n </Badge>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`Edit ${vendor.name}`}\n onClick={() => modal.openModal(vendor)}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" aria-label={`Delete ${vendor.name}`}>\n <Trash2 className=\"h-4 w-4 text-status-error-text\" />\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete vendor?</AlertDialogTitle>\n <AlertDialogDescription>\n This removes “{vendor.name}” from your vendor directory. This action cannot be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction onClick={() => void removeVendor(vendor.id)}>\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {vendor.category}\n </Badge>\n <div className=\"grid grid-cols-2 gap-2 mt-2\">\n <div>\n <p className=\"text-xs text-text-secondary\">Contact</p>\n <p className=\"text-sm\">{vendor.contactPerson}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Contract Value</p>\n <p className=\"text-sm font-medium\">${vendor.contractValue.toLocaleString()}</p>\n </div>\n </div>\n <div className=\"flex items-center justify-between pt-2 border-t mt-2\">\n <div className=\"flex items-center gap-1 text-xs text-text-secondary\">\n <Mail className=\"h-3 w-3\" />\n {vendor.email}\n </div>\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n <span className=\"text-sm\">{vendor.rating}</span>\n </div>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n )))}\n </div>\n {filtered.length > pageSize && (\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={filtered.length}\n onPageChange={setPage}\n />\n )}\n\n <FormModal\n open={modal.open}\n onOpenChange={modal.onOpenChange}\n title={modal.context ? 'Edit vendor' : 'Add vendor'}\n description=\"Track the vendor, its contract value, and primary contact.\"\n fields={VENDOR_FIELDS}\n initialValues={modal.context ? toInitialValues(modal.context) : undefined}\n submitLabel={modal.context ? 'Save changes' : 'Add vendor'}\n onSubmit={handleSubmit}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -2,52 +2,43 @@ import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
|
2
2
|
import { useMemo as t } from "react";
|
|
3
3
|
import { BarChart3 as n, DollarSign as r, Target as i, TrendingDown as a, TrendingUp as o, Users as s } from "lucide-react";
|
|
4
4
|
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
5
|
-
import { Badge as u, Card as d, CardContent as f, CardDescription as p, CardHeader as m, CardTitle as h, GlassCard as g, GradientText as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
|
|
5
|
+
import { Badge as u, Card as d, CardContent as f, CardDescription as p, CardHeader as m, CardTitle as h, GlassCard as g, GradientText as _, PagePurpose as v, ResponsiveTable as y } from "@burdenoff/fe-libs/ui";
|
|
6
6
|
//#region src/crewfoundry/pages/DashboardAnalyticsPagePage.tsx
|
|
7
|
-
function
|
|
8
|
-
let { employees:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
let
|
|
7
|
+
function b() {
|
|
8
|
+
let { employees: b, departments: x, jobPostings: S, payrollRecords: C, projects: w } = e(), T = t(() => {
|
|
9
|
+
if (b.length === 0) return [];
|
|
10
|
+
let e = (e) => {
|
|
11
|
+
let t = new Date(e);
|
|
12
|
+
return `${t.getFullYear()}-${String(t.getMonth()).padStart(2, "0")}`;
|
|
13
|
+
};
|
|
14
|
+
return Array.from(new Set(b.map((t) => e(t.startDate)))).sort().slice(-6).map((t) => {
|
|
15
|
+
let [n, r] = t.split("-").map(Number), i = new Date(n, r + 1, 0).getTime(), a = new Date(n, r, 1).toLocaleString("en-US", {
|
|
16
|
+
month: "short",
|
|
17
|
+
year: "2-digit"
|
|
18
|
+
}), o = b.filter((e) => new Date(e.startDate).getTime() <= i && e.status !== "terminated").length;
|
|
12
19
|
return {
|
|
13
|
-
month:
|
|
14
|
-
hires:
|
|
15
|
-
attrition:
|
|
16
|
-
headcount:
|
|
20
|
+
month: a,
|
|
21
|
+
hires: b.filter((n) => e(n.startDate) === t).length,
|
|
22
|
+
attrition: b.filter((n) => n.status === "terminated" && e(n.startDate) === t).length,
|
|
23
|
+
headcount: o
|
|
17
24
|
};
|
|
18
25
|
});
|
|
19
|
-
}, [
|
|
26
|
+
}, [b]), E = Math.max(1, ...T.map((e) => e.headcount)), D = C.reduce((e, t) => e + t.netPay, 0), O = Math.round(b.reduce((e, t) => e + t.salary, 0) / Math.max(b.length, 1)), k = S.filter((e) => e.status === "active").length, A = b.reduce((e, t) => {
|
|
20
27
|
let n = t.type.replace("_", " ");
|
|
21
28
|
return e[n] = (e[n] || 0) + 1, e;
|
|
22
|
-
}, {}),
|
|
23
|
-
let e = [
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
amount: x.reduce((e, t) => e + t.applicants * 120, 0)
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
category: "Project Delivery",
|
|
34
|
-
amount: C.reduce((e, t) => e + t.spent, 0)
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
category: "Department Ops",
|
|
38
|
-
amount: b.reduce((e, t) => e + t.budget * .03, 0)
|
|
39
|
-
}
|
|
40
|
-
], t = e.reduce((e, t) => e + t.amount, 0) || 1;
|
|
29
|
+
}, {}), j = t(() => {
|
|
30
|
+
let e = [{
|
|
31
|
+
category: "Net Payroll",
|
|
32
|
+
amount: D
|
|
33
|
+
}, {
|
|
34
|
+
category: "Project Delivery",
|
|
35
|
+
amount: w.reduce((e, t) => e + t.spent, 0)
|
|
36
|
+
}], t = e.reduce((e, t) => e + t.amount, 0) || 1;
|
|
41
37
|
return e.map((e) => ({
|
|
42
38
|
...e,
|
|
43
39
|
percentage: Math.round(e.amount / t * 100)
|
|
44
40
|
}));
|
|
45
|
-
}, [
|
|
46
|
-
b,
|
|
47
|
-
x,
|
|
48
|
-
C,
|
|
49
|
-
E
|
|
50
|
-
]);
|
|
41
|
+
}, [w, D]);
|
|
51
42
|
return /* @__PURE__ */ l("div", {
|
|
52
43
|
className: "space-y-6 p-6",
|
|
53
44
|
children: [
|
|
@@ -80,7 +71,7 @@ function y() {
|
|
|
80
71
|
}), /* @__PURE__ */ c(s, { className: "h-4 w-4 text-text-secondary" })]
|
|
81
72
|
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ c("div", {
|
|
82
73
|
className: "text-2xl font-bold tabular-nums",
|
|
83
|
-
children:
|
|
74
|
+
children: b.length
|
|
84
75
|
}), /* @__PURE__ */ l("div", {
|
|
85
76
|
className: "flex items-center text-xs text-status-success-text",
|
|
86
77
|
children: [/* @__PURE__ */ c(o, { className: "mr-1 h-3 w-3" }), "Live workforce count"]
|
|
@@ -97,7 +88,7 @@ function y() {
|
|
|
97
88
|
}), /* @__PURE__ */ c(r, { className: "h-4 w-4 text-text-secondary" })]
|
|
98
89
|
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
|
|
99
90
|
className: "text-2xl font-bold tabular-nums",
|
|
100
|
-
children: ["$",
|
|
91
|
+
children: ["$", O.toLocaleString()]
|
|
101
92
|
}), /* @__PURE__ */ l("div", {
|
|
102
93
|
className: "flex items-center text-xs text-status-success-text",
|
|
103
94
|
children: [/* @__PURE__ */ c(o, { className: "mr-1 h-3 w-3" }), "Updated from employee records"]
|
|
@@ -114,7 +105,7 @@ function y() {
|
|
|
114
105
|
}), /* @__PURE__ */ c(a, { className: "h-4 w-4 text-text-secondary" })]
|
|
115
106
|
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
|
|
116
107
|
className: "text-2xl font-bold tabular-nums",
|
|
117
|
-
children: [Math.round(
|
|
108
|
+
children: [Math.round(b.filter((e) => e.status === "terminated").length / Math.max(b.length, 1) * 100), "%"]
|
|
118
109
|
}), /* @__PURE__ */ l("div", {
|
|
119
110
|
className: "flex items-center text-xs text-status-success-text",
|
|
120
111
|
children: [/* @__PURE__ */ c(a, { className: "mr-1 h-3 w-3" }), "Calculated from status mix"]
|
|
@@ -131,7 +122,7 @@ function y() {
|
|
|
131
122
|
}), /* @__PURE__ */ c(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
132
123
|
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ c("div", {
|
|
133
124
|
className: "text-2xl font-bold tabular-nums",
|
|
134
|
-
children:
|
|
125
|
+
children: k
|
|
135
126
|
}), /* @__PURE__ */ c("p", {
|
|
136
127
|
className: "text-xs text-text-secondary",
|
|
137
128
|
children: "Based on active job postings"
|
|
@@ -145,7 +136,7 @@ function y() {
|
|
|
145
136
|
className: "col-span-4",
|
|
146
137
|
children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Headcount Trend" }), /* @__PURE__ */ c(p, { children: "Monthly headcount over recent months" })] }), /* @__PURE__ */ c(f, {
|
|
147
138
|
className: "space-y-3",
|
|
148
|
-
children:
|
|
139
|
+
children: T.map((e, t) => /* @__PURE__ */ l("div", {
|
|
149
140
|
className: "flex items-center gap-3",
|
|
150
141
|
children: [
|
|
151
142
|
/* @__PURE__ */ c("span", {
|
|
@@ -156,7 +147,7 @@ function y() {
|
|
|
156
147
|
className: "h-4 flex-1 overflow-hidden rounded bg-bg-sunken",
|
|
157
148
|
children: /* @__PURE__ */ c("div", {
|
|
158
149
|
className: "h-4 rounded bg-action-primary-bg",
|
|
159
|
-
style: { width: `${Math.round(e.headcount /
|
|
150
|
+
style: { width: `${Math.round(e.headcount / E * 100)}%` }
|
|
160
151
|
})
|
|
161
152
|
}),
|
|
162
153
|
/* @__PURE__ */ c("span", {
|
|
@@ -182,7 +173,7 @@ function y() {
|
|
|
182
173
|
className: "col-span-3",
|
|
183
174
|
children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Employee Types" }), /* @__PURE__ */ c(p, { children: "Distribution by employment type" })] }), /* @__PURE__ */ c(f, {
|
|
184
175
|
className: "space-y-4",
|
|
185
|
-
children: Object.entries(
|
|
176
|
+
children: Object.entries(A).sort(([, e], [, t]) => t - e).map(([e, t]) => /* @__PURE__ */ l("div", {
|
|
186
177
|
className: "flex items-center justify-between",
|
|
187
178
|
children: [/* @__PURE__ */ l("div", {
|
|
188
179
|
className: "flex items-center gap-2",
|
|
@@ -199,7 +190,7 @@ function y() {
|
|
|
199
190
|
className: "text-xs text-text-secondary",
|
|
200
191
|
children: [
|
|
201
192
|
"(",
|
|
202
|
-
Math.round(t / Math.max(
|
|
193
|
+
Math.round(t / Math.max(b.length, 1) * 100),
|
|
203
194
|
"%)"
|
|
204
195
|
]
|
|
205
196
|
})]
|
|
@@ -210,7 +201,7 @@ function y() {
|
|
|
210
201
|
}),
|
|
211
202
|
/* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Workforce Cost Breakdown" }), /* @__PURE__ */ c(p, { children: "Operational costs by category" })] }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ c("div", {
|
|
212
203
|
className: "space-y-3",
|
|
213
|
-
children:
|
|
204
|
+
children: j.map((e) => /* @__PURE__ */ l("div", {
|
|
214
205
|
className: "flex items-center gap-4",
|
|
215
206
|
children: [
|
|
216
207
|
/* @__PURE__ */ c("span", {
|
|
@@ -247,65 +238,70 @@ function y() {
|
|
|
247
238
|
className: "font-bold",
|
|
248
239
|
children: [
|
|
249
240
|
"$",
|
|
250
|
-
(
|
|
241
|
+
(j.reduce((e, t) => e + t.amount, 0) / 1e3).toFixed(0),
|
|
251
242
|
"K"
|
|
252
243
|
]
|
|
253
244
|
})]
|
|
254
245
|
})] })] }),
|
|
255
|
-
/* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Department Overview" }), /* @__PURE__ */ c(p, { children: "Key metrics by department" })] }), /* @__PURE__ */
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
246
|
+
/* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, { children: "Department Overview" }), /* @__PURE__ */ c(p, { children: "Key metrics by department" })] }), /* @__PURE__ */ c(f, { children: /* @__PURE__ */ c(y, {
|
|
247
|
+
columns: [
|
|
248
|
+
{
|
|
249
|
+
key: "name",
|
|
250
|
+
header: "Department",
|
|
251
|
+
priority: "primary",
|
|
252
|
+
cell: (e) => /* @__PURE__ */ c("span", {
|
|
253
|
+
className: "font-medium",
|
|
254
|
+
children: e.name
|
|
255
|
+
})
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
key: "head",
|
|
259
|
+
header: "Head",
|
|
260
|
+
priority: "secondary",
|
|
261
|
+
cell: (e) => /* @__PURE__ */ c("span", {
|
|
262
|
+
className: "text-text-secondary",
|
|
263
|
+
children: e.headName
|
|
264
|
+
})
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
key: "employees",
|
|
268
|
+
header: "Employees",
|
|
269
|
+
priority: "secondary",
|
|
270
|
+
cell: (e) => /* @__PURE__ */ c("span", {
|
|
271
|
+
className: "md:block md:text-right",
|
|
272
|
+
children: e.employeeCount
|
|
273
|
+
})
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
key: "budget",
|
|
277
|
+
header: "Budget",
|
|
278
|
+
priority: "secondary",
|
|
279
|
+
cell: (e) => /* @__PURE__ */ l("span", {
|
|
280
|
+
className: "md:block md:text-right",
|
|
281
|
+
children: [
|
|
282
|
+
"$",
|
|
283
|
+
(e.budget / 1e6).toFixed(1),
|
|
284
|
+
"M"
|
|
285
|
+
]
|
|
286
|
+
})
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
key: "status",
|
|
290
|
+
header: "Status",
|
|
291
|
+
priority: "primary",
|
|
292
|
+
cell: (e) => /* @__PURE__ */ c(u, {
|
|
299
293
|
variant: e.status === "active" ? "default" : "secondary",
|
|
300
294
|
children: e.status
|
|
301
295
|
})
|
|
302
|
-
}
|
|
303
|
-
]
|
|
304
|
-
|
|
296
|
+
}
|
|
297
|
+
],
|
|
298
|
+
data: x,
|
|
299
|
+
rowKey: (e) => e.id
|
|
300
|
+
}) })] })
|
|
305
301
|
]
|
|
306
302
|
});
|
|
307
303
|
}
|
|
308
304
|
//#endregion
|
|
309
|
-
export {
|
|
305
|
+
export { b as DashboardAnalyticsPagePage };
|
|
310
306
|
|
|
311
307
|
//# sourceMappingURL=DashboardAnalyticsPagePage.js.map
|