= {};
fields.forEach(f => { initialState[f.name] = f.defaultValue || ""; });
const [formData, setFormData] = useState(initialState);
const handleChange = (name: string, value: any) => {
setFormData(prev => ({ ...prev, [name]: value }));
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
// Basic validation
for (const field of fields) {
if (field.required && !formData[field.name]) {
toast({
title: "Required field",
description: `Please fill in ${field.label}`,
variant: "destructive",
});
return;
}
if (field.type === "email" && formData[field.name] && !formData[field.name].includes("@")) {
toast({
title: "Invalid email",
description: "Please enter a valid email address",
variant: "destructive",
});
return;
}
}
try {
const result = await mutate(formData);
setSubmitted(true);
toast({ title: "Success", description: successMessage });
setFormData(initialState);
onSuccess?.(result);
// Reset submitted state after 3 seconds
setTimeout(() => setSubmitted(false), 3000);
} catch (err) {
toast({
title: "Error",
description: "Something went wrong. Please try again.",
variant: "destructive",
});
}
};
const renderField = (field: FormField) => {
const id = `form-${collection}-${field.name}`;
return (
{field.type === "textarea" ? (
);
};
return (
);
}