@burdenoff/microfe-crewfoundry 2026.624.1 → 2026.625.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.
Files changed (131) hide show
  1. package/dist/crewfoundry/pages/AdminAdminPagePage.js +100 -76
  2. package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
  3. package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +118 -94
  4. package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
  5. package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +105 -81
  6. package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
  7. package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +134 -110
  8. package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
  9. package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +121 -97
  10. package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
  11. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +28 -15
  12. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
  13. package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +74 -54
  14. package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
  15. package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +87 -69
  16. package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
  17. package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +99 -80
  18. package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
  19. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +87 -68
  20. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
  21. package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +31 -15
  22. package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
  23. package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +81 -61
  24. package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
  25. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +71 -51
  26. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
  27. package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +82 -58
  28. package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
  29. package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +46 -39
  30. package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
  31. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +80 -62
  32. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
  33. package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +104 -80
  34. package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
  35. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +219 -151
  36. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
  37. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +183 -142
  38. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
  39. package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +121 -97
  40. package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
  41. package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +57 -46
  42. package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
  43. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +91 -67
  44. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
  45. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +112 -93
  46. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
  47. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +55 -48
  48. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
  49. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +70 -50
  50. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
  51. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +140 -97
  52. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
  53. package/dist/crewfoundry/pages/HiringJobsPagePage.js +101 -85
  54. package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
  55. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +68 -48
  56. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
  57. package/dist/crewfoundry/pages/HrEmployeesPagePage.js +99 -71
  58. package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
  59. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +97 -73
  60. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
  61. package/dist/crewfoundry/pages/HrPayrollPagePage.js +100 -76
  62. package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
  63. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +93 -69
  64. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
  65. package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +65 -45
  66. package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
  67. package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +93 -75
  68. package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
  69. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +117 -72
  70. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
  71. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +66 -54
  72. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
  73. package/dist/crewfoundry/pages/LearningCoursesPagePage.js +36 -20
  74. package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
  75. package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +90 -66
  76. package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
  77. package/dist/crewfoundry/pages/LearningLearningPagePage.js +81 -57
  78. package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
  79. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +90 -65
  80. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
  81. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +33 -17
  82. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
  83. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +83 -59
  84. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
  85. package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +68 -48
  86. package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
  87. package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +80 -60
  88. package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
  89. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +153 -118
  90. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
  91. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +42 -37
  92. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
  93. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +67 -47
  94. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
  95. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +104 -85
  96. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
  97. package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +76 -57
  98. package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
  99. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +78 -60
  100. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
  101. package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +138 -93
  102. package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
  103. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +98 -53
  104. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
  105. package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +69 -49
  106. package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
  107. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +84 -65
  108. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
  109. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +76 -52
  110. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
  111. package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +58 -40
  112. package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
  113. package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +85 -65
  114. package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
  115. package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +36 -29
  116. package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
  117. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +108 -73
  118. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
  119. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +43 -27
  120. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
  121. package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +67 -47
  122. package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
  123. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +108 -63
  124. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
  125. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +83 -64
  126. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
  127. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +185 -144
  128. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
  129. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +40 -24
  130. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
  131. package/package.json +2 -2
@@ -2,14 +2,14 @@ import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
2
2
  import { useMemo as t } from "react";
3
3
  import { CheckCircle as n, Clock as r, FileText as i, Play as a } from "lucide-react";
4
4
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
5
- import { Badge as c, Button as l, Card as u, CardContent as d, CardHeader as f, CardTitle as p } from "@burdenoff/fe-libs/ui";
5
+ import { Badge as c, Button as l, Card as u, CardContent as d, CardHeader as f, CardTitle as p, GlassCard as m, GradientText as h, PagePurpose as g } from "@burdenoff/fe-libs/ui";
6
6
  //#region src/crewfoundry/pages/LearningAssessmentsPagePage.tsx
