"use client"; import { useState } from "react"; import type { AnnouncementAudience, AnnouncementDisplayType, } from "@prisma/client"; import { toast } from "sonner"; import { createAnnouncement, updateAnnouncement, } from "@/actions/admin/announcements"; import { PendingSubmitButton } from "@/components/shared/pending-submit-button"; import { BooleanToggle } from "@/components/ui/boolean-toggle"; import { Button } from "@/components/ui/button"; import { Dialog, DialogBody, DialogContent, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; import { getErrorMessage } from "@/lib/errors"; interface AnnouncementOptionUser { id: string; email: string; } interface AnnouncementFormData { id: string; title: string; body: string; audience: AnnouncementAudience; displayType: AnnouncementDisplayType; targetUserId: string | null; dismissible: boolean; sendNotification: boolean; startAt: Date | string | null; endAt: Date | string | null; } const audienceLabels: Record = { PUBLIC: "公开", USERS: "全部用户", ADMINS: "全部管理员", SPECIFIC_USER: "指定用户", }; const displayTypeLabels: Record = { INLINE: "普通公告", BIG: "大公告", POPUP: "弹窗公告", }; function getAudienceLabel(value: unknown) { return audienceLabels[value as AnnouncementAudience] ?? "选择范围"; } function getDisplayTypeLabel(value: unknown) { return displayTypeLabels[value as AnnouncementDisplayType] ?? "选择展示方式"; } function getTargetUserLabel(users: AnnouncementOptionUser[], value: unknown) { if (!value) return "不指定"; return users.find((user) => user.id === value)?.email ?? "选择用户"; } function toDateTimeLocalValue(value: Date | string | null) { if (!value) { return ""; } const date = new Date(value); if (Number.isNaN(date.getTime())) { return ""; } const localTime = new Date(date.getTime() - date.getTimezoneOffset() * 60_000); return localTime.toISOString().slice(0, 16); } export function AnnouncementForm({ users, announcement, triggerLabel, triggerVariant = "outline", }: { users: AnnouncementOptionUser[]; announcement: AnnouncementFormData; triggerLabel?: string; triggerVariant?: "default" | "outline" | "ghost"; }) { const [open, setOpen] = useState(false); const [audience, setAudience] = useState(announcement.audience); async function handleSubmit(formData: FormData) { try { await updateAnnouncement(announcement.id, formData); toast.success("公告已更新"); setOpen(false); } catch (error) { toast.error(getErrorMessage(error, "更新公告失败")); } } return ( { if (nextOpen) { setAudience(announcement.audience); } setOpen(nextOpen); }} > }> {triggerLabel ?? "编辑"} 编辑公告