@burdenoff/microfe-crewfoundry 2026.704.3 → 2026.704.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/crewfoundry/pages/AdminAdminPagePage.js +76 -75
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +118 -117
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +115 -114
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +105 -104
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +52 -51
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +94 -93
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +97 -96
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +68 -67
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +96 -95
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +153 -152
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +107 -106
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +77 -76
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +80 -79
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +102 -101
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +126 -125
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +64 -63
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +96 -95
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +127 -126
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +118 -117
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +123 -122
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +77 -76
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +49 -48
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +62 -61
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +72 -71
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +70 -69
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +57 -56
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +58 -57
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +122 -121
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +70 -69
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +41 -40
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +65 -64
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +75 -74
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +60 -59
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +53 -52
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +37 -36
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +126 -125
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +62 -61
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +50 -49
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +72 -71
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +40 -39
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +130 -129
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +60 -59
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +177 -146
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/dist/crewfoundry/utils/formatEnumLabel.js +8 -0
- package/dist/crewfoundry/utils/formatEnumLabel.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
2
|
+
import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
|
|
3
|
+
import { FormModal as n, useFormModal as r } from "../components/forms/FormModal.js";
|
|
4
|
+
import { useState as i } from "react";
|
|
5
|
+
import { Plus as a, Search as o, Star as s, Users as c } from "lucide-react";
|
|
6
|
+
import { useNavigate as l } from "react-router-dom";
|
|
7
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
8
|
+
import { Badge as f, Button as p, CardContent as m, CardDescription as h, CardHeader as g, CardTitle as _, GlassCard as v, GradientText as y, IllustratedEmptyState as b, Input as x, PagePurpose as S, Pagination as C } from "@burdenoff/fe-libs/ui";
|
|
9
|
+
import { usePagination as w } from "@burdenoff/fe-libs/shared/hooks";
|
|
9
10
|
//#region src/crewfoundry/pages/LearningCoursesPagePage.tsx
|
|
10
|
-
var
|
|
11
|
+
var T = [
|
|
11
12
|
{
|
|
12
13
|
name: "title",
|
|
13
14
|
label: "Course Title",
|
|
@@ -96,80 +97,80 @@ var w = [
|
|
|
96
97
|
colSpan: 2
|
|
97
98
|
}
|
|
98
99
|
];
|
|
99
|
-
function
|
|
100
|
-
let { courses:
|
|
101
|
-
return /* @__PURE__ */
|
|
100
|
+
function E() {
|
|
101
|
+
let { courses: E, addCourse: D } = e(), O = l(), [k, A] = i(""), j = r(), { page: M, pageSize: N, offset: P, setPage: F } = w({ initialPageSize: 12 }), I = E.filter((e) => `${e.title} ${e.category} ${e.instructor}`.toLowerCase().includes(k.toLowerCase())), L = I.slice(P, P + N), R = (e) => O(`../../learning/course-details-page?id=${encodeURIComponent(e)}`);
|
|
102
|
+
return /* @__PURE__ */ d("div", {
|
|
102
103
|
className: "space-y-6 p-6",
|
|
103
104
|
children: [
|
|
104
|
-
/* @__PURE__ */
|
|
105
|
+
/* @__PURE__ */ d("div", {
|
|
105
106
|
className: "flex flex-wrap items-start justify-between gap-3",
|
|
106
|
-
children: [/* @__PURE__ */
|
|
107
|
-
/* @__PURE__ */
|
|
107
|
+
children: [/* @__PURE__ */ d("div", { children: [
|
|
108
|
+
/* @__PURE__ */ u("h1", {
|
|
108
109
|
className: "text-2xl font-semibold",
|
|
109
|
-
children: /* @__PURE__ */
|
|
110
|
+
children: /* @__PURE__ */ u(y, { children: "Course Catalog" })
|
|
110
111
|
}),
|
|
111
|
-
/* @__PURE__ */
|
|
112
|
+
/* @__PURE__ */ d("p", {
|
|
112
113
|
className: "text-sm text-text-secondary",
|
|
113
|
-
children: [
|
|
114
|
+
children: [E.length, " courses available"]
|
|
114
115
|
}),
|
|
115
|
-
/* @__PURE__ */
|
|
116
|
+
/* @__PURE__ */ u(S, {
|
|
116
117
|
className: "mt-1",
|
|
117
118
|
children: "Browse the course catalog — find training to grow your team's skills and enroll in the programs that fit your goals."
|
|
118
119
|
})
|
|
119
|
-
] }), /* @__PURE__ */
|
|
120
|
-
onClick: () =>
|
|
121
|
-
children: [/* @__PURE__ */
|
|
120
|
+
] }), /* @__PURE__ */ d(p, {
|
|
121
|
+
onClick: () => j.openModal(),
|
|
122
|
+
children: [/* @__PURE__ */ u(a, { className: "mr-1 h-4 w-4" }), "Create Course"]
|
|
122
123
|
})]
|
|
123
124
|
}),
|
|
124
|
-
/* @__PURE__ */
|
|
125
|
+
/* @__PURE__ */ d("div", {
|
|
125
126
|
className: "relative max-w-sm",
|
|
126
|
-
children: [/* @__PURE__ */
|
|
127
|
+
children: [/* @__PURE__ */ u(o, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ u(x, {
|
|
127
128
|
placeholder: "Search courses...",
|
|
128
129
|
className: "pl-9",
|
|
129
|
-
value:
|
|
130
|
+
value: k,
|
|
130
131
|
onChange: (e) => {
|
|
131
|
-
|
|
132
|
+
A(e.target.value), F(1);
|
|
132
133
|
}
|
|
133
134
|
})]
|
|
134
135
|
}),
|
|
135
|
-
/* @__PURE__ */
|
|
136
|
+
/* @__PURE__ */ u("div", {
|
|
136
137
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
137
|
-
children:
|
|
138
|
+
children: I.length === 0 ? /* @__PURE__ */ u("div", {
|
|
138
139
|
className: "col-span-full",
|
|
139
|
-
children: /* @__PURE__ */
|
|
140
|
+
children: /* @__PURE__ */ u(b, {
|
|
140
141
|
illustration: "empty-search",
|
|
141
142
|
title: "No courses found",
|
|
142
143
|
description: "Try a different search term to find training."
|
|
143
144
|
})
|
|
144
|
-
}) :
|
|
145
|
-
treatment:
|
|
146
|
-
glow:
|
|
145
|
+
}) : L.map((e, n) => /* @__PURE__ */ d(v, {
|
|
146
|
+
treatment: n === 0 ? "glass" : "plain",
|
|
147
|
+
glow: n === 0,
|
|
147
148
|
role: "button",
|
|
148
149
|
tabIndex: 0,
|
|
149
150
|
"aria-label": `View ${e.title}`,
|
|
150
|
-
onClick: () =>
|
|
151
|
+
onClick: () => R(e.id),
|
|
151
152
|
onKeyDown: (t) => {
|
|
152
|
-
(t.key === "Enter" || t.key === " ") && (t.preventDefault(),
|
|
153
|
+
(t.key === "Enter" || t.key === " ") && (t.preventDefault(), R(e.id));
|
|
153
154
|
},
|
|
154
155
|
className: "hover:shadow-md transition-shadow cursor-pointer focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]",
|
|
155
|
-
children: [/* @__PURE__ */
|
|
156
|
-
/* @__PURE__ */
|
|
156
|
+
children: [/* @__PURE__ */ d(g, { children: [
|
|
157
|
+
/* @__PURE__ */ d("div", {
|
|
157
158
|
className: "flex items-center justify-between",
|
|
158
|
-
children: [/* @__PURE__ */
|
|
159
|
+
children: [/* @__PURE__ */ u(f, {
|
|
159
160
|
variant: "outline",
|
|
160
161
|
className: "text-[10px]",
|
|
161
162
|
children: e.category
|
|
162
|
-
}), /* @__PURE__ */
|
|
163
|
+
}), /* @__PURE__ */ u(f, {
|
|
163
164
|
variant: e.level === "beginner" ? "secondary" : e.level === "intermediate" ? "default" : "destructive",
|
|
164
165
|
className: "text-[10px]",
|
|
165
|
-
children: e.level
|
|
166
|
+
children: t(e.level)
|
|
166
167
|
})]
|
|
167
168
|
}),
|
|
168
|
-
/* @__PURE__ */
|
|
169
|
+
/* @__PURE__ */ u(_, {
|
|
169
170
|
className: "text-base mt-2",
|
|
170
171
|
children: e.title
|
|
171
172
|
}),
|
|
172
|
-
/* @__PURE__ */
|
|
173
|
+
/* @__PURE__ */ d(h, { children: [
|
|
173
174
|
e.instructor,
|
|
174
175
|
" · ",
|
|
175
176
|
e.duration,
|
|
@@ -177,55 +178,55 @@ function T() {
|
|
|
177
178
|
e.modules,
|
|
178
179
|
" modules"
|
|
179
180
|
] })
|
|
180
|
-
] }), /* @__PURE__ */
|
|
181
|
-
/* @__PURE__ */
|
|
181
|
+
] }), /* @__PURE__ */ d(m, { children: [
|
|
182
|
+
/* @__PURE__ */ u("p", {
|
|
182
183
|
className: "text-sm text-text-secondary mb-3",
|
|
183
184
|
children: e.description
|
|
184
185
|
}),
|
|
185
|
-
/* @__PURE__ */
|
|
186
|
+
/* @__PURE__ */ u("div", {
|
|
186
187
|
className: "flex flex-wrap gap-1 mb-3",
|
|
187
|
-
children: e.skills.map((e) => /* @__PURE__ */
|
|
188
|
+
children: e.skills.map((e) => /* @__PURE__ */ u(f, {
|
|
188
189
|
variant: "outline",
|
|
189
190
|
className: "text-[9px]",
|
|
190
191
|
children: e
|
|
191
192
|
}, e))
|
|
192
193
|
}),
|
|
193
|
-
/* @__PURE__ */
|
|
194
|
+
/* @__PURE__ */ d("div", {
|
|
194
195
|
className: "flex items-center justify-between text-xs text-text-secondary",
|
|
195
196
|
children: [
|
|
196
|
-
/* @__PURE__ */
|
|
197
|
+
/* @__PURE__ */ d("span", {
|
|
197
198
|
className: "flex items-center gap-1",
|
|
198
|
-
children: [/* @__PURE__ */
|
|
199
|
+
children: [/* @__PURE__ */ u(s, { className: "h-3 w-3 text-status-warning-text" }), e.rating]
|
|
199
200
|
}),
|
|
200
|
-
/* @__PURE__ */
|
|
201
|
+
/* @__PURE__ */ d("span", {
|
|
201
202
|
className: "flex items-center gap-1",
|
|
202
203
|
children: [
|
|
203
|
-
/* @__PURE__ */
|
|
204
|
+
/* @__PURE__ */ u(c, { className: "h-3 w-3" }),
|
|
204
205
|
e.enrolled,
|
|
205
206
|
" enrolled"
|
|
206
207
|
]
|
|
207
208
|
}),
|
|
208
|
-
/* @__PURE__ */
|
|
209
|
+
/* @__PURE__ */ d("span", { children: [e.enrolled > 0 ? Math.round(e.completed / e.enrolled * 100) : 0, "% completion"] })
|
|
209
210
|
]
|
|
210
211
|
})
|
|
211
212
|
] })]
|
|
212
213
|
}, e.id))
|
|
213
214
|
}),
|
|
214
|
-
|
|
215
|
-
page:
|
|
216
|
-
pageSize:
|
|
217
|
-
totalItems:
|
|
218
|
-
onPageChange:
|
|
215
|
+
I.length > N && /* @__PURE__ */ u(C, {
|
|
216
|
+
page: M,
|
|
217
|
+
pageSize: N,
|
|
218
|
+
totalItems: I.length,
|
|
219
|
+
onPageChange: F
|
|
219
220
|
}),
|
|
220
|
-
/* @__PURE__ */
|
|
221
|
-
open:
|
|
222
|
-
onOpenChange:
|
|
221
|
+
/* @__PURE__ */ u(n, {
|
|
222
|
+
open: j.open,
|
|
223
|
+
onOpenChange: j.onOpenChange,
|
|
223
224
|
title: "Create Course",
|
|
224
225
|
description: "Add a new course to the catalog.",
|
|
225
|
-
fields:
|
|
226
|
+
fields: T,
|
|
226
227
|
submitLabel: "Create Course",
|
|
227
228
|
onSubmit: async (e) => {
|
|
228
|
-
await
|
|
229
|
+
await D({
|
|
229
230
|
id: `course-${Date.now()}`,
|
|
230
231
|
title: String(e.title ?? ""),
|
|
231
232
|
category: String(e.category ?? ""),
|
|
@@ -246,6 +247,6 @@ function T() {
|
|
|
246
247
|
});
|
|
247
248
|
}
|
|
248
249
|
//#endregion
|
|
249
|
-
export {
|
|
250
|
+
export { E as LearningCoursesPagePage };
|
|
250
251
|
|
|
251
252
|
//# sourceMappingURL=LearningCoursesPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LearningCoursesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningCoursesPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n Pagination,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { Plus, Search, Star, Users } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore, type LearningCourse } from '../store/crewfoundryStore';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\n\nconst COURSE_FIELDS: FieldConfig[] = [\n { name: 'title', label: 'Course Title', type: 'text', required: true, colSpan: 2 },\n { name: 'category', label: 'Category', type: 'text', required: true },\n { name: 'instructor', label: 'Instructor', type: 'text', required: true },\n {\n name: 'duration',\n label: 'Duration',\n type: 'text',\n required: true,\n placeholder: 'e.g. 6 weeks',\n },\n { name: 'modules', label: 'Modules', type: 'number', required: true, placeholder: 'e.g. 8' },\n {\n name: 'level',\n label: 'Level',\n type: 'select',\n required: true,\n options: [\n { label: 'Beginner', value: 'beginner' },\n { label: 'Intermediate', value: 'intermediate' },\n { label: 'Advanced', value: 'advanced' },\n ],\n },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n required: true,\n options: [\n { label: 'Active', value: 'active' },\n { label: 'Draft', value: 'draft' },\n { label: 'Archived', value: 'archived' },\n ],\n },\n { name: 'description', label: 'Description', type: 'textarea', required: true, colSpan: 2 },\n {\n name: 'skills',\n label: 'Skills',\n type: 'tags',\n placeholder: 'Add a skill and press Enter',\n colSpan: 2,\n },\n];\n\nexport function LearningCoursesPagePage() {\n const { courses, addCourse } = useCrewFoundryStore();\n const navigate = useNavigate();\n const [search, setSearch] = useState('');\n const createModal = useFormModal();\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 12 });\n const filtered = courses.filter((c) =>\n `${c.title} ${c.category} ${c.instructor}`.toLowerCase().includes(search.toLowerCase())\n );\n const paged = filtered.slice(offset, offset + pageSize);\n const openCourse = (id: string) =>\n navigate(`../../learning/course-details-page?id=${encodeURIComponent(id)}`);\n\n const handleCreate = async (values: FormValues) => {\n await addCourse({\n id: `course-${Date.now()}`,\n title: String(values.title ?? ''),\n category: String(values.category ?? ''),\n instructor: String(values.instructor ?? ''),\n duration: String(values.duration ?? ''),\n level: String(values.level ?? 'beginner') as LearningCourse['level'],\n enrolled: 0,\n completed: 0,\n rating: 0,\n status: String(values.status ?? 'draft') as LearningCourse['status'],\n description: String(values.description ?? ''),\n modules: typeof values.modules === 'number' ? values.modules : Number(values.modules) || 0,\n skills: Array.isArray(values.skills) ? values.skills : [],\n });\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Course Catalog</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{courses.length} courses available</p>\n <PagePurpose className=\"mt-1\">\n Browse the course catalog — find training to grow your team's skills and enroll in\n the programs that fit your goals.\n </PagePurpose>\n </div>\n <Button onClick={() => createModal.openModal()}>\n <Plus className=\"mr-1 h-4 w-4\" />\n Create Course\n </Button>\n </div>\n <div className=\"relative 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 courses...\"\n className=\"pl-9\"\n value={search}\n onChange={(e) => {\n setSearch(e.target.value);\n setPage(1);\n }}\n />\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {filtered.length === 0 ? (\n <div className=\"col-span-full\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No courses found\"\n description=\"Try a different search term to find training.\"\n />\n </div>\n ) : (\n paged.map((course, _idx) => (\n <GlassCard\n key={course.id}\n treatment={_idx === 0 ? 'glass' : 'plain'}\n glow={_idx === 0}\n role=\"button\"\n tabIndex={0}\n aria-label={`View ${course.title}`}\n onClick={() => openCourse(course.id)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n openCourse(course.id);\n }\n }}\n className=\"hover:shadow-md transition-shadow cursor-pointer focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]\"\n >\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {course.category}\n </Badge>\n <Badge\n variant={\n course.level === 'beginner'\n ? 'secondary'\n : course.level === 'intermediate'\n ? 'default'\n : 'destructive'\n }\n className=\"text-[10px]\"\n >\n {course.level}\n </Badge>\n </div>\n <CardTitle className=\"text-base mt-2\">{course.title}</CardTitle>\n <CardDescription>\n {course.instructor} · {course.duration} · {course.modules} modules\n </CardDescription>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-text-secondary mb-3\">{course.description}</p>\n <div className=\"flex flex-wrap gap-1 mb-3\">\n {course.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-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n {course.rating}\n </span>\n <span className=\"flex items-center gap-1\">\n <Users className=\"h-3 w-3\" />\n {course.enrolled} enrolled\n </span>\n <span>\n {course.enrolled > 0\n ? Math.round((course.completed / course.enrolled) * 100)\n : 0}\n % completion\n </span>\n </div>\n </CardContent>\n </GlassCard>\n ))\n )}\n </div>\n\n {filtered.length > pageSize && (\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={filtered.length}\n onPageChange={setPage}\n />\n )}\n\n <FormModal\n open={createModal.open}\n onOpenChange={createModal.onOpenChange}\n title=\"Create Course\"\n description=\"Add a new course to the catalog.\"\n fields={COURSE_FIELDS}\n submitLabel=\"Create Course\"\n onSubmit={handleCreate}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LearningCoursesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningCoursesPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n Pagination,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { Plus, Search, Star, Users } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore, type LearningCourse } from '../store/crewfoundryStore';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nconst COURSE_FIELDS: FieldConfig[] = [\n { name: 'title', label: 'Course Title', type: 'text', required: true, colSpan: 2 },\n { name: 'category', label: 'Category', type: 'text', required: true },\n { name: 'instructor', label: 'Instructor', type: 'text', required: true },\n {\n name: 'duration',\n label: 'Duration',\n type: 'text',\n required: true,\n placeholder: 'e.g. 6 weeks',\n },\n { name: 'modules', label: 'Modules', type: 'number', required: true, placeholder: 'e.g. 8' },\n {\n name: 'level',\n label: 'Level',\n type: 'select',\n required: true,\n options: [\n { label: 'Beginner', value: 'beginner' },\n { label: 'Intermediate', value: 'intermediate' },\n { label: 'Advanced', value: 'advanced' },\n ],\n },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n required: true,\n options: [\n { label: 'Active', value: 'active' },\n { label: 'Draft', value: 'draft' },\n { label: 'Archived', value: 'archived' },\n ],\n },\n { name: 'description', label: 'Description', type: 'textarea', required: true, colSpan: 2 },\n {\n name: 'skills',\n label: 'Skills',\n type: 'tags',\n placeholder: 'Add a skill and press Enter',\n colSpan: 2,\n },\n];\n\nexport function LearningCoursesPagePage() {\n const { courses, addCourse } = useCrewFoundryStore();\n const navigate = useNavigate();\n const [search, setSearch] = useState('');\n const createModal = useFormModal();\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 12 });\n const filtered = courses.filter((c) =>\n `${c.title} ${c.category} ${c.instructor}`.toLowerCase().includes(search.toLowerCase())\n );\n const paged = filtered.slice(offset, offset + pageSize);\n const openCourse = (id: string) =>\n navigate(`../../learning/course-details-page?id=${encodeURIComponent(id)}`);\n\n const handleCreate = async (values: FormValues) => {\n await addCourse({\n id: `course-${Date.now()}`,\n title: String(values.title ?? ''),\n category: String(values.category ?? ''),\n instructor: String(values.instructor ?? ''),\n duration: String(values.duration ?? ''),\n level: String(values.level ?? 'beginner') as LearningCourse['level'],\n enrolled: 0,\n completed: 0,\n rating: 0,\n status: String(values.status ?? 'draft') as LearningCourse['status'],\n description: String(values.description ?? ''),\n modules: typeof values.modules === 'number' ? values.modules : Number(values.modules) || 0,\n skills: Array.isArray(values.skills) ? values.skills : [],\n });\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Course Catalog</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{courses.length} courses available</p>\n <PagePurpose className=\"mt-1\">\n Browse the course catalog — find training to grow your team's skills and enroll in\n the programs that fit your goals.\n </PagePurpose>\n </div>\n <Button onClick={() => createModal.openModal()}>\n <Plus className=\"mr-1 h-4 w-4\" />\n Create Course\n </Button>\n </div>\n <div className=\"relative 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 courses...\"\n className=\"pl-9\"\n value={search}\n onChange={(e) => {\n setSearch(e.target.value);\n setPage(1);\n }}\n />\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {filtered.length === 0 ? (\n <div className=\"col-span-full\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No courses found\"\n description=\"Try a different search term to find training.\"\n />\n </div>\n ) : (\n paged.map((course, _idx) => (\n <GlassCard\n key={course.id}\n treatment={_idx === 0 ? 'glass' : 'plain'}\n glow={_idx === 0}\n role=\"button\"\n tabIndex={0}\n aria-label={`View ${course.title}`}\n onClick={() => openCourse(course.id)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n openCourse(course.id);\n }\n }}\n className=\"hover:shadow-md transition-shadow cursor-pointer focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]\"\n >\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {course.category}\n </Badge>\n <Badge\n variant={\n course.level === 'beginner'\n ? 'secondary'\n : course.level === 'intermediate'\n ? 'default'\n : 'destructive'\n }\n className=\"text-[10px]\"\n >\n {formatEnumLabel(course.level)}\n </Badge>\n </div>\n <CardTitle className=\"text-base mt-2\">{course.title}</CardTitle>\n <CardDescription>\n {course.instructor} · {course.duration} · {course.modules} modules\n </CardDescription>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-text-secondary mb-3\">{course.description}</p>\n <div className=\"flex flex-wrap gap-1 mb-3\">\n {course.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-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n {course.rating}\n </span>\n <span className=\"flex items-center gap-1\">\n <Users className=\"h-3 w-3\" />\n {course.enrolled} enrolled\n </span>\n <span>\n {course.enrolled > 0\n ? Math.round((course.completed / course.enrolled) * 100)\n : 0}\n % completion\n </span>\n </div>\n </CardContent>\n </GlassCard>\n ))\n )}\n </div>\n\n {filtered.length > pageSize && (\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={filtered.length}\n onPageChange={setPage}\n />\n )}\n\n <FormModal\n open={createModal.open}\n onOpenChange={createModal.onOpenChange}\n title=\"Create Course\"\n description=\"Add a new course to the catalog.\"\n fields={COURSE_FIELDS}\n submitLabel=\"Create Course\"\n onSubmit={handleCreate}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,141 +1,142 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
|
|
3
|
+
import { BookOpen as n, GraduationCap as r, Star as i, TrendingUp as a, Users as o } from "lucide-react";
|
|
4
|
+
import { useNavigate as s } from "react-router-dom";
|
|
5
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
6
|
+
import { Badge as u, Card as d, CardContent as f, CardDescription as p, CardHeader as m, CardTitle as h, GlassCard as g, GradientText as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
|
|
6
7
|
//#region src/crewfoundry/pages/LearningLearningPagePage.tsx
|
|
7
|
-
function
|
|
8
|
-
let
|
|
9
|
-
return /* @__PURE__ */
|
|
8
|
+
function y() {
|
|
9
|
+
let y = s(), { courses: b, learningPaths: x } = e(), S = b.reduce((e, t) => e + t.enrolled, 0), C = b.reduce((e, t) => e + t.completed, 0), w = [...b].sort((e, t) => t.rating - e.rating).slice(0, 3), T = (e) => y(`../../learning/course-details-page?id=${encodeURIComponent(e)}`), E = (e) => y(`../../learning/learning-path-detail-page?id=${encodeURIComponent(e)}`);
|
|
10
|
+
return /* @__PURE__ */ l("div", {
|
|
10
11
|
className: "space-y-6 p-6",
|
|
11
12
|
children: [
|
|
12
|
-
/* @__PURE__ */
|
|
13
|
-
/* @__PURE__ */
|
|
13
|
+
/* @__PURE__ */ l("div", { children: [
|
|
14
|
+
/* @__PURE__ */ c("h1", {
|
|
14
15
|
className: "text-2xl font-semibold",
|
|
15
|
-
children: /* @__PURE__ */
|
|
16
|
+
children: /* @__PURE__ */ c(_, { children: "Learning & Development" })
|
|
16
17
|
}),
|
|
17
|
-
/* @__PURE__ */
|
|
18
|
+
/* @__PURE__ */ c("p", {
|
|
18
19
|
className: "text-sm text-text-secondary",
|
|
19
20
|
children: "Explore courses, learning paths, and grow your skills"
|
|
20
21
|
}),
|
|
21
|
-
/* @__PURE__ */
|
|
22
|
+
/* @__PURE__ */ c(v, {
|
|
22
23
|
className: "mt-1",
|
|
23
24
|
children: "Your learning home — discover courses, continue where you left off, and keep developing the skills your role needs."
|
|
24
25
|
})
|
|
25
26
|
] }),
|
|
26
|
-
/* @__PURE__ */
|
|
27
|
+
/* @__PURE__ */ l("div", {
|
|
27
28
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
|
|
28
29
|
children: [
|
|
29
|
-
/* @__PURE__ */
|
|
30
|
+
/* @__PURE__ */ l(g, {
|
|
30
31
|
treatment: "glass",
|
|
31
32
|
glow: !0,
|
|
32
33
|
className: "border-border-seam",
|
|
33
|
-
children: [/* @__PURE__ */
|
|
34
|
+
children: [/* @__PURE__ */ l(m, {
|
|
34
35
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
35
|
-
children: [/* @__PURE__ */
|
|
36
|
+
children: [/* @__PURE__ */ c(h, {
|
|
36
37
|
className: "text-sm font-medium",
|
|
37
38
|
children: "Courses"
|
|
38
|
-
}), /* @__PURE__ */
|
|
39
|
-
}), /* @__PURE__ */
|
|
39
|
+
}), /* @__PURE__ */ c(n, { className: "h-4 w-4 text-text-secondary" })]
|
|
40
|
+
}), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ c("div", {
|
|
40
41
|
className: "text-2xl font-bold tabular-nums",
|
|
41
|
-
children:
|
|
42
|
-
}), /* @__PURE__ */
|
|
42
|
+
children: b.length
|
|
43
|
+
}), /* @__PURE__ */ c("p", {
|
|
43
44
|
className: "text-xs text-text-secondary",
|
|
44
45
|
children: "Active courses"
|
|
45
46
|
})] })]
|
|
46
47
|
}),
|
|
47
|
-
/* @__PURE__ */
|
|
48
|
+
/* @__PURE__ */ l(g, {
|
|
48
49
|
treatment: "metric",
|
|
49
50
|
className: "border-border-seam",
|
|
50
|
-
children: [/* @__PURE__ */
|
|
51
|
+
children: [/* @__PURE__ */ l(m, {
|
|
51
52
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
52
|
-
children: [/* @__PURE__ */
|
|
53
|
+
children: [/* @__PURE__ */ c(h, {
|
|
53
54
|
className: "text-sm font-medium",
|
|
54
55
|
children: "Enrolled"
|
|
55
|
-
}), /* @__PURE__ */
|
|
56
|
-
}), /* @__PURE__ */
|
|
56
|
+
}), /* @__PURE__ */ c(o, { className: "h-4 w-4 text-text-secondary" })]
|
|
57
|
+
}), /* @__PURE__ */ c(f, { children: /* @__PURE__ */ c("div", {
|
|
57
58
|
className: "text-2xl font-bold tabular-nums",
|
|
58
|
-
children:
|
|
59
|
+
children: S
|
|
59
60
|
}) })]
|
|
60
61
|
}),
|
|
61
|
-
/* @__PURE__ */
|
|
62
|
+
/* @__PURE__ */ l(g, {
|
|
62
63
|
treatment: "metric",
|
|
63
64
|
className: "border-border-seam",
|
|
64
|
-
children: [/* @__PURE__ */
|
|
65
|
+
children: [/* @__PURE__ */ l(m, {
|
|
65
66
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
66
|
-
children: [/* @__PURE__ */
|
|
67
|
+
children: [/* @__PURE__ */ c(h, {
|
|
67
68
|
className: "text-sm font-medium",
|
|
68
69
|
children: "Completed"
|
|
69
|
-
}), /* @__PURE__ */
|
|
70
|
-
}), /* @__PURE__ */
|
|
70
|
+
}), /* @__PURE__ */ c(r, { className: "h-4 w-4 text-status-success-text" })]
|
|
71
|
+
}), /* @__PURE__ */ c(f, { children: /* @__PURE__ */ c("div", {
|
|
71
72
|
className: "text-2xl font-bold tabular-nums",
|
|
72
|
-
children:
|
|
73
|
+
children: C
|
|
73
74
|
}) })]
|
|
74
75
|
}),
|
|
75
|
-
/* @__PURE__ */
|
|
76
|
+
/* @__PURE__ */ l(g, {
|
|
76
77
|
treatment: "metric",
|
|
77
78
|
className: "border-border-seam",
|
|
78
|
-
children: [/* @__PURE__ */
|
|
79
|
+
children: [/* @__PURE__ */ l(m, {
|
|
79
80
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
80
|
-
children: [/* @__PURE__ */
|
|
81
|
+
children: [/* @__PURE__ */ c(h, {
|
|
81
82
|
className: "text-sm font-medium",
|
|
82
83
|
children: "Paths"
|
|
83
|
-
}), /* @__PURE__ */
|
|
84
|
-
}), /* @__PURE__ */
|
|
84
|
+
}), /* @__PURE__ */ c(a, { className: "h-4 w-4 text-text-secondary" })]
|
|
85
|
+
}), /* @__PURE__ */ c(f, { children: /* @__PURE__ */ c("div", {
|
|
85
86
|
className: "text-2xl font-bold tabular-nums",
|
|
86
|
-
children:
|
|
87
|
+
children: x.length
|
|
87
88
|
}) })]
|
|
88
89
|
})
|
|
89
90
|
]
|
|
90
91
|
}),
|
|
91
|
-
/* @__PURE__ */
|
|
92
|
+
/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h2", {
|
|
92
93
|
className: "text-lg font-medium mb-3",
|
|
93
94
|
children: "Featured Courses"
|
|
94
|
-
}), /* @__PURE__ */
|
|
95
|
+
}), /* @__PURE__ */ c("div", {
|
|
95
96
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
96
|
-
children:
|
|
97
|
+
children: w.map((e) => /* @__PURE__ */ l(d, {
|
|
97
98
|
role: "button",
|
|
98
99
|
tabIndex: 0,
|
|
99
100
|
"aria-label": `View ${e.title}`,
|
|
100
|
-
onClick: () =>
|
|
101
|
+
onClick: () => T(e.id),
|
|
101
102
|
onKeyDown: (t) => {
|
|
102
|
-
(t.key === "Enter" || t.key === " ") && (t.preventDefault(),
|
|
103
|
+
(t.key === "Enter" || t.key === " ") && (t.preventDefault(), T(e.id));
|
|
103
104
|
},
|
|
104
105
|
className: "cursor-pointer transition-shadow hover:shadow-md focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]",
|
|
105
|
-
children: [/* @__PURE__ */
|
|
106
|
+
children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, {
|
|
106
107
|
className: "text-base",
|
|
107
108
|
children: e.title
|
|
108
|
-
}), /* @__PURE__ */
|
|
109
|
+
}), /* @__PURE__ */ l(p, { children: [
|
|
109
110
|
e.instructor,
|
|
110
111
|
" · ",
|
|
111
112
|
e.duration
|
|
112
|
-
] })] }), /* @__PURE__ */
|
|
113
|
-
/* @__PURE__ */
|
|
113
|
+
] })] }), /* @__PURE__ */ l(f, { children: [
|
|
114
|
+
/* @__PURE__ */ c("p", {
|
|
114
115
|
className: "text-sm text-text-secondary mb-3",
|
|
115
116
|
children: e.description
|
|
116
117
|
}),
|
|
117
|
-
/* @__PURE__ */
|
|
118
|
+
/* @__PURE__ */ l("div", {
|
|
118
119
|
className: "flex items-center justify-between",
|
|
119
|
-
children: [/* @__PURE__ */
|
|
120
|
+
children: [/* @__PURE__ */ l("div", {
|
|
120
121
|
className: "flex items-center gap-1",
|
|
121
|
-
children: [/* @__PURE__ */
|
|
122
|
+
children: [/* @__PURE__ */ c(i, { className: "h-3 w-3 text-status-warning-text" }), /* @__PURE__ */ c("span", {
|
|
122
123
|
className: "text-sm",
|
|
123
124
|
children: e.rating
|
|
124
125
|
})]
|
|
125
|
-
}), /* @__PURE__ */
|
|
126
|
+
}), /* @__PURE__ */ l("div", {
|
|
126
127
|
className: "flex gap-1",
|
|
127
|
-
children: [/* @__PURE__ */
|
|
128
|
+
children: [/* @__PURE__ */ c(u, {
|
|
128
129
|
variant: "outline",
|
|
129
130
|
className: "text-[10px]",
|
|
130
|
-
children: e.level
|
|
131
|
-
}), /* @__PURE__ */
|
|
131
|
+
children: t(e.level)
|
|
132
|
+
}), /* @__PURE__ */ c(u, {
|
|
132
133
|
variant: "outline",
|
|
133
134
|
className: "text-[10px]",
|
|
134
135
|
children: e.category
|
|
135
136
|
})]
|
|
136
137
|
})]
|
|
137
138
|
}),
|
|
138
|
-
/* @__PURE__ */
|
|
139
|
+
/* @__PURE__ */ l("div", {
|
|
139
140
|
className: "mt-2 text-xs text-text-secondary",
|
|
140
141
|
children: [
|
|
141
142
|
e.enrolled,
|
|
@@ -147,42 +148,42 @@ function v() {
|
|
|
147
148
|
] })]
|
|
148
149
|
}, e.id))
|
|
149
150
|
})] }),
|
|
150
|
-
/* @__PURE__ */
|
|
151
|
+
/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h2", {
|
|
151
152
|
className: "text-lg font-medium mb-3",
|
|
152
153
|
children: "Learning Paths"
|
|
153
|
-
}), /* @__PURE__ */
|
|
154
|
+
}), /* @__PURE__ */ c("div", {
|
|
154
155
|
className: "grid gap-4 md:grid-cols-3",
|
|
155
|
-
children:
|
|
156
|
+
children: x.map((e) => /* @__PURE__ */ l(d, {
|
|
156
157
|
role: "button",
|
|
157
158
|
tabIndex: 0,
|
|
158
159
|
"aria-label": `View ${e.title}`,
|
|
159
|
-
onClick: () =>
|
|
160
|
+
onClick: () => E(e.id),
|
|
160
161
|
onKeyDown: (t) => {
|
|
161
|
-
(t.key === "Enter" || t.key === " ") && (t.preventDefault(),
|
|
162
|
+
(t.key === "Enter" || t.key === " ") && (t.preventDefault(), E(e.id));
|
|
162
163
|
},
|
|
163
164
|
className: "cursor-pointer transition-shadow hover:shadow-md focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]",
|
|
164
|
-
children: [/* @__PURE__ */
|
|
165
|
+
children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ c(h, {
|
|
165
166
|
className: "text-base",
|
|
166
167
|
children: e.title
|
|
167
|
-
}), /* @__PURE__ */
|
|
168
|
+
}), /* @__PURE__ */ c(p, { children: e.description })] }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
|
|
168
169
|
className: "flex items-center justify-between text-sm text-text-secondary",
|
|
169
|
-
children: [/* @__PURE__ */
|
|
170
|
+
children: [/* @__PURE__ */ l("span", { children: [
|
|
170
171
|
e.courses.length,
|
|
171
172
|
" courses · ",
|
|
172
173
|
e.duration
|
|
173
|
-
] }), /* @__PURE__ */
|
|
174
|
+
] }), /* @__PURE__ */ c(u, {
|
|
174
175
|
variant: "outline",
|
|
175
176
|
className: "text-[10px]",
|
|
176
|
-
children: e.level
|
|
177
|
+
children: t(e.level)
|
|
177
178
|
})]
|
|
178
|
-
}), /* @__PURE__ */
|
|
179
|
+
}), /* @__PURE__ */ l("div", {
|
|
179
180
|
className: "mt-2 space-y-1",
|
|
180
|
-
children: [/* @__PURE__ */
|
|
181
|
+
children: [/* @__PURE__ */ l("div", {
|
|
181
182
|
className: "flex justify-between text-xs",
|
|
182
|
-
children: [/* @__PURE__ */
|
|
183
|
-
}), /* @__PURE__ */
|
|
183
|
+
children: [/* @__PURE__ */ l("span", { children: [e.enrolled, " enrolled"] }), /* @__PURE__ */ l("span", { children: [e.completionRate, "%"] })]
|
|
184
|
+
}), /* @__PURE__ */ c("div", {
|
|
184
185
|
className: "h-2 bg-bg-sunken rounded overflow-hidden",
|
|
185
|
-
children: /* @__PURE__ */
|
|
186
|
+
children: /* @__PURE__ */ c("div", {
|
|
186
187
|
className: "h-2 bg-action-primary-bg rounded",
|
|
187
188
|
style: { width: `${e.completionRate}%` }
|
|
188
189
|
})
|
|
@@ -194,6 +195,6 @@ function v() {
|
|
|
194
195
|
});
|
|
195
196
|
}
|
|
196
197
|
//#endregion
|
|
197
|
-
export {
|
|
198
|
+
export { y as LearningLearningPagePage };
|
|
198
199
|
|
|
199
200
|
//# sourceMappingURL=LearningLearningPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LearningLearningPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningLearningPagePage.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 { BookOpen, GraduationCap, Star, TrendingUp, Users } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function LearningLearningPagePage() {\n const navigate = useNavigate();\n const { courses, learningPaths } = useCrewFoundryStore();\n const totalEnrolled = courses.reduce((s, c) => s + c.enrolled, 0);\n const totalCompleted = courses.reduce((s, c) => s + c.completed, 0);\n const featuredCourses = [...courses].sort((a, b) => b.rating - a.rating).slice(0, 3);\n const openCourse = (id: string) =>\n navigate(`../../learning/course-details-page?id=${encodeURIComponent(id)}`);\n const openPath = (id: string) =>\n navigate(`../../learning/learning-path-detail-page?id=${encodeURIComponent(id)}`);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Learning & Development</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Explore courses, learning paths, and grow your skills\n </p>\n <PagePurpose className=\"mt-1\">\n Your learning home — discover courses, continue where you left off, and keep developing\n the skills your role needs.\n </PagePurpose>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg: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\">Courses</CardTitle>\n <BookOpen className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{courses.length}</div>\n <p className=\"text-xs text-text-secondary\">Active courses</p>\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\">Enrolled</CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{totalEnrolled}</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 <GraduationCap className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{totalCompleted}</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\">Paths</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{learningPaths.length}</div>\n </CardContent>\n </GlassCard>\n </div>\n <div>\n <h2 className=\"text-lg font-medium mb-3\">Featured Courses</h2>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {featuredCourses.map((course) => (\n <Card\n key={course.id}\n role=\"button\"\n tabIndex={0}\n aria-label={`View ${course.title}`}\n onClick={() => openCourse(course.id)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n openCourse(course.id);\n }\n }}\n className=\"cursor-pointer transition-shadow hover:shadow-md focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]\"\n >\n <CardHeader>\n <CardTitle className=\"text-base\">{course.title}</CardTitle>\n <CardDescription>\n {course.instructor} · {course.duration}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-text-secondary mb-3\">{course.description}</p>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n <span className=\"text-sm\">{course.rating}</span>\n </div>\n <div className=\"flex gap-1\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {course.level}\n </Badge>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {course.category}\n </Badge>\n </div>\n </div>\n <div className=\"mt-2 text-xs text-text-secondary\">\n {course.enrolled} enrolled · {course.completed} completed\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n <div>\n <h2 className=\"text-lg font-medium mb-3\">Learning Paths</h2>\n <div className=\"grid gap-4 md:grid-cols-3\">\n {learningPaths.map((path) => (\n <Card\n key={path.id}\n role=\"button\"\n tabIndex={0}\n aria-label={`View ${path.title}`}\n onClick={() => openPath(path.id)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n openPath(path.id);\n }\n }}\n className=\"cursor-pointer transition-shadow hover:shadow-md focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]\"\n >\n <CardHeader>\n <CardTitle className=\"text-base\">{path.title}</CardTitle>\n <CardDescription>{path.description}</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"flex items-center justify-between text-sm text-text-secondary\">\n <span>\n {path.courses.length} courses · {path.duration}\n </span>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {path.level}\n </Badge>\n </div>\n <div className=\"mt-2 space-y-1\">\n <div className=\"flex justify-between text-xs\">\n <span>{path.enrolled} enrolled</span>\n <span>{path.completionRate}%</span>\n </div>\n <div className=\"h-2 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-2 bg-action-primary-bg rounded\"\n style={{ width: `${path.completionRate}%` }}\n />\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LearningLearningPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningLearningPagePage.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 { BookOpen, GraduationCap, Star, TrendingUp, Users } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nexport function LearningLearningPagePage() {\n const navigate = useNavigate();\n const { courses, learningPaths } = useCrewFoundryStore();\n const totalEnrolled = courses.reduce((s, c) => s + c.enrolled, 0);\n const totalCompleted = courses.reduce((s, c) => s + c.completed, 0);\n const featuredCourses = [...courses].sort((a, b) => b.rating - a.rating).slice(0, 3);\n const openCourse = (id: string) =>\n navigate(`../../learning/course-details-page?id=${encodeURIComponent(id)}`);\n const openPath = (id: string) =>\n navigate(`../../learning/learning-path-detail-page?id=${encodeURIComponent(id)}`);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Learning & Development</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Explore courses, learning paths, and grow your skills\n </p>\n <PagePurpose className=\"mt-1\">\n Your learning home — discover courses, continue where you left off, and keep developing\n the skills your role needs.\n </PagePurpose>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg: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\">Courses</CardTitle>\n <BookOpen className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{courses.length}</div>\n <p className=\"text-xs text-text-secondary\">Active courses</p>\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\">Enrolled</CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{totalEnrolled}</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 <GraduationCap className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{totalCompleted}</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\">Paths</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{learningPaths.length}</div>\n </CardContent>\n </GlassCard>\n </div>\n <div>\n <h2 className=\"text-lg font-medium mb-3\">Featured Courses</h2>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {featuredCourses.map((course) => (\n <Card\n key={course.id}\n role=\"button\"\n tabIndex={0}\n aria-label={`View ${course.title}`}\n onClick={() => openCourse(course.id)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n openCourse(course.id);\n }\n }}\n className=\"cursor-pointer transition-shadow hover:shadow-md focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]\"\n >\n <CardHeader>\n <CardTitle className=\"text-base\">{course.title}</CardTitle>\n <CardDescription>\n {course.instructor} · {course.duration}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-text-secondary mb-3\">{course.description}</p>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n <span className=\"text-sm\">{course.rating}</span>\n </div>\n <div className=\"flex gap-1\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {formatEnumLabel(course.level)}\n </Badge>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {course.category}\n </Badge>\n </div>\n </div>\n <div className=\"mt-2 text-xs text-text-secondary\">\n {course.enrolled} enrolled · {course.completed} completed\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n <div>\n <h2 className=\"text-lg font-medium mb-3\">Learning Paths</h2>\n <div className=\"grid gap-4 md:grid-cols-3\">\n {learningPaths.map((path) => (\n <Card\n key={path.id}\n role=\"button\"\n tabIndex={0}\n aria-label={`View ${path.title}`}\n onClick={() => openPath(path.id)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n openPath(path.id);\n }\n }}\n className=\"cursor-pointer transition-shadow hover:shadow-md focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]\"\n >\n <CardHeader>\n <CardTitle className=\"text-base\">{path.title}</CardTitle>\n <CardDescription>{path.description}</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"flex items-center justify-between text-sm text-text-secondary\">\n <span>\n {path.courses.length} courses · {path.duration}\n </span>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {formatEnumLabel(path.level)}\n </Badge>\n </div>\n <div className=\"mt-2 space-y-1\">\n <div className=\"flex justify-between text-xs\">\n <span>{path.enrolled} enrolled</span>\n <span>{path.completionRate}%</span>\n </div>\n <div className=\"h-2 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-2 bg-action-primary-bg rounded\"\n style={{ width: `${path.completionRate}%` }}\n />\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|