import { Link } from "react-router-dom"; import { useQuery } from "@tanstack/react-query"; import { useTranslation } from "react-i18next"; import { ArrowRight, Calendar, GraduationCap, Sparkles, } from "lucide-react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Skeleton } from "@/components/ui/skeleton"; import { coursePlanService } from "@/services/coursePlan.service"; import { describeApiError } from "@/lib/api-client"; import type { CoursePlan } from "@/types"; /** * Student-facing list of AI course plans assigned to the current user. * * Reads from `GET /api/student/course-plans`, which only returns plans * the user has been linked to either directly (Phase D `students` mode) * or via the batch they're enrolled in. The card itself is intentionally * lightweight: tap → drill into `/student/course-plans/:id` for the full * weekly plan and embedded media. */ export default function StudentCoursePlans() { const { t } = useTranslation(); const { data, isLoading, isError, error } = useQuery({ queryKey: ["student-course-plans"], queryFn: () => coursePlanService.studentList(), }); const items = data?.items ?? []; return (

{t("coursePlan.student.listTitle")}

{t("coursePlan.student.listSubtitle")}

{isLoading && (
{[1, 2, 3].map((i) => ( ))}
)} {isError && (
{describeApiError(error, t("coursePlan.loadFailed"))}
)} {!isLoading && !isError && items.length === 0 && (

{t("coursePlan.student.empty")}

)} {items.length > 0 && (
{items.map((plan) => ( ))}
)}
); } function PlanCard({ plan }: { plan: CoursePlan }) { const { t } = useTranslation(); const a = plan.assignment; return (
{plan.name} {plan.cefr_level}
{plan.description && ( {plan.description} )}
{t("coursePlan.weeksCount", { count: plan.total_weeks })} {t("coursePlan.hoursPerWeek", { count: plan.contact_hours_per_week, })}
{a && (
{a.assigned_by_name && (
{t("coursePlan.student.assignedBy", { name: a.assigned_by_name })}
)}
{a.due_date ? t("coursePlan.student.due", { date: a.due_date }) : t("coursePlan.student.noDue")}
)}
); }