import { useEffect, useState, useRef } from "react" import { Link, useParams, useNavigate } from "react-router-dom" import { ArrowLeft, ToggleLeft, ToggleRight, MoreVertical, X, Trash2, AlertCircle, Edit } from "lucide-react" import practiceSrc from "../../assets/Practice.svg" import spinnerSrc from "../../assets/Circular-indeterminate progress indicator.svg" import { Card, CardContent } from "../../components/ui/card" import alertSrc from "../../assets/Alert.svg" import { Badge } from "../../components/ui/badge" import { Button } from "../../components/ui/button" import { getSubCoursesByCourse, getCoursesByCategory, getCourseCategories, createSubCourse, updateSubCourse, updateSubCourseStatus, deleteSubCourse } from "../../api/courses.api" import { Input } from "../../components/ui/input" import type { SubCourse, Course, CourseCategory } from "../../types/course.types" export function SubCoursesPage() { const { categoryId, courseId } = useParams<{ categoryId: string; courseId: string }>() const navigate = useNavigate() const [subCourses, setSubCourses] = useState([]) const [course, setCourse] = useState(null) const [category, setCategory] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [openMenuId, setOpenMenuId] = useState(null) const [togglingId, setTogglingId] = useState(null) const [showDeleteModal, setShowDeleteModal] = useState(false) const [subCourseToDelete, setSubCourseToDelete] = useState(null) const [deleting, setDeleting] = useState(false) const menuRef = useRef(null) const [showAddModal, setShowAddModal] = useState(false) const [showEditModal, setShowEditModal] = useState(false) const [subCourseToEdit, setSubCourseToEdit] = useState(null) const [title, setTitle] = useState("") const [description, setDescription] = useState("") const [level, setLevel] = useState("") const [saving, setSaving] = useState(false) const [saveError, setSaveError] = useState(null) useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (menuRef.current && !menuRef.current.contains(event.target as Node)) { setOpenMenuId(null) } } if (openMenuId !== null) { document.addEventListener("mousedown", handleClickOutside) } return () => document.removeEventListener("mousedown", handleClickOutside) }, [openMenuId]) const fetchSubCourses = async () => { if (!courseId) return try { const subCoursesRes = await getSubCoursesByCourse(Number(courseId)) setSubCourses(subCoursesRes.data.data.sub_courses ?? []) } catch (err) { console.error("Failed to fetch sub-courses:", err) } } useEffect(() => { const fetchData = async () => { if (!courseId || !categoryId) return try { const [subCoursesRes, coursesRes, categoriesRes] = await Promise.all([ getSubCoursesByCourse(Number(courseId)), getCoursesByCategory(Number(categoryId)), getCourseCategories(), ]) setSubCourses(subCoursesRes.data.data.sub_courses ?? []) const foundCourse = coursesRes.data.data.courses?.find( (c) => c.id === Number(courseId) ) setCourse(foundCourse ?? null) const foundCategory = categoriesRes.data.data.categories?.find( (c) => c.id === Number(categoryId) ) setCategory(foundCategory ?? null) } catch (err) { console.error("Failed to fetch sub-courses:", err) setError("Failed to load sub-courses") } finally { setLoading(false) } } fetchData() }, [courseId, categoryId]) const handleToggleStatus = async (subCourse: SubCourse) => { setTogglingId(subCourse.id) try { await updateSubCourseStatus(subCourse.id, { is_active: !subCourse.is_active, level: subCourse.level, title: subCourse.title, }) await fetchSubCourses() } catch (err) { console.error("Failed to update sub-course status:", err) } finally { setTogglingId(null) } } const handleDeleteClick = (subCourse: SubCourse) => { setSubCourseToDelete(subCourse) setShowDeleteModal(true) } const handleConfirmDelete = async () => { if (!subCourseToDelete) return setDeleting(true) try { await deleteSubCourse(subCourseToDelete.id) setShowDeleteModal(false) setSubCourseToDelete(null) await fetchSubCourses() } catch (err) { console.error("Failed to delete sub-course:", err) } finally { setDeleting(false) } } const handleAddSubCourse = () => { setTitle("") setDescription("") setLevel("") setSaveError(null) setShowAddModal(true) } const handleSaveNewSubCourse = async () => { if (!courseId) return setSaving(true) setSaveError(null) try { await createSubCourse({ course_id: Number(courseId), title, description, level, }) setShowAddModal(false) setTitle("") setDescription("") setLevel("") await fetchSubCourses() } catch (err) { console.error("Failed to create sub-course:", err) setSaveError("Failed to create sub-course") } finally { setSaving(false) } } const handleEditClick = (subCourse: SubCourse) => { setSubCourseToEdit(subCourse) setTitle(subCourse.title) setDescription(subCourse.description) setLevel(subCourse.level) setSaveError(null) setShowEditModal(true) } const handleSaveEditSubCourse = async () => { if (!subCourseToEdit) return setSaving(true) setSaveError(null) try { await updateSubCourse(subCourseToEdit.id, { title, description, level, }) setShowEditModal(false) setSubCourseToEdit(null) setTitle("") setDescription("") setLevel("") await fetchSubCourses() } catch (err) { console.error("Failed to update sub-course:", err) setSaveError("Failed to update sub-course") } finally { setSaving(false) } } const handleSubCourseClick = (subCourseId: number) => { navigate(`/content/category/${categoryId}/courses/${courseId}/sub-courses/${subCourseId}`) } if (loading) { return (
{/*

Loading sub-courses...

*/}
) } if (error) { return (

{error}

) } return (
{/* Header */}
{category?.name} {course?.title}

Sub-courses

{subCourses.length} sub-course{subCourses.length !== 1 ? "s" : ""} available

{/* Sub-course grid or empty state */} {subCourses.length === 0 ? (

No sub-courses yet

Get started by adding your first sub-course to this course

) : (
{subCourses.map((subCourse, index) => { const gradients = [ "bg-gradient-to-br from-blue-100 to-blue-200", "bg-gradient-to-br from-purple-100 to-purple-200", "bg-gradient-to-br from-green-100 to-green-200", "bg-gradient-to-br from-yellow-100 to-yellow-200", ] return ( handleSubCourseClick(subCourse.id)} > {/* Thumbnail with level badge */}
{subCourse.thumbnail ? ( {subCourse.title} ) : (
)} {subCourse.level && (
{subCourse.level}
)}
{/* Content */}
{/* Status and menu */}
{subCourse.is_active ? "Active" : "Inactive"}
e.stopPropagation()} > {openMenuId === subCourse.id && (
)}
{/* Title */}

{subCourse.title}

{subCourse.description || "No description available"}

{/* Edit button */}
) })}
)} {/* Delete Modal */} {showDeleteModal && subCourseToDelete && (

Delete Sub-course

Are you sure you want to delete{" "} {subCourseToDelete.title}? This action cannot be undone.

)} {/* Add Sub-course Modal */} {showAddModal && (

Add New Sub-course

setTitle(e.target.value)} placeholder="Enter sub-course title" />