This commit is contained in:
rgrgogu
2026-05-21 13:27:22 +08:00
parent 6d70011b44
commit e83caf28cc
17 changed files with 328 additions and 116 deletions
@@ -0,0 +1,58 @@
import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { ArrowLeft, House } from "lucide-react";
import { useCourses } from "@/contexts/AdminCoursesContext";
import AppBreadcrumb from "@/components/generic/Breadcrumb/AppBreadcrumb";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import ArchivedLessonsTable from "../../../components/courses/ArchivedLessonsTable";
export default function ArchivedLessonsList() {
const navigate = useNavigate();
const { courseId, unitId } = useParams();
const { fetchCourse, fetchUnit, course, unit, loading } = useCourses();
const [initializing, setInitializing] = useState(true);
useEffect(() => {
(async () => {
await fetchCourse(courseId)
await fetchUnit(courseId, unitId);
setInitializing(false);
})();
}, [courseId, unitId]);
const items = [
{ label: "Home", icon: <House className="size-4" />, to: "/admin" },
{ label: "Courses", to: "/admin/courses" },
{ label: course?.title, to: `/admin/courses/${courseId}/units` },
{ label: unit?.title ?? "...", to: `/admin/courses/${courseId}/units/${unitId}/lessons` },
{ label: "Archived" }
];
// Replace the loading check
if (initializing) {
return (
<div className="flex items-center justify-center h-64">
<Spinner className="h-6 w-6" />
</div>
);
}
return (
<section className="bg-muted/60 h-full">
<div className="lg:container lg:mx-auto lg:px-0 flex flex-col items-start px-4">
<div className="flex flex-col gap-2 my-6">
<AppBreadcrumb items={items} />
</div>
<div className="w-full space-y-6">
{/* ── Lessons ── */}
<ArchivedLessonsTable courseId={courseId} unitId={unitId} />
</div>
</div>
</section>
);
}
@@ -48,13 +48,45 @@ export default function LessonsList() {
<div className="w-full space-y-6">
{/* ── Unit header ── */}
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div>
<div className="bg-white rounded-xl border p-6 space-y-4">
{/* Title + Status */}
<div>
<h6 className="text-xs tracking-widest mb-1">UNIT</h6>
<div className="flex items-center gap-2">
<h1 className="text-xl font-semibold">{unit?.title}</h1>
{unit?.description && (
<p className="text-sm text-muted-foreground">{unit.description}</p>
)}
<span
className={`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${!unit?.deletedBy ? "bg-green-100 text-green-700" : "bg-red-100 text-red-600"
}`}
>
{!unit?.deletedBy ? "Active" : "Inactive"}
</span>
</div>
{unit?.description && (
<p className="text-sm text-muted-foreground mt-0.5">{unit.description}</p>
)}
</div>
{/* Stats row */}
<div className="grid grid-cols-2 lg:grid-cols-4 gap-3">
<div className="bg-muted/60 rounded-lg p-3 space-y-1">
<p className="text-xs text-muted-foreground uppercase tracking-wide font-medium">Lessons</p>
<p className="font-semibold text-sm">{unit?.lessons?.length}</p>
</div>
<div className="bg-muted/60 rounded-lg p-3 space-y-1">
<p className="text-xs text-muted-foreground uppercase tracking-wide font-medium">Order</p>
<p className="font-semibold text-sm">{unit?.order_index}</p>
</div>
<div className="bg-muted/60 rounded-lg p-3 space-y-1">
<p className="text-xs text-muted-foreground uppercase tracking-wide font-medium">Created</p>
<p className="font-semibold text-sm">
{unit?.createdAt ? new Date(unit.createdAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '—'}
</p>
</div>
<div className="bg-muted/60 rounded-lg p-3 space-y-1">
<p className="text-xs text-muted-foreground uppercase tracking-wide font-medium">Last Updated</p>
<p className="font-semibold text-sm">
{unit?.updatedAt ? new Date(unit.updatedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '—'}
</p>
</div>
</div>
</div>