Yimaru-Admin/src/pages/content-management/CourseManagementPage.tsx
2026-04-24 15:20:51 +03:00

265 lines
9.8 KiB
TypeScript

import { Link, useParams, useNavigate } from "react-router-dom";
import {
ArrowLeft,
Plus,
FileText,
LayoutGrid,
PlayCircle,
ClipboardCheck,
ChevronRight,
ArrowRight,
X,
} from "lucide-react";
import { Button } from "../../components/ui/button";
import { Card } from "../../components/ui/card";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
DialogClose,
} from "../../components/ui/dialog";
import { Input } from "../../components/ui/input";
import uploadIcon from "../../assets/icons/upload.png";
export function CourseManagementPage() {
const navigate = useNavigate();
const { programType, courseId } = useParams<{
programType: string;
courseId: string;
}>();
// Mock data for display titles
const courseTitles: Record<string, string> = {
duolingo: "Duolingo English Test",
ielts: "IELTS Academic",
};
const courseDisplayName =
courseTitles[courseId || ""] || "Duolingo English Test";
const units = [
{
id: "unit1",
name: "Greetings & Introductions",
description:
"Learn basic greetings, self-introductions, and polite expressions in everyday situations.",
modules: 3,
videos: 9,
practices: 9,
gradient:
"linear-gradient(135deg, rgba(158, 40, 145, 0.5) 0%, rgba(158, 40, 145, 0.8) 100%)",
},
{
id: "unit2",
name: "Speaking",
description:
"Core speaking practice and skill building for natural pronunciation and fluency.",
modules: 3,
videos: 9,
practices: 9,
gradient:
"linear-gradient(135deg, rgba(79, 70, 229, 0.5) 0%, rgba(79, 70, 229, 0.8) 100%)",
},
{
id: "unit3",
name: "Reading",
description:
"Reading comprehension and vocabulary improvement through various text types.",
modules: 3,
videos: 9,
practices: 9,
gradient:
"linear-gradient(135deg, rgba(124, 58, 237, 0.5) 0%, rgba(124, 58, 237, 0.8) 100%)",
},
];
return (
<div className="space-y-8 animate-in fade-in duration-500 pb-10">
{/* Navigation */}
<Link
to={`/new-content/courses/${programType}`}
className="flex items-center gap-2.5 text-[15px] font-semibold text-grayScale-600 hover:text-brand-500 transition-colors pt-4 group"
>
<ArrowLeft className="h-5 w-5 transition-transform group-hover:-translate-x-1" />
Back to Courses
</Link>
{/* Header section */}
<div className="flex items-start justify-between">
<div className="space-y-2">
<h1 className="text-[28px] font-medium tracking-tight text-grayScale-900">
{courseDisplayName}
</h1>
<p className="max-w-2xl text-[15px] font-medium leading-relaxed text-grayScale-500">
Manage units and modules inside the {courseDisplayName}
</p>
</div>
<div className="flex items-center gap-3 pt-2">
<Dialog>
<DialogTrigger asChild>
<Button className="h-10 px-6 rounded-[6px] bg-brand-500 font-bold text-white shadow-sm hover:bg-brand-600 transition-all flex items-center gap-2">
<Plus className="h-5 w-5" />
Add Unit
</Button>
</DialogTrigger>
<DialogContent className="max-w-[600px] p-0 border-none rounded-[16px] overflow-hidden">
<div className="bg-white">
<DialogHeader className="px-8 py-6 border-b border-grayScale-200 flex flex-row items-center justify-between">
<DialogTitle className="text-[20px] font-bold relative top-2 text-grayScale-900">
Create Courses
</DialogTitle>
</DialogHeader>
<div className="p-8 space-y-8">
<div className="space-y-3">
<label className="text-[15px] text-grayScale-800">
Unit Name
</label>
<Input
placeholder="e.g. Reading"
className="h-12 border-grayScale-400 rounded-[8px] px-4 placeholder:text-grayScale-400 text-[15px] focus:ring-brand-500/20"
/>
</div>
<div className="space-y-3">
<label className="text-[15px] text-grayScale-800">
Thumbnail
</label>
<div className="relative group cursor-pointer">
<div className="flex flex-col items-center justify-center rounded-[12px] border-2 border-dashed border-grayScale-400 bg-white py-8 px-10 transition-all ">
<div className="mb-4">
<img
src={uploadIcon}
alt="Upload icon"
className="h-10 w-10"
/>
</div>
<p className="text-[15px]">
<span className="text-brand-500 font-bold hover:underline">
Click to upload
</span>{" "}
<span className="text-grayScale-500">
or drag and drop
</span>
</p>
<p className="mt-1.5 text-[12px] text-grayScale-400 uppercase tracking-widest">
JPG, PNG (MAX 1 MB)
</p>
</div>
</div>
</div>
</div>
<div className="px-8 py-6 bg-grayScale-50/30 border-t border-grayScale-50 flex justify-end gap-3">
<DialogClose asChild>
<Button
variant="outline"
className="h-11 px-8 rounded-[8px] border-grayScale-200 text-grayScale-700 font-bold"
>
Cancel
</Button>
</DialogClose>
<Button className="h-11 px-8 rounded-[8px] bg-brand-500 text-white font-bold hover:bg-brand-600">
Create Courses
</Button>
</div>
</div>
</DialogContent>
</Dialog>
<Button
variant="outline"
className="h-10 px-6 rounded-[6px] border-brand-500 text-brand-500 font-bold hover:bg-brand-50 transition-all flex items-center gap-2"
onClick={() =>
navigate(`/new-content/courses/${programType}/attach-practice`)
}
>
<FileText className="h-5 w-5" />
Attach Practice
</Button>
</div>
</div>
{/* Horizontal Divider */}
<div className="relative">
<div className="absolute inset-0 flex items-center" aria-hidden="true">
<div className="w-full border-t border-grayScale-200" />
</div>
<div className="relative flex justify-center">
<div
className="h-[0.5px] w-full opacity-20 rounded-full"
style={{
background: "gray",
}}
/>
</div>
</div>
{/* Grid of Units */}
<div className="flex flex-wrap gap-4 pt-4">
{units.map((unit) => (
<Card
key={unit.id}
className="group flex w-[400px] flex-col h-full bg-white rounded-[12px] border border-grayScale-100 overflow-hidden shadow-sm hover:shadow-md transition-all"
>
{/* Gradient Header */}
<div
className="h-36 w-full transition-transform duration-500 "
style={{ background: unit.gradient }}
/>
<div className="p-4 flex flex-col flex-1 space-y-6">
<div className="space-y-3 flex-1">
<h3 className="text-[18px] font-medium text-grayScale-900 transition-colors">
{unit.name}
</h3>
<p className="text-[12px] text-grayScale-500 font-medium line-clamp-3">
{unit.description}
</p>
</div>
{/* Stats Pills */}
<div className="flex flex-wrap gap-3">
<div className="h-9 px-3 rounded-[6px] bg-grayScale-100 border border-grayScale-100 flex items-center gap-2 text-grayScale-600">
<LayoutGrid className="h-3.5 w-3.5 text-grayScale-400" />
<span className="text-[12px] font-bold">
{unit.modules} Modules
</span>
</div>
<div className="h-9 px-3 rounded-[6px] bg-grayScale-100 border border-grayScale-100 flex items-center gap-2 text-grayScale-600">
<PlayCircle className="h-3.5 w-3.5 text-grayScale-400" />
<span className="text-[12px] font-bold">
{unit.videos} Videos
</span>
</div>
<div className="h-9 px-3 rounded-[6px] bg-grayScale-100 border border-grayScale-100 flex items-center gap-2 text-grayScale-600">
<ClipboardCheck className="h-3.5 w-3.5 text-grayScale-400" />
<span className="text-[12px] font-bold">
{unit.practices} Practices
</span>
</div>
</div>
{/* Action Button */}
<Button
className="w-full h-10 bg-brand-500 text-white rounded-[6px] font-bold flex items-center justify-center gap-2 group/btn"
onClick={() =>
navigate(
`/new-content/courses/${programType}/${courseId}/${unit.id}`,
)
}
>
View Detail
<ArrowRight className="ml-2 h-4 w-4" />
</Button>
</div>
</Card>
))}
</div>
</div>
);
}