"use client"; import { useEffect, useMemo, useState } from "react"; import { zodResolver } from "@hookform/resolvers/zod"; import { Controller, Resolver, useForm } from "react-hook-form"; import { z } from "zod/v4"; import { OptionCombobox } from "@/components/option-combobox"; import { ProjectDialog } from "@/components/project-dialog"; import { Button } from "@/components/ui/button"; import { Field, FieldContent, FieldError, FieldLabel, } from "@/components/ui/field"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { type AdminQuickReply, type CreateAdminQuickReplyPayload, fetchQuickReply, } from "@/lib/api/admin"; import { getEnumOptions } from "@/lib/enums"; import { Status, StatusLabels } from "@/lib/generated/enums"; import { useI18n } from "@/i18n/provider"; type QuickReplyFormDialogProps = { open: boolean; saving: boolean; itemId: number | null; onOpenChange: (open: boolean) => void; onSubmit: (payload: CreateAdminQuickReplyPayload) => Promise; }; const emptyForm: EditForm = { groupName: "", title: "", content: "", status: String(Status.Ok), sortNo: "0", }; type EditForm = { groupName: string; title: string; content: string; status: string; sortNo: string; }; function createSchema(t: (key: string) => string) { return z.object({ groupName: z.string().trim().min(1, t("quickReply.groupNameRequired")), title: z.string().trim().min(1, t("quickReply.titleRequired")), content: z.string().trim().min(1, t("quickReply.contentRequired")), status: z.enum([String(Status.Ok), String(Status.Disabled)], { message: t("quickReply.statusRequired"), }), sortNo: z .string() .trim() .min(1, t("quickReply.sortRequired")) .regex(/^\d+$/, t("quickReply.sortInvalid")), }); } function getLocalizedStatusLabel(value: string | number, t: (key: string) => string) { const status = Number(value) as Status; if (status === Status.Disabled) { return t("status.disabled"); } if (status === Status.Deleted) { return t("status.deleted"); } return t("status.ok"); } function buildForm(item: AdminQuickReply | null): EditForm { if (!item) { return emptyForm; } return { groupName: item.groupName, title: item.title, content: item.content, status: String(item.status) as EditForm["status"], sortNo: String(item.sortNo), }; } function buildPayload(form: EditForm): CreateAdminQuickReplyPayload { return { groupName: form.groupName.trim(), title: form.title.trim(), content: form.content.trim(), status: Number(form.status) as Status, sortNo: Number(form.sortNo), }; } export function EditDialog({ open, saving, itemId, onOpenChange, onSubmit, }: QuickReplyFormDialogProps) { if (!open) { return null; } return ( ); } type QuickReplyFormDialogBodyProps = { open: boolean; saving: boolean; itemId: number | null; onOpenChange: (open: boolean) => void; onSubmit: (payload: CreateAdminQuickReplyPayload) => Promise; }; function QuickReplyFormDialogBody({ open, saving, itemId, onOpenChange, onSubmit, }: QuickReplyFormDialogBodyProps) { const t = useI18n(); const formId = "quick-reply-edit-form"; const [loading, setLoading] = useState(false); const quickReplyFormSchema = useMemo(() => createSchema(t), [t]); const editFormResolver = useMemo( () => zodResolver(quickReplyFormSchema as never) as Resolver< z.input, undefined, z.output >, [quickReplyFormSchema], ); const formStatusOptions = useMemo( () => getEnumOptions(StatusLabels) .filter((item) => Number(item.value) !== Status.Deleted) .map((item) => ({ value: String(item.value), label: getLocalizedStatusLabel(item.value, t), })), [t], ); const form = useForm< z.input, undefined, z.output >({ resolver: editFormResolver, defaultValues: emptyForm, }); const { control, handleSubmit, reset, register, formState: { errors }, } = form; useEffect(() => { async function loadDetail() { if (!itemId) { reset(emptyForm); return; } setLoading(true); try { const data = await fetchQuickReply(itemId); reset(buildForm(data)); } catch (error) { console.error("Failed to load quick reply:", error); } finally { setLoading(false); } } void loadDetail(); }, [itemId, reset]); async function onFormSubmit(values: EditForm) { const payload = buildPayload(values); await onSubmit(payload); } return ( } > {loading ? (
{t("quickReply.loadingDetail")}
) : (
{t("quickReply.groupName")} {t("quickReply.title")} {t("quickReply.content")}