7
- var m = (/* @__PURE__ */ new Date("2026-03-01T00:00:00Z")).getTime(), h = (e) => {
7
+ var _ = (/* @__PURE__ */ new Date("2026-03-01T00:00:00Z")).getTime(), v = (e) => {
8
8
  let t = new Date(e);
9
9
  return Number.isNaN(t.getTime()) ? "Unknown" : t.toISOString().split("T")[0];
10
10
  };
11
- function g() {
12
- let { courses: g } = e(), _ = t(() => g.slice(0, 16).map((e, t) => {
11
+ function y() {
12
+ let { courses: y } = e(), b = t(() => y.slice(0, 16).map((e, t) => {
13
13
  let n = t % 6 == 0 ? "overdue" : t % 2 == 0 ? "available" : "completed", r = 70 + t % 4 * 5;
14
14
  return {
15
15
  id: e.id,
@@ -19,58 +19,78 @@ function g() {
19
19
  duration: `${Math.max(15, e.modules * 8)} min`,
20
20
  status: n,
21
21
  score: n === "completed" ? Math.min(99, Math.round(e.rating * 20 + 20)) : void 0,
22
- dueDate: h(new Date(m + (t - 3) * 864e5 * 6).toISOString()),
22
+ dueDate: v(new Date(_ + (t - 3) * 864e5 * 6).toISOString()),
23
23
  passingScore: r
24
24
  };
25
- }), [g]);
25
+ }), [y]);
26
26
  return /* @__PURE__ */ s("div", {
27
27
  className: "space-y-6 p-6",
28
28
  children: [
29
- /* @__PURE__ */ s("div", { children: [/* @__PURE__ */ o("h1", {
30
- className: "text-2xl font-semibold",
31
- children: "Assessments"
32
- }), /* @__PURE__ */ o("p", {
33
- className: "text-sm text-text-secondary",
34
- children: "Quizzes and exams for your enrolled courses"
35
- })] }),
29
+ /* @__PURE__ */ s("div", { children: [
30
+ /* @__PURE__ */ o("h1", {
31
+ className: "text-2xl font-semibold",
32
+ children: /* @__PURE__ */ o(h, { children: "Assessments" })
33
+ }),
34
+ /* @__PURE__ */ o("p", {
35
+ className: "text-sm text-text-secondary",
36
+ children: "Quizzes and exams for your enrolled courses"
37
+ }),
38
+ /* @__PURE__ */ o(g, {
39
+ className: "mt-1",
40
+ children: "Create and review assessments that measure what your team has learned — use them to certify skills and identify knowledge gaps."
41
+ })
42
+ ] }),
36
43
  /* @__PURE__ */ s("div", {
37
44
  className: "grid gap-4 md:grid-cols-3",
38
45
  children: [
39
- /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ s(f, {
40
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
41
- children: [/* @__PURE__ */ o(p, {
42
- className: "text-sm font-medium",
43
- children: "Available"
44
- }), /* @__PURE__ */ o(i, { className: "h-4 w-4 text-blue-500" })]
45
- }), /* @__PURE__ */ o(d, { children: /* @__PURE__ */ o("div", {
46
- className: "text-2xl font-bold",
47
- children: _.filter((e) => e.status === "available").length
48
- }) })] }),
49
- /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ s(f, {
50
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
51
- children: [/* @__PURE__ */ o(p, {
52
- className: "text-sm font-medium",
53
- children: "Completed"
54
- }), /* @__PURE__ */ o(n, { className: "h-4 w-4 text-green-500" })]
55
- }), /* @__PURE__ */ o(d, { children: /* @__PURE__ */ o("div", {
56
- className: "text-2xl font-bold",
57
- children: _.filter((e) => e.status === "completed").length
58
- }) })] }),
59
- /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ s(f, {
60
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
61
- children: [/* @__PURE__ */ o(p, {
62
- className: "text-sm font-medium",
63
- children: "Overdue"
64
- }), /* @__PURE__ */ o(r, { className: "h-4 w-4 text-red-500" })]
65
- }), /* @__PURE__ */ o(d, { children: /* @__PURE__ */ o("div", {
66
- className: "text-2xl font-bold",
67
- children: _.filter((e) => e.status === "overdue").length
68
- }) })] })
46
+ /* @__PURE__ */ s(m, {
47
+ treatment: "glass",
48
+ glow: !0,
49
+ className: "border-border-seam",
50
+ children: [/* @__PURE__ */ s(f, {
51
+ className: "flex flex-row items-center justify-between space-y-0 pb-2",
52
+ children: [/* @__PURE__ */ o(p, {
53
+ className: "text-sm font-medium",
54
+ children: "Available"
55
+ }), /* @__PURE__ */ o(i, { className: "h-4 w-4 text-status-info-text" })]
56
+ }), /* @__PURE__ */ o(d, { children: /* @__PURE__ */ o("div", {
57
+ className: "text-2xl font-bold tabular-nums",
58
+ children: b.filter((e) => e.status === "available").length
59
+ }) })]
60
+ }),
61
+ /* @__PURE__ */ s(m, {
62
+ treatment: "metric",
63
+ className: "border-border-seam",
64
+ children: [/* @__PURE__ */ s(f, {
65
+ className: "flex flex-row items-center justify-between space-y-0 pb-2",
66
+ children: [/* @__PURE__ */ o(p, {
67
+ className: "text-sm font-medium",
68
+ children: "Completed"
69
+ }), /* @__PURE__ */ o(n, { className: "h-4 w-4 text-status-success-text" })]
70
+ }), /* @__PURE__ */ o(d, { children: /* @__PURE__ */ o("div", {
71
+ className: "text-2xl font-bold tabular-nums",
72
+ children: b.filter((e) => e.status === "completed").length
73
+ }) })]
74
+ }),
75
+ /* @__PURE__ */ s(m, {
76
+ treatment: "metric",
77
+ className: "border-border-seam",
78
+ children: [/* @__PURE__ */ s(f, {
79
+ className: "flex flex-row items-center justify-between space-y-0 pb-2",
80
+ children: [/* @__PURE__ */ o(p, {
81
+ className: "text-sm font-medium",
82
+ children: "Overdue"
83
+ }), /* @__PURE__ */ o(r, { className: "h-4 w-4 text-status-error-text" })]
84
+ }), /* @__PURE__ */ o(d, { children: /* @__PURE__ */ o("div", {
85
+ className: "text-2xl font-bold tabular-nums",
86
+ children: b.filter((e) => e.status === "overdue").length
87
+ }) })]
88
+ })
69
89
  ]
