@burdenoff/microfe-crewfoundry 2026.626.1 → 2026.703.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/forms/ConfirmDialog.js +43 -0
- package/dist/crewfoundry/components/forms/ConfirmDialog.js.map +1 -0
- package/dist/crewfoundry/components/forms/FormModal.js +220 -0
- package/dist/crewfoundry/components/forms/FormModal.js.map +1 -0
- package/dist/crewfoundry/components/forms/formValues.js +20 -0
- package/dist/crewfoundry/components/forms/formValues.js.map +1 -0
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +255 -65
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +28 -17
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +57 -53
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +32 -23
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +44 -29
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +183 -57
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +214 -92
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +165 -131
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +163 -133
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +269 -54
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +225 -78
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +213 -59
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +287 -90
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +49 -47
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +166 -59
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +274 -83
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +198 -88
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +216 -88
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +216 -66
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +6 -7
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +83 -68
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +167 -46
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +75 -55
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +152 -79
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +75 -63
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +3 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +235 -87
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +199 -86
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +21 -40
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +117 -45
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +249 -90
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +47 -45
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +262 -133
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +144 -77
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +339 -52
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
|
-
import { useMemo as t } from "react";
|
|
3
|
-
import { Award as
|
|
4
|
-
import { jsx as
|
|
5
|
-
import { Badge as
|
|
2
|
+
import { useMemo as t, useState as n } from "react";
|
|
3
|
+
import { Award as r, BookOpen as i, Clock as a, Play as o, Star as s } from "lucide-react";
|
|
4
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
5
|
+
import { Badge as u, Button as d, Card as f, CardContent as p, CardDescription as m, CardHeader as h, CardTitle as g, GlassCard as _, GradientText as v, PagePurpose as y } from "@burdenoff/fe-libs/ui";
|
|
6
|
+
import { useGlobalUi as b } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
6
7
|
//#region src/crewfoundry/pages/LearningMyLearningPagePage.tsx
|
|
7
|
-
var
|
|
8
|
+
var x = (/* @__PURE__ */ new Date("2026-03-01T00:00:00Z")).getTime(), S = (e) => {
|
|
8
9
|
let t = new Date(e);
|
|
9
10
|
return Number.isNaN(t.getTime()) ? "Unknown" : t.toISOString().split("T")[0];
|
|
10
11
|
};
|
|
11
|
-
function
|
|
12
|
-
let { courses:
|
|
12
|
+
function C() {
|
|
13
|
+
let { courses: C, enrollCourse: w } = e(), { showToast: T } = b(), [E, D] = n(null), O = async (e) => {
|
|
14
|
+
D(e);
|
|
15
|
+
try {
|
|
16
|
+
await w(e), T("Enrollment updated", "success");
|
|
17
|
+
} catch (e) {
|
|
18
|
+
T(e instanceof Error ? e.message : "Unable to update course", "error");
|
|
19
|
+
} finally {
|
|
20
|
+
D(null);
|
|
21
|
+
}
|
|
22
|
+
}, k = t(() => C.filter((e) => e.status === "active").slice(0, 8).map((e, t) => {
|
|
13
23
|
let n = Math.min(e.modules, Math.round(e.completed / Math.max(e.enrolled, 1) * e.modules)), r = Math.round(n / Math.max(e.modules, 1) * 100);
|
|
14
24
|
return {
|
|
15
25
|
id: e.id,
|
|
@@ -18,106 +28,106 @@ function x() {
|
|
|
18
28
|
modules: e.modules,
|
|
19
29
|
completedModules: n,
|
|
20
30
|
instructor: e.instructor,
|
|
21
|
-
dueDate:
|
|
31
|
+
dueDate: S(new Date(x + (t + 1) * 864e5 * 12).toISOString())
|
|
22
32
|
};
|
|
23
|
-
}), [
|
|
33
|
+
}), [C]), A = t(() => C.filter((e) => e.completed > 0).slice(0, 8).map((e, t) => ({
|
|
24
34
|
id: `completed-${e.id}`,
|
|
25
35
|
title: e.title,
|
|
26
|
-
completedDate:
|
|
36
|
+
completedDate: S((/* @__PURE__ */ new Date(x - (t + 1) * 864e5 * 15)).toISOString()),
|
|
27
37
|
rating: Number(e.rating.toFixed(1)),
|
|
28
38
|
certificate: e.completed / Math.max(e.enrolled, 1) > .35
|
|
29
|
-
})), [
|
|
30
|
-
return /* @__PURE__ */
|
|
39
|
+
})), [C]), j = k.reduce((e, t) => e + t.completedModules * 1.25, 0);
|
|
40
|
+
return /* @__PURE__ */ l("div", {
|
|
31
41
|
className: "space-y-6 p-6",
|
|
32
42
|
children: [
|
|
33
|
-
/* @__PURE__ */
|
|
34
|
-
/* @__PURE__ */
|
|
43
|
+
/* @__PURE__ */ l("div", { children: [
|
|
44
|
+
/* @__PURE__ */ c("h1", {
|
|
35
45
|
className: "text-2xl font-semibold",
|
|
36
|
-
children: /* @__PURE__ */
|
|
46
|
+
children: /* @__PURE__ */ c(v, { children: "My Learning" })
|
|
37
47
|
}),
|
|
38
|
-
/* @__PURE__ */
|
|
48
|
+
/* @__PURE__ */ c("p", {
|
|
39
49
|
className: "text-sm text-text-secondary",
|
|
40
50
|
children: "Track your learning progress and achievements"
|
|
41
51
|
}),
|
|
42
|
-
/* @__PURE__ */
|
|
52
|
+
/* @__PURE__ */ c(y, {
|
|
43
53
|
className: "mt-1",
|
|
44
54
|
children: "Everything you're currently learning — track your enrolled courses, progress, and certificates earned all in one place."
|
|
45
55
|
})
|
|
46
56
|
] }),
|
|
47
|
-
/* @__PURE__ */
|
|
57
|
+
/* @__PURE__ */ l("div", {
|
|
48
58
|
className: "grid gap-4 md:grid-cols-4",
|
|
49
59
|
children: [
|
|
50
|
-
/* @__PURE__ */
|
|
60
|
+
/* @__PURE__ */ l(_, {
|
|
51
61
|
treatment: "glass",
|
|
52
62
|
glow: !0,
|
|
53
63
|
className: "border-border-seam",
|
|
54
|
-
children: [/* @__PURE__ */
|
|
64
|
+
children: [/* @__PURE__ */ l(h, {
|
|
55
65
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
56
|
-
children: [/* @__PURE__ */
|
|
66
|
+
children: [/* @__PURE__ */ c(g, {
|
|
57
67
|
className: "text-sm font-medium",
|
|
58
68
|
children: "In Progress"
|
|
59
|
-
}), /* @__PURE__ */
|
|
60
|
-
}), /* @__PURE__ */
|
|
69
|
+
}), /* @__PURE__ */ c(i, { className: "h-4 w-4 text-status-info-text" })]
|
|
70
|
+
}), /* @__PURE__ */ c(p, { children: /* @__PURE__ */ c("div", {
|
|
61
71
|
className: "text-2xl font-bold tabular-nums",
|
|
62
|
-
children:
|
|
72
|
+
children: k.length
|
|
63
73
|
}) })]
|
|
64
74
|
}),
|
|
65
|
-
/* @__PURE__ */
|
|
75
|
+
/* @__PURE__ */ l(_, {
|
|
66
76
|
treatment: "metric",
|
|
67
77
|
className: "border-border-seam",
|
|
68
|
-
children: [/* @__PURE__ */
|
|
78
|
+
children: [/* @__PURE__ */ l(h, {
|
|
69
79
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
70
|
-
children: [/* @__PURE__ */
|
|
80
|
+
children: [/* @__PURE__ */ c(g, {
|
|
71
81
|
className: "text-sm font-medium",
|
|
72
82
|
children: "Completed"
|
|
73
|
-
}), /* @__PURE__ */
|
|
74
|
-
}), /* @__PURE__ */
|
|
83
|
+
}), /* @__PURE__ */ c(r, { className: "h-4 w-4 text-status-success-text" })]
|
|
84
|
+
}), /* @__PURE__ */ c(p, { children: /* @__PURE__ */ c("div", {
|
|
75
85
|
className: "text-2xl font-bold tabular-nums",
|
|
76
|
-
children:
|
|
86
|
+
children: A.length
|
|
77
87
|
}) })]
|
|
78
88
|
}),
|
|
79
|
-
/* @__PURE__ */
|
|
89
|
+
/* @__PURE__ */ l(_, {
|
|
80
90
|
treatment: "metric",
|
|
81
91
|
className: "border-border-seam",
|
|
82
|
-
children: [/* @__PURE__ */
|
|
92
|
+
children: [/* @__PURE__ */ l(h, {
|
|
83
93
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
84
|
-
children: [/* @__PURE__ */
|
|
94
|
+
children: [/* @__PURE__ */ c(g, {
|
|
85
95
|
className: "text-sm font-medium",
|
|
86
96
|
children: "Hours Logged"
|
|
87
|
-
}), /* @__PURE__ */
|
|
88
|
-
}), /* @__PURE__ */
|
|
97
|
+
}), /* @__PURE__ */ c(a, { className: "h-4 w-4 text-text-secondary" })]
|
|
98
|
+
}), /* @__PURE__ */ c(p, { children: /* @__PURE__ */ c("div", {
|
|
89
99
|
className: "text-2xl font-bold tabular-nums",
|
|
90
|
-
children:
|
|
100
|
+
children: j.toFixed(1)
|
|
91
101
|
}) })]
|
|
92
102
|
}),
|
|
93
|
-
/* @__PURE__ */
|
|
103
|
+
/* @__PURE__ */ l(_, {
|
|
94
104
|
treatment: "metric",
|
|
95
105
|
className: "border-border-seam",
|
|
96
|
-
children: [/* @__PURE__ */
|
|
106
|
+
children: [/* @__PURE__ */ l(h, {
|
|
97
107
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
98
|
-
children: [/* @__PURE__ */
|
|
108
|
+
children: [/* @__PURE__ */ c(g, {
|
|
99
109
|
className: "text-sm font-medium",
|
|
100
110
|
children: "Certificates"
|
|
101
|
-
}), /* @__PURE__ */
|
|
102
|
-
}), /* @__PURE__ */
|
|
111
|
+
}), /* @__PURE__ */ c(r, { className: "h-4 w-4 text-status-warning-text" })]
|
|
112
|
+
}), /* @__PURE__ */ c(p, { children: /* @__PURE__ */ c("div", {
|
|
103
113
|
className: "text-2xl font-bold tabular-nums",
|
|
104
|
-
children:
|
|
114
|
+
children: A.filter((e) => e.certificate).length
|
|
105
115
|
}) })]
|
|
106
116
|
})
|
|
107
117
|
]
|
|
108
118
|
}),
|
|
109
|
-
/* @__PURE__ */
|
|
119
|
+
/* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l(h, { children: [/* @__PURE__ */ c(g, { children: "In Progress" }), /* @__PURE__ */ c(m, { children: "Continue where you left off" })] }), /* @__PURE__ */ c(p, {
|
|
110
120
|
className: "space-y-4",
|
|
111
|
-
children:
|
|
121
|
+
children: k.map((e) => /* @__PURE__ */ l("div", {
|
|
112
122
|
className: "flex items-center gap-4 rounded border p-4",
|
|
113
|
-
children: [/* @__PURE__ */
|
|
123
|
+
children: [/* @__PURE__ */ l("div", {
|
|
114
124
|
className: "flex-1",
|
|
115
125
|
children: [
|
|
116
|
-
/* @__PURE__ */
|
|
126
|
+
/* @__PURE__ */ c("p", {
|
|
117
127
|
className: "text-sm font-medium",
|
|
118
128
|
children: e.title
|
|
119
129
|
}),
|
|
120
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ l("p", {
|
|
121
131
|
className: "text-xs text-text-secondary",
|
|
122
132
|
children: [
|
|
123
133
|
e.instructor,
|
|
@@ -125,20 +135,20 @@ function x() {
|
|
|
125
135
|
e.dueDate
|
|
126
136
|
]
|
|
127
137
|
}),
|
|
128
|
-
/* @__PURE__ */
|
|
138
|
+
/* @__PURE__ */ l("div", {
|
|
129
139
|
className: "mt-2 flex items-center gap-2",
|
|
130
|
-
children: [/* @__PURE__ */
|
|
140
|
+
children: [/* @__PURE__ */ c("div", {
|
|
131
141
|
className: "h-2 flex-1 overflow-hidden rounded bg-bg-sunken",
|
|
132
|
-
children: /* @__PURE__ */
|
|
142
|
+
children: /* @__PURE__ */ c("div", {
|
|
133
143
|
className: "h-2 rounded bg-action-primary-bg",
|
|
134
144
|
style: { width: `${e.progress}%` }
|
|
135
145
|
})
|
|
136
|
-
}), /* @__PURE__ */
|
|
146
|
+
}), /* @__PURE__ */ l("span", {
|
|
137
147
|
className: "text-xs font-medium",
|
|
138
148
|
children: [e.progress, "%"]
|
|
139
149
|
})]
|
|
140
150
|
}),
|
|
141
|
-
/* @__PURE__ */
|
|
151
|
+
/* @__PURE__ */ l("p", {
|
|
142
152
|
className: "mt-1 text-xs text-text-secondary",
|
|
143
153
|
children: [
|
|
144
154
|
e.completedModules,
|
|
@@ -148,32 +158,34 @@ function x() {
|
|
|
148
158
|
]
|
|
149
159
|
})
|
|
150
160
|
]
|
|
151
|
-
}), /* @__PURE__ */
|
|
161
|
+
}), /* @__PURE__ */ l(d, {
|
|
152
162
|
size: "sm",
|
|
153
|
-
|
|
163
|
+
onClick: () => O(e.id),
|
|
164
|
+
disabled: E === e.id,
|
|
165
|
+
children: [/* @__PURE__ */ c(o, { className: "mr-1 h-3 w-3" }), E === e.id ? "Saving…" : "Continue"]
|
|
154
166
|
})]
|
|
155
167
|
}, e.id))
|
|
156
168
|
})] }),
|
|
157
|
-
/* @__PURE__ */
|
|
169
|
+
/* @__PURE__ */ l(f, { children: [/* @__PURE__ */ c(h, { children: /* @__PURE__ */ c(g, { children: "Completed" }) }), /* @__PURE__ */ c(p, {
|
|
158
170
|
className: "space-y-3",
|
|
159
|
-
children:
|
|
171
|
+
children: A.map((e) => /* @__PURE__ */ l("div", {
|
|
160
172
|
className: "flex items-center justify-between rounded border p-3",
|
|
161
|
-
children: [/* @__PURE__ */
|
|
173
|
+
children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
|
|
162
174
|
className: "text-sm font-medium",
|
|
163
175
|
children: e.title
|
|
164
|
-
}), /* @__PURE__ */
|
|
176
|
+
}), /* @__PURE__ */ l("p", {
|
|
165
177
|
className: "text-xs text-text-secondary",
|
|
166
178
|
children: ["Completed ", e.completedDate]
|
|
167
|
-
})] }), /* @__PURE__ */
|
|
179
|
+
})] }), /* @__PURE__ */ l("div", {
|
|
168
180
|
className: "flex items-center gap-2",
|
|
169
|
-
children: [/* @__PURE__ */
|
|
181
|
+
children: [/* @__PURE__ */ l("div", {
|
|
170
182
|
className: "flex items-center gap-1",
|
|
171
183
|
children: [
|
|
172
|
-
/* @__PURE__ */ s
|
|
184
|
+
/* @__PURE__ */ c(s, { className: "h-3 w-3 text-status-warning-text" }),
|
|
173
185
|
e.rating,
|
|
174
186
|
"/5"
|
|
175
187
|
]
|
|
176
|
-
}), e.certificate ? /* @__PURE__ */
|
|
188
|
+
}), e.certificate ? /* @__PURE__ */ c(u, {
|
|
177
189
|
variant: "default",
|
|
178
190
|
className: "text-[10px]",
|
|
179
191
|
children: "Certificate"
|
|
@@ -185,6 +197,6 @@ function x() {
|
|
|
185
197
|
});
|
|
186
198
|
}
|
|
187
199
|
//#endregion
|
|
188
|
-
export {
|
|
200
|
+
export { C as LearningMyLearningPagePage };
|
|
189
201
|
|
|
190
202
|
//# sourceMappingURL=LearningMyLearningPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LearningMyLearningPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningMyLearningPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Award, BookOpen, Clock, Play, Star } from 'lucide-react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype EnrolledCourse = {\n id: string;\n title: string;\n progress: number;\n modules: number;\n completedModules: number;\n instructor: string;\n dueDate: string;\n};\n\ntype CompletedCourse = {\n id: string;\n title: string;\n completedDate: string;\n rating: number;\n certificate: boolean;\n};\n\nconst BASE_TS = new Date('2026-03-01T00:00:00Z').getTime();\n\nconst isoDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function LearningMyLearningPagePage() {\n const { courses } = useCrewFoundryStore();\n\n const myEnrolledCourses = useMemo<EnrolledCourse[]>(() => {\n return courses\n .filter((course) => course.status === 'active')\n .slice(0, 8)\n .map((course, index) => {\n const completedModules = Math.min(\n course.modules,\n Math.round((course.completed / Math.max(course.enrolled, 1)) * course.modules)\n );\n const progress = Math.round((completedModules / Math.max(course.modules, 1)) * 100);\n return {\n id: course.id,\n title: course.title,\n progress,\n modules: course.modules,\n completedModules,\n instructor: course.instructor,\n dueDate: isoDate(new Date(BASE_TS + (index + 1) * 86400000 * 12).toISOString()),\n };\n });\n }, [courses]);\n\n const completedCourses = useMemo<CompletedCourse[]>(() => {\n return courses\n .filter((course) => course.completed > 0)\n .slice(0, 8)\n .map((course, index) => ({\n id: `completed-${course.id}`,\n title: course.title,\n completedDate: isoDate(new Date(BASE_TS - (index + 1) * 86400000 * 15).toISOString()),\n rating: Number(course.rating.toFixed(1)),\n certificate: course.completed / Math.max(course.enrolled, 1) > 0.35,\n }));\n }, [courses]);\n\n const hoursLogged = myEnrolledCourses.reduce(\n (sum, course) => sum + course.completedModules * 1.25,\n 0\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>My Learning</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Track your learning progress and achievements</p>\n <PagePurpose className=\"mt-1\">Everything you're currently learning — track your enrolled courses, progress, and certificates earned all in one place.</PagePurpose>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">In Progress</CardTitle>\n <BookOpen className=\"h-4 w-4 text-status-info-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{myEnrolledCourses.length}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Completed</CardTitle>\n <Award className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{completedCourses.length}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Hours Logged</CardTitle>\n <Clock className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{hoursLogged.toFixed(1)}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Certificates</CardTitle>\n <Award className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {completedCourses.filter((course) => course.certificate).length}\n </div>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>In Progress</CardTitle>\n <CardDescription>Continue where you left off</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {myEnrolledCourses.map((course) => (\n <div key={course.id} className=\"flex items-center gap-4 rounded border p-4\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium\">{course.title}</p>\n <p className=\"text-xs text-text-secondary\">\n {course.instructor} · Due {course.dueDate}\n </p>\n <div className=\"mt-2 flex items-center gap-2\">\n <div className=\"h-2 flex-1 overflow-hidden rounded bg-bg-sunken\">\n <div\n className=\"h-2 rounded bg-action-primary-bg\"\n style={{ width: `${course.progress}%` }}\n />\n </div>\n <span className=\"text-xs font-medium\">{course.progress}%</span>\n </div>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {course.completedModules}/{course.modules} modules\n </p>\n </div>\n <Button size=\"sm\">\n <Play className=\"mr-1 h-3 w-3\" />\n Continue\n </Button>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Completed</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {completedCourses.map((course) => (\n <div key={course.id} className=\"flex items-center justify-between rounded border p-3\">\n <div>\n <p className=\"text-sm font-medium\">{course.title}</p>\n <p className=\"text-xs text-text-secondary\">Completed {course.completedDate}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n {course.rating}/5\n </div>\n {course.certificate ? (\n <Badge variant=\"default\" className=\"text-[10px]\">\n Certificate\n </Badge>\n ) : null}\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LearningMyLearningPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningMyLearningPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { Award, BookOpen, Clock, Play, Star } from 'lucide-react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype EnrolledCourse = {\n id: string;\n title: string;\n progress: number;\n modules: number;\n completedModules: number;\n instructor: string;\n dueDate: string;\n};\n\ntype CompletedCourse = {\n id: string;\n title: string;\n completedDate: string;\n rating: number;\n certificate: boolean;\n};\n\nconst BASE_TS = new Date('2026-03-01T00:00:00Z').getTime();\n\nconst isoDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function LearningMyLearningPagePage() {\n const { courses, enrollCourse } = useCrewFoundryStore();\n const { showToast } = useGlobalUi();\n const [enrollingId, setEnrollingId] = useState<string | null>(null);\n\n const handleContinue = async (id: string) => {\n setEnrollingId(id);\n try {\n await enrollCourse(id);\n showToast('Enrollment updated', 'success');\n } catch (error) {\n showToast(error instanceof Error ? error.message : 'Unable to update course', 'error');\n } finally {\n setEnrollingId(null);\n }\n };\n\n const myEnrolledCourses = useMemo<EnrolledCourse[]>(() => {\n return courses\n .filter((course) => course.status === 'active')\n .slice(0, 8)\n .map((course, index) => {\n const completedModules = Math.min(\n course.modules,\n Math.round((course.completed / Math.max(course.enrolled, 1)) * course.modules)\n );\n const progress = Math.round((completedModules / Math.max(course.modules, 1)) * 100);\n return {\n id: course.id,\n title: course.title,\n progress,\n modules: course.modules,\n completedModules,\n instructor: course.instructor,\n dueDate: isoDate(new Date(BASE_TS + (index + 1) * 86400000 * 12).toISOString()),\n };\n });\n }, [courses]);\n\n const completedCourses = useMemo<CompletedCourse[]>(() => {\n return courses\n .filter((course) => course.completed > 0)\n .slice(0, 8)\n .map((course, index) => ({\n id: `completed-${course.id}`,\n title: course.title,\n completedDate: isoDate(new Date(BASE_TS - (index + 1) * 86400000 * 15).toISOString()),\n rating: Number(course.rating.toFixed(1)),\n certificate: course.completed / Math.max(course.enrolled, 1) > 0.35,\n }));\n }, [courses]);\n\n const hoursLogged = myEnrolledCourses.reduce(\n (sum, course) => sum + course.completedModules * 1.25,\n 0\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>My Learning</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Track your learning progress and achievements</p>\n <PagePurpose className=\"mt-1\">Everything you're currently learning — track your enrolled courses, progress, and certificates earned all in one place.</PagePurpose>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">In Progress</CardTitle>\n <BookOpen className=\"h-4 w-4 text-status-info-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{myEnrolledCourses.length}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Completed</CardTitle>\n <Award className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{completedCourses.length}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Hours Logged</CardTitle>\n <Clock className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{hoursLogged.toFixed(1)}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Certificates</CardTitle>\n <Award className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {completedCourses.filter((course) => course.certificate).length}\n </div>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>In Progress</CardTitle>\n <CardDescription>Continue where you left off</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {myEnrolledCourses.map((course) => (\n <div key={course.id} className=\"flex items-center gap-4 rounded border p-4\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium\">{course.title}</p>\n <p className=\"text-xs text-text-secondary\">\n {course.instructor} · Due {course.dueDate}\n </p>\n <div className=\"mt-2 flex items-center gap-2\">\n <div className=\"h-2 flex-1 overflow-hidden rounded bg-bg-sunken\">\n <div\n className=\"h-2 rounded bg-action-primary-bg\"\n style={{ width: `${course.progress}%` }}\n />\n </div>\n <span className=\"text-xs font-medium\">{course.progress}%</span>\n </div>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {course.completedModules}/{course.modules} modules\n </p>\n </div>\n <Button\n size=\"sm\"\n onClick={() => handleContinue(course.id)}\n disabled={enrollingId === course.id}\n >\n <Play className=\"mr-1 h-3 w-3\" />\n {enrollingId === course.id ? 'Saving…' : 'Continue'}\n </Button>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Completed</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {completedCourses.map((course) => (\n <div key={course.id} className=\"flex items-center justify-between rounded border p-3\">\n <div>\n <p className=\"text-sm font-medium\">{course.title}</p>\n <p className=\"text-xs text-text-secondary\">Completed {course.completedDate}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n {course.rating}/5\n </div>\n {course.certificate ? (\n <Badge variant=\"default\" className=\"text-[10px]\">\n Certificate\n </Badge>\n ) : null}\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -45,7 +45,9 @@ function v() {
|
|
|
45
45
|
})
|
|
46
46
|
] }), /* @__PURE__ */ s(l, {
|
|
47
47
|
size: "sm",
|
|
48
|
-
|
|
48
|
+
disabled: !0,
|
|
49
|
+
title: "Booking creation is coming soon",
|
|
50
|
+
children: [/* @__PURE__ */ o(a, { className: "mr-1 h-4 w-4" }), "New Booking · Coming soon"]
|
|
49
51
|
})]
|
|
50
52
|
}),
|
|
51
53
|
/* @__PURE__ */ s("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarketplaceBookingManagementPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceBookingManagementPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Calendar, CheckCircle, Clock, Plus } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype Booking = {\n id: string;\n service: string;\n provider: string;\n date: string;\n time: string;\n duration: string;\n status: 'confirmed' | 'pending' | 'completed';\n};\n\nconst formatDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function MarketplaceBookingManagementPagePage() {\n const { marketplaceServices, projects, teams } = useCrewFoundryStore();\n\n const bookings = useMemo<Booking[]>(() => {\n return marketplaceServices.slice(0, 12).map((service, index) => {\n const project = projects[index % Math.max(projects.length, 1)];\n const team = teams[index % Math.max(teams.length, 1)];\n const status: Booking['status'] =\n service.status === 'active'\n ? 'confirmed'\n : service.status === 'pending'\n ? 'pending'\n : 'completed';\n\n return {\n id: service.id,\n service: service.title,\n provider: service.provider,\n date: formatDate(project?.startDate || service.deliveryTime),\n time: `${String((index % 12) + 1).padStart(2, '0')}:00 ${index % 2 === 0 ? 'AM' : 'PM'}`,\n duration: `${Math.max(1, Math.ceil((team?.memberCount || 4) / 4))} hours`,\n status,\n };\n });\n }, [marketplaceServices, projects, teams]);\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>Booking Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Manage service provider appointments</p>\n <PagePurpose className=\"mt-1\">Manage your service bookings — review upcoming engagements, confirm schedules, and keep your client commitments on track.</PagePurpose>\n </div>\n <Button size=\"sm\">\n <Plus className=\"mr-1 h-4 w-4\" />\n New Booking\n </Button>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Upcoming</CardTitle>\n <Calendar className=\"h-4 w-4 text-status-info-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {bookings.filter((booking) => booking.status !== 'completed').length}\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Confirmed</CardTitle>\n <CheckCircle className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {bookings.filter((booking) => booking.status === 'confirmed').length}\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Pending</CardTitle>\n <Clock className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {bookings.filter((booking) => booking.status === 'pending').length}\n </div>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>All Bookings</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {bookings.map((booking) => (\n <div key={booking.id} className=\"flex items-center justify-between rounded border p-4\">\n <div>\n <p className=\"text-sm font-medium\">{booking.service}</p>\n <p className=\"text-xs text-text-secondary\">{booking.provider}</p>\n </div>\n <div className=\"flex items-center gap-3\">\n <div className=\"text-right text-xs\">\n <p className=\"font-medium\">{booking.date}</p>\n <p className=\"text-text-secondary\">\n {booking.time} · {booking.duration}\n </p>\n </div>\n <Badge\n variant={\n booking.status === 'confirmed'\n ? 'default'\n : booking.status === 'completed'\n ? 'secondary'\n : 'outline'\n }\n className=\"text-[10px]\"\n >\n {booking.status}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":";;;;;;AAyBA,IAAM,KAAc,MAA0B;CAC5C,IAAM,IAAS,IAAI,KAAK,EAAM;AAI9B,QAHI,OAAO,MAAM,EAAO,SAAS,CAAC,GACzB,YAEF,EAAO,aAAa,CAAC,MAAM,IAAI,CAAC;;AAGzC,SAAgB,IAAuC;CACrD,IAAM,EAAE,wBAAqB,aAAU,aAAU,GAAqB,EAEhE,IAAW,QACR,EAAoB,MAAM,GAAG,GAAG,CAAC,KAAK,GAAS,MAAU;EAC9D,IAAM,IAAU,EAAS,IAAQ,KAAK,IAAI,EAAS,QAAQ,EAAE,GACvD,IAAO,EAAM,IAAQ,KAAK,IAAI,EAAM,QAAQ,EAAE,GAC9C,IACJ,EAAQ,WAAW,WACf,cACA,EAAQ,WAAW,YACjB,YACA;AAER,SAAO;GACL,IAAI,EAAQ;GACZ,SAAS,EAAQ;GACjB,UAAU,EAAQ;GAClB,MAAM,EAAW,GAAS,aAAa,EAAQ,aAAa;GAC5D,MAAM,GAAG,OAAQ,IAAQ,KAAM,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,IAAQ,KAAM,IAAI,OAAO;GAClF,UAAU,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,GAAM,eAAe,KAAK,EAAE,CAAC,CAAC;GAClE;GACD;GACD,EACD;EAAC;EAAqB;EAAU;EAAM,CAAC;AAE1C,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA;KACE,kBAAC,MAAD;MAAI,WAAU;gBACZ,kBAAC,GAAD,EAAA,UAAc,sBAAiC,CAAA;MAC5C,CAAA;KACL,kBAAC,KAAD;MAAG,WAAU;gBAA8B;MAAwC,CAAA;KACnF,kBAAC,GAAD;MAAa,WAAU;gBAAO;MAAuI,CAAA;KACjK,EAAA,CAAA,
|
|
1
|
+
{"version":3,"file":"MarketplaceBookingManagementPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceBookingManagementPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Calendar, CheckCircle, Clock, Plus } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype Booking = {\n id: string;\n service: string;\n provider: string;\n date: string;\n time: string;\n duration: string;\n status: 'confirmed' | 'pending' | 'completed';\n};\n\nconst formatDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function MarketplaceBookingManagementPagePage() {\n const { marketplaceServices, projects, teams } = useCrewFoundryStore();\n\n const bookings = useMemo<Booking[]>(() => {\n return marketplaceServices.slice(0, 12).map((service, index) => {\n const project = projects[index % Math.max(projects.length, 1)];\n const team = teams[index % Math.max(teams.length, 1)];\n const status: Booking['status'] =\n service.status === 'active'\n ? 'confirmed'\n : service.status === 'pending'\n ? 'pending'\n : 'completed';\n\n return {\n id: service.id,\n service: service.title,\n provider: service.provider,\n date: formatDate(project?.startDate || service.deliveryTime),\n time: `${String((index % 12) + 1).padStart(2, '0')}:00 ${index % 2 === 0 ? 'AM' : 'PM'}`,\n duration: `${Math.max(1, Math.ceil((team?.memberCount || 4) / 4))} hours`,\n status,\n };\n });\n }, [marketplaceServices, projects, teams]);\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>Booking Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Manage service provider appointments</p>\n <PagePurpose className=\"mt-1\">Manage your service bookings — review upcoming engagements, confirm schedules, and keep your client commitments on track.</PagePurpose>\n </div>\n {/* Bookings derive from marketplace services; there is no standalone\n booking-creation mutation yet, so this stays an honest disabled\n control instead of a silently-dead button. */}\n <Button size=\"sm\" disabled title=\"Booking creation is coming soon\">\n <Plus className=\"mr-1 h-4 w-4\" />\n New Booking · Coming soon\n </Button>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Upcoming</CardTitle>\n <Calendar className=\"h-4 w-4 text-status-info-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {bookings.filter((booking) => booking.status !== 'completed').length}\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Confirmed</CardTitle>\n <CheckCircle className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {bookings.filter((booking) => booking.status === 'confirmed').length}\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Pending</CardTitle>\n <Clock className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {bookings.filter((booking) => booking.status === 'pending').length}\n </div>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>All Bookings</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {bookings.map((booking) => (\n <div key={booking.id} className=\"flex items-center justify-between rounded border p-4\">\n <div>\n <p className=\"text-sm font-medium\">{booking.service}</p>\n <p className=\"text-xs text-text-secondary\">{booking.provider}</p>\n </div>\n <div className=\"flex items-center gap-3\">\n <div className=\"text-right text-xs\">\n <p className=\"font-medium\">{booking.date}</p>\n <p className=\"text-text-secondary\">\n {booking.time} · {booking.duration}\n </p>\n </div>\n <Badge\n variant={\n booking.status === 'confirmed'\n ? 'default'\n : booking.status === 'completed'\n ? 'secondary'\n : 'outline'\n }\n className=\"text-[10px]\"\n >\n {booking.status}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarketplaceMarketplacePagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceMarketplacePagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {
|
|
1
|
+
{"version":3,"file":"MarketplaceMarketplacePagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceMarketplacePagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { ShoppingBag, Star, Users } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function MarketplaceMarketplacePagePage() {\n const { t: translate } = useI18n();\n const { marketplaceServices } = useCrewFoundryStore();\n const t = (key: string, fallback: string) => {\n const value = translate(key);\n return value === key ? fallback : value;\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>\n {t('crewfoundry.marketplace.title', 'HR Services Marketplace')}\n </GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {t('crewfoundry.marketplace.subtitle', 'Find and hire professional HR service providers')}\n </p>\n <PagePurpose className=\"mt-1\">Discover freelancers and services for your projects — browse the marketplace to find and hire the right talent on demand.</PagePurpose>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {t('crewfoundry.marketplace.stats.services', 'Services')}\n </CardTitle>\n <ShoppingBag className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{marketplaceServices.length}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {t('crewfoundry.marketplace.stats.avgRating', 'Avg Rating')}\n </CardTitle>\n <Star className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {(\n marketplaceServices.reduce((s, m) => s + m.rating, 0) / marketplaceServices.length\n ).toFixed(1)}\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {t('crewfoundry.marketplace.stats.totalReviews', 'Total Reviews')}\n </CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {marketplaceServices.reduce((s, m) => s + m.reviews, 0)}\n </div>\n </CardContent>\n </GlassCard>\n </div>\n <h2 className=\"text-lg font-medium\">\n {t('crewfoundry.marketplace.featured.title', 'Featured Services')}\n </h2>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {marketplaceServices.map((svc) => (\n <Card key={svc.id} className=\"hover:shadow-md transition-shadow cursor-pointer\">\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {svc.category}\n </Badge>\n <Badge\n variant={svc.status === 'active' ? 'default' : 'secondary'}\n className=\"text-[10px]\"\n >\n {svc.status}\n </Badge>\n </div>\n <CardTitle className=\"text-base mt-2\">{svc.title}</CardTitle>\n <CardDescription>{svc.provider}</CardDescription>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-text-secondary mb-3\">{svc.description}</p>\n <div className=\"flex flex-wrap gap-1 mb-3\">\n {svc.skills.map((s) => (\n <Badge key={s} variant=\"outline\" className=\"text-[9px]\">\n {s}\n </Badge>\n ))}\n </div>\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"font-bold\">\n ${svc.price.toLocaleString()}\n <span className=\"text-xs font-normal text-text-secondary\">/{svc.priceType}</span>\n </span>\n <span className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n {svc.rating} ({svc.reviews})\n </span>\n </div>\n <p className=\"text-xs text-text-secondary mt-1\">\n {t('crewfoundry.marketplace.card.delivery', 'Delivery')}: {svc.deliveryTime}\n </p>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|