@burdenoff/microfe-crewfoundry 2026.704.5 → 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 +252 -249
- 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 +35 -31
- 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 +136 -133
- 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/MarketplaceFreelancerProfilePageEnhancedPage.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/MarketplaceProjectDetailsPagePage.js +28 -25
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +290 -138
- 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/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +65 -61
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.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 +142 -76
- 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/TeamsTeamSettingsPagePage.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,65 +1,110 @@
|
|
|
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 { getInitials as n } from "../components/viz/lib/format.js";
|
|
4
|
+
import { RatingStars as r } from "../components/viz/RatingStars.js";
|
|
5
|
+
import { SegmentedTabs as i } from "../components/viz/SegmentedTabs.js";
|
|
6
|
+
import "../components/viz/index.js";
|
|
7
|
+
import { useEffect as a, useMemo as o, useState as s } from "react";
|
|
8
|
+
import { Search as c } from "lucide-react";
|
|
9
|
+
import { useNavigate as l } from "react-router-dom";
|
|
10
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
11
|
+
import { Badge as f, CardContent as p, GlassCard as m, GradientText as h, IllustratedEmptyState as g, Input as _, PagePurpose as v, Pagination as y, ResponsiveTable as b } from "@burdenoff/fe-libs/ui";
|
|
12
|
+
import { usePagination as x } from "@burdenoff/fe-libs/shared/hooks";
|
|
9
13
|
//#region src/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.tsx
|
|
10
|
-
function
|
|
11
|
-
let
|
|
12
|
-
|
|
14
|
+
function S() {
|
|
15
|
+
let S = l(), { marketplaceServices: C } = e(), [w, T] = s(""), [E, D] = s("all"), { page: O, pageSize: k, offset: A, setPage: j } = x({ initialPageSize: 10 }), M = o(() => {
|
|
16
|
+
let e = /* @__PURE__ */ new Map();
|
|
17
|
+
for (let t of C) e.set(t.category, (e.get(t.category) ?? 0) + 1);
|
|
18
|
+
let t = [{
|
|
19
|
+
id: "all",
|
|
20
|
+
label: "All",
|
|
21
|
+
count: C.length
|
|
22
|
+
}];
|
|
23
|
+
for (let [n, r] of [...e.entries()].sort((e, t) => e[0].localeCompare(t[0]))) t.push({
|
|
24
|
+
id: n,
|
|
25
|
+
label: n,
|
|
26
|
+
count: r
|
|
27
|
+
});
|
|
28
|
+
return t;
|
|
29
|
+
}, [C]), N = C.filter((e) => E !== "all" && e.category !== E ? !1 : `${e.title} ${e.provider} ${e.category}`.toLowerCase().includes(w.toLowerCase())), P = N.slice(A, A + k);
|
|
30
|
+
return a(() => {
|
|
31
|
+
j(1);
|
|
32
|
+
}, [
|
|
33
|
+
w,
|
|
34
|
+
E,
|
|
35
|
+
j
|
|
36
|
+
]), /* @__PURE__ */ d("div", {
|
|
13
37
|
className: "space-y-6 p-6",
|
|
14
38
|
children: [
|
|
15
|
-
/* @__PURE__ */
|
|
16
|
-
/* @__PURE__ */
|
|
39
|
+
/* @__PURE__ */ d("div", { children: [
|
|
40
|
+
/* @__PURE__ */ u("h1", {
|
|
17
41
|
className: "text-2xl font-semibold",
|
|
18
|
-
children: /* @__PURE__ */
|
|
42
|
+
children: /* @__PURE__ */ u(h, { children: "Browse Services" })
|
|
19
43
|
}),
|
|
20
|
-
/* @__PURE__ */
|
|
44
|
+
/* @__PURE__ */ d("p", {
|
|
21
45
|
className: "text-sm text-text-secondary",
|
|
22
|
-
children: [
|
|
46
|
+
children: [C.length, " services available"]
|
|
23
47
|
}),
|
|
24
|
-
/* @__PURE__ */
|
|
48
|
+
/* @__PURE__ */ u(v, {
|
|
25
49
|
className: "mt-1",
|
|
26
50
|
children: "Explore services offered on the marketplace — search and compare offerings to find exactly the help your project needs."
|
|
27
51
|
})
|
|
28
52
|
] }),
|
|
29
|
-
/* @__PURE__ */
|
|
30
|
-
className: "
|
|
31
|
-
children: [/* @__PURE__ */
|
|
32
|
-
|
|
33
|
-
className: "
|
|
34
|
-
|
|
35
|
-
|
|
53
|
+
/* @__PURE__ */ d("div", {
|
|
54
|
+
className: "flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between",
|
|
55
|
+
children: [/* @__PURE__ */ d("div", {
|
|
56
|
+
className: "relative w-full max-w-sm",
|
|
57
|
+
children: [/* @__PURE__ */ u(c, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ u(_, {
|
|
58
|
+
placeholder: "Search services...",
|
|
59
|
+
className: "pl-9",
|
|
60
|
+
value: w,
|
|
61
|
+
onChange: (e) => T(e.target.value)
|
|
62
|
+
})]
|
|
63
|
+
}), /* @__PURE__ */ u("div", {
|
|
64
|
+
className: "-mx-1 overflow-x-auto px-1 pb-1",
|
|
65
|
+
children: /* @__PURE__ */ u(i, {
|
|
66
|
+
tabs: M,
|
|
67
|
+
value: E,
|
|
68
|
+
onChange: D,
|
|
69
|
+
"aria-label": "Filter services by category"
|
|
70
|
+
})
|
|
36
71
|
})]
|
|
37
72
|
}),
|
|
38
|
-
/* @__PURE__ */
|
|
73
|
+
/* @__PURE__ */ u(m, {
|
|
39
74
|
treatment: "glass",
|
|
40
75
|
glow: !0,
|
|
41
76
|
className: "border-border-seam",
|
|
42
|
-
children: /* @__PURE__ */
|
|
77
|
+
children: /* @__PURE__ */ u(p, {
|
|
43
78
|
className: "p-4",
|
|
44
|
-
children: /* @__PURE__ */
|
|
79
|
+
children: /* @__PURE__ */ u(b, {
|
|
45
80
|
columns: [
|
|
46
81
|
{
|
|
47
82
|
key: "service",
|
|
48
83
|
header: "Service",
|
|
49
84
|
priority: "primary",
|
|
50
|
-
cell: (e) => /* @__PURE__ */
|
|
51
|
-
className: "
|
|
52
|
-
children:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
85
|
+
cell: (e) => /* @__PURE__ */ d("div", {
|
|
86
|
+
className: "flex items-center gap-2.5",
|
|
87
|
+
children: [/* @__PURE__ */ u("span", {
|
|
88
|
+
className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-action-primary-bg text-[11px] font-semibold text-action-primary-text",
|
|
89
|
+
"aria-hidden": "true",
|
|
90
|
+
children: n(e.provider)
|
|
91
|
+
}), /* @__PURE__ */ d("div", {
|
|
92
|
+
className: "min-w-0",
|
|
93
|
+
children: [/* @__PURE__ */ u("p", {
|
|
94
|
+
className: "font-medium",
|
|
95
|
+
children: e.title
|
|
96
|
+
}), /* @__PURE__ */ d("p", {
|
|
97
|
+
className: "truncate text-xs text-text-secondary",
|
|
98
|
+
children: [e.description.slice(0, 60), e.description.length > 60 ? "…" : ""]
|
|
99
|
+
})]
|
|
100
|
+
})]
|
|
101
|
+
})
|
|
57
102
|
},
|
|
58
103
|
{
|
|
59
104
|
key: "provider",
|
|
60
105
|
header: "Provider",
|
|
61
106
|
priority: "secondary",
|
|
62
|
-
cell: (e) => /* @__PURE__ */
|
|
107
|
+
cell: (e) => /* @__PURE__ */ u("span", {
|
|
63
108
|
className: "text-text-secondary",
|
|
64
109
|
children: e.provider
|
|
65
110
|
})
|
|
@@ -68,7 +113,7 @@ function v() {
|
|
|
68
113
|
key: "category",
|
|
69
114
|
header: "Category",
|
|
70
115
|
priority: "secondary",
|
|
71
|
-
cell: (e) => /* @__PURE__ */
|
|
116
|
+
cell: (e) => /* @__PURE__ */ u(f, {
|
|
72
117
|
variant: "outline",
|
|
73
118
|
className: "w-fit h-fit text-[10px]",
|
|
74
119
|
children: e.category
|
|
@@ -78,7 +123,7 @@ function v() {
|
|
|
78
123
|
key: "price",
|
|
79
124
|
header: "Price",
|
|
80
125
|
priority: "secondary",
|
|
81
|
-
cell: (e) => /* @__PURE__ */
|
|
126
|
+
cell: (e) => /* @__PURE__ */ d("span", {
|
|
82
127
|
className: "font-medium",
|
|
83
128
|
children: [
|
|
84
129
|
"$",
|
|
@@ -92,32 +137,27 @@ function v() {
|
|
|
92
137
|
key: "rating",
|
|
93
138
|
header: "Rating",
|
|
94
139
|
priority: "secondary",
|
|
95
|
-
cell: (e) => /* @__PURE__ */
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
e.rating,
|
|
100
|
-
" (",
|
|
101
|
-
e.reviews,
|
|
102
|
-
")"
|
|
103
|
-
]
|
|
140
|
+
cell: (e) => /* @__PURE__ */ u(r, {
|
|
141
|
+
value: e.rating,
|
|
142
|
+
count: e.reviews,
|
|
143
|
+
size: 12
|
|
104
144
|
})
|
|
105
145
|
},
|
|
106
146
|
{
|
|
107
147
|
key: "status",
|
|
108
148
|
header: "Status",
|
|
109
149
|
priority: "secondary",
|
|
110
|
-
cell: (e) => /* @__PURE__ */
|
|
150
|
+
cell: (e) => /* @__PURE__ */ u(f, {
|
|
111
151
|
variant: e.status === "active" ? "default" : "secondary",
|
|
112
152
|
className: "text-[10px]",
|
|
113
153
|
children: t(e.status)
|
|
114
154
|
})
|
|
115
155
|
}
|
|
116
156
|
],
|
|
117
|
-
data:
|
|
157
|
+
data: P,
|
|
118
158
|
rowKey: (e) => e.id,
|
|
119
|
-
onRowClick: (e) =>
|
|
120
|
-
emptyState: /* @__PURE__ */
|
|
159
|
+
onRowClick: (e) => S(`../marketplace/service-details-page?id=${e.id}`),
|
|
160
|
+
emptyState: /* @__PURE__ */ u(g, {
|
|
121
161
|
illustration: "empty-search",
|
|
122
162
|
title: "No services found",
|
|
123
163
|
description: "Try a different search term to find the help you need."
|
|
@@ -125,16 +165,16 @@ function v() {
|
|
|
125
165
|
})
|
|
126
166
|
})
|
|
127
167
|
}),
|
|
128
|
-
|
|
129
|
-
page:
|
|
130
|
-
pageSize:
|
|
131
|
-
totalItems:
|
|
132
|
-
onPageChange:
|
|
168
|
+
N.length > 0 ? /* @__PURE__ */ u(y, {
|
|
169
|
+
page: O,
|
|
170
|
+
pageSize: k,
|
|
171
|
+
totalItems: N.length,
|
|
172
|
+
onPageChange: j
|
|
133
173
|
}) : null
|
|
134
174
|
]
|
|
135
175
|
});
|
|
136
176
|
}
|
|
137
177
|
//#endregion
|
|
138
|
-
export {
|
|
178
|
+
export { S as MarketplaceMarketplaceServicesPagePage };
|
|
139
179
|
|
|
140
180
|
//# sourceMappingURL=MarketplaceMarketplaceServicesPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarketplaceMarketplaceServicesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n CardContent,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n Pagination,\n ResponsiveTable,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { Search
|
|
1
|
+
{"version":3,"file":"MarketplaceMarketplaceServicesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport {\n Badge,\n CardContent,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n Pagination,\n ResponsiveTable,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { Search } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore, type MarketplaceService } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\nimport { RatingStars, SegmentedTabs, getInitials, type SegmentedTab } from '../components/viz';\n\nexport function MarketplaceMarketplaceServicesPagePage() {\n const navigate = useNavigate();\n const { marketplaceServices } = useCrewFoundryStore();\n const [search, setSearch] = useState('');\n const [category, setCategory] = useState('all');\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 10 });\n\n const categoryTabs = useMemo<SegmentedTab[]>(() => {\n const counts = new Map<string, number>();\n for (const svc of marketplaceServices) {\n counts.set(svc.category, (counts.get(svc.category) ?? 0) + 1);\n }\n const tabs: SegmentedTab[] = [{ id: 'all', label: 'All', count: marketplaceServices.length }];\n for (const [name, count] of [...counts.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {\n tabs.push({ id: name, label: name, count });\n }\n return tabs;\n }, [marketplaceServices]);\n\n const filtered = marketplaceServices.filter((s) => {\n if (category !== 'all' && s.category !== category) {\n return false;\n }\n return `${s.title} ${s.provider} ${s.category}`.toLowerCase().includes(search.toLowerCase());\n });\n const paged = filtered.slice(offset, offset + pageSize);\n\n useEffect(() => {\n setPage(1);\n }, [search, category, setPage]);\n\n const columns: ResponsiveTableColumn<MarketplaceService>[] = [\n {\n key: 'service',\n header: 'Service',\n priority: 'primary',\n cell: (svc) => (\n <div className=\"flex items-center gap-2.5\">\n <span\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-action-primary-bg text-[11px] font-semibold text-action-primary-text\"\n aria-hidden=\"true\"\n >\n {getInitials(svc.provider)}\n </span>\n <div className=\"min-w-0\">\n <p className=\"font-medium\">{svc.title}</p>\n <p className=\"truncate text-xs text-text-secondary\">\n {svc.description.slice(0, 60)}\n {svc.description.length > 60 ? '…' : ''}\n </p>\n </div>\n </div>\n ),\n },\n {\n key: 'provider',\n header: 'Provider',\n priority: 'secondary',\n cell: (svc) => <span className=\"text-text-secondary\">{svc.provider}</span>,\n },\n {\n key: 'category',\n header: 'Category',\n priority: 'secondary',\n cell: (svc) => (\n <Badge variant=\"outline\" className=\"w-fit h-fit text-[10px]\">\n {svc.category}\n </Badge>\n ),\n },\n {\n key: 'price',\n header: 'Price',\n priority: 'secondary',\n cell: (svc) => (\n <span className=\"font-medium\">\n ${svc.price.toLocaleString()}/{svc.priceType}\n </span>\n ),\n },\n {\n key: 'rating',\n header: 'Rating',\n priority: 'secondary',\n cell: (svc) => <RatingStars value={svc.rating} count={svc.reviews} size={12} />,\n },\n {\n key: 'status',\n header: 'Status',\n priority: 'secondary',\n cell: (svc) => (\n <Badge variant={svc.status === 'active' ? 'default' : 'secondary'} className=\"text-[10px]\">\n {formatEnumLabel(svc.status)}\n </Badge>\n ),\n },\n ];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Browse Services</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {marketplaceServices.length} services available\n </p>\n <PagePurpose className=\"mt-1\">\n Explore services offered on the marketplace — search and compare offerings to find exactly\n the help your project needs.\n </PagePurpose>\n </div>\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"relative w-full max-w-sm\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder=\"Search services...\"\n className=\"pl-9\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n <div className=\"-mx-1 overflow-x-auto px-1 pb-1\">\n <SegmentedTabs\n tabs={categoryTabs}\n value={category}\n onChange={setCategory}\n aria-label=\"Filter services by category\"\n />\n </div>\n </div>\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardContent className=\"p-4\">\n <ResponsiveTable\n columns={columns}\n data={paged}\n rowKey={(svc) => svc.id}\n onRowClick={(svc) => navigate(`../marketplace/service-details-page?id=${svc.id}`)}\n emptyState={\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No services found\"\n description=\"Try a different search term to find the help you need.\"\n />\n }\n />\n </CardContent>\n </GlassCard>\n {filtered.length > 0 ? (\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={filtered.length}\n onPageChange={setPage}\n />\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -3,11 +3,14 @@ import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
|
|
|
3
3
|
import { Calendar as n, DollarSign as r, MessageSquare as i, Users as a } from "lucide-react";
|
|
4
4
|
import { useLocation as o, useNavigate as s } from "react-router-dom";
|
|
5
5
|
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
6
|
-
import { Badge as u, Card as d, CardContent as f, EmphasisPanel as p, GradientText as m, IllustratedEmptyState as h, NextSteps as g, PagePurpose as _ } from "@burdenoff/fe-libs/ui";
|
|
6
|
+
import { Badge as u, Card as d, CardContent as f, EmphasisPanel as p, GradientText as m, IllustratedEmptyState as h, NextSteps as g, PagePurpose as _, Spinner as v } from "@burdenoff/fe-libs/ui";
|
|
7
7
|
//#region src/crewfoundry/pages/MarketplaceProjectDetailsPagePage.tsx
|
|
8
|
-
function
|
|
9
|
-
let
|
|
10
|
-
return S ? /* @__PURE__ */
|
|
8
|
+
function y() {
|
|
9
|
+
let y = s(), b = o(), { projects: x, initialized: S } = e(), C = new URLSearchParams(b.search).get("id"), w = x.find((e) => e.id === C) ?? x[0];
|
|
10
|
+
return !S && !w ? /* @__PURE__ */ c("div", {
|
|
11
|
+
className: "flex min-h-[60vh] items-center justify-center p-6",
|
|
12
|
+
children: /* @__PURE__ */ c(v, { size: "lg" })
|
|
13
|
+
}) : w ? /* @__PURE__ */ l("div", {
|
|
11
14
|
className: "space-y-6 p-6 max-w-4xl",
|
|
12
15
|
children: [
|
|
13
16
|
/* @__PURE__ */ l("div", {
|
|
@@ -15,19 +18,19 @@ function v() {
|
|
|
15
18
|
children: [/* @__PURE__ */ l("div", { children: [
|
|
16
19
|
/* @__PURE__ */ c("h1", {
|
|
17
20
|
className: "text-2xl font-semibold",
|
|
18
|
-
children: /* @__PURE__ */ c(m, { children:
|
|
21
|
+
children: /* @__PURE__ */ c(m, { children: w.name })
|
|
19
22
|
}),
|
|
20
23
|
/* @__PURE__ */ c("p", {
|
|
21
24
|
className: "text-sm text-text-secondary",
|
|
22
|
-
children:
|
|
25
|
+
children: w.description
|
|
23
26
|
}),
|
|
24
27
|
/* @__PURE__ */ c(_, {
|
|
25
28
|
className: "mt-2",
|
|
26
29
|
children: "The full picture of a marketplace project — scope, budget, timeline, and progress — so you can track delivery and stay aligned with the team doing the work."
|
|
27
30
|
})
|
|
28
31
|
] }), /* @__PURE__ */ c(u, {
|
|
29
|
-
variant:
|
|
30
|
-
children: t(
|
|
32
|
+
variant: w.status === "active" ? "default" : "secondary",
|
|
33
|
+
children: t(w.status)
|
|
31
34
|
})]
|
|
32
35
|
}),
|
|
33
36
|
/* @__PURE__ */ c(g, {
|
|
@@ -38,21 +41,21 @@ function v() {
|
|
|
38
41
|
label: "Message the team",
|
|
39
42
|
description: "Coordinate on scope, blockers, and next milestones.",
|
|
40
43
|
icon: /* @__PURE__ */ c(i, { className: "h-4 w-4" }),
|
|
41
|
-
onClick: () =>
|
|
44
|
+
onClick: () => y("../marketplace/messaging-page")
|
|
42
45
|
},
|
|
43
46
|
{
|
|
44
47
|
id: "bookings",
|
|
45
48
|
label: "Review bookings",
|
|
46
49
|
description: "Check the engagements tied to this project.",
|
|
47
50
|
icon: /* @__PURE__ */ c(n, { className: "h-4 w-4" }),
|
|
48
|
-
onClick: () =>
|
|
51
|
+
onClick: () => y("../marketplace/booking-management-page")
|
|
49
52
|
},
|
|
50
53
|
{
|
|
51
54
|
id: "earnings",
|
|
52
55
|
label: "Track earnings",
|
|
53
56
|
description: "See payouts and balances connected to your work.",
|
|
54
57
|
icon: /* @__PURE__ */ c(r, { className: "h-4 w-4" }),
|
|
55
|
-
onClick: () =>
|
|
58
|
+
onClick: () => y("../marketplace/earnings-page")
|
|
56
59
|
}
|
|
57
60
|
]
|
|
58
61
|
}),
|
|
@@ -67,7 +70,7 @@ function v() {
|
|
|
67
70
|
className: "text-lg font-bold",
|
|
68
71
|
children: [
|
|
69
72
|
"$",
|
|
70
|
-
(
|
|
73
|
+
(w.budget / 1e3).toFixed(0),
|
|
71
74
|
"K"
|
|
72
75
|
]
|
|
73
76
|
}),
|
|
@@ -85,7 +88,7 @@ function v() {
|
|
|
85
88
|
className: "text-lg font-bold",
|
|
86
89
|
children: [
|
|
87
90
|
"$",
|
|
88
|
-
(
|
|
91
|
+
(w.spent / 1e3).toFixed(0),
|
|
89
92
|
"K"
|
|
90
93
|
]
|
|
91
94
|
}),
|
|
@@ -101,7 +104,7 @@ function v() {
|
|
|
101
104
|
/* @__PURE__ */ c(a, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
102
105
|
/* @__PURE__ */ c("p", {
|
|
103
106
|
className: "text-lg font-bold",
|
|
104
|
-
children:
|
|
107
|
+
children: w.teamName
|
|
105
108
|
}),
|
|
106
109
|
/* @__PURE__ */ c("p", {
|
|
107
110
|
className: "text-xs text-text-secondary",
|
|
@@ -115,7 +118,7 @@ function v() {
|
|
|
115
118
|
/* @__PURE__ */ c(n, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
116
119
|
/* @__PURE__ */ c("p", {
|
|
117
120
|
className: "text-lg font-bold",
|
|
118
|
-
children:
|
|
121
|
+
children: w.endDate
|
|
119
122
|
}),
|
|
120
123
|
/* @__PURE__ */ c("p", {
|
|
121
124
|
className: "text-xs text-text-secondary",
|
|
@@ -135,19 +138,19 @@ function v() {
|
|
|
135
138
|
children: [/* @__PURE__ */ l("div", {
|
|
136
139
|
className: "flex justify-between text-sm",
|
|
137
140
|
children: [/* @__PURE__ */ l("span", { children: [
|
|
138
|
-
|
|
141
|
+
w.completedTasks,
|
|
139
142
|
" of ",
|
|
140
|
-
|
|
143
|
+
w.tasks,
|
|
141
144
|
" tasks"
|
|
142
145
|
] }), /* @__PURE__ */ l("span", {
|
|
143
146
|
className: "font-medium",
|
|
144
|
-
children: [
|
|
147
|
+
children: [w.progress, "%"]
|
|
145
148
|
})]
|
|
146
149
|
}), /* @__PURE__ */ c("div", {
|
|
147
150
|
className: "h-3 bg-bg-sunken rounded overflow-hidden",
|
|
148
151
|
children: /* @__PURE__ */ c("div", {
|
|
149
152
|
className: "h-3 bg-action-primary-bg rounded",
|
|
150
|
-
style: { width: `${
|
|
153
|
+
style: { width: `${w.progress}%` }
|
|
151
154
|
})
|
|
152
155
|
})]
|
|
153
156
|
}),
|
|
@@ -159,28 +162,28 @@ function v() {
|
|
|
159
162
|
children: "Manager"
|
|
160
163
|
}), /* @__PURE__ */ c("p", {
|
|
161
164
|
className: "text-sm font-medium",
|
|
162
|
-
children:
|
|
165
|
+
children: w.managerName
|
|
163
166
|
})] }),
|
|
164
167
|
/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
|
|
165
168
|
className: "text-xs text-text-secondary",
|
|
166
169
|
children: "Priority"
|
|
167
170
|
}), /* @__PURE__ */ c(u, {
|
|
168
|
-
variant:
|
|
169
|
-
children: t(
|
|
171
|
+
variant: w.priority === "critical" ? "destructive" : w.priority === "high" ? "default" : "secondary",
|
|
172
|
+
children: t(w.priority)
|
|
170
173
|
})] }),
|
|
171
174
|
/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
|
|
172
175
|
className: "text-xs text-text-secondary",
|
|
173
176
|
children: "Start Date"
|
|
174
177
|
}), /* @__PURE__ */ c("p", {
|
|
175
178
|
className: "text-sm",
|
|
176
|
-
children:
|
|
179
|
+
children: w.startDate
|
|
177
180
|
})] }),
|
|
178
181
|
/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
|
|
179
182
|
className: "text-xs text-text-secondary",
|
|
180
183
|
children: "End Date"
|
|
181
184
|
}), /* @__PURE__ */ c("p", {
|
|
182
185
|
className: "text-sm",
|
|
183
|
-
children:
|
|
186
|
+
children: w.endDate
|
|
184
187
|
})] })
|
|
185
188
|
]
|
|
186
189
|
})
|
|
@@ -196,6 +199,6 @@ function v() {
|
|
|
196
199
|
});
|
|
197
200
|
}
|
|
198
201
|
//#endregion
|
|
199
|
-
export {
|
|
202
|
+
export { y as MarketplaceProjectDetailsPagePage };
|
|
200
203
|
|
|
201
204
|
//# sourceMappingURL=MarketplaceProjectDetailsPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarketplaceProjectDetailsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceProjectDetailsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Calendar, DollarSign, MessageSquare, Users } from 'lucide-react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nexport function MarketplaceProjectDetailsPagePage() {\n const navigate = useNavigate();\n const location = useLocation();\n const { projects } = useCrewFoundryStore();\n const selectedId = new URLSearchParams(location.search).get('id');\n const project = projects.find((p) => p.id === selectedId) ?? projects[0];\n if (!project)\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Project not found\"\n description=\"This project is no longer available.\"\n />\n </div>\n );\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{project.name}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{project.description}</p>\n <PagePurpose className=\"mt-2\">\n The full picture of a marketplace project — scope, budget, timeline, and progress — so\n you can track delivery and stay aligned with the team doing the work.\n </PagePurpose>\n </div>\n <Badge variant={project.status === 'active' ? 'default' : 'secondary'}>\n {formatEnumLabel(project.status)}\n </Badge>\n </div>\n\n <NextSteps\n storageKey=\"crewfoundry-marketplace-project-details\"\n steps={[\n {\n id: 'message',\n label: 'Message the team',\n description: 'Coordinate on scope, blockers, and next milestones.',\n icon: <MessageSquare className=\"h-4 w-4\" />,\n onClick: () => navigate('../marketplace/messaging-page'),\n },\n {\n id: 'bookings',\n label: 'Review bookings',\n description: 'Check the engagements tied to this project.',\n icon: <Calendar className=\"h-4 w-4\" />,\n onClick: () => navigate('../marketplace/booking-management-page'),\n },\n {\n id: 'earnings',\n label: 'Track earnings',\n description: 'See payouts and balances connected to your work.',\n icon: <DollarSign className=\"h-4 w-4\" />,\n onClick: () => navigate('../marketplace/earnings-page'),\n },\n ]}\n />\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardContent className=\"p-4 text-center\">\n <DollarSign className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">${(project.budget / 1000).toFixed(0)}K</p>\n <p className=\"text-xs text-text-secondary\">Budget</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <DollarSign className=\"h-5 w-5 mx-auto text-status-success-text mb-1\" />\n <p className=\"text-lg font-bold\">${(project.spent / 1000).toFixed(0)}K</p>\n <p className=\"text-xs text-text-secondary\">Spent</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Users className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{project.teamName}</p>\n <p className=\"text-xs text-text-secondary\">Team</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Calendar className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{project.endDate}</p>\n <p className=\"text-xs text-text-secondary\">Deadline</p>\n </CardContent>\n </Card>\n </div>\n <EmphasisPanel>\n <div className=\"mb-2 text-lg font-semibold\">Progress</div>\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-sm\">\n <span>\n {project.completedTasks} of {project.tasks} tasks\n </span>\n <span className=\"font-medium\">{project.progress}%</span>\n </div>\n <div className=\"h-3 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-3 bg-action-primary-bg rounded\"\n style={{ width: `${project.progress}%` }}\n />\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4 mt-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Manager</p>\n <p className=\"text-sm font-medium\">{project.managerName}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Priority</p>\n <Badge\n variant={\n project.priority === 'critical'\n ? 'destructive'\n : project.priority === 'high'\n ? 'default'\n : 'secondary'\n }\n >\n {formatEnumLabel(project.priority)}\n </Badge>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Start Date</p>\n <p className=\"text-sm\">{project.startDate}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">End Date</p>\n <p className=\"text-sm\">{project.endDate}</p>\n </div>\n </div>\n </EmphasisPanel>\n </div>\n );\n}\n"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"MarketplaceProjectDetailsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceProjectDetailsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n Spinner,\n} from '@burdenoff/fe-libs/ui';\nimport { Calendar, DollarSign, MessageSquare, Users } from 'lucide-react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nexport function MarketplaceProjectDetailsPagePage() {\n const navigate = useNavigate();\n const location = useLocation();\n const { projects, initialized } = useCrewFoundryStore();\n const selectedId = new URLSearchParams(location.search).get('id');\n const project = projects.find((p) => p.id === selectedId) ?? projects[0];\n if (!initialized && !project) {\n return (\n <div className=\"flex min-h-[60vh] items-center justify-center p-6\">\n <Spinner size=\"lg\" />\n </div>\n );\n }\n\n if (!project)\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Project not found\"\n description=\"This project is no longer available.\"\n />\n </div>\n );\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{project.name}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{project.description}</p>\n <PagePurpose className=\"mt-2\">\n The full picture of a marketplace project — scope, budget, timeline, and progress — so\n you can track delivery and stay aligned with the team doing the work.\n </PagePurpose>\n </div>\n <Badge variant={project.status === 'active' ? 'default' : 'secondary'}>\n {formatEnumLabel(project.status)}\n </Badge>\n </div>\n\n <NextSteps\n storageKey=\"crewfoundry-marketplace-project-details\"\n steps={[\n {\n id: 'message',\n label: 'Message the team',\n description: 'Coordinate on scope, blockers, and next milestones.',\n icon: <MessageSquare className=\"h-4 w-4\" />,\n onClick: () => navigate('../marketplace/messaging-page'),\n },\n {\n id: 'bookings',\n label: 'Review bookings',\n description: 'Check the engagements tied to this project.',\n icon: <Calendar className=\"h-4 w-4\" />,\n onClick: () => navigate('../marketplace/booking-management-page'),\n },\n {\n id: 'earnings',\n label: 'Track earnings',\n description: 'See payouts and balances connected to your work.',\n icon: <DollarSign className=\"h-4 w-4\" />,\n onClick: () => navigate('../marketplace/earnings-page'),\n },\n ]}\n />\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardContent className=\"p-4 text-center\">\n <DollarSign className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">${(project.budget / 1000).toFixed(0)}K</p>\n <p className=\"text-xs text-text-secondary\">Budget</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <DollarSign className=\"h-5 w-5 mx-auto text-status-success-text mb-1\" />\n <p className=\"text-lg font-bold\">${(project.spent / 1000).toFixed(0)}K</p>\n <p className=\"text-xs text-text-secondary\">Spent</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Users className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{project.teamName}</p>\n <p className=\"text-xs text-text-secondary\">Team</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Calendar className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{project.endDate}</p>\n <p className=\"text-xs text-text-secondary\">Deadline</p>\n </CardContent>\n </Card>\n </div>\n <EmphasisPanel>\n <div className=\"mb-2 text-lg font-semibold\">Progress</div>\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-sm\">\n <span>\n {project.completedTasks} of {project.tasks} tasks\n </span>\n <span className=\"font-medium\">{project.progress}%</span>\n </div>\n <div className=\"h-3 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-3 bg-action-primary-bg rounded\"\n style={{ width: `${project.progress}%` }}\n />\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4 mt-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Manager</p>\n <p className=\"text-sm font-medium\">{project.managerName}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Priority</p>\n <Badge\n variant={\n project.priority === 'critical'\n ? 'destructive'\n : project.priority === 'high'\n ? 'default'\n : 'secondary'\n }\n >\n {formatEnumLabel(project.priority)}\n </Badge>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Start Date</p>\n <p className=\"text-sm\">{project.startDate}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">End Date</p>\n <p className=\"text-sm\">{project.endDate}</p>\n </div>\n </div>\n </EmphasisPanel>\n </div>\n );\n}\n"],"mappings":"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"}
|