feat: Ajout de la gestion des fichier d'inscription [#1]

This commit is contained in:
Luc SORIGNET
2025-01-11 16:14:03 +01:00
parent fb5d485ce1
commit 3c27133cdb
16 changed files with 469 additions and 143 deletions

View File

@ -13,17 +13,19 @@ import Button from '@/components/Button';
import DropdownMenu from "@/components/DropdownMenu";
import { swapFormatDate } from '@/utils/Date';
import { formatPhoneNumber } from '@/utils/Telephone';
import { MoreVertical, Send, Edit, Trash2, FileText, ChevronUp, UserPlus, CheckCircle, Plus} from 'lucide-react';
import { MoreVertical, Send, Edit, Trash2, FileText, ChevronUp, UserPlus, CheckCircle, Plus, Download } from 'lucide-react';
import Modal from '@/components/Modal';
import InscriptionForm from '@/components/Inscription/InscriptionForm'
import AffectationClasseForm from '@/components/AffectationClasseForm'
import FileUpload from './components/FileUpload';
import { BK_GESTIONINSCRIPTION_FICHESINSCRIPTION_URL,
BK_GESTIONINSCRIPTION_SEND_URL,
FR_ADMIN_SUBSCRIPTIONS_EDIT_URL,
BK_GESTIONINSCRIPTION_ARCHIVE_URL,
BK_GESTIONENSEIGNANTS_CLASSES_URL,
import { BASE_URL, BK_GESTIONINSCRIPTION_FICHESINSCRIPTION_URL,
BK_GESTIONINSCRIPTION_SEND_URL,
FR_ADMIN_SUBSCRIPTIONS_EDIT_URL,
BK_GESTIONINSCRIPTION_ARCHIVE_URL,
BK_GESTIONENSEIGNANTS_CLASSES_URL,
BK_GESTIONINSCRIPTION_FICHEINSCRIPTION_URL,
BK_GESTIONINSCRIPTION_FICHERSINSCRIPTION_URL ,
BK_GESTIONINSCRIPTION_ELEVES_URL,
BK_PROFILE_URL } from '@/utils/Url';
@ -53,6 +55,10 @@ export default function Page({ params: { locale } }) {
const [totalArchives, setTotalArchives] = useState(0);
const [itemsPerPage, setItemsPerPage] = useState(5); // Définir le nombre d'éléments par page
const [fichiers, setFichiers] = useState([]);
const [nomFichier, setNomFichier] = useState('');
const [fichier, setFichier] = useState(null);
const [isOpen, setIsOpen] = useState(false);
const [isOpenAffectationClasse, setIsOpenAffectationClasse] = useState(false);
const [eleve, setEleve] = useState('');
@ -180,6 +186,32 @@ export default function Page({ params: { locale } }) {
});
};
useEffect(() => {
const fetchFichiers = () => {
const request = new Request(
`${BK_GESTIONINSCRIPTION_FICHERSINSCRIPTION_URL}`,
{
method:'GET',
headers: {
'Content-Type':'application/json'
},
}
);
fetch(request).then(response => response.json())
.then(data => {
console.log('Success FILES:', data);
setFichiers(data);
})
.catch(error => {
console.error('Error fetching data:', error);
error = error.message;
console.log(error);
});
};
fetchFichiers();
}, []);
useEffect(() => {
fetchClasses();
fetchStudents();
@ -326,7 +358,7 @@ export default function Page({ params: { locale } }) {
{
method:'POST',
headers: {
'Content-Type':'application/json',
'Content-Type':'application/json',
'X-CSRFToken': csrfToken
},
credentials: 'include',
@ -371,7 +403,7 @@ export default function Page({ params: { locale } }) {
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
console.log('Success:', data);
setFichesInscriptionsDataEnCours(prevState => {
if (prevState && prevState.length > 0) {
return [...prevState, data];
@ -429,13 +461,11 @@ const columns = [
)
},
{ name: t('files'), transform: (row) => (
<ul>
{row.fichiers?.map((fichier, fileIndex) => (
<li key={fileIndex} className="flex items-center gap-2">
<ul>
<li className="flex items-center gap-2">
<FileText size={16} />
<a href={fichier.url}>{fichier.nom}</a>
<a href={ `${BASE_URL}${row.fichierInscription}`} target='_blank'>{row.fichierInscription.split('/').pop()}</a>
</li>
))}
</ul>
) },
{ name: 'Actions', transform: (row) => (
@ -509,14 +539,13 @@ const columnsSubscribed = [
</div>
)
},
{ name: t('files'), transform: (row) => (
{ name: t('files'), transform: (row) =>
(
<ul>
{row.fichiers?.map((fichier, fileIndex) => (
<li key={fileIndex} className="flex items-center gap-2">
<li className="flex items-center gap-2">
<FileText size={16} />
<a href={fichier.url}>{fichier.nom}</a>
<a href={ `${BASE_URL}${row.fichierInscription}`} target='_blank'>{row.fichierInscription.split('/').pop()}</a>
</li>
))}
</ul>
) },
{ name: 'Actions', transform: (row) => (
@ -545,6 +574,98 @@ const columnsSubscribed = [
];
const handleFileDelete = (fileId) => {
fetch(`${BK_GESTIONINSCRIPTION_FICHERSINSCRIPTION_URL}/${fileId}`, {
method: 'DELETE',
headers: {
'X-CSRFToken': csrfToken,
},
credentials: 'include',
})
.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 columnsFiles = [
{ name: 'Nom du fichier', transform: (row) => row.name },
{ name: 'Date de création', transform: (row) => row.date_ajout },
{ name: 'Actions', transform: (row) => (
<div className="flex items-center justify-center gap-2">
<a href={`${BASE_URL}${row.file}`} target='_blank' className="text-blue-500 hover:text-blue-700">
<Download size={16} />
</a>
<button onClick={() => handleFileDelete(row.id)} className="text-red-500 hover:text-red-700">
<Trash2 size={16} />
</button>
</div>
) },
];
const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
const [uploadFile, setUploadFile] = useState(null);
const [uploadFileName, setUploadFileName] = useState('');
const [fileName, setFileName] = useState('');
const openUploadModal = () => {
setIsUploadModalOpen(true);
};
const closeUploadModal = () => {
setIsUploadModalOpen(false);
setUploadFile(null);
setUploadFileName('');
setFileName('');
};
const handleFileChange = (event) => {
const file = event.target.files[0];
setUploadFile(file);
setUploadFileName(file ? file.name : '');
};
const handleFileNameChange = (event) => {
setFileName(event.target.value);
};
const handleFileUpload = (file, fileName) => {
if (!file || !fileName) {
alert('Veuillez sélectionner un fichier et entrer un nom de fichier.');
return;
}
const formData = new FormData();
formData.append('file', file);
formData.append('name', fileName);
fetch(`${BK_GESTIONINSCRIPTION_FICHERSINSCRIPTION_URL}`, {
method: 'POST',
body: formData,
headers: {
'X-CSRFToken': csrfToken,
},
credentials: 'include',
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
setFichiers([...fichiers, data]);
closeUploadModal();
})
.catch(error => {
console.error('Error uploading file:', error);
});
};
if (isLoading) {
return <Loader />;
} else {
@ -593,16 +714,23 @@ const columnsSubscribed = [
active={activeTab === 'archived'}
onClick={() => setActiveTab('archived')}
/>
<Tab
text={(
<>
{t('subscribeFiles')}
<span className="ml-2 text-sm text-gray-400">({totalSubscribed})</span>
</>
)}
active={activeTab === 'subscribeFiles'}
onClick={() => setActiveTab('subscribeFiles')}
/>
</div>
</div>
<div className="border-b border-gray-200 mb-6 w-full">
{/*SI STATE == pending || subscribe || archived */}
{activeTab === 'pending' || activeTab === 'subscribed' || activeTab === 'archived' ? (
<React.Fragment>
<div className="flex justify-between items-center mb-4 w-full">
<button
onClick={openModal}
className="flex items-center bg-emerald-600 text-white p-2 rounded-full shadow hover:bg-emerald-900 transition duration-200 mr-4"
>
<Plus className="w-5 h-5" />
</button>
<div className="relative flex-grow">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" size={20} />
<input
@ -613,7 +741,14 @@ const columnsSubscribed = [
onChange={handleSearchChange}
/>
</div>
<button
onClick={openModal}
className="flex items-center bg-emerald-600 text-white p-2 rounded-full shadow hover:bg-emerald-900 transition duration-200 ml-4"
>
<Plus className="w-5 h-5" />
</button>
</div>
<div className="w-full">
<DjangoCSRFToken csrfToken={csrfToken} />
<Table
@ -636,6 +771,25 @@ const columnsSubscribed = [
onPageChange={handlePageChange}
/>
</div>
</React.Fragment>
) : null}
{/*SI STATE == subscribeFiles */}
{activeTab === 'subscribeFiles' && (
<div>
<FileUpload onFileUpload={handleFileUpload} className="mb-4" />
<div className="mt-8">
<Table
data={fichiers}
columns={columnsFiles}
itemsPerPage={itemsPerPage}
currentPage={currentPage}
totalPages={totalPages}
onPageChange={handlePageChange}
className="mt-8"
/>
</div>
</div>
)}
</div>
<Popup
visible={popup.visible}
@ -654,10 +808,10 @@ const columnsSubscribed = [
title={"Création d'un nouveau dossier d'inscription"}
size='sm:w-1/4'
ContentComponent={() => (
<InscriptionForm eleves={eleves}
onSubmit={createDI}
/>
)}
<InscriptionForm eleves={eleves}
onSubmit={createDI}
/>
)}
/>
)}
{isOpenAffectationClasse && (
@ -674,6 +828,17 @@ const columnsSubscribed = [
)}
/>
)}
{isUploadModalOpen && (
<Modal
isOpen={isUploadModalOpen}
setIsOpen={setIsUploadModalOpen}
title="Uploader un nouveau fichier"
size='sm:w-1/4'
ContentComponent={() => (
<FileUpload onFileUpload={handleFileUpload} />
)}
/>
)}
</div>
);
}