mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-28 23:43:22 +00:00
Merge remote-tracking branch 'origin/WIP_Inscriptions' into develop
This commit is contained in:
@ -1,36 +1,40 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
Plus,
|
||||
Download,
|
||||
Edit3,
|
||||
Trash2,
|
||||
FolderPlus,
|
||||
Signature,
|
||||
} from 'lucide-react';
|
||||
import { Download, Edit3, Trash2, FolderPlus, Signature } from 'lucide-react';
|
||||
import Modal from '@/components/Modal';
|
||||
import Table from '@/components/Table';
|
||||
import FileUpload from '@/components/Structure/Files/FileUpload';
|
||||
import FileUploadDocuSeal from '@/components/Structure/Files/FileUploadDocuSeal';
|
||||
import { BASE_URL } from '@/utils/Url';
|
||||
import {
|
||||
// GET
|
||||
fetchRegistrationFileGroups,
|
||||
fetchRegistrationSchoolFileMasters,
|
||||
fetchRegistrationSchoolFileTemplates,
|
||||
fetchRegistrationParentFileMasters,
|
||||
// POST
|
||||
createRegistrationFileGroup,
|
||||
deleteRegistrationFileGroup,
|
||||
createRegistrationSchoolFileMaster,
|
||||
createRegistrationParentFileMaster,
|
||||
// PUT
|
||||
editRegistrationFileGroup,
|
||||
fetchRegistrationTemplateMaster,
|
||||
createRegistrationTemplateMaster,
|
||||
editRegistrationTemplateMaster,
|
||||
deleteRegistrationTemplateMaster,
|
||||
fetchRegistrationTemplates,
|
||||
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';
|
||||
import SectionHeader from '@/components/SectionHeader';
|
||||
|
||||
export default function FilesGroupsManagement({
|
||||
csrfToken,
|
||||
selectedEstablishmentId,
|
||||
}) {
|
||||
const [templateMasters, setTemplateMasters] = useState([]);
|
||||
const [templates, setTemplates] = useState([]);
|
||||
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);
|
||||
@ -39,6 +43,10 @@ export default function FilesGroupsManagement({
|
||||
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 [uploadedFileName, setUploadedFileName] = useState('');
|
||||
|
||||
const handleReloadTemplates = () => {
|
||||
setReloadTemplates(true);
|
||||
@ -61,19 +69,28 @@ export default function FilesGroupsManagement({
|
||||
useEffect(() => {
|
||||
if (selectedEstablishmentId) {
|
||||
Promise.all([
|
||||
fetchRegistrationTemplateMaster(),
|
||||
fetchRegistrationSchoolFileMasters(),
|
||||
fetchRegistrationFileGroups(selectedEstablishmentId),
|
||||
fetchRegistrationTemplates(),
|
||||
fetchRegistrationSchoolFileTemplates(),
|
||||
fetchRegistrationParentFileMasters(),
|
||||
])
|
||||
.then(([filesTemplateMasters, groupsData, filesTemplates]) => {
|
||||
setGroups(groupsData);
|
||||
setTemplates(filesTemplates);
|
||||
// Transformer chaque fichier pour inclure les informations complètes du groupe
|
||||
const transformedFiles = filesTemplateMasters.map((file) =>
|
||||
transformFileData(file, groupsData)
|
||||
);
|
||||
setTemplateMasters(transformedFiles);
|
||||
})
|
||||
.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);
|
||||
})
|
||||
@ -85,7 +102,7 @@ export default function FilesGroupsManagement({
|
||||
|
||||
const deleteTemplateMaster = (templateMaster) => {
|
||||
// Supprimer les clones associés via l'API DocuSeal
|
||||
const removeClonesPromises = templates
|
||||
const removeClonesPromises = schoolFileTemplates
|
||||
.filter((template) => template.master === templateMaster.id)
|
||||
.map((template) => removeTemplate(template.id));
|
||||
|
||||
@ -100,11 +117,11 @@ export default function FilesGroupsManagement({
|
||||
logger.debug('Master et clones supprimés avec succès de DocuSeal.');
|
||||
|
||||
// Supprimer le template master de la base de données
|
||||
deleteRegistrationTemplateMaster(templateMaster.id, csrfToken)
|
||||
deleteRegistrationSchoolFileMaster(templateMaster.id, csrfToken)
|
||||
.then((response) => {
|
||||
if (response.ok) {
|
||||
setTemplateMasters(
|
||||
templateMasters.filter(
|
||||
setSchoolFileMasters(
|
||||
schoolFileMasters.filter(
|
||||
(fichier) => fichier.id !== templateMaster.id
|
||||
)
|
||||
);
|
||||
@ -175,11 +192,11 @@ export default function FilesGroupsManagement({
|
||||
};
|
||||
logger.debug(data);
|
||||
|
||||
createRegistrationTemplateMaster(data, csrfToken)
|
||||
createRegistrationSchoolFileMaster(data, csrfToken)
|
||||
.then((data) => {
|
||||
// Transformer le nouveau fichier avec les informations du groupe
|
||||
const transformedFile = transformFileData(data, groups);
|
||||
setTemplateMasters((prevFiles) => [...prevFiles, transformedFile]);
|
||||
setSchoolFileMasters((prevFiles) => [...prevFiles, transformedFile]);
|
||||
setIsModalOpen(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
@ -196,11 +213,11 @@ export default function FilesGroupsManagement({
|
||||
};
|
||||
logger.debug(data);
|
||||
|
||||
editRegistrationTemplateMaster(id, data, csrfToken)
|
||||
editRegistrationSchoolFileMaster(id, data, csrfToken)
|
||||
.then((data) => {
|
||||
// Transformer le fichier mis à jour avec les informations du groupe
|
||||
const transformedFile = transformFileData(data, groups);
|
||||
setTemplateMasters((prevFichiers) =>
|
||||
setSchoolFileMasters((prevFichiers) =>
|
||||
prevFichiers.map((f) => (f.id === id ? transformedFile : f))
|
||||
);
|
||||
setIsModalOpen(false);
|
||||
@ -228,7 +245,13 @@ export default function FilesGroupsManagement({
|
||||
alert("Erreur lors de l'opération sur le groupe");
|
||||
});
|
||||
} else {
|
||||
createRegistrationFileGroup(groupData, csrfToken)
|
||||
// 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);
|
||||
@ -246,13 +269,13 @@ export default function FilesGroupsManagement({
|
||||
};
|
||||
|
||||
const handleGroupDelete = (groupId) => {
|
||||
// Vérifier si des templateMasters utilisent ce groupe
|
||||
const filesInGroup = templateMasters.filter(
|
||||
// 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 templateMasters. Veuillez d'abord retirer tous les templateMasters de ce groupe."
|
||||
"Impossible de supprimer ce groupe car il contient des schoolFileMasters. Veuillez d'abord retirer tous les schoolFileMasters de ce groupe."
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -279,7 +302,62 @@ export default function FilesGroupsManagement({
|
||||
}
|
||||
};
|
||||
|
||||
const filteredFiles = templateMasters.filter((file) => {
|
||||
const handleCreate = (newParentFile) => {
|
||||
return createRegistrationParentFileMaster(newParentFile, csrfToken)
|
||||
.then((response) => {
|
||||
const createdFile = response;
|
||||
// Ajouter le nouveau fichier parent à la liste existante
|
||||
setParentFileMasters((prevFiles) => [...prevFiles, createdFile]);
|
||||
logger.debug('Document parent créé avec succès:', createdFile);
|
||||
return 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.'
|
||||
);
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
|
||||
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 &&
|
||||
@ -288,9 +366,9 @@ export default function FilesGroupsManagement({
|
||||
});
|
||||
|
||||
const columnsFiles = [
|
||||
{ name: 'Nom du fichier', transform: (row) => row.name },
|
||||
{ name: 'Nom du formulaire', transform: (row) => row.name },
|
||||
{
|
||||
name: 'Groupes',
|
||||
name: "Dossiers d'inscription",
|
||||
transform: (row) =>
|
||||
row.groups && row.groups.length > 0
|
||||
? row.groups.map((group) => group.name).join(', ')
|
||||
@ -327,7 +405,7 @@ export default function FilesGroupsManagement({
|
||||
];
|
||||
|
||||
const columnsGroups = [
|
||||
{ name: 'Nom du groupe', transform: (row) => row.name },
|
||||
{ name: 'Nom du dossier', transform: (row) => row.name },
|
||||
{ name: 'Description', transform: (row) => row.description },
|
||||
{
|
||||
name: 'Actions',
|
||||
@ -351,7 +429,8 @@ export default function FilesGroupsManagement({
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="w-full mx-auto mt-6">
|
||||
{/* Modal pour les fichiers */}
|
||||
<Modal
|
||||
isOpen={isModalOpen}
|
||||
setIsOpen={(isOpen) => {
|
||||
@ -362,7 +441,7 @@ export default function FilesGroupsManagement({
|
||||
}}
|
||||
title={isEditing ? 'Modification du document' : 'Ajouter un document'}
|
||||
ContentComponent={() => (
|
||||
<FileUpload
|
||||
<FileUploadDocuSeal
|
||||
handleCreateTemplateMaster={handleCreateTemplateMaster}
|
||||
handleEditTemplateMaster={handleEditTemplateMaster}
|
||||
fileToEdit={fileToEdit}
|
||||
@ -371,13 +450,15 @@ export default function FilesGroupsManagement({
|
||||
)}
|
||||
modalClassName="w-4/5 h-4/5"
|
||||
/>
|
||||
|
||||
{/* Modal pour les groupes */}
|
||||
<Modal
|
||||
isOpen={isGroupModalOpen}
|
||||
setIsOpen={setIsGroupModalOpen}
|
||||
title={
|
||||
groupToEdit
|
||||
? 'Modifier le groupe'
|
||||
: 'Ajouter un groupe de templateMasters'
|
||||
: 'Ajouter un groupe de schoolFileMasters'
|
||||
}
|
||||
ContentComponent={() => (
|
||||
<RegistrationFileGroupForm
|
||||
@ -386,61 +467,45 @@ export default function FilesGroupsManagement({
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<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)}
|
||||
|
||||
{/* Section Groupes de fichiers */}
|
||||
<div className="mt-8 w-3/5">
|
||||
<SectionHeader
|
||||
icon={FolderPlus}
|
||||
title="Dossiers d'inscriptions"
|
||||
description="Gérez les dossiers d'inscription pour organiser vos documents."
|
||||
button={true}
|
||||
buttonOpeningModal={true}
|
||||
onClick={() => setIsGroupModalOpen(true)}
|
||||
/>
|
||||
<Table data={groups} columns={columnsGroups} />
|
||||
</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>
|
||||
)}
|
||||
|
||||
{/* Section Fichiers */}
|
||||
<div className="mt-12 mb-4 w-3/5">
|
||||
<SectionHeader
|
||||
icon={Signature}
|
||||
title="Formulaires à remplir"
|
||||
description="Gérez les formulaires nécessitant une signature électronique."
|
||||
button={true}
|
||||
buttonOpeningModal={true}
|
||||
onClick={() => {
|
||||
setIsModalOpen(true);
|
||||
setIsEditing(false);
|
||||
}}
|
||||
/>
|
||||
<Table data={filteredFiles} columns={columnsFiles} />
|
||||
</div>
|
||||
|
||||
{/* Section Pièces à fournir */}
|
||||
<ParentFilesSection
|
||||
parentFiles={parentFiles}
|
||||
setParentFileMasters={setParentFileMasters}
|
||||
groups={groups}
|
||||
handleCreate={handleCreate}
|
||||
handleEdit={handleEdit}
|
||||
handleDelete={handleDelete}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user