'use client' import React, { useState, useEffect } from 'react' import { useRouter } from 'next/navigation' import { Plus, Edit, Trash2, Eye, RefreshCw, BookOpen, List, X } from 'lucide-react' interface Course { id: string title: string subject: string description: string difficulty: string mentor: string video_url: string students: number status: 'published' | 'draft' created_at: string } interface Module { id: string course_id: string title: string description: string order: number created_at?: string } interface Lesson { id: string module_id: string title: string description: string video_url: string order: number created_at?: string } export default function AdminDashboard() { const [isClient, setIsClient] = useState(false) const [isAuthenticated, setIsAuthenticated] = useState(false) const [authChecked, setAuthChecked] = useState(false) const [courses, setCourses] = useState([]) const [loading, setLoading] = useState(true) const [showAddForm, setShowAddForm] = useState(false) const [editingCourse, setEditingCourse] = useState(null) // Module/Lesson Management State const [showModulesModal, setShowModulesModal] = useState(false) const [selectedCourse, setSelectedCourse] = useState(null) const [modules, setModules] = useState([]) const [lessons, setLessons] = useState([]) const [modulesLoading, setModulesLoading] = useState(false) const [lessonsLoading, setLessonsLoading] = useState(false) const [errorMessage, setErrorMessage] = useState(null) const [stats, setStats] = useState({ total_courses: 0, total_lessons: 0, active_students: 0, completion_rate: 0 }) const router = useRouter() // Authentication logic useEffect(() => { setIsClient(true) const checkAuth = async () => { try { await new Promise(resolve => setTimeout(resolve, 500)) const token = localStorage.getItem('admin_token') if (!token) { router.push('/admin/login') return } if (token === 'admin-secret-key') { try { const response = await fetch('http://127.0.0.1:5000/api/admin/courses', { headers: { 'Authorization': `Bearer ${token}` } }) if (response.ok) { setIsAuthenticated(true) fetchData() } else { localStorage.removeItem('admin_token') router.push('/admin/login') } } catch (apiError) { setIsAuthenticated(true) fetchData() } } else { localStorage.removeItem('admin_token') router.push('/admin/login') } } catch (error) { router.push('/admin/login') } finally { setAuthChecked(true) } } checkAuth() }, [router]) const fetchData = async () => { await Promise.all([fetchCourses(), fetchStats()]) } const fetchCourses = async () => { try { const response = await fetch('http://127.0.0.1:5000/api/admin/courses', { headers: { 'Authorization': 'Bearer admin-secret-key', 'Content-Type': 'application/json' } }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const data = await response.json() if (Array.isArray(data)) { setCourses(data) } else { setCourses([]) } } catch (error) { setCourses([]) } finally { setLoading(false) } } const fetchStats = async () => { try { const response = await fetch('http://127.0.0.1:5000/api/admin/dashboard', { headers: { 'Authorization': 'Bearer admin-secret-key' } }) if (response.ok) { const data = await response.json() setStats(data) } } catch (error) { // Silent fail for stats } } // ✅ FIXED: Module fetching - the key fix here const fetchModules = async (courseId: string) => { setModulesLoading(true) setErrorMessage(null) try { console.log('🔍 Fetching modules for course:', courseId) // Debug log const response = await fetch(`http://127.0.0.1:5000/api/admin/courses/${courseId}/modules`, { headers: { 'Authorization': 'Bearer admin-secret-key', 'Content-Type': 'application/json' } }) console.log('🔍 Modules response status:', response.status) // Debug log if (response.ok) { const data = await response.json() console.log('🔍 Modules response data:', data) // Debug log // ✅ FIXED: Proper handling of modules response let modulesList: Module[] = [] if (data.modules && Array.isArray(data.modules)) { modulesList = data.modules } else if (Array.isArray(data)) { modulesList = data } else if (data.success && data.data && Array.isArray(data.data)) { modulesList = data.data } console.log('🔍 Setting modules:', modulesList) // Debug log setModules(modulesList) } else { console.error('❌ Failed to fetch modules:', response.status) setModules([]) setErrorMessage(`Failed to load modules: ${response.status}`) } } catch (error) { console.error('❌ Network error fetching modules:', error) setModules([]) setErrorMessage('Network error loading modules') } finally { setModulesLoading(false) } } // ✅ FIXED: Lesson fetching - the key fix here const fetchLessons = async (moduleId: string) => { setLessonsLoading(true) setErrorMessage(null) try { console.log('🔍 Fetching lessons for module:', moduleId) // Debug log const response = await fetch(`http://127.0.0.1:5000/api/admin/modules/${moduleId}/lessons`, { headers: { 'Authorization': 'Bearer admin-secret-key', 'Content-Type': 'application/json' } }) console.log('🔍 Lessons response status:', response.status) // Debug log if (response.ok) { const data = await response.json() console.log('🔍 Lessons response data:', data) // Debug log // ✅ FIXED: Proper handling of lessons response let lessonsList: Lesson[] = [] if (data.lessons && Array.isArray(data.lessons)) { lessonsList = data.lessons } else if (Array.isArray(data)) { lessonsList = data } else if (data.success && data.data && Array.isArray(data.data)) { lessonsList = data.data } console.log('🔍 Setting lessons:', lessonsList) // Debug log setLessons(lessonsList) } else { console.error('❌ Failed to fetch lessons:', response.status) setLessons([]) setErrorMessage(`Failed to load lessons: ${response.status}`) } } catch (error) { console.error('❌ Network error fetching lessons:', error) setLessons([]) setErrorMessage('Network error loading lessons') } finally { setLessonsLoading(false) } } // Course CRUD operations const handleCreateCourse = async (formData: any) => { try { const response = await fetch('http://127.0.0.1:5000/api/admin/courses', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer admin-secret-key' }, body: JSON.stringify(formData) }) if (response.ok) { await fetchData() setShowAddForm(false) alert('Course created successfully!') } else { const error = await response.json() alert(`Error: ${error.error || 'Failed to create course'}`) } } catch (error) { alert('Failed to create course') } } const handleUpdateCourse = async (courseId: string, formData: any) => { try { const response = await fetch(`http://127.0.0.1:5000/api/admin/courses/${courseId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer admin-secret-key' }, body: JSON.stringify(formData) }) if (response.ok) { await fetchData() setEditingCourse(null) alert('Course updated successfully!') } else { alert('Failed to update course') } } catch (error) { alert('Failed to update course') } } const handleDeleteCourse = async (courseId: string) => { if (confirm('Are you sure you want to delete this course?')) { try { const response = await fetch(`http://127.0.0.1:5000/api/admin/courses/${courseId}`, { method: 'DELETE', headers: { 'Authorization': 'Bearer admin-secret-key' } }) if (response.ok) { await fetchData() alert('Course deleted successfully!') } else { alert('Failed to delete course') } } catch (error) { alert('Failed to delete course') } } } // Module/Lesson Management const openModulesManager = async (course: Course) => { console.log('🔍 Opening modules manager for course:', course.id) setSelectedCourse(course) setShowModulesModal(true) setModules([]) setLessons([]) setErrorMessage(null) await fetchModules(course.id) } const handleCreateModule = async (formData: any) => { try { console.log('🔍 Creating module with data:', formData) const response = await fetch(`http://127.0.0.1:5000/api/admin/courses/${selectedCourse?.id}/modules`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer admin-secret-key' }, body: JSON.stringify(formData) }) if (response.ok) { await fetchModules(selectedCourse!.id) alert('Module created successfully!') } else { const error = await response.json() alert(`Error: ${error.error || 'Failed to create module'}`) } } catch (error) { alert('Failed to create module') } } const handleCreateLesson = async (moduleId: string, formData: any) => { try { console.log('🔍 Creating lesson for module:', moduleId, 'with data:', formData) const response = await fetch(`http://127.0.0.1:5000/api/admin/modules/${moduleId}/lessons`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer admin-secret-key' }, body: JSON.stringify(formData) }) if (response.ok) { await fetchLessons(moduleId) alert('Lesson created successfully!') } else { const error = await response.json() alert(`Error: ${error.error || 'Failed to create lesson'}`) } } catch (error) { alert('Failed to create lesson') } } const handleLogout = () => { localStorage.removeItem('admin_token') router.push('/') } if (!isClient || !authChecked) { return (

Checking authentication...

) } if (!isAuthenticated) { return (

Redirecting to login...

) } return (
{/* Header */}
OL

OpenLearnX Admin Panel

DYNAMIC
Welcome, Admin! 👋
{/* Error Display */} {errorMessage && (
{errorMessage}
)} {/* Action Buttons */}

Course Management

Manage courses, modules, and lessons

{/* Stats Cards */}

Total Courses

{stats.total_courses}

Active Students

{stats.active_students}

Total Lessons

{stats.total_lessons}

Completion Rate

{stats.completion_rate}%

{/* Course Table */}

All Courses

{loading ? (

Loading courses...

) : courses.length === 0 ? (

No courses found.

) : (
{courses.map((course) => ( ))}
Course Mentor Students Actions
{course.title}
{course.subject} • {course.difficulty}
{course.mentor} {course.students?.toLocaleString() || 0}
)}
{/* Course Form Modal */} {showAddForm && ( setShowAddForm(false)} onSubmit={handleCreateCourse} /> )} {editingCourse && ( setEditingCourse(null)} onSubmit={(data) => handleUpdateCourse(editingCourse.id, data)} /> )} {/* ✅ FIXED: Modules & Lessons Modal */} {showModulesModal && selectedCourse && ( { setShowModulesModal(false) setSelectedCourse(null) setModules([]) setLessons([]) setErrorMessage(null) }} onCreateModule={handleCreateModule} onCreateLesson={handleCreateLesson} onFetchLessons={fetchLessons} onRefreshModules={() => fetchModules(selectedCourse.id)} /> )}
) } // ✅ FIXED: Enhanced Modules & Lessons Modal with better debugging function ModulesLessonsModal({ course, modules, lessons, modulesLoading, lessonsLoading, onClose, onCreateModule, onCreateLesson, onFetchLessons, onRefreshModules }: { course: Course modules: Module[] lessons: Lesson[] modulesLoading: boolean lessonsLoading: boolean onClose: () => void onCreateModule: (data: any) => void onCreateLesson: (moduleId: string, data: any) => void onFetchLessons: (moduleId: string) => void onRefreshModules: () => void }) { const [activeTab, setActiveTab] = useState<'modules' | 'lessons'>('modules') const [showModuleForm, setShowModuleForm] = useState(false) const [showLessonForm, setShowLessonForm] = useState(false) const [selectedModuleId, setSelectedModuleId] = useState(null) const [moduleFormData, setModuleFormData] = useState({ title: '', description: '', order: 1 }) const [lessonFormData, setLessonFormData] = useState({ title: '', description: '', video_url: '', order: 1 }) const handleModuleSubmit = (e: React.FormEvent) => { e.preventDefault() onCreateModule(moduleFormData) setModuleFormData({ title: '', description: '', order: 1 }) setShowModuleForm(false) } const handleLessonSubmit = (e: React.FormEvent) => { e.preventDefault() console.log('🔍 Creating lesson for module ID:', selectedModuleId) // Debug log console.log('🔍 Lesson form data:', lessonFormData) // Debug log if (selectedModuleId) { onCreateLesson(selectedModuleId, lessonFormData) setLessonFormData({ title: '', description: '', video_url: '', order: 1 }) setShowLessonForm(false) } } // ✅ FIXED: Enhanced module selection with better debugging const handleSelectModule = (moduleId: string) => { console.log('🔍 Selecting module with ID:', moduleId) // Debug log console.log('🔍 Available modules:', modules) // Debug log setSelectedModuleId(moduleId) onFetchLessons(moduleId) setActiveTab('lessons') } return (

Manage: {course.title}

{/* Tab Navigation */}
{/* ✅ DEBUG INFO - Remove after fixing */}

Debug Info:

Selected Module ID: {selectedModuleId || 'None'}

Modules Count: {modules.length}

Lessons Count: {lessons.length}

Active Tab: {activeTab}

{/* Modules Tab */} {activeTab === 'modules' && (

Course Modules

{modulesLoading ? (

Loading modules...

) : modules.length === 0 ? (

No modules found for this course.

Click "Add Module" to create your first module.

) : (
{modules.map((module, index) => (
{module.title}

{module.description}

Order: {module.order} | ID: {module.id}

))}
)} {/* Module Form */} {showModuleForm && (
Add New Module
setModuleFormData({...moduleFormData, title: e.target.value})} className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="e.g., Introduction to Python" />