"use client"; import React, { useEffect, useState } from "react"; import { PeopleSchema, PeopleFormData, CreatePeopleSchema, UpdatePeopleSchema, ViewPeopleSchema, fieldDefinitions, fieldsByMode, } from "./schema"; import { getTranslation, LanguageKey } from "./language"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { cn } from "@/lib/utils"; interface FormComponentProps { lang: LanguageKey; mode: "create" | "update" | "view"; onCancel: () => void; refetch: () => void; setMode: React.Dispatch< React.SetStateAction<"list" | "create" | "view" | "update"> >; setSelectedItem: React.Dispatch>; initialData?: Partial; } export function FormComponent({ lang, mode, onCancel, refetch, setMode, setSelectedItem, initialData, }: FormComponentProps) { // Derive readOnly from mode const readOnly = mode === "view"; const t = getTranslation(lang); const [formSubmitting, setFormSubmitting] = useState(false); // Select the appropriate schema based on the mode const getSchemaForMode = () => { switch (mode) { case "create": return CreatePeopleSchema; case "update": return UpdatePeopleSchema; case "view": return ViewPeopleSchema; default: return PeopleSchema; } }; // Get field definitions for the current mode const modeFieldDefinitions = fieldDefinitions.getDefinitionsByMode( mode ) as Record; // Define FormValues type based on the current mode to fix TypeScript errors type FormValues = Record; // Get default values directly from the field definitions const getDefaultValues = (): FormValues => { // For view and update modes, use initialData if available if ((mode === "view" || mode === "update") && initialData) { return initialData as FormValues; } // For create mode or when initialData is not available, use default values from schema const defaults: FormValues = {}; Object.entries(modeFieldDefinitions).forEach(([key, field]) => { if (field && typeof field === "object" && "defaultValue" in field) { defaults[key] = field.defaultValue; } }); return defaults; }; // Define form with react-hook-form and zod validation const form = useForm({ resolver: zodResolver(getSchemaForMode()) as any, // Type assertion to fix TypeScript errors defaultValues: getDefaultValues(), mode: "onChange", }); // Update form values when initialData changes useEffect(() => { if (initialData && (mode === "update" || mode === "view")) { // Reset the form with initialData form.reset(initialData as FormValues); } }, [initialData, form, mode]); // Define the submission handler function const onSubmitHandler = async (data: FormValues) => { setFormSubmitting(true); try { // Call different API methods based on the current mode if (mode === "create") { // Call create API console.log("Creating new record:", data); // Simulate API call await new Promise((resolve) => setTimeout(resolve, 1000)); // In a real application, you would call your API here // Example: await createPerson(data); } else if (mode === "update") { // Call update API console.log("Updating existing record:", data); // Simulate API call await new Promise((resolve) => setTimeout(resolve, 1000)); // In a real application, you would call your API here // Example: await updatePerson(data); } // Show success message or notification here // Return to list view and reset selected item handleReturnToList(); // Refresh data refetch(); } catch (error) { // Handle any errors from the API calls console.error("Error saving data:", error); // You could set an error state here to display to the user } finally { setFormSubmitting(false); } }; // Helper function to return to list view const handleReturnToList = () => { setMode("list"); setSelectedItem(null); }; // Handle cancel button click const handleCancel = () => { onCancel(); // Return to list view handleReturnToList(); }; // Filter fields based on the current mode const activeFields = fieldsByMode[readOnly ? "view" : mode]; // Group fields by their section using mode-specific field definitions const fieldGroups = activeFields.reduce( (groups: Record, fieldName: string) => { const field = modeFieldDefinitions[fieldName]; if (field && typeof field === "object" && "group" in field) { const group = field.group as string; if (!groups[group]) { groups[group] = []; } groups[group].push({ name: fieldName, type: field.type as string, readOnly: (field.readOnly as boolean) || readOnly, // Combine component readOnly with field readOnly required: (field.required as boolean) || false, label: (field.label as string) || fieldName, }); } return groups; }, {} as Record< string, { name: string; type: string; readOnly: boolean; required: boolean; label: string; }[] > ); // Create helper variables for field group checks const hasIdentificationFields = fieldGroups.identificationInfo?.length > 0; const hasPersonalFields = fieldGroups.personalInfo?.length > 0; const hasLocationFields = fieldGroups.locationInfo?.length > 0; const hasExpiryFields = fieldGroups.expiryInfo?.length > 0; const hasStatusFields = fieldGroups.statusInfo?.length > 0; return (
{formSubmitting && (
{mode === "create" ? t.creating : t.updating}...
)}

{t.title || "Person Details"}

{readOnly ? t.view : initialData?.uu_id ? t.update : t.createNew}

{/* Identification Information Section */} {hasIdentificationFields && (

Identification

{fieldGroups.identificationInfo.map((field) => ( ( {field.label} {field.required && ( * )} {field.type === "checkbox" ? ( ) : field.type === "date" ? ( ) : ( )} {field.name ? (t as any)[`form.descriptions.${field.name}`] || "" : ""} )} /> ))}
)} {/* Personal Information Section */} {hasPersonalFields && (

Personal Information

{fieldGroups.personalInfo.map((field) => ( ( {field.label} {field.required && ( * )} {field.type === "checkbox" ? ( ) : field.type === "date" ? ( ) : ( )} {field.name ? (t as any)[`form.descriptions.${field.name}`] || "" : ""} )} /> ))}
)} {/* Location Information Section */} {hasLocationFields && (

Location Information

{fieldGroups.locationInfo.map((field) => ( ( {field.label} {field.name ? (t as any)[`form.descriptions.${field.name}`] || "" : ""} )} /> ))}
)} {/* Expiry Information Section */} {hasExpiryFields && (

Expiry Information

{fieldGroups.expiryInfo.map((field) => ( ( {field.label} {field.required && ( * )} {field.name ? (t as any)[`form.descriptions.${field.name}`] || "" : ""} )} /> ))}
)} {/* Status Information Section */} {hasStatusFields && (

Status Information

{fieldGroups.statusInfo.map((field) => ( (
{field.label} {field.required && ( * )} {field.name ? (t as any)[`form.descriptions.${field.name}`] || "" : ""}
)} /> ))}
)}
{!readOnly && ( )}
); }