import { Form } from "@/components/ui/form"; 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 "./add-service/types"; import { ServiceBasicFields } from "./add-service/ServiceBasicFields"; import { ServiceTypeField } from "./add-service/ServiceTypeField"; import { ServiceConfigFields } from "./add-service/ServiceConfigFields"; import { ServiceNotificationFields } from "./add-service/ServiceNotificationFields"; import { ServiceFormActions } from "./add-service/ServiceFormActions"; import { serviceService } from "@/services/serviceService"; import { Service } from "@/types/service.types"; interface ServiceFormProps { onSuccess: () => void; onCancel: () => void; initialData?: Service | null; isEdit?: boolean; onSubmitStart?: () => void; } export function ServiceForm({ onSuccess, onCancel, initialData, isEdit = false, onSubmitStart }: ServiceFormProps) { const { toast } = useToast(); const [isSubmitting, setIsSubmitting] = useState(false); // Initialize form with default values const form = useForm({ resolver: zodResolver(serviceSchema), defaultValues: { name: "", type: "http", url: "", port: "", interval: "60", retries: "3", notificationChannel: "", alertTemplate: "", }, mode: "onBlur", }); // Populate form when initialData changes (separate from initialization) useEffect(() => { if (initialData && isEdit) { // Ensure the type is one of the allowed values const serviceType = (initialData.type || "http").toLowerCase(); const validType = ["http", "ping", "tcp", "dns"].includes(serviceType) ? serviceType as "http" | "ping" | "tcp" | "dns" : "http"; // For PING services, use host field; for DNS use domain field; for TCP use host field; others use url let urlValue = ""; let portValue = ""; if (validType === "ping") { urlValue = initialData.host || ""; } else if (validType === "dns") { urlValue = initialData.domain || ""; } else if (validType === "tcp") { urlValue = initialData.host || ""; portValue = String(initialData.port || ""); } else { urlValue = initialData.url || ""; } // Reset the form with initial data values form.reset({ name: initialData.name || "", type: validType, url: urlValue, port: portValue, interval: String(initialData.interval || 60), retries: String(initialData.retries || 3), notificationChannel: initialData.notificationChannel === "none" ? "" : initialData.notificationChannel || "", alertTemplate: initialData.alertTemplate === "default" ? "" : initialData.alertTemplate || "", }); // Log for debugging console.log("Populating form with data:", { type: validType, url: urlValue, port: portValue }); } }, [initialData, isEdit, form]); const handleSubmit = async (data: ServiceFormData) => { if (isSubmitting) return; setIsSubmitting(true); if (onSubmitStart) onSubmitStart(); try { console.log("Form data being submitted:", data); // Debug log for submitted data // Prepare service data with proper field mapping const serviceData = { name: data.name, type: data.type, interval: parseInt(data.interval), retries: parseInt(data.retries), notificationChannel: data.notificationChannel === "none" ? "" : data.notificationChannel, alertTemplate: data.alertTemplate === "default" ? "" : data.alertTemplate, // Map the URL field to appropriate database field based on service type ...(data.type === "dns" ? { domain: data.url, url: "", host: "", port: undefined } // DNS: store in domain field : data.type === "ping" ? { host: data.url, url: "", domain: "", port: undefined } // PING: store in host field : data.type === "tcp" ? { host: data.url, port: parseInt(data.port || "80"), url: "", domain: "" } // TCP: store in host and port fields : { url: data.url, domain: "", host: "", port: undefined } // HTTP: store in url field ) }; if (isEdit && initialData) { // Update existing service await serviceService.updateService(initialData.id, serviceData); toast({ title: "Service updated", description: `${data.name} has been updated successfully.`, }); } else { // Create new service await serviceService.createService(serviceData); toast({ title: "Service created", description: `${data.name} has been added to monitoring.`, }); } onSuccess(); if (!isEdit) { form.reset(); } } catch (error) { console.error(`Error ${isEdit ? 'updating' : 'creating'} service:`, error); toast({ title: `Failed to ${isEdit ? 'update' : 'create'} service`, description: `An error occurred while ${isEdit ? 'updating' : 'creating'} the service.`, variant: "destructive", }); } finally { setIsSubmitting(false); } }; return (

Basic Information

Configuration

Notifications

); }