@burdenoff/microfe-crewfoundry 2026.1013.2 → 2026.1029.1
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 +323 -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,293 +0,0 @@
|
|
|
1
|
-
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
|
-
import { chartPalette as t } from "../components/viz/lib/palette.js";
|
|
3
|
-
import { StatCard as n } from "../components/viz/StatCard.js";
|
|
4
|
-
import { RatingStars as r } from "../components/viz/RatingStars.js";
|
|
5
|
-
import { CertificateCard as i } from "../components/viz/CertificateCard.js";
|
|
6
|
-
import { SegmentedTabs as a } from "../components/viz/SegmentedTabs.js";
|
|
7
|
-
import "../components/viz/index.js";
|
|
8
|
-
import { readAllCourseProgress as o } from "../utils/courseProgress.js";
|
|
9
|
-
import { useMemo as s, useState as c } from "react";
|
|
10
|
-
import { Award as l, BookOpen as u, GraduationCap as d, Layers as f, Play as p } from "lucide-react";
|
|
11
|
-
import { useNavigate as m } from "react-router";
|
|
12
|
-
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
13
|
-
import { Badge as _, Button as v, GlassCard as y, GradientText as b, IllustratedEmptyState as x, PagePurpose as S } from "@burdenoff/fe-libs/ui";
|
|
14
|
-
import { useAuth as C } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
15
|
-
//#region src/crewfoundry/pages/LearningMyLearningPagePage.tsx
|
|
16
|
-
var w = "crewfoundry:course-enrolled:v1";
|
|
17
|
-
function T() {
|
|
18
|
-
if (typeof window > "u") return /* @__PURE__ */ new Set();
|
|
19
|
-
try {
|
|
20
|
-
let e = window.localStorage.getItem(w), t = e ? JSON.parse(e) : [];
|
|
21
|
-
return new Set(Array.isArray(t) ? t.filter((e) => typeof e == "string") : []);
|
|
22
|
-
} catch {
|
|
23
|
-
return /* @__PURE__ */ new Set();
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
function E(e) {
|
|
27
|
-
let n = t(8), r = 0;
|
|
28
|
-
for (let t = 0; t < e.length; t += 1) r = r * 31 + e.charCodeAt(t) >>> 0;
|
|
29
|
-
return n[r % n.length];
|
|
30
|
-
}
|
|
31
|
-
function D(e) {
|
|
32
|
-
if (!e) return "—";
|
|
33
|
-
let t = new Date(e);
|
|
34
|
-
return Number.isNaN(t.getTime()) ? "—" : t.toLocaleDateString(void 0, {
|
|
35
|
-
year: "numeric",
|
|
36
|
-
month: "short",
|
|
37
|
-
day: "numeric"
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
function O(e, t, n, r) {
|
|
41
|
-
if (typeof document > "u") return;
|
|
42
|
-
let i = (e) => e.replace(/[&<>"]/g, (e) => ({
|
|
43
|
-
"&": "&",
|
|
44
|
-
"<": "<",
|
|
45
|
-
">": ">",
|
|
46
|
-
"\"": """
|
|
47
|
-
})[e] ?? e), a = `<!doctype html><html><head><meta charset="utf-8"><title>Certificate — ${i(e)}</title>
|
|
48
|
-
<style>
|
|
49
|
-
body{font-family:Georgia,'Times New Roman',serif;margin:0;padding:48px;text-align:center}
|
|
50
|
-
.frame{border:6px double currentColor;padding:56px 40px;max-width:760px;margin:0 auto}
|
|
51
|
-
.kicker{letter-spacing:.3em;text-transform:uppercase;font-size:12px;opacity:.7}
|
|
52
|
-
h1{font-size:34px;margin:24px 0 8px}
|
|
53
|
-
.recipient{font-size:26px;margin:20px 0}
|
|
54
|
-
.rule{width:200px;border:0;border-top:1px solid currentColor;margin:24px auto;opacity:.4}
|
|
55
|
-
.meta{font-size:13px;opacity:.7;margin-top:32px}
|
|
56
|
-
</style></head><body>
|
|
57
|
-
<div class="frame">
|
|
58
|
-
<div class="kicker">CrewFoundry · Certificate of Completion</div>
|
|
59
|
-
<h1>${i(e)}</h1>
|
|
60
|
-
<div class="kicker">Awarded to</div>
|
|
61
|
-
<div class="recipient">${i(t)}</div>
|
|
62
|
-
<hr class="rule" />
|
|
63
|
-
<div class="meta">Issued ${i(n)} · Credential ID: ${i(r)}</div>
|
|
64
|
-
</div>
|
|
65
|
-
</body></html>`, o = new Blob([a], { type: "text/html" }), s = URL.createObjectURL(o), c = document.createElement("a");
|
|
66
|
-
c.href = s, c.download = `crewfoundry-certificate-${r}.html`, document.body.appendChild(c), c.click(), c.remove(), URL.revokeObjectURL(s);
|
|
67
|
-
}
|
|
68
|
-
var k = u;
|
|
69
|
-
function A() {
|
|
70
|
-
let { courses: t } = e(), w = C(), A = m(), [j, M] = c("in-progress"), N = w.user?.name?.trim() || "CrewFoundry Learner", { inProgress: P, completed: F, modulesDone: I } = s(() => {
|
|
71
|
-
let e = o(), n = T(), r = [], i = [], a = 0;
|
|
72
|
-
for (let o of t) {
|
|
73
|
-
let t = e[o.id], s = t?.completed.length ?? 0;
|
|
74
|
-
a += s;
|
|
75
|
-
let c = Math.max(o.modules, 1), l = {
|
|
76
|
-
course: o,
|
|
77
|
-
completedModules: s,
|
|
78
|
-
totalModules: c,
|
|
79
|
-
pct: Math.min(100, Math.round(s / c * 100)),
|
|
80
|
-
completedAt: t?.completedAt
|
|
81
|
-
};
|
|
82
|
-
s >= c && s > 0 ? i.push(l) : (s > 0 || n.has(o.id)) && r.push(l);
|
|
83
|
-
}
|
|
84
|
-
return r.sort((e, t) => t.pct - e.pct), i.sort((e, t) => (t.completedAt ?? "").localeCompare(e.completedAt ?? "")), {
|
|
85
|
-
inProgress: r,
|
|
86
|
-
completed: i,
|
|
87
|
-
modulesDone: a
|
|
88
|
-
};
|
|
89
|
-
}, [t]), L = (e) => A(`../learning/course-learning-page?id=${encodeURIComponent(e)}`);
|
|
90
|
-
return /* @__PURE__ */ g("div", {
|
|
91
|
-
className: "space-y-6 p-6",
|
|
92
|
-
children: [
|
|
93
|
-
/* @__PURE__ */ g("div", { children: [
|
|
94
|
-
/* @__PURE__ */ h("h1", {
|
|
95
|
-
className: "text-2xl font-semibold",
|
|
96
|
-
children: /* @__PURE__ */ h(b, { children: "My Learning" })
|
|
97
|
-
}),
|
|
98
|
-
/* @__PURE__ */ h("p", {
|
|
99
|
-
className: "text-sm text-text-secondary",
|
|
100
|
-
children: "Track your learning progress and achievements"
|
|
101
|
-
}),
|
|
102
|
-
/* @__PURE__ */ h(S, {
|
|
103
|
-
className: "mt-1",
|
|
104
|
-
children: "Everything you're currently learning — track your enrolled courses, completed training and the certificates you've earned, all in one place."
|
|
105
|
-
})
|
|
106
|
-
] }),
|
|
107
|
-
/* @__PURE__ */ g("div", {
|
|
108
|
-
className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-4",
|
|
109
|
-
children: [
|
|
110
|
-
/* @__PURE__ */ h(n, {
|
|
111
|
-
label: "Courses in progress",
|
|
112
|
-
value: P.length,
|
|
113
|
-
icon: /* @__PURE__ */ h(u, { className: "h-4 w-4" })
|
|
114
|
-
}),
|
|
115
|
-
/* @__PURE__ */ h(n, {
|
|
116
|
-
label: "Completed",
|
|
117
|
-
value: F.length,
|
|
118
|
-
icon: /* @__PURE__ */ h(l, { className: "h-4 w-4" })
|
|
119
|
-
}),
|
|
120
|
-
/* @__PURE__ */ h(n, {
|
|
121
|
-
label: "Certificates",
|
|
122
|
-
value: F.length,
|
|
123
|
-
icon: /* @__PURE__ */ h(d, { className: "h-4 w-4" })
|
|
124
|
-
}),
|
|
125
|
-
/* @__PURE__ */ h(n, {
|
|
126
|
-
label: "Modules done",
|
|
127
|
-
value: I,
|
|
128
|
-
icon: /* @__PURE__ */ h(f, { className: "h-4 w-4" })
|
|
129
|
-
})
|
|
130
|
-
]
|
|
131
|
-
}),
|
|
132
|
-
/* @__PURE__ */ h("div", {
|
|
133
|
-
className: "overflow-x-auto pb-1",
|
|
134
|
-
children: /* @__PURE__ */ h(a, {
|
|
135
|
-
"aria-label": "My learning",
|
|
136
|
-
value: j,
|
|
137
|
-
onChange: (e) => M(e),
|
|
138
|
-
className: "w-max",
|
|
139
|
-
tabs: [
|
|
140
|
-
{
|
|
141
|
-
id: "in-progress",
|
|
142
|
-
label: "In Progress",
|
|
143
|
-
count: P.length
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
id: "completed",
|
|
147
|
-
label: "Completed",
|
|
148
|
-
count: F.length
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
id: "certificates",
|
|
152
|
-
label: "Certificates",
|
|
153
|
-
count: F.length
|
|
154
|
-
}
|
|
155
|
-
]
|
|
156
|
-
})
|
|
157
|
-
}),
|
|
158
|
-
j === "in-progress" && (P.length === 0 ? /* @__PURE__ */ h(x, {
|
|
159
|
-
illustration: "empty-generic",
|
|
160
|
-
title: "Nothing in progress yet",
|
|
161
|
-
description: "Enroll in a course and it will show up here so you can pick up where you left off.",
|
|
162
|
-
action: /* @__PURE__ */ h(v, {
|
|
163
|
-
variant: "outline",
|
|
164
|
-
onClick: () => A("../learning/courses-page"),
|
|
165
|
-
children: "Browse courses"
|
|
166
|
-
})
|
|
167
|
-
}) : /* @__PURE__ */ h("div", {
|
|
168
|
-
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
169
|
-
children: P.map(({ course: e, pct: t, completedModules: n, totalModules: r }) => {
|
|
170
|
-
let i = E(e.category);
|
|
171
|
-
return /* @__PURE__ */ g(y, {
|
|
172
|
-
treatment: "plain",
|
|
173
|
-
className: "flex flex-col overflow-hidden",
|
|
174
|
-
children: [/* @__PURE__ */ h("div", {
|
|
175
|
-
className: "flex h-20 items-center justify-center",
|
|
176
|
-
style: { background: `linear-gradient(135deg, color-mix(in srgb, ${i} 26%, var(--color-bg-surface)), color-mix(in srgb, ${i} 8%, var(--color-bg-surface)))` },
|
|
177
|
-
children: /* @__PURE__ */ h("span", {
|
|
178
|
-
className: "flex h-10 w-10 items-center justify-center rounded-xl bg-bg-surface/70 shadow-elevation-1",
|
|
179
|
-
style: { color: i },
|
|
180
|
-
children: /* @__PURE__ */ h(k, { className: "h-5 w-5" })
|
|
181
|
-
})
|
|
182
|
-
}), /* @__PURE__ */ g("div", {
|
|
183
|
-
className: "flex flex-1 flex-col gap-3 p-4",
|
|
184
|
-
children: [
|
|
185
|
-
/* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("p", {
|
|
186
|
-
className: "text-sm font-semibold",
|
|
187
|
-
children: e.title
|
|
188
|
-
}), /* @__PURE__ */ h("p", {
|
|
189
|
-
className: "text-xs text-text-secondary",
|
|
190
|
-
children: e.instructor
|
|
191
|
-
})] }),
|
|
192
|
-
/* @__PURE__ */ g("div", {
|
|
193
|
-
className: "mt-auto space-y-1",
|
|
194
|
-
children: [/* @__PURE__ */ g("div", {
|
|
195
|
-
className: "flex justify-between text-xs text-text-secondary",
|
|
196
|
-
children: [/* @__PURE__ */ g("span", {
|
|
197
|
-
className: "tabular-nums",
|
|
198
|
-
children: [t, "% complete"]
|
|
199
|
-
}), /* @__PURE__ */ g("span", {
|
|
200
|
-
className: "tabular-nums",
|
|
201
|
-
children: [
|
|
202
|
-
n,
|
|
203
|
-
"/",
|
|
204
|
-
r,
|
|
205
|
-
" modules"
|
|
206
|
-
]
|
|
207
|
-
})]
|
|
208
|
-
}), /* @__PURE__ */ h("div", {
|
|
209
|
-
className: "h-2 overflow-hidden rounded-full bg-bg-sunken",
|
|
210
|
-
children: /* @__PURE__ */ h("div", {
|
|
211
|
-
className: "h-full rounded-full bg-action-primary-bg",
|
|
212
|
-
style: { width: `${t}%` }
|
|
213
|
-
})
|
|
214
|
-
})]
|
|
215
|
-
}),
|
|
216
|
-
/* @__PURE__ */ g(v, {
|
|
217
|
-
className: "w-full",
|
|
218
|
-
onClick: () => L(e.id),
|
|
219
|
-
children: [/* @__PURE__ */ h(p, { className: "mr-1 h-4 w-4" }), "Continue"]
|
|
220
|
-
})
|
|
221
|
-
]
|
|
222
|
-
})]
|
|
223
|
-
}, e.id);
|
|
224
|
-
})
|
|
225
|
-
})),
|
|
226
|
-
j === "completed" && (F.length === 0 ? /* @__PURE__ */ h(x, {
|
|
227
|
-
illustration: "empty-generic",
|
|
228
|
-
title: "No completed courses yet",
|
|
229
|
-
description: "Finish a course from the player and it will be marked complete here."
|
|
230
|
-
}) : /* @__PURE__ */ h("div", {
|
|
231
|
-
className: "space-y-3",
|
|
232
|
-
children: F.map(({ course: e, completedAt: t }) => /* @__PURE__ */ g("button", {
|
|
233
|
-
type: "button",
|
|
234
|
-
onClick: () => L(e.id),
|
|
235
|
-
className: "flex w-full items-center justify-between gap-3 rounded-lg border border-border-subtle p-4 text-left transition-colors hover:border-border-strong hover:bg-bg-sunken",
|
|
236
|
-
children: [/* @__PURE__ */ g("div", {
|
|
237
|
-
className: "min-w-0",
|
|
238
|
-
children: [/* @__PURE__ */ h("p", {
|
|
239
|
-
className: "truncate text-sm font-medium",
|
|
240
|
-
children: e.title
|
|
241
|
-
}), /* @__PURE__ */ g("p", {
|
|
242
|
-
className: "text-xs text-text-secondary",
|
|
243
|
-
children: [
|
|
244
|
-
"Completed ",
|
|
245
|
-
D(t),
|
|
246
|
-
" · ",
|
|
247
|
-
e.instructor
|
|
248
|
-
]
|
|
249
|
-
})]
|
|
250
|
-
}), /* @__PURE__ */ g("div", {
|
|
251
|
-
className: "flex shrink-0 items-center gap-3",
|
|
252
|
-
children: [/* @__PURE__ */ h(r, {
|
|
253
|
-
value: e.rating,
|
|
254
|
-
size: 13,
|
|
255
|
-
showValue: !0
|
|
256
|
-
}), /* @__PURE__ */ h(_, {
|
|
257
|
-
variant: "secondary",
|
|
258
|
-
className: "text-[10px]",
|
|
259
|
-
children: "Completed"
|
|
260
|
-
})]
|
|
261
|
-
})]
|
|
262
|
-
}, e.id))
|
|
263
|
-
})),
|
|
264
|
-
j === "certificates" && (F.length === 0 ? /* @__PURE__ */ h(x, {
|
|
265
|
-
illustration: "empty-generic",
|
|
266
|
-
title: "No certificates yet",
|
|
267
|
-
description: "Certificates are issued when you complete a course. Finish one and it will appear here to download.",
|
|
268
|
-
action: /* @__PURE__ */ h(v, {
|
|
269
|
-
variant: "outline",
|
|
270
|
-
onClick: () => A("../learning/courses-page"),
|
|
271
|
-
children: "Browse courses"
|
|
272
|
-
})
|
|
273
|
-
}) : /* @__PURE__ */ h("div", {
|
|
274
|
-
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
275
|
-
children: F.map(({ course: e, completedAt: t }) => {
|
|
276
|
-
let n = `CF-${e.id.slice(-6).toUpperCase()}`, r = D(t);
|
|
277
|
-
return /* @__PURE__ */ h(i, {
|
|
278
|
-
title: e.title,
|
|
279
|
-
recipient: N,
|
|
280
|
-
date: r,
|
|
281
|
-
issuer: "CrewFoundry",
|
|
282
|
-
credentialId: n,
|
|
283
|
-
onDownload: () => O(e.title, N, r, n)
|
|
284
|
-
}, e.id);
|
|
285
|
-
})
|
|
286
|
-
}))
|
|
287
|
-
]
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
//#endregion
|
|
291
|
-
export { A as LearningMyLearningPagePage };
|
|
292
|
-
|
|
293
|
-
//# sourceMappingURL=LearningMyLearningPagePage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LearningMyLearningPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningMyLearningPagePage.tsx"],"sourcesContent":["import { useMemo, useState, type ComponentType } from 'react';\nimport { Award, BookOpen, GraduationCap, Layers, Play } from 'lucide-react';\nimport {\n Badge,\n Button,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useNavigate } from 'react-router';\nimport { useAuth } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useCrewFoundryStore, type LearningCourse } from '../store/crewfoundryStore';\nimport {\n CertificateCard,\n chartPalette,\n RatingStars,\n SegmentedTabs,\n StatCard,\n} from '../components/viz';\nimport { readAllCourseProgress } from '../utils/courseProgress';\n\nconst ENROLLED_KEY = 'crewfoundry:course-enrolled:v1';\n\nfunction readEnrolledIds(): Set<string> {\n if (typeof window === 'undefined') return new Set();\n try {\n const raw = window.localStorage.getItem(ENROLLED_KEY);\n const ids: unknown = raw ? JSON.parse(raw) : [];\n return new Set(Array.isArray(ids) ? ids.filter((x): x is string => typeof x === 'string') : []);\n } catch {\n return new Set();\n }\n}\n\nfunction categoryAccent(category: string): string {\n const palette = chartPalette(8);\n let hash = 0;\n for (let i = 0; i < category.length; i += 1) {\n hash = (hash * 31 + category.charCodeAt(i)) >>> 0;\n }\n return palette[hash % palette.length];\n}\n\nfunction formatDate(iso?: string): string {\n if (!iso) return '—';\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return '—';\n return date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n}\n\n/** Generate a self-contained, printable certificate document (no app tokens, no raw colors). */\nfunction downloadCertificate(\n course: string,\n recipient: string,\n dateLabel: string,\n id: string\n): void {\n if (typeof document === 'undefined') return;\n const esc = (s: string) =>\n s.replace(\n /[&<>\"]/g,\n (c) => ({ '&': '&', '<': '<', '>': '>', '\"': '"' })[c] ?? c\n );\n const html = `<!doctype html><html><head><meta charset=\"utf-8\"><title>Certificate — ${esc(course)}</title>\n<style>\n body{font-family:Georgia,'Times New Roman',serif;margin:0;padding:48px;text-align:center}\n .frame{border:6px double currentColor;padding:56px 40px;max-width:760px;margin:0 auto}\n .kicker{letter-spacing:.3em;text-transform:uppercase;font-size:12px;opacity:.7}\n h1{font-size:34px;margin:24px 0 8px}\n .recipient{font-size:26px;margin:20px 0}\n .rule{width:200px;border:0;border-top:1px solid currentColor;margin:24px auto;opacity:.4}\n .meta{font-size:13px;opacity:.7;margin-top:32px}\n</style></head><body>\n <div class=\"frame\">\n <div class=\"kicker\">CrewFoundry · Certificate of Completion</div>\n <h1>${esc(course)}</h1>\n <div class=\"kicker\">Awarded to</div>\n <div class=\"recipient\">${esc(recipient)}</div>\n <hr class=\"rule\" />\n <div class=\"meta\">Issued ${esc(dateLabel)} · Credential ID: ${esc(id)}</div>\n </div>\n</body></html>`;\n const blob = new Blob([html], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = `crewfoundry-certificate-${id}.html`;\n document.body.appendChild(anchor);\n anchor.click();\n anchor.remove();\n URL.revokeObjectURL(url);\n}\n\ntype Tab = 'in-progress' | 'completed' | 'certificates';\n\ninterface LearnerCourse {\n course: LearningCourse;\n completedModules: number;\n totalModules: number;\n pct: number;\n completedAt?: string;\n}\n\nconst CATEGORY_ICON: ComponentType<{ className?: string }> = BookOpen;\n\nexport function LearningMyLearningPagePage() {\n const { courses } = useCrewFoundryStore();\n const auth = useAuth();\n const navigate = useNavigate();\n const [tab, setTab] = useState<Tab>('in-progress');\n\n const recipient = auth.user?.name?.trim() || 'CrewFoundry Learner';\n\n const { inProgress, completed, modulesDone } = useMemo(() => {\n const progressMap = readAllCourseProgress();\n const enrolled = readEnrolledIds();\n const inProg: LearnerCourse[] = [];\n const done: LearnerCourse[] = [];\n let totalModulesDone = 0;\n\n for (const course of courses) {\n const entry = progressMap[course.id];\n const completedModules = entry?.completed.length ?? 0;\n totalModulesDone += completedModules;\n const totalModules = Math.max(course.modules, 1);\n const pct = Math.min(100, Math.round((completedModules / totalModules) * 100));\n const record: LearnerCourse = {\n course,\n completedModules,\n totalModules,\n pct,\n completedAt: entry?.completedAt,\n };\n if (completedModules >= totalModules && completedModules > 0) {\n done.push(record);\n } else if (completedModules > 0 || enrolled.has(course.id)) {\n inProg.push(record);\n }\n }\n inProg.sort((a, b) => b.pct - a.pct);\n done.sort((a, b) => (b.completedAt ?? '').localeCompare(a.completedAt ?? ''));\n return { inProgress: inProg, completed: done, modulesDone: totalModulesDone };\n }, [courses]);\n\n const openPlayer = (id: string) =>\n navigate(`../learning/course-learning-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>My Learning</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Track your learning progress and achievements</p>\n <PagePurpose className=\"mt-1\">\n Everything you're currently learning — track your enrolled courses, completed\n training and the certificates you've earned, all in one place.\n </PagePurpose>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n label=\"Courses in progress\"\n value={inProgress.length}\n icon={<BookOpen className=\"h-4 w-4\" />}\n />\n <StatCard label=\"Completed\" value={completed.length} icon={<Award className=\"h-4 w-4\" />} />\n <StatCard\n label=\"Certificates\"\n value={completed.length}\n icon={<GraduationCap className=\"h-4 w-4\" />}\n />\n <StatCard label=\"Modules done\" value={modulesDone} icon={<Layers className=\"h-4 w-4\" />} />\n </div>\n\n <div className=\"overflow-x-auto pb-1\">\n <SegmentedTabs\n aria-label=\"My learning\"\n value={tab}\n onChange={(id) => setTab(id as Tab)}\n className=\"w-max\"\n tabs={[\n { id: 'in-progress', label: 'In Progress', count: inProgress.length },\n { id: 'completed', label: 'Completed', count: completed.length },\n { id: 'certificates', label: 'Certificates', count: completed.length },\n ]}\n />\n </div>\n\n {tab === 'in-progress' &&\n (inProgress.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"Nothing in progress yet\"\n description=\"Enroll in a course and it will show up here so you can pick up where you left off.\"\n action={\n <Button variant=\"outline\" onClick={() => navigate('../learning/courses-page')}>\n Browse courses\n </Button>\n }\n />\n ) : (\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {inProgress.map(({ course, pct, completedModules, totalModules }) => {\n const accent = categoryAccent(course.category);\n return (\n <GlassCard\n key={course.id}\n treatment=\"plain\"\n className=\"flex flex-col overflow-hidden\"\n >\n <div\n className=\"flex h-20 items-center justify-center\"\n style={{\n background: `linear-gradient(135deg, color-mix(in srgb, ${accent} 26%, var(--color-bg-surface)), color-mix(in srgb, ${accent} 8%, var(--color-bg-surface)))`,\n }}\n >\n <span\n className=\"flex h-10 w-10 items-center justify-center rounded-xl bg-bg-surface/70 shadow-elevation-1\"\n style={{ color: accent }}\n >\n <CATEGORY_ICON className=\"h-5 w-5\" />\n </span>\n </div>\n <div className=\"flex flex-1 flex-col gap-3 p-4\">\n <div>\n <p className=\"text-sm font-semibold\">{course.title}</p>\n <p className=\"text-xs text-text-secondary\">{course.instructor}</p>\n </div>\n <div className=\"mt-auto space-y-1\">\n <div className=\"flex justify-between text-xs text-text-secondary\">\n <span className=\"tabular-nums\">{pct}% complete</span>\n <span className=\"tabular-nums\">\n {completedModules}/{totalModules} modules\n </span>\n </div>\n <div className=\"h-2 overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-full rounded-full bg-action-primary-bg\"\n style={{ width: `${pct}%` }}\n />\n </div>\n </div>\n <Button className=\"w-full\" onClick={() => openPlayer(course.id)}>\n <Play className=\"mr-1 h-4 w-4\" />\n Continue\n </Button>\n </div>\n </GlassCard>\n );\n })}\n </div>\n ))}\n\n {tab === 'completed' &&\n (completed.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No completed courses yet\"\n description=\"Finish a course from the player and it will be marked complete here.\"\n />\n ) : (\n <div className=\"space-y-3\">\n {completed.map(({ course, completedAt }) => (\n <button\n key={course.id}\n type=\"button\"\n onClick={() => openPlayer(course.id)}\n className=\"flex w-full items-center justify-between gap-3 rounded-lg border border-border-subtle p-4 text-left transition-colors hover:border-border-strong hover:bg-bg-sunken\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium\">{course.title}</p>\n <p className=\"text-xs text-text-secondary\">\n Completed {formatDate(completedAt)} · {course.instructor}\n </p>\n </div>\n <div className=\"flex shrink-0 items-center gap-3\">\n <RatingStars value={course.rating} size={13} showValue />\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n Completed\n </Badge>\n </div>\n </button>\n ))}\n </div>\n ))}\n\n {tab === 'certificates' &&\n (completed.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No certificates yet\"\n description=\"Certificates are issued when you complete a course. Finish one and it will appear here to download.\"\n action={\n <Button variant=\"outline\" onClick={() => navigate('../learning/courses-page')}>\n Browse courses\n </Button>\n }\n />\n ) : (\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {completed.map(({ course, completedAt }) => {\n const credentialId = `CF-${course.id.slice(-6).toUpperCase()}`;\n const dateLabel = formatDate(completedAt);\n return (\n <CertificateCard\n key={course.id}\n title={course.title}\n recipient={recipient}\n date={dateLabel}\n issuer=\"CrewFoundry\"\n credentialId={credentialId}\n onDownload={() =>\n downloadCertificate(course.title, recipient, dateLabel, credentialId)\n }\n />\n );\n })}\n </div>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MarketplaceEarningsPagePage.d.ts","sourceRoot":"","sources":["../../../src/crewfoundry/pages/MarketplaceEarningsPagePage.tsx"],"names":[],"mappings":"AA6CA,wBAAgB,2BAA2B,gCAmI1C"}
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
|
-
import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
|
|
3
|
-
import { useMemo as n } from "react";
|
|
4
|
-
import { DollarSign as r, TrendingUp as i, Wallet as a } from "lucide-react";
|
|
5
|
-
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
6
|
-
import { Badge as c, Card as l, CardContent as u, CardHeader as d, CardTitle as f, GlassCard as p, GradientText as m, PagePurpose as h } from "@burdenoff/fe-libs/ui";
|
|
7
|
-
//#region src/crewfoundry/pages/MarketplaceEarningsPagePage.tsx
|
|
8
|
-
var g = (e) => {
|
|
9
|
-
let t = new Date(e);
|
|
10
|
-
return Number.isNaN(t.getTime()) ? "N/A" : t.toLocaleString("en-US", { month: "short" });
|
|
11
|
-
}, _ = (e) => {
|
|
12
|
-
let t = new Date(e);
|
|
13
|
-
return Number.isNaN(t.getTime()) ? "Unknown" : t.toISOString().split("T")[0];
|
|
14
|
-
};
|
|
15
|
-
function v() {
|
|
16
|
-
let { invoices: v } = e(), y = n(() => v.slice(0, 12).map((e) => ({
|
|
17
|
-
id: e.id,
|
|
18
|
-
client: e.clientName,
|
|
19
|
-
amount: e.amount,
|
|
20
|
-
date: _(e.issueDate),
|
|
21
|
-
status: e.status === "paid" ? "completed" : "pending"
|
|
22
|
-
})), [v]), b = n(() => y.slice(0, 6).map((e, t) => {
|
|
23
|
-
let n = y.filter((t) => g(t.date) === g(e.date)), r = n.reduce((e, t) => e + t.amount, 0);
|
|
24
|
-
return {
|
|
25
|
-
month: g(e.date) || `M${t + 1}`,
|
|
26
|
-
amount: r,
|
|
27
|
-
orders: n.length
|
|
28
|
-
};
|
|
29
|
-
}), [y]), x = b.reduce((e, t) => e + t.amount, 0), S = Math.max(1, ...b.map((e) => e.amount)), C = b.reduce((e, t) => e + t.orders, 0), w = y.filter((e) => e.status === "pending").reduce((e, t) => e + t.amount, 0);
|
|
30
|
-
return /* @__PURE__ */ s("div", {
|
|
31
|
-
className: "space-y-6 p-6",
|
|
32
|
-
children: [
|
|
33
|
-
/* @__PURE__ */ s("div", { children: [
|
|
34
|
-
/* @__PURE__ */ o("h1", {
|
|
35
|
-
className: "text-2xl font-semibold",
|
|
36
|
-
children: /* @__PURE__ */ o(m, { children: "Earnings" })
|
|
37
|
-
}),
|
|
38
|
-
/* @__PURE__ */ o("p", {
|
|
39
|
-
className: "text-sm text-text-secondary",
|
|
40
|
-
children: "Revenue from marketplace services"
|
|
41
|
-
}),
|
|
42
|
-
/* @__PURE__ */ o(h, {
|
|
43
|
-
className: "mt-1",
|
|
44
|
-
children: "Track what you've earned on the marketplace — payouts, pending balances, and earning trends so you always know where you stand."
|
|
45
|
-
})
|
|
46
|
-
] }),
|
|
47
|
-
/* @__PURE__ */ s("div", {
|
|
48
|
-
className: "grid gap-4 md:grid-cols-3",
|
|
49
|
-
children: [
|
|
50
|
-
/* @__PURE__ */ s(p, {
|
|
51
|
-
treatment: "glass",
|
|
52
|
-
glow: !0,
|
|
53
|
-
className: "border-border-seam",
|
|
54
|
-
children: [/* @__PURE__ */ s(d, {
|
|
55
|
-
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
56
|
-
children: [/* @__PURE__ */ o(f, {
|
|
57
|
-
className: "text-sm font-medium",
|
|
58
|
-
children: "Total Earnings"
|
|
59
|
-
}), /* @__PURE__ */ o(r, { className: "h-4 w-4 text-text-secondary" })]
|
|
60
|
-
}), /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ s("div", {
|
|
61
|
-
className: "text-2xl font-bold tabular-nums",
|
|
62
|
-
children: ["$", x.toLocaleString()]
|
|
63
|
-
}), /* @__PURE__ */ s("p", {
|
|
64
|
-
className: "text-xs text-text-secondary",
|
|
65
|
-
children: [
|
|
66
|
-
"Across ",
|
|
67
|
-
C,
|
|
68
|
-
" paid orders"
|
|
69
|
-
]
|
|
70
|
-
})] })]
|
|
71
|
-
}),
|
|
72
|
-
/* @__PURE__ */ s(p, {
|
|
73
|
-
treatment: "metric",
|
|
74
|
-
className: "border-border-seam",
|
|
75
|
-
children: [/* @__PURE__ */ s(d, {
|
|
76
|
-
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
77
|
-
children: [/* @__PURE__ */ o(f, {
|
|
78
|
-
className: "text-sm font-medium",
|
|
79
|
-
children: "Avg Order Value"
|
|
80
|
-
}), /* @__PURE__ */ o(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
81
|
-
}), /* @__PURE__ */ o(u, { children: /* @__PURE__ */ s("div", {
|
|
82
|
-
className: "text-2xl font-bold tabular-nums",
|
|
83
|
-
children: ["$", Math.round(x / Math.max(C, 1)).toLocaleString()]
|
|
84
|
-
}) })]
|
|
85
|
-
}),
|
|
86
|
-
/* @__PURE__ */ s(p, {
|
|
87
|
-
treatment: "metric",
|
|
88
|
-
className: "border-border-seam",
|
|
89
|
-
children: [/* @__PURE__ */ s(d, {
|
|
90
|
-
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
91
|
-
children: [/* @__PURE__ */ o(f, {
|
|
92
|
-
className: "text-sm font-medium",
|
|
93
|
-
children: "Pending"
|
|
94
|
-
}), /* @__PURE__ */ o(a, { className: "h-4 w-4 text-status-warning-text" })]
|
|
95
|
-
}), /* @__PURE__ */ o(u, { children: /* @__PURE__ */ s("div", {
|
|
96
|
-
className: "text-2xl font-bold tabular-nums",
|
|
97
|
-
children: ["$", w.toLocaleString()]
|
|
98
|
-
}) })]
|
|
99
|
-
})
|
|
100
|
-
]
|
|
101
|
-
}),
|
|
102
|
-
/* @__PURE__ */ s(l, { children: [/* @__PURE__ */ o(d, { children: /* @__PURE__ */ o(f, { children: "Earnings Trend" }) }), /* @__PURE__ */ o(u, {
|
|
103
|
-
className: "space-y-3",
|
|
104
|
-
children: b.map((e, t) => /* @__PURE__ */ s("div", {
|
|
105
|
-
className: "flex items-center gap-3",
|
|
106
|
-
children: [
|
|
107
|
-
/* @__PURE__ */ o("span", {
|
|
108
|
-
className: "w-10 text-sm text-text-secondary",
|
|
109
|
-
children: e.month
|
|
110
|
-
}),
|
|
111
|
-
/* @__PURE__ */ o("div", {
|
|
112
|
-
className: "h-4 flex-1 overflow-hidden rounded bg-bg-sunken",
|
|
113
|
-
children: /* @__PURE__ */ o("div", {
|
|
114
|
-
className: "h-4 rounded bg-action-primary-bg",
|
|
115
|
-
style: { width: `${Math.round(e.amount / S * 100)}%` }
|
|
116
|
-
})
|
|
117
|
-
}),
|
|
118
|
-
/* @__PURE__ */ s("span", {
|
|
119
|
-
className: "w-16 text-right text-sm font-medium",
|
|
120
|
-
children: [
|
|
121
|
-
"$",
|
|
122
|
-
(e.amount / 1e3).toFixed(1),
|
|
123
|
-
"K"
|
|
124
|
-
]
|
|
125
|
-
}),
|
|
126
|
-
/* @__PURE__ */ s(c, {
|
|
127
|
-
variant: "outline",
|
|
128
|
-
className: "text-[10px]",
|
|
129
|
-
children: [e.orders, " orders"]
|
|
130
|
-
})
|
|
131
|
-
]
|
|
132
|
-
}, `${e.month}-${t}`))
|
|
133
|
-
})] }),
|
|
134
|
-
/* @__PURE__ */ s(l, { children: [/* @__PURE__ */ o(d, { children: /* @__PURE__ */ o(f, { children: "Recent Payments" }) }), /* @__PURE__ */ o(u, {
|
|
135
|
-
className: "space-y-3",
|
|
136
|
-
children: y.map((e) => /* @__PURE__ */ s("div", {
|
|
137
|
-
className: "flex items-center justify-between rounded border p-3",
|
|
138
|
-
children: [/* @__PURE__ */ s("div", { children: [/* @__PURE__ */ o("p", {
|
|
139
|
-
className: "text-sm font-medium",
|
|
140
|
-
children: e.client
|
|
141
|
-
}), /* @__PURE__ */ o("p", {
|
|
142
|
-
className: "text-xs text-text-secondary",
|
|
143
|
-
children: e.date
|
|
144
|
-
})] }), /* @__PURE__ */ s("div", {
|
|
145
|
-
className: "flex items-center gap-2",
|
|
146
|
-
children: [/* @__PURE__ */ s("span", {
|
|
147
|
-
className: "text-sm font-bold",
|
|
148
|
-
children: ["$", e.amount.toLocaleString()]
|
|
149
|
-
}), /* @__PURE__ */ o(c, {
|
|
150
|
-
variant: e.status === "completed" ? "default" : "secondary",
|
|
151
|
-
className: "text-[10px]",
|
|
152
|
-
children: t(e.status)
|
|
153
|
-
})]
|
|
154
|
-
})]
|
|
155
|
-
}, e.id))
|
|
156
|
-
})] })
|
|
157
|
-
]
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
//#endregion
|
|
161
|
-
export { v as MarketplaceEarningsPagePage };
|
|
162
|
-
|
|
163
|
-
//# sourceMappingURL=MarketplaceEarningsPagePage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MarketplaceEarningsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceEarningsPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Badge,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { DollarSign, TrendingUp, Wallet } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\ntype EarningPoint = {\n month: string;\n amount: number;\n orders: number;\n};\n\ntype PaymentItem = {\n id: string;\n client: string;\n amount: number;\n date: string;\n status: 'completed' | 'pending';\n};\n\nconst monthLabel = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'N/A';\n }\n return parsed.toLocaleString('en-US', { month: 'short' });\n};\n\nconst isoDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function MarketplaceEarningsPagePage() {\n const { invoices } = useCrewFoundryStore();\n\n const recentPayments = useMemo<PaymentItem[]>(() => {\n return invoices.slice(0, 12).map((invoice) => ({\n id: invoice.id,\n client: invoice.clientName,\n amount: invoice.amount,\n date: isoDate(invoice.issueDate),\n status: invoice.status === 'paid' ? 'completed' : 'pending',\n }));\n }, [invoices]);\n\n const earningsData = useMemo<EarningPoint[]>(() => {\n return recentPayments.slice(0, 6).map((payment, index) => {\n const sibling = recentPayments.filter(\n (item) => monthLabel(item.date) === monthLabel(payment.date)\n );\n const amount = sibling.reduce((sum, item) => sum + item.amount, 0);\n return {\n month: monthLabel(payment.date) || `M${index + 1}`,\n amount,\n orders: sibling.length,\n };\n });\n }, [recentPayments]);\n\n const totalEarnings = earningsData.reduce((sum, point) => sum + point.amount, 0);\n const maxEarning = Math.max(1, ...earningsData.map((point) => point.amount));\n const totalOrders = earningsData.reduce((sum, point) => sum + point.orders, 0);\n const pendingAmount = recentPayments\n .filter((payment) => payment.status === 'pending')\n .reduce((sum, payment) => sum + payment.amount, 0);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Earnings</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Revenue from marketplace services</p>\n <PagePurpose className=\"mt-1\">\n Track what you've earned on the marketplace — payouts, pending balances, and earning\n trends so you always know where you stand.\n </PagePurpose>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Earnings</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${totalEarnings.toLocaleString()}</div>\n <p className=\"text-xs text-text-secondary\">Across {totalOrders} paid orders</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\">Avg Order Value</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${Math.round(totalEarnings / Math.max(totalOrders, 1)).toLocaleString()}\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Pending</CardTitle>\n <Wallet className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${pendingAmount.toLocaleString()}</div>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Earnings Trend</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {earningsData.map((earning, index) => (\n <div key={`${earning.month}-${index}`} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-sm text-text-secondary\">{earning.month}</span>\n <div className=\"h-4 flex-1 overflow-hidden rounded bg-bg-sunken\">\n <div\n className=\"h-4 rounded bg-action-primary-bg\"\n style={{ width: `${Math.round((earning.amount / maxEarning) * 100)}%` }}\n />\n </div>\n <span className=\"w-16 text-right text-sm font-medium\">\n ${(earning.amount / 1000).toFixed(1)}K\n </span>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {earning.orders} orders\n </Badge>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Recent Payments</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {recentPayments.map((payment) => (\n <div key={payment.id} className=\"flex items-center justify-between rounded border p-3\">\n <div>\n <p className=\"text-sm font-medium\">{payment.client}</p>\n <p className=\"text-xs text-text-secondary\">{payment.date}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-bold\">${payment.amount.toLocaleString()}</span>\n <Badge\n variant={payment.status === 'completed' ? 'default' : 'secondary'}\n className=\"text-[10px]\"\n >\n {formatEnumLabel(payment.status)}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MarketplaceFreelancerProfilePageEnhancedPage.d.ts","sourceRoot":"","sources":["../../../src/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.tsx"],"names":[],"mappings":"AAyCA,wBAAgB,4CAA4C,gCA0T3D"}
|