"use client" import Link from "next/link" import { memo, useState, useTransition } from "react" import { useRouter } from "next/navigation" import { toast } from "sonner" import { useTranslations } from "next-intl" import { Card, CardContent, CardHeader, CardTitle, CardDescription, CardFooter } from "@/shared/components/ui/card" import { Badge } from "@/shared/components/ui/badge" import { Button } from "@/shared/components/ui/button" import { EmptyState } from "@/shared/components/ui/empty-state" import { Input } from "@/shared/components/ui/input" import { Label } from "@/shared/components/ui/label" import { BookOpen, Building2, Inbox, CalendarDays, User, PlusCircle, PenTool, Mail, School } from "lucide-react" import type { StudentEnrolledClass } from "@/modules/classes/types" import { joinClassByInvitationCodeAction } from "@/modules/classes/actions" const ClassCard = memo(function ClassCard({ c }: { c: StudentEnrolledClass }) { const t = useTranslations("student") return (
{c.name} {t("coursesView.grade", { grade: c.grade })} {c.homeroom && ( <> {c.homeroom} )}
{t("coursesView.active")}
{c.schoolName && (
{c.schoolName}
)} {c.teacherName && (
{c.teacherName}
)} {c.teacherEmail && (
{c.teacherEmail}
)} {c.room && (
{t("coursesView.room", { room: c.room })}
)}
) }) export function StudentCoursesView({ classes, }: { classes: StudentEnrolledClass[] }) { const t = useTranslations("student") const router = useRouter() const [code, setCode] = useState("") const [isPending, startTransition] = useTransition() const handleJoin = async (formData: FormData) => { startTransition(async () => { try { const res = await joinClassByInvitationCodeAction(null, formData) if (res.success) { toast.success(res.message || t("coursesView.joinedSuccess")) setCode("") router.refresh() } else { toast.error(res.message || t("coursesView.joinFailed")) } } catch (err) { console.error("[joinClass] failed:", err) toast.error(t("coursesView.joinFailed")) } }) } return (
{classes.length > 0 && (
{classes.map((c) => ( ))}
)} {classes.length === 0 && ( )} {/* 加入班级表单:无课程时置顶,有课程时置底 */}

{t("coursesView.joinClass")}

{t("coursesView.joinClassDesc")}

setCode(e.target.value)} maxLength={6} pattern="\d{6}" className="max-w-md font-mono tracking-widest" required />
) }