@burdenoff/microfe-crewfoundry 2026.1029.2 → 2026.1030.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/crewfoundry/components/EmployeeSkillsPanel.d.ts +12 -0
- package/dist/crewfoundry/components/EmployeeSkillsPanel.d.ts.map +1 -0
- package/dist/crewfoundry/components/EmployeeSkillsPanel.js +168 -0
- package/dist/crewfoundry/components/EmployeeSkillsPanel.js.map +1 -0
- package/dist/crewfoundry/lib/useFocusedRecordParam.d.ts +51 -0
- package/dist/crewfoundry/lib/useFocusedRecordParam.d.ts.map +1 -0
- package/dist/crewfoundry/lib/useFocusedRecordParam.js +38 -0
- package/dist/crewfoundry/lib/useFocusedRecordParam.js.map +1 -0
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +119 -112
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +78 -71
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +88 -81
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +133 -126
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +150 -143
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +110 -103
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.js +124 -134
- package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +173 -162
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +169 -158
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +179 -163
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.d.ts +22 -0
- package/dist/crewfoundry/store/crewfoundryStore.d.ts.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +158 -129
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/dist/utils/pageContext.d.ts +43 -4
- package/dist/utils/pageContext.d.ts.map +1 -1
- package/dist/utils/pageContext.js +10 -3
- package/dist/utils/pageContext.js.map +1 -1
- package/package.json +3 -2
|
@@ -5,12 +5,13 @@ import { AvatarStack as r } from "../components/viz/AvatarStack.js";
|
|
|
5
5
|
import { SegmentedTabs as ee } from "../components/viz/SegmentedTabs.js";
|
|
6
6
|
import "../components/viz/index.js";
|
|
7
7
|
import { FormModal as te, useFormModal as i } from "../components/forms/FormModal.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
8
|
+
import { useFocusedRecordParam as a } from "../lib/useFocusedRecordParam.js";
|
|
9
|
+
import { clientRevenue as o, totalContractValue as s } from "../lib/companyFinance.js";
|
|
10
|
+
import { useState as c } from "react";
|
|
11
|
+
import { MoreHorizontal as l, Pencil as ne, Plus as re, Search as ie, Trash2 as ae } from "lucide-react";
|
|
12
|
+
import { useNavigate as oe } from "react-router";
|
|
13
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
14
|
+
import { AlertDialog as se, AlertDialogAction as ce, AlertDialogCancel as le, AlertDialogContent as ue, AlertDialogDescription as f, AlertDialogFooter as p, AlertDialogHeader as m, AlertDialogTitle as h, Badge as g, Button as _, Card as v, CardContent as y, CardHeader as b, CardTitle as x, DropdownMenu as S, DropdownMenuContent as C, DropdownMenuItem as w, DropdownMenuSeparator as T, DropdownMenuTrigger as E, GradientText as D, IllustratedEmptyState as O, Input as k, PagePurpose as A, Pagination as j, ResponsiveTable as M, Select as N, SelectContent as P, SelectItem as F, SelectTrigger as de, SelectValue as I } from "@burdenoff/fe-libs/ui";
|
|
14
15
|
import { usePagination as L } from "@burdenoff/fe-libs/shared/hooks";
|
|
15
16
|
//#region src/crewfoundry/pages/CompanyClientManagementPagePage.tsx
|
|
16
17
|
var R = [
|
|
@@ -97,21 +98,27 @@ var R = [
|
|
|
97
98
|
since: String(e.since ?? "")
|
|
98
99
|
}), V = (e) => e === "active" ? "default" : e === "prospect" ? "secondary" : "destructive", H = (e) => e >= 1e6 ? `$${(e / 1e6).toFixed(1)}M` : e >= 1e3 ? `$${Math.round(e / 1e3)}k` : `$${Math.round(e)}`;
|
|
99
100
|
function U() {
|
|
100
|
-
let { clients: U, vendors: W, addClient:
|
|
101
|
+
let { clients: U, vendors: W, addClient: fe, updateClient: pe, removeClient: me } = e(), he = oe(), G = i();
|
|
102
|
+
a({
|
|
103
|
+
records: U,
|
|
104
|
+
activeId: G.open ? G.context?.id ?? null : null,
|
|
105
|
+
onRestore: G.openModal
|
|
106
|
+
});
|
|
107
|
+
let [K, ge] = c(""), [q, _e] = c("all"), [J, Y] = c(null), { page: ve, pageSize: X, offset: Z, setPage: Q } = L({ initialPageSize: 25 }), ye = U.filter((e) => e.status === "active"), be = s(U, W), xe = o(U), $ = U.filter((e) => {
|
|
101
108
|
let t = `${e.name} ${e.industry} ${e.contactPerson} ${e.email}`.toLowerCase().includes(K.toLowerCase()), n = q === "all" || e.status === q;
|
|
102
109
|
return t && n;
|
|
103
|
-
}),
|
|
104
|
-
return /* @__PURE__ */
|
|
110
|
+
}), Se = $.slice(Z, Z + X);
|
|
111
|
+
return /* @__PURE__ */ d("div", {
|
|
105
112
|
className: "space-y-6 p-6",
|
|
106
113
|
children: [
|
|
107
|
-
/* @__PURE__ */
|
|
114
|
+
/* @__PURE__ */ d("div", {
|
|
108
115
|
className: "flex items-center justify-between",
|
|
109
|
-
children: [/* @__PURE__ */
|
|
110
|
-
/* @__PURE__ */
|
|
116
|
+
children: [/* @__PURE__ */ d("div", { children: [
|
|
117
|
+
/* @__PURE__ */ u("h1", {
|
|
111
118
|
className: "text-2xl font-semibold",
|
|
112
|
-
children: /* @__PURE__ */
|
|
119
|
+
children: /* @__PURE__ */ u(D, { children: "Clients & Vendors" })
|
|
113
120
|
}),
|
|
114
|
-
/* @__PURE__ */
|
|
121
|
+
/* @__PURE__ */ d("p", {
|
|
115
122
|
className: "text-sm text-text-secondary",
|
|
116
123
|
children: [
|
|
117
124
|
U.length,
|
|
@@ -120,22 +127,22 @@ function U() {
|
|
|
120
127
|
" vendors"
|
|
121
128
|
]
|
|
122
129
|
}),
|
|
123
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ u(A, {
|
|
124
131
|
className: "mt-1",
|
|
125
132
|
children: "Keep track of the clients you work with — their contacts, status, and engagements — so account relationships never slip through the cracks."
|
|
126
133
|
})
|
|
127
|
-
] }), /* @__PURE__ */
|
|
134
|
+
] }), /* @__PURE__ */ d(_, {
|
|
128
135
|
size: "sm",
|
|
129
136
|
onClick: () => G.openModal(),
|
|
130
|
-
children: [/* @__PURE__ */
|
|
137
|
+
children: [/* @__PURE__ */ u(re, { className: "h-4 w-4 mr-1" }), "Add Client"]
|
|
131
138
|
})]
|
|
132
139
|
}),
|
|
133
|
-
/* @__PURE__ */
|
|
140
|
+
/* @__PURE__ */ u(ee, {
|
|
134
141
|
"aria-label": "Clients and vendors",
|
|
135
142
|
variant: "underline",
|
|
136
143
|
value: "clients",
|
|
137
144
|
onChange: (e) => {
|
|
138
|
-
e === "vendors" &&
|
|
145
|
+
e === "vendors" && he("../company/vendor-management-page");
|
|
139
146
|
},
|
|
140
147
|
tabs: [{
|
|
141
148
|
id: "clients",
|
|
@@ -147,90 +154,90 @@ function U() {
|
|
|
147
154
|
count: W.length
|
|
148
155
|
}]
|
|
149
156
|
}),
|
|
150
|
-
/* @__PURE__ */
|
|
157
|
+
/* @__PURE__ */ d("div", {
|
|
151
158
|
className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-4",
|
|
152
159
|
children: [
|
|
153
|
-
/* @__PURE__ */
|
|
160
|
+
/* @__PURE__ */ u(n, {
|
|
154
161
|
label: "Active Clients",
|
|
155
|
-
value:
|
|
162
|
+
value: ye.length
|
|
156
163
|
}),
|
|
157
|
-
/* @__PURE__ */
|
|
164
|
+
/* @__PURE__ */ u(n, {
|
|
158
165
|
label: "Vendors",
|
|
159
166
|
value: W.length
|
|
160
167
|
}),
|
|
161
|
-
/* @__PURE__ */
|
|
168
|
+
/* @__PURE__ */ u(n, {
|
|
162
169
|
label: "Total Contract Value",
|
|
163
|
-
value: H(
|
|
170
|
+
value: H(be)
|
|
164
171
|
}),
|
|
165
|
-
/* @__PURE__ */
|
|
172
|
+
/* @__PURE__ */ u(n, {
|
|
166
173
|
label: "Client Revenue",
|
|
167
|
-
value: H(
|
|
174
|
+
value: H(xe)
|
|
168
175
|
})
|
|
169
176
|
]
|
|
170
177
|
}),
|
|
171
|
-
/* @__PURE__ */
|
|
178
|
+
/* @__PURE__ */ d(v, { children: [/* @__PURE__ */ u(b, { children: /* @__PURE__ */ u(x, { children: "Client Portfolio" }) }), /* @__PURE__ */ d(y, {
|
|
172
179
|
className: "space-y-4",
|
|
173
180
|
children: [
|
|
174
|
-
/* @__PURE__ */
|
|
181
|
+
/* @__PURE__ */ d("div", {
|
|
175
182
|
className: "flex flex-col gap-2 sm:flex-row sm:items-center",
|
|
176
|
-
children: [/* @__PURE__ */
|
|
183
|
+
children: [/* @__PURE__ */ d("div", {
|
|
177
184
|
className: "relative flex-1",
|
|
178
|
-
children: [/* @__PURE__ */
|
|
185
|
+
children: [/* @__PURE__ */ u(ie, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ u(k, {
|
|
179
186
|
placeholder: "Search clients...",
|
|
180
187
|
className: "pl-9",
|
|
181
188
|
value: K,
|
|
182
189
|
onChange: (e) => {
|
|
183
|
-
|
|
190
|
+
ge(e.target.value), Q(1);
|
|
184
191
|
}
|
|
185
192
|
})]
|
|
186
|
-
}), /* @__PURE__ */
|
|
193
|
+
}), /* @__PURE__ */ d(N, {
|
|
187
194
|
value: q,
|
|
188
195
|
onValueChange: (e) => {
|
|
189
|
-
|
|
196
|
+
_e(e), Q(1);
|
|
190
197
|
},
|
|
191
|
-
children: [/* @__PURE__ */
|
|
198
|
+
children: [/* @__PURE__ */ u(de, {
|
|
192
199
|
className: "w-full sm:w-40",
|
|
193
200
|
"aria-label": "Filter by status",
|
|
194
|
-
children: /* @__PURE__ */
|
|
195
|
-
}), /* @__PURE__ */
|
|
196
|
-
/* @__PURE__ */
|
|
201
|
+
children: /* @__PURE__ */ u(I, {})
|
|
202
|
+
}), /* @__PURE__ */ d(P, { children: [
|
|
203
|
+
/* @__PURE__ */ u(F, {
|
|
197
204
|
value: "all",
|
|
198
205
|
children: "All statuses"
|
|
199
206
|
}),
|
|
200
|
-
/* @__PURE__ */
|
|
207
|
+
/* @__PURE__ */ u(F, {
|
|
201
208
|
value: "active",
|
|
202
209
|
children: "Active"
|
|
203
210
|
}),
|
|
204
|
-
/* @__PURE__ */
|
|
211
|
+
/* @__PURE__ */ u(F, {
|
|
205
212
|
value: "prospect",
|
|
206
213
|
children: "Prospect"
|
|
207
214
|
}),
|
|
208
|
-
/* @__PURE__ */
|
|
215
|
+
/* @__PURE__ */ u(F, {
|
|
209
216
|
value: "churned",
|
|
210
217
|
children: "Churned"
|
|
211
218
|
})
|
|
212
219
|
] })]
|
|
213
220
|
})]
|
|
214
221
|
}),
|
|
215
|
-
/* @__PURE__ */
|
|
216
|
-
data:
|
|
222
|
+
/* @__PURE__ */ u(M, {
|
|
223
|
+
data: Se,
|
|
217
224
|
rowKey: (e) => e.id,
|
|
218
225
|
columns: [
|
|
219
226
|
{
|
|
220
227
|
key: "name",
|
|
221
228
|
header: "Client",
|
|
222
229
|
priority: "primary",
|
|
223
|
-
cell: (e) => /* @__PURE__ */
|
|
230
|
+
cell: (e) => /* @__PURE__ */ d("div", {
|
|
224
231
|
className: "flex items-center gap-3",
|
|
225
|
-
children: [/* @__PURE__ */
|
|
232
|
+
children: [/* @__PURE__ */ u(r, {
|
|
226
233
|
people: [{ name: e.name }],
|
|
227
234
|
size: 36
|
|
228
|
-
}), /* @__PURE__ */
|
|
235
|
+
}), /* @__PURE__ */ d("div", {
|
|
229
236
|
className: "min-w-0",
|
|
230
|
-
children: [/* @__PURE__ */
|
|
237
|
+
children: [/* @__PURE__ */ u("p", {
|
|
231
238
|
className: "truncate font-medium",
|
|
232
239
|
children: e.name
|
|
233
|
-
}), /* @__PURE__ */
|
|
240
|
+
}), /* @__PURE__ */ u("p", {
|
|
234
241
|
className: "truncate text-xs text-text-secondary",
|
|
235
242
|
children: e.industry || "—"
|
|
236
243
|
})]
|
|
@@ -241,10 +248,10 @@ function U() {
|
|
|
241
248
|
key: "contact",
|
|
242
249
|
header: "Primary Contact",
|
|
243
250
|
priority: "secondary",
|
|
244
|
-
cell: (e) => /* @__PURE__ */
|
|
251
|
+
cell: (e) => /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
|
|
245
252
|
className: "text-xs",
|
|
246
253
|
children: e.contactPerson || "—"
|
|
247
|
-
}), /* @__PURE__ */
|
|
254
|
+
}), /* @__PURE__ */ u("p", {
|
|
248
255
|
className: "text-xs text-text-secondary",
|
|
249
256
|
children: e.email
|
|
250
257
|
})] })
|
|
@@ -253,7 +260,7 @@ function U() {
|
|
|
253
260
|
key: "status",
|
|
254
261
|
header: "Status",
|
|
255
262
|
priority: "secondary",
|
|
256
|
-
cell: (e) => /* @__PURE__ */
|
|
263
|
+
cell: (e) => /* @__PURE__ */ u(g, {
|
|
257
264
|
variant: V(e.status),
|
|
258
265
|
className: "text-[10px]",
|
|
259
266
|
children: t(e.status)
|
|
@@ -265,7 +272,7 @@ function U() {
|
|
|
265
272
|
priority: "hidden-on-mobile",
|
|
266
273
|
headerClassName: "text-right",
|
|
267
274
|
cellClassName: "text-right",
|
|
268
|
-
cell: (e) => /* @__PURE__ */
|
|
275
|
+
cell: (e) => /* @__PURE__ */ u("span", {
|
|
269
276
|
className: "tabular-nums",
|
|
270
277
|
children: e.projects
|
|
271
278
|
})
|
|
@@ -276,54 +283,54 @@ function U() {
|
|
|
276
283
|
priority: "secondary",
|
|
277
284
|
headerClassName: "text-right",
|
|
278
285
|
cellClassName: "text-right",
|
|
279
|
-
cell: (e) => /* @__PURE__ */
|
|
286
|
+
cell: (e) => /* @__PURE__ */ d("span", {
|
|
280
287
|
className: "tabular-nums",
|
|
281
288
|
children: ["$", e.revenue.toLocaleString()]
|
|
282
289
|
})
|
|
283
290
|
}
|
|
284
291
|
],
|
|
285
|
-
emptyState: /* @__PURE__ */
|
|
292
|
+
emptyState: /* @__PURE__ */ u(O, {
|
|
286
293
|
illustration: "empty-search",
|
|
287
294
|
title: "No clients match",
|
|
288
295
|
description: "Try a different search term or status filter."
|
|
289
296
|
}),
|
|
290
|
-
rowActions: (e) => /* @__PURE__ */
|
|
297
|
+
rowActions: (e) => /* @__PURE__ */ u("div", {
|
|
291
298
|
className: "flex items-center justify-end",
|
|
292
|
-
children: /* @__PURE__ */
|
|
299
|
+
children: /* @__PURE__ */ d(S, { children: [/* @__PURE__ */ u(E, {
|
|
293
300
|
asChild: !0,
|
|
294
|
-
children: /* @__PURE__ */
|
|
301
|
+
children: /* @__PURE__ */ u(_, {
|
|
295
302
|
variant: "ghost",
|
|
296
303
|
size: "icon",
|
|
297
304
|
className: "h-8 w-8",
|
|
298
305
|
"aria-label": `More actions for ${e.name}`,
|
|
299
|
-
children: /* @__PURE__ */
|
|
306
|
+
children: /* @__PURE__ */ u(l, { className: "h-4 w-4" })
|
|
300
307
|
})
|
|
301
|
-
}), /* @__PURE__ */
|
|
308
|
+
}), /* @__PURE__ */ d(C, {
|
|
302
309
|
align: "end",
|
|
303
310
|
children: [
|
|
304
|
-
/* @__PURE__ */
|
|
311
|
+
/* @__PURE__ */ d(w, {
|
|
305
312
|
onSelect: () => G.openModal(e),
|
|
306
|
-
children: [/* @__PURE__ */
|
|
313
|
+
children: [/* @__PURE__ */ u(ne, { className: "mr-2 h-4 w-4" }), "Edit"]
|
|
307
314
|
}),
|
|
308
|
-
/* @__PURE__ */
|
|
309
|
-
/* @__PURE__ */
|
|
315
|
+
/* @__PURE__ */ u(T, {}),
|
|
316
|
+
/* @__PURE__ */ d(w, {
|
|
310
317
|
className: "text-status-error-text",
|
|
311
318
|
onSelect: () => Y(e),
|
|
312
|
-
children: [/* @__PURE__ */
|
|
319
|
+
children: [/* @__PURE__ */ u(ae, { className: "mr-2 h-4 w-4" }), "Delete"]
|
|
313
320
|
})
|
|
314
321
|
]
|
|
315
322
|
})] })
|
|
316
323
|
})
|
|
317
324
|
}),
|
|
318
|
-
$.length > X && /* @__PURE__ */
|
|
319
|
-
page:
|
|
325
|
+
$.length > X && /* @__PURE__ */ u(j, {
|
|
326
|
+
page: ve,
|
|
320
327
|
pageSize: X,
|
|
321
328
|
totalItems: $.length,
|
|
322
329
|
onPageChange: Q
|
|
323
330
|
})
|
|
324
331
|
]
|
|
325
332
|
})] }),
|
|
326
|
-
/* @__PURE__ */
|
|
333
|
+
/* @__PURE__ */ u(te, {
|
|
327
334
|
open: G.open,
|
|
328
335
|
onOpenChange: G.onOpenChange,
|
|
329
336
|
title: G.context ? "Edit client" : "Add client",
|
|
@@ -332,17 +339,17 @@ function U() {
|
|
|
332
339
|
initialValues: G.context ? z(G.context) : void 0,
|
|
333
340
|
submitLabel: G.context ? "Save changes" : "Add client",
|
|
334
341
|
onSubmit: async (e) => {
|
|
335
|
-
G.context ? await
|
|
342
|
+
G.context ? await pe(G.context.id, B(e, G.context)) : await fe(B(e));
|
|
336
343
|
}
|
|
337
344
|
}),
|
|
338
|
-
/* @__PURE__ */
|
|
345
|
+
/* @__PURE__ */ u(se, {
|
|
339
346
|
open: J !== null,
|
|
340
347
|
onOpenChange: (e) => {
|
|
341
348
|
e || Y(null);
|
|
342
349
|
},
|
|
343
|
-
children: /* @__PURE__ */
|
|
350
|
+
children: /* @__PURE__ */ d(ue, { children: [/* @__PURE__ */ d(m, { children: [/* @__PURE__ */ u(h, { children: "Delete client?" }), /* @__PURE__ */ u(f, { children: J ? `This removes “${J.name}” from your client portfolio. This action cannot be undone.` : "" })] }), /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ u(le, { children: "Cancel" }), /* @__PURE__ */ u(ce, {
|
|
344
351
|
onClick: (e) => {
|
|
345
|
-
e.preventDefault(), J &&
|
|
352
|
+
e.preventDefault(), J && me(J.id), Y(null);
|
|
346
353
|
},
|
|
347
354
|
children: "Delete"
|
|
348
355
|
})] })] })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompanyClientManagementPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CompanyClientManagementPagePage.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 Card,\n CardContent,\n CardHeader,\n CardTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n Pagination,\n ResponsiveTable,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { MoreHorizontal, Pencil, Plus, Search, Trash2 } from 'lucide-react';\nimport { useNavigate } from 'react-router';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Client } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\nimport { AvatarStack, SegmentedTabs, StatCard } from '../components/viz';\nimport { clientRevenue, totalContractValue } from '../lib/companyFinance';\n\nconst CLIENT_FIELDS: FieldConfig[] = [\n { name: 'name', label: 'Client name', type: 'text', required: true },\n { name: 'industry', label: 'Industry', type: 'text' },\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: 'Prospect', value: 'prospect' },\n { label: 'Churned', value: 'churned' },\n ],\n },\n { name: 'revenue', label: 'Revenue (USD)', type: 'number' },\n { name: 'projects', label: 'Projects', type: 'number' },\n { name: 'since', label: 'Client since', type: 'date' },\n];\n\nconst toInitialValues = (client: Client): FormValues => ({\n name: client.name,\n industry: client.industry,\n contactPerson: client.contactPerson,\n email: client.email,\n phone: client.phone,\n status: client.status,\n revenue: client.revenue,\n projects: client.projects,\n since: client.since ? client.since.slice(0, 10) : '',\n});\n\nconst valuesToClient = (values: FormValues, base?: Client): Client => ({\n id: base?.id ?? crypto.randomUUID(),\n name: String(values.name ?? ''),\n industry: String(values.industry ?? ''),\n contactPerson: String(values.contactPerson ?? ''),\n email: String(values.email ?? ''),\n phone: String(values.phone ?? ''),\n status: (values.status as Client['status']) || 'prospect',\n revenue: typeof values.revenue === 'number' ? values.revenue : Number(values.revenue) || 0,\n projects: typeof values.projects === 'number' ? values.projects : Number(values.projects) || 0,\n since: String(values.since ?? ''),\n});\n\nconst statusVariant = (status: Client['status']) =>\n status === 'active' ? 'default' : status === 'prospect' ? 'secondary' : 'destructive';\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 CompanyClientManagementPagePage() {\n const { clients, vendors, addClient, updateClient, removeClient } = useCrewFoundryStore();\n const navigate = useNavigate();\n const modal = useFormModal<Client>();\n const [search, setSearch] = useState('');\n const [filterStatus, setFilterStatus] = useState<string>('all');\n const [deleteTarget, setDeleteTarget] = useState<Client | null>(null);\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 25 });\n\n const activeClients = clients.filter((c) => c.status === 'active');\n const contractValue = totalContractValue(clients, vendors);\n const revenue = clientRevenue(clients);\n\n const filtered = clients.filter((c) => {\n const matchSearch = `${c.name} ${c.industry} ${c.contactPerson} ${c.email}`\n .toLowerCase()\n .includes(search.toLowerCase());\n const matchStatus = filterStatus === 'all' || c.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 updateClient(modal.context.id, valuesToClient(values, modal.context));\n } else {\n await addClient(valuesToClient(values));\n }\n };\n\n const columns: ResponsiveTableColumn<Client>[] = [\n {\n key: 'name',\n header: 'Client',\n priority: 'primary',\n cell: (c) => (\n <div className=\"flex items-center gap-3\">\n <AvatarStack people={[{ name: c.name }]} size={36} />\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium\">{c.name}</p>\n <p className=\"truncate text-xs text-text-secondary\">{c.industry || '—'}</p>\n </div>\n </div>\n ),\n },\n {\n key: 'contact',\n header: 'Primary Contact',\n priority: 'secondary',\n cell: (c) => (\n <div>\n <p className=\"text-xs\">{c.contactPerson || '—'}</p>\n <p className=\"text-xs text-text-secondary\">{c.email}</p>\n </div>\n ),\n },\n {\n key: 'status',\n header: 'Status',\n priority: 'secondary',\n cell: (c) => (\n <Badge variant={statusVariant(c.status)} className=\"text-[10px]\">\n {formatEnumLabel(c.status)}\n </Badge>\n ),\n },\n {\n key: 'projects',\n header: 'Projects',\n priority: 'hidden-on-mobile',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (c) => <span className=\"tabular-nums\">{c.projects}</span>,\n },\n {\n key: 'revenue',\n header: 'Value',\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (c) => <span className=\"tabular-nums\">${c.revenue.toLocaleString()}</span>,\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 Keep track of the clients you work with — their contacts, status, and engagements — so\n account relationships never slip through the cracks.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => modal.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Client\n </Button>\n </div>\n\n <SegmentedTabs\n aria-label=\"Clients and vendors\"\n variant=\"underline\"\n value=\"clients\"\n onChange={(id) => {\n if (id === 'vendors') {\n navigate('../company/vendor-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=\"Client Revenue\" value={compactMoney(revenue)} />\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Client Portfolio</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\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 clients...\"\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=\"prospect\">Prospect</SelectItem>\n <SelectItem value=\"churned\">Churned</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <ResponsiveTable\n data={paged}\n rowKey={(c) => c.id}\n columns={columns}\n emptyState={\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No clients match\"\n description=\"Try a different search term or status filter.\"\n />\n }\n rowActions={(c) => (\n <div className=\"flex items-center justify-end\">\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 ${c.name}`}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onSelect={() => modal.openModal(c)}>\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(c)}\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n )}\n />\n {filtered.length > pageSize && (\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={filtered.length}\n onPageChange={setPage}\n />\n )}\n </CardContent>\n </Card>\n\n <FormModal\n open={modal.open}\n onOpenChange={modal.onOpenChange}\n title={modal.context ? 'Edit client' : 'Add client'}\n description=\"Track the client relationship, contacts, and engagement value.\"\n fields={CLIENT_FIELDS}\n initialValues={modal.context ? toInitialValues(modal.context) : undefined}\n submitLabel={modal.context ? 'Save changes' : 'Add client'}\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 client?</AlertDialogTitle>\n <AlertDialogDescription>\n {deleteTarget\n ? `This removes “${deleteTarget.name}” from your client portfolio. 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 removeClient(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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"}
|
|
1
|
+
{"version":3,"file":"CompanyClientManagementPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CompanyClientManagementPagePage.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 Card,\n CardContent,\n CardHeader,\n CardTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n Pagination,\n ResponsiveTable,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { MoreHorizontal, Pencil, Plus, Search, Trash2 } from 'lucide-react';\nimport { useNavigate } from 'react-router';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Client } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\nimport { useFocusedRecordParam } from '../lib/useFocusedRecordParam';\nimport { AvatarStack, SegmentedTabs, StatCard } from '../components/viz';\nimport { clientRevenue, totalContractValue } from '../lib/companyFinance';\n\nconst CLIENT_FIELDS: FieldConfig[] = [\n { name: 'name', label: 'Client name', type: 'text', required: true },\n { name: 'industry', label: 'Industry', type: 'text' },\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: 'Prospect', value: 'prospect' },\n { label: 'Churned', value: 'churned' },\n ],\n },\n { name: 'revenue', label: 'Revenue (USD)', type: 'number' },\n { name: 'projects', label: 'Projects', type: 'number' },\n { name: 'since', label: 'Client since', type: 'date' },\n];\n\nconst toInitialValues = (client: Client): FormValues => ({\n name: client.name,\n industry: client.industry,\n contactPerson: client.contactPerson,\n email: client.email,\n phone: client.phone,\n status: client.status,\n revenue: client.revenue,\n projects: client.projects,\n since: client.since ? client.since.slice(0, 10) : '',\n});\n\nconst valuesToClient = (values: FormValues, base?: Client): Client => ({\n id: base?.id ?? crypto.randomUUID(),\n name: String(values.name ?? ''),\n industry: String(values.industry ?? ''),\n contactPerson: String(values.contactPerson ?? ''),\n email: String(values.email ?? ''),\n phone: String(values.phone ?? ''),\n status: (values.status as Client['status']) || 'prospect',\n revenue: typeof values.revenue === 'number' ? values.revenue : Number(values.revenue) || 0,\n projects: typeof values.projects === 'number' ? values.projects : Number(values.projects) || 0,\n since: String(values.since ?? ''),\n});\n\nconst statusVariant = (status: Client['status']) =>\n status === 'active' ? 'default' : status === 'prospect' ? 'secondary' : 'destructive';\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 CompanyClientManagementPagePage() {\n const { clients, vendors, addClient, updateClient, removeClient } = useCrewFoundryStore();\n const navigate = useNavigate();\n const modal = useFormModal<Client>();\n // The client open in the edit dialog is \"this client\" for the assistant.\n useFocusedRecordParam({\n records: clients,\n activeId: modal.open ? (modal.context?.id ?? null) : null,\n onRestore: modal.openModal,\n });\n const [search, setSearch] = useState('');\n const [filterStatus, setFilterStatus] = useState<string>('all');\n const [deleteTarget, setDeleteTarget] = useState<Client | null>(null);\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 25 });\n\n const activeClients = clients.filter((c) => c.status === 'active');\n const contractValue = totalContractValue(clients, vendors);\n const revenue = clientRevenue(clients);\n\n const filtered = clients.filter((c) => {\n const matchSearch = `${c.name} ${c.industry} ${c.contactPerson} ${c.email}`\n .toLowerCase()\n .includes(search.toLowerCase());\n const matchStatus = filterStatus === 'all' || c.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 updateClient(modal.context.id, valuesToClient(values, modal.context));\n } else {\n await addClient(valuesToClient(values));\n }\n };\n\n const columns: ResponsiveTableColumn<Client>[] = [\n {\n key: 'name',\n header: 'Client',\n priority: 'primary',\n cell: (c) => (\n <div className=\"flex items-center gap-3\">\n <AvatarStack people={[{ name: c.name }]} size={36} />\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium\">{c.name}</p>\n <p className=\"truncate text-xs text-text-secondary\">{c.industry || '—'}</p>\n </div>\n </div>\n ),\n },\n {\n key: 'contact',\n header: 'Primary Contact',\n priority: 'secondary',\n cell: (c) => (\n <div>\n <p className=\"text-xs\">{c.contactPerson || '—'}</p>\n <p className=\"text-xs text-text-secondary\">{c.email}</p>\n </div>\n ),\n },\n {\n key: 'status',\n header: 'Status',\n priority: 'secondary',\n cell: (c) => (\n <Badge variant={statusVariant(c.status)} className=\"text-[10px]\">\n {formatEnumLabel(c.status)}\n </Badge>\n ),\n },\n {\n key: 'projects',\n header: 'Projects',\n priority: 'hidden-on-mobile',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (c) => <span className=\"tabular-nums\">{c.projects}</span>,\n },\n {\n key: 'revenue',\n header: 'Value',\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (c) => <span className=\"tabular-nums\">${c.revenue.toLocaleString()}</span>,\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 Keep track of the clients you work with — their contacts, status, and engagements — so\n account relationships never slip through the cracks.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => modal.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Client\n </Button>\n </div>\n\n <SegmentedTabs\n aria-label=\"Clients and vendors\"\n variant=\"underline\"\n value=\"clients\"\n onChange={(id) => {\n if (id === 'vendors') {\n navigate('../company/vendor-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=\"Client Revenue\" value={compactMoney(revenue)} />\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Client Portfolio</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\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 clients...\"\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=\"prospect\">Prospect</SelectItem>\n <SelectItem value=\"churned\">Churned</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <ResponsiveTable\n data={paged}\n rowKey={(c) => c.id}\n columns={columns}\n emptyState={\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No clients match\"\n description=\"Try a different search term or status filter.\"\n />\n }\n rowActions={(c) => (\n <div className=\"flex items-center justify-end\">\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 ${c.name}`}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onSelect={() => modal.openModal(c)}>\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(c)}\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n )}\n />\n {filtered.length > pageSize && (\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={filtered.length}\n onPageChange={setPage}\n />\n )}\n </CardContent>\n </Card>\n\n <FormModal\n open={modal.open}\n onOpenChange={modal.onOpenChange}\n title={modal.context ? 'Edit client' : 'Add client'}\n description=\"Track the client relationship, contacts, and engagement value.\"\n fields={CLIENT_FIELDS}\n initialValues={modal.context ? toInitialValues(modal.context) : undefined}\n submitLabel={modal.context ? 'Save changes' : 'Add client'}\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 client?</AlertDialogTitle>\n <AlertDialogDescription>\n {deleteTarget\n ? `This removes “${deleteTarget.name}” from your client portfolio. 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 removeClient(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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompanyVendorManagementPagePage.d.ts","sourceRoot":"","sources":["../../../src/crewfoundry/pages/CompanyVendorManagementPagePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CompanyVendorManagementPagePage.d.ts","sourceRoot":"","sources":["../../../src/crewfoundry/pages/CompanyVendorManagementPagePage.tsx"],"names":[],"mappings":"AAuGA,wBAAgB,+BAA+B,gCAqQ9C"}
|