refactor(add-service): Refactor ServiceForm.tsx to support internationalization

- Extract ServiceForm.tsx validation logic into the custom hook useServiceSchema
- Add internationalization support and move error messages to translation files
This commit is contained in:
YiZixuan
2025-08-17 23:13:25 +08:00
parent 6bf75b2bf7
commit fa3ad9b2e1
5 changed files with 57 additions and 20 deletions
@@ -3,7 +3,7 @@ import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useState, useEffect } from "react";
import { useToast } from "@/hooks/use-toast";
import { serviceSchema, ServiceFormData } from "./types";
import { useServiceSchema, ServiceFormData } from "./types";
import { ServiceBasicFields } from "./ServiceBasicFields";
import { ServiceTypeField } from "./ServiceTypeField";
import { ServiceConfigFields } from "./ServiceConfigFields";
@@ -36,6 +36,8 @@ export function ServiceForm({
const [isSubmitting, setIsSubmitting] = useState(false);
const queryClient = useQueryClient();
const serviceSchema = useServiceSchema();
// Initialize form with default values
const form = useForm<ServiceFormData>({
resolver: zodResolver(serviceSchema),
@@ -1,22 +1,42 @@
import { z } from "zod";
import type { ZodSchema } from "zod";
import { useLanguage } from "@/contexts/LanguageContext";
export const serviceSchema = z.object({
name: z.string().min(1, "Service name is required"),
type: z.enum(["http", "ping", "tcp", "dns"]),
url: z.string().min(1, "URL/Domain/Host is required").refine((value) => {
// Basic validation - more specific validation can be added per type
return value.trim().length > 0;
}, "Please enter a valid URL, hostname, or domain"),
port: z.string().optional(),
interval: z.string(),
retries: z.string(),
notificationStatus: z.enum(["enabled", "disabled"]).optional(),
notificationChannels: z.array(z.string()).optional(),
alertTemplate: z.string().optional(),
// Regional monitoring fields - now supports multiple agents
regionalMonitoringEnabled: z.boolean().optional(),
regionalAgents: z.array(z.string()).optional(),
});
export type ServiceFormData = z.infer<typeof serviceSchema>;
export type ServiceFormData = {
name: string;
type: "http" | "ping" | "tcp" | "dns";
url: string;
port?: string;
interval: string;
retries: string;
notificationStatus?: "enabled" | "disabled";
notificationChannels?: string[];
alertTemplate?: string;
regionalMonitoringEnabled?: boolean;
regionalAgents?: string[];
};
// Hook to use the schema with translations
export const useServiceSchema = () => {
const { t } = useLanguage();
return z.object({
name: z.string().min(1, t("serviceNameRequired")),
type: z.enum(["http", "ping", "tcp", "dns"]),
url: z.string()
.min(1, t("urlDomainHostRequired"))
.refine(
(value) => value.trim().length > 0,
t("enterValidUrlHostnameDomain")
),
port: z.string().optional(),
interval: z.string(),
retries: z.string(),
notificationStatus: z.enum(["enabled", "disabled"]).optional(),
notificationChannels: z.array(z.string()).optional(),
alertTemplate: z.string().optional(),
// Regional monitoring fields - now supports multiple agents
regionalMonitoringEnabled: z.boolean().optional(),
regionalAgents: z.array(z.string()).optional(),
});
};
@@ -84,4 +84,9 @@ export const servicesTranslations: ServicesTranslations = {
targetDNSDesc: "Enter domain name for DNS record monitoring (A, AAAA, MX, etc.)",
targetDefaultDesc: "Enter the target URL or hostname for monitoring",
targetDefaultPlaceholder: "Enter URL or hostname",
// types.ts
serviceNameRequired: "Service name is required",
urlDomainHostRequired: "URL/Domain/Host is required",
enterValidUrlHostnameDomain: "Please enter a valid URL, hostname, or domain",
};
@@ -82,4 +82,9 @@ export interface ServicesTranslations {
targetDNSDesc: string;
targetDefaultDesc: string;
targetDefaultPlaceholder: string;
// types.ts
serviceNameRequired: string;
urlDomainHostRequired: string;
enterValidUrlHostnameDomain: string;
}
@@ -84,4 +84,9 @@ export const servicesTranslations: ServicesTranslations = {
targetDNSDesc: "输入要监控的 DNS 记录域名(A、AAAA、MX等)",
targetDefaultDesc: "输入要监控的目标 URL 或主机名",
targetDefaultPlaceholder: "输入 URL 或主机名",
// types.ts
serviceNameRequired: "服务名称是必填项",
urlDomainHostRequired: "URL/域名/主机名是必填项",
enterValidUrlHostnameDomain: "请输入有效的URL、主机名或域名",
};