mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-04-04 04:01:27 +00:00
feat: Upload du SEPA par les parents / Création d'un composant header
pour les titres de tableau
This commit is contained in:
@ -1,17 +1,214 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import Table from '@/components/Table';
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
import { Upload, Eye, Trash2, FileText } from 'lucide-react';
|
||||
import { BASE_URL } from '@/utils/Url';
|
||||
import Popup from '@/components/Popup';
|
||||
import logger from '@/utils/logger';
|
||||
|
||||
export default function FilesToUpload({ parentFileTemplates, uploadedFiles, onFileUpload, onFileDelete }) {
|
||||
const [selectedFile, setSelectedFile] = useState(null); // État pour le fichier sélectionné
|
||||
const [actionType, setActionType] = useState(null);
|
||||
|
||||
const [popupVisible, setPopupVisible] = useState(false);
|
||||
const [popupMessage, setPopupMessage] = useState("");
|
||||
const [removePopupVisible, setRemovePopupVisible] = useState(false);
|
||||
const [removePopupMessage, setRemovePopupMessage] = useState("");
|
||||
const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {});
|
||||
|
||||
// Vérification si un fichier est déjà uploadé
|
||||
const isFileUploaded = (file) => {
|
||||
return file && file.fileName; // Si `fileName` est défini, le fichier est considéré comme téléversé
|
||||
};
|
||||
|
||||
// Récupération d'un fichier uploadé
|
||||
const getUploadedFile = (templateId) => {
|
||||
return uploadedFiles.find(file => parseInt(file.id) === templateId && file.fileName);
|
||||
};
|
||||
|
||||
const handleUpload = (file, selectedFile) => {
|
||||
if (!file || !selectedFile) {
|
||||
logger.error('Données manquantes pour le téléversement.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Appeler la fonction de téléversement passée en prop
|
||||
onFileUpload(file, selectedFile)
|
||||
.then((response) => {
|
||||
// Mettre à jour uploadedFiles avec les nouvelles données
|
||||
const updatedFiles = uploadedFiles.map(f =>
|
||||
f.id === selectedFile.id
|
||||
? { ...f, fileName: response.data.fileName, file: response.data.file_url }
|
||||
: f
|
||||
);
|
||||
|
||||
// Si le fichier n'existe pas encore, l'ajouter
|
||||
if (!updatedFiles.find(f => f.id === selectedFile.id)) {
|
||||
updatedFiles.push({
|
||||
id: selectedFile.id,
|
||||
fileName: response.data.fileName,
|
||||
file: response.data.file_url,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('Erreur lors du téléversement du fichier :', error);
|
||||
});
|
||||
|
||||
// Mettre à jour l'état local
|
||||
setSelectedFile(null);
|
||||
setActionType(null); // Réinitialiser l'action après l'upload
|
||||
};
|
||||
|
||||
// Définition des colonnes
|
||||
const columns = [
|
||||
{ name: 'Nom du fichier', transform: (row) => row.master_name },
|
||||
{ name: 'Description du fichier', transform: (row) => row.master_description },
|
||||
{ name: 'Statut', transform: (row) => {
|
||||
const uploadedFile = getUploadedFile(row.id);
|
||||
return (
|
||||
<span className={`px-2 py-1 rounded-md text-sm font-medium ${
|
||||
isFileUploaded(uploadedFile) ? 'bg-green-50 text-green-600' : 'bg-orange-50 text-orange-600'
|
||||
}`}>
|
||||
{isFileUploaded(uploadedFile) ? 'Chargé' : 'A ajouter'}
|
||||
</span>
|
||||
);
|
||||
}},
|
||||
{ name: 'Actions', transform: (row) => {
|
||||
const uploadedFile = getUploadedFile(row.id);
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-center gap-4">
|
||||
{uploadedFile && (
|
||||
<>
|
||||
<button
|
||||
className={`flex items-center justify-center w-8 h-8 rounded-full ${
|
||||
actionType === 'view' && selectedFile?.id === row.id
|
||||
? 'bg-blue-100 text-blue-600 ring-3 ring-blue-500'
|
||||
: 'text-blue-500 hover:text-blue-700'
|
||||
}`}
|
||||
onClick={() => {
|
||||
if (actionType === 'view' && selectedFile?.id === row.id) {
|
||||
setSelectedFile(null);
|
||||
setActionType(null);
|
||||
} else {
|
||||
const uploadedFile = getUploadedFile(row.id);
|
||||
setSelectedFile(uploadedFile || row); // Utiliser les données mises à jour
|
||||
setActionType('view');
|
||||
}
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
<Eye className="w-5 h-5" />
|
||||
</button>
|
||||
<button
|
||||
className="flex items-center justify-center w-8 h-8 rounded-full text-red-500 hover:text-red-700"
|
||||
onClick={() => {
|
||||
setRemovePopupVisible(true);
|
||||
setRemovePopupMessage(
|
||||
`Êtes-vous sûr(e) de vouloir supprimer le fichier "${row.master_name}" ?`
|
||||
);
|
||||
setRemovePopupOnConfirm(() => () => {
|
||||
onFileDelete(row.id)
|
||||
.then(() => {
|
||||
setPopupMessage(`Le fichier "${row.master_name}" a été supprimé avec succès.`);
|
||||
setPopupVisible(true);
|
||||
setRemovePopupVisible(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('Erreur lors de la suppression du fichier :', error);
|
||||
setPopupMessage(`Erreur lors de la suppression du fichier "${row.master_name}".`);
|
||||
setPopupVisible(true);
|
||||
setRemovePopupVisible(false);
|
||||
});
|
||||
setActionType(null);
|
||||
setSelectedFile(null);
|
||||
});
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
<Trash2 className="w-5 h-5" />
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
{!uploadedFile && (
|
||||
<button
|
||||
className={`flex items-center justify-center w-8 h-8 rounded-full ${
|
||||
actionType === 'upload' && selectedFile?.id === row.id
|
||||
? 'bg-emerald-100 text-emerald-600 ring-3 ring-emerald-500'
|
||||
: 'text-emerald-500 hover:text-emerald-700'
|
||||
}`}
|
||||
onClick={() => {
|
||||
if (actionType === 'upload' && selectedFile?.id === row.id) {
|
||||
setSelectedFile(null);
|
||||
setActionType(null);
|
||||
} else {
|
||||
setSelectedFile(row);
|
||||
setActionType('upload');
|
||||
}
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
<Upload className="w-5 h-5" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}},
|
||||
];
|
||||
|
||||
export default function FilesToUpload({ parentFileTemplates, columns }) {
|
||||
return (
|
||||
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
|
||||
<h2 className="text-xl font-bold mb-4 text-gray-800">Fichiers à uploader</h2>
|
||||
<div className="mt-8 mb-4 w-3/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">
|
||||
Ajoutez les documents pour compléter votre inscription
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Table
|
||||
data={parentFileTemplates}
|
||||
columns={columns}
|
||||
itemsPerPage={5}
|
||||
currentPage={1}
|
||||
totalPages={1}
|
||||
onPageChange={() => {}}
|
||||
/>
|
||||
{selectedFile && (
|
||||
<div className="mt-4">
|
||||
{actionType === 'view' && selectedFile.fileName ? (
|
||||
<iframe
|
||||
src={`${BASE_URL}/${selectedFile.fileName}`}
|
||||
title="Document Viewer"
|
||||
className="w-full"
|
||||
style={{
|
||||
height: '75vh',
|
||||
border: 'none',
|
||||
}}
|
||||
/>
|
||||
) : actionType === 'upload' ? (
|
||||
<FileUpload
|
||||
selectionMessage={`Téléversez le fichier ${selectedFile.master_name}`}
|
||||
onFileSelect={(file) => handleUpload(file, selectedFile)}
|
||||
uploadedFileName={selectedFile.fileName || ''}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
<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