'use client'; import {zodResolver} from '@hookform/resolvers/zod'; import {useMutation, useQueryClient} from '@tanstack/react-query'; import {useEffect} from 'react'; import {useForm} from 'react-hook-form'; import {z} from 'zod'; import {AppModal} from '@/components/ui/app-modal'; import {createOrigin, updateOrigin} from '@/features/origins/api/origins'; import type {OriginItem, OriginMutationPayload,} from '@/features/origins/types'; import { PrimaryButton, ResourceField, ResourceInput, ResourceTextarea, SecondaryButton, } from '@/features/shared/components/resource-primitives'; const originSchema = z.object({ name: z.string().max(255, '源站名不能超过 255 个字符'), address: z .string() .trim() .min(1, '请输入源站地址') .refine( (value) => !/[/?#]/.test(value) && !value.includes('://'), '源站地址格式不合法', ), remark: z.string().max(255, '备注不能超过 255 个字符'), }); type OriginFormValues = z.infer; function toPayload(values: OriginFormValues): OriginMutationPayload { return { name: values.name.trim(), address: values.address.trim(), remark: values.remark.trim(), }; } function toFormValues(origin?: OriginItem | null): OriginFormValues { if (!origin) { return { name: '', address: '', remark: '', }; } return { name: origin.name, address: origin.address, remark: origin.remark || '', }; } export function OriginEditorModal({ isOpen, onClose, origin, onSaved, }: { isOpen: boolean; onClose: () => void; origin?: OriginItem | null; onSaved?: (origin: OriginItem, mode: 'create' | 'update') => void; }) { const queryClient = useQueryClient(); const form = useForm({ resolver: zodResolver(originSchema), defaultValues: toFormValues(origin), }); useEffect(() => { form.reset(toFormValues(origin)); }, [form, origin, isOpen]); const mutation = useMutation({ mutationFn: async (values: OriginFormValues) => { const payload = toPayload(values); return origin ? updateOrigin(origin.id, payload) : createOrigin(payload); }, onSuccess: async (savedOrigin) => { await Promise.all([ queryClient.invalidateQueries({ queryKey: ['origins'] }), queryClient.invalidateQueries({ queryKey: ['proxy-routes'] }), ]); onSaved?.(savedOrigin, origin ? 'update' : 'create'); onClose(); }, }); const handleSubmit = form.handleSubmit((values) => { mutation.mutate(values); }); return ( 取消 {mutation.isPending ? '保存中...' : origin ? '保存修改' : '新增源站'} } >
{mutation.isError ? (

{mutation.error instanceof Error ? mutation.error.message : '请求失败,请稍后重试。'}

) : null}
); }