mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
344 lines
12 KiB
JavaScript
344 lines
12 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { Plus, Download, Edit, Trash2, FolderPlus, Signature } from 'lucide-react';
|
|
import Modal from '@/components/Modal';
|
|
import Table from '@/components/Table';
|
|
import FileUpload from '@/components/FileUpload';
|
|
import { formatDate } from '@/utils/Date';
|
|
import { BASE_URL } from '@/utils/Url';
|
|
import {
|
|
fetchRegisterFormFileTemplate,
|
|
createRegistrationFormFileTemplate,
|
|
editRegistrationFormFileTemplate,
|
|
deleteRegisterFormFileTemplate,
|
|
getRegisterFormFileTemplate
|
|
} from '@/app/actions/subscriptionAction';
|
|
import {
|
|
fetchRegistrationFileGroups,
|
|
createRegistrationFileGroup,
|
|
deleteRegistrationFileGroup,
|
|
editRegistrationFileGroup
|
|
} from '@/app/actions/registerFileGroupAction';
|
|
import RegistrationFileGroupForm from '@/components/RegistrationFileGroupForm';
|
|
import { useEstablishment } from '@/context/EstablishmentContext';
|
|
|
|
export default function FilesManagement({ csrfToken }) {
|
|
const [fichiers, setFichiers] = 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 { selectedEstablishmentId } = useEstablishment();
|
|
|
|
// Fonction pour transformer les données des fichiers avec les informations complètes du groupe
|
|
const transformFileData = (file, groups) => {
|
|
if (!file.group) return file;
|
|
|
|
const groupInfo = groups.find(g => g.id === file.group);
|
|
return {
|
|
...file,
|
|
group: groupInfo || { id: file.group, name: 'Groupe inconnu' }
|
|
};
|
|
};
|
|
|
|
useEffect(() => {
|
|
Promise.all([
|
|
fetchRegisterFormFileTemplate(),
|
|
fetchRegistrationFileGroups(selectedEstablishmentId)
|
|
]).then(([filesData, groupsData]) => {
|
|
setGroups(groupsData);
|
|
// Sélectionner automatiquement le premier groupe s'il existe
|
|
if (groupsData.length > 0) {
|
|
setSelectedGroup(groupsData[0].id.toString());
|
|
}
|
|
// Transformer chaque fichier pour inclure les informations complètes du groupe
|
|
const transformedFiles = filesData.map(file => transformFileData(file, groupsData));
|
|
setFichiers(transformedFiles);
|
|
}).catch(err => {
|
|
console.log(err.message);
|
|
});
|
|
}, []);
|
|
|
|
const handleFileDelete = (fileId) => {
|
|
deleteRegisterFormFileTemplate(fileId, csrfToken)
|
|
.then(response => {
|
|
if (response.ok) {
|
|
setFichiers(fichiers.filter(fichier => fichier.id !== fileId));
|
|
alert('Fichier supprimé avec succès.');
|
|
} else {
|
|
alert('Erreur lors de la suppression du fichier.');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error deleting file:', error);
|
|
alert('Erreur lors de la suppression du fichier.');
|
|
});
|
|
};
|
|
|
|
const handleFileEdit = (file) => {
|
|
setIsEditing(true);
|
|
setFileToEdit(file);
|
|
setIsModalOpen(true);
|
|
};
|
|
|
|
const handleFileUpload = ({file, name, is_required, order, groupId}) => {
|
|
if (!name) {
|
|
alert('Veuillez entrer un nom de fichier.');
|
|
return;
|
|
}
|
|
|
|
const formData = new FormData();
|
|
if(file) {
|
|
formData.append('file', file);
|
|
}
|
|
formData.append('name', name);
|
|
formData.append('is_required', is_required);
|
|
formData.append('order', order);
|
|
|
|
// Modification ici : vérifier si groupId existe et n'est pas vide
|
|
if (groupId && groupId !== '') {
|
|
formData.append('group', groupId); // Notez que le nom du champ est 'group' et non 'group_id'
|
|
}
|
|
|
|
if (isEditing && fileToEdit) {
|
|
editRegistrationFormFileTemplate(fileToEdit.id, formData, csrfToken)
|
|
.then(data => {
|
|
// Transformer le fichier mis à jour avec les informations du groupe
|
|
const transformedFile = transformFileData(data, groups);
|
|
setFichiers(prevFichiers =>
|
|
prevFichiers.map(f => f.id === fileToEdit.id ? transformedFile : f)
|
|
);
|
|
setIsModalOpen(false);
|
|
setFileToEdit(null);
|
|
setIsEditing(false);
|
|
})
|
|
.catch(error => {
|
|
console.error('Error editing file:', error);
|
|
alert('Erreur lors de la modification du fichier');
|
|
});
|
|
} else {
|
|
createRegistrationFormFileTemplate(formData, csrfToken)
|
|
.then(data => {
|
|
// Transformer le nouveau fichier avec les informations du groupe
|
|
const transformedFile = transformFileData(data, groups);
|
|
setFichiers(prevFiles => [...prevFiles, transformedFile]);
|
|
setIsModalOpen(false);
|
|
})
|
|
.catch(error => {
|
|
console.error('Error uploading file:', error);
|
|
});
|
|
}
|
|
};
|
|
|
|
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 {
|
|
createRegistrationFileGroup(groupData, 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 fichiers utilisent ce groupe
|
|
const filesInGroup = fichiers.filter(file => file.group && file.group.id === groupId);
|
|
if (filesInGroup.length > 0) {
|
|
alert('Impossible de supprimer ce groupe car il contient des fichiers. Veuillez d\'abord retirer tous les fichiers 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.');
|
|
});
|
|
}
|
|
};
|
|
|
|
// Ajouter cette fonction de filtrage
|
|
const filteredFiles = fichiers.filter(file => {
|
|
if (!selectedGroup) return true;
|
|
return file.group && file.group.id === parseInt(selectedGroup);
|
|
});
|
|
|
|
const columnsFiles = [
|
|
{ name: 'Nom du fichier', transform: (row) => row.name },
|
|
{ name: 'Groupe', transform: (row) => row.group ? row.group.name : 'Aucun' },
|
|
{ name: 'Date de création', transform: (row) => formatDate(new Date (row.date_added),"DD/MM/YYYY hh:mm:ss") },
|
|
{ name: 'Fichier Obligatoire', transform: (row) => row.is_required ? 'Oui' : 'Non' },
|
|
{ name: 'Ordre de fusion', transform: (row) => row.order },
|
|
{ name: 'Actions', transform: (row) => (
|
|
<div className="flex items-center justify-center gap-2">
|
|
{row.file && (
|
|
<a href={`${BASE_URL}${row.file}`} target='_blank' className="text-blue-500 hover:text-blue-700">
|
|
<Download size={16} />
|
|
</a>
|
|
)}
|
|
<button onClick={() => handleFileEdit(row)} className="text-blue-500 hover:text-blue-700">
|
|
<Edit size={16} />
|
|
</button>
|
|
<button onClick={() => handleFileDelete(row.id)} className="text-red-500 hover:text-red-700">
|
|
<Trash2 size={16} />
|
|
</button>
|
|
<button onClick={() => handleSignatureRequest(row)} className="text-green-500 hover:text-green-700">
|
|
<Signature size={16} />
|
|
</button>
|
|
</div>
|
|
)}
|
|
];
|
|
|
|
const columnsGroups = [
|
|
{ name: 'Nom du groupe', transform: (row) => row.name },
|
|
{ name: 'Description', transform: (row) => row.description },
|
|
{ name: 'Actions', transform: (row) => (
|
|
<div className="flex items-center justify-center gap-2">
|
|
<button onClick={() => handleGroupEdit(row)} className="text-blue-500 hover:text-blue-700">
|
|
<Edit size={16} />
|
|
</button>
|
|
<button onClick={() => handleGroupDelete(row.id)} className="text-red-500 hover:text-red-700">
|
|
<Trash2 size={16} />
|
|
</button>
|
|
</div>
|
|
)}
|
|
];
|
|
|
|
// Fonction pour gérer la demande de signature
|
|
const handleSignatureRequest = (file) => {
|
|
const formData = new FormData();
|
|
formData.append('file', file);
|
|
console.log('Demande de signature pour le fichier :', file);
|
|
|
|
fetch('http://localhost:8080:/DocuSeal/generateToken', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': 'Bearer NFPZy6BBGvYs1BwTuXMQ3XAu5N1kLFiXWftGQhkiz2A',
|
|
},
|
|
body: formData,
|
|
})
|
|
.then((response) => {
|
|
if (!response.ok) {
|
|
throw new Error('Erreur lors du téléversement du document : ' + response.statusText);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then((data) => {
|
|
const documentId = data.documentId;
|
|
console.log('Document téléversé avec succès, ID :', documentId);
|
|
onUpload(documentId);
|
|
});
|
|
.catch((error) => console.error(error));
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<Modal
|
|
isOpen={isModalOpen}
|
|
setIsOpen={setIsModalOpen}
|
|
title={isEditing ? 'Modifier un fichier' : 'Ajouter un fichier'}
|
|
ContentComponent={() => (
|
|
<FileUpload
|
|
onFileUpload={handleFileUpload}
|
|
fileToEdit={fileToEdit}
|
|
/>
|
|
)}
|
|
/>
|
|
<Modal
|
|
isOpen={isGroupModalOpen}
|
|
setIsOpen={setIsGroupModalOpen}
|
|
title={groupToEdit ? "Modifier le groupe" : "Ajouter un groupe de fichiers"}
|
|
ContentComponent={() => (
|
|
<RegistrationFileGroupForm
|
|
onSubmit={handleGroupSubmit}
|
|
initialData={groupToEdit}
|
|
/>
|
|
)}
|
|
/>
|
|
<div className="mt-8 mb-4">
|
|
<div className="flex justify-between items-center mb-4">
|
|
<h2 className="text-xl font-bold">Groupes de fichiers</h2>
|
|
<button
|
|
onClick={() => setIsGroupModalOpen(true)}
|
|
className="flex items-center bg-blue-600 text-white p-2 rounded-full shadow hover:bg-blue-900 transition duration-200"
|
|
>
|
|
<FolderPlus className="w-5 h-5" />
|
|
</button>
|
|
</div>
|
|
<Table
|
|
data={groups}
|
|
columns={columnsGroups}
|
|
itemsPerPage={5}
|
|
currentPage={1}
|
|
totalPages={Math.ceil(groups.length / 5)}
|
|
/>
|
|
</div>
|
|
{groups.length > 0 && (
|
|
<div className="mt-8">
|
|
<div className="flex justify-between items-center mb-4">
|
|
<h2 className="text-xl font-bold">Fichiers</h2>
|
|
<div className="flex items-center gap-4">
|
|
<select
|
|
className="border rounded p-2"
|
|
value={selectedGroup || ''}
|
|
onChange={(e) => setSelectedGroup(e.target.value)}
|
|
>
|
|
<option value="">Tous les groupes</option>
|
|
{groups.map(group => (
|
|
<option key={group.id} value={group.id}>{group.name}</option>
|
|
))}
|
|
</select>
|
|
<button
|
|
onClick={() => { setIsModalOpen(true); setIsEditing(false); }}
|
|
className="flex items-center bg-emerald-600 text-white p-2 rounded-full shadow hover:bg-emerald-900 transition duration-200"
|
|
>
|
|
<Plus className="w-5 h-5" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<Table
|
|
data={filteredFiles}
|
|
columns={columnsFiles}
|
|
itemsPerPage={10}
|
|
currentPage={1}
|
|
totalPages={Math.ceil(filteredFiles.length / 10)}
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|