import React, { useState, useEffect } from 'react'; import { Plus, Download, Edit3, Trash2, FolderPlus, Signature, FileText, Check, X } from 'lucide-react'; import Modal from '@/components/Modal'; import Table from '@/components/Table'; import FileUploadDocuSeal from '@/components/Structure/Files/FileUploadDocuSeal'; import { BASE_URL } from '@/utils/Url'; import { // GET fetchRegistrationFileGroups, fetchRegistrationSchoolFileMasters, fetchRegistrationSchoolFileTemplates, fetchRegistrationParentFileMasters, // POST createRegistrationFileGroup, createRegistrationSchoolFileMaster, createRegistrationParentFileMaster, // PUT editRegistrationFileGroup, editRegistrationSchoolFileMaster, editRegistrationParentFileMaster, // DELETE deleteRegistrationFileGroup, deleteRegistrationSchoolFileMaster, deleteRegistrationParentFileMaster, } from '@/app/actions/registerFileGroupAction'; import RegistrationFileGroupForm from '@/components/Structure/Files/RegistrationFileGroupForm'; import logger from '@/utils/logger'; import ParentFilesSection from '@/components/Structure/Files/ParentFilesSection'; export default function FilesGroupsManagement({ csrfToken, selectedEstablishmentId }) { const [schoolFileMasters, setSchoolFileMasters] = useState([]); const [schoolFileTemplates, setSchoolFileTemplates] = useState([]); const [parentFiles, setParentFileMasters] = useState([]); const [groups, setGroups] = useState([]); const [selectedGroup, setSelectedGroup] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [isEditing, setIsEditing] = useState(false); const [fileToEdit, setFileToEdit] = useState(null); const [isGroupModalOpen, setIsGroupModalOpen] = useState(false); const [groupToEdit, setGroupToEdit] = useState(null); const [reloadTemplates, setReloadTemplates] = useState(false); const [editingDocumentId, setEditingDocumentId] = useState(null); const [formData, setFormData] = useState({}); const handleReloadTemplates = () => { setReloadTemplates(true); } const transformFileData = (file, groups) => { const groupInfos = file.groups.map(groupId => groups.find(g => g.id === groupId) || { id: groupId, name: 'Groupe inconnu' }); return { ...file, groups: groupInfos }; }; useEffect(() => { if (selectedEstablishmentId) { Promise.all([ fetchRegistrationSchoolFileMasters(), fetchRegistrationFileGroups(selectedEstablishmentId), fetchRegistrationSchoolFileTemplates(), fetchRegistrationParentFileMasters() ]).then(([dataSchoolFileMasters, groupsData, dataSchoolFileTemplates, dataParentFileMasters]) => { setGroups(groupsData); setSchoolFileTemplates(dataSchoolFileTemplates); setParentFileMasters(dataParentFileMasters); // Transformer chaque fichier pour inclure les informations complètes du groupe const transformedFiles = dataSchoolFileMasters.map(file => transformFileData(file, groupsData)); setSchoolFileMasters(transformedFiles); }).catch(err => { console.log(err.message); }).finally(() => { setReloadTemplates(false); }); } }, [reloadTemplates, selectedEstablishmentId]); const deleteTemplateMaster = (templateMaster) => { // Supprimer les clones associés via l'API DocuSeal const removeClonesPromises = schoolFileTemplates .filter(template => template.master === templateMaster.id) .map(template => removeTemplate(template.id)); // Ajouter la suppression du master à la liste des promesses removeClonesPromises.push(removeTemplate(templateMaster.id)); // Attendre que toutes les suppressions dans DocuSeal soient terminées Promise.all(removeClonesPromises) .then(responses => { const allSuccessful = responses.every(response => response.ok); if (allSuccessful) { logger.debug('Master et clones supprimés avec succès de DocuSeal.'); // Supprimer le template master de la base de données deleteRegistrationSchoolFileMaster(templateMaster.id, csrfToken) .then(response => { if (response.ok) { setSchoolFileMasters(schoolFileMasters.filter(fichier => fichier.id !== templateMaster.id)); alert('Fichier supprimé avec succès.'); } else { alert('Erreur lors de la suppression du fichier dans la base de données.'); } }) .catch(error => { console.error('Error deleting file from database:', error); alert('Erreur lors de la suppression du fichier dans la base de données.'); }); } else { alert('Erreur lors de la suppression du master ou des clones dans DocuSeal.'); } }) .catch(error => { console.error('Error removing template from DocuSeal:', error); alert('Erreur lors de la suppression du master ou des clones dans DocuSeal.'); }); }; const removeTemplate = (templateId) => { return fetch('/api/docuseal/removeTemplate/', { method: 'DELETE', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrfToken }, body: JSON.stringify({ templateId }) }) .then(response => { if (!response.ok) { return response.json().then(err => { throw new Error(err.message); }); } return response; }) .catch(error => { console.error('Error removing template:', error); throw error; }); }; const editTemplateMaster = (file) => { setIsEditing(true); setFileToEdit(file); setIsModalOpen(true); }; const handleCreateTemplateMaster = ({name, group_ids, id, is_required}) => { const data = { name: name, id: id, groups: group_ids, is_required: is_required }; logger.debug(data); createRegistrationSchoolFileMaster(data, csrfToken) .then(data => { // Transformer le nouveau fichier avec les informations du groupe const transformedFile = transformFileData(data, groups); setSchoolFileMasters(prevFiles => [...prevFiles, transformedFile]); setIsModalOpen(false); }) .catch(error => { console.error('Error uploading file:', error); }); }; const handleEditTemplateMaster = ({name, group_ids, id, is_required}) => { const data = { name: name, id: id, groups: group_ids, is_required: is_required }; logger.debug(data); editRegistrationSchoolFileMaster(id, data, csrfToken) .then(data => { // Transformer le fichier mis à jour avec les informations du groupe const transformedFile = transformFileData(data, groups); setSchoolFileMasters(prevFichiers => prevFichiers.map(f => f.id === id ? transformedFile : f) ); setIsModalOpen(false); }) .catch(error => { console.error('Error editing file:', error); alert('Erreur lors de la modification du fichier'); }); }; const handleGroupSubmit = (groupData) => { if (groupToEdit) { editRegistrationFileGroup(groupToEdit.id, groupData, csrfToken) .then(updatedGroup => { setGroups(groups.map(group => group.id === groupToEdit.id ? updatedGroup : group)); setGroupToEdit(null); setIsGroupModalOpen(false); }) .catch(error => { console.error('Error handling group:', error); alert('Erreur lors de l\'opération sur le groupe'); }); } else { // Ajouter l'établissement sélectionné lors de la création d'un nouveau groupe const newGroupData = { ...groupData, establishment: selectedEstablishmentId }; createRegistrationFileGroup(newGroupData, csrfToken) .then(newGroup => { setGroups([...groups, newGroup]); setIsGroupModalOpen(false); }) .catch(error => { console.error('Error handling group:', error); alert('Erreur lors de l\'opération sur le groupe'); }); } }; const handleGroupEdit = (group) => { setGroupToEdit(group); setIsGroupModalOpen(true); }; const handleGroupDelete = (groupId) => { // Vérifier si des schoolFileMasters utilisent ce groupe const filesInGroup = schoolFileMasters.filter(file => file.group && file.group.id === groupId); if (filesInGroup.length > 0) { alert('Impossible de supprimer ce groupe car il contient des schoolFileMasters. Veuillez d\'abord retirer tous les schoolFileMasters de ce groupe.'); return; } if (window.confirm('Êtes-vous sûr de vouloir supprimer ce groupe ?')) { deleteRegistrationFileGroup(groupId, csrfToken) .then((response) => { if (response.status === 409) { throw new Error('Ce groupe est lié à des inscriptions existantes.'); } if (!response.ok) { throw new Error('Erreur lors de la suppression du groupe.'); } setGroups(groups.filter(group => group.id !== groupId)); alert('Groupe supprimé avec succès.'); }) .catch(error => { console.error('Error deleting group:', error); alert(error.message || 'Erreur lors de la suppression du groupe. Vérifiez qu\'aucune inscription n\'utilise ce groupe.'); }); } }; const renderRequiredDocumentCell = (document, column) => { const isEditing = editingDocumentId === document.id; if (isEditing) { switch (column) { case 'Nom de la pièce': return ( handleChange(e, 'name')} placeholder="Nom de la pièce" className="w-full" /> ); case 'Description': return ( handleChange(e, 'description')} placeholder="Description" className="w-full" /> ); case 'Actions': return (
); default: return null; } } else { switch (column) { case 'Nom de la pièce': return {document.name}; case 'Description': return {document.description}; case 'Actions': return (
); default: return null; } } }; const handleCreate = (newParentFile) => { return createRegistrationParentFileMaster(newParentFile, csrfToken) .then((createdFile) => { // Ajouter le nouveau fichier parent à la liste existante setParentFileMasters((prevFiles) => [...prevFiles, createdFile]); logger.debug('Document parent créé avec succès:', createdFile); }) .catch((error) => { logger.error('Erreur lors de la création du document parent:', error); alert('Une erreur est survenue lors de la création du document parent.'); }); }; const handleEdit = (id, updatedFile) => { return editRegistrationParentFileMaster(id, updatedFile, csrfToken) .then((response) => { const modifiedFile = response.data; // Extraire les données mises à jour // Mettre à jour la liste des fichiers parents setParentFileMasters((prevFiles) => prevFiles.map((file) => (file.id === id ? modifiedFile : file)) ); logger.debug('Document parent mis à jour avec succès:', modifiedFile); return modifiedFile; // Retourner le fichier mis à jour }) .catch((error) => { logger.error('Erreur lors de la modification du document parent:', error); alert('Une erreur est survenue lors de la modification du document parent.'); throw error; }); }; const handleDelete = (id) => { return deleteRegistrationParentFileMaster(id, csrfToken) .then(() => { // Mettre à jour la liste des fichiers parents en supprimant l'élément correspondant setParentFileMasters((prevFiles) => prevFiles.filter((file) => file.id !== id)); logger.debug('Document parent supprimé avec succès:', id); }) .catch((error) => { logger.error('Erreur lors de la suppression du fichier parent:', error); }); }; const filteredFiles = schoolFileMasters.filter(file => { if (!selectedGroup) return true; return file.groups && file.groups.some(group => group.id === parseInt(selectedGroup)); }); const columnsFiles = [ { name: 'Nom du formulaire', transform: (row) => row.name }, { name: 'Dossiers d\'inscription', transform: (row) => row.groups && row.groups.length > 0 ? row.groups.map(group => group.name).join(', ') : 'Aucun' }, { name: 'Actions', transform: (row) => (
{row.file && ( )}
)} ]; const columnsGroups = [ { name: 'Nom du dossier', transform: (row) => row.name }, { name: 'Description', transform: (row) => row.description }, { name: 'Actions', transform: (row) => (
)} ]; const columnsRequiredDocuments = [ { name: 'Nom de la pièce', transform: (row) => renderRequiredDocumentCell(row, 'Nom de la pièce') }, { name: 'Description', transform: (row) => renderRequiredDocumentCell(row, 'Description') }, { name: 'Actions', transform: (row) => renderRequiredDocumentCell(row, 'Actions') }, ]; return (
{/* Modal pour les fichiers */} { setIsModalOpen(isOpen); if (!isOpen) { setFileToEdit(null); } }} title={isEditing ? 'Modification du document' : 'Ajouter un document'} ContentComponent={() => ( )} modalClassName="w-4/5 h-4/5" /> {/* Modal pour les groupes */} ( )} /> {/* Section Groupes de fichiers */}

Dossiers d'inscriptions

Gérez les dossiers d'inscription pour organiser vos documents.

{/* Section Fichiers */}

Formulaires à remplir

Gérez les formulaires nécessitant une signature électronique.

{/* Section Pièces à fournir */} ); }