'use client'; import React, { useEffect, useMemo, useState } from 'react'; import { useSearchParams, useRouter } from 'next/navigation'; import { ArrowLeft } from 'lucide-react'; import FormTemplateBuilder from '@/components/Form/FormTemplateBuilder'; import { useEstablishment } from '@/context/EstablishmentContext'; import { useCsrfToken } from '@/context/CsrfContext'; import { fetchRegistrationFileGroups, fetchRegistrationSchoolFileMasterById, createRegistrationSchoolFileMaster, editRegistrationSchoolFileMaster, } from '@/app/actions/registerFileGroupAction'; import { getSecureFileUrl } from '@/utils/fileUrl'; import logger from '@/utils/logger'; import { useNotification } from '@/context/NotificationContext'; import { FE_ADMIN_STRUCTURE_URL } from '@/utils/Url'; export default function FormBuilderPage() { const searchParams = useSearchParams(); const router = useRouter(); const { selectedEstablishmentId } = useEstablishment(); const csrfToken = useCsrfToken(); const { showNotification } = useNotification(); const formId = searchParams.get('id'); const preGroupId = searchParams.get('groupId'); const isEditing = !!formId; const [groups, setGroups] = useState([]); const [initialData, setInitialData] = useState(null); const [loading, setLoading] = useState(true); const [uploadedFile, setUploadedFile] = useState(null); const [existingFileUrl, setExistingFileUrl] = useState(null); const normalizeBackendFile = (rawFile, rawFileUrl) => { if (typeof rawFileUrl === 'string' && rawFileUrl.trim()) { return rawFileUrl; } if (typeof rawFile === 'string' && rawFile.trim()) { return rawFile; } if (rawFile && typeof rawFile === 'object') { if (typeof rawFile.url === 'string' && rawFile.url.trim()) { return rawFile.url; } if (typeof rawFile.path === 'string' && rawFile.path.trim()) { return rawFile.path; } if (typeof rawFile.name === 'string' && rawFile.name.trim()) { return rawFile.name; } } return null; }; const previewFileUrl = useMemo(() => { if (uploadedFile instanceof File) { return URL.createObjectURL(uploadedFile); } return existingFileUrl || null; }, [uploadedFile, existingFileUrl]); useEffect(() => { return () => { if (previewFileUrl && previewFileUrl.startsWith('blob:')) { URL.revokeObjectURL(previewFileUrl); } }; }, [previewFileUrl]); useEffect(() => { if (!selectedEstablishmentId) return; Promise.all([ fetchRegistrationFileGroups(selectedEstablishmentId), formId ? fetchRegistrationSchoolFileMasterById(formId) : Promise.resolve(null), ]) .then(([groupsData, formData]) => { setGroups(groupsData || []); if (formData) { setInitialData(formData); const resolvedFile = normalizeBackendFile( formData.file, formData.file_url ); if (resolvedFile) { setExistingFileUrl(resolvedFile); } } else if (preGroupId) { setInitialData({ groups: [{ id: Number(preGroupId) }] }); } }) .catch((err) => { logger.error('Error loading FormBuilder data:', err); }) .finally(() => { setLoading(false); }); }, [selectedEstablishmentId, formId, preGroupId]); const buildFormData = async (name, group_ids, formMasterData) => { const dataToSend = new FormData(); dataToSend.append( 'data', JSON.stringify({ name, groups: group_ids, formMasterData, establishment: selectedEstablishmentId, }) ); if (uploadedFile instanceof File) { const ext = uploadedFile.name.lastIndexOf('.') !== -1 ? uploadedFile.name.substring(uploadedFile.name.lastIndexOf('.')) : ''; const cleanName = (name || 'document') .replace(/[^a-zA-Z0-9_\-]/g, '_') .replace(/_+/g, '_') .replace(/^_+|_+$/g, ''); dataToSend.append('file', uploadedFile, `${cleanName}${ext}`); } else if (existingFileUrl && isEditing) { const lastDot = existingFileUrl.lastIndexOf('.'); const ext = lastDot !== -1 ? existingFileUrl.substring(lastDot) : ''; const cleanName = (name || 'document') .replace(/[^a-zA-Z0-9_\-]/g, '_') .replace(/_+/g, '_') .replace(/^_+|_+$/g, ''); try { const resp = await fetch(getSecureFileUrl(existingFileUrl)); if (resp.ok) { const blob = await resp.blob(); dataToSend.append('file', blob, `${cleanName}${ext}`); } } catch (e) { logger.error('Could not re-fetch existing file:', e); } } return dataToSend; }; const handleSave = async ({ name, group_ids, formMasterData, id }) => { const hasFileField = (formMasterData?.fields || []).some( (field) => field.type === 'file' ); const hasUploadedDocument = uploadedFile instanceof File || Boolean(existingFileUrl); if (hasFileField && !hasUploadedDocument) { showNotification( 'Un document PDF doit être uploadé si le formulaire contient un champ fichier.', 'error', 'Erreur' ); return; } try { const dataToSend = await buildFormData(name, group_ids, formMasterData); if (isEditing) { await editRegistrationSchoolFileMaster(id || formId, dataToSend, csrfToken); showNotification( `Le formulaire "${name}" a été modifié avec succès.`, 'success', 'Succès' ); } else { await createRegistrationSchoolFileMaster(dataToSend, csrfToken); showNotification( `Le formulaire "${name}" a été créé avec succès.`, 'success', 'Succès' ); } router.push(FE_ADMIN_STRUCTURE_URL); } catch (err) { logger.error('Error saving form:', err); showNotification('Erreur lors de la sauvegarde du formulaire', 'error', 'Erreur'); } }; if (loading) { return (
Chargement...