mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 16:03:21 +00:00
feat: Gestion des pièces à fournir par les parents (configuration école)
This commit is contained in:
246
Front-End/src/components/Structure/Files/ParentFilesSection.js
Normal file
246
Front-End/src/components/Structure/Files/ParentFilesSection.js
Normal file
@ -0,0 +1,246 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Plus, Edit3, Trash2, Check, X, FileText } from 'lucide-react';
|
||||
import Table from '@/components/Table';
|
||||
import InputText from '@/components/InputText';
|
||||
import MultiSelect from '@/components/MultiSelect';
|
||||
import Popup from '@/components/Popup';
|
||||
import logger from '@/utils/logger';
|
||||
|
||||
export default function ParentFilesSection({ parentFiles, groups, handleCreate, handleEdit, handleDelete }) {
|
||||
const [editingDocumentId, setEditingDocumentId] = useState(null);
|
||||
const [formData, setFormData] = useState(null);
|
||||
const [selectedGroups, setSelectedGroups] = useState([]); // Gestion des groupes sélectionnés
|
||||
|
||||
const [popupVisible, setPopupVisible] = useState(false);
|
||||
const [popupMessage, setPopupMessage] = useState("");
|
||||
const [removePopupVisible, setRemovePopupVisible] = useState(false);
|
||||
const [removePopupMessage, setRemovePopupMessage] = useState("");
|
||||
const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {});
|
||||
|
||||
const handleAddEmptyRequiredDocument = () => {
|
||||
setEditingDocumentId('new');
|
||||
setFormData({ name: '', description: '', groups: [] });
|
||||
setSelectedGroups([]); // Réinitialiser les groupes sélectionnés
|
||||
};
|
||||
|
||||
const handleEditDocument = (document) => {
|
||||
setEditingDocumentId(document.id);
|
||||
setFormData(document);
|
||||
const initialSelectedGroups = document.groups.map((groupId) =>
|
||||
groups.find((group) => group.id === groupId)
|
||||
);
|
||||
setSelectedGroups(initialSelectedGroups);
|
||||
};
|
||||
|
||||
const handleSaveDocument = () => {
|
||||
if (!formData.name) {
|
||||
alert('Le nom de la pièce est requis.');
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedFormData = {
|
||||
...formData,
|
||||
groups: selectedGroups.map((group) => group.id),
|
||||
};
|
||||
|
||||
if (editingDocumentId === 'new') {
|
||||
handleCreate(updatedFormData).then(() => {
|
||||
setEditingDocumentId(null);
|
||||
setFormData(null);
|
||||
setSelectedGroups([]);
|
||||
});
|
||||
} else {
|
||||
handleEdit(editingDocumentId, updatedFormData).then(() => {
|
||||
setEditingDocumentId(null);
|
||||
setFormData(null);
|
||||
setSelectedGroups([]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveDocument = (id) => {
|
||||
return handleDelete(id)
|
||||
.then(() => {
|
||||
setEditingDocumentId(null);
|
||||
setFormData(null);
|
||||
setSelectedGroups([]);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(error);
|
||||
});
|
||||
};
|
||||
|
||||
const handleCancelEdit = () => {
|
||||
setEditingDocumentId(null);
|
||||
setFormData(null);
|
||||
setSelectedGroups([]);
|
||||
};
|
||||
|
||||
const handleGroupChange = (selected) => {
|
||||
setSelectedGroups(selected);
|
||||
};
|
||||
|
||||
const renderRequiredDocumentCell = (document, column) => {
|
||||
const isEditing = editingDocumentId === document.id || (editingDocumentId === 'new' && !document.id);
|
||||
|
||||
if (isEditing) {
|
||||
switch (column) {
|
||||
case 'Nom de la pièce':
|
||||
return (
|
||||
<InputText
|
||||
name="name"
|
||||
value={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
placeholder="Nom de la pièce"
|
||||
className="w-full"
|
||||
/>
|
||||
);
|
||||
case 'Description':
|
||||
return (
|
||||
<InputText
|
||||
name="description"
|
||||
value={formData.description}
|
||||
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
|
||||
placeholder="Description"
|
||||
className="w-full"
|
||||
/>
|
||||
);
|
||||
case 'Dossiers d\'inscription':
|
||||
return (
|
||||
<MultiSelect
|
||||
name="groups"
|
||||
label="Sélection de groupes de fichiers"
|
||||
options={groups.map((group) => ({ id: group.id, name: group.name }))}
|
||||
selectedOptions={selectedGroups}
|
||||
onChange={handleGroupChange}
|
||||
errorMsg={null}
|
||||
/>
|
||||
);
|
||||
case 'Actions':
|
||||
return (
|
||||
<div className="flex justify-center space-x-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleSaveDocument}
|
||||
className="text-green-500 hover:text-green-700"
|
||||
>
|
||||
<Check className="w-5 h-5" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleCancelEdit}
|
||||
className="text-red-500 hover:text-red-700"
|
||||
>
|
||||
<X className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
switch (column) {
|
||||
case 'Nom de la pièce':
|
||||
return <span>{document.name}</span>;
|
||||
case 'Description':
|
||||
return <span>{document.description}</span>;
|
||||
case 'Dossiers d\'inscription':
|
||||
return (
|
||||
<span>
|
||||
{document.groups
|
||||
.map((groupId) => groups.find((group) => group.id === groupId)?.name || 'Dossiers d\'inscription inconnu')
|
||||
.join(', ')}
|
||||
</span>
|
||||
);
|
||||
case 'Actions':
|
||||
return (
|
||||
<div className="flex justify-center space-x-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleEditDocument(document)}
|
||||
className="text-blue-500 hover:text-blue-700"
|
||||
>
|
||||
<Edit3 className="w-5 h-5" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setRemovePopupVisible(true);
|
||||
setRemovePopupMessage(
|
||||
`Attentions ! \nVous êtes sur le point de supprimer le document "${document.name}".\nÊtes-vous sûr(e) de vouloir poursuivre l'opération ?`
|
||||
);
|
||||
setRemovePopupOnConfirm(() => () => {
|
||||
handleRemoveDocument(document.id)
|
||||
.then(() => {
|
||||
setPopupMessage(`Le document "${document.name}" a été correctement supprimé.`);
|
||||
setPopupVisible(true);
|
||||
setRemovePopupVisible(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('Erreur lors de la suppression du document:', error);
|
||||
setPopupMessage(`Erreur lors de la suppression du document "${document.name}".`);
|
||||
setPopupVisible(true);
|
||||
setRemovePopupVisible(false);
|
||||
});
|
||||
});
|
||||
}}
|
||||
className="text-red-500 hover:text-red-700"
|
||||
>
|
||||
<Trash2 className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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: 'Dossiers d\'inscription', transform: (row) => renderRequiredDocumentCell(row, 'Dossiers d\'inscription') },
|
||||
{ name: 'Actions', transform: (row) => renderRequiredDocumentCell(row, 'Actions') },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="mt-8 mb-4 w-4/5">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="bg-emerald-100 p-3 rounded-full shadow-md">
|
||||
<FileText className="w-8 h-8 text-emerald-600" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold text-gray-800">Pièces à fournir</h2>
|
||||
<p className="text-sm text-gray-500 italic">
|
||||
Configurez la liste des documents que les parents doivent fournir.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={handleAddEmptyRequiredDocument}
|
||||
className="text-emerald-500 hover:text-emerald-700"
|
||||
>
|
||||
<Plus className="w-6 h-6" />
|
||||
</button>
|
||||
</div>
|
||||
<Table
|
||||
data={editingDocumentId === 'new' ? [formData, ...parentFiles] : parentFiles}
|
||||
columns={columnsRequiredDocuments}
|
||||
/>
|
||||
<Popup
|
||||
visible={popupVisible}
|
||||
message={popupMessage}
|
||||
onConfirm={() => setPopupVisible(false)}
|
||||
onCancel={() => setPopupVisible(false)}
|
||||
uniqueConfirmButton={true}
|
||||
/>
|
||||
<Popup
|
||||
visible={removePopupVisible}
|
||||
message={removePopupMessage}
|
||||
onConfirm={removePopupOnConfirm}
|
||||
onCancel={() => setRemovePopupVisible(false)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user