70
90
  }),
71
91
  /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ o(f, { children: /* @__PURE__ */ o(p, { children: "All Assessments" }) }), /* @__PURE__ */ o(d, {
72
92
  className: "space-y-3",
73
- children: _.map((e) => /* @__PURE__ */ s("div", {
93
+ children: b.map((e) => /* @__PURE__ */ s("div", {
74
94
  className: "flex items-center justify-between rounded border p-4",
75
95
  children: [/* @__PURE__ */ s("div", { children: [
76
96
  /* @__PURE__ */ o("p", {
@@ -131,6 +151,6 @@ function g() {
131
151
  });
132
152
  }
133
153
  //#endregion
134
- export { g as LearningAssessmentsPagePage };
154
+ export { y as LearningAssessmentsPagePage };
135
155
 
136
156
  //# sourceMappingURL=LearningAssessmentsPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LearningAssessmentsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningAssessmentsPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Badge, Button, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { CheckCircle, Clock, FileText, Play } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype Assessment = {\n id: string;\n title: string;\n course: string;\n questions: number;\n duration: string;\n status: 'available' | 'completed' | 'overdue';\n score?: number;\n dueDate: string;\n passingScore: number;\n};\n\nconst BASE_TS = new Date('2026-03-01T00:00:00Z').getTime();\n\nconst formatDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function LearningAssessmentsPagePage() {\n const { courses } = useCrewFoundryStore();\n\n const assessments = useMemo<Assessment[]>(() => {\n return courses.slice(0, 16).map((course, index) => {\n const status: Assessment['status'] =\n index % 6 === 0 ? 'overdue' : index % 2 === 0 ? 'available' : 'completed';\n const passingScore = 70 + (index % 4) * 5;\n\n return {\n id: course.id,\n title: `${course.title} Assessment`,\n course: course.title,\n questions: Math.max(10, course.modules * 4),\n duration: `${Math.max(15, course.modules * 8)} min`,\n status,\n score:\n status === 'completed' ? Math.min(99, Math.round(course.rating * 20 + 20)) : undefined,\n dueDate: formatDate(new Date(BASE_TS + (index - 3) * 86400000 * 6).toISOString()),\n passingScore,\n };\n });\n }, [courses]);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Assessments</h1>\n <p className=\"text-sm text-text-secondary\">Quizzes and exams for your enrolled courses</p>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Available</CardTitle>\n <FileText className=\"h-4 w-4 text-blue-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {assessments.filter((assessment) => assessment.status === 'available').length}\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Completed</CardTitle>\n <CheckCircle className=\"h-4 w-4 text-green-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {assessments.filter((assessment) => assessment.status === 'completed').length}\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Overdue</CardTitle>\n <Clock className=\"h-4 w-4 text-red-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {assessments.filter((assessment) => assessment.status === 'overdue').length}\n </div>\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>All Assessments</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {assessments.map((assessment) => (\n <div\n key={assessment.id}\n className=\"flex items-center justify-between rounded border p-4\"\n >\n <div>\n <p className=\"text-sm font-medium\">{assessment.title}</p>\n <p className=\"text-xs text-text-secondary\">\n {assessment.course} · {assessment.questions} questions · {assessment.duration}\n </p>\n <p className=\"text-xs text-text-secondary\">\n Due: {assessment.dueDate} · Passing: {assessment.passingScore}%\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n {assessment.status === 'completed' && assessment.score ? (\n <Badge\n variant={\n assessment.score >= assessment.passingScore ? 'default' : 'destructive'\n }\n className=\"text-[10px]\"\n >\n Score: {assessment.score}%\n </Badge>\n ) : null}\n <Badge\n variant={\n assessment.status === 'completed'\n ? 'default'\n : assessment.status === 'overdue'\n ? 'destructive'\n : 'secondary'\n }\n className=\"text-[10px]\"\n >\n {assessment.status}\n </Badge>\n {assessment.status === 'available' ? (\n <Button size=\"sm\">\n <Play className=\"mr-1 h-3 w-3\" />\n Start\n </Button>\n ) : null}\n {assessment.status === 'overdue' ? (\n <Button size=\"sm\" variant=\"destructive\">\n <Play className=\"mr-1 h-3 w-3\" />\n Take Now\n </Button>\n ) : null}\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"LearningAssessmentsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningAssessmentsPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { CheckCircle, Clock, FileText, Play } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype Assessment = {\n id: string;\n title: string;\n course: string;\n questions: number;\n duration: string;\n status: 'available' | 'completed' | 'overdue';\n score?: number;\n dueDate: string;\n passingScore: number;\n};\n\nconst BASE_TS = new Date('2026-03-01T00:00:00Z').getTime();\n\nconst formatDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function LearningAssessmentsPagePage() {\n const { courses } = useCrewFoundryStore();\n\n const assessments = useMemo<Assessment[]>(() => {\n return courses.slice(0, 16).map((course, index) => {\n const status: Assessment['status'] =\n index % 6 === 0 ? 'overdue' : index % 2 === 0 ? 'available' : 'completed';\n const passingScore = 70 + (index % 4) * 5;\n\n return {\n id: course.id,\n title: `${course.title} Assessment`,\n course: course.title,\n questions: Math.max(10, course.modules * 4),\n duration: `${Math.max(15, course.modules * 8)} min`,\n status,\n score:\n status === 'completed' ? Math.min(99, Math.round(course.rating * 20 + 20)) : undefined,\n dueDate: formatDate(new Date(BASE_TS + (index - 3) * 86400000 * 6).toISOString()),\n passingScore,\n };\n });\n }, [courses]);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Assessments</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Quizzes and exams for your enrolled courses</p>\n <PagePurpose className=\"mt-1\">Create and review assessments that measure what your team has learned — use them to certify skills and identify knowledge gaps.</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\">Available</CardTitle>\n <FileText className=\"h-4 w-4 text-status-info-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {assessments.filter((assessment) => assessment.status === 'available').length}\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Completed</CardTitle>\n <CheckCircle className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {assessments.filter((assessment) => assessment.status === 'completed').length}\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Overdue</CardTitle>\n <Clock className=\"h-4 w-4 text-status-error-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {assessments.filter((assessment) => assessment.status === 'overdue').length}\n </div>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>All Assessments</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {assessments.map((assessment) => (\n <div\n key={assessment.id}\n className=\"flex items-center justify-between rounded border p-4\"\n >\n <div>\n <p className=\"text-sm font-medium\">{assessment.title}</p>\n <p className=\"text-xs text-text-secondary\">\n {assessment.course} · {assessment.questions} questions · {assessment.duration}\n </p>\n <p className=\"text-xs text-text-secondary\">\n Due: {assessment.dueDate} · Passing: {assessment.passingScore}%\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n {assessment.status === 'completed' && assessment.score ? (\n <Badge\n variant={\n assessment.score >= assessment.passingScore ? 'default' : 'destructive'\n }\n className=\"text-[10px]\"\n >\n Score: {assessment.score}%\n </Badge>\n ) : null}\n <Badge\n variant={\n assessment.status === 'completed'\n ? 'default'\n : assessment.status === 'overdue'\n ? 'destructive'\n : 'secondary'\n }\n className=\"text-[10px]\"\n >\n {assessment.status}\n </Badge>\n {assessment.status === 'available' ? (\n <Button size=\"sm\">\n <Play className=\"mr-1 h-3 w-3\" />\n Start\n </Button>\n ) : null}\n {assessment.status === 'overdue' ? (\n <Button size=\"sm\" variant=\"destructive\">\n <Play className=\"mr-1 h-3 w-3\" />\n Take Now\n </Button>\n ) : null}\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -2,102 +2,120 @@ import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
2
2
  import { useMemo as t } from "react";
3
3
  import { Award as n, Download as r, ExternalLink as i } from "lucide-react";
4
4
  import { jsx as a, jsxs as o } from "react/jsx-runtime";
5
- import { Badge as s, Button as c, Card as l, CardContent as u, CardHeader as d, CardTitle as f } from "@burdenoff/fe-libs/ui";
5
+ import { Badge as s, Button as c, CardContent as l, CardHeader as u, CardTitle as d, GlassCard as f, GradientText as p, IllustratedEmptyState as m, PagePurpose as h } from "@burdenoff/fe-libs/ui";
6
6
  //#region src/crewfoundry/pages/LearningCertificatesPagePage.tsx
7
- var p = (/* @__PURE__ */ new Date("2026-03-01T00:00:00Z")).getTime(), m = (e) => {
7
+ var g = (/* @__PURE__ */ new Date("2026-03-01T00:00:00Z")).getTime(), _ = (e) => {
8
8
  let t = new Date(e);
9
9
  return Number.isNaN(t.getTime()) ? "Unknown" : t.toISOString().split("T")[0];
10
10
  };
11
- function h() {
12
- let { courses: h, employees: g } = e(), _ = t(() => h.slice(0, 12).map((e, t) => {
13
- let n = g[t % Math.max(g.length, 1)]?.firstName && g[t % Math.max(g.length, 1)]?.lastName ? `${g[t % g.length].firstName} ${g[t % g.length].lastName}` : e.instructor;
11
+ function v() {
12
+ let { courses: v, employees: y } = e(), b = t(() => v.slice(0, 12).map((e, t) => {
13
+ let n = y[t % Math.max(y.length, 1)]?.firstName && y[t % Math.max(y.length, 1)]?.lastName ? `${y[t % y.length].firstName} ${y[t % y.length].lastName}` : e.instructor;
14
14
  return {
15
15
  id: e.id,
16
16
  title: e.title,
17
- issueDate: m((/* @__PURE__ */ new Date(p - t * 864e5 * 12)).toISOString()),
17
+ issueDate: _((/* @__PURE__ */ new Date(g - t * 864e5 * 12)).toISOString()),
18
18
  instructor: n,
19
19
  credentialId: `CF-${e.id.slice(0, 6).toUpperCase()}-${t + 1}`,
20
20
  status: t % 5 == 0 ? "expiring" : "active",
21
- expiryDate: t % 5 == 0 ? m(new Date(p + 864e5 * (60 + t * 3)).toISOString()) : void 0
21
+ expiryDate: t % 5 == 0 ? _(new Date(g + 864e5 * (60 + t * 3)).toISOString()) : void 0
22
22
  };
23
- }), [h, g]);
23
+ }), [v, y]);
24
24
  return /* @__PURE__ */ o("div", {
25
25
  className: "space-y-6 p-6",
26
- children: [/* @__PURE__ */ o("div", { children: [/* @__PURE__ */ a("h1", {
27
- className: "text-2xl font-semibold",
28
- children: "Certificates"
29
- }), /* @__PURE__ */ o("p", {
30
- className: "text-sm text-text-secondary",
31
- children: [_.length, " certificates earned"]
32
- })] }), /* @__PURE__ */ a("div", {
26
+ children: [/* @__PURE__ */ o("div", { children: [
27
+ /* @__PURE__ */ a("h1", {
28
+ className: "text-2xl font-semibold",
29
+ children: /* @__PURE__ */ a(p, { children: "Certificates" })
30
+ }),
31
+ /* @__PURE__ */ o("p", {
32
+ className: "text-sm text-text-secondary",
33
+ children: [b.length, " certificates earned"]
34
+ }),
35
+ /* @__PURE__ */ a(h, {
36
+ className: "mt-1",
37
+ children: "View and manage the certificates your team has earned — proof of completed training and validated skills."
38
+ })
39
+ ] }), /* @__PURE__ */ a("div", {
33
40
  className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
34
- children: _.map((e) => /* @__PURE__ */ o(l, { children: [/* @__PURE__ */ o(d, { children: [/* @__PURE__ */ o("div", {
35
- className: "flex items-center justify-between",
36
- children: [/* @__PURE__ */ a(n, { className: "h-8 w-8 text-yellow-500" }), /* @__PURE__ */ a(s, {
37
- variant: e.status === "active" ? "default" : "secondary",
38
- className: "text-[10px]",
39
- children: e.status
40
- })]
41
- }), /* @__PURE__ */ a(f, {
42
- className: "mt-2 text-base",
43
- children: e.title
44
- })] }), /* @__PURE__ */ o(u, { children: [/* @__PURE__ */ o("div", {
45
- className: "space-y-2 text-sm text-text-secondary",
46
- children: [
47
- /* @__PURE__ */ o("div", { children: [
48
- /* @__PURE__ */ a("span", {
49
- className: "text-xs",
50
- children: "Instructor:"
51
- }),
52
- " ",
53
- e.instructor
54
- ] }),
55
- /* @__PURE__ */ o("div", { children: [
56
- /* @__PURE__ */ a("span", {
57
- className: "text-xs",
58
- children: "Issued:"
59
- }),
60
- " ",
61
- e.issueDate
62
- ] }),
63
- /* @__PURE__ */ o("div", { children: [
64
- /* @__PURE__ */ a("span", {
65
- className: "text-xs",
66
- children: "Credential ID:"
67
- }),
68
- " ",
69
- e.credentialId
70
- ] }),
71
- e.expiryDate ? /* @__PURE__ */ o("div", {
72
- className: "text-yellow-600",
73
- children: [
41
+ children: b.length === 0 ? /* @__PURE__ */ a("div", {
42
+ className: "col-span-full",
43
+ children: /* @__PURE__ */ a(m, {
44
+ illustration: "empty-generic",
45
+ title: "No certificates yet",
46
+ description: "Certificates appear here as your team completes courses."
47
+ })
48
+ }) : b.map((e, t) => /* @__PURE__ */ o(f, {
49
+ treatment: t === 0 ? "glass" : "plain",
50
+ glow: t === 0,
51
+ children: [/* @__PURE__ */ o(u, { children: [/* @__PURE__ */ o("div", {
52
+ className: "flex items-center justify-between",
53
+ children: [/* @__PURE__ */ a(n, { className: "h-8 w-8 text-status-warning-text" }), /* @__PURE__ */ a(s, {
54
+ variant: e.status === "active" ? "default" : "secondary",
55
+ className: "text-[10px]",
56
+ children: e.status
57
+ })]
58
+ }), /* @__PURE__ */ a(d, {
59
+ className: "mt-2 text-base",
60
+ children: e.title
61
+ })] }), /* @__PURE__ */ o(l, { children: [/* @__PURE__ */ o("div", {
62
+ className: "space-y-2 text-sm text-text-secondary",
63
+ children: [
64
+ /* @__PURE__ */ o("div", { children: [
74
65
  /* @__PURE__ */ a("span", {
75
66
  className: "text-xs",
76
- children: "Expires:"
67
+ children: "Instructor:"
77
68
  }),
78
69
  " ",
79
- e.expiryDate
80
- ]
81
- }) : null
82
- ]
83
- }), /* @__PURE__ */ o("div", {
84
- className: "mt-3 flex gap-2",
85
- children: [/* @__PURE__ */ o(c, {
86
- variant: "outline",
87
- size: "sm",
88
- className: "flex-1",
89
- children: [/* @__PURE__ */ a(r, { className: "mr-1 h-3 w-3" }), "Download"]
90
- }), /* @__PURE__ */ o(c, {
91
- variant: "outline",
92
- size: "sm",
93
- className: "flex-1",
94
- children: [/* @__PURE__ */ a(i, { className: "mr-1 h-3 w-3" }), "Verify"]
95
- })]
96
- })] })] }, e.id))
70
+ e.instructor
71
+ ] }),
72
+ /* @__PURE__ */ o("div", { children: [
73
+ /* @__PURE__ */ a("span", {
74
+ className: "text-xs",
75
+ children: "Issued:"
76
+ }),
77
+ " ",
78
+ e.issueDate
79
+ ] }),
80
+ /* @__PURE__ */ o("div", { children: [
81
+ /* @__PURE__ */ a("span", {
82
+ className: "text-xs",
83
+ children: "Credential ID:"
84
+ }),
85
+ " ",
86
+ e.credentialId
87
+ ] }),
88
+ e.expiryDate ? /* @__PURE__ */ o("div", {
89
+ className: "text-status-warning-text",
90
+ children: [
91
+ /* @__PURE__ */ a("span", {
92
+ className: "text-xs",
93
+ children: "Expires:"
94
+ }),
95
+ " ",
96
+ e.expiryDate
97
+ ]
98
+ }) : null
99
+ ]
100
+ }), /* @__PURE__ */ o("div", {
101
+ className: "mt-3 flex gap-2",
102
+ children: [/* @__PURE__ */ o(c, {
103
+ variant: "outline",
104
+ size: "sm",
105
+ className: "flex-1",
106
+ children: [/* @__PURE__ */ a(r, { className: "mr-1 h-3 w-3" }), "Download"]
107
+ }), /* @__PURE__ */ o(c, {
108
+ variant: "outline",
109
+ size: "sm",
110
+ className: "flex-1",
111
+ children: [/* @__PURE__ */ a(i, { className: "mr-1 h-3 w-3" }), "Verify"]
112
+ })]
113
+ })] })]
114
+ }, e.id))
97
115
  })]
98
116
  });
99
117
  }
100
118
  //#endregion
101
- export { h as LearningCertificatesPagePage };
119
+ export { v as LearningCertificatesPagePage };
102
120
 
103
121
  //# sourceMappingURL=LearningCertificatesPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LearningCertificatesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningCertificatesPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Badge, Button, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Award, Download, ExternalLink } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype Certificate = {\n id: string;\n title: string;\n issueDate: string;\n instructor: string;\n credentialId: string;\n status: 'active' | 'expiring';\n expiryDate?: string;\n};\n\nconst BASE_TS = new Date('2026-03-01T00:00:00Z').getTime();\n\nconst isoDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function LearningCertificatesPagePage() {\n const { courses, employees } = useCrewFoundryStore();\n\n const certificates = useMemo<Certificate[]>(() => {\n return courses.slice(0, 12).map((course, index) => {\n const instructor =\n employees[index % Math.max(employees.length, 1)]?.firstName &&\n employees[index % Math.max(employees.length, 1)]?.lastName\n ? `${employees[index % employees.length].firstName} ${employees[index % employees.length].lastName}`\n : course.instructor;\n\n return {\n id: course.id,\n title: course.title,\n issueDate: isoDate(new Date(BASE_TS - index * 86400000 * 12).toISOString()),\n instructor,\n credentialId: `CF-${course.id.slice(0, 6).toUpperCase()}-${index + 1}`,\n status: index % 5 === 0 ? 'expiring' : 'active',\n expiryDate:\n index % 5 === 0\n ? isoDate(new Date(BASE_TS + 86400000 * (60 + index * 3)).toISOString())\n : undefined,\n };\n });\n }, [courses, employees]);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Certificates</h1>\n <p className=\"text-sm text-text-secondary\">{certificates.length} certificates earned</p>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {certificates.map((certificate) => (\n <Card key={certificate.id}>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <Award className=\"h-8 w-8 text-yellow-500\" />\n <Badge\n variant={certificate.status === 'active' ? 'default' : 'secondary'}\n className=\"text-[10px]\"\n >\n {certificate.status}\n </Badge>\n </div>\n <CardTitle className=\"mt-2 text-base\">{certificate.title}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2 text-sm text-text-secondary\">\n <div>\n <span className=\"text-xs\">Instructor:</span> {certificate.instructor}\n </div>\n <div>\n <span className=\"text-xs\">Issued:</span> {certificate.issueDate}\n </div>\n <div>\n <span className=\"text-xs\">Credential ID:</span> {certificate.credentialId}\n </div>\n {certificate.expiryDate ? (\n <div className=\"text-yellow-600\">\n <span className=\"text-xs\">Expires:</span> {certificate.expiryDate}\n </div>\n ) : null}\n </div>\n\n <div className=\"mt-3 flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" className=\"flex-1\">\n <Download className=\"mr-1 h-3 w-3\" />\n Download\n </Button>\n <Button variant=\"outline\" size=\"sm\" className=\"flex-1\">\n <ExternalLink className=\"mr-1 h-3 w-3\" />\n Verify\n </Button>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"LearningCertificatesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningCertificatesPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Badge,\n Button,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Award, Download, ExternalLink } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype Certificate = {\n id: string;\n title: string;\n issueDate: string;\n instructor: string;\n credentialId: string;\n status: 'active' | 'expiring';\n expiryDate?: string;\n};\n\nconst BASE_TS = new Date('2026-03-01T00:00:00Z').getTime();\n\nconst isoDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function LearningCertificatesPagePage() {\n const { courses, employees } = useCrewFoundryStore();\n\n const certificates = useMemo<Certificate[]>(() => {\n return courses.slice(0, 12).map((course, index) => {\n const instructor =\n employees[index % Math.max(employees.length, 1)]?.firstName &&\n employees[index % Math.max(employees.length, 1)]?.lastName\n ? `${employees[index % employees.length].firstName} ${employees[index % employees.length].lastName}`\n : course.instructor;\n\n return {\n id: course.id,\n title: course.title,\n issueDate: isoDate(new Date(BASE_TS - index * 86400000 * 12).toISOString()),\n instructor,\n credentialId: `CF-${course.id.slice(0, 6).toUpperCase()}-${index + 1}`,\n status: index % 5 === 0 ? 'expiring' : 'active',\n expiryDate:\n index % 5 === 0\n ? isoDate(new Date(BASE_TS + 86400000 * (60 + index * 3)).toISOString())\n : undefined,\n };\n });\n }, [courses, employees]);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Certificates</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{certificates.length} certificates earned</p>\n <PagePurpose className=\"mt-1\">View and manage the certificates your team has earned — proof of completed training and validated skills.</PagePurpose>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {certificates.length === 0 ? (\n <div className=\"col-span-full\">\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No certificates yet\"\n description=\"Certificates appear here as your team completes courses.\"\n />\n </div>\n ) : (\n certificates.map((certificate, _idx) => (\n <GlassCard\n key={certificate.id}\n treatment={_idx === 0 ? 'glass' : 'plain'}\n glow={_idx === 0}\n >\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <Award className=\"h-8 w-8 text-status-warning-text\" />\n <Badge\n variant={certificate.status === 'active' ? 'default' : 'secondary'}\n className=\"text-[10px]\"\n >\n {certificate.status}\n </Badge>\n </div>\n <CardTitle className=\"mt-2 text-base\">{certificate.title}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2 text-sm text-text-secondary\">\n <div>\n <span className=\"text-xs\">Instructor:</span> {certificate.instructor}\n </div>\n <div>\n <span className=\"text-xs\">Issued:</span> {certificate.issueDate}\n </div>\n <div>\n <span className=\"text-xs\">Credential ID:</span> {certificate.credentialId}\n </div>\n {certificate.expiryDate ? (\n <div className=\"text-status-warning-text\">\n <span className=\"text-xs\">Expires:</span> {certificate.expiryDate}\n </div>\n ) : null}\n </div>\n\n <div className=\"mt-3 flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" className=\"flex-1\">\n <Download className=\"mr-1 h-3 w-3\" />\n Download\n </Button>\n <Button variant=\"outline\" size=\"sm\" className=\"flex-1\">\n <ExternalLink className=\"mr-1 h-3 w-3\" />\n Verify\n </Button>\n </div>\n </CardContent>\n </GlassCard>\n )))}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}