"use client" import { useTranslations } from "next-intl" import { CalendarDays, CheckCircle2, XCircle, Clock, Ban } from "lucide-react" import { Badge } from "@/shared/components/ui/badge" import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card" import { EmptyState } from "@/shared/components/ui/empty-state" import type { LeaveRequestListItem, LeaveStatus, LeaveType } from "../types" type IconKey = "clock" | "check" | "x" | "ban" const STATUS_STYLES: Record = { pending: { variant: "secondary", iconKey: "clock" }, approved: { variant: "default", iconKey: "check" }, rejected: { variant: "destructive", iconKey: "x" }, cancelled: { variant: "outline", iconKey: "ban" }, } const STATUS_ICONS: Record = { clock: Clock, check: CheckCircle2, x: XCircle, ban: Ban, } /** * 请假申请列表(只读展示)。 * * 适用于家长/学生查看自己的请假记录,教师查看本班请假(审批操作走 LeaveReviewDialog)。 */ export function LeaveRequestList({ items, emptyTitle, emptyDescription, }: { items: LeaveRequestListItem[] emptyTitle: string emptyDescription: string }) { const t = useTranslations("leave") if (items.length === 0) { return ( ) } return (
{items.map((item) => { const meta = STATUS_STYLES[item.status] const Icon = STATUS_ICONS[meta.iconKey] return (
{item.studentName} · {item.className}

{t("types." + item.leaveType)} · {item.startDate} ~ {item.endDate}

{t("status." + item.status)}
{t("list.reason")}: {item.reason}
{item.reviewerName && item.reviewedAt && (
{t("list.reviewedBy", { name: item.reviewerName, date: item.reviewedAt.slice(0, 10) })}
)} {item.reviewComment && (
{t("list.reviewComment")}: {item.reviewComment}
)} {item.attendanceSynced && (
{t("list.attendanceSynced")}
)}
) })}
) } /** 请假类型中文标签(复用工具函数,避免重复定义)。 */ export function leaveTypeLabel(type: LeaveType): string { const labels: Record = { sick: "病假", personal: "事假", family: "家庭事务", other: "其他", } return labels[type] ?? type }