chore: application prettier

This commit is contained in:
Luc SORIGNET
2025-04-15 19:37:47 +02:00
parent dd0884bbce
commit f7666c894b
174 changed files with 10609 additions and 8760 deletions

View File

@ -1,15 +1,29 @@
import React, { useState, useEffect } from 'react';
import ToggleSwitch from '@/components/ToggleSwitch'; // Import du composant ToggleSwitch
import { fetchRegistrationFileGroups, createRegistrationTemplates, cloneTemplate, generateToken } from '@/app/actions/registerFileGroupAction';
import {
fetchRegistrationFileGroups,
createRegistrationTemplates,
cloneTemplate,
generateToken,
} from '@/app/actions/registerFileGroupAction';
import { DocusealBuilder } from '@docuseal/react';
import logger from '@/utils/logger';
import { BE_DOCUSEAL_GET_JWT, BASE_URL, FE_API_DOCUSEAL_GENERATE_TOKEN } from '@/utils/Url';
import {
BE_DOCUSEAL_GET_JWT,
BASE_URL,
FE_API_DOCUSEAL_GENERATE_TOKEN,
} from '@/utils/Url';
import Button from '@/components/Button'; // Import du composant Button
import MultiSelect from '@/components/MultiSelect'; // Import du composant MultiSelect
import { useCsrfToken } from '@/context/CsrfContext';
import { useEstablishment } from '@/context/EstablishmentContext';
export default function FileUpload({ handleCreateTemplateMaster, handleEditTemplateMaster, fileToEdit = null, onSuccess }) {
export default function FileUpload({
handleCreateTemplateMaster,
handleEditTemplateMaster,
fileToEdit = null,
onSuccess,
}) {
const [isRequired, setIsRequired] = useState(false); // État pour le toggle isRequired
const [order, setOrder] = useState(0);
const [groups, setGroups] = useState([]);
@ -24,7 +38,9 @@ export default function FileUpload({ handleCreateTemplateMaster, handleEditTempl
const { selectedEstablishmentId } = useEstablishment();
useEffect(() => {
fetchRegistrationFileGroups(selectedEstablishmentId).then(data => setGroups(data));
fetchRegistrationFileGroups(selectedEstablishmentId).then((data) =>
setGroups(data)
);
if (fileToEdit) {
setUploadedFileName(fileToEdit.name || '');
@ -40,7 +56,9 @@ export default function FileUpload({ handleCreateTemplateMaster, handleEditTempl
.then((data) => {
setToken(data.token);
})
.catch((error) => console.error('Erreur lors de la génération du token:', error));
.catch((error) =>
console.error('Erreur lors de la génération du token:', error)
);
}, [fileToEdit]);
const handleFileNameChange = (event) => {
@ -49,14 +67,14 @@ export default function FileUpload({ handleCreateTemplateMaster, handleEditTempl
const handleGroupChange = (selectedGroups) => {
setSelectedGroups(selectedGroups);
const details = selectedGroups.flatMap(group =>
group.registration_forms.flatMap(form =>
form.guardians.map(guardian => ({
const details = selectedGroups.flatMap((group) =>
group.registration_forms.flatMap((form) =>
form.guardians.map((guardian) => ({
email: guardian.associated_profile_email,
last_name: form.last_name,
first_name: form.first_name,
registration_form: form.student_id
registration_form: form.student_id,
}))
)
);
@ -65,9 +83,9 @@ export default function FileUpload({ handleCreateTemplateMaster, handleEditTempl
const handleLoad = (detail) => {
const templateId = detail?.id;
logger.debug('loading template id : ', detail)
logger.debug('loading template id : ', detail);
setTemplateMaster(detail);
}
};
const handleUpload = (detail) => {
logger.debug('Uploaded file detail:', detail);
@ -75,54 +93,57 @@ export default function FileUpload({ handleCreateTemplateMaster, handleEditTempl
};
const handleChange = (detail) => {
logger.debug(detail)
logger.debug(detail);
setUploadedFileName(detail.name);
}
};
const handleSubmit = (data) => {
const is_required = (data.fields.length > 0)
const is_required = data.fields.length > 0;
if (fileToEdit) {
logger.debug('Modification du template master:', templateMaster?.id);
handleEditTemplateMaster({
name: uploadedFileName,
group_ids: selectedGroups.map(group => group.id),
group_ids: selectedGroups.map((group) => group.id),
id: templateMaster?.id,
is_required: is_required
is_required: is_required,
});
} else {
logger.debug('Création du template master:', templateMaster?.id);
handleCreateTemplateMaster({
name: uploadedFileName,
group_ids: selectedGroups.map(group => group.id),
group_ids: selectedGroups.map((group) => group.id),
id: templateMaster?.id,
is_required: is_required
is_required: is_required,
});
guardianDetails.forEach((guardian, index) => {
logger.debug('creation du clone avec required : ', is_required)
logger.debug('creation du clone avec required : ', is_required);
cloneTemplate(templateMaster?.id, guardian.email, is_required)
.then(clonedDocument => {
.then((clonedDocument) => {
// Sauvegarde des templates clonés dans la base de données
const data = {
name: `${uploadedFileName}_${guardian.first_name}_${guardian.last_name}`,
slug: clonedDocument.slug,
id: clonedDocument.id,
master: templateMaster?.id,
registration_form: guardian.registration_form
registration_form: guardian.registration_form,
};
createRegistrationTemplates(data, csrfToken)
.then(response => {
.then((response) => {
logger.debug('Template enregistré avec succès:', response);
onSuccess();
})
.catch(error => {
logger.error('Erreur lors de l\'enregistrement du template:', error);
.catch((error) => {
logger.error(
"Erreur lors de l'enregistrement du template:",
error
);
});
// Logique pour envoyer chaque template au submitter
logger.debug('Sending template to:', guardian.email);
})
.catch(error => {
.catch((error) => {
logger.error('Error during cloning or sending:', error);
});
});
@ -144,10 +165,10 @@ export default function FileUpload({ handleCreateTemplateMaster, handleEditTempl
</div>
<div className="col-span-8">
{token && (
<DocusealBuilder
token={token}
<DocusealBuilder
token={token}
headers={{
'Authorization': `Bearer ${token}`
Authorization: `Bearer ${token}`,
}}
withSendButton={false}
withSaveButton={false}
@ -168,4 +189,4 @@ export default function FileUpload({ handleCreateTemplateMaster, handleEditTempl
</div>
</div>
);
}
}

View File

@ -1,5 +1,12 @@
import React, { useState, useEffect } from 'react';
import { Plus, Download, Edit3, Trash2, FolderPlus, Signature } from 'lucide-react';
import {
Plus,
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';
@ -13,12 +20,15 @@ import {
createRegistrationTemplateMaster,
editRegistrationTemplateMaster,
deleteRegistrationTemplateMaster,
fetchRegistrationTemplates
fetchRegistrationTemplates,
} from '@/app/actions/registerFileGroupAction';
import RegistrationFileGroupForm from '@/components/Structure/Files/RegistrationFileGroupForm';
import logger from '@/utils/logger';
export default function FilesGroupsManagement({ csrfToken, selectedEstablishmentId }) {
export default function FilesGroupsManagement({
csrfToken,
selectedEstablishmentId,
}) {
const [templateMasters, setTemplateMasters] = useState([]);
const [templates, setTemplates] = useState([]);
const [groups, setGroups] = useState([]);
@ -32,13 +42,19 @@ export default function FilesGroupsManagement({ csrfToken, selectedEstablishment
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' });
const groupInfos = file.groups.map(
(groupId) =>
groups.find((g) => g.id === groupId) || {
id: groupId,
name: 'Groupe inconnu',
}
);
return {
...file,
groups: groupInfos
groups: groupInfos,
};
};
@ -47,58 +63,75 @@ export default function FilesGroupsManagement({ csrfToken, selectedEstablishment
Promise.all([
fetchRegistrationTemplateMaster(),
fetchRegistrationFileGroups(selectedEstablishmentId),
fetchRegistrationTemplates()
]).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);
}).catch(err => {
console.log(err.message);
}).finally(() => {
setReloadTemplates(false);
});
fetchRegistrationTemplates(),
])
.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);
})
.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 = templates
.filter(template => template.master === templateMaster.id)
.map(template => removeTemplate(template.id));
.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);
.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
deleteRegistrationTemplateMaster(templateMaster.id, csrfToken)
.then(response => {
.then((response) => {
if (response.ok) {
setTemplateMasters(templateMasters.filter(fichier => fichier.id !== templateMaster.id));
setTemplateMasters(
templateMasters.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.');
alert(
'Erreur lors de la suppression du fichier dans la base de données.'
);
}
})
.catch(error => {
.catch((error) => {
console.error('Error deleting file from database:', error);
alert('Erreur lors de la suppression du fichier dans la base de données.');
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.');
alert(
'Erreur lors de la suppression du master ou des clones dans DocuSeal.'
);
}
})
.catch(error => {
.catch((error) => {
console.error('Error removing template from DocuSeal:', error);
alert('Erreur lors de la suppression du master ou des clones dans DocuSeal.');
alert(
'Erreur lors de la suppression du master ou des clones dans DocuSeal.'
);
});
};
@ -107,22 +140,24 @@ export default function FilesGroupsManagement({ csrfToken, selectedEstablishment
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrfToken
'X-CSRFToken': csrfToken,
},
body: JSON.stringify({
templateId
templateId,
}),
})
.then((response) => {
if (!response.ok) {
return response.json().then((err) => {
throw new Error(err.message);
});
}
return response;
})
})
.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;
});
.catch((error) => {
console.error('Error removing template:', error);
throw error;
});
};
const editTemplateMaster = (file) => {
@ -131,72 +166,76 @@ export default function FilesGroupsManagement({ csrfToken, selectedEstablishment
setIsModalOpen(true);
};
const handleCreateTemplateMaster = ({name, group_ids, id, is_required}) => {
const handleCreateTemplateMaster = ({ name, group_ids, id, is_required }) => {
const data = {
name: name,
id: id,
groups: group_ids,
is_required: is_required
is_required: is_required,
};
logger.debug(data);
createRegistrationTemplateMaster(data, csrfToken)
.then(data => {
// Transformer le nouveau fichier avec les informations du groupe
const transformedFile = transformFileData(data, groups);
setTemplateMasters(prevFiles => [...prevFiles, transformedFile]);
setIsModalOpen(false);
})
.catch(error => {
console.error('Error uploading file:', error);
});
.then((data) => {
// Transformer le nouveau fichier avec les informations du groupe
const transformedFile = transformFileData(data, groups);
setTemplateMasters((prevFiles) => [...prevFiles, transformedFile]);
setIsModalOpen(false);
})
.catch((error) => {
console.error('Error uploading file:', error);
});
};
const handleEditTemplateMaster = ({name, group_ids, id, is_required}) => {
const handleEditTemplateMaster = ({ name, group_ids, id, is_required }) => {
const data = {
name: name,
id: id,
groups: group_ids,
is_required: is_required
is_required: is_required,
};
logger.debug(data);
editRegistrationTemplateMaster(id, data, csrfToken)
.then(data => {
// Transformer le fichier mis à jour avec les informations du groupe
const transformedFile = transformFileData(data, groups);
setTemplateMasters(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');
});
.then((data) => {
// Transformer le fichier mis à jour avec les informations du groupe
const transformedFile = transformFileData(data, groups);
setTemplateMasters((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));
.then((updatedGroup) => {
setGroups(
groups.map((group) =>
group.id === groupToEdit.id ? updatedGroup : group
)
);
setGroupToEdit(null);
setIsGroupModalOpen(false);
})
.catch(error => {
.catch((error) => {
console.error('Error handling group:', error);
alert('Erreur lors de l\'opération sur le groupe');
alert("Erreur lors de l'opération sur le groupe");
});
} else {
createRegistrationFileGroup(groupData, csrfToken)
.then(newGroup => {
.then((newGroup) => {
setGroups([...groups, newGroup]);
setIsGroupModalOpen(false);
})
.catch(error => {
.catch((error) => {
console.error('Error handling group:', error);
alert('Erreur lors de l\'opération sur le groupe');
alert("Erreur lors de l'opération sur le groupe");
});
}
};
@ -208,9 +247,13 @@ export default function FilesGroupsManagement({ csrfToken, selectedEstablishment
const handleGroupDelete = (groupId) => {
// Vérifier si des templateMasters utilisent ce groupe
const filesInGroup = templateMasters.filter(file => file.group && file.group.id === groupId);
const filesInGroup = templateMasters.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.');
alert(
"Impossible de supprimer ce groupe car il contient des templateMasters. Veuillez d'abord retirer tous les templateMasters de ce groupe."
);
return;
}
@ -223,54 +266,88 @@ export default function FilesGroupsManagement({ csrfToken, selectedEstablishment
if (!response.ok) {
throw new Error('Erreur lors de la suppression du groupe.');
}
setGroups(groups.filter(group => group.id !== groupId));
setGroups(groups.filter((group) => group.id !== groupId));
alert('Groupe supprimé avec succès.');
})
.catch(error => {
.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.');
alert(
error.message ||
"Erreur lors de la suppression du groupe. Vérifiez qu'aucune inscription n'utilise ce groupe."
);
});
}
};
const filteredFiles = templateMasters.filter(file => {
const filteredFiles = templateMasters.filter((file) => {
if (!selectedGroup) return true;
return file.groups && file.groups.some(group => group.id === parseInt(selectedGroup));
return (
file.groups &&
file.groups.some((group) => group.id === parseInt(selectedGroup))
);
});
const columnsFiles = [
{ name: 'Nom du fichier', transform: (row) => row.name },
{ name: 'Groupes', transform: (row) => row.groups && row.groups.length > 0 ? row.groups.map(group => group.name).join(', ') : 'Aucun' },
{ 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 className="w-5 h-5" />
</a>
)}
<button onClick={() => editTemplateMaster(row)} className="text-blue-500 hover:text-blue-700">
<Edit3 className="w-5 h-5" />
</button>
<button onClick={() => deleteTemplateMaster(row)} className="text-red-500 hover:text-red-700">
<Trash2 className="w-5 h-5" />
</button>
</div>
)}
{
name: 'Groupes',
transform: (row) =>
row.groups && row.groups.length > 0
? row.groups.map((group) => group.name).join(', ')
: 'Aucun',
},
{
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 className="w-5 h-5" />
</a>
)}
<button
onClick={() => editTemplateMaster(row)}
className="text-blue-500 hover:text-blue-700"
>
<Edit3 className="w-5 h-5" />
</button>
<button
onClick={() => deleteTemplateMaster(row)}
className="text-red-500 hover:text-red-700"
>
<Trash2 className="w-5 h-5" />
</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">
<Edit3 className="w-5 h-5" />
</button>
<button onClick={() => handleGroupDelete(row.id)} className="text-red-500 hover:text-red-700">
<Trash2 className="w-5 h-5" />
</button>
</div>
)}
{
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"
>
<Edit3 className="w-5 h-5" />
</button>
<button
onClick={() => handleGroupDelete(row.id)}
className="text-red-500 hover:text-red-700"
>
<Trash2 className="w-5 h-5" />
</button>
</div>
),
},
];
return (
@ -292,12 +369,16 @@ export default function FilesGroupsManagement({ csrfToken, selectedEstablishment
onSuccess={handleReloadTemplates}
/>
)}
modalClassName='w-4/5 h-4/5'
modalClassName="w-4/5 h-4/5"
/>
<Modal
isOpen={isGroupModalOpen}
setIsOpen={setIsGroupModalOpen}
title={groupToEdit ? "Modifier le groupe" : "Ajouter un groupe de templateMasters"}
title={
groupToEdit
? 'Modifier le groupe'
: 'Ajouter un groupe de templateMasters'
}
ContentComponent={() => (
<RegistrationFileGroupForm
onSubmit={handleGroupSubmit}
@ -334,12 +415,17 @@ export default function FilesGroupsManagement({ csrfToken, selectedEstablishment
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>
{groups.map((group) => (
<option key={group.id} value={group.id}>
{group.name}
</option>
))}
</select>
<button
onClick={() => { setIsModalOpen(true); setIsEditing(false); }}
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" />

View File

@ -53,4 +53,4 @@ export default function RegistrationFileGroupForm({ onSubmit, initialData }) {
</div>
</form>
);
}
}

View File

@ -8,17 +8,19 @@ export default function RegistrationFileGroupList() {
const { selectedEstablishmentId } = useEstablishment();
useEffect(() => {
fetchRegistrationFileGroups(selectedEstablishmentId).then(data => setGroups(data));
fetchRegistrationFileGroups(selectedEstablishmentId).then((data) =>
setGroups(data)
);
}, []);
return (
<div>
<h2>Groupes de fichiers d&apos;inscription</h2>
<ul>
{groups.map(group => (
{groups.map((group) => (
<li key={group.id}>{group.name}</li>
))}
</ul>
</div>
);
}
}