"use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; import { Resolver, useForm } from "react-hook-form"; import { z } from "zod/v4"; 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 { fetchSkillDefinition, type CreateSkillDefinitionPayload, type SkillDefinition, } from "@/lib/api/admin"; type SkillEditDialogProps = { open: boolean; saving: boolean; itemId: number | null; onOpenChange: (open: boolean) => void; onSubmit: (payload: CreateSkillDefinitionPayload) => Promise; }; const emptyForm: EditForm = { code: "", name: "", description: "", prompt: "", remark: "", }; const skillFormSchema = z.object({ code: z .string() .trim() .min(1, "Skill 编码不能为空") .regex(/^[a-zA-Z0-9_-]+$/, "Skill 编码仅支持字母、数字、下划线和中划线"), name: z.string().trim().min(1, "Skill 名称不能为空"), description: z.string().trim(), prompt: z.string().trim().min(1, "Prompt 不能为空"), remark: z.string().trim(), }); type EditForm = z.infer; const editFormResolver = zodResolver(skillFormSchema as never) as Resolver< z.input, undefined, z.output >; function buildForm(item: SkillDefinition | null): EditForm { if (!item) { return emptyForm; } return { code: item.code, name: item.name, description: item.description ?? "", prompt: item.prompt ?? "", remark: item.remark ?? "", }; } function buildPayload(form: EditForm): CreateSkillDefinitionPayload { return { code: form.code.trim(), name: form.name.trim(), description: form.description.trim(), prompt: form.prompt.trim(), remark: form.remark.trim(), }; } export function EditDialog({ open, saving, itemId, onOpenChange, onSubmit, }: SkillEditDialogProps) { if (!open) { return null; } return ( ); } type SkillEditDialogBodyProps = SkillEditDialogProps; function SkillEditDialogBody({ open, saving, itemId, onOpenChange, onSubmit, }: SkillEditDialogBodyProps) { const formId = "skill-definition-edit-form"; const [loading, setLoading] = useState(false); const form = useForm< z.input, undefined, z.output >({ resolver: editFormResolver, defaultValues: emptyForm, }); const { handleSubmit, reset, register, formState: { errors }, } = form; useEffect(() => { async function loadDetail() { if (!itemId) { reset(emptyForm); return; } setLoading(true); try { const data = await fetchSkillDefinition(itemId); reset(buildForm(data)); } catch (error) { console.error("Failed to load skill definition:", error); } finally { setLoading(false); } } void loadDetail(); }, [itemId, reset]); async function onFormSubmit(values: EditForm) { await onSubmit(buildPayload(values)); } return ( } > {loading ? (
加载中...
) : (
编码 名称
描述