@learnmd/default-theme 0.0.1-beta.0 → 0.0.2-beta.0
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/components/CatalogViewer.d.ts +3 -1
- package/dist/components/CatalogViewer.d.ts.map +1 -1
- package/dist/components/CatalogViewer.js +18 -3
- package/dist/components/CatalogViewer.js.map +1 -1
- package/dist/components/CourseOverview.d.ts +11 -0
- package/dist/components/CourseOverview.d.ts.map +1 -0
- package/dist/components/CourseOverview.js +21 -0
- package/dist/components/CourseOverview.js.map +1 -0
- package/dist/components/CourseViewer.d.ts +3 -1
- package/dist/components/CourseViewer.d.ts.map +1 -1
- package/dist/components/CourseViewer.js +89 -17
- package/dist/components/CourseViewer.js.map +1 -1
- package/dist/components/ProfileViewer.d.ts.map +1 -1
- package/dist/components/ProfileViewer.js +22 -6
- package/dist/components/ProfileViewer.js.map +1 -1
- package/dist/components/Quiz.d.ts +3 -1
- package/dist/components/Quiz.d.ts.map +1 -1
- package/dist/components/Quiz.js +5 -3
- package/dist/components/Quiz.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/layouts/CourseLayout.d.ts.map +1 -1
- package/dist/layouts/CourseLayout.js +2 -11
- package/dist/layouts/CourseLayout.js.map +1 -1
- package/dist/layouts/MainLayout.d.ts +5 -1
- package/dist/layouts/MainLayout.d.ts.map +1 -1
- package/dist/layouts/MainLayout.js +19 -3
- package/dist/layouts/MainLayout.js.map +1 -1
- package/dist/styles/output.css +143 -55
- package/package.json +5 -4
- package/dist/components/Callout.test.d.ts +0 -2
- package/dist/components/Callout.test.d.ts.map +0 -1
- package/dist/components/Callout.test.js +0 -24
- package/dist/components/Callout.test.js.map +0 -1
- package/dist/components/Quiz.test.d.ts +0 -2
- package/dist/components/Quiz.test.d.ts.map +0 -1
- package/dist/components/Quiz.test.js +0 -48
- package/dist/components/Quiz.test.js.map +0 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
export interface CatalogViewerProps {
|
|
2
3
|
courses: Array<{
|
|
3
4
|
courseSlug: string;
|
|
4
5
|
slug: string;
|
|
5
6
|
frontmatter: Record<string, unknown>;
|
|
6
7
|
}>;
|
|
8
|
+
HomeComponent?: React.ComponentType;
|
|
7
9
|
}
|
|
8
|
-
export declare function CatalogViewer({ courses }: CatalogViewerProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function CatalogViewer({ courses, HomeComponent }: CatalogViewerProps): import("react/jsx-runtime").JSX.Element;
|
|
9
11
|
//# sourceMappingURL=CatalogViewer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogViewer.d.ts","sourceRoot":"","sources":["../../src/components/CatalogViewer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CatalogViewer.d.ts","sourceRoot":"","sources":["../../src/components/CatalogViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAqB1B,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC3F,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CACrC;AAED,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE,kBAAkB,2CAiE3E"}
|
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { MainLayout, Header } from '../layouts/MainLayout';
|
|
3
3
|
import { Link } from 'react-router-dom';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
import { MDXProvider } from '@mdx-js/react';
|
|
6
|
+
import { Callout } from './Callout';
|
|
7
|
+
import { Quiz } from './Quiz';
|
|
8
|
+
import { VideoEmbed } from './VideoEmbed';
|
|
9
|
+
import { Progress } from './Progress';
|
|
10
|
+
import { LanguageSwitcher } from './LanguageSwitcher';
|
|
11
|
+
import { Paragraph } from './Paragraph';
|
|
12
|
+
const components = {
|
|
13
|
+
Callout,
|
|
14
|
+
Quiz,
|
|
15
|
+
VideoEmbed,
|
|
16
|
+
Progress,
|
|
17
|
+
LanguageSwitcher,
|
|
18
|
+
Paragraph,
|
|
19
|
+
};
|
|
20
|
+
export function CatalogViewer({ courses, HomeComponent }) {
|
|
6
21
|
// Group lessons by courseSlug
|
|
7
22
|
const courseMap = new Map();
|
|
8
23
|
courses.forEach(lesson => {
|
|
@@ -19,6 +34,6 @@ export function CatalogViewer({ courses }) {
|
|
|
19
34
|
}
|
|
20
35
|
});
|
|
21
36
|
const uniqueCourses = Array.from(courseMap.values());
|
|
22
|
-
return (_jsxs(MainLayout, { children: [_jsx(Header, { title: "Course Catalog",
|
|
37
|
+
return (_jsxs(MainLayout, { children: [_jsx(Header, { title: "Course Catalog" }), _jsxs("div", { className: "container mx-auto px-4 py-8 max-w-5xl", children: [HomeComponent && (_jsx("div", { className: "prose dark:prose-invert max-w-none mb-12", children: _jsx(MDXProvider, { components: components, children: _jsx(HomeComponent, {}) }) })), _jsx("h1", { className: "text-3xl font-bold mb-8 text-[rgb(var(--text-primary))]", children: "Available Courses" }), "...", uniqueCourses.length === 0 ? (_jsx("div", { className: "text-center py-12 text-gray-500", children: "No courses available yet. Add some courses in the 'courses/' folder!" })) : (_jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: uniqueCourses.map(course => (_jsxs(Link, { to: `/courses/${course.id}`, className: "block p-6 bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 hover:shadow-md hover:border-emerald-500 transition-all group", children: [_jsx("h2", { className: "text-xl font-semibold mb-2 group-hover:text-emerald-500 transition-colors", children: course.title }), _jsxs("p", { className: "text-sm text-gray-500 dark:text-gray-400 mb-4", children: [course.totalLessons, " lessons inside"] }), _jsxs("div", { className: "text-emerald-600 dark:text-emerald-400 text-sm font-medium flex items-center", children: ["Start Course", _jsx("svg", { className: "w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })] })] }, course.id))) }))] })] }));
|
|
23
38
|
}
|
|
24
39
|
//# sourceMappingURL=CatalogViewer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogViewer.js","sourceRoot":"","sources":["../../src/components/CatalogViewer.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"CatalogViewer.js","sourceRoot":"","sources":["../../src/components/CatalogViewer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Course } from '@learnmd/core';
|
|
3
|
+
export interface CourseOverviewProps {
|
|
4
|
+
course: Course;
|
|
5
|
+
overviewContent?: React.ReactNode;
|
|
6
|
+
onStartCourse?: () => void;
|
|
7
|
+
completedLessons?: string[];
|
|
8
|
+
courseProgress?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function CourseOverview({ course, overviewContent, onStartCourse, completedLessons, courseProgress }: CourseOverviewProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=CourseOverview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CourseOverview.d.ts","sourceRoot":"","sources":["../../src/components/CourseOverview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAK5C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAqB,EAAE,cAAkB,EAAE,EAAE,mBAAmB,2CA6GxI"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useI18n } from '../hooks';
|
|
3
|
+
import { Link } from 'react-router-dom';
|
|
4
|
+
export function CourseOverview({ course, overviewContent, onStartCourse, completedLessons = [], courseProgress = 0 }) {
|
|
5
|
+
const { currentLanguage } = useI18n();
|
|
6
|
+
const title = typeof course.title === 'string'
|
|
7
|
+
? course.title
|
|
8
|
+
: course.title[currentLanguage] || Object.values(course.title)[0];
|
|
9
|
+
const description = course.description
|
|
10
|
+
? (typeof course.description === 'string' ? course.description : course.description[currentLanguage] || Object.values(course.description)[0])
|
|
11
|
+
: null;
|
|
12
|
+
return (_jsxs("div", { className: "course-overview container mx-auto px-4 py-8 max-w-5xl", children: [_jsxs("header", { className: "mb-8 border-b border-[rgb(var(--border-color))] pb-8", children: [_jsx("h1", { className: "text-4xl font-bold mb-4 text-[rgb(var(--text-primary))]", children: title }), description && (_jsx("p", { className: "text-xl text-[rgb(var(--text-secondary))] mb-6", children: description })), _jsxs("div", { className: "flex flex-wrap gap-4 text-sm mb-6", children: [course.difficulty && (_jsxs("span", { className: "px-3 py-1 bg-[rgb(var(--bg-tertiary))] text-[rgb(var(--text-primary))] rounded-full", children: ["Difficulty: ", _jsx("span", { className: "font-semibold capitalize", children: course.difficulty })] })), course.estimatedTime && (_jsxs("span", { className: "px-3 py-1 bg-[rgb(var(--bg-tertiary))] text-[rgb(var(--text-primary))] rounded-full", children: ["Time: ", _jsx("span", { className: "font-semibold", children: course.estimatedTime })] }))] }), onStartCourse && (_jsx("button", { onClick: onStartCourse, className: "px-6 py-3 bg-[rgb(var(--color-primary-500))] hover:bg-[rgb(var(--color-primary-600))] text-white font-bold rounded-lg transition-colors shadow-sm", children: completedLessons.length > 0 ? (completedLessons.length >= (course.lessons?.length || 0) ? 'Review Course' : 'Continue Course') : 'Start Course' }))] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-8", children: [_jsxs("div", { className: "md:col-span-2", children: [overviewContent && (_jsx("div", { className: "prose dark:prose-invert max-w-none mb-8 text-[rgb(var(--text-primary))]", children: overviewContent })), _jsx("h2", { className: "text-2xl font-bold mb-4 text-[rgb(var(--text-primary))]", children: "Syllabus" }), _jsx("div", { className: "space-y-4", children: course.lessons && course.lessons.length > 0 ? (course.lessons.map((lesson, idx) => {
|
|
13
|
+
const lessonTitle = typeof lesson === 'string'
|
|
14
|
+
? lesson
|
|
15
|
+
: (typeof lesson.frontmatter.title === 'string' ? lesson.frontmatter.title : 'Lesson');
|
|
16
|
+
const slug = typeof lesson === 'string' ? lesson : lesson.slug;
|
|
17
|
+
const isCompleted = completedLessons.includes(slug);
|
|
18
|
+
return (_jsxs("div", { className: "p-4 border border-[rgb(var(--border-color))] rounded-lg hover:border-[rgb(var(--color-primary-500))] transition-colors bg-[rgb(var(--bg-secondary))] flex justify-between items-center", children: [_jsxs(Link, { to: `${course.basePath}/${slug}`, className: "text-lg font-medium text-[rgb(var(--text-primary))] hover:text-[rgb(var(--color-primary-500))] transition-colors block", children: [_jsxs("span", { className: "text-[rgb(var(--text-secondary))] mr-2", children: [idx + 1, "."] }), " ", lessonTitle] }), isCompleted && (_jsxs("span", { className: "text-sm text-emerald-500 font-semibold flex items-center gap-1", children: [_jsx("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z", clipRule: "evenodd" }) }), " Completed"] }))] }, idx));
|
|
19
|
+
})) : (_jsx("p", { className: "text-[rgb(var(--text-secondary))]", children: "No lessons available yet." })) })] }), _jsxs("div", { className: "md:col-span-1 space-y-6", children: [course.prerequisites && course.prerequisites.length > 0 && (_jsxs("div", { className: "bg-[rgb(var(--bg-secondary))] p-6 rounded-lg border border-[rgb(var(--border-color))]", children: [_jsx("h3", { className: "font-bold mb-3 text-[rgb(var(--text-primary))]", children: "Prerequisites" }), _jsx("ul", { className: "list-disc list-inside space-y-2 text-sm text-[rgb(var(--text-secondary))]", children: course.prerequisites.map((prereq, i) => (_jsx("li", { children: prereq }, i))) })] })), course.expectedSkills && course.expectedSkills.length > 0 && (_jsxs("div", { className: "bg-[rgb(var(--bg-secondary))] p-6 rounded-lg border border-[rgb(var(--border-color))]", children: [_jsx("h3", { className: "font-bold mb-3 text-[rgb(var(--text-primary))]", children: "What You'll Learn" }), _jsx("ul", { className: "list-disc list-inside space-y-2 text-sm text-[rgb(var(--text-secondary))]", children: course.expectedSkills.map((skill, i) => (_jsx("li", { children: skill }, i))) })] }))] })] })] }));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=CourseOverview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CourseOverview.js","sourceRoot":"","sources":["../../src/components/CourseOverview.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { Course } from '@learnmd/core';
|
|
2
3
|
export interface CourseViewerProps {
|
|
3
4
|
allLessons: Array<{
|
|
4
5
|
courseSlug: string;
|
|
@@ -6,6 +7,7 @@ export interface CourseViewerProps {
|
|
|
6
7
|
Component: React.ComponentType;
|
|
7
8
|
frontmatter: Record<string, unknown>;
|
|
8
9
|
}>;
|
|
10
|
+
coursesConfig?: Record<string, Course>;
|
|
9
11
|
}
|
|
10
|
-
export declare function CourseViewer({ allLessons }: CourseViewerProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export declare function CourseViewer({ allLessons, coursesConfig }: CourseViewerProps): import("react/jsx-runtime").JSX.Element;
|
|
11
13
|
//# sourceMappingURL=CourseViewer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CourseViewer.d.ts","sourceRoot":"","sources":["../../src/components/CourseViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"CourseViewer.d.ts","sourceRoot":"","sources":["../../src/components/CourseViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAW5D,OAAO,EAAuB,MAAM,EAAc,MAAM,eAAe,CAAC;AAKxE,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9H,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,wBAAgB,YAAY,CAAC,EAAE,UAAU,EAAE,aAAkB,EAAE,EAAE,iBAAiB,2CAgMjF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useEffect, useState } from 'react';
|
|
2
3
|
import { ThemeProvider } from '../hooks';
|
|
3
4
|
import { CourseLayout } from '../layouts';
|
|
4
5
|
// @ts-ignore
|
|
@@ -9,23 +10,55 @@ import { VideoEmbed } from './VideoEmbed';
|
|
|
9
10
|
import { Progress } from './Progress';
|
|
10
11
|
import { LanguageSwitcher } from './LanguageSwitcher';
|
|
11
12
|
import { Paragraph } from './Paragraph';
|
|
12
|
-
import { getTranslatedString } from '@learnmd/core';
|
|
13
|
+
import { getTranslatedString, useLearnMD } from '@learnmd/core';
|
|
14
|
+
import { CourseOverview } from './CourseOverview';
|
|
13
15
|
import { useParams, useNavigate } from 'react-router-dom';
|
|
14
|
-
|
|
15
|
-
Callout,
|
|
16
|
-
Quiz,
|
|
17
|
-
VideoEmbed,
|
|
18
|
-
Progress,
|
|
19
|
-
LanguageSwitcher,
|
|
20
|
-
Paragraph,
|
|
21
|
-
};
|
|
22
|
-
export function CourseViewer({ allLessons }) {
|
|
16
|
+
export function CourseViewer({ allLessons, coursesConfig = {} }) {
|
|
23
17
|
const { courseId, '*': pathLessonSlug } = useParams();
|
|
24
18
|
const navigate = useNavigate();
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
19
|
+
const { storage, completeLesson } = useLearnMD();
|
|
20
|
+
const [completedLessons, setCompletedLessons] = useState([]);
|
|
21
|
+
const [courseProgress, setCourseProgress] = useState(0);
|
|
22
|
+
const courseLessons = useMemo(() => allLessons.filter(l => l.courseSlug === courseId), [allLessons, courseId]);
|
|
23
|
+
// If no specific lesson slug is provided, we are at the course root -> show overview
|
|
24
|
+
const isOverview = !pathLessonSlug;
|
|
25
|
+
const currentSlug = pathLessonSlug || '';
|
|
26
|
+
const currentLesson = courseLessons.find(l => l.slug === currentSlug);
|
|
28
27
|
const Component = currentLesson?.Component;
|
|
28
|
+
const currentIndex = courseLessons.findIndex(l => l.slug === currentSlug);
|
|
29
|
+
const prevLesson = currentIndex > 0 ? courseLessons[currentIndex - 1] : null;
|
|
30
|
+
const nextLesson = currentIndex < courseLessons.length - 1 ? courseLessons[currentIndex + 1] : null;
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (!courseId)
|
|
33
|
+
return;
|
|
34
|
+
storage.getCourseProgress(courseId).then((progress) => {
|
|
35
|
+
if (progress) {
|
|
36
|
+
setCompletedLessons(progress.completedLessons || []);
|
|
37
|
+
const pct = courseLessons.length > 0 ? ((progress.completedLessons?.length || 0) / courseLessons.length) * 100 : 0;
|
|
38
|
+
setCourseProgress(Math.min(100, Math.round(pct)));
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}, [courseId, currentSlug, storage, courseLessons.length]);
|
|
42
|
+
const handleNavigate = (slug) => {
|
|
43
|
+
navigate(`/courses/${courseId}/${slug}`);
|
|
44
|
+
};
|
|
45
|
+
const handleCompleteAndNext = async () => {
|
|
46
|
+
if (courseId && currentSlug) {
|
|
47
|
+
await completeLesson(courseId, currentSlug, { totalLessons: courseLessons.length });
|
|
48
|
+
const progress = await storage.getCourseProgress(courseId);
|
|
49
|
+
if (nextLesson) {
|
|
50
|
+
handleNavigate(nextLesson.slug);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// Force refresh progress if it's the last lesson
|
|
54
|
+
if (progress) {
|
|
55
|
+
setCompletedLessons(progress.completedLessons || []);
|
|
56
|
+
setCourseProgress(100);
|
|
57
|
+
}
|
|
58
|
+
handleNavigate(''); // Go back to overview
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
29
62
|
const navigation = [{
|
|
30
63
|
type: 'module',
|
|
31
64
|
id: `module-${courseId}`,
|
|
@@ -35,11 +68,50 @@ export function CourseViewer({ allLessons }) {
|
|
|
35
68
|
id: l.slug,
|
|
36
69
|
title: getTranslatedString(l.frontmatter?.title, 'en') || l.slug,
|
|
37
70
|
slug: l.slug,
|
|
71
|
+
completed: completedLessons.includes(l.slug)
|
|
38
72
|
}))
|
|
39
73
|
}];
|
|
40
|
-
const
|
|
41
|
-
|
|
74
|
+
const courseData = coursesConfig[courseId || ''] || {
|
|
75
|
+
id: courseId || '',
|
|
76
|
+
title: String(courseId).replace(/-/g, ' ').toUpperCase(),
|
|
77
|
+
modules: [],
|
|
78
|
+
lessons: courseLessons.map(l => ({ slug: l.slug, title: getTranslatedString(l.frontmatter?.title, 'en') || l.slug })),
|
|
79
|
+
frontmatter: {},
|
|
80
|
+
basePath: `/courses/${courseId}`
|
|
81
|
+
};
|
|
82
|
+
// Inject props into Quiz to handle completion
|
|
83
|
+
const components = {
|
|
84
|
+
Callout,
|
|
85
|
+
Quiz: (props) => {
|
|
86
|
+
const isCompleted = completedLessons.includes(currentSlug);
|
|
87
|
+
// We don't have the exact score in completedLessons array, but we can assume 100 or fetch it
|
|
88
|
+
// For now, if the lesson is completed, we pass initialCompleted=true
|
|
89
|
+
return (_jsx(Quiz, { ...props, initialCompleted: isCompleted, initialScore: 100, onComplete: async (results) => {
|
|
90
|
+
if (props.onComplete)
|
|
91
|
+
props.onComplete(results);
|
|
92
|
+
if (results.passed && courseId && currentSlug) {
|
|
93
|
+
await completeLesson(courseId, currentSlug, {
|
|
94
|
+
totalLessons: courseLessons.length,
|
|
95
|
+
score: results.score,
|
|
96
|
+
passed: results.passed
|
|
97
|
+
});
|
|
98
|
+
const progress = await storage.getCourseProgress(courseId);
|
|
99
|
+
if (progress) {
|
|
100
|
+
setCompletedLessons(progress.completedLessons || []);
|
|
101
|
+
const pct = courseLessons.length > 0 ? ((progress.completedLessons?.length || 0) / courseLessons.length) * 100 : 0;
|
|
102
|
+
setCourseProgress(Math.min(100, Math.round(pct)));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
} }));
|
|
106
|
+
},
|
|
107
|
+
VideoEmbed,
|
|
108
|
+
Progress,
|
|
109
|
+
LanguageSwitcher,
|
|
110
|
+
Paragraph,
|
|
42
111
|
};
|
|
43
|
-
return (_jsx(ThemeProvider, { children: _jsx(CourseLayout, { courseTitle: String(courseId).replace(/-/g, ' ').toUpperCase(), navigation: navigation, currentLessonSlug: currentSlug, completedLessons:
|
|
112
|
+
return (_jsx(ThemeProvider, { children: _jsx(CourseLayout, { courseTitle: String(courseId).replace(/-/g, ' ').toUpperCase(), navigation: navigation, currentLessonSlug: currentSlug, completedLessons: completedLessons, progress: courseProgress, onNavigate: handleNavigate, children: _jsx("div", { className: "prose px-8 py-4 max-w-4xl mx-auto pb-24", children: isOverview ? (_jsx(CourseOverview, { course: courseData, overviewContent: undefined, onStartCourse: () => {
|
|
113
|
+
const firstUncompleted = courseLessons.find(l => !completedLessons.includes(l.slug));
|
|
114
|
+
handleNavigate(firstUncompleted?.slug || courseLessons[0]?.slug || '');
|
|
115
|
+
}, completedLessons: completedLessons, courseProgress: courseProgress })) : Component ? (_jsxs(_Fragment, { children: [_jsx(MDXProvider, { components: components, children: _jsx(Component, {}) }), _jsxs("div", { className: "mt-16 pt-8 border-t border-[rgb(var(--border-color))] flex flex-col sm:flex-row items-center justify-between gap-4", children: [_jsx("div", { className: "w-full sm:w-auto", children: prevLesson && (_jsxs("button", { onClick: () => handleNavigate(prevLesson.slug), className: "w-full px-6 py-3 border border-[rgb(var(--border-color))] hover:bg-[rgb(var(--bg-secondary))] text-[rgb(var(--text-primary))] font-medium rounded-lg transition-colors flex items-center justify-center gap-2", children: [_jsx("span", { children: "\u2190" }), " Previous"] })) }), _jsxs("div", { className: "w-full sm:w-auto flex flex-col sm:flex-row gap-4 ml-auto", children: [!completedLessons.includes(currentSlug) && (_jsx("button", { onClick: handleCompleteAndNext, className: "w-full px-6 py-3 bg-[rgb(var(--color-primary-500))] hover:bg-[rgb(var(--color-primary-600))] text-white font-bold rounded-lg transition-colors shadow-sm", children: nextLesson ? 'Mark Complete & Next' : 'Finish Course' })), completedLessons.includes(currentSlug) && nextLesson && (_jsxs("button", { onClick: () => handleNavigate(nextLesson.slug), className: "w-full px-6 py-3 bg-[rgb(var(--bg-secondary))] hover:bg-[rgb(var(--border-color))] text-[rgb(var(--text-primary))] font-bold rounded-lg transition-colors shadow-sm flex items-center justify-center gap-2", children: ["Next ", _jsx("span", { children: "\u2192" })] })), completedLessons.includes(currentSlug) && !nextLesson && (_jsxs("button", { onClick: () => handleNavigate(''), className: "w-full px-6 py-3 bg-[rgb(var(--bg-secondary))] hover:bg-[rgb(var(--border-color))] text-[rgb(var(--text-primary))] font-bold rounded-lg transition-colors shadow-sm flex items-center justify-center gap-2", children: ["Return to Overview ", _jsx("span", { children: "\u2192" })] }))] })] })] })) : (_jsx("div", { className: "text-center p-8", children: _jsx("p", { className: "text-lg text-[rgb(var(--text-muted))]", children: "Lesson not found." }) })) }) }) }));
|
|
44
116
|
}
|
|
45
117
|
//# sourceMappingURL=CourseViewer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CourseViewer.js","sourceRoot":"","sources":["../../src/components/CourseViewer.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"CourseViewer.js","sourceRoot":"","sources":["../../src/components/CourseViewer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileViewer.d.ts","sourceRoot":"","sources":["../../src/components/ProfileViewer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProfileViewer.d.ts","sourceRoot":"","sources":["../../src/components/ProfileViewer.tsx"],"names":[],"mappings":"AAOA,wBAAgB,aAAa,4CAkK5B"}
|
|
@@ -1,31 +1,47 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useEffect } from 'react';
|
|
3
3
|
import { useLearnMD } from '@learnmd/core';
|
|
4
|
-
import { MainLayout, Header } from '../layouts/MainLayout';
|
|
5
4
|
import { Link } from 'react-router-dom';
|
|
5
|
+
import { generateCertificate } from '@learnmd/plugin-pdf';
|
|
6
6
|
export function ProfileViewer() {
|
|
7
7
|
const { storage } = useLearnMD();
|
|
8
|
+
const [profile, setProfile] = useState(null);
|
|
9
|
+
const [progressData, setProgressData] = useState({});
|
|
8
10
|
const [name, setName] = useState('');
|
|
9
11
|
const [email, setEmail] = useState('');
|
|
10
12
|
const [isSaving, setIsSaving] = useState(false);
|
|
11
13
|
const [saved, setSaved] = useState(false);
|
|
12
14
|
useEffect(() => {
|
|
13
|
-
async function
|
|
15
|
+
async function loadData() {
|
|
14
16
|
const p = await storage.getUserProfile() || { id: '1', name: '', email: '', totalPoints: 0, badges: [], coursesProgress: {}, streak: { current: 0, longest: 0, lastActiveDate: '' }, achievements: [], createdAt: Date.now(), updatedAt: Date.now() };
|
|
17
|
+
setProfile(p);
|
|
15
18
|
setName(p.name || '');
|
|
16
19
|
setEmail(p.email || '');
|
|
20
|
+
const allProgress = await storage.getAllCourseProgress();
|
|
21
|
+
setProgressData(allProgress);
|
|
17
22
|
}
|
|
18
|
-
|
|
23
|
+
loadData();
|
|
19
24
|
}, [storage]);
|
|
20
25
|
const handleSave = async (e) => {
|
|
21
26
|
e.preventDefault();
|
|
27
|
+
if (!profile)
|
|
28
|
+
return;
|
|
22
29
|
setIsSaving(true);
|
|
23
|
-
const
|
|
24
|
-
await storage.saveUserProfile(
|
|
30
|
+
const updated = { ...profile, name, email };
|
|
31
|
+
await storage.saveUserProfile(updated);
|
|
32
|
+
setProfile(updated);
|
|
25
33
|
setIsSaving(false);
|
|
26
34
|
setSaved(true);
|
|
27
35
|
setTimeout(() => setSaved(false), 3000);
|
|
28
36
|
};
|
|
29
|
-
|
|
37
|
+
const handleDownloadCertificate = async (courseId) => {
|
|
38
|
+
if (!profile)
|
|
39
|
+
return;
|
|
40
|
+
await generateCertificate(profile, { courseTitle: courseId });
|
|
41
|
+
};
|
|
42
|
+
return (_jsxs("div", { className: "container mx-auto px-4 py-8 max-w-4xl text-left", children: [_jsx(Link, { to: "/", className: "inline-block mb-6 text-sm font-medium text-[rgb(var(--text-secondary))] hover:text-[rgb(var(--color-primary-500))] transition-colors", children: "\u00AB Back to Catalog" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-8", children: [_jsxs("div", { className: "bg-[rgb(var(--bg-secondary))] p-8 rounded-xl shadow-sm border border-[rgb(var(--border-color))] h-fit", children: [_jsxs("div", { className: "flex items-center gap-4 mb-8 border-b border-[rgb(var(--border-color))] pb-6", children: [_jsx("div", { className: "w-16 h-16 rounded-full bg-[rgb(var(--color-primary-100))] dark:bg-[rgb(var(--color-primary-900))] flex items-center justify-center text-[rgb(var(--color-primary-600))] dark:text-[rgb(var(--color-primary-400))] text-2xl font-bold", children: name ? name.charAt(0).toUpperCase() : '?' }), _jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-bold text-[rgb(var(--text-primary))]", children: "Your Account" }), _jsx("p", { className: "text-[rgb(var(--text-secondary))] text-sm", children: "Update your basic information" })] })] }), _jsxs("form", { onSubmit: handleSave, className: "space-y-6", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: "name", className: "block text-sm font-medium text-[rgb(var(--text-primary))] mb-2", children: "Full Name" }), _jsx("input", { type: "text", id: "name", value: name, onChange: (e) => setName(e.target.value), required: true, className: "w-full px-4 py-2 bg-[rgb(var(--bg-primary))] border border-[rgb(var(--border-color))] text-[rgb(var(--text-primary))] rounded-md focus:ring-2 focus:ring-[rgb(var(--color-primary-500))] focus:border-[rgb(var(--color-primary-500))] outline-none transition-shadow", placeholder: "John Doe" })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "email", className: "block text-sm font-medium text-[rgb(var(--text-primary))] mb-2", children: "Email Address" }), _jsx("input", { type: "email", id: "email", value: email, onChange: (e) => setEmail(e.target.value), className: "w-full px-4 py-2 bg-[rgb(var(--bg-primary))] border border-[rgb(var(--border-color))] text-[rgb(var(--text-primary))] rounded-md focus:ring-2 focus:ring-[rgb(var(--color-primary-500))] focus:border-[rgb(var(--color-primary-500))] outline-none transition-shadow", placeholder: "john@example.com" })] }), _jsxs("div", { className: "flex items-center justify-between pt-4", children: [_jsx("span", { className: `text-sm font-medium text-[rgb(var(--color-primary-500))] transition-opacity duration-300 ${saved ? 'opacity-100' : 'opacity-0'}`, children: "\u2705 Profile saved successfully!" }), _jsx("button", { type: "submit", disabled: isSaving, className: "px-6 py-2 bg-[rgb(var(--color-primary-500))] hover:bg-[rgb(var(--color-primary-600))] text-white font-medium rounded-md shadow-sm transition-colors disabled:opacity-50", children: isSaving ? 'Saving...' : 'Save Changes' })] })] })] }), _jsxs("div", { className: "space-y-8", children: [_jsxs("div", { className: "bg-[rgb(var(--bg-secondary))] p-8 rounded-xl shadow-sm border border-[rgb(var(--border-color))]", children: [_jsx("h2", { className: "text-xl font-bold mb-4 text-[rgb(var(--text-primary))]", children: "Metrics & History" }), _jsx("div", { className: "space-y-6", children: Object.keys(progressData || {}).length > 0 ? (Object.entries(progressData).map(([courseId, progress]) => {
|
|
43
|
+
const isCompleted = !!progress.completedAt;
|
|
44
|
+
return (_jsxs("div", { className: "border-b border-[rgb(var(--border-color))] pb-4 last:border-0 last:pb-0", children: [_jsxs("div", { className: "flex justify-between items-center mb-2", children: [_jsx("span", { className: "font-semibold text-[rgb(var(--text-primary))]", children: courseId }), isCompleted && (_jsx("span", { className: "text-xs px-2 py-1 bg-[rgb(var(--color-primary-100))] text-[rgb(var(--color-primary-800))] dark:text-white dark:bg-[rgb(var(--color-primary-900))] rounded-full font-medium", children: "In Progress / Completed" }))] }), _jsx("div", { className: "mb-2", children: _jsx("div", { className: "h-2 w-full bg-[rgb(var(--bg-tertiary))] rounded-full overflow-hidden", children: _jsx("div", { className: "h-full bg-[rgb(var(--color-primary-500))]", style: { width: `${Math.min(100, Math.max(10, progress.progressPercentage || (progress.completedAt ? 100 : (progress.completedLessons.length * 20))))}%` } }) }) }), _jsxs("div", { className: "flex justify-between items-center mt-3", children: [_jsxs("span", { className: "text-sm text-[rgb(var(--text-secondary))]", children: ["Points: ", progress.totalPoints || 0] }), isCompleted && (_jsx("button", { onClick: () => handleDownloadCertificate(courseId), className: "text-sm px-4 py-1.5 bg-[rgb(var(--color-primary-500))] hover:bg-[rgb(var(--color-primary-600))] text-white rounded transition-colors", children: "Download Certificate" }))] })] }, courseId));
|
|
45
|
+
})) : (_jsx("p", { className: "text-[rgb(var(--text-secondary))] text-sm", children: "No course progress yet." })) })] }), _jsxs("div", { className: "bg-[rgb(var(--bg-secondary))] p-8 rounded-xl shadow-sm border border-[rgb(var(--border-color))]", children: [_jsx("h2", { className: "text-xl font-bold mb-4 text-[rgb(var(--text-primary))]", children: "Badges Earned" }), profile?.badges && profile.badges.length > 0 ? (_jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4", children: profile.badges.map((badge) => (_jsxs("div", { className: "flex flex-col items-center p-4 bg-[rgb(var(--bg-primary))] rounded-lg text-center border border-[rgb(var(--border-color))]", children: [_jsx("span", { className: "text-3xl mb-2", children: badge.icon || '🏆' }), _jsx("span", { className: "text-sm font-semibold text-[rgb(var(--text-primary))]", children: badge.name })] }, badge.id))) })) : (_jsx("p", { className: "text-[rgb(var(--text-secondary))] text-sm", children: "No badges earned yet. Keep learning!" }))] })] })] })] }));
|
|
30
46
|
}
|
|
31
47
|
//# sourceMappingURL=ProfileViewer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileViewer.js","sourceRoot":"","sources":["../../src/components/ProfileViewer.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"ProfileViewer.js","sourceRoot":"","sources":["../../src/components/ProfileViewer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,8 @@ export interface QuizProps {
|
|
|
17
17
|
allowRetry?: boolean;
|
|
18
18
|
showCorrectAnswers?: boolean;
|
|
19
19
|
onComplete?: (results: QuizResults) => void;
|
|
20
|
+
initialCompleted?: boolean;
|
|
21
|
+
initialScore?: number;
|
|
20
22
|
}
|
|
21
23
|
export interface QuizResults {
|
|
22
24
|
score: number;
|
|
@@ -29,6 +31,6 @@ export interface QuizAnswer {
|
|
|
29
31
|
selectedAnswer: string;
|
|
30
32
|
correct: boolean;
|
|
31
33
|
}
|
|
32
|
-
export declare function Quiz({ questions, passingScore, allowRetry, showCorrectAnswers, onComplete, }: QuizProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export declare function Quiz({ questions, passingScore, allowRetry, showCorrectAnswers, onComplete, initialCompleted, initialScore, }: QuizProps): import("react/jsx-runtime").JSX.Element;
|
|
33
35
|
export default Quiz;
|
|
34
36
|
//# sourceMappingURL=Quiz.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Quiz.d.ts","sourceRoot":"","sources":["../../src/components/Quiz.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,GAAG,YAAY,GAAG,OAAO,CAAC;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"Quiz.d.ts","sourceRoot":"","sources":["../../src/components/Quiz.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,GAAG,YAAY,GAAG,OAAO,CAAC;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAC5C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,IAAI,CAAC,EACnB,SAAS,EACT,YAAiB,EACjB,UAAiB,EACjB,kBAAyB,EACzB,UAAU,EACV,gBAAwB,EACxB,YAAkB,GACnB,EAAE,SAAS,2CAkQX;AAED,eAAe,IAAI,CAAC"}
|
package/dist/components/Quiz.js
CHANGED
|
@@ -2,15 +2,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState, useCallback } from 'react';
|
|
3
3
|
import { getTranslatedString } from '@learnmd/core';
|
|
4
4
|
import { useI18n } from '../hooks';
|
|
5
|
-
export function Quiz({ questions, passingScore = 70, allowRetry = true, showCorrectAnswers = true, onComplete, }) {
|
|
5
|
+
export function Quiz({ questions, passingScore = 70, allowRetry = true, showCorrectAnswers = true, onComplete, initialCompleted = false, initialScore = 100, }) {
|
|
6
6
|
const { currentLanguage } = useI18n();
|
|
7
7
|
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
|
|
8
8
|
const [answers, setAnswers] = useState([]);
|
|
9
9
|
const [selectedAnswer, setSelectedAnswer] = useState(null);
|
|
10
10
|
const [showExplanation, setShowExplanation] = useState(false);
|
|
11
11
|
const [submitted, setSubmitted] = useState(false);
|
|
12
|
-
const [quizCompleted, setQuizCompleted] = useState(
|
|
13
|
-
const [results, setResults] = useState(
|
|
12
|
+
const [quizCompleted, setQuizCompleted] = useState(initialCompleted);
|
|
13
|
+
const [results, setResults] = useState(initialCompleted
|
|
14
|
+
? { score: initialScore, totalQuestions: questions.length, passed: initialScore >= passingScore, answers: [] }
|
|
15
|
+
: null);
|
|
14
16
|
const currentQuestion = questions[currentQuestionIndex];
|
|
15
17
|
const isLastQuestion = currentQuestionIndex === questions.length - 1;
|
|
16
18
|
const calculateScore = useCallback((quizAnswers) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Quiz.js","sourceRoot":"","sources":["../../src/components/Quiz.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"Quiz.js","sourceRoot":"","sources":["../../src/components/Quiz.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,SAAS,EACT,aAAa,EACb,aAAa,EACb,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAExB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,SAAS,EACT,aAAa,EACb,aAAa,EACb,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAExB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}
|
package/dist/components/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,SAAS,EACT,aAAa,EACb,aAAa,EACb,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAExB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,SAAS,EACT,aAAa,EACb,aAAa,EACb,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAExB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CourseLayout.d.ts","sourceRoot":"","sources":["../../src/layouts/CourseLayout.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAIxD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"CourseLayout.d.ts","sourceRoot":"","sources":["../../src/layouts/CourseLayout.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAIxD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,kBAAyB,EACzB,YAAmB,EACnB,cAAqB,EACrB,MAAM,GACP,EAAE,iBAAiB,2CAmFnB;AA+DD,MAAM,WAAW,qBAAqB;IACpC,cAAc,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,cAAc,EACd,UAAU,EACV,UAAU,EACV,MAAM,GACP,EAAE,qBAAqB,2CAoCvB;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { Progress } from '../components';
|
|
4
|
-
import {
|
|
5
|
-
function ThemeToggle() {
|
|
6
|
-
const { resolvedTheme, setTheme } = useTheme();
|
|
7
|
-
const isDark = resolvedTheme === 'dark';
|
|
8
|
-
return (_jsx("button", { onClick: () => setTheme(isDark ? 'light' : 'dark'), className: "p-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors", "aria-label": "Toggle Dark Mode", children: isDark ? (
|
|
9
|
-
// Sun Icon
|
|
10
|
-
_jsx("svg", { className: "w-5 h-5 text-yellow-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) })) : (
|
|
11
|
-
// Moon Icon
|
|
12
|
-
_jsx("svg", { className: "w-5 h-5 text-slate-700", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" }) })) }));
|
|
13
|
-
}
|
|
4
|
+
import { Header } from './MainLayout';
|
|
14
5
|
export function CourseLayout({ children, courseTitle, navigation, currentLessonSlug, completedLessons, progress, onNavigate, sidebarCollapsible = true, showProgress = true, showNavigation = true, footer, }) {
|
|
15
6
|
const [isSidebarOpen, setIsSidebarOpen] = useState(true);
|
|
16
7
|
const [expandedModules, setExpandedModules] = useState(new Set(navigation.map((m) => m.id)));
|
|
@@ -26,7 +17,7 @@ export function CourseLayout({ children, courseTitle, navigation, currentLessonS
|
|
|
26
17
|
return next;
|
|
27
18
|
});
|
|
28
19
|
};
|
|
29
|
-
return (_jsxs("div", { className: "flex flex-col min-h-screen font-sans bg-
|
|
20
|
+
return (_jsxs("div", { className: "flex flex-col min-h-screen font-sans bg-[rgb(var(--bg-primary))] text-[rgb(var(--text-primary))] transition-colors duration-200", children: [_jsx(Header, { title: courseTitle, actions: _jsxs("div", { className: "flex items-center gap-4", children: [sidebarCollapsible && (_jsx("button", { onClick: () => setIsSidebarOpen(!isSidebarOpen), className: "xl:hidden p-2 -ml-2 rounded-md hover:bg-[rgb(var(--bg-secondary))] mr-2", children: _jsx("svg", { className: "w-6 h-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 12h16M4 18h16" }) }) })), showProgress && (_jsxs("div", { className: "hidden lg:flex items-center gap-3 w-48", children: [_jsx(Progress, { value: progress, size: "sm" }), _jsxs("span", { className: "text-sm font-medium text-[rgb(var(--text-secondary))]", children: [Math.round(progress), "%"] })] }))] }) }), _jsxs("div", { className: "flex flex-1 overflow-hidden", children: [showNavigation && (_jsx("aside", { className: `${isSidebarOpen ? 'w-72 translate-x-0' : 'w-0 -translate-x-full'} fixed inset-y-0 left-0 z-30 mt-16 xl:static xl:mt-0 flex-shrink-0 overflow-y-auto bg-[#f5f6f7] dark:bg-[#1c1e21] border-r border-gray-200 dark:border-gray-800 transition-all duration-300`, children: _jsx("nav", { className: "p-4 space-y-1", children: navigation.map((module) => (_jsx(ModuleItem, { module: module, isExpanded: expandedModules.has(module.id), currentLessonSlug: currentLessonSlug, completedLessons: completedLessons, onToggle: () => toggleModule(module.id), onNavigate: onNavigate }, module.id))) }) })), _jsx("main", { className: "flex-1 overflow-y-auto w-full", children: _jsxs("div", { className: "max-w-[800px] mx-auto px-6 py-10 lg:px-12 lg:py-16", children: [children, footer && (_jsx("div", { className: "mt-16", children: footer }))] }) })] })] }));
|
|
30
21
|
}
|
|
31
22
|
function ModuleItem({ module, isExpanded, currentLessonSlug, completedLessons, onToggle, onNavigate, }) {
|
|
32
23
|
return (_jsxs("div", { className: "mb-4", children: [_jsxs("button", { onClick: onToggle, className: "w-full flex items-center justify-between px-3 py-2 text-sm font-bold text-slate-900 dark:text-gray-100 uppercase tracking-wider hover:bg-gray-200 dark:hover:bg-gray-800 rounded-md transition-colors", children: [_jsx("span", { className: "truncate", children: module.title }), _jsx("svg", { className: `w-4 h-4 transition-transform duration-200 ${isExpanded ? 'rotate-90' : ''}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })] }), isExpanded && module.children && module.children.length > 0 && (_jsx("ul", { className: "mt-2 space-y-1 border-l border-gray-200 dark:border-gray-700 ml-4 pl-1", children: module.children.map((lesson) => (_jsx("li", { children: _jsxs("button", { onClick: () => lesson.slug && onNavigate(lesson.slug), className: `w-full flex items-center gap-3 px-3 py-2 text-sm rounded-md transition-colors ${currentLessonSlug === lesson.id
|