// DocumentForm.js import React, { useState, useEffect } from "react"; import { z } from "zod"; // Helper function to format file size // const formatFileSize = (bytes) => { // if (bytes === 0) return "0 Bytes"; // const k = 1024; // const sizes = ["Bytes", "KB", "MB", "GB", "TB"]; // const i = Math.floor(Math.log(bytes) / Math.log(k)); // return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; // }; // Define the Zod schema for the form const DocumentSchema = z.object({ name: z.string().min(1, { message: "Document Name is required." }), documentNumber: z.string().min(1, { message: "Document Number is required." }), category: z.enum(["public", "private"], { errorMap: () => ({ message: "Category is required." }), }), documentType: z.string().min(1, { message: "Document Type is required." }), files: z .array(z.any()) .min(1, { message: "At least one file must be uploaded." }) .refine( (files) => files.every((file) => file.fileSize <= 5 * 1024 * 1024), { message: "File size exceeds 5MB.", } ), }); const DocumentForm = ({ initialData, onSave, onCancel }) => { const formKey = initialData ? initialData.name : "new"; const [formData, setFormData] = useState({ name: "", documentNumber: "", category: "", documentType: "", files: initialData ? initialData.files || [] : [], ...initialData, }); const [files, setFiles] = useState(initialData?.files || []); const [errors, setErrors] = useState({}); useEffect(() => { if (initialData && initialData.files) { setFiles(initialData.files); } }, [initialData]); const handleChange = (e) => { const { name, value } = e.target; setFormData((prevData) => ({ ...prevData, [name]: value, })); }; const onFileChange = (e) => { const newFiles = Array.from(e.target.files).map((file) => ({ file, fileName: file.name, fileSize: file.size, preSignedUrl: URL.createObjectURL(file), })); setFiles((prevFiles) => [...prevFiles, ...newFiles]); }; const removeFile = (fileToRemove) => { setFiles((prevFiles) => prevFiles.filter((file) => file !== fileToRemove)); }; const handleSubmit = (e) => { e.preventDefault(); const validationData = { ...formData, files, }; const result = DocumentSchema.safeParse(validationData); if (result.success) { setErrors({}); onSave({ ...formData, files }); } else { const fieldErrors = result.error.flatten().fieldErrors; const fileErrors = fieldErrors.files ? [{ message: fieldErrors.files.join(", ") }] : []; setErrors({ ...fieldErrors, billAttachments: fileErrors, }); } }; return (
{initialData ? "Edit Document" : "Create Document"}
{/* Document Name */}
{errors.name && (
{errors.name}
)}
{/* Document Number */}
{errors.documentNumber && (
{errors.documentNumber}
)}
{/* Category Dropdown */}
{errors.category && (
{errors.category}
)}
{/* Document Type Dropdown */}
{errors.documentType && (
{errors.documentType}
)}
{/* File Uploader */}
document.getElementById("billAttachments").click() } > Click to select or click here to browse (PDF, JPG, PNG, max 5MB) (e.target.value = null)} />
{errors.billAttachments && (
{errors.billAttachments.map((err, idx) => (
{err.message || err.fileSize?.message}
))}
)} {files.length > 0 && ( )}
{/* Buttons */}
); }; export default DocumentForm;