@burdenoff/microfe-crewfoundry 2026.1013.2 → 2026.1029.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/CrewFoundryRoot.d.ts.map +1 -1
- package/dist/crewfoundry/CrewFoundryRoot.js +160 -256
- package/dist/crewfoundry/CrewFoundryRoot.js.map +1 -1
- package/dist/crewfoundry/CrewFoundryRoutes.d.ts.map +1 -1
- package/dist/crewfoundry/CrewFoundryRoutes.js +152 -192
- package/dist/crewfoundry/CrewFoundryRoutes.js.map +1 -1
- package/dist/crewfoundry/components/InlineError.d.ts +5 -0
- package/dist/crewfoundry/components/InlineError.d.ts.map +1 -0
- package/dist/crewfoundry/components/InlineError.js +17 -0
- package/dist/crewfoundry/components/InlineError.js.map +1 -0
- package/dist/crewfoundry/components/marketplace/BookServiceModal.d.ts +14 -0
- package/dist/crewfoundry/components/marketplace/BookServiceModal.d.ts.map +1 -0
- package/dist/crewfoundry/components/marketplace/BookServiceModal.js +75 -0
- package/dist/crewfoundry/components/marketplace/BookServiceModal.js.map +1 -0
- package/dist/crewfoundry/components/marketplace/MarketplaceTabs.d.ts +24 -0
- package/dist/crewfoundry/components/marketplace/MarketplaceTabs.d.ts.map +1 -0
- package/dist/crewfoundry/components/marketplace/MarketplaceTabs.js +47 -0
- package/dist/crewfoundry/components/marketplace/MarketplaceTabs.js.map +1 -0
- package/dist/crewfoundry/components/marketplace/ServiceListingModal.d.ts +12 -0
- package/dist/crewfoundry/components/marketplace/ServiceListingModal.d.ts.map +1 -0
- package/dist/crewfoundry/components/marketplace/ServiceListingModal.js +123 -0
- package/dist/crewfoundry/components/marketplace/ServiceListingModal.js.map +1 -0
- package/dist/crewfoundry/components/viz/CertificateCard.js +4 -118
- package/dist/crewfoundry/components/viz/PathSteps.js +3 -68
- package/dist/crewfoundry/components/viz/lib/geometry.js +5 -13
- package/dist/crewfoundry/components/viz/lib/geometry.js.map +1 -1
- package/dist/crewfoundry/lib/analytics.d.ts +1 -6
- package/dist/crewfoundry/lib/analytics.d.ts.map +1 -1
- package/dist/crewfoundry/lib/analytics.js +3 -18
- package/dist/crewfoundry/lib/analytics.js.map +1 -1
- package/dist/crewfoundry/lib/companyFinance.d.ts +3 -7
- package/dist/crewfoundry/lib/companyFinance.d.ts.map +1 -1
- package/dist/crewfoundry/lib/companyFinance.js +3 -8
- package/dist/crewfoundry/lib/companyFinance.js.map +1 -1
- package/dist/crewfoundry/lib/learning.d.ts +12 -0
- package/dist/crewfoundry/lib/learning.d.ts.map +1 -0
- package/dist/crewfoundry/lib/learning.js +26 -0
- package/dist/crewfoundry/lib/learning.js.map +1 -0
- package/dist/crewfoundry/lib/marketplace.d.ts +30 -0
- package/dist/crewfoundry/lib/marketplace.d.ts.map +1 -0
- package/dist/crewfoundry/lib/marketplace.js +91 -0
- package/dist/crewfoundry/lib/marketplace.js.map +1 -0
- package/dist/crewfoundry/lib/useEnsureLoaded.d.ts +7 -0
- package/dist/crewfoundry/lib/useEnsureLoaded.d.ts.map +1 -0
- package/dist/crewfoundry/lib/useEnsureLoaded.js +25 -0
- package/dist/crewfoundry/lib/useEnsureLoaded.js.map +1 -0
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +12 -25
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +145 -157
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +14 -14
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +14 -14
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +71 -33
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +247 -173
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.d.ts +12 -0
- package/dist/crewfoundry/pages/LearningCoursesPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +307 -293
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningEnrollmentsPagePage.d.ts +2 -0
- package/dist/crewfoundry/pages/LearningEnrollmentsPagePage.d.ts.map +1 -0
- package/dist/crewfoundry/pages/LearningEnrollmentsPagePage.js +223 -0
- package/dist/crewfoundry/pages/LearningEnrollmentsPagePage.js.map +1 -0
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.d.ts +4 -0
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +115 -160
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +165 -75
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEscrowPagePage.d.ts +7 -0
- package/dist/crewfoundry/pages/MarketplaceEscrowPagePage.d.ts.map +1 -0
- package/dist/crewfoundry/pages/MarketplaceEscrowPagePage.js +175 -0
- package/dist/crewfoundry/pages/MarketplaceEscrowPagePage.js.map +1 -0
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +182 -223
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +168 -227
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +127 -290
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.d.ts +138 -78
- package/dist/crewfoundry/store/crewfoundryStore.d.ts.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +338 -244
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/dist/crewfoundry/utils/dateUtils.d.ts +5 -0
- package/dist/crewfoundry/utils/dateUtils.d.ts.map +1 -1
- package/dist/crewfoundry/utils/dateUtils.js +10 -1
- package/dist/crewfoundry/utils/dateUtils.js.map +1 -1
- package/dist/generated/global-types.d.ts +5145 -1627
- package/dist/generated/global-types.d.ts.map +1 -1
- package/dist/generated/wspace-types.d.ts +100373 -34602
- package/dist/generated/wspace-types.d.ts.map +1 -1
- package/dist/utils/pageContext.d.ts.map +1 -1
- package/dist/utils/pageContext.js +0 -1
- package/dist/utils/pageContext.js.map +1 -1
- package/package.json +1 -1
- package/dist/crewfoundry/components/viz/CertificateCard.js.map +0 -1
- package/dist/crewfoundry/components/viz/PathSteps.js.map +0 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +0 -53
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +0 -107
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +0 -62
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +0 -37
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +0 -111
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +0 -309
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/LearningLearningPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +0 -200
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +0 -190
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +0 -230
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +0 -293
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +0 -163
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.d.ts +0 -2
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +0 -365
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +0 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +0 -224
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +0 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +0 -180
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +0 -38
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +0 -204
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +0 -55
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +0 -335
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +0 -160
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +0 -80
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +0 -1
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.d.ts +0 -2
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.d.ts.map +0 -1
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +0 -191
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +0 -1
- package/dist/crewfoundry/utils/courseProgress.d.ts +0 -33
- package/dist/crewfoundry/utils/courseProgress.d.ts.map +0 -1
- package/dist/crewfoundry/utils/courseProgress.js +0 -46
- package/dist/crewfoundry/utils/courseProgress.js.map +0 -1
|
@@ -1,200 +1,274 @@
|
|
|
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 { StatCard as t } from "../components/viz/StatCard.js";
|
|
3
|
+
import { AvatarStack as n } from "../components/viz/AvatarStack.js";
|
|
4
|
+
import "../components/viz/index.js";
|
|
5
|
+
import { FormModal as r, useFormModal as i } from "../components/forms/FormModal.js";
|
|
6
|
+
import { formatDate as a } from "../utils/dateUtils.js";
|
|
7
|
+
import { InlineError as o } from "../components/InlineError.js";
|
|
8
|
+
import { ENROLLMENT_STATUS_LABEL as s, ENROLLMENT_STATUS_OPTIONS as c, formatDuration as ee } from "../lib/learning.js";
|
|
9
|
+
import { useEnsureLoaded as te } from "../lib/useEnsureLoaded.js";
|
|
10
|
+
import { COURSE_FIELDS as ne, courseToValues as re, valuesToCourseInput as ie } from "./LearningCoursesPagePage.js";
|
|
11
|
+
import { useMemo as ae, useState as l } from "react";
|
|
12
|
+
import { ArrowLeft as oe, Clock as u, ExternalLink as d, Pencil as f, Trash2 as se, UserPlus as ce } from "lucide-react";
|
|
13
|
+
import { useNavigate as p, useSearchParams as m } from "react-router";
|
|
14
|
+
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
15
|
+
import { Badge as _, Button as v, Card as y, CardContent as b, CardDescription as x, CardHeader as S, CardTitle as C, GradientText as le, IllustratedEmptyState as w, ResponsiveTable as T, Select as E, SelectContent as D, SelectItem as O, SelectTrigger as k, SelectValue as A, Spinner as j } from "@burdenoff/fe-libs/ui";
|
|
9
16
|
//#region src/crewfoundry/pages/LearningCourseDetailsPagePage.tsx
|
|
10
|
-
function
|
|
11
|
-
let
|
|
12
|
-
|
|
17
|
+
function M() {
|
|
18
|
+
let M = p(), [N] = m(), { trainingCourses: P, enrollments: F, employees: I, learningLoaded: L, fetchLearning: R, updateTrainingCourse: ue, enrollEmployee: z, updateEnrollmentStatus: B, removeEnrollment: V } = e(), H = te(L, R), U = i(), W = i(), [G, K] = l(), [de, q] = l(null), J = N.get("id"), Y = P.find((e) => e.id === J), X = ae(() => F.filter((e) => e.courseId === J), [F, J]), fe = new Set(X.map((e) => e.employeeId)), Z = I.filter((e) => e.status !== "terminated" && !fe.has(e.id)), Q = async (e) => {
|
|
19
|
+
q(null);
|
|
20
|
+
try {
|
|
21
|
+
await e();
|
|
22
|
+
} catch (e) {
|
|
23
|
+
q(e instanceof Error ? e.message : "Something went wrong");
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
if (!L && !H) return /* @__PURE__ */ h("div", {
|
|
13
27
|
className: "flex min-h-[60vh] items-center justify-center p-6",
|
|
14
|
-
children: /* @__PURE__ */
|
|
28
|
+
children: /* @__PURE__ */ h(j, { size: "lg" })
|
|
15
29
|
});
|
|
16
|
-
if (!
|
|
17
|
-
className: "p-6",
|
|
18
|
-
children: /* @__PURE__ */
|
|
30
|
+
if (!Y) return /* @__PURE__ */ g("div", {
|
|
31
|
+
className: "space-y-4 p-6",
|
|
32
|
+
children: [/* @__PURE__ */ h(o, { message: H }), /* @__PURE__ */ h(w, {
|
|
19
33
|
illustration: "empty-search",
|
|
20
34
|
title: "Course not found",
|
|
21
|
-
description: "This course
|
|
22
|
-
|
|
35
|
+
description: "This course was removed or the link is incomplete.",
|
|
36
|
+
action: /* @__PURE__ */ h(v, {
|
|
37
|
+
size: "sm",
|
|
38
|
+
onClick: () => M("../learning/courses-page"),
|
|
39
|
+
children: "Back to courses"
|
|
40
|
+
})
|
|
41
|
+
})]
|
|
23
42
|
});
|
|
24
|
-
let
|
|
25
|
-
return /* @__PURE__ */
|
|
26
|
-
className: "space-y-6 p-6
|
|
43
|
+
let $ = (e) => X.filter((t) => t.status === e).length;
|
|
44
|
+
return /* @__PURE__ */ g("div", {
|
|
45
|
+
className: "space-y-6 p-6",
|
|
27
46
|
children: [
|
|
28
|
-
/* @__PURE__ */
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
47
|
+
/* @__PURE__ */ g(v, {
|
|
48
|
+
variant: "ghost",
|
|
49
|
+
size: "sm",
|
|
50
|
+
onClick: () => M("../learning/courses-page"),
|
|
51
|
+
children: [/* @__PURE__ */ h(oe, { className: "mr-1 h-4 w-4" }), "Courses"]
|
|
52
|
+
}),
|
|
53
|
+
/* @__PURE__ */ g("div", {
|
|
54
|
+
className: "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",
|
|
55
|
+
children: [/* @__PURE__ */ g("div", {
|
|
56
|
+
className: "min-w-0",
|
|
57
|
+
children: [/* @__PURE__ */ g("div", {
|
|
58
|
+
className: "flex flex-wrap items-center gap-2",
|
|
59
|
+
children: [/* @__PURE__ */ h("h1", {
|
|
34
60
|
className: "text-2xl font-semibold",
|
|
35
|
-
children: /* @__PURE__ */
|
|
36
|
-
}), /* @__PURE__ */
|
|
37
|
-
variant:
|
|
38
|
-
|
|
61
|
+
children: /* @__PURE__ */ h(le, { children: Y.title })
|
|
62
|
+
}), /* @__PURE__ */ h(_, {
|
|
63
|
+
variant: Y.isActive ? "default" : "secondary",
|
|
64
|
+
className: "text-[10px]",
|
|
65
|
+
children: Y.isActive ? "Active" : "Archived"
|
|
39
66
|
})]
|
|
67
|
+
}), /* @__PURE__ */ g("p", {
|
|
68
|
+
className: "mt-1 flex items-center gap-1 text-sm text-text-secondary",
|
|
69
|
+
children: [/* @__PURE__ */ h(u, { className: "h-3.5 w-3.5" }), ee(Y.durationMinutes)]
|
|
70
|
+
})]
|
|
71
|
+
}), /* @__PURE__ */ g("div", {
|
|
72
|
+
className: "flex flex-wrap gap-2",
|
|
73
|
+
children: [
|
|
74
|
+
/* @__PURE__ */ h(v, {
|
|
75
|
+
size: "sm",
|
|
76
|
+
variant: "outline",
|
|
77
|
+
asChild: !0,
|
|
78
|
+
children: /* @__PURE__ */ g("a", {
|
|
79
|
+
href: Y.contentUrl,
|
|
80
|
+
target: "_blank",
|
|
81
|
+
rel: "noopener noreferrer",
|
|
82
|
+
children: [/* @__PURE__ */ h(d, { className: "mr-1 h-4 w-4" }), "Open content"]
|
|
83
|
+
})
|
|
84
|
+
}),
|
|
85
|
+
/* @__PURE__ */ g(v, {
|
|
86
|
+
size: "sm",
|
|
87
|
+
variant: "outline",
|
|
88
|
+
onClick: () => {
|
|
89
|
+
K(void 0), U.openModal();
|
|
90
|
+
},
|
|
91
|
+
children: [/* @__PURE__ */ h(f, { className: "mr-1 h-4 w-4" }), "Edit"]
|
|
92
|
+
}),
|
|
93
|
+
/* @__PURE__ */ g(v, {
|
|
94
|
+
size: "sm",
|
|
95
|
+
disabled: !Y.isActive || Z.length === 0,
|
|
96
|
+
title: Y.isActive ? Z.length === 0 ? "Every active employee is already enrolled" : void 0 : "Reactivate the course to enroll employees",
|
|
97
|
+
onClick: () => {
|
|
98
|
+
K(void 0), W.openModal();
|
|
99
|
+
},
|
|
100
|
+
children: [/* @__PURE__ */ h(ce, { className: "mr-1 h-4 w-4" }), "Enroll employee"]
|
|
101
|
+
})
|
|
102
|
+
]
|
|
103
|
+
})]
|
|
104
|
+
}),
|
|
105
|
+
/* @__PURE__ */ h(o, { message: H ?? de }),
|
|
106
|
+
/* @__PURE__ */ g(y, { children: [/* @__PURE__ */ h(S, { children: /* @__PURE__ */ h(C, {
|
|
107
|
+
className: "text-base",
|
|
108
|
+
children: "About this course"
|
|
109
|
+
}) }), /* @__PURE__ */ g(b, {
|
|
110
|
+
className: "space-y-3",
|
|
111
|
+
children: [/* @__PURE__ */ h("p", {
|
|
112
|
+
className: "whitespace-pre-line text-sm text-text-secondary",
|
|
113
|
+
children: Y.description
|
|
114
|
+
}), Y.requiredForRoles.length > 0 && /* @__PURE__ */ g("div", {
|
|
115
|
+
className: "flex flex-wrap items-center gap-1",
|
|
116
|
+
children: [/* @__PURE__ */ h("span", {
|
|
117
|
+
className: "mr-1 text-xs text-text-secondary",
|
|
118
|
+
children: "Required for"
|
|
119
|
+
}), Y.requiredForRoles.map((e) => /* @__PURE__ */ h(_, {
|
|
120
|
+
variant: "outline",
|
|
121
|
+
className: "text-[10px]",
|
|
122
|
+
children: e
|
|
123
|
+
}, e))]
|
|
124
|
+
})]
|
|
125
|
+
})] }),
|
|
126
|
+
/* @__PURE__ */ g("div", {
|
|
127
|
+
className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-4",
|
|
128
|
+
children: [
|
|
129
|
+
/* @__PURE__ */ h(t, {
|
|
130
|
+
label: "Enrolled",
|
|
131
|
+
value: X.length
|
|
40
132
|
}),
|
|
41
|
-
/* @__PURE__ */
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"by ",
|
|
45
|
-
F.instructor,
|
|
46
|
-
" · ",
|
|
47
|
-
F.category
|
|
48
|
-
]
|
|
133
|
+
/* @__PURE__ */ h(t, {
|
|
134
|
+
label: s.not_started,
|
|
135
|
+
value: $("not_started")
|
|
49
136
|
}),
|
|
50
|
-
/* @__PURE__ */
|
|
51
|
-
|
|
52
|
-
|
|
137
|
+
/* @__PURE__ */ h(t, {
|
|
138
|
+
label: s.in_progress,
|
|
139
|
+
value: $("in_progress")
|
|
140
|
+
}),
|
|
141
|
+
/* @__PURE__ */ h(t, {
|
|
142
|
+
label: s.completed,
|
|
143
|
+
value: $("completed")
|
|
53
144
|
})
|
|
54
|
-
]
|
|
55
|
-
onClick: async () => {
|
|
56
|
-
N(!0);
|
|
57
|
-
try {
|
|
58
|
-
await k(F.id), j("Enrolled — your course is ready", "success"), E(`../learning/course-learning-page?id=${encodeURIComponent(F.id)}`);
|
|
59
|
-
} catch (e) {
|
|
60
|
-
j(e instanceof Error ? e.message : "Unable to enroll in course", "error");
|
|
61
|
-
} finally {
|
|
62
|
-
N(!1);
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
disabled: M,
|
|
66
|
-
children: [/* @__PURE__ */ d(o, { className: "h-4 w-4 mr-1" }), M ? "Enrolling…" : "Start Course"]
|
|
67
|
-
})]
|
|
145
|
+
]
|
|
68
146
|
}),
|
|
69
|
-
/* @__PURE__ */
|
|
70
|
-
|
|
71
|
-
|
|
147
|
+
/* @__PURE__ */ g(y, { children: [/* @__PURE__ */ g(S, { children: [/* @__PURE__ */ h(C, {
|
|
148
|
+
className: "text-base",
|
|
149
|
+
children: "Enrolled employees"
|
|
150
|
+
}), /* @__PURE__ */ h(x, { children: "Update each person’s progress as they start and finish the course." })] }), /* @__PURE__ */ h(b, { children: /* @__PURE__ */ h(T, {
|
|
151
|
+
data: X,
|
|
152
|
+
rowKey: (e) => e.id,
|
|
153
|
+
columns: [
|
|
154
|
+
{
|
|
155
|
+
key: "employee",
|
|
156
|
+
header: "Employee",
|
|
157
|
+
priority: "primary",
|
|
158
|
+
cell: (e) => /* @__PURE__ */ g("div", {
|
|
159
|
+
className: "flex items-center gap-2.5",
|
|
160
|
+
children: [/* @__PURE__ */ h(n, {
|
|
161
|
+
people: [{ name: e.employeeName }],
|
|
162
|
+
size: 28
|
|
163
|
+
}), /* @__PURE__ */ h("span", {
|
|
164
|
+
className: "font-medium",
|
|
165
|
+
children: e.employeeName
|
|
166
|
+
})]
|
|
167
|
+
})
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
key: "status",
|
|
171
|
+
header: "Status",
|
|
172
|
+
cell: (e) => /* @__PURE__ */ g(E, {
|
|
173
|
+
value: e.status,
|
|
174
|
+
onValueChange: (t) => void Q(() => B(e.id, t)),
|
|
175
|
+
children: [/* @__PURE__ */ h(k, {
|
|
176
|
+
className: "h-8 w-36",
|
|
177
|
+
"aria-label": `Status for ${e.employeeName}`,
|
|
178
|
+
children: /* @__PURE__ */ h(A, {})
|
|
179
|
+
}), /* @__PURE__ */ h(D, { children: c.map((e) => /* @__PURE__ */ h(O, {
|
|
180
|
+
value: e.value,
|
|
181
|
+
children: e.label
|
|
182
|
+
}, e.value)) })]
|
|
183
|
+
})
|
|
184
|
+
},
|
|
72
185
|
{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
186
|
+
key: "started",
|
|
187
|
+
header: "Started",
|
|
188
|
+
cell: (e) => /* @__PURE__ */ h("span", {
|
|
189
|
+
className: "text-text-secondary",
|
|
190
|
+
children: e.startedAt ? a(e.startedAt) : "—"
|
|
191
|
+
})
|
|
78
192
|
},
|
|
79
193
|
{
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
194
|
+
key: "completed",
|
|
195
|
+
header: "Completed",
|
|
196
|
+
cell: (e) => /* @__PURE__ */ h("span", {
|
|
197
|
+
className: "text-text-secondary",
|
|
198
|
+
children: e.completedAt ? a(e.completedAt) : "—"
|
|
199
|
+
})
|
|
85
200
|
},
|
|
86
201
|
{
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
202
|
+
key: "actions",
|
|
203
|
+
header: "",
|
|
204
|
+
cellClassName: "md:text-right",
|
|
205
|
+
cell: (e) => /* @__PURE__ */ h(v, {
|
|
206
|
+
variant: "ghost",
|
|
207
|
+
size: "icon",
|
|
208
|
+
className: "h-8 w-8",
|
|
209
|
+
"aria-label": `Remove ${e.employeeName} from this course`,
|
|
210
|
+
onClick: () => void Q(() => V(e.id)),
|
|
211
|
+
children: /* @__PURE__ */ h(se, { className: "h-4 w-4" })
|
|
212
|
+
})
|
|
92
213
|
}
|
|
93
|
-
]
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
children: [
|
|
98
|
-
/* @__PURE__ */ d(h, { children: /* @__PURE__ */ f(g, {
|
|
99
|
-
className: "p-4 text-center",
|
|
100
|
-
children: [
|
|
101
|
-
/* @__PURE__ */ d(i, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
102
|
-
/* @__PURE__ */ d("p", {
|
|
103
|
-
className: "text-lg font-bold",
|
|
104
|
-
children: F.duration
|
|
105
|
-
}),
|
|
106
|
-
/* @__PURE__ */ d("p", {
|
|
107
|
-
className: "text-xs text-text-secondary",
|
|
108
|
-
children: "Duration"
|
|
109
|
-
})
|
|
110
|
-
]
|
|
111
|
-
}) }),
|
|
112
|
-
/* @__PURE__ */ d(h, { children: /* @__PURE__ */ f(g, {
|
|
113
|
-
className: "p-4 text-center",
|
|
114
|
-
children: [
|
|
115
|
-
/* @__PURE__ */ d(r, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
116
|
-
/* @__PURE__ */ d("p", {
|
|
117
|
-
className: "text-lg font-bold",
|
|
118
|
-
children: F.modules
|
|
119
|
-
}),
|
|
120
|
-
/* @__PURE__ */ d("p", {
|
|
121
|
-
className: "text-xs text-text-secondary",
|
|
122
|
-
children: "Modules"
|
|
123
|
-
})
|
|
124
|
-
]
|
|
125
|
-
}) }),
|
|
126
|
-
/* @__PURE__ */ d(h, { children: /* @__PURE__ */ f(g, {
|
|
127
|
-
className: "p-4 text-center",
|
|
128
|
-
children: [
|
|
129
|
-
/* @__PURE__ */ d(c, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
130
|
-
/* @__PURE__ */ d("p", {
|
|
131
|
-
className: "text-lg font-bold",
|
|
132
|
-
children: F.enrolled
|
|
133
|
-
}),
|
|
134
|
-
/* @__PURE__ */ d("p", {
|
|
135
|
-
className: "text-xs text-text-secondary",
|
|
136
|
-
children: "Enrolled"
|
|
137
|
-
})
|
|
138
|
-
]
|
|
139
|
-
}) }),
|
|
140
|
-
/* @__PURE__ */ d(h, { children: /* @__PURE__ */ f(g, {
|
|
141
|
-
className: "p-4 text-center",
|
|
142
|
-
children: [
|
|
143
|
-
/* @__PURE__ */ d(s, { className: "h-5 w-5 mx-auto text-status-warning-text mb-1" }),
|
|
144
|
-
/* @__PURE__ */ f("p", {
|
|
145
|
-
className: "text-lg font-bold",
|
|
146
|
-
children: [F.rating, "/5"]
|
|
147
|
-
}),
|
|
148
|
-
/* @__PURE__ */ d("p", {
|
|
149
|
-
className: "text-xs text-text-secondary",
|
|
150
|
-
children: "Rating"
|
|
151
|
-
})
|
|
152
|
-
]
|
|
153
|
-
}) })
|
|
154
|
-
]
|
|
155
|
-
}),
|
|
156
|
-
/* @__PURE__ */ f(y, { children: [
|
|
157
|
-
/* @__PURE__ */ d("div", {
|
|
158
|
-
className: "mb-2 text-lg font-semibold",
|
|
159
|
-
children: "About this Course"
|
|
160
|
-
}),
|
|
161
|
-
/* @__PURE__ */ d("p", {
|
|
162
|
-
className: "text-sm text-text-secondary",
|
|
163
|
-
children: F.description
|
|
164
|
-
}),
|
|
165
|
-
/* @__PURE__ */ d("div", {
|
|
166
|
-
className: "flex flex-wrap gap-1 mt-3",
|
|
167
|
-
children: F.skills.map((e) => /* @__PURE__ */ d(p, {
|
|
168
|
-
variant: "outline",
|
|
169
|
-
children: e
|
|
170
|
-
}, e))
|
|
214
|
+
],
|
|
215
|
+
emptyState: /* @__PURE__ */ h("p", {
|
|
216
|
+
className: "py-6 text-center text-sm text-text-secondary",
|
|
217
|
+
children: "No one is enrolled yet."
|
|
171
218
|
})
|
|
172
|
-
] }),
|
|
173
|
-
/* @__PURE__ */
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
219
|
+
}) })] }),
|
|
220
|
+
/* @__PURE__ */ h(r, {
|
|
221
|
+
open: U.open,
|
|
222
|
+
onOpenChange: U.onOpenChange,
|
|
223
|
+
title: "Edit course",
|
|
224
|
+
fields: ne,
|
|
225
|
+
initialValues: re(Y),
|
|
226
|
+
submitLabel: "Save changes",
|
|
227
|
+
errorMessage: G,
|
|
228
|
+
onValidationError: K,
|
|
229
|
+
onSubmit: async (e) => {
|
|
230
|
+
K(void 0);
|
|
231
|
+
try {
|
|
232
|
+
await ue(Y.id, ie(e));
|
|
233
|
+
} catch (e) {
|
|
234
|
+
throw K(e instanceof Error ? e.message : "Unable to save course"), e;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}),
|
|
238
|
+
/* @__PURE__ */ h(r, {
|
|
239
|
+
open: W.open,
|
|
240
|
+
onOpenChange: W.onOpenChange,
|
|
241
|
+
title: "Enroll employee",
|
|
242
|
+
description: `Enroll someone in “${Y.title}”. They start as Not started.`,
|
|
243
|
+
fields: [{
|
|
244
|
+
name: "employeeId",
|
|
245
|
+
label: "Employee",
|
|
246
|
+
type: "select",
|
|
247
|
+
required: !0,
|
|
248
|
+
colSpan: 2,
|
|
249
|
+
options: Z.map((e) => ({
|
|
250
|
+
value: e.id,
|
|
251
|
+
label: `${e.firstName} ${e.lastName} · ${e.position}`
|
|
252
|
+
}))
|
|
253
|
+
}],
|
|
254
|
+
submitLabel: "Enroll",
|
|
255
|
+
errorMessage: G,
|
|
256
|
+
onValidationError: K,
|
|
257
|
+
onSubmit: async (e) => {
|
|
258
|
+
K(void 0);
|
|
259
|
+
let t = I.find((t) => t.id === e.employeeId);
|
|
260
|
+
try {
|
|
261
|
+
if (!t) throw Error("Choose an employee to enroll");
|
|
262
|
+
await z(Y.id, t);
|
|
263
|
+
} catch (e) {
|
|
264
|
+
throw K(e instanceof Error ? e.message : "Unable to enroll employee"), e;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
})
|
|
194
268
|
]
|
|
195
269
|
});
|
|
196
270
|
}
|
|
197
271
|
//#endregion
|
|
198
|
-
export {
|
|
272
|
+
export { M as LearningCourseDetailsPagePage };
|
|
199
273
|
|
|
200
274
|
//# sourceMappingURL=LearningCourseDetailsPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LearningCourseDetailsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningCourseDetailsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n Spinner,\n} from '@burdenoff/fe-libs/ui';\nimport { BookOpen, Clock, GraduationCap, Play, Star, Users } from 'lucide-react';\nimport { useNavigate, useSearchParams } from 'react-router';\nimport { useState } from 'react';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nexport function LearningCourseDetailsPagePage() {\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { courses, enrollCourse, initialized } = useCrewFoundryStore();\n const { showToast } = useGlobalUi();\n const [enrolling, setEnrolling] = useState(false);\n const courseId = searchParams.get('id');\n const course = courseId ? courses.find((c) => c.id === courseId) : courses[0];\n if (!initialized && !course) {\n return (\n <div className=\"flex min-h-[60vh] items-center justify-center p-6\">\n <Spinner size=\"lg\" />\n </div>\n );\n }\n\n if (!course)\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Course not found\"\n description=\"This course is no longer available.\"\n />\n </div>\n );\n const completionRate =\n course.enrolled > 0 ? Math.round((course.completed / course.enrolled) * 100) : 0;\n\n const handleStart = async () => {\n setEnrolling(true);\n try {\n await enrollCourse(course.id);\n showToast('Enrolled — your course is ready', 'success');\n navigate(`../learning/course-learning-page?id=${encodeURIComponent(course.id)}`);\n } catch (error) {\n showToast(error instanceof Error ? error.message : 'Unable to enroll in course', 'error');\n } finally {\n setEnrolling(false);\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div>\n <div className=\"flex items-center gap-2 mb-1\">\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{course.title}</GradientText>\n </h1>\n <Badge\n variant={\n course.level === 'beginner'\n ? 'secondary'\n : course.level === 'intermediate'\n ? 'default'\n : 'destructive'\n }\n >\n {formatEnumLabel(course.level)}\n </Badge>\n </div>\n <p className=\"text-sm text-text-secondary\">\n by {course.instructor} · {course.category}\n </p>\n <PagePurpose className=\"mt-2\">\n Everything you need to decide on and start this course — what it covers, who it's\n for, and how others have done — so you can enroll with confidence and build the right\n skills.\n </PagePurpose>\n </div>\n <Button onClick={handleStart} disabled={enrolling}>\n <Play className=\"h-4 w-4 mr-1\" />\n {enrolling ? 'Enrolling…' : 'Start Course'}\n </Button>\n </div>\n\n <NextSteps\n storageKey=\"crewfoundry-course-details\"\n steps={[\n {\n id: 'start',\n label: 'Start the first module',\n description: 'Begin learning and track your progress as you go.',\n icon: <Play className=\"h-4 w-4\" />,\n onClick: () =>\n navigate(`../learning/course-learning-page?id=${encodeURIComponent(course.id)}`),\n },\n {\n id: 'my-learning',\n label: 'See all your learning',\n description: 'Review everything you are currently enrolled in.',\n icon: <GraduationCap className=\"h-4 w-4\" />,\n onClick: () => navigate('../learning/my-learning-page'),\n },\n {\n id: 'browse',\n label: 'Browse more courses',\n description: 'Find related training to round out your skills.',\n icon: <BookOpen className=\"h-4 w-4\" />,\n onClick: () => navigate('../learning/courses-page'),\n },\n ]}\n />\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Clock className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{course.duration}</p>\n <p className=\"text-xs text-text-secondary\">Duration</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <BookOpen className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{course.modules}</p>\n <p className=\"text-xs text-text-secondary\">Modules</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Users className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{course.enrolled}</p>\n <p className=\"text-xs text-text-secondary\">Enrolled</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Star className=\"h-5 w-5 mx-auto text-status-warning-text mb-1\" />\n <p className=\"text-lg font-bold\">{course.rating}/5</p>\n <p className=\"text-xs text-text-secondary\">Rating</p>\n </CardContent>\n </Card>\n </div>\n <EmphasisPanel>\n <div className=\"mb-2 text-lg font-semibold\">About this Course</div>\n <p className=\"text-sm text-text-secondary\">{course.description}</p>\n <div className=\"flex flex-wrap gap-1 mt-3\">\n {course.skills.map((s) => (\n <Badge key={s} variant=\"outline\">\n {s}\n </Badge>\n ))}\n </div>\n </EmphasisPanel>\n <Card>\n <CardHeader>\n <CardTitle>Completion Statistics</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-sm\">\n <span>\n {course.completed} of {course.enrolled} students completed\n </span>\n <span className=\"font-medium\">{completionRate}%</span>\n </div>\n <div className=\"h-3 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-3 bg-status-success-text rounded\"\n style={{ width: `${completionRate}%` }}\n />\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LearningCourseDetailsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningCourseDetailsPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GradientText,\n IllustratedEmptyState,\n ResponsiveTable,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Spinner,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowLeft, Clock, ExternalLink, Pencil, Trash2, UserPlus } from 'lucide-react';\nimport { useNavigate, useSearchParams } from 'react-router';\nimport { FormModal, useFormModal, type FormValues } from '../components/forms/FormModal';\nimport { InlineError } from '../components/InlineError';\nimport { AvatarStack, StatCard } from '../components/viz';\nimport {\n useCrewFoundryStore,\n type CrewEnrollment,\n type CrewEnrollmentStatus,\n} from '../store/crewfoundryStore';\nimport {\n ENROLLMENT_STATUS_LABEL,\n ENROLLMENT_STATUS_OPTIONS,\n formatDuration,\n} from '../lib/learning';\nimport { useEnsureLoaded } from '../lib/useEnsureLoaded';\nimport { COURSE_FIELDS, courseToValues, valuesToCourseInput } from './LearningCoursesPagePage';\nimport { formatDate } from '../utils/dateUtils';\n\nexport function LearningCourseDetailsPagePage() {\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const {\n trainingCourses,\n enrollments,\n employees,\n learningLoaded,\n fetchLearning,\n updateTrainingCourse,\n enrollEmployee,\n updateEnrollmentStatus,\n removeEnrollment,\n } = useCrewFoundryStore();\n const loadError = useEnsureLoaded(learningLoaded, fetchLearning);\n const editModal = useFormModal();\n const enrollModal = useFormModal();\n const [formError, setFormError] = useState<string | undefined>();\n const [actionError, setActionError] = useState<string | null>(null);\n\n const courseId = searchParams.get('id');\n const course = trainingCourses.find((item) => item.id === courseId);\n const roster = useMemo(\n () => enrollments.filter((row) => row.courseId === courseId),\n [enrollments, courseId]\n );\n const enrolledIds = new Set(roster.map((row) => row.employeeId));\n const enrollable = employees.filter(\n (employee) => employee.status !== 'terminated' && !enrolledIds.has(employee.id)\n );\n\n const runAction = async (action: () => Promise<void>) => {\n setActionError(null);\n try {\n await action();\n } catch (error) {\n setActionError(error instanceof Error ? error.message : 'Something went wrong');\n }\n };\n\n if (!learningLoaded && !loadError) {\n return (\n <div className=\"flex min-h-[60vh] items-center justify-center p-6\">\n <Spinner size=\"lg\" />\n </div>\n );\n }\n\n if (!course) {\n return (\n <div className=\"space-y-4 p-6\">\n <InlineError message={loadError} />\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Course not found\"\n description=\"This course was removed or the link is incomplete.\"\n action={\n <Button size=\"sm\" onClick={() => navigate('../learning/courses-page')}>\n Back to courses\n </Button>\n }\n />\n </div>\n );\n }\n\n const countBy = (status: CrewEnrollmentStatus) =>\n roster.filter((row) => row.status === status).length;\n\n const handleEdit = async (values: FormValues) => {\n setFormError(undefined);\n try {\n await updateTrainingCourse(course.id, valuesToCourseInput(values));\n } catch (error) {\n setFormError(error instanceof Error ? error.message : 'Unable to save course');\n throw error;\n }\n };\n\n const handleEnroll = async (values: FormValues) => {\n setFormError(undefined);\n const employee = employees.find((item) => item.id === values.employeeId);\n try {\n if (!employee) throw new Error('Choose an employee to enroll');\n await enrollEmployee(course.id, employee);\n } catch (error) {\n setFormError(error instanceof Error ? error.message : 'Unable to enroll employee');\n throw error;\n }\n };\n\n const columns: ResponsiveTableColumn<CrewEnrollment>[] = [\n {\n key: 'employee',\n header: 'Employee',\n priority: 'primary',\n cell: (row) => (\n <div className=\"flex items-center gap-2.5\">\n <AvatarStack people={[{ name: row.employeeName }]} size={28} />\n <span className=\"font-medium\">{row.employeeName}</span>\n </div>\n ),\n },\n {\n key: 'status',\n header: 'Status',\n cell: (row) => (\n <Select\n value={row.status}\n onValueChange={(value) =>\n void runAction(() => updateEnrollmentStatus(row.id, value as CrewEnrollmentStatus))\n }\n >\n <SelectTrigger className=\"h-8 w-36\" aria-label={`Status for ${row.employeeName}`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ENROLLMENT_STATUS_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ),\n },\n {\n key: 'started',\n header: 'Started',\n cell: (row) => (\n <span className=\"text-text-secondary\">\n {row.startedAt ? formatDate(row.startedAt) : '—'}\n </span>\n ),\n },\n {\n key: 'completed',\n header: 'Completed',\n cell: (row) => (\n <span className=\"text-text-secondary\">\n {row.completedAt ? formatDate(row.completedAt) : '—'}\n </span>\n ),\n },\n {\n key: 'actions',\n header: '',\n cellClassName: 'md:text-right',\n cell: (row) => (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n aria-label={`Remove ${row.employeeName} from this course`}\n onClick={() => void runAction(() => removeEnrollment(row.id))}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n ),\n },\n ];\n\n return (\n <div className=\"space-y-6 p-6\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigate('../learning/courses-page')}>\n <ArrowLeft className=\"mr-1 h-4 w-4\" />\n Courses\n </Button>\n\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{course.title}</GradientText>\n </h1>\n <Badge variant={course.isActive ? 'default' : 'secondary'} className=\"text-[10px]\">\n {course.isActive ? 'Active' : 'Archived'}\n </Badge>\n </div>\n <p className=\"mt-1 flex items-center gap-1 text-sm text-text-secondary\">\n <Clock className=\"h-3.5 w-3.5\" />\n {formatDuration(course.durationMinutes)}\n </p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <Button size=\"sm\" variant=\"outline\" asChild>\n <a href={course.contentUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n <ExternalLink className=\"mr-1 h-4 w-4\" />\n Open content\n </a>\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n setFormError(undefined);\n editModal.openModal();\n }}\n >\n <Pencil className=\"mr-1 h-4 w-4\" />\n Edit\n </Button>\n <Button\n size=\"sm\"\n disabled={!course.isActive || enrollable.length === 0}\n title={\n !course.isActive\n ? 'Reactivate the course to enroll employees'\n : enrollable.length === 0\n ? 'Every active employee is already enrolled'\n : undefined\n }\n onClick={() => {\n setFormError(undefined);\n enrollModal.openModal();\n }}\n >\n <UserPlus className=\"mr-1 h-4 w-4\" />\n Enroll employee\n </Button>\n </div>\n </div>\n\n <InlineError message={loadError ?? actionError} />\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">About this course</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <p className=\"whitespace-pre-line text-sm text-text-secondary\">{course.description}</p>\n {course.requiredForRoles.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-1\">\n <span className=\"mr-1 text-xs text-text-secondary\">Required for</span>\n {course.requiredForRoles.map((role) => (\n <Badge key={role} variant=\"outline\" className=\"text-[10px]\">\n {role}\n </Badge>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n <StatCard label=\"Enrolled\" value={roster.length} />\n <StatCard label={ENROLLMENT_STATUS_LABEL.not_started} value={countBy('not_started')} />\n <StatCard label={ENROLLMENT_STATUS_LABEL.in_progress} value={countBy('in_progress')} />\n <StatCard label={ENROLLMENT_STATUS_LABEL.completed} value={countBy('completed')} />\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Enrolled employees</CardTitle>\n <CardDescription>\n Update each person’s progress as they start and finish the course.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <ResponsiveTable<CrewEnrollment>\n data={roster}\n rowKey={(row) => row.id}\n columns={columns}\n emptyState={\n <p className=\"py-6 text-center text-sm text-text-secondary\">\n No one is enrolled yet.\n </p>\n }\n />\n </CardContent>\n </Card>\n\n <FormModal\n open={editModal.open}\n onOpenChange={editModal.onOpenChange}\n title=\"Edit course\"\n fields={COURSE_FIELDS}\n initialValues={courseToValues(course)}\n submitLabel=\"Save changes\"\n errorMessage={formError}\n onValidationError={setFormError}\n onSubmit={handleEdit}\n />\n\n <FormModal\n open={enrollModal.open}\n onOpenChange={enrollModal.onOpenChange}\n title=\"Enroll employee\"\n description={`Enroll someone in “${course.title}”. They start as Not started.`}\n fields={[\n {\n name: 'employeeId',\n label: 'Employee',\n type: 'select',\n required: true,\n colSpan: 2,\n options: enrollable.map((employee) => ({\n value: employee.id,\n label: `${employee.firstName} ${employee.lastName} · ${employee.position}`,\n })),\n },\n ]}\n submitLabel=\"Enroll\"\n errorMessage={formError}\n onValidationError={setFormError}\n onSubmit={handleEnroll}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,14 @@
|
|
|
1
|
+
import { FieldConfig, FormValues } from '../components/forms/FormModal';
|
|
2
|
+
import { CrewTrainingCourse, CrewTrainingCourseInput } from '../store/crewfoundryStore';
|
|
3
|
+
|
|
4
|
+
export declare const COURSE_FIELDS: FieldConfig[];
|
|
5
|
+
export declare const courseToValues: (course: CrewTrainingCourse) => FormValues;
|
|
6
|
+
/** Validate + coerce form values into the course mutation input. Throws a user-facing message. */
|
|
7
|
+
export declare const valuesToCourseInput: (values: FormValues) => CrewTrainingCourseInput;
|
|
8
|
+
export declare const LEARNING_TABS: {
|
|
9
|
+
id: string;
|
|
10
|
+
label: string;
|
|
11
|
+
path: string;
|
|
12
|
+
}[];
|
|
1
13
|
export declare function LearningCoursesPagePage(): import("react").JSX.Element;
|
|
2
14
|
//# sourceMappingURL=LearningCoursesPagePage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LearningCoursesPagePage.d.ts","sourceRoot":"","sources":["../../../src/crewfoundry/pages/LearningCoursesPagePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LearningCoursesPagePage.d.ts","sourceRoot":"","sources":["../../../src/crewfoundry/pages/LearningCoursesPagePage.tsx"],"names":[],"mappings":"AA+CA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC7B,MAAM,2BAA2B,CAAC;AAInC,eAAO,MAAM,aAAa,EAAE,WAAW,EAyBtC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,QAAQ,kBAAkB,KAAG,UAO1D,CAAC;AAEH,kGAAkG;AAClG,eAAO,MAAM,mBAAmB,GAAI,QAAQ,UAAU,KAAG,uBAexD,CAAC;AAEF,eAAO,MAAM,aAAa;;;;GAIzB,CAAC;AAEF,wBAAgB,uBAAuB,gCAsVtC"}
|