@burdenoff/microfe-crewfoundry 2026.704.6 → 2026.704.7
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/CrewFoundryRoutes.js +51 -43
- package/dist/crewfoundry/CrewFoundryRoutes.js.map +1 -1
- package/dist/crewfoundry/components/forms/formValues.js +5 -2
- package/dist/crewfoundry/components/forms/formValues.js.map +1 -1
- package/dist/crewfoundry/components/viz/AllocationBar.js +68 -0
- package/dist/crewfoundry/components/viz/AllocationBar.js.map +1 -0
- package/dist/crewfoundry/components/viz/AreaChart.js +102 -0
- package/dist/crewfoundry/components/viz/AreaChart.js.map +1 -0
- package/dist/crewfoundry/components/viz/AvatarStack.js +36 -0
- package/dist/crewfoundry/components/viz/AvatarStack.js.map +1 -0
- package/dist/crewfoundry/components/viz/BarChart.js +83 -0
- package/dist/crewfoundry/components/viz/BarChart.js.map +1 -0
- package/dist/crewfoundry/components/viz/CertificateCard.js +118 -0
- package/dist/crewfoundry/components/viz/CertificateCard.js.map +1 -0
- package/dist/crewfoundry/components/viz/DonutChart.js +109 -0
- package/dist/crewfoundry/components/viz/DonutChart.js.map +1 -0
- package/dist/crewfoundry/components/viz/HBarFunnel.js +54 -0
- package/dist/crewfoundry/components/viz/HBarFunnel.js.map +1 -0
- package/dist/crewfoundry/components/viz/Heatmap.js +91 -0
- package/dist/crewfoundry/components/viz/Heatmap.js.map +1 -0
- package/dist/crewfoundry/components/viz/KanbanBoard.js +50 -0
- package/dist/crewfoundry/components/viz/KanbanBoard.js.map +1 -0
- package/dist/crewfoundry/components/viz/LineChart.js +123 -0
- package/dist/crewfoundry/components/viz/LineChart.js.map +1 -0
- package/dist/crewfoundry/components/viz/OrgTree.js +83 -0
- package/dist/crewfoundry/components/viz/OrgTree.js.map +1 -0
- package/dist/crewfoundry/components/viz/PathSteps.js +68 -0
- package/dist/crewfoundry/components/viz/PathSteps.js.map +1 -0
- package/dist/crewfoundry/components/viz/ProgressRing.js +68 -0
- package/dist/crewfoundry/components/viz/ProgressRing.js.map +1 -0
- package/dist/crewfoundry/components/viz/RatingStars.js +51 -0
- package/dist/crewfoundry/components/viz/RatingStars.js.map +1 -0
- package/dist/crewfoundry/components/viz/SegmentedTabs.js +69 -0
- package/dist/crewfoundry/components/viz/SegmentedTabs.js.map +1 -0
- package/dist/crewfoundry/components/viz/SkillBar.js +3 -0
- package/dist/crewfoundry/components/viz/Sparkline.js +74 -0
- package/dist/crewfoundry/components/viz/Sparkline.js.map +1 -0
- package/dist/crewfoundry/components/viz/StatCard.js +60 -0
- package/dist/crewfoundry/components/viz/StatCard.js.map +1 -0
- package/dist/crewfoundry/components/viz/StepProgress.js +3 -0
- package/dist/crewfoundry/components/viz/Timeline.js +66 -0
- package/dist/crewfoundry/components/viz/Timeline.js.map +1 -0
- package/dist/crewfoundry/components/viz/index.js +23 -0
- package/dist/crewfoundry/components/viz/lib/Avatar.js +30 -0
- package/dist/crewfoundry/components/viz/lib/Avatar.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/CartesianFrame.js +119 -0
- package/dist/crewfoundry/components/viz/lib/CartesianFrame.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/ResponsiveSvg.js +35 -0
- package/dist/crewfoundry/components/viz/lib/ResponsiveSvg.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/format.js +21 -0
- package/dist/crewfoundry/components/viz/lib/format.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/geometry.js +69 -0
- package/dist/crewfoundry/components/viz/lib/geometry.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/hooks.js +39 -0
- package/dist/crewfoundry/components/viz/lib/hooks.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/palette.js +27 -0
- package/dist/crewfoundry/components/viz/lib/palette.js.map +1 -0
- package/dist/crewfoundry/lib/analytics.js +323 -0
- package/dist/crewfoundry/lib/analytics.js.map +1 -0
- package/dist/crewfoundry/lib/companyFinance.js +16 -0
- package/dist/crewfoundry/lib/companyFinance.js.map +1 -0
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +226 -283
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +107 -120
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +122 -162
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +121 -158
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +316 -211
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +75 -27
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +167 -165
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +168 -109
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +401 -290
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +84 -75
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +368 -174
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +236 -201
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +369 -196
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +269 -270
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +210 -110
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +216 -178
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.js +385 -0
- package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.js.map +1 -0
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +189 -130
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +397 -241
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +262 -147
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +345 -167
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +98 -24
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +289 -108
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +221 -114
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +134 -135
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +148 -97
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +264 -157
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +85 -93
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +211 -122
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +94 -54
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +289 -140
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +169 -79
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +296 -125
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsResourcingPagePage.js +187 -0
- package/dist/crewfoundry/pages/ProjectsResourcingPagePage.js.map +1 -0
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +140 -78
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +93 -43
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +250 -98
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/dist/crewfoundry/utils/cn.js +10 -0
- package/dist/crewfoundry/utils/cn.js.map +1 -0
- package/dist/crewfoundry/utils/courseProgress.js +46 -0
- package/dist/crewfoundry/utils/courseProgress.js.map +1 -0
- package/dist/node_modules/clsx/dist/clsx.js +18 -0
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
2
|
import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
3
|
+
import { StatCard as n } from "../components/viz/StatCard.js";
|
|
4
|
+
import { AvatarStack as r } from "../components/viz/AvatarStack.js";
|
|
5
|
+
import { SegmentedTabs as ee } from "../components/viz/SegmentedTabs.js";
|
|
6
|
+
import "../components/viz/index.js";
|
|
7
|
+
import { FormModal as te, useFormModal as i } from "../components/forms/FormModal.js";
|
|
8
|
+
import { thisQuarterRevenue as a, totalContractValue as o } from "../lib/companyFinance.js";
|
|
9
|
+
import { useState as s } from "react";
|
|
10
|
+
import { Mail as c, MoreHorizontal as l, Pencil as u, Plus as d, Search as f, Star as ne, Trash2 as re } from "lucide-react";
|
|
11
|
+
import { useNavigate as ie } from "react-router-dom";
|
|
12
|
+
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
13
|
+
import { AlertDialog as ae, AlertDialogAction as oe, AlertDialogCancel as se, AlertDialogContent as ce, AlertDialogDescription as le, AlertDialogFooter as h, AlertDialogHeader as g, AlertDialogTitle as _, Badge as v, Button as y, CardContent as b, CardHeader as x, CardTitle as S, DropdownMenu as C, DropdownMenuContent as w, DropdownMenuItem as T, DropdownMenuSeparator as E, DropdownMenuTrigger as D, GlassCard as O, GradientText as k, IllustratedEmptyState as A, Input as j, PagePurpose as M, Pagination as N, Select as P, SelectContent as F, SelectItem as I, SelectTrigger as L, SelectValue as R } from "@burdenoff/fe-libs/ui";
|
|
14
|
+
import { usePagination as ue } from "@burdenoff/fe-libs/shared/hooks";
|
|
9
15
|
//#region src/crewfoundry/pages/CompanyVendorManagementPagePage.tsx
|
|
10
|
-
var
|
|
16
|
+
var z = [
|
|
11
17
|
{
|
|
12
18
|
name: "name",
|
|
13
19
|
label: "Vendor name",
|
|
@@ -64,7 +70,7 @@ var L = [
|
|
|
64
70
|
label: "Rating (0-5)",
|
|
65
71
|
type: "number"
|
|
66
72
|
}
|
|
67
|
-
],
|
|
73
|
+
], B = (e) => ({
|
|
68
74
|
name: e.name,
|
|
69
75
|
category: e.category,
|
|
70
76
|
contactPerson: e.contactPerson,
|
|
@@ -73,7 +79,7 @@ var L = [
|
|
|
73
79
|
status: e.status,
|
|
74
80
|
contractValue: e.contractValue,
|
|
75
81
|
rating: e.rating
|
|
76
|
-
}),
|
|
82
|
+
}), V = (e, t) => ({
|
|
77
83
|
id: t?.id ?? crypto.randomUUID(),
|
|
78
84
|
name: String(e.name ?? ""),
|
|
79
85
|
category: String(e.category ?? ""),
|
|
@@ -83,172 +89,213 @@ var L = [
|
|
|
83
89
|
status: e.status || "pending",
|
|
84
90
|
contractValue: typeof e.contractValue == "number" ? e.contractValue : Number(e.contractValue) || 0,
|
|
85
91
|
rating: typeof e.rating == "number" ? e.rating : Number(e.rating) || 0
|
|
86
|
-
})
|
|
87
|
-
function
|
|
88
|
-
let { vendors:
|
|
89
|
-
let t = `${e.name} ${e.category} ${e.contactPerson} ${e.email}`.toLowerCase().includes(
|
|
92
|
+
}), H = (e) => e >= 1e6 ? `$${(e / 1e6).toFixed(1)}M` : e >= 1e3 ? `$${Math.round(e / 1e3)}k` : `$${Math.round(e)}`;
|
|
93
|
+
function U() {
|
|
94
|
+
let { vendors: U, clients: W, invoices: de, addVendor: fe, updateVendor: pe, removeVendor: me } = e(), he = ie(), G = i(), [K, ge] = s(""), [q, _e] = s("all"), [J, Y] = s(null), { page: ve, pageSize: X, offset: Z, setPage: Q } = ue({ initialPageSize: 12 }), ye = W.filter((e) => e.status === "active"), be = o(W, U), xe = a(de), $ = U.filter((e) => {
|
|
95
|
+
let t = `${e.name} ${e.category} ${e.contactPerson} ${e.email}`.toLowerCase().includes(K.toLowerCase()), n = q === "all" || e.status === q;
|
|
90
96
|
return t && n;
|
|
91
|
-
}),
|
|
92
|
-
return /* @__PURE__ */
|
|
97
|
+
}), Se = $.slice(Z, Z + X);
|
|
98
|
+
return /* @__PURE__ */ m("div", {
|
|
93
99
|
className: "space-y-6 p-6",
|
|
94
100
|
children: [
|
|
95
|
-
/* @__PURE__ */
|
|
101
|
+
/* @__PURE__ */ m("div", {
|
|
96
102
|
className: "flex items-center justify-between",
|
|
97
|
-
children: [/* @__PURE__ */
|
|
98
|
-
/* @__PURE__ */
|
|
103
|
+
children: [/* @__PURE__ */ m("div", { children: [
|
|
104
|
+
/* @__PURE__ */ p("h1", {
|
|
99
105
|
className: "text-2xl font-semibold",
|
|
100
|
-
children: /* @__PURE__ */
|
|
106
|
+
children: /* @__PURE__ */ p(k, { children: "Clients & Vendors" })
|
|
101
107
|
}),
|
|
102
|
-
/* @__PURE__ */
|
|
108
|
+
/* @__PURE__ */ m("p", {
|
|
103
109
|
className: "text-sm text-text-secondary",
|
|
104
110
|
children: [
|
|
105
|
-
|
|
106
|
-
"
|
|
107
|
-
|
|
108
|
-
"
|
|
111
|
+
W.length,
|
|
112
|
+
" clients · ",
|
|
113
|
+
U.length,
|
|
114
|
+
" vendors"
|
|
109
115
|
]
|
|
110
116
|
}),
|
|
111
|
-
/* @__PURE__ */
|
|
117
|
+
/* @__PURE__ */ p(M, {
|
|
112
118
|
className: "mt-1",
|
|
113
119
|
children: "Track the vendors and suppliers you depend on — contracts, contacts, and status — to manage external relationships in one place."
|
|
114
120
|
})
|
|
115
|
-
] }), /* @__PURE__ */
|
|
121
|
+
] }), /* @__PURE__ */ m(y, {
|
|
116
122
|
size: "sm",
|
|
117
|
-
onClick: () =>
|
|
118
|
-
children: [/* @__PURE__ */
|
|
123
|
+
onClick: () => G.openModal(),
|
|
124
|
+
children: [/* @__PURE__ */ p(d, { className: "h-4 w-4 mr-1" }), "Add Vendor"]
|
|
119
125
|
})]
|
|
120
126
|
}),
|
|
121
|
-
/* @__PURE__ */
|
|
127
|
+
/* @__PURE__ */ p(ee, {
|
|
128
|
+
"aria-label": "Clients and vendors",
|
|
129
|
+
variant: "underline",
|
|
130
|
+
value: "vendors",
|
|
131
|
+
onChange: (e) => {
|
|
132
|
+
e === "clients" && he("../company/client-management-page");
|
|
133
|
+
},
|
|
134
|
+
tabs: [{
|
|
135
|
+
id: "clients",
|
|
136
|
+
label: "Clients",
|
|
137
|
+
count: W.length
|
|
138
|
+
}, {
|
|
139
|
+
id: "vendors",
|
|
140
|
+
label: "Vendors",
|
|
141
|
+
count: U.length
|
|
142
|
+
}]
|
|
143
|
+
}),
|
|
144
|
+
/* @__PURE__ */ m("div", {
|
|
145
|
+
className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-4",
|
|
146
|
+
children: [
|
|
147
|
+
/* @__PURE__ */ p(n, {
|
|
148
|
+
label: "Active Clients",
|
|
149
|
+
value: ye.length
|
|
150
|
+
}),
|
|
151
|
+
/* @__PURE__ */ p(n, {
|
|
152
|
+
label: "Vendors",
|
|
153
|
+
value: U.length
|
|
154
|
+
}),
|
|
155
|
+
/* @__PURE__ */ p(n, {
|
|
156
|
+
label: "Total Contract Value",
|
|
157
|
+
value: H(be)
|
|
158
|
+
}),
|
|
159
|
+
/* @__PURE__ */ p(n, {
|
|
160
|
+
label: "This Quarter",
|
|
161
|
+
value: H(xe)
|
|
162
|
+
})
|
|
163
|
+
]
|
|
164
|
+
}),
|
|
165
|
+
/* @__PURE__ */ m("div", {
|
|
122
166
|
className: "flex flex-col gap-2 sm:flex-row sm:items-center",
|
|
123
|
-
children: [/* @__PURE__ */
|
|
167
|
+
children: [/* @__PURE__ */ m("div", {
|
|
124
168
|
className: "relative flex-1",
|
|
125
|
-
children: [/* @__PURE__ */
|
|
169
|
+
children: [/* @__PURE__ */ p(f, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ p(j, {
|
|
126
170
|
placeholder: "Search vendors...",
|
|
127
171
|
className: "pl-9",
|
|
128
|
-
value:
|
|
172
|
+
value: K,
|
|
129
173
|
onChange: (e) => {
|
|
130
|
-
|
|
174
|
+
ge(e.target.value), Q(1);
|
|
131
175
|
}
|
|
132
176
|
})]
|
|
133
|
-
}), /* @__PURE__ */
|
|
177
|
+
}), /* @__PURE__ */ m(P, {
|
|
134
178
|
value: q,
|
|
135
179
|
onValueChange: (e) => {
|
|
136
|
-
|
|
180
|
+
_e(e), Q(1);
|
|
137
181
|
},
|
|
138
|
-
children: [/* @__PURE__ */
|
|
182
|
+
children: [/* @__PURE__ */ p(L, {
|
|
139
183
|
className: "w-full sm:w-40",
|
|
140
184
|
"aria-label": "Filter by status",
|
|
141
|
-
children: /* @__PURE__ */
|
|
142
|
-
}), /* @__PURE__ */
|
|
143
|
-
/* @__PURE__ */
|
|
185
|
+
children: /* @__PURE__ */ p(R, {})
|
|
186
|
+
}), /* @__PURE__ */ m(F, { children: [
|
|
187
|
+
/* @__PURE__ */ p(I, {
|
|
144
188
|
value: "all",
|
|
145
189
|
children: "All statuses"
|
|
146
190
|
}),
|
|
147
|
-
/* @__PURE__ */
|
|
191
|
+
/* @__PURE__ */ p(I, {
|
|
148
192
|
value: "active",
|
|
149
193
|
children: "Active"
|
|
150
194
|
}),
|
|
151
|
-
/* @__PURE__ */
|
|
195
|
+
/* @__PURE__ */ p(I, {
|
|
152
196
|
value: "inactive",
|
|
153
197
|
children: "Inactive"
|
|
154
198
|
}),
|
|
155
|
-
/* @__PURE__ */
|
|
199
|
+
/* @__PURE__ */ p(I, {
|
|
156
200
|
value: "pending",
|
|
157
201
|
children: "Pending"
|
|
158
202
|
})
|
|
159
203
|
] })]
|
|
160
204
|
})]
|
|
161
205
|
}),
|
|
162
|
-
/* @__PURE__ */
|
|
206
|
+
/* @__PURE__ */ p("div", {
|
|
163
207
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
164
|
-
children:
|
|
208
|
+
children: U.length === 0 ? /* @__PURE__ */ p("div", {
|
|
165
209
|
className: "col-span-full",
|
|
166
|
-
children: /* @__PURE__ */
|
|
210
|
+
children: /* @__PURE__ */ p(A, {
|
|
167
211
|
illustration: "empty-data",
|
|
168
212
|
title: "No vendors yet",
|
|
169
213
|
description: "Add a vendor to start tracking external relationships."
|
|
170
214
|
})
|
|
171
|
-
}) : $.length === 0 ? /* @__PURE__ */
|
|
215
|
+
}) : $.length === 0 ? /* @__PURE__ */ p("div", {
|
|
172
216
|
className: "col-span-full",
|
|
173
|
-
children: /* @__PURE__ */
|
|
217
|
+
children: /* @__PURE__ */ p(A, {
|
|
174
218
|
illustration: "empty-search",
|
|
175
219
|
title: "No vendors match",
|
|
176
220
|
description: "Try a different search term or status filter."
|
|
177
221
|
})
|
|
178
|
-
}) :
|
|
179
|
-
treatment:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
222
|
+
}) : Se.map((e) => /* @__PURE__ */ m(O, {
|
|
223
|
+
treatment: "glass",
|
|
224
|
+
children: [/* @__PURE__ */ p(x, { children: /* @__PURE__ */ m("div", {
|
|
225
|
+
className: "flex items-center justify-between gap-2",
|
|
226
|
+
children: [/* @__PURE__ */ m("div", {
|
|
227
|
+
className: "flex min-w-0 items-center gap-3",
|
|
228
|
+
children: [/* @__PURE__ */ p(r, {
|
|
229
|
+
people: [{ name: e.name }],
|
|
230
|
+
size: 36
|
|
231
|
+
}), /* @__PURE__ */ p(S, {
|
|
232
|
+
className: "truncate text-base",
|
|
233
|
+
children: e.name
|
|
234
|
+
})]
|
|
235
|
+
}), /* @__PURE__ */ m("div", {
|
|
187
236
|
className: "flex items-center gap-1",
|
|
188
|
-
children: [
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
/* @__PURE__ */
|
|
237
|
+
children: [/* @__PURE__ */ p(v, {
|
|
238
|
+
variant: e.status === "active" ? "default" : "secondary",
|
|
239
|
+
className: "text-[10px]",
|
|
240
|
+
children: t(e.status)
|
|
241
|
+
}), /* @__PURE__ */ m(C, { children: [/* @__PURE__ */ p(D, {
|
|
242
|
+
asChild: !0,
|
|
243
|
+
children: /* @__PURE__ */ p(y, {
|
|
195
244
|
variant: "ghost",
|
|
196
245
|
size: "icon",
|
|
197
|
-
"
|
|
198
|
-
|
|
199
|
-
children: /* @__PURE__ */
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
"
|
|
207
|
-
|
|
246
|
+
className: "h-8 w-8",
|
|
247
|
+
"aria-label": `More actions for ${e.name}`,
|
|
248
|
+
children: /* @__PURE__ */ p(l, { className: "h-4 w-4" })
|
|
249
|
+
})
|
|
250
|
+
}), /* @__PURE__ */ m(w, {
|
|
251
|
+
align: "end",
|
|
252
|
+
children: [
|
|
253
|
+
/* @__PURE__ */ m(T, {
|
|
254
|
+
onSelect: () => G.openModal(e),
|
|
255
|
+
children: [/* @__PURE__ */ p(u, { className: "mr-2 h-4 w-4" }), "Edit"]
|
|
256
|
+
}),
|
|
257
|
+
/* @__PURE__ */ p(E, {}),
|
|
258
|
+
/* @__PURE__ */ m(T, {
|
|
259
|
+
className: "text-status-error-text",
|
|
260
|
+
onSelect: () => Y(e),
|
|
261
|
+
children: [/* @__PURE__ */ p(re, { className: "mr-2 h-4 w-4" }), "Delete"]
|
|
208
262
|
})
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
e.name,
|
|
212
|
-
"” from your vendor directory. This action cannot be undone."
|
|
213
|
-
] })] }), /* @__PURE__ */ d(_, { children: [/* @__PURE__ */ u(m, { children: "Cancel" }), /* @__PURE__ */ u(p, {
|
|
214
|
-
onClick: () => void U(e.id),
|
|
215
|
-
children: "Delete"
|
|
216
|
-
})] })] })] })
|
|
217
|
-
]
|
|
263
|
+
]
|
|
264
|
+
})] })]
|
|
218
265
|
})]
|
|
219
|
-
}) }), /* @__PURE__ */
|
|
266
|
+
}) }), /* @__PURE__ */ p(b, { children: /* @__PURE__ */ m("div", {
|
|
220
267
|
className: "space-y-2",
|
|
221
268
|
children: [
|
|
222
|
-
/* @__PURE__ */
|
|
269
|
+
/* @__PURE__ */ p(v, {
|
|
223
270
|
variant: "outline",
|
|
224
271
|
className: "text-[10px]",
|
|
225
272
|
children: e.category
|
|
226
273
|
}),
|
|
227
|
-
/* @__PURE__ */
|
|
274
|
+
/* @__PURE__ */ m("div", {
|
|
228
275
|
className: "grid grid-cols-2 gap-2 mt-2",
|
|
229
|
-
children: [/* @__PURE__ */
|
|
276
|
+
children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
|
|
230
277
|
className: "text-xs text-text-secondary",
|
|
231
278
|
children: "Contact"
|
|
232
|
-
}), /* @__PURE__ */
|
|
279
|
+
}), /* @__PURE__ */ p("p", {
|
|
233
280
|
className: "text-sm",
|
|
234
|
-
children: e.contactPerson
|
|
235
|
-
})] }), /* @__PURE__ */
|
|
281
|
+
children: e.contactPerson || "—"
|
|
282
|
+
})] }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
|
|
236
283
|
className: "text-xs text-text-secondary",
|
|
237
284
|
children: "Contract Value"
|
|
238
|
-
}), /* @__PURE__ */
|
|
239
|
-
className: "text-sm font-medium",
|
|
285
|
+
}), /* @__PURE__ */ m("p", {
|
|
286
|
+
className: "text-sm font-medium tabular-nums",
|
|
240
287
|
children: ["$", e.contractValue.toLocaleString()]
|
|
241
288
|
})] })]
|
|
242
289
|
}),
|
|
243
|
-
/* @__PURE__ */
|
|
290
|
+
/* @__PURE__ */ m("div", {
|
|
244
291
|
className: "flex items-center justify-between pt-2 border-t mt-2",
|
|
245
|
-
children: [/* @__PURE__ */
|
|
292
|
+
children: [/* @__PURE__ */ m("div", {
|
|
246
293
|
className: "flex items-center gap-1 text-xs text-text-secondary",
|
|
247
|
-
children: [/* @__PURE__ */
|
|
248
|
-
}), /* @__PURE__ */
|
|
294
|
+
children: [/* @__PURE__ */ p(c, { className: "h-3 w-3" }), e.email || "—"]
|
|
295
|
+
}), /* @__PURE__ */ m("div", {
|
|
249
296
|
className: "flex items-center gap-1",
|
|
250
|
-
children: [/* @__PURE__ */
|
|
251
|
-
className: "text-sm",
|
|
297
|
+
children: [/* @__PURE__ */ p(ne, { className: "h-3 w-3 text-status-warning-text" }), /* @__PURE__ */ p("span", {
|
|
298
|
+
className: "text-sm tabular-nums",
|
|
252
299
|
children: e.rating
|
|
253
300
|
})]
|
|
254
301
|
})]
|
|
@@ -257,28 +304,40 @@ function B() {
|
|
|
257
304
|
}) })]
|
|
258
305
|
}, e.id))
|
|
259
306
|
}),
|
|
260
|
-
$.length > X && /* @__PURE__ */
|
|
261
|
-
page:
|
|
307
|
+
$.length > X && /* @__PURE__ */ p(N, {
|
|
308
|
+
page: ve,
|
|
262
309
|
pageSize: X,
|
|
263
310
|
totalItems: $.length,
|
|
264
311
|
onPageChange: Q
|
|
265
312
|
}),
|
|
266
|
-
/* @__PURE__ */
|
|
267
|
-
open:
|
|
268
|
-
onOpenChange:
|
|
269
|
-
title:
|
|
313
|
+
/* @__PURE__ */ p(te, {
|
|
314
|
+
open: G.open,
|
|
315
|
+
onOpenChange: G.onOpenChange,
|
|
316
|
+
title: G.context ? "Edit vendor" : "Add vendor",
|
|
270
317
|
description: "Track the vendor, its contract value, and primary contact.",
|
|
271
|
-
fields:
|
|
272
|
-
initialValues:
|
|
273
|
-
submitLabel:
|
|
318
|
+
fields: z,
|
|
319
|
+
initialValues: G.context ? B(G.context) : void 0,
|
|
320
|
+
submitLabel: G.context ? "Save changes" : "Add vendor",
|
|
274
321
|
onSubmit: async (e) => {
|
|
275
|
-
|
|
322
|
+
G.context ? await pe(G.context.id, V(e, G.context)) : await fe(V(e));
|
|
276
323
|
}
|
|
324
|
+
}),
|
|
325
|
+
/* @__PURE__ */ p(ae, {
|
|
326
|
+
open: J !== null,
|
|
327
|
+
onOpenChange: (e) => {
|
|
328
|
+
e || Y(null);
|
|
329
|
+
},
|
|
330
|
+
children: /* @__PURE__ */ m(ce, { children: [/* @__PURE__ */ m(g, { children: [/* @__PURE__ */ p(_, { children: "Delete vendor?" }), /* @__PURE__ */ p(le, { children: J ? `This removes “${J.name}” from your vendor directory. This action cannot be undone.` : "" })] }), /* @__PURE__ */ m(h, { children: [/* @__PURE__ */ p(se, { children: "Cancel" }), /* @__PURE__ */ p(oe, {
|
|
331
|
+
onClick: (e) => {
|
|
332
|
+
e.preventDefault(), J && me(J.id), Y(null);
|
|
333
|
+
},
|
|
334
|
+
children: "Delete"
|
|
335
|
+
})] })] })
|
|
277
336
|
})
|
|
278
337
|
]
|
|
279
338
|
});
|
|
280
339
|
}
|
|
281
340
|
//#endregion
|
|
282
|
-
export {
|
|
341
|
+
export { U as CompanyVendorManagementPagePage };
|
|
283
342
|
|
|
284
343
|
//# sourceMappingURL=CompanyVendorManagementPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
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';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\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\">\n Track the vendors and suppliers you depend on — contracts, contacts, and status — to\n manage external relationships in one place.\n </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\n illustration=\"empty-data\"\n title=\"No vendors yet\"\n description=\"Add a vendor to start tracking external relationships.\"\n />\n </div>\n ) : filtered.length === 0 ? (\n <div className=\"col-span-full\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No vendors match\"\n description=\"Try a different search term or status filter.\"\n />\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 {formatEnumLabel(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\n 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\">\n ${vendor.contractValue.toLocaleString()}\n </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 )}\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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"}
|
|
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 Badge,\n Button,\n CardContent,\n CardHeader,\n CardTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\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, MoreHorizontal, Pencil, Plus, Search, Star, Trash2 } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Vendor } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\nimport { AvatarStack, SegmentedTabs, StatCard } from '../components/viz';\nimport { totalContractValue, thisQuarterRevenue } from '../lib/companyFinance';\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\nconst compactMoney = (value: number): string => {\n if (value >= 1_000_000) {\n return `$${(value / 1_000_000).toFixed(1)}M`;\n }\n if (value >= 1_000) {\n return `$${Math.round(value / 1_000)}k`;\n }\n return `$${Math.round(value)}`;\n};\n\nexport function CompanyVendorManagementPagePage() {\n const { vendors, clients, invoices, addVendor, updateVendor, removeVendor } =\n useCrewFoundryStore();\n const navigate = useNavigate();\n const modal = useFormModal<Vendor>();\n const [search, setSearch] = useState('');\n const [filterStatus, setFilterStatus] = useState<string>('all');\n const [deleteTarget, setDeleteTarget] = useState<Vendor | null>(null);\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 12 });\n\n const activeClients = clients.filter((c) => c.status === 'active');\n const contractValue = totalContractValue(clients, vendors);\n const quarterRevenue = thisQuarterRevenue(invoices);\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>Clients & Vendors</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {clients.length} clients · {vendors.length} vendors\n </p>\n <PagePurpose className=\"mt-1\">\n Track the vendors and suppliers you depend on — contracts, contacts, and status — to\n manage external relationships in one place.\n </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\n <SegmentedTabs\n aria-label=\"Clients and vendors\"\n variant=\"underline\"\n value=\"vendors\"\n onChange={(id) => {\n if (id === 'clients') {\n navigate('../company/client-management-page');\n }\n }}\n tabs={[\n { id: 'clients', label: 'Clients', count: clients.length },\n { id: 'vendors', label: 'Vendors', count: vendors.length },\n ]}\n />\n\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n <StatCard label=\"Active Clients\" value={activeClients.length} />\n <StatCard label=\"Vendors\" value={vendors.length} />\n <StatCard label=\"Total Contract Value\" value={compactMoney(contractValue)} />\n <StatCard label=\"This Quarter\" value={compactMoney(quarterRevenue)} />\n </div>\n\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\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\n illustration=\"empty-data\"\n title=\"No vendors yet\"\n description=\"Add a vendor to start tracking external relationships.\"\n />\n </div>\n ) : filtered.length === 0 ? (\n <div className=\"col-span-full\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No vendors match\"\n description=\"Try a different search term or status filter.\"\n />\n </div>\n ) : (\n paged.map((vendor) => (\n <GlassCard key={vendor.id} treatment=\"glass\">\n <CardHeader>\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex min-w-0 items-center gap-3\">\n <AvatarStack people={[{ name: vendor.name }]} size={36} />\n <CardTitle className=\"truncate text-base\">{vendor.name}</CardTitle>\n </div>\n <div className=\"flex items-center gap-1\">\n <Badge\n variant={vendor.status === 'active' ? 'default' : 'secondary'}\n className=\"text-[10px]\"\n >\n {formatEnumLabel(vendor.status)}\n </Badge>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n aria-label={`More actions for ${vendor.name}`}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onSelect={() => modal.openModal(vendor)}>\n <Pencil className=\"mr-2 h-4 w-4\" />\n Edit\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"text-status-error-text\"\n onSelect={() => setDeleteTarget(vendor)}\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\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 tabular-nums\">\n ${vendor.contractValue.toLocaleString()}\n </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 tabular-nums\">{vendor.rating}</span>\n </div>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n ))\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\n <AlertDialog\n open={deleteTarget !== null}\n onOpenChange={(open) => {\n if (!open) {\n setDeleteTarget(null);\n }\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete vendor?</AlertDialogTitle>\n <AlertDialogDescription>\n {deleteTarget\n ? `This removes “${deleteTarget.name}” from your vendor directory. This action cannot be undone.`\n : ''}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={(event) => {\n event.preventDefault();\n if (deleteTarget) {\n void removeVendor(deleteTarget.id);\n }\n setDeleteTarget(null);\n }}\n >\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n"],"mappings":"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"}
|