import { useEffect, useState } from "react" import { Link } from "react-router-dom" import { FolderOpen, RefreshCw, BookOpen, Plus, Trash2 } from "lucide-react" import spinnerSrc from "../../assets/Circular-indeterminate progress indicator.svg" import alertSrc from "../../assets/Alert.svg" import { Card, CardContent, CardHeader, CardTitle } from "../../components/ui/card" import { Button } from "../../components/ui/button" import { Input } from "../../components/ui/input" import { Select } from "../../components/ui/select" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "../../components/ui/dialog" import { getCourseCategories, createCourseCategory, deleteCourseCategory } from "../../api/courses.api" import type { CourseCategory } from "../../types/course.types" import { toast } from "sonner" export function CourseCategoryPage() { const [categories, setCategories] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [createOpen, setCreateOpen] = useState(false) const [newCategoryName, setNewCategoryName] = useState("") const [creating, setCreating] = useState(false) const [parentCategoryId, setParentCategoryId] = useState(null) const [newSubCategoryName, setNewSubCategoryName] = useState("") const [pendingSubCategories, setPendingSubCategories] = useState([]) const [searchQuery, setSearchQuery] = useState("") const [deleteTarget, setDeleteTarget] = useState(null) const [deleting, setDeleting] = useState(false) const fetchCategories = async () => { setLoading(true) setError(null) try { const res = await getCourseCategories() setCategories(res.data.data.categories) } catch (err) { console.error("Failed to fetch categories:", err) setError("Failed to load categories") } finally { setLoading(false) } } useEffect(() => { fetchCategories() }, []) const normalizedQuery = searchQuery.trim().toLowerCase() const filteredCategories = normalizedQuery ? categories.filter((c) => c.name?.toLowerCase().includes(normalizedQuery)) : categories if (loading) { return (
Loading categories…
) } if (error) { return (

{error}

Please check your connection and try again

) } return (
{/* Page header */}

Course Categories

Browse and manage your course categories below

setSearchQuery(e.target.value)} placeholder="Search categories..." aria-label="Search categories" />
{categories.length === 0 ? (

No categories yet

Course categories will appear here once created. Start by adding your first category.

) : filteredCategories.length === 0 ? (

No matching categories

Try a different search term.

) : (
{filteredCategories.map((category) => ( {/* Decorative gradient strip */}
{category.name}
View Sub-categories
))}
)} {/* Create category dialog */} Create course category Add a new high-level bucket to organize your courses. You can also nest it under an existing parent category.
setNewCategoryName(e.target.value)} />

When left empty, this becomes a parent category. Any sub categories you add on the right will be created under it.

Sub categories for this category (optional)

{pendingSubCategories.length > 0 && ( {pendingSubCategories.length} sub categor {pendingSubCategories.length === 1 ? "y" : "ies"} to create )}
setNewSubCategoryName(e.target.value)} className="h-9 text-sm" />
{pendingSubCategories.length === 0 ? (

Added sub categories will appear here so you can visually confirm the structure before saving. This is optional.

) : (
{pendingSubCategories.map((name) => ( ))}
)}
!open && setDeleteTarget(null)}> Delete category? {deleteTarget ? `This will permanently delete "${deleteTarget.name}" and all linked sub-categories/courses.` : ""}
) }