import React, { useState, useEffect, useMemo } from 'react';
import { initializeApp } from 'firebase/app';
import {
getAuth,
signInAnonymously,
signInWithCustomToken,
onAuthStateChanged,
signOut
} from 'firebase/auth';
import {
getFirestore,
doc,
setDoc,
getDoc,
onSnapshot,
collection,
updateDoc,
addDoc,
query,
where
} from 'firebase/firestore';
import {
BookOpen,
CheckCircle,
PlayCircle,
Award,
LogOut,
User,
ChevronRight,
Clock,
FileText,
Layout,
GraduationCap,
PlusCircle,
Settings,
Trash2,
Save,
Send,
Users
} from 'lucide-react';
// --- Firebase Configuration ---
const firebaseConfig = JSON.parse(__firebase_config);
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
const appId = typeof __app_id !== 'undefined' ? __app_id : 'lms-pro-system';
// --- Default Seed Data ---
const DEFAULT_COURSES = [
{
id: 'default-1',
title: 'Modern Leadership Essentials',
instructor: 'Dr. Sarah Jenkins',
description: 'Master the fundamental shifts in leadership required for the digital age.',
modules: [
{ id: 'm1', title: 'The Evolving Role of a Leader', type: 'video', duration: '12:00', content: 'Leadership has transitioned from "command and control" to "empower and enable".' },
{ id: 'm2', title: 'Emotional Intelligence', type: 'reading', duration: '15:00', content: 'Analysis of the five components of EQ.' },
{ id: 'm3', title: 'Quick Quiz', type: 'quiz', questions: [{ q: 'Key shift?', options: ['Hierarchy', 'Empowerment'], correct: 1 }] }
]
}
];
// --- Sub-Components ---
const Sidebar = ({ activeTab, setActiveTab, user, role, setRole }) => (
<div className="w-64 bg-slate-900 h-screen fixed left-0 top-0 text-white p-6 flex flex-col z-20">
<div className="flex items-center gap-3 mb-10">
<GraduationCap className="text-blue-400 w-8 h-8" />
<h1 className="text-xl font-bold tracking-tight">Lumina LMS</h1>
</div>
<nav className="flex-1 space-y-2">
<div className="pb-4 mb-4 border-b border-slate-800">
<p className="text-[10px] uppercase font-bold text-slate-500 mb-2 px-3 tracking-widest">Navigation</p>
<button
onClick={() => setActiveTab('dashboard')}
className={`w-full flex items-center gap-3 p-3 rounded-lg transition-colors ${activeTab === 'dashboard' ? 'bg-blue-600' : 'hover:bg-slate-800'}`}
>
<Layout size={18} /> Dashboard
</button>
<button
onClick={() => setActiveTab('courses')}
className={`w-full flex items-center gap-3 p-3 rounded-lg transition-colors ${activeTab === 'courses' ? 'bg-blue-600' : 'hover:bg-slate-800'}`}
>
<BookOpen size={18} /> {role === 'tutor' ? 'My Content' : 'My Learning'}
</button>
</div>
{role === 'tutor' && (
<div>
<p className="text-[10px] uppercase font-bold text-slate-500 mb-2 px-3 tracking-widest">Tutor Tools</p>
<button
onClick={() => setActiveTab('create')}
className={`w-full flex items-center gap-3 p-3 rounded-lg transition-colors ${activeTab === 'create' ? 'bg-blue-600' : 'hover:bg-slate-800'}`}
>
<PlusCircle size={18} /> Create Course
</button>
</div>
)}
</nav>
<div className="pt-6 border-t border-slate-800 space-y-4">
<div className="px-3">
<button
onClick={() => setRole(role === 'student' ? 'tutor' : 'student')}
className="w-full text-xs bg-slate-800 border border-slate-700 p-2 rounded flex items-center justify-between hover:bg-slate-700 transition-colors"
>
<span className="capitalize">{role} Mode</span>
<Settings size={14} className="text-slate-400" />
</button>
</div>
<div className="flex items-center gap-3 p-3">
<div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-xs font-bold shrink-0">
{user?.uid?.substring(0, 2).toUpperCase()}
</div>
<div className="overflow-hidden">
<p className="text-[10px] text-slate-400 truncate">User: {user?.uid}</p>
</div>
</div>
<button
onClick={() => signOut(auth)}
className="w-full flex items-center gap-3 p-3 rounded-lg hover:bg-red-900/30 text-red-400 transition-colors text-sm"
>
<LogOut size={18} /> Sign Out
</button>
</div>
</div>
);
const CourseEditor = ({ onSave, onCancel }) => {
const [course, setCourse] = useState({
title: '',
instructor: '',
description: '',
modules: []
});
const addModule = (type) => {
const newMod = {
id: 'mod-' + Date.now(),
title: 'New Module',
type,
content: '',
duration: '10:00',
questions: type === 'quiz' || type === 'exam' ? [{ q: '', options: ['', ''], correct: 0 }] : []
};
setCourse(prev => ({ ...prev, modules: [...prev.modules, newMod] }));
};
const updateModule = (idx, data) => {
const newModules = [...course.modules];
newModules[idx] = { ...newModules[idx], ...data };
setCourse(prev => ({ ...prev, modules: newModules }));
};
const removeModule = (idx) => {
setCourse(prev => ({ ...prev, modules: prev.modules.filter((_, i) => i !== idx) }));
};
return (
<div className="max-w-4xl mx-auto space-y-8 pb-20">
<div className="bg-white p-8 rounded-2xl border border-slate-200 shadow-sm">
<h2 className="text-2xl font-bold text-slate-900 mb-6">Course Framework</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<label className="text-xs font-bold uppercase text-slate-500">Course Title</label>
<input
className="w-full p-3 rounded-xl border border-slate-200 focus:ring-2 focus:ring-blue-500 outline-none"
placeholder="e.g. Strategic Talent Management"
value={course.title}
onChange={e => setCourse({...course, title: e.target.value})}
/>
</div>
<div className="space-y-2">
<label className="text-xs font-bold uppercase text-slate-500">Instructor Name</label>
<input
className="w-full p-3 rounded-xl border border-slate-200 focus:ring-2 focus:ring-blue-500 outline-none"
placeholder="Your name"
value={course.instructor}
onChange={e => setCourse({...course, instructor: e.target.value})}
/>
</div>
<div className="md:col-span-2 space-y-2">
<label className="text-xs font-bold uppercase text-slate-500">Learning Objectives</label>
<textarea
className="w-full p-3 rounded-xl border border-slate-200 h-24 focus:ring-2 focus:ring-blue-500 outline-none"
placeholder="What will the students achieve?"
value={course.description}
onChange={e => setCourse({...course, description: e.target.value})}
/>
</div>
</div>
</div>
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-xl font-bold text-slate-800">Syllabus & Modules</h3>
<div className="flex gap-2">
<button onClick={() => addModule('reading')} className="text-xs bg-slate-100 px-3 py-2 rounded-lg font-bold hover:bg-slate-200 flex items-center gap-1">
<PlusCircle size={14} /> Add Reading
</button>
<button onClick={() => addModule('video')} className="text-xs bg-slate-100 px-3 py-2 rounded-lg font-bold hover:bg-slate-200 flex items-center gap-1">
<PlayCircle size={14} /> Add Video
</button>
<button onClick={() => addModule('quiz')} className="text-xs bg-slate-100 px-3 py-2 rounded-lg font-bold hover:bg-slate-200 flex items-center gap-1">
<FileText size={14} /> Add Quiz
</button>
</div>
</div>
{course.modules.length === 0 && (
<div className="text-center p-12 border-2 border-dashed border-slate-200 rounded-2xl text-slate-400">
No modules added yet. Select a content type above to begin building your curriculum.
</div>
)}
{course.modules.map((mod, idx) => (
<div key={mod.id} className="bg-white border border-slate-200 rounded-2xl overflow-hidden shadow-sm">
<div className="bg-slate-50 p-4 border-b border-slate-200 flex justify-between items-center">
<div className="flex items-center gap-3">
<span className="bg-blue-600 text-white w-6 h-6 flex items-center justify-center rounded-full text-xs font-bold">{idx + 1}</span>
<input
className="bg-transparent font-bold text-slate-800 border-none focus:ring-0 p-0"
value={mod.title}
onChange={e => updateModule(idx, { title: e.target.value })}
/>
</div>
<button onClick={() => removeModule(idx)} className="text-red-400 hover:text-red-600">
<Trash2 size={18} />
</button>
</div>
<div className="p-6">
{mod.type === 'quiz' ? (
<div className="space-y-4">
<p className="text-xs font-bold text-slate-400 uppercase">Assessment Settings</p>
{mod.questions.map((q, qIdx) => (
<div key={qIdx} className="space-y-3 p-4 bg-slate-50 rounded-xl border border-slate-100">
<input
className="w-full p-2 rounded-lg border border-slate-200 text-sm"
placeholder="Question text..."
value={q.q}
onChange={e => {
const newQ = [...mod.questions];
newQ[qIdx].q = e.target.value;
updateModule(idx, { questions: newQ });
}}
/>
<div className="grid grid-cols-2 gap-2">
{q.options.map((opt, oIdx) => (
<div key={oIdx} className="flex gap-2 items-center">
<input type="radio" checked={q.correct === oIdx} onChange={() => {
const newQ = [...mod.questions];
newQ[qIdx].correct = oIdx;
updateModule(idx, { questions: newQ });
}} />
<input
className="flex-1 p-2 text-xs border border-slate-200 rounded"
value={opt}
placeholder={`Option ${oIdx + 1}`}
onChange={e => {
const newQ = [...mod.questions];
newQ[qIdx].options[oIdx] = e.target.value;
updateModule(idx, { questions: newQ });
}}
/>
</div>
))}
</div>
</div>
))}
</div>
) : (
<div className="space-y-4">
<div className="flex gap-4">
<div className="flex-1 space-y-2">
<label className="text-[10px] font-bold text-slate-400 uppercase">Est. Duration</label>
<input
className="w-full p-2 border border-slate-200 rounded-lg text-sm"
value={mod.duration}
onChange={e => updateModule(idx, { duration: e.target.value })}
/>
</div>
</div>
<div className="space-y-2">
<label className="text-[10px] font-bold text-slate-400 uppercase">Body Content</label>
<textarea
className="w-full p-3 border border-slate-200 rounded-lg h-32 text-sm"
placeholder="Add instructional text or video URL..."
value={mod.content}
onChange={e => updateModule(idx, { content: e.target.value })}
/>
</div>
</div>
)}
</div>
</div>
))}
</div>
<div className="flex justify-end gap-4">
<button onClick={onCancel} className="px-6 py-3 rounded-xl font-bold text-slate-600 hover:bg-slate-100 transition-colors">
Discard Draft
</button>
<button
onClick={() => onSave(course)}
disabled={!course.title || course.modules.length === 0}
className="bg-blue-600 text-white px-8 py-3 rounded-xl font-bold hover:bg-blue-700 transition-all flex items-center gap-2 shadow-lg disabled:opacity-50"
>
<Send size={18} /> Publish Course
</button>
</div>
</div>
);
};
// --- Main App ---
export default function App() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [activeTab, setActiveTab] = useState('dashboard');
const [activeCourse, setActiveCourse] = useState(null);
const [role, setRole] = useState('student'); // 'student' or 'tutor'
// Data State
const [allCourses, setAllCourses] = useState([]);
const [progressData, setProgressData] = useState({});
useEffect(() => {
const initAuth = async () => {
try {
if (typeof __initial_auth_token !== 'undefined' && __initial_auth_token) {
await signInWithCustomToken(auth, __initial_auth_token);
} else {
await signInAnonymously(auth);
}
} catch (error) {
console.error("Auth error:", error);
}
};
initAuth();
const unsubscribe = onAuthStateChanged(auth, (u) => {
setUser(u);
setLoading(false);
});
return () => unsubscribe();
}, []);
useEffect(() => {
if (!user) return;
// Sync Courses from Public Data
const coursesRef = collection(db, 'artifacts', appId, 'public', 'data', 'courses');
const unsubCourses = onSnapshot(coursesRef, (snapshot) => {
const courses = [];
snapshot.forEach(doc => courses.push({ id: doc.id, ...doc.data() }));
setAllCourses(courses.length > 0 ? courses : DEFAULT_COURSES);
}, (err) => console.error("Course fetch error:", err));
// Sync User Progress
const progressRef = collection(db, 'artifacts', appId, 'users', user.uid, 'progress');
const unsubProgress = onSnapshot(progressRef, (snapshot) => {
const data = {};
snapshot.forEach(doc => data[doc.id] = doc.data());
setProgressData(data);
});
return () => {
unsubCourses();
unsubProgress();
};
}, [user]);
const publishCourse = async (courseData) => {
if (!user) return;
try {
const coursesRef = collection(db, 'artifacts', appId, 'public', 'data', 'courses');
await addDoc(coursesRef, {
...courseData,
tutorId: user.uid,
createdAt: Date.now(),
status: 'published'
});
setActiveTab('courses');
} catch (err) {
console.error("Error publishing course:", err);
}
};
const handleCompleteModule = async (courseId, moduleId) => {
if (!user) return;
const courseProgress = progressData[courseId] || { completedModules: [], lastAccessed: Date.now() };
if (!courseProgress.completedModules.includes(moduleId)) {
const updatedModules = [...courseProgress.completedModules, moduleId];
const docRef = doc(db, 'artifacts', appId, 'users', user.uid, 'progress', courseId);
await setDoc(docRef, {
completedModules: updatedModules,
lastAccessed: Date.now(),
lastModuleId: moduleId
}, { merge: true });
}
};
if (loading) {
return (
<div className="h-screen w-full flex items-center justify-center bg-slate-50">
<div className="flex flex-col items-center gap-4 text-center">
<div className="w-12 h-12 border-4 border-blue-600 border-t-transparent rounded-full animate-spin"></div>
<p className="font-bold text-slate-600">Lumina Academy<br/><span className="text-sm font-normal opacity-70">Synchronising with Learning Cloud...</span></p>
</div>
</div>
);
}
// Course Player takes over full screen
if (activeCourse) {
return (
<CoursePlayer
course={activeCourse}
userProgress={progressData[activeCourse.id]}
onCompleteModule={handleCompleteModule}
onBack={() => setActiveCourse(null)}
/>
);
}
return (
<div className="min-h-screen bg-slate-50 flex">
<Sidebar
activeTab={activeTab}
setActiveTab={setActiveTab}
user={user}
role={role}
setRole={setRole}
/>
<main className="ml-64 flex-1 p-10">
<header className="mb-10 flex justify-between items-center">
<div>
<h2 className="text-3xl font-extrabold text-slate-900 tracking-tight">
{role === 'tutor' ? 'Tutor Management Console' : 'Student Resource Centre'}
</h2>
<p className="text-slate-500 mt-1">
{role === 'tutor' ? 'Develop and curate world-class educational material.' : 'Pick up where you left off or discover new modules.'}
</p>
</div>
<div className="bg-white border border-slate-200 rounded-2xl p-4 flex gap-6 shadow-sm">
<div className="text-center px-2">
<p className="text-[10px] uppercase font-bold text-slate-400 mb-1">Courses</p>
<p className="text-xl font-black text-slate-800">{allCourses.length}</p>
</div>
<div className="w-px bg-slate-100 my-2"></div>
<div className="text-center px-2">
<p className="text-[10px] uppercase font-bold text-slate-400 mb-1">Students</p>
<p className="text-xl font-black text-slate-800">1,248</p>
</div>
</div>
</header>
{activeTab === 'create' && role === 'tutor' ? (
<CourseEditor onSave={publishCourse} onCancel={() => setActiveTab('dashboard')} />
) : activeTab === 'courses' ? (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{allCourses.map(c => (
<CourseCard key={c.id} course={c} progress={progressData[c.id]} onSelect={setActiveCourse} />
))}
</div>
) : (
<div className="space-y-12">
<section className="bg-gradient-to-r from-blue-700 to-indigo-800 rounded-[2rem] p-10 text-white relative overflow-hidden shadow-2xl shadow-blue-200">
<div className="relative z-10 max-w-xl">
<div className="bg-white/20 w-fit px-3 py-1 rounded-full text-[10px] font-bold uppercase tracking-widest mb-4">Lumina Insights</div>
<h3 className="text-3xl font-bold mb-3">Mastering the Remote Workplace</h3>
<p className="text-blue-100 mb-8 leading-relaxed">Our latest high-impact module for 2026 is now live. Learn the psychology of digital collaboration and workflow management.</p>
<div className="flex gap-4">
<button className="bg-white text-blue-800 px-6 py-3 rounded-xl font-bold hover:bg-blue-50 transition-colors shadow-lg">Enrol Now</button>
<button className="bg-white/10 text-white px-6 py-3 rounded-xl font-bold hover:bg-white/20 transition-colors border border-white/30 backdrop-blur-sm">View Curriculum</button>
</div>
</div>
<Users size={180} className="text-white/5 absolute -right-10 -bottom-10" />
</section>
<section>
<div className="flex items-center justify-between mb-6">
<div className="flex items-center gap-2">
<Clock size={20} className="text-blue-500" />
<h3 className="text-xl font-bold text-slate-800">Available Learning Pathways</h3>
</div>
<button className="text-sm font-bold text-blue-600 hover:underline">View All</button>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{allCourses.map(c => (
<CourseCard key={c.id} course={c} progress={progressData[c.id]} onSelect={setActiveCourse} />
))}
</div>
</section>
</div>
)}
</main>
</div>
);
}
// Reuse the previously defined CourseCard and CoursePlayer with minor tweaks for dynamic IDs
const CourseCard = ({ course, progress, onSelect }) => {
const percent = progress ? Math.round((progress.completedModules?.length / course.modules.length) * 100) : 0;
return (
<div className="bg-white border border-slate-200 rounded-2xl overflow-hidden shadow-sm hover:shadow-xl transition-all group cursor-pointer" onClick={() => onSelect(course)}>
<div className="h-40 bg-slate-900 p-6 relative">
<div className="absolute inset-0 bg-gradient-to-br from-blue-600/40 to-indigo-900/80 mix-blend-overlay"></div>
<div className="relative z-10">
<span className="bg-white/20 text-white text-[10px] font-bold uppercase tracking-wider px-2 py-1 rounded backdrop-blur-md">Professional Series</span>
<h3 className="font-black text-white text-xl mt-4 leading-tight group-hover:translate-x-1 transition-transform">{course.title}</h3>
</div>
</div>
<div className="p-6">
<div className="flex items-center gap-2 mb-4">
<div className="w-6 h-6 bg-slate-100 rounded-full flex items-center justify-center text-[10px] font-bold">{course.instructor?.substring(0, 1)}</div>
<p className="text-xs font-bold text-slate-500 uppercase tracking-tighter">{course.instructor}</p>
</div>
<div className="w-full bg-slate-100 h-2 rounded-full mb-3 overflow-hidden">
<div className="bg-blue-600 h-2 rounded-full transition-all duration-700 ease-out" style={{ width: `${percent}%` }}></div>
</div>
<div className="flex justify-between items-center text-[10px] font-bold text-slate-400 uppercase">
<span className="flex items-center gap-1"><BookOpen size={12} /> {course.modules.length} Modules</span>
<span className={percent === 100 ? 'text-green-500' : ''}>{percent}% Progress</span>
</div>
</div>
</div>
);
};
const CoursePlayer = ({ course, userProgress, onCompleteModule, onBack }) => {
const [currentModuleIdx, setCurrentModuleIdx] = useState(0);
const [quizState, setQuizState] = useState({ answers: {}, submitted: false, score: null });
const currentModule = course.modules[currentModuleIdx];
const isCompleted = userProgress?.completedModules?.includes(currentModule.id);
const handleNext = () => {
if (currentModuleIdx < course.modules.length - 1) {
setCurrentModuleIdx(prev => prev + 1);
setQuizState({ answers: {}, submitted: false, score: null });
}
};
const handlePrev = () => {
if (currentModuleIdx > 0) {
setCurrentModuleIdx(prev => prev - 1);
setQuizState({ answers: {}, submitted: false, score: null });
}
};
const submitQuiz = () => {
let score = 0;
currentModule.questions.forEach((q, idx) => {
if (quizState.answers[idx] === q.correct) score++;
});
setQuizState(prev => ({ ...prev, submitted: true, score }));
if (score === currentModule.questions.length) onCompleteModule(course.id, currentModule.id);
};
return (
<div className="flex flex-col h-screen bg-slate-50">
<header className="bg-white border-b border-slate-200 p-4 flex justify-between items-center px-10 z-10 shadow-sm">
<button onClick={onBack} className="flex items-center text-slate-600 hover:text-slate-900 font-bold transition-colors">
<ChevronRight className="rotate-180 mr-2" size={20} /> Exit Player
</button>
<div className="text-center">
<h2 className="font-black text-slate-800 tracking-tight">{course.title}</h2>
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{currentModule.title}</p>
</div>
<div className="bg-slate-50 px-4 py-2 rounded-full border border-slate-100 flex items-center gap-2">
<Award className="text-amber-500" size={18} />
<span className="text-sm font-bold">{userProgress?.completedModules?.length || 0} / {course.modules.length}</span>
</div>
</header>
<div className="flex flex-1 overflow-hidden">
<div className="flex-1 overflow-y-auto p-12">
<div className="max-w-4xl mx-auto">
{currentModule.type === 'video' && (
<div className="aspect-video bg-slate-900 rounded-[2rem] flex items-center justify-center text-white flex-col gap-6 mb-10 shadow-2xl relative overflow-hidden group">
<PlayCircle size={80} className="text-blue-400 opacity-60 group-hover:scale-110 transition-transform duration-500" />
<div className="absolute bottom-0 left-0 right-0 p-8 bg-gradient-to-t from-black/80 to-transparent">
<p className="font-bold">Streaming: {currentModule.title}</p>
</div>
</div>
)}
<div className="bg-white p-10 rounded-[2.5rem] border border-slate-200 shadow-xl shadow-slate-100 min-h-[400px]">
{currentModule.type === 'quiz' || currentModule.type === 'exam' ? (
<div className="space-y-10">
<div className="border-b border-slate-100 pb-6">
<h1 className="text-3xl font-black text-slate-900">Module Assessment</h1>
<p className="text-slate-500 mt-2">Demonstrate your understanding of the preceding concepts.</p>
</div>
{currentModule.questions.map((q, idx) => (
<div key={idx} className="space-y-6">
<p className="font-bold text-xl text-slate-800">Q{idx + 1}. {q.q}</p>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{q.options.map((opt, oIdx) => (
<button
key={oIdx}
disabled={quizState.submitted}
onClick={() => setQuizState(prev => ({ ...prev, answers: { ...prev.answers, [idx]: oIdx } }))}
className={`w-full text-left p-6 rounded-2xl border-2 transition-all font-bold ${
quizState.answers[idx] === oIdx
? 'border-blue-600 bg-blue-50 text-blue-700'
: 'border-slate-100 hover:border-slate-200 text-slate-600'
}`}
>
{opt}
</button>
))}
</div>
</div>
))}
{!quizState.submitted ? (
<button
onClick={submitQuiz}
className="bg-slate-900 text-white px-10 py-4 rounded-2xl font-bold hover:bg-black transition-all shadow-lg active:scale-95"
>
Verify Answers
</button>
) : (
<div className={`p-8 rounded-[2rem] border-2 ${quizState.score === currentModule.questions.length ? 'bg-green-50 border-green-100 text-green-800' : 'bg-red-50 border-red-100 text-red-800'}`}>
<div className="flex items-center gap-4 mb-3">
{quizState.score === currentModule.questions.length ? <CheckCircle size={32} /> : <FileText size={32} />}
<p className="font-black text-2xl">
{quizState.score === currentModule.questions.length ? 'Perfect Score!' : 'Room for Improvement'}
</p>
</div>
<p className="text-lg opacity-80">You correctly identified {quizState.score} of {currentModule.questions.length} critical points.</p>
</div>
)}
</div>
) : (
<div className="space-y-8">
<div className="flex justify-between items-start">
<h1 className="text-4xl font-black text-slate-900 leading-tight">{currentModule.title}</h1>
<span className="text-[10px] font-bold text-slate-400 bg-slate-50 px-3 py-1 rounded-full uppercase tracking-widest">{currentModule.duration}</span>
</div>
<div className="prose prose-slate prose-lg max-w-none text-slate-700 leading-relaxed">
{currentModule.content.split('\n').map((para, i) => <p key={i} className="mb-6">{para}</p>)}
</div>
<div className="mt-12 pt-8 border-t border-slate-100 flex justify-center">
<button
onClick={() => onCompleteModule(course.id, currentModule.id)}
disabled={isCompleted}
className={`flex items-center gap-3 px-10 py-5 rounded-2xl font-black transition-all shadow-xl active:scale-95 ${isCompleted ? 'bg-green-100 text-green-700 border-2 border-green-200' : 'bg-blue-600 text-white hover:bg-blue-700 shadow-blue-200'}`}
>
{isCompleted ? <><CheckCircle size={24} /> Module Certified</> : 'Complete Learning'}
</button>
</div>
</div>
)}
</div>
<div className="flex justify-between mt-12 pb-24 px-4">
<button onClick={handlePrev} disabled={currentModuleIdx === 0} className="text-slate-400 font-black flex items-center hover:text-slate-900 disabled:opacity-0 transition-colors">
<ChevronRight className="rotate-180 mr-2" size={24} /> PREVIOUS MODULE
</button>
<button onClick={handleNext} disabled={currentModuleIdx === course.modules.length - 1} className="text-slate-400 font-black flex items-center hover:text-slate-900 disabled:opacity-0 transition-colors">
NEXT MODULE <ChevronRight className="ml-2" size={24} />
</button>
</div>
</div>
</div>
<div className="w-96 bg-white border-l border-slate-200 overflow-y-auto hidden xl:block shadow-[-10px_0_30px_rgba(0,0,0,0.02)]">
<div className="p-8">
<h3 className="font-black text-slate-900 text-lg mb-6 tracking-tight uppercase border-b pb-4 border-slate-100">Programme Structure</h3>
<div className="space-y-3">
{course.modules.map((mod, idx) => (
<button
key={mod.id}
onClick={() => setCurrentModuleIdx(idx)}
className={`w-full text-left p-4 rounded-2xl flex items-start gap-4 transition-all duration-300 ${currentModuleIdx === idx ? 'bg-blue-600 text-white shadow-xl shadow-blue-100 -translate-x-2' : 'hover:bg-slate-50 text-slate-500'}`}
>
<div className="mt-1 shrink-0">
{userProgress?.completedModules?.includes(mod.id) ? (
<CheckCircle size={20} className={currentModuleIdx === idx ? 'text-white' : 'text-green-500'} />
) : mod.type === 'video' ? (
<PlayCircle size={20} />
) : mod.type === 'quiz' ? (
<FileText size={20} />
) : (
<BookOpen size={20} />
)}
</div>
<div>
<p className={`text-sm font-bold leading-tight ${currentModuleIdx === idx ? 'text-white' : 'text-slate-700'}`}>{mod.title}</p>
<span className={`text-[10px] uppercase font-black tracking-widest ${currentModuleIdx === idx ? 'text-blue-100' : 'text-slate-400'}`}>{mod.duration || 'Assessment'}</span>
</div>
</button>
))}
</div>
</div>
</div>
</div>
</div>
);
};