mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-28 23:43:22 +00:00
refactor: Renommage du menu "Eleves" en "Inscriptions"
This commit is contained in:
651
Front-End/src/app/[locale]/admin/subscriptions/page.js
Normal file
651
Front-End/src/app/[locale]/admin/subscriptions/page.js
Normal file
@ -0,0 +1,651 @@
|
||||
'use client'
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import Table from '@/components/Table';
|
||||
import {mockFicheInscription} from '@/data/mockFicheInscription';
|
||||
import Tab from '@/components/Tab';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import StatusLabel from '@/components/StatusLabel';
|
||||
import { Search } from 'lucide-react';
|
||||
import Popup from '@/components/Popup';
|
||||
import Loader from '@/components/Loader';
|
||||
import AlertWithModal from '@/components/AlertWithModal';
|
||||
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 } from 'lucide-react';
|
||||
import Modal from '@/components/Modal';
|
||||
import InscriptionForm from '@/components/Inscription/InscriptionForm'
|
||||
import AffectationClasseForm from '@/components/AffectationClasseForm'
|
||||
|
||||
import { BK_GESTIONINSCRIPTION_FICHESINSCRIPTION_URL,
|
||||
BK_GESTIONINSCRIPTION_SEND_URL,
|
||||
FR_ADMIN_SUBSCRIPTIONS_EDIT_URL,
|
||||
BK_GESTIONINSCRIPTION_ARCHIVE_URL,
|
||||
BK_GESTIONINSCRIPTION_CLASSES_URL,
|
||||
BK_GESTIONINSCRIPTION_FICHEINSCRIPTION_URL,
|
||||
BK_GESTIONINSCRIPTION_ELEVES_URL,
|
||||
BK_PROFILE_URL } from '@/utils/Url';
|
||||
|
||||
import DjangoCSRFToken from '@/components/DjangoCSRFToken'
|
||||
import useCsrfToken from '@/hooks/useCsrfToken';
|
||||
|
||||
const useFakeData = process.env.NEXT_PUBLIC_USE_FAKE_DATA === 'true';
|
||||
|
||||
export default function Page({ params: { locale } }) {
|
||||
const t = useTranslations('subscriptions');
|
||||
const [ficheInscriptions, setFicheInscriptions] = useState([]);
|
||||
const [fichesInscriptionsDataEnCours, setFichesInscriptionsDataEnCours] = useState([]);
|
||||
const [fichesInscriptionsDataInscrits, setFichesInscriptionsDataInscrits] = useState([]);
|
||||
const [fichesInscriptionsDataArchivees, setFichesInscriptionsDataArchivees] = useState([]);
|
||||
// const [filter, setFilter] = useState('*');
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [alertPage, setAlertPage] = useState(false);
|
||||
const [mailSent, setMailSent] = useState(false);
|
||||
const [ficheArchivee, setFicheArchivee] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [popup, setPopup] = useState({ visible: false, message: '', onConfirm: null });
|
||||
const [activeTab, setActiveTab] = useState('pending');
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [totalPages, setTotalPages] = useState(1);
|
||||
const [totalPending, setTotalPending] = useState(0);
|
||||
const [totalSubscribed, setTotalSubscribed] = useState(0);
|
||||
const [totalArchives, setTotalArchives] = useState(0);
|
||||
const [itemsPerPage, setItemsPerPage] = useState(5); // Définir le nombre d'éléments par page
|
||||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [isOpenAffectationClasse, setIsOpenAffectationClasse] = useState(false);
|
||||
const [eleve, setEleve] = useState('');
|
||||
const [classes, setClasses] = useState([]);
|
||||
const [eleves, setEleves] = useState([]);
|
||||
|
||||
const csrfToken = useCsrfToken();
|
||||
|
||||
const openModal = () => {
|
||||
setIsOpen(true);
|
||||
}
|
||||
|
||||
const closeModal = () => {
|
||||
setIsOpen(false);
|
||||
}
|
||||
|
||||
const openModalAssociationEleve = (eleveSelected) => {
|
||||
setIsOpenAffectationClasse(true);
|
||||
setEleve(eleveSelected);
|
||||
}
|
||||
// Modifier la fonction fetchData pour inclure le terme de recherche
|
||||
const fetchData = (page, pageSize, search = '') => {
|
||||
const url = `${BK_GESTIONINSCRIPTION_FICHESINSCRIPTION_URL}/pending?page=${page}&page_size=${pageSize}&search=${search}`;
|
||||
fetch(url, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}).then(response => response.json())
|
||||
.then(data => {
|
||||
setIsLoading(false);
|
||||
if (data) {
|
||||
const { fichesInscriptions, count } = data;
|
||||
if (ficheInscriptions) {
|
||||
setFichesInscriptionsDataEnCours(fichesInscriptions);
|
||||
}
|
||||
const calculatedTotalPages = Math.ceil(count / pageSize);
|
||||
setTotalPending(count);
|
||||
setTotalPages(calculatedTotalPages);
|
||||
}
|
||||
console.log('Success PENDING:', data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching data:', error);
|
||||
setIsLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
const fetchDataSubscribed = () => {
|
||||
fetch(`${BK_GESTIONINSCRIPTION_FICHESINSCRIPTION_URL}/subscribed`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}).then(response => response.json())
|
||||
.then(data => {
|
||||
setIsLoading(false);
|
||||
if (data) {
|
||||
const { fichesInscriptions, count } = data;
|
||||
setTotalSubscribed(count);
|
||||
if (fichesInscriptions) {
|
||||
setFichesInscriptionsDataInscrits(fichesInscriptions);
|
||||
}
|
||||
}
|
||||
console.log('Success SUBSCRIBED:', data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching data:', error);
|
||||
setIsLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
const fetchDataArchived = () => {
|
||||
fetch(`${BK_GESTIONINSCRIPTION_FICHESINSCRIPTION_URL}/archived`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}).then(response => response.json())
|
||||
.then(data => {
|
||||
setIsLoading(false);
|
||||
if (data) {
|
||||
const { fichesInscriptions, count } = data;
|
||||
setTotalArchives(count);
|
||||
if (fichesInscriptions) {
|
||||
setFichesInscriptionsDataArchivees(fichesInscriptions);
|
||||
}
|
||||
}
|
||||
console.log('Success ARCHIVED:', data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching data:', error);
|
||||
setIsLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
const fetchClasses = () => {
|
||||
fetch(`${BK_GESTIONINSCRIPTION_CLASSES_URL}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
setClasses(data);
|
||||
console.log("Success CLASSES : ", data)
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching classes:', error);
|
||||
});
|
||||
};
|
||||
|
||||
const fetchStudents = () => {
|
||||
const request = new Request(
|
||||
`${BK_GESTIONINSCRIPTION_ELEVES_URL}`,
|
||||
{
|
||||
method:'GET',
|
||||
headers: {
|
||||
'Content-Type':'application/json'
|
||||
},
|
||||
}
|
||||
);
|
||||
fetch(request).then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Success STUDENTS:', data);
|
||||
setEleves(data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching data:', error);
|
||||
error = error.message;
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchClasses();
|
||||
fetchStudents();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchDataAndSetState = () => {
|
||||
if (!useFakeData) {
|
||||
fetchData(currentPage, itemsPerPage, searchTerm);
|
||||
fetchDataSubscribed();
|
||||
fetchDataArchived();
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
setFichesInscriptionsDataEnCours(mockFicheInscription);
|
||||
setIsLoading(false);
|
||||
}, 1000);
|
||||
}
|
||||
setFicheArchivee(false);
|
||||
setMailSent(false);
|
||||
};
|
||||
|
||||
fetchDataAndSetState();
|
||||
}, [mailSent, ficheArchivee, currentPage, itemsPerPage]);
|
||||
|
||||
// Modifier le useEffect pour la recherche
|
||||
useEffect(() => {
|
||||
const timeoutId = setTimeout(() => {
|
||||
fetchData(currentPage, itemsPerPage, searchTerm);
|
||||
}, 500); // Debounce la recherche
|
||||
|
||||
return () => clearTimeout(timeoutId);
|
||||
}, [searchTerm, currentPage, itemsPerPage]);
|
||||
|
||||
const archiveFicheInscription = (id, nom, prenom) => {
|
||||
setPopup({
|
||||
visible: true,
|
||||
message: `Attentions ! \nVous êtes sur le point d'archiver le dossier d'inscription de ${nom} ${prenom}\nÊtes-vous sûr(e) de vouloir poursuivre l'opération ?`,
|
||||
onConfirm: () => {
|
||||
const url = `${BK_GESTIONINSCRIPTION_ARCHIVE_URL}/${id}`;
|
||||
fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}).then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Success:', data);
|
||||
setFicheInscriptions(ficheInscriptions.filter(fiche => fiche.id !== id));
|
||||
setFicheArchivee(true);
|
||||
alert("Le dossier d'inscription a été correctement archivé");
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error archiving data:', error);
|
||||
alert("Erreur lors de l'archivage du dossier d'inscription.\nContactez l'administrateur.");
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const sendConfirmFicheInscription = (id, nom, prenom) => {
|
||||
setPopup({
|
||||
visible: true,
|
||||
message: `Avertissement ! \nVous êtes sur le point d'envoyer un dossier d'inscription à ${nom} ${prenom}\nÊtes-vous sûr(e) de vouloir poursuivre l'opération ?`,
|
||||
onConfirm: () => {
|
||||
const url = `${BK_GESTIONINSCRIPTION_SEND_URL}/${id}`;
|
||||
fetch(url, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}).then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Success:', data);
|
||||
setMailSent(true);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching data:', error);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const updateStatusAction = (id, newStatus) => {
|
||||
console.log('Edit fiche inscription with id:', id);
|
||||
};
|
||||
|
||||
const handleLetterClick = (letter) => {
|
||||
setFilter(letter);
|
||||
};
|
||||
|
||||
const handleSearchChange = (event) => {
|
||||
setSearchTerm(event.target.value);
|
||||
};
|
||||
|
||||
const handlePageChange = (newPage) => {
|
||||
setCurrentPage(newPage);
|
||||
fetchData(newPage, itemsPerPage); // Appeler fetchData directement ici
|
||||
};
|
||||
|
||||
const createDI = (updatedData) => {
|
||||
if (updatedData.selectedResponsables.length !== 0) {
|
||||
const selectedResponsablesIds = updatedData.selectedResponsables.map(responsableId => responsableId)
|
||||
|
||||
const data = {
|
||||
eleve: {
|
||||
nom: updatedData.eleveNom,
|
||||
prenom: updatedData.elevePrenom,
|
||||
},
|
||||
idResponsables: selectedResponsablesIds
|
||||
};
|
||||
|
||||
const url = `${BK_GESTIONINSCRIPTION_FICHEINSCRIPTION_URL}`;
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': csrfToken
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
credentials: 'include'
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Success:', data);
|
||||
setFichesInscriptionsDataEnCours(prevState => [...prevState, data]);
|
||||
setTotalPending(totalPending+1);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
}
|
||||
else {
|
||||
// Création d'un profil associé à l'adresse mail du responsable saisie
|
||||
// Le profil est inactif
|
||||
const request = new Request(
|
||||
`${BK_PROFILE_URL}`,
|
||||
{
|
||||
method:'POST',
|
||||
headers: {
|
||||
'Content-Type':'application/json',
|
||||
'X-CSRFToken': csrfToken
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify( {
|
||||
email: updatedData.responsableEmail,
|
||||
password: 'Provisoire01!',
|
||||
username: updatedData.responsableEmail,
|
||||
is_active: 0, // On rend le profil inactif : impossible de s'y connecter dans la fenêtre du login tant qu'il ne s'est pas inscrit
|
||||
droit:1
|
||||
}),
|
||||
}
|
||||
);
|
||||
fetch(request).then(response => response.json())
|
||||
.then(response => {
|
||||
console.log('Success:', response);
|
||||
if (response.id) {
|
||||
let idProfil = response.id;
|
||||
|
||||
const data = {
|
||||
eleve: {
|
||||
nom: updatedData.eleveNom,
|
||||
prenom: updatedData.elevePrenom,
|
||||
responsables: [
|
||||
{
|
||||
mail: updatedData.responsableEmail,
|
||||
//telephone: telephoneResponsable,
|
||||
profilAssocie: idProfil // Association entre le reponsable de l'élève et le profil créé par défaut précédemment
|
||||
}
|
||||
],
|
||||
freres: []
|
||||
}
|
||||
};
|
||||
const url = `${BK_GESTIONINSCRIPTION_FICHEINSCRIPTION_URL}`;
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': csrfToken
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
credentials: 'include'
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Success:', data);
|
||||
setFichesInscriptionsDataEnCours(prevState => [...prevState, data]);
|
||||
setTotalPending(totalPending+1);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching data:', error);
|
||||
error = error.errorMessage;
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
closeModal();
|
||||
}
|
||||
|
||||
const validateAndAssociate = (updatedData) => {
|
||||
fetch(`${BK_GESTIONINSCRIPTION_FICHEINSCRIPTION_URL}/${eleve.id}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': csrfToken
|
||||
},
|
||||
body: JSON.stringify(updatedData),
|
||||
credentials: 'include'
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Succès :', data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erreur :', error);
|
||||
});
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{ name: t('studentName'), transform: (row) => row.eleve.nom },
|
||||
{ name: t('studentFistName'), transform: (row) => row.eleve.prenom },
|
||||
{ name: t('mainContactMail'), transform: (row) => row.eleve.responsables[0].mail },
|
||||
{ name: t('phone'), transform: (row) => formatPhoneNumber(row.eleve.responsables[0].telephone) },
|
||||
{ name: t('lastUpdateDate'), transform: (row) => row.dateMAJ_formattee},
|
||||
{ name: t('registrationFileStatus'), transform: (row) => (
|
||||
<div className="flex justify-center items-center h-full">
|
||||
<StatusLabel etat={row.etat} onChange={(newStatus) => updateStatusAction(row.eleve.id, newStatus)} showDropdown={false} />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{ name: t('files'), transform: (row) => (
|
||||
<ul>
|
||||
{row.fichiers?.map((fichier, fileIndex) => (
|
||||
<li key={fileIndex} className="flex items-center gap-2">
|
||||
<FileText size={16} />
|
||||
<a href={fichier.url}>{fichier.nom}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
) },
|
||||
{ name: 'Actions', transform: (row) => (
|
||||
<DropdownMenu
|
||||
buttonContent={<MoreVertical size={20} className="text-gray-400 hover:text-gray-600" />}
|
||||
items={[
|
||||
...(row.etat === 1 ? [{
|
||||
label: (
|
||||
<>
|
||||
<Send size={16} className="mr-2" /> Envoyer
|
||||
</>
|
||||
),
|
||||
onClick: () => sendConfirmFicheInscription(row.eleve.id, row.eleve.nom, row.eleve.prenom),
|
||||
}] : []),
|
||||
...(row.etat === 1 ? [{
|
||||
label: (
|
||||
<>
|
||||
<Edit size={16} className="mr-2" /> Modifier
|
||||
</>
|
||||
),
|
||||
onClick: () => window.location.href = `${FR_ADMIN_SUBSCRIPTIONS_EDIT_URL}?idEleve=${row.eleve.id}&id=1`,
|
||||
}] : []),
|
||||
...(row.etat === 2 ? [{
|
||||
label: (
|
||||
<>
|
||||
<Edit size={16} className="mr-2" /> Modifier
|
||||
</>
|
||||
),
|
||||
onClick: () => window.location.href = `${FR_ADMIN_SUBSCRIPTIONS_EDIT_URL}?idEleve=${row.eleve.id}&id=1`,
|
||||
}] : []),
|
||||
...(row.etat === 3 ? [{
|
||||
label: (
|
||||
<>
|
||||
<CheckCircle size={16} className="mr-2" /> Valider
|
||||
</>
|
||||
),
|
||||
onClick: () => openModalAssociationEleve(row.eleve),
|
||||
}] : []),
|
||||
...(row.etat === 5 ? [{
|
||||
label: (
|
||||
<>
|
||||
<CheckCircle size={16} className="mr-2" /> Rattacher
|
||||
</>
|
||||
),
|
||||
onClick: () => openModalAssociationEleve(row.eleve),
|
||||
}] : []),
|
||||
...(row.etat !== 6 ? [{
|
||||
label: (
|
||||
<>
|
||||
<Trash2 size={16} className="mr-2 text-red-700" /> Archiver
|
||||
</>
|
||||
),
|
||||
onClick: () => archiveFicheInscription(row.eleve.id, row.eleve.nom, row.eleve.prenom),
|
||||
}] : []),
|
||||
]}
|
||||
buttonClassName="text-gray-400 hover:text-gray-600"
|
||||
menuClassName="absolute right-0 mt-2 w-48 bg-white border border-gray-200 rounded-md shadow-lg z-10 flex flex-col items-center"
|
||||
/>
|
||||
) },
|
||||
|
||||
];
|
||||
|
||||
const columnsSubscribed = [
|
||||
{ name: t('studentName'), transform: (row) => row.eleve.nom },
|
||||
{ name: t('studentFistName'), transform: (row) => row.eleve.prenom },
|
||||
{ name: t('lastUpdateDate'), transform: (row) => row.dateMAJ_formattee},
|
||||
{ name: t('class'), transform: (row) => row.eleve.classeAssocieeName},
|
||||
{ name: t('registrationFileStatus'), transform: (row) => (
|
||||
<div className="flex justify-center items-center h-full">
|
||||
<StatusLabel etat={row.etat} onChange={(newStatus) => updateStatusAction(row.eleve.id, newStatus)} showDropdown={false} />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{ name: t('files'), transform: (row) => (
|
||||
<ul>
|
||||
{row.fichiers?.map((fichier, fileIndex) => (
|
||||
<li key={fileIndex} className="flex items-center gap-2">
|
||||
<FileText size={16} />
|
||||
<a href={fichier.url}>{fichier.nom}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
) },
|
||||
{ name: 'Actions', transform: (row) => (
|
||||
<DropdownMenu
|
||||
buttonContent={<MoreVertical size={20} className="text-gray-400 hover:text-gray-600" />}
|
||||
items={[
|
||||
{ label: (
|
||||
<>
|
||||
<CheckCircle size={16} className="mr-2" /> Rattacher
|
||||
</>
|
||||
),
|
||||
onClick: () => openModalAssociationEleve(row.eleve)
|
||||
},
|
||||
{ label: (
|
||||
<>
|
||||
<Trash2 size={16} className="mr-2 text-red-700" /> Archiver
|
||||
</>
|
||||
),
|
||||
onClick: () => archiveFicheInscription(row.eleve.id, row.eleve.nom, row.eleve.prenom),
|
||||
}
|
||||
]}
|
||||
buttonClassName="text-gray-400 hover:text-gray-600"
|
||||
menuClassName="absolute right-0 mt-2 w-48 bg-white border border-gray-200 rounded-md shadow-lg z-10 flex flex-col items-center"
|
||||
/>
|
||||
) },
|
||||
|
||||
];
|
||||
|
||||
if (isLoading) {
|
||||
return <Loader />;
|
||||
} else {
|
||||
if (ficheInscriptions.length === 0 && fichesInscriptionsDataArchivees.length === 0 && alertPage) {
|
||||
return (
|
||||
<div className='p-8'>
|
||||
<AlertWithModal
|
||||
title={t("information")}
|
||||
message={t("no_records") + " " + t("create_first_record")}
|
||||
buttonText={t("add_button")}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className='p-8'>
|
||||
<div className="border-b border-gray-200 mb-6">
|
||||
<div className="flex gap-8">
|
||||
<Tab
|
||||
text={<>
|
||||
{t('pending')}
|
||||
<span className="ml-2 text-sm text-gray-400">({totalPending})</span>
|
||||
</>}
|
||||
active={activeTab === 'pending'}
|
||||
onClick={() => setActiveTab('pending')}
|
||||
/>
|
||||
<Tab
|
||||
text={<>
|
||||
{t('subscribed')}
|
||||
<span className="ml-2 text-sm text-gray-400">({totalSubscribed})</span>
|
||||
</>}
|
||||
active={activeTab === 'subscribed'}
|
||||
onClick={() => setActiveTab('subscribed')}
|
||||
/>
|
||||
<Tab
|
||||
text={<>
|
||||
{t('archived')}
|
||||
<span className="ml-2 text-sm text-gray-400">({totalArchives})</span>
|
||||
</>}
|
||||
active={activeTab === 'archived'}
|
||||
onClick={() => setActiveTab('archived')}
|
||||
/>
|
||||
<Button text={t("addStudent")} primary onClick={openModal} icon={<UserPlus size={20} />} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div className="relative flex-grow mr-4">
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" size={20} />
|
||||
<input
|
||||
type="text"
|
||||
placeholder={t('searchStudent')}
|
||||
className="w-full pl-10 pr-4 py-2 border border-gray-200 rounded-md"
|
||||
value={searchTerm}
|
||||
onChange={handleSearchChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DjangoCSRFToken csrfToken={csrfToken} />
|
||||
<Table
|
||||
key={`${currentPage}-${searchTerm}`}
|
||||
data={
|
||||
activeTab === 'pending'
|
||||
? fichesInscriptionsDataEnCours
|
||||
: activeTab === 'subscribed'
|
||||
? fichesInscriptionsDataInscrits
|
||||
: fichesInscriptionsDataArchivees
|
||||
}
|
||||
columns={
|
||||
activeTab === 'subscribed'
|
||||
? columnsSubscribed
|
||||
: columns
|
||||
}
|
||||
itemsPerPage={itemsPerPage}
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
onPageChange={handlePageChange}
|
||||
/>
|
||||
<Popup
|
||||
visible={popup.visible}
|
||||
message={popup.message}
|
||||
onConfirm={() => {
|
||||
popup.onConfirm();
|
||||
setPopup({ ...popup, visible: false });
|
||||
}}
|
||||
onCancel={() => setPopup({ ...popup, visible: false })}
|
||||
/>
|
||||
|
||||
{isOpen && (
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
setIsOpen={setIsOpen}
|
||||
title={"Création d'un nouveau dossier d'inscription"}
|
||||
ContentComponent={() => (
|
||||
<InscriptionForm eleves={eleves}
|
||||
onSubmit={createDI}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{isOpenAffectationClasse && (
|
||||
<Modal
|
||||
isOpen={isOpenAffectationClasse}
|
||||
setIsOpen={setIsOpenAffectationClasse}
|
||||
title="Affectation à une classe"
|
||||
ContentComponent={() => (
|
||||
<AffectationClasseForm
|
||||
eleve={eleve}
|
||||
onSubmit={validateAndAssociate}
|
||||
classes={classes}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user