@learnmd/default-theme 0.0.1-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/LICENSE +21 -0
- package/README.md +30 -0
- package/dist/components/Callout.d.ts +10 -0
- package/dist/components/Callout.d.ts.map +1 -0
- package/dist/components/Callout.js +44 -0
- package/dist/components/Callout.js.map +1 -0
- package/dist/components/Callout.test.d.ts +2 -0
- package/dist/components/Callout.test.d.ts.map +1 -0
- package/dist/components/Callout.test.js +24 -0
- package/dist/components/Callout.test.js.map +1 -0
- package/dist/components/CatalogViewer.d.ts +9 -0
- package/dist/components/CatalogViewer.d.ts.map +1 -0
- package/dist/components/CatalogViewer.js +24 -0
- package/dist/components/CatalogViewer.js.map +1 -0
- package/dist/components/CourseViewer.d.ts +11 -0
- package/dist/components/CourseViewer.d.ts.map +1 -0
- package/dist/components/CourseViewer.js +45 -0
- package/dist/components/CourseViewer.js.map +1 -0
- package/dist/components/Gamification.d.ts +32 -0
- package/dist/components/Gamification.d.ts.map +1 -0
- package/dist/components/Gamification.js +27 -0
- package/dist/components/Gamification.js.map +1 -0
- package/dist/components/ImageEmbed.d.ts +23 -0
- package/dist/components/ImageEmbed.d.ts.map +1 -0
- package/dist/components/ImageEmbed.js +39 -0
- package/dist/components/ImageEmbed.js.map +1 -0
- package/dist/components/LanguageSwitcher.d.ts +8 -0
- package/dist/components/LanguageSwitcher.d.ts.map +1 -0
- package/dist/components/LanguageSwitcher.js +61 -0
- package/dist/components/LanguageSwitcher.js.map +1 -0
- package/dist/components/Paragraph.d.ts +8 -0
- package/dist/components/Paragraph.d.ts.map +1 -0
- package/dist/components/Paragraph.js +23 -0
- package/dist/components/Paragraph.js.map +1 -0
- package/dist/components/ProfileViewer.d.ts +2 -0
- package/dist/components/ProfileViewer.d.ts.map +1 -0
- package/dist/components/ProfileViewer.js +31 -0
- package/dist/components/ProfileViewer.js.map +1 -0
- package/dist/components/Progress.d.ts +31 -0
- package/dist/components/Progress.d.ts.map +1 -0
- package/dist/components/Progress.js +41 -0
- package/dist/components/Progress.js.map +1 -0
- package/dist/components/Quiz.d.ts +34 -0
- package/dist/components/Quiz.d.ts.map +1 -0
- package/dist/components/Quiz.js +109 -0
- package/dist/components/Quiz.js.map +1 -0
- package/dist/components/Quiz.test.d.ts +2 -0
- package/dist/components/Quiz.test.d.ts.map +1 -0
- package/dist/components/Quiz.test.js +48 -0
- package/dist/components/Quiz.test.js.map +1 -0
- package/dist/components/Search.d.ts +17 -0
- package/dist/components/Search.d.ts.map +1 -0
- package/dist/components/Search.js +30 -0
- package/dist/components/Search.js.map +1 -0
- package/dist/components/VideoEmbed.d.ts +15 -0
- package/dist/components/VideoEmbed.d.ts.map +1 -0
- package/dist/components/VideoEmbed.js +83 -0
- package/dist/components/VideoEmbed.js.map +1 -0
- package/dist/components/index.d.ts +13 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +13 -0
- package/dist/components/index.js.map +1 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +3 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useI18n.d.ts +11 -0
- package/dist/hooks/useI18n.d.ts.map +1 -0
- package/dist/hooks/useI18n.js +39 -0
- package/dist/hooks/useI18n.js.map +1 -0
- package/dist/hooks/useTheme.d.ts +13 -0
- package/dist/hooks/useTheme.d.ts.map +1 -0
- package/dist/hooks/useTheme.js +49 -0
- package/dist/hooks/useTheme.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/layouts/CourseLayout.d.ts +40 -0
- package/dist/layouts/CourseLayout.d.ts.map +1 -0
- package/dist/layouts/CourseLayout.js +40 -0
- package/dist/layouts/CourseLayout.js.map +1 -0
- package/dist/layouts/MainLayout.d.ts +18 -0
- package/dist/layouts/MainLayout.d.ts.map +1 -0
- package/dist/layouts/MainLayout.js +23 -0
- package/dist/layouts/MainLayout.js.map +1 -0
- package/dist/layouts/index.d.ts +5 -0
- package/dist/layouts/index.d.ts.map +1 -0
- package/dist/layouts/index.js +3 -0
- package/dist/layouts/index.js.map +1 -0
- package/dist/styles/output.css +2586 -0
- package/dist/test/setup.d.ts +2 -0
- package/dist/test/setup.d.ts.map +1 -0
- package/dist/test/setup.js +22 -0
- package/dist/test/setup.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
import { useLearnMD } from '@learnmd/core';
|
|
4
|
+
import { MainLayout, Header } from '../layouts/MainLayout';
|
|
5
|
+
import { Link } from 'react-router-dom';
|
|
6
|
+
export function ProfileViewer() {
|
|
7
|
+
const { storage } = useLearnMD();
|
|
8
|
+
const [name, setName] = useState('');
|
|
9
|
+
const [email, setEmail] = useState('');
|
|
10
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
11
|
+
const [saved, setSaved] = useState(false);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
async function loadProfile() {
|
|
14
|
+
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() };
|
|
15
|
+
setName(p.name || '');
|
|
16
|
+
setEmail(p.email || '');
|
|
17
|
+
}
|
|
18
|
+
loadProfile();
|
|
19
|
+
}, [storage]);
|
|
20
|
+
const handleSave = async (e) => {
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
setIsSaving(true);
|
|
23
|
+
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() };
|
|
24
|
+
await storage.saveUserProfile({ ...p, name, email });
|
|
25
|
+
setIsSaving(false);
|
|
26
|
+
setSaved(true);
|
|
27
|
+
setTimeout(() => setSaved(false), 3000);
|
|
28
|
+
};
|
|
29
|
+
return (_jsxs(MainLayout, { children: [_jsx(Header, { title: "User Profile", actions: _jsx(Link, { to: "/", className: "text-sm font-medium hover:text-emerald-500", children: "\u00AB Back to Catalog" }) }), _jsx("div", { className: "container mx-auto px-4 py-8 max-w-2xl", children: _jsxs("div", { className: "bg-white dark:bg-gray-800 p-8 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700", children: [_jsxs("div", { className: "flex items-center gap-4 mb-8 border-b border-gray-200 dark:border-gray-700 pb-6", children: [_jsx("div", { className: "w-16 h-16 rounded-full bg-emerald-100 dark:bg-emerald-900 flex items-center justify-center text-emerald-600 dark:text-emerald-400 text-2xl font-bold", children: name ? name.charAt(0).toUpperCase() : '?' }), _jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-bold", children: "Your Account" }), _jsx("p", { className: "text-gray-500 dark:text-gray-400 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-gray-700 dark:text-gray-300 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-gray-50 dark:bg-gray-900 border border-gray-300 dark:border-gray-700 rounded-md focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500 outline-none transition-shadow", placeholder: "John Doe" })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "email", className: "block text-sm font-medium text-gray-700 dark:text-gray-300 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-gray-50 dark:bg-gray-900 border border-gray-300 dark:border-gray-700 rounded-md focus:ring-2 focus:ring-emerald-500 focus:border-emerald-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-emerald-600 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-emerald-600 hover:bg-emerald-700 text-white font-medium rounded-md shadow-sm transition-colors disabled:opacity-50", children: isSaving ? 'Saving...' : 'Save Changes' })] })] })] }) })] }));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=ProfileViewer.js.map
|
|
@@ -0,0 +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;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,EAAE,CAAC;IAEjC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACrC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE1C,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,UAAU,WAAW;YACxB,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,cAAc,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACtP,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;YACtB,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC1B,CAAC;QACD,WAAW,EAAE,CAAC;IAChB,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,MAAM,UAAU,GAAG,KAAK,EAAE,CAAkB,EAAE,EAAE;QAC9C,CAAC,CAAC,cAAc,EAAE,CAAC;QACnB,WAAW,CAAC,IAAI,CAAC,CAAC;QAElB,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,cAAc,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACtP,MAAM,OAAO,CAAC,eAAe,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAErD,WAAW,CAAC,KAAK,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF,OAAO,CACL,MAAC,UAAU,eACT,KAAC,MAAM,IACL,KAAK,EAAC,cAAc,EACpB,OAAO,EACL,KAAC,IAAI,IAAC,EAAE,EAAC,GAAG,EAAC,SAAS,EAAC,4CAA4C,uCAE5D,GAET,EACF,cAAK,SAAS,EAAC,uCAAuC,YACpD,eAAK,SAAS,EAAC,gGAAgG,aAC7G,eAAK,SAAS,EAAC,iFAAiF,aAC9F,cAAK,SAAS,EAAC,sJAAsJ,YAClK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,GACtC,EACN,0BACE,aAAI,SAAS,EAAC,oBAAoB,6BAAkB,EACpD,YAAG,SAAS,EAAC,0CAA0C,8CAAkC,IACrF,IACF,EAEN,gBAAM,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAC,WAAW,aAC/C,0BACE,gBAAO,OAAO,EAAC,MAAM,EAAC,SAAS,EAAC,iEAAiE,0BAEzF,EACR,gBACE,IAAI,EAAC,MAAM,EACX,EAAE,EAAC,MAAM,EACT,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACxC,QAAQ,QACR,SAAS,EAAC,iMAAiM,EAC3M,WAAW,EAAC,UAAU,GACtB,IACE,EAEN,0BACE,gBAAO,OAAO,EAAC,OAAO,EAAC,SAAS,EAAC,iEAAiE,8BAE1F,EACR,gBACE,IAAI,EAAC,OAAO,EACZ,EAAE,EAAC,OAAO,EACV,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACzC,SAAS,EAAC,iMAAiM,EAC3M,WAAW,EAAC,kBAAkB,GAC9B,IACE,EAEN,eAAK,SAAS,EAAC,wCAAwC,aACrD,eAAM,SAAS,EAAE,wEAAwE,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,EAAE,mDAEvH,EACP,iBACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAC,iIAAiI,YAE1I,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,GACjC,IACL,IACD,IACH,GACF,IACK,CACd,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface ProgressProps {
|
|
2
|
+
value: number;
|
|
3
|
+
max?: number;
|
|
4
|
+
label?: string;
|
|
5
|
+
showPercentage?: boolean;
|
|
6
|
+
size?: 'sm' | 'md' | 'lg';
|
|
7
|
+
variant?: 'default' | 'success' | 'warning' | 'error';
|
|
8
|
+
animated?: boolean;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ProgressRingProps {
|
|
12
|
+
value: number;
|
|
13
|
+
max?: number;
|
|
14
|
+
size?: number;
|
|
15
|
+
strokeWidth?: number;
|
|
16
|
+
label?: string;
|
|
17
|
+
showPercentage?: boolean;
|
|
18
|
+
variant?: 'default' | 'success' | 'warning' | 'error';
|
|
19
|
+
}
|
|
20
|
+
export declare function Progress({ value, max, label, showPercentage, size, variant, animated, className, }: ProgressProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export declare function ProgressRing({ value, max, size, strokeWidth, label, showPercentage, variant, }: ProgressRingProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export declare function ProgressSteps({ steps, currentStep, className, }: {
|
|
23
|
+
steps: Array<{
|
|
24
|
+
label: string;
|
|
25
|
+
completed?: boolean;
|
|
26
|
+
}>;
|
|
27
|
+
currentStep: number;
|
|
28
|
+
className?: string;
|
|
29
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export default Progress;
|
|
31
|
+
//# sourceMappingURL=Progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Progress.d.ts","sourceRoot":"","sources":["../../src/components/Progress.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;CACvD;AAeD,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,GAAS,EACT,KAAK,EACL,cAAsB,EACtB,IAAW,EACX,OAAmB,EACnB,QAAe,EACf,SAAc,GACf,EAAE,aAAa,2CAqBf;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,GAAS,EACT,IAAS,EACT,WAAe,EACf,KAAK,EACL,cAAqB,EACrB,OAAmB,GACpB,EAAE,iBAAiB,2CA2CnB;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAW,EACX,SAAc,GACf,EAAE;IACD,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CA6CA;AAED,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
const sizeClasses = {
|
|
4
|
+
sm: 'h-1',
|
|
5
|
+
md: 'h-2',
|
|
6
|
+
lg: 'h-3',
|
|
7
|
+
};
|
|
8
|
+
const variantClasses = {
|
|
9
|
+
default: 'bg-[rgb(var(--color-primary-500))]',
|
|
10
|
+
success: 'bg-[rgb(var(--success))]',
|
|
11
|
+
warning: 'bg-[rgb(var(--warning))]',
|
|
12
|
+
error: 'bg-[rgb(var(--error))]',
|
|
13
|
+
};
|
|
14
|
+
export function Progress({ value, max = 100, label, showPercentage = false, size = 'md', variant = 'default', animated = true, className = '', }) {
|
|
15
|
+
const percentage = Math.min(Math.max((value / max) * 100, 0), 100);
|
|
16
|
+
return (_jsxs("div", { className: className, children: [(label || showPercentage) && (_jsxs("div", { className: "flex justify-between items-center mb-1", children: [label && _jsx("span", { className: "text-sm text-[rgb(var(--text-secondary))]", children: label }), showPercentage && _jsxs("span", { className: "text-sm font-medium", children: [Math.round(percentage), "%"] })] })), _jsx("div", { className: `progress-bar ${sizeClasses[size]}`, children: _jsx("div", { className: `progress-bar-fill ${variantClasses[variant]} ${animated ? 'transition-all duration-500 ease-out' : ''}`, style: { width: `${percentage}%` } }) })] }));
|
|
17
|
+
}
|
|
18
|
+
export function ProgressRing({ value, max = 100, size = 64, strokeWidth = 4, label, showPercentage = true, variant = 'default', }) {
|
|
19
|
+
const percentage = Math.min(Math.max((value / max) * 100, 0), 100);
|
|
20
|
+
const radius = (size - strokeWidth) / 2;
|
|
21
|
+
const circumference = radius * 2 * Math.PI;
|
|
22
|
+
const offset = circumference - (percentage / 100) * circumference;
|
|
23
|
+
const variantColors = {
|
|
24
|
+
default: 'var(--color-primary-500)',
|
|
25
|
+
success: 'rgb(var(--success))',
|
|
26
|
+
warning: 'rgb(var(--warning))',
|
|
27
|
+
error: 'rgb(var(--error))',
|
|
28
|
+
};
|
|
29
|
+
return (_jsxs("div", { className: "relative inline-flex items-center justify-center", children: [_jsxs("svg", { width: size, height: size, className: "-rotate-90", children: [_jsx("circle", { cx: size / 2, cy: size / 2, r: radius, fill: "none", stroke: "rgb(var(--bg-tertiary))", strokeWidth: strokeWidth }), _jsx("circle", { cx: size / 2, cy: size / 2, r: radius, fill: "none", stroke: variantColors[variant], strokeWidth: strokeWidth, strokeDasharray: circumference, strokeDashoffset: offset, strokeLinecap: "round", className: "transition-all duration-500 ease-out" })] }), _jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center", children: [showPercentage && _jsxs("span", { className: "text-lg font-bold", children: [Math.round(percentage), "%"] }), label && _jsx("span", { className: "text-xs text-[rgb(var(--text-secondary))]", children: label })] })] }));
|
|
30
|
+
}
|
|
31
|
+
export function ProgressSteps({ steps, currentStep, className = '', }) {
|
|
32
|
+
return (_jsx("div", { className: className, children: _jsx("div", { className: "flex items-center", children: steps.map((step, index) => (_jsxs(React.Fragment, { children: [_jsxs("div", { className: "flex flex-col items-center", children: [_jsx("div", { className: `w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium transition-colors ${index < currentStep || step.completed
|
|
33
|
+
? 'bg-[rgb(var(--color-primary-500))] text-white'
|
|
34
|
+
: index === currentStep
|
|
35
|
+
? 'bg-[rgb(var(--color-primary-500))] text-white ring-4 ring-[rgb(var(--color-primary-200))]'
|
|
36
|
+
: 'bg-[rgb(var(--bg-tertiary))] text-[rgb(var(--text-muted))]'}`, children: index < currentStep || step.completed ? (_jsx("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) })) : (index + 1) }), _jsx("span", { className: "text-xs mt-1 text-[rgb(var(--text-secondary))]", children: step.label })] }), index < steps.length - 1 && (_jsx("div", { className: `flex-1 h-0.5 mx-2 ${index < currentStep
|
|
37
|
+
? 'bg-[rgb(var(--color-primary-500))]'
|
|
38
|
+
: 'bg-[rgb(var(--bg-tertiary))]'}` }))] }, step.label))) }) }));
|
|
39
|
+
}
|
|
40
|
+
export default Progress;
|
|
41
|
+
//# sourceMappingURL=Progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Progress.js","sourceRoot":"","sources":["../../src/components/Progress.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface QuizQuestion {
|
|
2
|
+
id: string;
|
|
3
|
+
type: 'multiple-choice' | 'true-false' | 'input';
|
|
4
|
+
question: string;
|
|
5
|
+
options?: Array<{
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
}>;
|
|
9
|
+
correctAnswer: string | string[];
|
|
10
|
+
explanation?: string;
|
|
11
|
+
points?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface QuizProps {
|
|
14
|
+
id: string;
|
|
15
|
+
questions: QuizQuestion[];
|
|
16
|
+
passingScore?: number;
|
|
17
|
+
allowRetry?: boolean;
|
|
18
|
+
showCorrectAnswers?: boolean;
|
|
19
|
+
onComplete?: (results: QuizResults) => void;
|
|
20
|
+
}
|
|
21
|
+
export interface QuizResults {
|
|
22
|
+
score: number;
|
|
23
|
+
totalQuestions: number;
|
|
24
|
+
passed: boolean;
|
|
25
|
+
answers: QuizAnswer[];
|
|
26
|
+
}
|
|
27
|
+
export interface QuizAnswer {
|
|
28
|
+
questionId: string;
|
|
29
|
+
selectedAnswer: string;
|
|
30
|
+
correct: boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare function Quiz({ questions, passingScore, allowRetry, showCorrectAnswers, onComplete, }: QuizProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export default Quiz;
|
|
34
|
+
//# sourceMappingURL=Quiz.d.ts.map
|
|
@@ -0,0 +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;CAC7C;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,GACX,EAAE,SAAS,2CA8PX;AAED,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useCallback } from 'react';
|
|
3
|
+
import { getTranslatedString } from '@learnmd/core';
|
|
4
|
+
import { useI18n } from '../hooks';
|
|
5
|
+
export function Quiz({ questions, passingScore = 70, allowRetry = true, showCorrectAnswers = true, onComplete, }) {
|
|
6
|
+
const { currentLanguage } = useI18n();
|
|
7
|
+
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
|
|
8
|
+
const [answers, setAnswers] = useState([]);
|
|
9
|
+
const [selectedAnswer, setSelectedAnswer] = useState(null);
|
|
10
|
+
const [showExplanation, setShowExplanation] = useState(false);
|
|
11
|
+
const [submitted, setSubmitted] = useState(false);
|
|
12
|
+
const [quizCompleted, setQuizCompleted] = useState(false);
|
|
13
|
+
const [results, setResults] = useState(null);
|
|
14
|
+
const currentQuestion = questions[currentQuestionIndex];
|
|
15
|
+
const isLastQuestion = currentQuestionIndex === questions.length - 1;
|
|
16
|
+
const calculateScore = useCallback((quizAnswers) => {
|
|
17
|
+
const correctAnswers = quizAnswers.filter((a) => a.correct).length;
|
|
18
|
+
const score = Math.round((correctAnswers / questions.length) * 100);
|
|
19
|
+
return {
|
|
20
|
+
score,
|
|
21
|
+
totalQuestions: questions.length,
|
|
22
|
+
passed: score >= passingScore,
|
|
23
|
+
answers: quizAnswers,
|
|
24
|
+
};
|
|
25
|
+
}, [questions.length, passingScore]);
|
|
26
|
+
const handleAnswerSelect = (answer) => {
|
|
27
|
+
if (submitted)
|
|
28
|
+
return;
|
|
29
|
+
setSelectedAnswer(answer);
|
|
30
|
+
};
|
|
31
|
+
const handleSubmitAnswer = () => {
|
|
32
|
+
if (!selectedAnswer || submitted)
|
|
33
|
+
return;
|
|
34
|
+
const isCorrect = Array.isArray(currentQuestion.correctAnswer)
|
|
35
|
+
? currentQuestion.correctAnswer.includes(selectedAnswer)
|
|
36
|
+
: selectedAnswer === currentQuestion.correctAnswer;
|
|
37
|
+
const newAnswer = {
|
|
38
|
+
questionId: currentQuestion.id,
|
|
39
|
+
selectedAnswer,
|
|
40
|
+
correct: isCorrect,
|
|
41
|
+
};
|
|
42
|
+
const newAnswers = [...answers, newAnswer];
|
|
43
|
+
setAnswers(newAnswers);
|
|
44
|
+
setSubmitted(true);
|
|
45
|
+
setShowExplanation(true);
|
|
46
|
+
if (isLastQuestion) {
|
|
47
|
+
const finalResults = calculateScore(newAnswers);
|
|
48
|
+
setResults(finalResults);
|
|
49
|
+
setQuizCompleted(true);
|
|
50
|
+
onComplete?.(finalResults);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const handleNextQuestion = () => {
|
|
54
|
+
setCurrentQuestionIndex((prev) => prev + 1);
|
|
55
|
+
setSelectedAnswer(null);
|
|
56
|
+
setSubmitted(false);
|
|
57
|
+
setShowExplanation(false);
|
|
58
|
+
};
|
|
59
|
+
const handleRetry = () => {
|
|
60
|
+
setCurrentQuestionIndex(0);
|
|
61
|
+
setAnswers([]);
|
|
62
|
+
setSelectedAnswer(null);
|
|
63
|
+
setSubmitted(false);
|
|
64
|
+
setShowExplanation(false);
|
|
65
|
+
setQuizCompleted(false);
|
|
66
|
+
setResults(null);
|
|
67
|
+
};
|
|
68
|
+
if (quizCompleted && results) {
|
|
69
|
+
return (_jsxs("div", { className: "bg-white dark:bg-[#202124] shadow-md border border-gray-200 dark:border-gray-800 rounded-xl p-8 my-8 transition-colors", children: [_jsxs("div", { className: "text-center mb-8", children: [_jsx("div", { className: `inline-flex items-center justify-center w-24 h-24 rounded-full mb-6 ${results.passed
|
|
70
|
+
? 'bg-emerald-100 dark:bg-emerald-900/40 text-emerald-600 dark:text-emerald-400'
|
|
71
|
+
: 'bg-rose-100 dark:bg-rose-900/40 text-rose-600 dark:text-rose-400'}`, children: results.passed ? (_jsx("svg", { className: "w-12 h-12", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) })) : (_jsx("svg", { className: "w-12 h-12", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })) }), _jsx("h3", { className: "text-3xl font-extrabold mb-3 text-slate-900 dark:text-white", children: results.passed ? 'Congratulations!' : 'Keep Trying!' }), _jsxs("p", { className: "text-5xl font-black mb-3 text-emerald-600 dark:text-emerald-500", children: [results.score, "%"] }), _jsxs("p", { className: "text-lg font-medium text-slate-500 dark:text-gray-400", children: [results.answers.filter((a) => a.correct).length, " of ", results.totalQuestions, " correct"] })] }), showCorrectAnswers && (_jsxs("div", { className: "space-y-4 mb-8", children: [_jsx("h4", { className: "text-xl font-bold border-b border-gray-200 dark:border-gray-800 pb-2 mb-4 text-slate-800 dark:text-white", children: "Review Answers" }), results.answers.map((answer, index) => {
|
|
72
|
+
const question = questions.find((q) => q.id === answer.questionId);
|
|
73
|
+
return (_jsxs("div", { className: `p-5 rounded-lg border ${answer.correct
|
|
74
|
+
? 'bg-emerald-50 dark:bg-emerald-900/10 border-emerald-200 dark:border-emerald-800/50'
|
|
75
|
+
: 'bg-rose-50 dark:bg-rose-900/10 border-rose-200 dark:border-rose-800/50'}`, children: [_jsxs("p", { className: "text-sm font-semibold tracking-wide uppercase text-slate-500 dark:text-gray-400 mb-2", children: ["Question ", index + 1] }), _jsx("p", { className: "text-lg font-medium text-slate-900 dark:text-gray-200 mb-3", children: question?.question }), _jsxs("p", { className: `font-semibold ${answer.correct ? 'text-emerald-700 dark:text-emerald-400' : 'text-rose-700 dark:text-rose-400'}`, children: ["Your answer: ", answer.selectedAnswer] }), !answer.correct && (_jsxs("p", { className: "font-semibold text-emerald-700 dark:text-emerald-400 mt-2", children: ["Correct answer:", ' ', Array.isArray(question?.correctAnswer)
|
|
76
|
+
? question?.correctAnswer[0]
|
|
77
|
+
: question?.correctAnswer] }))] }, answer.questionId));
|
|
78
|
+
})] })), allowRetry && !results.passed && (_jsx("button", { onClick: handleRetry, className: "w-full py-4 rounded-xl bg-slate-900 dark:bg-white text-white dark:text-slate-900 font-bold hover:bg-slate-800 dark:hover:bg-gray-100 transition-colors shadow-sm", children: "Try Again" }))] }));
|
|
79
|
+
}
|
|
80
|
+
return (_jsxs("div", { className: "bg-white dark:bg-[#202124] shadow-sm border border-gray-200 dark:border-gray-800 rounded-xl p-6 lg:p-8 my-8 transition-colors", children: [_jsxs("div", { className: "mb-6", children: [_jsxs("div", { className: "flex justify-between items-end mb-3", children: [_jsxs("span", { className: "text-sm font-bold uppercase tracking-wider text-slate-500 dark:text-gray-400", children: ["Question ", currentQuestionIndex + 1, " of ", questions.length] }), currentQuestion.points && (_jsxs("span", { className: "bg-emerald-100 dark:bg-emerald-900/40 text-emerald-700 dark:text-emerald-400 text-xs font-bold px-3 py-1 rounded-full", children: [currentQuestion.points, " pts"] }))] }), _jsx("div", { className: "h-2 w-full bg-gray-100 dark:bg-gray-800 rounded-full overflow-hidden", children: _jsx("div", { className: "h-full bg-emerald-500 rounded-full transition-all duration-500 ease-out", style: { width: `${((currentQuestionIndex + 1) / questions.length) * 100}%` } }) })] }), _jsx("h3", { className: "text-2xl font-bold mb-6 text-slate-900 dark:text-white leading-snug", children: getTranslatedString(currentQuestion.question, currentLanguage) }), _jsx("div", { className: "space-y-3 mb-8", children: currentQuestion.options?.map((option) => {
|
|
81
|
+
const isSelected = selectedAnswer === option.id;
|
|
82
|
+
const isCorrect = Array.isArray(currentQuestion.correctAnswer)
|
|
83
|
+
? currentQuestion.correctAnswer.includes(option.id)
|
|
84
|
+
: currentQuestion.correctAnswer === option.id;
|
|
85
|
+
const label = getTranslatedString(option.label, currentLanguage);
|
|
86
|
+
let className = 'p-4 rounded-xl border-2 cursor-pointer transition-all duration-200';
|
|
87
|
+
if (submitted) {
|
|
88
|
+
if (isCorrect) {
|
|
89
|
+
className += ' bg-emerald-50 dark:bg-emerald-900/20 border-emerald-500 dark:border-emerald-500 text-emerald-900 dark:text-emerald-100';
|
|
90
|
+
}
|
|
91
|
+
else if (isSelected && !isCorrect) {
|
|
92
|
+
className += ' bg-rose-50 dark:bg-rose-900/20 border-rose-500 dark:border-rose-500 text-rose-900 dark:text-rose-100';
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
className += ' border-gray-200 dark:border-gray-800 opacity-50 text-slate-500 dark:text-gray-400';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
className += isSelected
|
|
100
|
+
? ' border-emerald-500 bg-emerald-50/50 dark:bg-emerald-900/10 text-emerald-900 dark:text-emerald-100 shadow-sm'
|
|
101
|
+
: ' border-gray-200 dark:border-gray-700 hover:border-emerald-400 hover:bg-gray-50 dark:hover:bg-gray-800 text-slate-700 dark:text-gray-200';
|
|
102
|
+
}
|
|
103
|
+
return (_jsx("div", { className: className, onClick: () => handleAnswerSelect(option.id), children: _jsxs("div", { className: "flex items-center gap-4", children: [_jsx("div", { className: `w-6 h-6 rounded-full border-2 flex items-center justify-center transition-colors ${isSelected
|
|
104
|
+
? 'border-emerald-500 bg-emerald-500'
|
|
105
|
+
: 'border-gray-300 dark:border-gray-600'}`, children: isSelected && _jsx("div", { className: "w-2.5 h-2.5 rounded-full bg-white" }) }), _jsx("span", { className: "font-medium text-lg", children: label })] }) }, option.id));
|
|
106
|
+
}) }), showExplanation && currentQuestion.explanation && (_jsx("div", { className: "bg-blue-50 dark:bg-blue-900/20 border-l-4 border-blue-500 rounded-r-lg p-5 mb-8", children: _jsxs("p", { className: "text-blue-800 dark:text-blue-200", children: [_jsx("strong", { className: "font-bold", children: "Explanation:" }), " ", getTranslatedString(currentQuestion.explanation, currentLanguage)] }) })), _jsx("div", { className: "flex gap-4", children: !submitted ? (_jsx("button", { onClick: handleSubmitAnswer, disabled: !selectedAnswer, className: "w-full py-4 rounded-xl bg-emerald-600 text-white font-bold text-lg hover:bg-emerald-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm", children: "Submit Answer" })) : (_jsx("button", { onClick: handleNextQuestion, className: "w-full py-4 rounded-xl bg-slate-900 dark:bg-white text-white dark:text-slate-900 font-bold text-lg hover:bg-slate-800 dark:hover:bg-gray-100 transition-colors shadow-sm", children: isLastQuestion ? 'Finish Quiz' : 'Next Question' })) })] }));
|
|
107
|
+
}
|
|
108
|
+
export default Quiz;
|
|
109
|
+
//# sourceMappingURL=Quiz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Quiz.js","sourceRoot":"","sources":["../../src/components/Quiz.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Quiz.test.d.ts","sourceRoot":"","sources":["../../src/components/Quiz.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
3
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
4
|
+
import Quiz from './Quiz';
|
|
5
|
+
describe('Quiz', () => {
|
|
6
|
+
const mockQuestions = [
|
|
7
|
+
{
|
|
8
|
+
id: 'q1',
|
|
9
|
+
type: 'multiple-choice',
|
|
10
|
+
question: 'What is 1+1?',
|
|
11
|
+
options: [
|
|
12
|
+
{ id: '1', label: '1' },
|
|
13
|
+
{ id: '2', label: '2' },
|
|
14
|
+
],
|
|
15
|
+
correctAnswer: '2',
|
|
16
|
+
explanation: 'Math basic',
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
it('should render the first question', () => {
|
|
20
|
+
render(_jsx(Quiz, { id: "quiz-1", questions: mockQuestions }));
|
|
21
|
+
expect(screen.getByText('What is 1+1?')).toBeDefined();
|
|
22
|
+
expect(screen.getByText('Question 1 of 1')).toBeDefined();
|
|
23
|
+
});
|
|
24
|
+
it('should allow selecting and submitting an answer', () => {
|
|
25
|
+
const onComplete = vi.fn();
|
|
26
|
+
render(_jsx(Quiz, { id: "quiz-1", questions: mockQuestions, onComplete: onComplete }));
|
|
27
|
+
// Select answer
|
|
28
|
+
const option = screen.getByText('2');
|
|
29
|
+
fireEvent.click(option);
|
|
30
|
+
// Submit
|
|
31
|
+
const submitBtn = screen.getByText('Submit Answer');
|
|
32
|
+
fireEvent.click(submitBtn);
|
|
33
|
+
// The results view is shown immediately for the last question
|
|
34
|
+
expect(onComplete).toHaveBeenCalledWith(expect.objectContaining({
|
|
35
|
+
score: 100,
|
|
36
|
+
passed: true
|
|
37
|
+
}));
|
|
38
|
+
expect(screen.getByText('Congratulations!')).toBeDefined();
|
|
39
|
+
});
|
|
40
|
+
it('should show results on completion', () => {
|
|
41
|
+
render(_jsx(Quiz, { id: "quiz-1", questions: mockQuestions }));
|
|
42
|
+
fireEvent.click(screen.getByText('2'));
|
|
43
|
+
fireEvent.click(screen.getByText('Submit Answer'));
|
|
44
|
+
expect(screen.getByText('Congratulations!')).toBeDefined();
|
|
45
|
+
expect(screen.getByText('100%')).toBeDefined();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=Quiz.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Quiz.test.js","sourceRoot":"","sources":["../../src/components/Quiz.test.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,IAAI,MAAM,QAAQ,CAAC;AAE1B,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;IACpB,MAAM,aAAa,GAAG;QACpB;YACE,EAAE,EAAE,IAAI;YACR,IAAI,EAAE,iBAA0B;YAChC,QAAQ,EAAE,cAAc;YACxB,OAAO,EAAE;gBACP,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE;gBACvB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE;aACxB;YACD,aAAa,EAAE,GAAG;YAClB,WAAW,EAAE,YAAY;SAC1B;KACF,CAAC;IAEF,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,KAAC,IAAI,IAAC,EAAE,EAAC,QAAQ,EAAC,SAAS,EAAE,aAAa,GAAI,CAAC,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,UAAU,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAC,IAAI,IAAC,EAAE,EAAC,QAAQ,EAAC,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,GAAI,CAAC,CAAC;QAE/E,gBAAgB;QAChB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACrC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAExB,SAAS;QACT,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QACpD,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAE3B,8DAA8D;QAC9D,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,gBAAgB,CAAC;YAC9D,KAAK,EAAE,GAAG;YACV,MAAM,EAAE,IAAI;SACb,CAAC,CAAC,CAAC;QACJ,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,KAAC,IAAI,IAAC,EAAE,EAAC,QAAQ,EAAC,SAAS,EAAE,aAAa,GAAI,CAAC,CAAC;QAEvD,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACvC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC;QAEnD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface SearchResult {
|
|
2
|
+
lessonSlug: string;
|
|
3
|
+
lessonTitle: string;
|
|
4
|
+
moduleId?: string;
|
|
5
|
+
moduleTitle?: string;
|
|
6
|
+
excerpt: string;
|
|
7
|
+
score: number;
|
|
8
|
+
}
|
|
9
|
+
export interface SearchProps {
|
|
10
|
+
results: SearchResult[];
|
|
11
|
+
onSearch: (query: string) => void;
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function Search({ results, onSearch, placeholder, className, }: SearchProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export default Search;
|
|
17
|
+
//# sourceMappingURL=Search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Search.d.ts","sourceRoot":"","sources":["../../src/components/Search.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,MAAM,CAAC,EACrB,OAAO,EACP,QAAQ,EACR,WAAyB,EACzB,SAAc,GACf,EAAE,WAAW,2CAqFb;AAsBD,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useCallback } from 'react';
|
|
3
|
+
export function Search({ results, onSearch, placeholder = 'Search...', className = '', }) {
|
|
4
|
+
const [query, setQuery] = useState('');
|
|
5
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
6
|
+
const handleChange = useCallback((e) => {
|
|
7
|
+
const value = e.target.value;
|
|
8
|
+
setQuery(value);
|
|
9
|
+
onSearch(value);
|
|
10
|
+
setIsOpen(value.length > 0);
|
|
11
|
+
}, [onSearch]);
|
|
12
|
+
const handleFocus = () => {
|
|
13
|
+
if (query.length > 0) {
|
|
14
|
+
setIsOpen(true);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const handleBlur = () => {
|
|
18
|
+
setTimeout(() => setIsOpen(false), 200);
|
|
19
|
+
};
|
|
20
|
+
return (_jsxs("div", { className: `relative ${className}`, children: [_jsxs("div", { className: "relative", children: [_jsx("svg", { className: "absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-[rgb(var(--text-muted))]", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }), _jsx("input", { type: "text", value: query, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, placeholder: placeholder, className: "input pl-10 pr-4" }), query && (_jsx("button", { onClick: () => {
|
|
21
|
+
setQuery('');
|
|
22
|
+
onSearch('');
|
|
23
|
+
setIsOpen(false);
|
|
24
|
+
}, className: "absolute right-3 top-1/2 -translate-y-1/2 text-[rgb(var(--text-muted))] hover:text-[rgb(var(--text-secondary))]", children: _jsx("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }))] }), isOpen && results.length > 0 && (_jsx("div", { className: "absolute top-full left-0 right-0 mt-2 bg-[rgb(var(--bg-primary))] border border-[rgb(var(--border-color))] rounded-lg shadow-lg z-50 max-h-80 overflow-y-auto", children: results.map((result) => (_jsx(SearchResultItem, { result: result }, result.lessonSlug))) })), isOpen && query && results.length === 0 && (_jsx("div", { className: "absolute top-full left-0 right-0 mt-2 bg-[rgb(var(--bg-primary))] border border-[rgb(var(--border-color))] rounded-lg shadow-lg p-4 text-center text-[rgb(var(--text-secondary))]", children: "No results found" }))] }));
|
|
25
|
+
}
|
|
26
|
+
function SearchResultItem({ result }) {
|
|
27
|
+
return (_jsxs("a", { href: `#${result.lessonSlug}`, className: "block px-4 py-3 hover:bg-[rgb(var(--bg-tertiary))] transition-colors border-b border-[rgb(var(--border-color))] last:border-b-0", children: [_jsxs("div", { className: "flex items-center gap-2 mb-1", children: [result.moduleTitle && (_jsx("span", { className: "text-xs text-[rgb(var(--text-muted))]", children: result.moduleTitle })), _jsx("span", { className: "text-xs text-[rgb(var(--text-muted))]", children: "/" }), _jsx("span", { className: "text-sm font-medium text-[rgb(var(--text-primary))]", children: result.lessonTitle })] }), _jsx("p", { className: "text-sm text-[rgb(var(--text-secondary))] line-clamp-2", children: result.excerpt })] }));
|
|
28
|
+
}
|
|
29
|
+
export default Search;
|
|
30
|
+
//# sourceMappingURL=Search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Search.js","sourceRoot":"","sources":["../../src/components/Search.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAkB9C,MAAM,UAAU,MAAM,CAAC,EACrB,OAAO,EACP,QAAQ,EACR,WAAW,GAAG,WAAW,EACzB,SAAS,GAAG,EAAE,GACF;IACZ,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE5C,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,CAAsC,EAAE,EAAE;QACzC,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QAC7B,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChB,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChB,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC9B,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAE,YAAY,SAAS,EAAE,aACrC,eAAK,SAAS,EAAC,UAAU,aACvB,cACE,SAAS,EAAC,gFAAgF,EAC1F,IAAI,EAAC,MAAM,EACX,OAAO,EAAC,WAAW,EACnB,MAAM,EAAC,cAAc,YAErB,eACE,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,WAAW,EAAE,CAAC,EACd,CAAC,EAAC,6CAA6C,GAC/C,GACE,EACN,gBACE,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAC,kBAAkB,GAC5B,EACD,KAAK,IAAI,CACR,iBACE,OAAO,EAAE,GAAG,EAAE;4BACZ,QAAQ,CAAC,EAAE,CAAC,CAAC;4BACb,QAAQ,CAAC,EAAE,CAAC,CAAC;4BACb,SAAS,CAAC,KAAK,CAAC,CAAC;wBACnB,CAAC,EACD,SAAS,EAAC,iHAAiH,YAE3H,cAAK,SAAS,EAAC,SAAS,EAAC,IAAI,EAAC,MAAM,EAAC,OAAO,EAAC,WAAW,EAAC,MAAM,EAAC,cAAc,YAC5E,eACE,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,WAAW,EAAE,CAAC,EACd,CAAC,EAAC,sBAAsB,GACxB,GACE,GACC,CACV,IACG,EAEL,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAC/B,cAAK,SAAS,EAAC,+JAA+J,YAC3K,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CACvB,KAAC,gBAAgB,IAAyB,MAAM,EAAE,MAAM,IAAjC,MAAM,CAAC,UAAU,CAAoB,CAC7D,CAAC,GACE,CACP,EAEA,MAAM,IAAI,KAAK,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAC1C,cAAK,SAAS,EAAC,mLAAmL,iCAE5L,CACP,IACG,CACP,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,EAAE,MAAM,EAA4B;IAC5D,OAAO,CACL,aACE,IAAI,EAAE,IAAI,MAAM,CAAC,UAAU,EAAE,EAC7B,SAAS,EAAC,iIAAiI,aAE3I,eAAK,SAAS,EAAC,8BAA8B,aAC1C,MAAM,CAAC,WAAW,IAAI,CACrB,eAAM,SAAS,EAAC,uCAAuC,YAAE,MAAM,CAAC,WAAW,GAAQ,CACpF,EACD,eAAM,SAAS,EAAC,uCAAuC,kBAAS,EAChE,eAAM,SAAS,EAAC,qDAAqD,YAClE,MAAM,CAAC,WAAW,GACd,IACH,EACN,YAAG,SAAS,EAAC,wDAAwD,YAAE,MAAM,CAAC,OAAO,GAAK,IACxF,CACL,CAAC;AACJ,CAAC;AAED,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface VideoEmbedProps {
|
|
2
|
+
provider: 'youtube' | 'vimeo' | 'onedrive' | 'googledrive' | 'custom';
|
|
3
|
+
id?: string;
|
|
4
|
+
url?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
startTime?: number;
|
|
7
|
+
endTime?: number;
|
|
8
|
+
autoplay?: boolean;
|
|
9
|
+
loop?: boolean;
|
|
10
|
+
showControls?: boolean;
|
|
11
|
+
aspectRatio?: '16:9' | '4:3' | '1:1';
|
|
12
|
+
}
|
|
13
|
+
export declare function VideoEmbed({ provider, id, url, title, startTime, endTime, autoplay, loop, showControls, aspectRatio, }: VideoEmbedProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export default VideoEmbed;
|
|
15
|
+
//# sourceMappingURL=VideoEmbed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VideoEmbed.d.ts","sourceRoot":"","sources":["../../src/components/VideoEmbed.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,aAAa,GAAG,QAAQ,CAAC;IACtE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;CACtC;AA8CD,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,EAAE,EACF,GAAG,EACH,KAAK,EACL,SAAS,EACT,OAAO,EACP,QAAgB,EAChB,IAAY,EACZ,YAAmB,EACnB,WAAoB,GACrB,EAAE,eAAe,2CAiFjB;AAED,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
function getYouTubeEmbedUrl(id, startTime, endTime) {
|
|
4
|
+
const params = new URLSearchParams();
|
|
5
|
+
params.set('embed', id);
|
|
6
|
+
params.set('rel', '0');
|
|
7
|
+
params.set('modestbranding', '1');
|
|
8
|
+
if (startTime)
|
|
9
|
+
params.set('start', String(startTime));
|
|
10
|
+
if (endTime)
|
|
11
|
+
params.set('end', String(endTime));
|
|
12
|
+
return `https://www.youtube.com/embed/${id}?${params.toString()}`;
|
|
13
|
+
}
|
|
14
|
+
function getYouTubeId(url) {
|
|
15
|
+
const patterns = [
|
|
16
|
+
/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([^&\n?#]+)/,
|
|
17
|
+
/youtube\.com\/shorts\/([^&\n?#]+)/,
|
|
18
|
+
];
|
|
19
|
+
for (const pattern of patterns) {
|
|
20
|
+
const match = url.match(pattern);
|
|
21
|
+
if (match)
|
|
22
|
+
return match[1];
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
function getVimeoEmbedUrl(id) {
|
|
27
|
+
return `https://player.vimeo.com/video/${id}?dnt=1`;
|
|
28
|
+
}
|
|
29
|
+
function getVimeoId(url) {
|
|
30
|
+
const match = url.match(/vimeo\.com\/(\d+)/);
|
|
31
|
+
return match ? match[1] : null;
|
|
32
|
+
}
|
|
33
|
+
function getOneDriveEmbedUrl(url) {
|
|
34
|
+
const encodedUrl = encodeURIComponent(url);
|
|
35
|
+
return `https://onedrive.live.com/embed?resid=${encodedUrl}`;
|
|
36
|
+
}
|
|
37
|
+
function getGoogleDriveEmbedUrl(url) {
|
|
38
|
+
const match = url.match(/\/file\/d\/([^/]+)/);
|
|
39
|
+
if (match) {
|
|
40
|
+
return `https://drive.google.com/file/d/${match[1]}/preview`;
|
|
41
|
+
}
|
|
42
|
+
return url;
|
|
43
|
+
}
|
|
44
|
+
export function VideoEmbed({ provider, id, url, title, startTime, endTime, autoplay = false, loop = false, showControls = true, aspectRatio = '16:9', }) {
|
|
45
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
46
|
+
const resolvedUrl = (() => {
|
|
47
|
+
if (provider === 'youtube') {
|
|
48
|
+
if (url) {
|
|
49
|
+
const videoId = getYouTubeId(url);
|
|
50
|
+
return videoId ? getYouTubeEmbedUrl(videoId, startTime, endTime) : '';
|
|
51
|
+
}
|
|
52
|
+
return id ? getYouTubeEmbedUrl(id, startTime, endTime) : '';
|
|
53
|
+
}
|
|
54
|
+
if (provider === 'vimeo') {
|
|
55
|
+
if (url) {
|
|
56
|
+
const videoId = getVimeoId(url);
|
|
57
|
+
return videoId ? getVimeoEmbedUrl(videoId) : '';
|
|
58
|
+
}
|
|
59
|
+
return id ? getVimeoEmbedUrl(id) : '';
|
|
60
|
+
}
|
|
61
|
+
if (provider === 'onedrive' && url) {
|
|
62
|
+
return getOneDriveEmbedUrl(url);
|
|
63
|
+
}
|
|
64
|
+
if (provider === 'googledrive' && url) {
|
|
65
|
+
return getGoogleDriveEmbedUrl(url);
|
|
66
|
+
}
|
|
67
|
+
if (provider === 'custom' && url) {
|
|
68
|
+
return url;
|
|
69
|
+
}
|
|
70
|
+
return '';
|
|
71
|
+
})();
|
|
72
|
+
const aspectRatioClass = {
|
|
73
|
+
'16:9': 'aspect-video',
|
|
74
|
+
'4:3': 'aspect-[4/3]',
|
|
75
|
+
'1:1': 'aspect-square',
|
|
76
|
+
}[aspectRatio];
|
|
77
|
+
if (!resolvedUrl) {
|
|
78
|
+
return (_jsx("div", { className: "card my-4 bg-[rgb(var(--error))]/10 border-[rgb(var(--error))]/30", children: _jsx("p", { className: "text-[rgb(var(--error))]", children: "Invalid video URL or ID" }) }));
|
|
79
|
+
}
|
|
80
|
+
return (_jsxs("div", { className: "my-6", children: [title && _jsx("h4", { className: "font-semibold mb-2", children: title }), _jsxs("div", { className: `relative ${aspectRatioClass} rounded-lg overflow-hidden bg-black`, children: [!isLoaded && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-[rgb(var(--bg-tertiary))]", children: _jsx("button", { onClick: () => setIsLoaded(true), className: "w-16 h-16 rounded-full bg-[rgb(var(--color-primary-500))] text-white flex items-center justify-center hover:bg-[rgb(var(--color-primary-600))] transition-colors", "aria-label": "Load video", children: _jsx("svg", { className: "w-8 h-8 ml-1", fill: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { d: "M8 5v14l11-7z" }) }) }) })), (isLoaded || autoplay) && (_jsx("iframe", { src: `${resolvedUrl}${resolvedUrl.includes('?') ? '&' : '?'}autoplay=${autoplay}&loop=${loop}&controls=${showControls}`, title: title || 'Video player', allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture", allowFullScreen: true, className: "absolute inset-0 w-full h-full", onLoad: () => setIsLoaded(true) }))] }), _jsxs("p", { className: "text-xs text-[rgb(var(--text-muted))] mt-2 capitalize", children: [provider === 'youtube' && 'YouTube', provider === 'vimeo' && 'Vimeo', provider === 'onedrive' && 'Microsoft OneDrive', provider === 'googledrive' && 'Google Drive', provider === 'custom' && 'Video'] })] }));
|
|
81
|
+
}
|
|
82
|
+
export default VideoEmbed;
|
|
83
|
+
//# sourceMappingURL=VideoEmbed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VideoEmbed.js","sourceRoot":"","sources":["../../src/components/VideoEmbed.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { Badge, BadgeCard, PointsDisplay, StreakDisplay, GamificationSummary, } from './Gamification';
|
|
2
|
+
export * from './Callout';
|
|
3
|
+
export * from './Paragraph';
|
|
4
|
+
export * from './Quiz';
|
|
5
|
+
export * from './Progress';
|
|
6
|
+
export * from './VideoEmbed';
|
|
7
|
+
export * from './ImageEmbed';
|
|
8
|
+
export * from './Search';
|
|
9
|
+
export * from './LanguageSwitcher';
|
|
10
|
+
export * from './CourseViewer';
|
|
11
|
+
export * from './CatalogViewer';
|
|
12
|
+
export * from './ProfileViewer';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { Badge, BadgeCard, PointsDisplay, StreakDisplay, GamificationSummary, } from './Gamification';
|
|
2
|
+
export * from './Callout';
|
|
3
|
+
export * from './Paragraph';
|
|
4
|
+
export * from './Quiz';
|
|
5
|
+
export * from './Progress';
|
|
6
|
+
export * from './VideoEmbed';
|
|
7
|
+
export * from './ImageEmbed';
|
|
8
|
+
export * from './Search';
|
|
9
|
+
export * from './LanguageSwitcher';
|
|
10
|
+
export * from './CourseViewer';
|
|
11
|
+
export * from './CatalogViewer';
|
|
12
|
+
export * from './ProfileViewer';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|