import { useEffect, useState, useRef } from "react"
import { Link, useParams, useNavigate } from "react-router-dom"
import { Plus, ArrowLeft, BookOpen, ToggleLeft, ToggleRight, X, Trash2, MoreVertical, Edit, RefreshCw, AlertCircle } from "lucide-react"
import { Card, CardContent } from "../../components/ui/card"
import { Button } from "../../components/ui/button"
import { Badge } from "../../components/ui/badge"
import { Input } from "../../components/ui/input"
import { FileUpload } from "../../components/ui/file-upload"
import { getCoursesByCategory, getCourseCategories, createCourse, deleteCourse, updateCourseStatus, updateCourse } from "../../api/courses.api"
import type { Course, CourseCategory } from "../../types/course.types"
function CourseThumbnail({ src, alt, gradient }: { src?: string; alt: string; gradient: string }) {
const [imgError, setImgError] = useState(false)
if (!src || imgError) {
return
}
return (
setImgError(true)}
/>
)
}
export function CoursesPage() {
const { categoryId } = useParams<{ categoryId: string }>()
const navigate = useNavigate()
const [courses, setCourses] = useState([])
const [category, setCategory] = useState(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const [showModal, setShowModal] = useState(false)
const [title, setTitle] = useState("")
const [description, setDescription] = useState("")
const [saving, setSaving] = useState(false)
const [saveError, setSaveError] = useState(null)
const [newThumbnailFile, setNewThumbnailFile] = useState(null)
const [newVideoFile, setNewVideoFile] = useState(null)
const [showDeleteModal, setShowDeleteModal] = useState(false)
const [courseToDelete, setCourseToDelete] = useState(null)
const [deleting, setDeleting] = useState(false)
const [togglingId, setTogglingId] = useState(null)
const [openMenuId, setOpenMenuId] = useState(null)
const menuRef = useRef(null)
const [showEditModal, setShowEditModal] = useState(false)
const [courseToEdit, setCourseToEdit] = useState(null)
const [editTitle, setEditTitle] = useState("")
const [editDescription, setEditDescription] = useState("")
const [editThumbnail, setEditThumbnail] = useState("")
const [updating, setUpdating] = useState(false)
const [updateError, setUpdateError] = 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 fetchCourses = async () => {
if (!categoryId) return
try {
const coursesRes = await getCoursesByCategory(Number(categoryId))
console.log("Courses response:", coursesRes.data.data.courses)
setCourses(coursesRes.data.data.courses ?? [])
} catch (err) {
console.error("Failed to fetch courses:", err)
}
}
useEffect(() => {
const fetchData = async () => {
if (!categoryId) return
try {
const [coursesRes, categoriesRes] = await Promise.all([
getCoursesByCategory(Number(categoryId)),
getCourseCategories(),
])
setCourses(coursesRes.data.data.courses)
const foundCategory = categoriesRes.data.data.categories.find(
(c) => c.id === Number(categoryId)
)
setCategory(foundCategory ?? null)
} catch (err) {
console.error("Failed to fetch courses:", err)
setError("Failed to load courses")
} finally {
setLoading(false)
}
}
fetchData()
}, [categoryId])
const handleOpenModal = () => {
setTitle("")
setDescription("")
setSaveError(null)
setNewThumbnailFile(null)
setNewVideoFile(null)
setShowModal(true)
}
const handleCloseModal = () => {
setShowModal(false)
setTitle("")
setDescription("")
setSaveError(null)
setNewThumbnailFile(null)
setNewVideoFile(null)
}
const handleSave = async () => {
if (!title.trim()) {
setSaveError("Title is required")
return
}
if (!description.trim()) {
setSaveError("Description is required")
return
}
setSaving(true)
setSaveError(null)
try {
await createCourse({
category_id: Number(categoryId),
title: title.trim(),
description: description.trim(),
})
handleCloseModal()
await fetchCourses()
} catch (err: any) {
console.error("Failed to create course:", err)
setSaveError(err.response?.data?.message || "Failed to create course")
} finally {
setSaving(false)
}
}
const handleDeleteClick = (course: Course) => {
setCourseToDelete(course)
setShowDeleteModal(true)
}
const handleConfirmDelete = async () => {
if (!courseToDelete) return
setDeleting(true)
try {
await deleteCourse(courseToDelete.id)
setShowDeleteModal(false)
setCourseToDelete(null)
await fetchCourses()
} catch (err) {
console.error("Failed to delete course:", err)
} finally {
setDeleting(false)
}
}
const handleToggleStatus = async (course: Course) => {
setTogglingId(course.id)
try {
await updateCourseStatus(course.id, !course.is_active)
await fetchCourses()
} catch (err) {
console.error("Failed to update course status:", err)
} finally {
setTogglingId(null)
}
}
const handleEditClick = (course: Course) => {
setCourseToEdit(course)
setEditTitle(course.title || "")
setEditDescription(course.description || "")
setEditThumbnail(course.thumbnail || "")
setUpdateError(null)
setShowEditModal(true)
}
const handleCloseEditModal = () => {
setShowEditModal(false)
setCourseToEdit(null)
setEditTitle("")
setEditDescription("")
setEditThumbnail("")
setUpdateError(null)
}
const handleUpdate = async () => {
if (!courseToEdit) return
if (!editTitle.trim()) {
setUpdateError("Title is required")
return
}
if (!editDescription.trim()) {
setUpdateError("Description is required")
return
}
setUpdating(true)
setUpdateError(null)
try {
await updateCourse(courseToEdit.id, {
title: editTitle.trim(),
description: editDescription.trim(),
thumbnail: editThumbnail.trim() || undefined,
is_active: courseToEdit.is_active,
})
handleCloseEditModal()
await fetchCourses()
} catch (err: any) {
console.error("Failed to update course:", err)
setUpdateError(err.response?.data?.message || "Failed to update course")
} finally {
setUpdating(false)
}
}
const handleCourseClick = (courseId: number) => {
navigate(`/content/category/${categoryId}/courses/${courseId}/sub-courses`)
}
if (loading) {
return (
)
}
if (error) {
return (
)
}
return (
{/* Header */}
{category?.name} Courses
{courses.length} courses available
{/* Course grid or empty state */}
{courses.length === 0 ? (
No courses yet
No courses found in this category
) : (
{courses.map((course, 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 (
handleCourseClick(course.id)}
>
{/* Thumbnail */}
{/* Content */}
{/* Status and menu */}
{course.is_active ? "ACTIVE" : "INACTIVE"}
e.stopPropagation()}>
{openMenuId === course.id && (
)}
{/* Title */}
{course.title}
{course.description || "No description available"}
{/* Edit button */}
)
})}
)}
{/* Add Course Modal */}
{showModal && (
Add New Course
{saveError && (
)}
setTitle(e.target.value)}
/>
Category: {category?.name}
)}
{/* Edit Course Modal */}
{showEditModal && courseToEdit && (
Edit Course
)}
{/* Delete Course Modal */}
{showDeleteModal && courseToDelete && (
Delete Course
Are you sure you want to delete{" "}
{courseToDelete.title}? This action cannot
be undone.
)}
)
}