@burdenoff/microfe-crewfoundry 2026.529.1 → 2026.624.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/pages/AdminAdminPagePage.js +15 -15
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +15 -15
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +17 -17
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +19 -19
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +16 -16
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +5 -5
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +7 -7
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +7 -7
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +7 -7
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +7 -7
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +3 -3
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +8 -8
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +8 -8
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +14 -14
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +10 -10
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +4 -4
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +17 -17
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +19 -19
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +17 -17
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +12 -12
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +12 -12
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +11 -11
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +7 -7
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +7 -7
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +13 -13
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +7 -7
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +10 -10
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +9 -9
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +13 -13
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +10 -10
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +9 -9
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +3 -3
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +2 -2
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +11 -11
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +7 -7
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +4 -4
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +9 -9
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +10 -10
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +11 -11
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +5 -5
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +7 -7
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +3 -3
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +7 -7
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +11 -11
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +11 -11
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +6 -6
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +6 -6
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +7 -7
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +2 -2
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +15 -15
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +10 -10
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +5 -5
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +6 -6
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +6 -6
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +4 -4
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +4 -4
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +15 -15
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +4 -4
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +8 -8
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +14 -14
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +6 -6
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +20 -20
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +3 -3
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LearningLearningAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningLearningAnalyticsPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Clock, GraduationCap, Star, Users } from 'lucide-react';\nimport {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype MonthlyLearning = {\n month: string;\n hours: number;\n completions: number;\n enrollments: number;\n};\n\nconst BASE_TS = new Date('2026-03-01T00:00:00Z').getTime();\n\nexport function LearningLearningAnalyticsPagePage() {\n const { courses } = useCrewFoundryStore();\n\n const totalEnrolled = courses.reduce((sum, course) => sum + course.enrolled, 0);\n const totalCompleted = courses.reduce((sum, course) => sum + course.completed, 0);\n const avgRating = (\n courses.reduce((sum, course) => sum + course.rating, 0) / Math.max(courses.length, 1)\n ).toFixed(1);\n\n const monthlyLearning = useMemo<MonthlyLearning[]>(() => {\n return courses.slice(0, 6).map((course, index) => {\n const month = new Date(BASE_TS - (5 - index) * 86400000 * 30).toLocaleString('en-US', {\n month: 'short',\n });\n return {\n month,\n hours: Math.round((course.completed + Math.max(course.modules, 1)) * 2.2),\n completions: course.completed,\n enrollments: course.enrolled,\n };\n });\n }, [courses]);\n\n const maxHours = Math.max(1, ...monthlyLearning.map((item) => item.hours));\n const totalHours = monthlyLearning.reduce((sum, item) => sum + item.hours, 0);\n\n const categoryDistribution = courses.reduce<Record<string, number>>((acc, course) => {\n acc[course.category] = (acc[course.category] || 0) + course.enrolled;\n return acc;\n }, {});\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Learning Analytics</h1>\n <p className=\"text-sm text-muted-foreground\">Training metrics and engagement insights</p>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Enrollments</CardTitle>\n <Users className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{totalEnrolled}</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\">Completions</CardTitle>\n <GraduationCap className=\"h-4 w-4 text-green-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{totalCompleted}</div>\n <p className=\"text-xs text-muted-foreground\">\n {Math.round((totalCompleted / Math.max(totalEnrolled, 1)) * 100)}% rate\n </p>\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\">Avg Rating</CardTitle>\n <Star className=\"h-4 w-4 text-yellow-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{avgRating}/5</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\">Training Hours</CardTitle>\n <Clock className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{totalHours.toLocaleString()}</div>\n <p className=\"text-xs text-muted-foreground\">Recent 6-month trend</p>\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Monthly Training Activity</CardTitle>\n <CardDescription>Hours and completions over time</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {monthlyLearning.map((item) => (\n <div key={`${item.month}-${item.hours}`} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-sm text-muted-foreground\">{item.month}</span>\n <div className=\"h-4 flex-1 overflow-hidden rounded bg-muted\">\n <div\n className=\"h-4 rounded bg-primary\"\n style={{ width: `${Math.round((item.hours / maxHours) * 100)}%` }}\n />\n </div>\n <span className=\"w-16 text-right text-sm font-medium\">{item.hours}h</span>\n <Badge variant=\"default\" className=\"text-[10px]\">\n {item.completions} done\n </Badge>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>Category Distribution</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {Object.entries(categoryDistribution)\n .sort(([, a], [, b]) => b - a)\n .map(([category, count]) => (\n <div key={category} className=\"flex items-center justify-between\">\n <span className=\"text-sm\">{category}</span>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium\">{count}</span>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {Math.round((count / Math.max(totalEnrolled, 1)) * 100)}%\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Course Performance</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"mb-2 grid grid-cols-4 gap-2 border-b pb-2 text-xs font-medium text-muted-foreground\">\n <span>Course</span>\n <span className=\"text-right\">Enrolled</span>\n <span className=\"text-right\">Completed</span>\n <span className=\"text-right\">Rating</span>\n </div>\n {courses.map((course) => (\n <div\n key={course.id}\n className=\"grid grid-cols-4 gap-2 border-b py-2 text-sm last:border-0\"\n >\n <span className=\"truncate font-medium\">{course.title}</span>\n <span className=\"text-right\">{course.enrolled}</span>\n <span className=\"text-right\">{course.completed}</span>\n <div className=\"flex items-center justify-end gap-1\">\n <Star className=\"h-3 w-3 text-yellow-500\" />\n {course.rating}\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LearningLearningAnalyticsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningLearningAnalyticsPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Clock, GraduationCap, Star, Users } from 'lucide-react';\nimport {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype MonthlyLearning = {\n month: string;\n hours: number;\n completions: number;\n enrollments: number;\n};\n\nconst BASE_TS = new Date('2026-03-01T00:00:00Z').getTime();\n\nexport function LearningLearningAnalyticsPagePage() {\n const { courses } = useCrewFoundryStore();\n\n const totalEnrolled = courses.reduce((sum, course) => sum + course.enrolled, 0);\n const totalCompleted = courses.reduce((sum, course) => sum + course.completed, 0);\n const avgRating = (\n courses.reduce((sum, course) => sum + course.rating, 0) / Math.max(courses.length, 1)\n ).toFixed(1);\n\n const monthlyLearning = useMemo<MonthlyLearning[]>(() => {\n return courses.slice(0, 6).map((course, index) => {\n const month = new Date(BASE_TS - (5 - index) * 86400000 * 30).toLocaleString('en-US', {\n month: 'short',\n });\n return {\n month,\n hours: Math.round((course.completed + Math.max(course.modules, 1)) * 2.2),\n completions: course.completed,\n enrollments: course.enrolled,\n };\n });\n }, [courses]);\n\n const maxHours = Math.max(1, ...monthlyLearning.map((item) => item.hours));\n const totalHours = monthlyLearning.reduce((sum, item) => sum + item.hours, 0);\n\n const categoryDistribution = courses.reduce<Record<string, number>>((acc, course) => {\n acc[course.category] = (acc[course.category] || 0) + course.enrolled;\n return acc;\n }, {});\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Learning Analytics</h1>\n <p className=\"text-sm text-text-secondary\">Training metrics and engagement insights</p>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Enrollments</CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{totalEnrolled}</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\">Completions</CardTitle>\n <GraduationCap className=\"h-4 w-4 text-green-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{totalCompleted}</div>\n <p className=\"text-xs text-text-secondary\">\n {Math.round((totalCompleted / Math.max(totalEnrolled, 1)) * 100)}% rate\n </p>\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\">Avg Rating</CardTitle>\n <Star className=\"h-4 w-4 text-yellow-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{avgRating}/5</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\">Training Hours</CardTitle>\n <Clock className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{totalHours.toLocaleString()}</div>\n <p className=\"text-xs text-text-secondary\">Recent 6-month trend</p>\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Monthly Training Activity</CardTitle>\n <CardDescription>Hours and completions over time</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {monthlyLearning.map((item) => (\n <div key={`${item.month}-${item.hours}`} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-sm text-text-secondary\">{item.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((item.hours / maxHours) * 100)}%` }}\n />\n </div>\n <span className=\"w-16 text-right text-sm font-medium\">{item.hours}h</span>\n <Badge variant=\"default\" className=\"text-[10px]\">\n {item.completions} done\n </Badge>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>Category Distribution</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {Object.entries(categoryDistribution)\n .sort(([, a], [, b]) => b - a)\n .map(([category, count]) => (\n <div key={category} className=\"flex items-center justify-between\">\n <span className=\"text-sm\">{category}</span>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium\">{count}</span>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {Math.round((count / Math.max(totalEnrolled, 1)) * 100)}%\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Course Performance</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"mb-2 grid grid-cols-4 gap-2 border-b pb-2 text-xs font-medium text-text-secondary\">\n <span>Course</span>\n <span className=\"text-right\">Enrolled</span>\n <span className=\"text-right\">Completed</span>\n <span className=\"text-right\">Rating</span>\n </div>\n {courses.map((course) => (\n <div\n key={course.id}\n className=\"grid grid-cols-4 gap-2 border-b py-2 text-sm last:border-0\"\n >\n <span className=\"truncate font-medium\">{course.title}</span>\n <span className=\"text-right\">{course.enrolled}</span>\n <span className=\"text-right\">{course.completed}</span>\n <div className=\"flex items-center justify-end gap-1\">\n <Star className=\"h-3 w-3 text-yellow-500\" />\n {course.rating}\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ function m() {
|
|
|
12
12
|
className: "text-2xl font-semibold",
|
|
13
13
|
children: "Learning & Development"
|
|
14
14
|
}), /* @__PURE__ */ o("p", {
|
|
15
|
-
className: "text-sm text-
|
|
15
|
+
className: "text-sm text-text-secondary",
|
|
16
16
|
children: "Explore courses, learning paths, and grow your skills"
|
|
17
17
|
})] }),
|
|
18
18
|
/* @__PURE__ */ s("div", {
|
|
@@ -23,12 +23,12 @@ function m() {
|
|
|
23
23
|
children: [/* @__PURE__ */ o(p, {
|
|
24
24
|
className: "text-sm font-medium",
|
|
25
25
|
children: "Courses"
|
|
26
|
-
}), /* @__PURE__ */ o(t, { className: "h-4 w-4 text-
|
|
26
|
+
}), /* @__PURE__ */ o(t, { className: "h-4 w-4 text-text-secondary" })]
|
|
27
27
|
}), /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ o("div", {
|
|
28
28
|
className: "text-2xl font-bold",
|
|
29
29
|
children: m.length
|
|
30
30
|
}), /* @__PURE__ */ o("p", {
|
|
31
|
-
className: "text-xs text-
|
|
31
|
+
className: "text-xs text-text-secondary",
|
|
32
32
|
children: "Active courses"
|
|
33
33
|
})] })] }),
|
|
34
34
|
/* @__PURE__ */ s(l, { children: [/* @__PURE__ */ s(f, {
|
|
@@ -36,7 +36,7 @@ function m() {
|
|
|
36
36
|
children: [/* @__PURE__ */ o(p, {
|
|
37
37
|
className: "text-sm font-medium",
|
|
38
38
|
children: "Enrolled"
|
|
39
|
-
}), /* @__PURE__ */ o(a, { className: "h-4 w-4 text-
|
|
39
|
+
}), /* @__PURE__ */ o(a, { className: "h-4 w-4 text-text-secondary" })]
|
|
40
40
|
}), /* @__PURE__ */ o(u, { children: /* @__PURE__ */ o("div", {
|
|
41
41
|
className: "text-2xl font-bold",
|
|
42
42
|
children: g
|
|
@@ -56,7 +56,7 @@ function m() {
|
|
|
56
56
|
children: [/* @__PURE__ */ o(p, {
|
|
57
57
|
className: "text-sm font-medium",
|
|
58
58
|
children: "Paths"
|
|
59
|
-
}), /* @__PURE__ */ o(i, { className: "h-4 w-4 text-
|
|
59
|
+
}), /* @__PURE__ */ o(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
60
60
|
}), /* @__PURE__ */ o(u, { children: /* @__PURE__ */ o("div", {
|
|
61
61
|
className: "text-2xl font-bold",
|
|
62
62
|
children: h.length
|
|
@@ -77,7 +77,7 @@ function m() {
|
|
|
77
77
|
e.duration
|
|
78
78
|
] })] }), /* @__PURE__ */ s(u, { children: [
|
|
79
79
|
/* @__PURE__ */ o("p", {
|
|
80
|
-
className: "text-sm text-
|
|
80
|
+
className: "text-sm text-text-secondary mb-3",
|
|
81
81
|
children: e.description
|
|
82
82
|
}),
|
|
83
83
|
/* @__PURE__ */ s("div", {
|
|
@@ -102,7 +102,7 @@ function m() {
|
|
|
102
102
|
})]
|
|
103
103
|
}),
|
|
104
104
|
/* @__PURE__ */ s("div", {
|
|
105
|
-
className: "mt-2 text-xs text-
|
|
105
|
+
className: "mt-2 text-xs text-text-secondary",
|
|
106
106
|
children: [
|
|
107
107
|
e.enrolled,
|
|
108
108
|
" enrolled · ",
|
|
@@ -121,7 +121,7 @@ function m() {
|
|
|
121
121
|
className: "text-base",
|
|
122
122
|
children: e.title
|
|
123
123
|
}), /* @__PURE__ */ o(d, { children: e.description })] }), /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ s("div", {
|
|
124
|
-
className: "flex items-center justify-between text-sm text-
|
|
124
|
+
className: "flex items-center justify-between text-sm text-text-secondary",
|
|
125
125
|
children: [/* @__PURE__ */ s("span", { children: [
|
|
126
126
|
e.courses.length,
|
|
127
127
|
" courses · ",
|
|
@@ -137,9 +137,9 @@ function m() {
|
|
|
137
137
|
className: "flex justify-between text-xs",
|
|
138
138
|
children: [/* @__PURE__ */ s("span", { children: [e.enrolled, " enrolled"] }), /* @__PURE__ */ s("span", { children: [e.completionRate, "%"] })]
|
|
139
139
|
}), /* @__PURE__ */ o("div", {
|
|
140
|
-
className: "h-2 bg-
|
|
140
|
+
className: "h-2 bg-bg-sunken rounded overflow-hidden",
|
|
141
141
|
children: /* @__PURE__ */ o("div", {
|
|
142
|
-
className: "h-2 bg-primary rounded",
|
|
142
|
+
className: "h-2 bg-action-primary-bg rounded",
|
|
143
143
|
style: { width: `${e.completionRate}%` }
|
|
144
144
|
})
|
|
145
145
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LearningLearningPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningLearningPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { Award, BookOpen, GraduationCap, Star, TrendingUp, Users } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function LearningLearningPagePage() {\n const { courses, learningPaths } = useCrewFoundryStore();\n const totalEnrolled = courses.reduce((s, c) => s + c.enrolled, 0);\n const totalCompleted = courses.reduce((s, c) => s + c.completed, 0);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Learning & Development</h1>\n <p className=\"text-sm text-
|
|
1
|
+
{"version":3,"file":"LearningLearningPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningLearningPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { Award, BookOpen, GraduationCap, Star, TrendingUp, Users } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function LearningLearningPagePage() {\n const { courses, learningPaths } = useCrewFoundryStore();\n const totalEnrolled = courses.reduce((s, c) => s + c.enrolled, 0);\n const totalCompleted = courses.reduce((s, c) => s + c.completed, 0);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Learning & Development</h1>\n <p className=\"text-sm text-text-secondary\">\n Explore courses, learning paths, and grow your skills\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Courses</CardTitle>\n <BookOpen className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{courses.length}</div>\n <p className=\"text-xs text-text-secondary\">Active courses</p>\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\">Enrolled</CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{totalEnrolled}</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 <GraduationCap className=\"h-4 w-4 text-green-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{totalCompleted}</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\">Paths</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{learningPaths.length}</div>\n </CardContent>\n </Card>\n </div>\n <div>\n <h2 className=\"text-lg font-medium mb-3\">Featured Courses</h2>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {courses.slice(0, 3).map((course) => (\n <Card key={course.id}>\n <CardHeader>\n <CardTitle className=\"text-base\">{course.title}</CardTitle>\n <CardDescription>\n {course.instructor} · {course.duration}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-text-secondary mb-3\">{course.description}</p>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-yellow-500\" />\n <span className=\"text-sm\">{course.rating}</span>\n </div>\n <div className=\"flex gap-1\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {course.level}\n </Badge>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {course.category}\n </Badge>\n </div>\n </div>\n <div className=\"mt-2 text-xs text-text-secondary\">\n {course.enrolled} enrolled · {course.completed} completed\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n <div>\n <h2 className=\"text-lg font-medium mb-3\">Learning Paths</h2>\n <div className=\"grid gap-4 md:grid-cols-3\">\n {learningPaths.map((path) => (\n <Card key={path.id}>\n <CardHeader>\n <CardTitle className=\"text-base\">{path.title}</CardTitle>\n <CardDescription>{path.description}</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"flex items-center justify-between text-sm text-text-secondary\">\n <span>\n {path.courses.length} courses · {path.duration}\n </span>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {path.level}\n </Badge>\n </div>\n <div className=\"mt-2 space-y-1\">\n <div className=\"flex justify-between text-xs\">\n <span>{path.enrolled} enrolled</span>\n <span>{path.completionRate}%</span>\n </div>\n <div className=\"h-2 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-2 bg-action-primary-bg rounded\"\n style={{ width: `${path.completionRate}%` }}\n />\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ import { Badge as c, Button as l, Card as u, CardContent as d, CardDescription a
|
|
|
6
6
|
function h() {
|
|
7
7
|
let { learningPaths: h, courses: g } = e(), _ = h[0];
|
|
8
8
|
if (!_) return /* @__PURE__ */ o("div", {
|
|
9
|
-
className: "p-6 text-
|
|
9
|
+
className: "p-6 text-text-secondary",
|
|
10
10
|
children: "No learning path found."
|
|
11
11
|
});
|
|
12
12
|
let v = g.filter((e) => _.courses.includes(e.id));
|
|
@@ -19,7 +19,7 @@ function h() {
|
|
|
19
19
|
className: "text-2xl font-semibold",
|
|
20
20
|
children: _.title
|
|
21
21
|
}), /* @__PURE__ */ o("p", {
|
|
22
|
-
className: "text-sm text-
|
|
22
|
+
className: "text-sm text-text-secondary",
|
|
23
23
|
children: _.description
|
|
24
24
|
})] }), /* @__PURE__ */ o(l, { children: "Enroll Now" })]
|
|
25
25
|
}),
|
|
@@ -29,13 +29,13 @@ function h() {
|
|
|
29
29
|
/* @__PURE__ */ o(u, { children: /* @__PURE__ */ s(d, {
|
|
30
30
|
className: "p-4 text-center",
|
|
31
31
|
children: [
|
|
32
|
-
/* @__PURE__ */ o(t, { className: "h-5 w-5 mx-auto text-
|
|
32
|
+
/* @__PURE__ */ o(t, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
33
33
|
/* @__PURE__ */ o("p", {
|
|
34
34
|
className: "text-lg font-bold",
|
|
35
35
|
children: _.courses.length
|
|
36
36
|
}),
|
|
37
37
|
/* @__PURE__ */ o("p", {
|
|
38
|
-
className: "text-xs text-
|
|
38
|
+
className: "text-xs text-text-secondary",
|
|
39
39
|
children: "Courses"
|
|
40
40
|
})
|
|
41
41
|
]
|
|
@@ -43,13 +43,13 @@ function h() {
|
|
|
43
43
|
/* @__PURE__ */ o(u, { children: /* @__PURE__ */ s(d, {
|
|
44
44
|
className: "p-4 text-center",
|
|
45
45
|
children: [
|
|
46
|
-
/* @__PURE__ */ o(r, { className: "h-5 w-5 mx-auto text-
|
|
46
|
+
/* @__PURE__ */ o(r, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
47
47
|
/* @__PURE__ */ o("p", {
|
|
48
48
|
className: "text-lg font-bold",
|
|
49
49
|
children: _.duration
|
|
50
50
|
}),
|
|
51
51
|
/* @__PURE__ */ o("p", {
|
|
52
|
-
className: "text-xs text-
|
|
52
|
+
className: "text-xs text-text-secondary",
|
|
53
53
|
children: "Duration"
|
|
54
54
|
})
|
|
55
55
|
]
|
|
@@ -57,13 +57,13 @@ function h() {
|
|
|
57
57
|
/* @__PURE__ */ o(u, { children: /* @__PURE__ */ s(d, {
|
|
58
58
|
className: "p-4 text-center",
|
|
59
59
|
children: [
|
|
60
|
-
/* @__PURE__ */ o(a, { className: "h-5 w-5 mx-auto text-
|
|
60
|
+
/* @__PURE__ */ o(a, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
61
61
|
/* @__PURE__ */ o("p", {
|
|
62
62
|
className: "text-lg font-bold",
|
|
63
63
|
children: _.enrolled
|
|
64
64
|
}),
|
|
65
65
|
/* @__PURE__ */ o("p", {
|
|
66
|
-
className: "text-xs text-
|
|
66
|
+
className: "text-xs text-text-secondary",
|
|
67
67
|
children: "Enrolled"
|
|
68
68
|
})
|
|
69
69
|
]
|
|
@@ -77,7 +77,7 @@ function h() {
|
|
|
77
77
|
children: [_.completionRate, "%"]
|
|
78
78
|
}),
|
|
79
79
|
/* @__PURE__ */ o("p", {
|
|
80
|
-
className: "text-xs text-
|
|
80
|
+
className: "text-xs text-text-secondary",
|
|
81
81
|
children: "Completion"
|
|
82
82
|
})
|
|
83
83
|
]
|
|
@@ -94,7 +94,7 @@ function h() {
|
|
|
94
94
|
className: "flex items-center gap-3 rounded border p-4",
|
|
95
95
|
children: [
|
|
96
96
|
/* @__PURE__ */ o("div", {
|
|
97
|
-
className: "flex-shrink-0 w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center text-sm font-bold",
|
|
97
|
+
className: "flex-shrink-0 w-8 h-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-sm font-bold",
|
|
98
98
|
children: t + 1
|
|
99
99
|
}),
|
|
100
100
|
/* @__PURE__ */ s("div", {
|
|
@@ -103,7 +103,7 @@ function h() {
|
|
|
103
103
|
className: "text-sm font-medium",
|
|
104
104
|
children: e.title
|
|
105
105
|
}), /* @__PURE__ */ s("p", {
|
|
106
|
-
className: "text-xs text-
|
|
106
|
+
className: "text-xs text-text-secondary",
|
|
107
107
|
children: [
|
|
108
108
|
e.instructor,
|
|
109
109
|
" · ",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LearningLearningPathDetailPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningLearningPathDetailPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { BookOpen, CheckCircle, Clock, Star, Users } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function LearningLearningPathDetailPagePage() {\n const { learningPaths, courses } = useCrewFoundryStore();\n const path = learningPaths[0];\n if (!path) return <div className=\"p-6 text-
|
|
1
|
+
{"version":3,"file":"LearningLearningPathDetailPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningLearningPathDetailPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { BookOpen, CheckCircle, Clock, Star, Users } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function LearningLearningPathDetailPagePage() {\n const { learningPaths, courses } = useCrewFoundryStore();\n const path = learningPaths[0];\n if (!path) return <div className=\"p-6 text-text-secondary\">No learning path found.</div>;\n const pathCourses = courses.filter((c) => path.courses.includes(c.id));\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">{path.title}</h1>\n <p className=\"text-sm text-text-secondary\">{path.description}</p>\n </div>\n <Button>Enroll Now</Button>\n </div>\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardContent className=\"p-4 text-center\">\n <BookOpen className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{path.courses.length}</p>\n <p className=\"text-xs text-text-secondary\">Courses</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Clock className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{path.duration}</p>\n <p className=\"text-xs text-text-secondary\">Duration</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Users className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{path.enrolled}</p>\n <p className=\"text-xs text-text-secondary\">Enrolled</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <CheckCircle className=\"h-5 w-5 mx-auto text-green-500 mb-1\" />\n <p className=\"text-lg font-bold\">{path.completionRate}%</p>\n <p className=\"text-xs text-text-secondary\">Completion</p>\n </CardContent>\n </Card>\n </div>\n <Card>\n <CardHeader>\n <CardTitle>Courses in this Path</CardTitle>\n <CardDescription>\n {pathCourses.length} courses · {path.level}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {pathCourses.map((course, idx) => (\n <div key={course.id} className=\"flex items-center gap-3 rounded border p-4\">\n <div className=\"flex-shrink-0 w-8 h-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-sm font-bold\">\n {idx + 1}\n </div>\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium\">{course.title}</p>\n <p className=\"text-xs text-text-secondary\">\n {course.instructor} · {course.duration} · {course.modules} modules\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-yellow-500\" />\n <span className=\"text-sm\">{course.rating}</span>\n </div>\n <Badge\n variant={\n course.level === 'beginner'\n ? 'secondary'\n : course.level === 'intermediate'\n ? 'default'\n : 'destructive'\n }\n className=\"text-[10px]\"\n >\n {course.level}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ function d() {
|
|
|
11
11
|
className: "text-2xl font-semibold",
|
|
12
12
|
children: "Learning Paths"
|
|
13
13
|
}), /* @__PURE__ */ r("p", {
|
|
14
|
-
className: "text-sm text-
|
|
14
|
+
className: "text-sm text-text-secondary",
|
|
15
15
|
children: "Structured learning journeys for career growth"
|
|
16
16
|
})] }), /* @__PURE__ */ r("div", {
|
|
17
17
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
@@ -26,7 +26,7 @@ function d() {
|
|
|
26
26
|
className: "space-y-3",
|
|
27
27
|
children: [
|
|
28
28
|
/* @__PURE__ */ i("div", {
|
|
29
|
-
className: "flex items-center justify-between text-sm text-
|
|
29
|
+
className: "flex items-center justify-between text-sm text-text-secondary",
|
|
30
30
|
children: [/* @__PURE__ */ i("span", {
|
|
31
31
|
className: "flex items-center gap-1",
|
|
32
32
|
children: [
|
|
@@ -44,7 +44,7 @@ function d() {
|
|
|
44
44
|
/* @__PURE__ */ r("div", {
|
|
45
45
|
className: "space-y-1 mt-2",
|
|
46
46
|
children: d.map((e) => /* @__PURE__ */ i("div", {
|
|
47
|
-
className: "flex items-center gap-2 text-xs text-
|
|
47
|
+
className: "flex items-center gap-2 text-xs text-text-secondary",
|
|
48
48
|
children: [/* @__PURE__ */ r(n, { className: "h-3 w-3" }), e.title]
|
|
49
49
|
}, e.id))
|
|
50
50
|
}),
|
|
@@ -54,9 +54,9 @@ function d() {
|
|
|
54
54
|
className: "flex justify-between text-xs mb-1",
|
|
55
55
|
children: [/* @__PURE__ */ i("span", { children: [e.enrolled, " enrolled"] }), /* @__PURE__ */ i("span", { children: [e.completionRate, "%"] })]
|
|
56
56
|
}), /* @__PURE__ */ r("div", {
|
|
57
|
-
className: "h-2 bg-
|
|
57
|
+
className: "h-2 bg-bg-sunken rounded overflow-hidden",
|
|
58
58
|
children: /* @__PURE__ */ r("div", {
|
|
59
|
-
className: "h-2 bg-primary rounded",
|
|
59
|
+
className: "h-2 bg-action-primary-bg rounded",
|
|
60
60
|
style: { width: `${e.completionRate}%` }
|
|
61
61
|
})
|
|
62
62
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LearningLearningPathsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningLearningPathsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { BookOpen, GraduationCap, Users } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function LearningLearningPathsPagePage() {\n const { learningPaths, courses } = useCrewFoundryStore();\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Learning Paths</h1>\n <p className=\"text-sm text-
|
|
1
|
+
{"version":3,"file":"LearningLearningPathsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningLearningPathsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { BookOpen, GraduationCap, Users } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function LearningLearningPathsPagePage() {\n const { learningPaths, courses } = useCrewFoundryStore();\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Learning Paths</h1>\n <p className=\"text-sm text-text-secondary\">\n Structured learning journeys for career growth\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {learningPaths.map((path) => {\n const pathCourses = courses.filter((c) => path.courses.includes(c.id));\n return (\n <Card key={path.id} className=\"hover:shadow-md transition-shadow cursor-pointer\">\n <CardHeader>\n <CardTitle className=\"text-lg\">{path.title}</CardTitle>\n <CardDescription>{path.description}</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between text-sm text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <BookOpen className=\"h-3 w-3\" />\n {path.courses.length} courses\n </span>\n <span>{path.duration}</span>\n </div>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {path.level}\n </Badge>\n <div className=\"space-y-1 mt-2\">\n {pathCourses.map((c) => (\n <div\n key={c.id}\n className=\"flex items-center gap-2 text-xs text-text-secondary\"\n >\n <GraduationCap className=\"h-3 w-3\" />\n {c.title}\n </div>\n ))}\n </div>\n <div className=\"pt-2 border-t\">\n <div className=\"flex justify-between text-xs mb-1\">\n <span>{path.enrolled} enrolled</span>\n <span>{path.completionRate}%</span>\n </div>\n <div className=\"h-2 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-2 bg-action-primary-bg rounded\"\n style={{ width: `${path.completionRate}%` }}\n />\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n );\n })}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAWA,SAAgB,IAAgC;CAC9C,IAAM,EAAE,kBAAe,eAAY,GAAqB;AAExD,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;GAAI,WAAU;aAAyB;GAAmB,CAAA,EAC1D,kBAAC,KAAD;GAAG,WAAU;aAA8B;GAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAc,KAAK,MAAS;IAC3B,IAAM,IAAc,EAAQ,QAAQ,MAAM,EAAK,QAAQ,SAAS,EAAE,GAAG,CAAC;AACtE,WACE,kBAAC,GAAD;KAAoB,WAAU;eAA9B,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAW,WAAU;gBAAW,EAAK;MAAkB,CAAA,EACvD,kBAAC,GAAD,EAAA,UAAkB,EAAK,aAA8B,CAAA,CAC1C,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAhB;UACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;UAC/B,EAAK,QAAQ;UAAO;UAChB;YACP,kBAAC,QAAD,EAAA,UAAO,EAAK,UAAgB,CAAA,CACxB;;OACN,kBAAC,GAAD;QAAO,SAAQ;QAAU,WAAU;kBAChC,EAAK;QACA,CAAA;OACR,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAY,KAAK,MAChB,kBAAC,OAAD;SAEE,WAAU;mBAFZ,CAIE,kBAAC,GAAD,EAAe,WAAU,WAAY,CAAA,EACpC,EAAE,MACC;WALC,EAAE,GAKH,CACN;QACE,CAAA;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD,EAAA,UAAA,CAAO,EAAK,UAAS,YAAgB,EAAA,CAAA,EACrC,kBAAC,QAAD,EAAA,UAAA,CAAO,EAAK,gBAAe,IAAQ,EAAA,CAAA,CAC/B;YACN,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,OAAD;UACE,WAAU;UACV,OAAO,EAAE,OAAO,GAAG,EAAK,eAAe,IAAI;UAC3C,CAAA;SACE,CAAA,CACF;;OACF;SACM,CAAA,CACT;OA1CI,EAAK,GA0CT;KAET;GACE,CAAA,CACF"}
|
|
@@ -34,7 +34,7 @@ function v() {
|
|
|
34
34
|
className: "text-2xl font-semibold",
|
|
35
35
|
children: "My Learning"
|
|
36
36
|
}), /* @__PURE__ */ s("p", {
|
|
37
|
-
className: "text-sm text-
|
|
37
|
+
className: "text-sm text-text-secondary",
|
|
38
38
|
children: "Track your learning progress and achievements"
|
|
39
39
|
})] }),
|
|
40
40
|
/* @__PURE__ */ c("div", {
|
|
@@ -65,7 +65,7 @@ function v() {
|
|
|
65
65
|
children: [/* @__PURE__ */ s(h, {
|
|
66
66
|
className: "text-sm font-medium",
|
|
67
67
|
children: "Hours Logged"
|
|
68
|
-
}), /* @__PURE__ */ s(i, { className: "h-4 w-4 text-
|
|
68
|
+
}), /* @__PURE__ */ s(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
69
69
|
}), /* @__PURE__ */ s(f, { children: /* @__PURE__ */ s("div", {
|
|
70
70
|
className: "text-2xl font-bold",
|
|
71
71
|
children: x.toFixed(1)
|
|
@@ -94,7 +94,7 @@ function v() {
|
|
|
94
94
|
children: e.title
|
|
95
95
|
}),
|
|
96
96
|
/* @__PURE__ */ c("p", {
|
|
97
|
-
className: "text-xs text-
|
|
97
|
+
className: "text-xs text-text-secondary",
|
|
98
98
|
children: [
|
|
99
99
|
e.instructor,
|
|
100
100
|
" · Due ",
|
|
@@ -104,9 +104,9 @@ function v() {
|
|
|
104
104
|
/* @__PURE__ */ c("div", {
|
|
105
105
|
className: "mt-2 flex items-center gap-2",
|
|
106
106
|
children: [/* @__PURE__ */ s("div", {
|
|
107
|
-
className: "h-2 flex-1 overflow-hidden rounded bg-
|
|
107
|
+
className: "h-2 flex-1 overflow-hidden rounded bg-bg-sunken",
|
|
108
108
|
children: /* @__PURE__ */ s("div", {
|
|
109
|
-
className: "h-2 rounded bg-primary",
|
|
109
|
+
className: "h-2 rounded bg-action-primary-bg",
|
|
110
110
|
style: { width: `${e.progress}%` }
|
|
111
111
|
})
|
|
112
112
|
}), /* @__PURE__ */ c("span", {
|
|
@@ -115,7 +115,7 @@ function v() {
|
|
|
115
115
|
})]
|
|
116
116
|
}),
|
|
117
117
|
/* @__PURE__ */ c("p", {
|
|
118
|
-
className: "mt-1 text-xs text-
|
|
118
|
+
className: "mt-1 text-xs text-text-secondary",
|
|
119
119
|
children: [
|
|
120
120
|
e.completedModules,
|
|
121
121
|
"/",
|
|
@@ -138,7 +138,7 @@ function v() {
|
|
|
138
138
|
className: "text-sm font-medium",
|
|
139
139
|
children: e.title
|
|
140
140
|
}), /* @__PURE__ */ c("p", {
|
|
141
|
-
className: "text-xs text-
|
|
141
|
+
className: "text-xs text-text-secondary",
|
|
142
142
|
children: ["Completed ", e.completedDate]
|
|
143
143
|
})] }), /* @__PURE__ */ c("div", {
|
|
144
144
|
className: "flex items-center gap-2",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LearningMyLearningPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningMyLearningPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Award, BookOpen, Clock, Play, Star } from 'lucide-react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype EnrolledCourse = {\n id: string;\n title: string;\n progress: number;\n modules: number;\n completedModules: number;\n instructor: string;\n dueDate: string;\n};\n\ntype CompletedCourse = {\n id: string;\n title: string;\n completedDate: string;\n rating: number;\n certificate: boolean;\n};\n\nconst BASE_TS = new Date('2026-03-01T00:00:00Z').getTime();\n\nconst isoDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function LearningMyLearningPagePage() {\n const { courses } = useCrewFoundryStore();\n\n const myEnrolledCourses = useMemo<EnrolledCourse[]>(() => {\n return courses\n .filter((course) => course.status === 'active')\n .slice(0, 8)\n .map((course, index) => {\n const completedModules = Math.min(\n course.modules,\n Math.round((course.completed / Math.max(course.enrolled, 1)) * course.modules)\n );\n const progress = Math.round((completedModules / Math.max(course.modules, 1)) * 100);\n return {\n id: course.id,\n title: course.title,\n progress,\n modules: course.modules,\n completedModules,\n instructor: course.instructor,\n dueDate: isoDate(new Date(BASE_TS + (index + 1) * 86400000 * 12).toISOString()),\n };\n });\n }, [courses]);\n\n const completedCourses = useMemo<CompletedCourse[]>(() => {\n return courses\n .filter((course) => course.completed > 0)\n .slice(0, 8)\n .map((course, index) => ({\n id: `completed-${course.id}`,\n title: course.title,\n completedDate: isoDate(new Date(BASE_TS - (index + 1) * 86400000 * 15).toISOString()),\n rating: Number(course.rating.toFixed(1)),\n certificate: course.completed / Math.max(course.enrolled, 1) > 0.35,\n }));\n }, [courses]);\n\n const hoursLogged = myEnrolledCourses.reduce(\n (sum, course) => sum + course.completedModules * 1.25,\n 0\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">My Learning</h1>\n <p className=\"text-sm text-muted-foreground\">\n Track your learning progress and achievements\n </p>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">In Progress</CardTitle>\n <BookOpen className=\"h-4 w-4 text-blue-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{myEnrolledCourses.length}</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 <Award className=\"h-4 w-4 text-green-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{completedCourses.length}</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\">Hours Logged</CardTitle>\n <Clock className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{hoursLogged.toFixed(1)}</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\">Certificates</CardTitle>\n <Award className=\"h-4 w-4 text-yellow-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {completedCourses.filter((course) => course.certificate).length}\n </div>\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>In Progress</CardTitle>\n <CardDescription>Continue where you left off</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {myEnrolledCourses.map((course) => (\n <div key={course.id} className=\"flex items-center gap-4 rounded border p-4\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium\">{course.title}</p>\n <p className=\"text-xs text-muted-foreground\">\n {course.instructor} · Due {course.dueDate}\n </p>\n <div className=\"mt-2 flex items-center gap-2\">\n <div className=\"h-2 flex-1 overflow-hidden rounded bg-muted\">\n <div\n className=\"h-2 rounded bg-primary\"\n style={{ width: `${course.progress}%` }}\n />\n </div>\n <span className=\"text-xs font-medium\">{course.progress}%</span>\n </div>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {course.completedModules}/{course.modules} modules\n </p>\n </div>\n <Button size=\"sm\">\n <Play className=\"mr-1 h-3 w-3\" />\n Continue\n </Button>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Completed</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {completedCourses.map((course) => (\n <div key={course.id} className=\"flex items-center justify-between rounded border p-3\">\n <div>\n <p className=\"text-sm font-medium\">{course.title}</p>\n <p className=\"text-xs text-muted-foreground\">Completed {course.completedDate}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-yellow-500\" />\n {course.rating}/5\n </div>\n {course.certificate ? (\n <Badge variant=\"default\" className=\"text-[10px]\">\n Certificate\n </Badge>\n ) : null}\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LearningMyLearningPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningMyLearningPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Award, BookOpen, Clock, Play, Star } from 'lucide-react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype EnrolledCourse = {\n id: string;\n title: string;\n progress: number;\n modules: number;\n completedModules: number;\n instructor: string;\n dueDate: string;\n};\n\ntype CompletedCourse = {\n id: string;\n title: string;\n completedDate: string;\n rating: number;\n certificate: boolean;\n};\n\nconst BASE_TS = new Date('2026-03-01T00:00:00Z').getTime();\n\nconst isoDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function LearningMyLearningPagePage() {\n const { courses } = useCrewFoundryStore();\n\n const myEnrolledCourses = useMemo<EnrolledCourse[]>(() => {\n return courses\n .filter((course) => course.status === 'active')\n .slice(0, 8)\n .map((course, index) => {\n const completedModules = Math.min(\n course.modules,\n Math.round((course.completed / Math.max(course.enrolled, 1)) * course.modules)\n );\n const progress = Math.round((completedModules / Math.max(course.modules, 1)) * 100);\n return {\n id: course.id,\n title: course.title,\n progress,\n modules: course.modules,\n completedModules,\n instructor: course.instructor,\n dueDate: isoDate(new Date(BASE_TS + (index + 1) * 86400000 * 12).toISOString()),\n };\n });\n }, [courses]);\n\n const completedCourses = useMemo<CompletedCourse[]>(() => {\n return courses\n .filter((course) => course.completed > 0)\n .slice(0, 8)\n .map((course, index) => ({\n id: `completed-${course.id}`,\n title: course.title,\n completedDate: isoDate(new Date(BASE_TS - (index + 1) * 86400000 * 15).toISOString()),\n rating: Number(course.rating.toFixed(1)),\n certificate: course.completed / Math.max(course.enrolled, 1) > 0.35,\n }));\n }, [courses]);\n\n const hoursLogged = myEnrolledCourses.reduce(\n (sum, course) => sum + course.completedModules * 1.25,\n 0\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">My Learning</h1>\n <p className=\"text-sm text-text-secondary\">\n Track your learning progress and achievements\n </p>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">In Progress</CardTitle>\n <BookOpen className=\"h-4 w-4 text-blue-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{myEnrolledCourses.length}</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 <Award className=\"h-4 w-4 text-green-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{completedCourses.length}</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\">Hours Logged</CardTitle>\n <Clock className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{hoursLogged.toFixed(1)}</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\">Certificates</CardTitle>\n <Award className=\"h-4 w-4 text-yellow-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {completedCourses.filter((course) => course.certificate).length}\n </div>\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>In Progress</CardTitle>\n <CardDescription>Continue where you left off</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {myEnrolledCourses.map((course) => (\n <div key={course.id} className=\"flex items-center gap-4 rounded border p-4\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium\">{course.title}</p>\n <p className=\"text-xs text-text-secondary\">\n {course.instructor} · Due {course.dueDate}\n </p>\n <div className=\"mt-2 flex items-center gap-2\">\n <div className=\"h-2 flex-1 overflow-hidden rounded bg-bg-sunken\">\n <div\n className=\"h-2 rounded bg-action-primary-bg\"\n style={{ width: `${course.progress}%` }}\n />\n </div>\n <span className=\"text-xs font-medium\">{course.progress}%</span>\n </div>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {course.completedModules}/{course.modules} modules\n </p>\n </div>\n <Button size=\"sm\">\n <Play className=\"mr-1 h-3 w-3\" />\n Continue\n </Button>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Completed</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {completedCourses.map((course) => (\n <div key={course.id} className=\"flex items-center justify-between rounded border p-3\">\n <div>\n <p className=\"text-sm font-medium\">{course.title}</p>\n <p className=\"text-xs text-text-secondary\">Completed {course.completedDate}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-yellow-500\" />\n {course.rating}/5\n </div>\n {course.certificate ? (\n <Badge variant=\"default\" className=\"text-[10px]\">\n Certificate\n </Badge>\n ) : null}\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":";;;;;;AA+BA,IAAM,qBAAU,IAAI,KAAK,uBAAuB,EAAC,SAAS,EAEpD,KAAW,MAA0B;CACzC,IAAM,IAAS,IAAI,KAAK,EAAM;AAI9B,QAHI,OAAO,MAAM,EAAO,SAAS,CAAC,GACzB,YAEF,EAAO,aAAa,CAAC,MAAM,IAAI,CAAC;;AAGzC,SAAgB,IAA6B;CAC3C,IAAM,EAAE,eAAY,GAAqB,EAEnC,IAAoB,QACjB,EACJ,QAAQ,MAAW,EAAO,WAAW,SAAS,CAC9C,MAAM,GAAG,EAAE,CACX,KAAK,GAAQ,MAAU;EACtB,IAAM,IAAmB,KAAK,IAC5B,EAAO,SACP,KAAK,MAAO,EAAO,YAAY,KAAK,IAAI,EAAO,UAAU,EAAE,GAAI,EAAO,QAAQ,CAC/E,EACK,IAAW,KAAK,MAAO,IAAmB,KAAK,IAAI,EAAO,SAAS,EAAE,GAAI,IAAI;AACnF,SAAO;GACL,IAAI,EAAO;GACX,OAAO,EAAO;GACd;GACA,SAAS,EAAO;GAChB;GACA,YAAY,EAAO;GACnB,SAAS,EAAQ,IAAI,KAAK,KAAW,IAAQ,KAAK,QAAW,GAAG,CAAC,aAAa,CAAC;GAChF;GACD,EACH,CAAC,EAAQ,CAAC,EAEP,IAAmB,QAChB,EACJ,QAAQ,MAAW,EAAO,YAAY,EAAE,CACxC,MAAM,GAAG,EAAE,CACX,KAAK,GAAQ,OAAW;EACvB,IAAI,aAAa,EAAO;EACxB,OAAO,EAAO;EACd,eAAe,mBAAQ,IAAI,KAAK,KAAW,IAAQ,KAAK,QAAW,GAAG,EAAC,aAAa,CAAC;EACrF,QAAQ,OAAO,EAAO,OAAO,QAAQ,EAAE,CAAC;EACxC,aAAa,EAAO,YAAY,KAAK,IAAI,EAAO,UAAU,EAAE,GAAG;EAChE,EAAE,EACJ,CAAC,EAAQ,CAAC,EAEP,IAAc,EAAkB,QACnC,GAAK,MAAW,IAAM,EAAO,mBAAmB,MACjD,EACD;AAED,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;cAAyB;IAAgB,CAAA,EACvD,kBAAC,KAAD;IAAG,WAAU;cAA8B;IAEvC,CAAA,CACA,EAAA,CAAA;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAY,WAAU;gBAAtB,CACE,kBAAC,GAAD;OAAW,WAAU;iBAAsB;OAAuB,CAAA,EAClE,kBAAC,GAAD,EAAU,WAAU,yBAA0B,CAAA,CACnC;SACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBAAsB,EAAkB;MAAa,CAAA,EACxD,CAAA,CACT,EAAA,CAAA;KACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAY,WAAU;gBAAtB,CACE,kBAAC,GAAD;OAAW,WAAU;iBAAsB;OAAqB,CAAA,EAChE,kBAAC,GAAD,EAAO,WAAU,0BAA2B,CAAA,CACjC;SACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBAAsB,EAAiB;MAAa,CAAA,EACvD,CAAA,CACT,EAAA,CAAA;KACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAY,WAAU;gBAAtB,CACE,kBAAC,GAAD;OAAW,WAAU;iBAAsB;OAAwB,CAAA,EACnE,kBAAC,GAAD,EAAO,WAAU,+BAAgC,CAAA,CACtC;SACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBAAsB,EAAY,QAAQ,EAAE;MAAO,CAAA,EACtD,CAAA,CACT,EAAA,CAAA;KACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAY,WAAU;gBAAtB,CACE,kBAAC,GAAD;OAAW,WAAU;iBAAsB;OAAwB,CAAA,EACnE,kBAAC,GAAD,EAAO,WAAU,2BAA4B,CAAA,CAClC;SACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAiB,QAAQ,MAAW,EAAO,YAAY,CAAC;MACrD,CAAA,EACM,CAAA,CACT,EAAA,CAAA;KACH;;GAEN,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAW,eAAuB,CAAA,EAClC,kBAAC,GAAD,EAAA,UAAiB,+BAA6C,CAAA,CACnD,EAAA,CAAA,EACb,kBAAC,GAAD;IAAa,WAAU;cACpB,EAAkB,KAAK,MACtB,kBAAC,OAAD;KAAqB,WAAU;eAA/B,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,KAAD;QAAG,WAAU;kBAAuB,EAAO;QAAU,CAAA;OACrD,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG,EAAO;SAAW;SAAQ,EAAO;SAChC;;OACJ,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,OAAD;UACE,WAAU;UACV,OAAO,EAAE,OAAO,GAAG,EAAO,SAAS,IAAI;UACvC,CAAA;SACE,CAAA,EACN,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CAAuC,EAAO,UAAS,IAAQ;WAC3D;;OACN,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG,EAAO;SAAiB;SAAE,EAAO;SAAQ;SACxC;;OACA;SACN,kBAAC,GAAD;MAAQ,MAAK;gBAAb,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAAA,WAE1B;QACL;OAvBI,EAAO,GAuBX,CACN;IACU,CAAA,CACT,EAAA,CAAA;GAEP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,aAAqB,CAAA,EACrB,CAAA,EACb,kBAAC,GAAD;IAAa,WAAU;cACpB,EAAiB,KAAK,MACrB,kBAAC,OAAD;KAAqB,WAAU;eAA/B,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAuB,EAAO;MAAU,CAAA,EACrD,kBAAC,KAAD;MAAG,WAAU;gBAAb,CAA2C,cAAW,EAAO,cAAkB;QAC3E,EAAA,CAAA,EACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAM,WAAU,2BAA4B,CAAA;QAC3C,EAAO;QAAO;QACX;UACL,EAAO,cACN,kBAAC,GAAD;OAAO,SAAQ;OAAU,WAAU;iBAAc;OAEzC,CAAA,GACN,KACA;QACF;OAhBI,EAAO,GAgBX,CACN;IACU,CAAA,CACT,EAAA,CAAA;GACH"}
|
|
@@ -34,7 +34,7 @@ function h() {
|
|
|
34
34
|
className: "text-2xl font-semibold",
|
|
35
35
|
children: "Booking Management"
|
|
36
36
|
}), /* @__PURE__ */ o("p", {
|
|
37
|
-
className: "text-sm text-
|
|
37
|
+
className: "text-sm text-text-secondary",
|
|
38
38
|
children: "Manage service provider appointments"
|
|
39
39
|
})] }), /* @__PURE__ */ s(l, {
|
|
40
40
|
size: "sm",
|
|
@@ -84,7 +84,7 @@ function h() {
|
|
|
84
84
|
className: "text-sm font-medium",
|
|
85
85
|
children: e.service
|
|
86
86
|
}), /* @__PURE__ */ o("p", {
|
|
87
|
-
className: "text-xs text-
|
|
87
|
+
className: "text-xs text-text-secondary",
|
|
88
88
|
children: e.provider
|
|
89
89
|
})] }), /* @__PURE__ */ s("div", {
|
|
90
90
|
className: "flex items-center gap-3",
|
|
@@ -94,7 +94,7 @@ function h() {
|
|
|
94
94
|
className: "font-medium",
|
|
95
95
|
children: e.date
|
|
96
96
|
}), /* @__PURE__ */ s("p", {
|
|
97
|
-
className: "text-
|
|
97
|
+
className: "text-text-secondary",
|
|
98
98
|
children: [
|
|
99
99
|
e.time,
|
|
100
100
|
" · ",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarketplaceBookingManagementPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceBookingManagementPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Badge, Button, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Calendar, CheckCircle, Clock, Plus } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype Booking = {\n id: string;\n service: string;\n provider: string;\n date: string;\n time: string;\n duration: string;\n status: 'confirmed' | 'pending' | 'completed';\n};\n\nconst formatDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function MarketplaceBookingManagementPagePage() {\n const { marketplaceServices, projects, teams } = useCrewFoundryStore();\n\n const bookings = useMemo<Booking[]>(() => {\n return marketplaceServices.slice(0, 12).map((service, index) => {\n const project = projects[index % Math.max(projects.length, 1)];\n const team = teams[index % Math.max(teams.length, 1)];\n const status: Booking['status'] =\n service.status === 'active'\n ? 'confirmed'\n : service.status === 'pending'\n ? 'pending'\n : 'completed';\n\n return {\n id: service.id,\n service: service.title,\n provider: service.provider,\n date: formatDate(project?.startDate || service.deliveryTime),\n time: `${String((index % 12) + 1).padStart(2, '0')}:00 ${index % 2 === 0 ? 'AM' : 'PM'}`,\n duration: `${Math.max(1, Math.ceil((team?.memberCount || 4) / 4))} hours`,\n status,\n };\n });\n }, [marketplaceServices, projects, teams]);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Booking Management</h1>\n <p className=\"text-sm text-
|
|
1
|
+
{"version":3,"file":"MarketplaceBookingManagementPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceBookingManagementPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Badge, Button, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Calendar, CheckCircle, Clock, Plus } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype Booking = {\n id: string;\n service: string;\n provider: string;\n date: string;\n time: string;\n duration: string;\n status: 'confirmed' | 'pending' | 'completed';\n};\n\nconst formatDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function MarketplaceBookingManagementPagePage() {\n const { marketplaceServices, projects, teams } = useCrewFoundryStore();\n\n const bookings = useMemo<Booking[]>(() => {\n return marketplaceServices.slice(0, 12).map((service, index) => {\n const project = projects[index % Math.max(projects.length, 1)];\n const team = teams[index % Math.max(teams.length, 1)];\n const status: Booking['status'] =\n service.status === 'active'\n ? 'confirmed'\n : service.status === 'pending'\n ? 'pending'\n : 'completed';\n\n return {\n id: service.id,\n service: service.title,\n provider: service.provider,\n date: formatDate(project?.startDate || service.deliveryTime),\n time: `${String((index % 12) + 1).padStart(2, '0')}:00 ${index % 2 === 0 ? 'AM' : 'PM'}`,\n duration: `${Math.max(1, Math.ceil((team?.memberCount || 4) / 4))} hours`,\n status,\n };\n });\n }, [marketplaceServices, projects, teams]);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Booking Management</h1>\n <p className=\"text-sm text-text-secondary\">Manage service provider appointments</p>\n </div>\n <Button size=\"sm\">\n <Plus className=\"mr-1 h-4 w-4\" />\n New Booking\n </Button>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Upcoming</CardTitle>\n <Calendar className=\"h-4 w-4 text-blue-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {bookings.filter((booking) => booking.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\">Confirmed</CardTitle>\n <CheckCircle className=\"h-4 w-4 text-green-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {bookings.filter((booking) => booking.status === 'confirmed').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\">Pending</CardTitle>\n <Clock className=\"h-4 w-4 text-yellow-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {bookings.filter((booking) => booking.status === 'pending').length}\n </div>\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>All Bookings</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {bookings.map((booking) => (\n <div key={booking.id} className=\"flex items-center justify-between rounded border p-4\">\n <div>\n <p className=\"text-sm font-medium\">{booking.service}</p>\n <p className=\"text-xs text-text-secondary\">{booking.provider}</p>\n </div>\n <div className=\"flex items-center gap-3\">\n <div className=\"text-right text-xs\">\n <p className=\"font-medium\">{booking.date}</p>\n <p className=\"text-text-secondary\">\n {booking.time} · {booking.duration}\n </p>\n </div>\n <Badge\n variant={\n booking.status === 'confirmed'\n ? 'default'\n : booking.status === 'completed'\n ? 'secondary'\n : 'outline'\n }\n className=\"text-[10px]\"\n >\n {booking.status}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":";;;;;;AAeA,IAAM,KAAc,MAA0B;CAC5C,IAAM,IAAS,IAAI,KAAK,EAAM;AAI9B,QAHI,OAAO,MAAM,EAAO,SAAS,CAAC,GACzB,YAEF,EAAO,aAAa,CAAC,MAAM,IAAI,CAAC;;AAGzC,SAAgB,IAAuC;CACrD,IAAM,EAAE,wBAAqB,aAAU,aAAU,GAAqB,EAEhE,IAAW,QACR,EAAoB,MAAM,GAAG,GAAG,CAAC,KAAK,GAAS,MAAU;EAC9D,IAAM,IAAU,EAAS,IAAQ,KAAK,IAAI,EAAS,QAAQ,EAAE,GACvD,IAAO,EAAM,IAAQ,KAAK,IAAI,EAAM,QAAQ,EAAE,GAC9C,IACJ,EAAQ,WAAW,WACf,cACA,EAAQ,WAAW,YACjB,YACA;AAER,SAAO;GACL,IAAI,EAAQ;GACZ,SAAS,EAAQ;GACjB,UAAU,EAAQ;GAClB,MAAM,EAAW,GAAS,aAAa,EAAQ,aAAa;GAC5D,MAAM,GAAG,OAAQ,IAAQ,KAAM,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,IAAQ,KAAM,IAAI,OAAO;GAClF,UAAU,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,GAAM,eAAe,KAAK,EAAE,CAAC,CAAC;GAClE;GACD;GACD,EACD;EAAC;EAAqB;EAAU;EAAM,CAAC;AAE1C,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eAAyB;KAAuB,CAAA,EAC9D,kBAAC,KAAD;KAAG,WAAU;eAA8B;KAAwC,CAAA,CAC/E,EAAA,CAAA,EACN,kBAAC,GAAD;KAAQ,MAAK;eAAb,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAAA,cAE1B;OACL;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAY,WAAU;gBAAtB,CACE,kBAAC,GAAD;OAAW,WAAU;iBAAsB;OAAoB,CAAA,EAC/D,kBAAC,GAAD,EAAU,WAAU,yBAA0B,CAAA,CACnC;SACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAS,QAAQ,MAAY,EAAQ,WAAW,YAAY,CAAC;MAC1D,CAAA,EACM,CAAA,CACT,EAAA,CAAA;KACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAY,WAAU;gBAAtB,CACE,kBAAC,GAAD;OAAW,WAAU;iBAAsB;OAAqB,CAAA,EAChE,kBAAC,GAAD,EAAa,WAAU,0BAA2B,CAAA,CACvC;SACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAS,QAAQ,MAAY,EAAQ,WAAW,YAAY,CAAC;MAC1D,CAAA,EACM,CAAA,CACT,EAAA,CAAA;KACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAY,WAAU;gBAAtB,CACE,kBAAC,GAAD;OAAW,WAAU;iBAAsB;OAAmB,CAAA,EAC9D,kBAAC,GAAD,EAAO,WAAU,2BAA4B,CAAA,CAClC;SACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAS,QAAQ,MAAY,EAAQ,WAAW,UAAU,CAAC;MACxD,CAAA,EACM,CAAA,CACT,EAAA,CAAA;KACH;;GAEN,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,gBAAwB,CAAA,EACxB,CAAA,EACb,kBAAC,GAAD;IAAa,WAAU;cACpB,EAAS,KAAK,MACb,kBAAC,OAAD;KAAsB,WAAU;eAAhC,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAuB,EAAQ;MAAY,CAAA,EACxD,kBAAC,KAAD;MAAG,WAAU;gBAA+B,EAAQ;MAAa,CAAA,CAC7D,EAAA,CAAA,EACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAe,EAAQ;QAAS,CAAA,EAC7C,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG,EAAQ;SAAK;SAAI,EAAQ;SACxB;UACA;UACN,kBAAC,GAAD;OACE,SACE,EAAQ,WAAW,cACf,YACA,EAAQ,WAAW,cACjB,cACA;OAER,WAAU;iBAET,EAAQ;OACH,CAAA,CACJ;QACF;OAzBI,EAAQ,GAyBZ,CACN;IACU,CAAA,CACT,EAAA,CAAA;GACH"}
|