mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-28 23:43:22 +00:00
733 lines
25 KiB
JavaScript
733 lines
25 KiB
JavaScript
'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 DropdownMenu from "@/components/DropdownMenu";
|
|
import { formatPhoneNumber } from '@/utils/Telephone';
|
|
import { MoreVertical, Send, Edit, Trash2, FileText, CheckCircle, Plus } from 'lucide-react';
|
|
import Modal from '@/components/Modal';
|
|
import InscriptionForm from '@/components/Inscription/InscriptionForm'
|
|
import AffectationClasseForm from '@/components/AffectationClasseForm'
|
|
|
|
import {
|
|
PENDING,
|
|
SUBSCRIBED,
|
|
ARCHIVED,
|
|
fetchRegisterForms,
|
|
createRegisterForm,
|
|
sendRegisterForm,
|
|
archiveRegisterForm,
|
|
fetchRegisterFormFileTemplate,
|
|
fetchStudents,
|
|
editRegisterForm } from "@/app/actions/subscriptionAction"
|
|
|
|
import {
|
|
fetchClasses,
|
|
fetchRegistrationDiscounts,
|
|
fetchTuitionDiscounts,
|
|
fetchRegistrationFees,
|
|
fetchTuitionFees } from '@/app/actions/schoolAction';
|
|
|
|
import { createProfile } from '@/app/actions/authAction';
|
|
|
|
import {
|
|
BASE_URL,
|
|
FE_ADMIN_SUBSCRIPTIONS_EDIT_URL } from '@/utils/Url';
|
|
|
|
import DjangoCSRFToken from '@/components/DjangoCSRFToken'
|
|
import { useCsrfToken } from '@/context/CsrfContext';
|
|
import { fetchRegistrationFileGroups } from '@/app/actions/registerFileGroupAction';
|
|
import { ESTABLISHMENT_ID } from '@/utils/Url';
|
|
import logger from '@/utils/logger';
|
|
|
|
const useFakeData = process.env.NEXT_PUBLIC_USE_FAKE_DATA === 'true';
|
|
|
|
export default function Page({ params: { locale } }) {
|
|
const t = useTranslations('subscriptions');
|
|
const [registrationForms, setRegistrationForms] = useState([]);
|
|
const [registrationFormsDataPending, setRegistrationFormsDataPending] = useState([]);
|
|
const [registrationFormsDataSubscribed, setRegistrationFormsDataSubscribed] = useState([]);
|
|
const [registrationFormsDataArchived, setRegistrationFormsDataArchived] = useState([]);
|
|
// const [filter, setFilter] = useState('*');
|
|
const [searchTerm, setSearchTerm] = useState('');
|
|
const [alertPage, setAlertPage] = useState(false);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
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 [fichiers, setFichiers] = useState([]);
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const [isOpenAffectationClasse, setIsOpenAffectationClasse] = useState(false);
|
|
const [student, setStudent] = useState('');
|
|
const [classes, setClasses] = useState([]);
|
|
const [students, setEleves] = useState([]);
|
|
const [reloadFetch, setReloadFetch] = useState(false);
|
|
|
|
|
|
const [registrationDiscounts, setRegistrationDiscounts] = useState([]);
|
|
const [tuitionDiscounts, setTuitionDiscounts] = useState([]);
|
|
const [registrationFees, setRegistrationFees] = useState([]);
|
|
const [tuitionFees, setTuitionFees] = useState([]);
|
|
const [groups, setGroups] = useState([]);
|
|
|
|
const csrfToken = useCsrfToken();
|
|
|
|
const openModal = () => {
|
|
setIsOpen(true);
|
|
}
|
|
|
|
const closeModal = () => {
|
|
setIsOpen(false);
|
|
|
|
}
|
|
|
|
const openModalAssociationEleve = (eleveSelected) => {
|
|
setIsOpenAffectationClasse(true);
|
|
setStudent(eleveSelected);
|
|
}
|
|
|
|
const requestErrorHandler = (err)=>{
|
|
logger.error('Error fetching data:', err);
|
|
}
|
|
|
|
/**
|
|
* Handles the pending data for the registration form.
|
|
*
|
|
* @param {Object} data - The data object containing registration forms and count.
|
|
* @param {Array} data.registerForms - The array of registration forms.
|
|
* @param {number} data.count - The total count of registration forms.
|
|
*/
|
|
const registerFormPendingDataHandler = (data) => {
|
|
if (data) {
|
|
const { registerForms, count, page_size } = data;
|
|
if (registerForms) {
|
|
setRegistrationFormsDataPending(registerForms);
|
|
}
|
|
const calculatedTotalPages = count === 0 ? 1 : Math.ceil(count / page_size);
|
|
setTotalPending(count);
|
|
setTotalPages(calculatedTotalPages);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Handles the data received from the subscription registration form.
|
|
*
|
|
* @param {Object} data - The data object received from the subscription registration form.
|
|
* @param {Array} data.registerForms - An array of registration forms.
|
|
* @param {number} data.count - The total count of subscribed forms.
|
|
*/
|
|
const registerFormSubscribedDataHandler = (data) => {
|
|
if (data) {
|
|
const { registerForms, count, page_size } = data;
|
|
setTotalSubscribed(count);
|
|
if (registerForms) {
|
|
setRegistrationFormsDataSubscribed(registerForms);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Handles the archived data for the register form.
|
|
*
|
|
* @param {Object} data - The data object containing archived register forms and count.
|
|
* @param {Array} data.registerForms - The array of archived register forms.
|
|
* @param {number} data.count - The total count of archived register forms.
|
|
*/
|
|
const registerFormArchivedDataHandler = (data) => {
|
|
if (data) {
|
|
const { registerForms, count, page_size } = data;
|
|
|
|
setTotalArchives(count);
|
|
if (registerForms) {
|
|
setRegistrationFormsDataArchived(registerForms);
|
|
}
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
const fetchInitialData = async () => {
|
|
try {
|
|
const [classesData, studentsData] = await Promise.all([
|
|
fetchClasses(),
|
|
fetchStudents()
|
|
]);
|
|
|
|
setClasses(classesData);
|
|
setEleves(studentsData);
|
|
logger.debug('Success - Classes:', classesData);
|
|
logger.debug('Success - Students:', studentsData);
|
|
} catch (error) {
|
|
logger.error('Error fetching initial data:', error);
|
|
}
|
|
};
|
|
|
|
fetchInitialData();
|
|
}, []);
|
|
|
|
|
|
useEffect(() => {
|
|
const fetchDataAndSetState = () => {
|
|
|
|
setIsLoading(true);
|
|
if (!useFakeData) {
|
|
fetchRegisterForms(PENDING, currentPage, itemsPerPage, searchTerm)
|
|
.then(registerFormPendingDataHandler)
|
|
.catch(requestErrorHandler)
|
|
fetchRegisterForms(SUBSCRIBED)
|
|
.then(registerFormSubscribedDataHandler)
|
|
.catch(requestErrorHandler)
|
|
fetchRegisterForms(ARCHIVED)
|
|
.then(registerFormArchivedDataHandler)
|
|
.catch(requestErrorHandler)
|
|
fetchRegisterFormFileTemplate()
|
|
.then((data)=> {
|
|
logger.debug(data);
|
|
|
|
setFichiers(data)
|
|
})
|
|
.catch((err)=>{ err = err.message; logger.debug(err);})
|
|
fetchRegistrationDiscounts()
|
|
.then(data => {
|
|
setRegistrationDiscounts(data);
|
|
})
|
|
.catch(requestErrorHandler)
|
|
fetchTuitionDiscounts()
|
|
.then(data => {
|
|
setTuitionDiscounts(data);
|
|
})
|
|
.catch(requestErrorHandler)
|
|
fetchRegistrationFees()
|
|
.then(data => {
|
|
setRegistrationFees(data);
|
|
})
|
|
.catch(requestErrorHandler)
|
|
fetchTuitionFees()
|
|
.then(data => {
|
|
setTuitionFees(data);
|
|
})
|
|
.catch(requestErrorHandler);
|
|
fetchRegistrationFileGroups()
|
|
.then(data => {
|
|
setGroups(data);
|
|
})
|
|
.catch(error => logger.error('Error fetching file groups:', error));
|
|
} else {
|
|
setTimeout(() => {
|
|
setRegistrationFormsDataPending(mockFicheInscription);
|
|
}, 1000);
|
|
}
|
|
setIsLoading(false);
|
|
setReloadFetch(false);
|
|
};
|
|
|
|
|
|
fetchDataAndSetState();
|
|
}, [reloadFetch, currentPage]);
|
|
|
|
useEffect(() => {
|
|
const fetchDataAndSetState = () => {
|
|
|
|
setIsLoading(true);
|
|
if (!useFakeData) {
|
|
fetchRegisterForms(PENDING, currentPage, itemsPerPage, searchTerm)
|
|
.then(registerFormPendingDataHandler)
|
|
.catch(requestErrorHandler)
|
|
fetchRegisterForms(SUBSCRIBED)
|
|
.then(registerFormSubscribedDataHandler)
|
|
.catch(requestErrorHandler)
|
|
fetchRegisterForms(ARCHIVED)
|
|
.then(registerFormArchivedDataHandler)
|
|
.catch(requestErrorHandler)
|
|
fetchRegisterFormFileTemplate()
|
|
.then((data)=> {setFichiers(data)})
|
|
.catch((err)=>{ err = err.message; logger.debug(err);});
|
|
} else {
|
|
setTimeout(() => {
|
|
setRegistrationFormsDataPending(mockFicheInscription);
|
|
}, 1000);
|
|
}
|
|
setIsLoading(false);
|
|
setReloadFetch(false);
|
|
};
|
|
|
|
const timeoutId = setTimeout(() => {
|
|
fetchDataAndSetState();
|
|
}, 500); // Debounce la recherche
|
|
return () => clearTimeout(timeoutId);
|
|
}, [searchTerm]);
|
|
|
|
/**
|
|
* UseEffect to update page count of tab
|
|
*/
|
|
useEffect(()=>{
|
|
if (activeTab === 'pending') {
|
|
setTotalPages(Math.ceil(totalPending / itemsPerPage));
|
|
} else if (activeTab === 'subscribed') {
|
|
setTotalPages(Math.ceil(totalSubscribed / itemsPerPage));
|
|
} else if (activeTab === 'archived') {
|
|
setTotalPages(Math.ceil(totalArchives / itemsPerPage));
|
|
}
|
|
},[currentPage]);
|
|
/**
|
|
* Archives a registration form after user confirmation.
|
|
*
|
|
* @param {number} id - The ID of the registration form to be archived.
|
|
* @param {string} nom - The last name of the person whose registration form is being archived.
|
|
* @param {string} prenom - The first name of the person whose registration form is being archived.
|
|
*/
|
|
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: () => {
|
|
archiveRegisterForm(id)
|
|
.then(data => {
|
|
logger.debug('Success:', data);
|
|
setRegistrationForms(registrationForms.filter(fiche => fiche.id !== id));
|
|
setReloadFetch(true);
|
|
alert("Le dossier d'inscription a été correctement archivé");
|
|
})
|
|
.catch(error => {
|
|
logger.error('Error archiving data:', error);
|
|
alert("Erreur lors de l'archivage du dossier d'inscription.\nContactez l'administrateur.");
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
const sendConfirmRegisterForm = (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: () => {
|
|
sendRegisterForm(id).then(data => {
|
|
logger.debug('Success:', data);
|
|
setReloadFetch(true);
|
|
})
|
|
.catch(error => {
|
|
logger.error('Error fetching data:', error);
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
const affectationClassFormSubmitHandler = (formdata)=> {
|
|
editRegisterForm(student.id,formData, csrfToken)
|
|
.then(data => {
|
|
logger.debug('Success:', data);
|
|
setReloadFetch(true);
|
|
})
|
|
.catch(error => {
|
|
logger.error('Error :', error);
|
|
});
|
|
}
|
|
|
|
const updateStatusAction = (id, newStatus) => {
|
|
logger.debug('Edit fiche inscription with id:', id);
|
|
};
|
|
|
|
const handleSearchChange = (event) => {
|
|
setSearchTerm(event.target.value);
|
|
};
|
|
|
|
const handlePageChange = (newPage) => {
|
|
setCurrentPage(newPage);
|
|
};
|
|
|
|
const createRF = (updatedData) => {
|
|
logger.debug('createRF updatedData:', updatedData);
|
|
const selectedRegistrationFeesIds = updatedData.selectedRegistrationFees.map(feeId => feeId)
|
|
const selectedRegistrationDiscountsIds = updatedData.selectedRegistrationDiscounts.map(discountId => discountId)
|
|
const selectedTuitionFeesIds = updatedData.selectedTuitionFees.map(feeId => feeId)
|
|
const selectedTuitionDiscountsIds = updatedData.selectedTuitionDiscounts.map(discountId => discountId)
|
|
const selectedFileGroup = updatedData.selectedFileGroup
|
|
const allFeesIds = [...selectedRegistrationFeesIds, ...selectedTuitionFeesIds];
|
|
const allDiscountsds = [...selectedRegistrationDiscountsIds, ...selectedTuitionDiscountsIds];
|
|
|
|
if (updatedData.selectedGuardians.length !== 0) {
|
|
const selectedGuardiansIds = updatedData.selectedGuardians.map(guardianId => guardianId)
|
|
const data = {
|
|
student: {
|
|
last_name: updatedData.studentLastName,
|
|
first_name: updatedData.studentFirstName,
|
|
},
|
|
idGuardians: selectedGuardiansIds,
|
|
fees: allFeesIds,
|
|
discounts: allDiscountsds,
|
|
fileGroup: selectedFileGroup,
|
|
establishment: ESTABLISHMENT_ID
|
|
};
|
|
|
|
createRegisterForm(data, csrfToken)
|
|
.then(data => {
|
|
// Mise à jour immédiate des données
|
|
setRegistrationFormsDataPending(prevState => [...(prevState || []), data]);
|
|
setTotalPending(prev => prev + 1);
|
|
if (updatedData.autoMail) {
|
|
sendConfirmRegisterForm(data.student.id, updatedData.studentLastName, updatedData.studentFirstName);
|
|
}
|
|
closeModal();
|
|
// Forcer le rechargement complet des données
|
|
setReloadFetch(true);
|
|
})
|
|
.catch((error) => {
|
|
logger.error('Error:', error);
|
|
});
|
|
} else {
|
|
const data = {
|
|
email: updatedData.guardianEmail,
|
|
password: 'Provisoire01!',
|
|
username: updatedData.guardianEmail,
|
|
is_active: 0,
|
|
droit: 2
|
|
}
|
|
|
|
createProfile(data, csrfToken)
|
|
.then(response => {
|
|
if (response.id) {
|
|
const data = {
|
|
student: {
|
|
last_name: updatedData.studentLastName,
|
|
first_name: updatedData.studentFirstName,
|
|
guardians: [{
|
|
email: updatedData.guardianEmail,
|
|
phone: updatedData.guardianPhone,
|
|
associated_profile: response.id
|
|
}],
|
|
sibling: []
|
|
},
|
|
fees: allFeesIds,
|
|
discounts: allDiscountsds,
|
|
establishment: ESTABLISHMENT_ID
|
|
};
|
|
|
|
createRegisterForm(data, csrfToken)
|
|
.then(data => {
|
|
// Mise à jour immédiate des données
|
|
setRegistrationFormsDataPending(prevState => [...(prevState || []), data]);
|
|
setTotalPending(prev => prev + 1);
|
|
if (updatedData.autoMail) {
|
|
sendConfirmRegisterForm(data.student.id, updatedData.studentLastName, updatedData.studentFirstName);
|
|
}
|
|
closeModal();
|
|
logger.debug('Success:', data);
|
|
// Forcer le rechargement complet des données
|
|
setReloadFetch(true);
|
|
})
|
|
.catch((error) => {
|
|
logger.error('Error:', error);
|
|
});
|
|
}
|
|
})
|
|
.catch(error => {
|
|
logger.error('Error:', error);
|
|
});
|
|
}
|
|
}
|
|
|
|
const columns = [
|
|
{ name: t('studentName'), transform: (row) => row.student.last_name },
|
|
{ name: t('studentFistName'), transform: (row) => row.student.first_name },
|
|
{ name: t('mainContactMail'), transform: (row) => row.student.guardians[0].email },
|
|
{ name: t('phone'), transform: (row) => formatPhoneNumber(row.student.guardians[0].phone) },
|
|
{ name: t('lastUpdateDate'), transform: (row) => row.formatted_last_update},
|
|
{ name: t('registrationFileStatus'), transform: (row) => (
|
|
<div className="flex justify-center items-center h-full">
|
|
<StatusLabel status={row.status} onChange={(newStatus) => updateStatusAction(row.student.id, newStatus)} showDropdown={false} />
|
|
</div>
|
|
)
|
|
},
|
|
{ name: t('files'), transform: (row) =>
|
|
(row.registration_file != null) &&(
|
|
<ul>
|
|
<li className="flex items-center gap-2">
|
|
<FileText size={16} />
|
|
<a href={ `${BASE_URL}${row.registration_file}`} target='_blank'>{row.registration_file?.split('/').pop()}</a>
|
|
</li>
|
|
</ul>
|
|
) },
|
|
{ name: 'Actions', transform: (row) => (
|
|
<DropdownMenu
|
|
buttonContent={<MoreVertical size={20} className="text-gray-400 hover:text-gray-600" />}
|
|
items={[
|
|
...(row.status === 1 ? [{
|
|
label: (
|
|
<>
|
|
<Send size={16} className="mr-2" /> Envoyer
|
|
</>
|
|
),
|
|
onClick: () => sendConfirmRegisterForm(row.student.id, row.student.last_name, row.student.first_name),
|
|
}] : []),
|
|
...(row.status === 1 ? [{
|
|
label: (
|
|
<>
|
|
<Edit size={16} className="mr-2" /> Modifier
|
|
</>
|
|
),
|
|
onClick: () => window.location.href = `${FE_ADMIN_SUBSCRIPTIONS_EDIT_URL}?studentId=${row.student.id}&id=1`,
|
|
}] : []),
|
|
...(row.status === 2 ? [{
|
|
label: (
|
|
<>
|
|
<Edit size={16} className="mr-2" /> Modifier
|
|
</>
|
|
),
|
|
onClick: () => window.location.href = `${FE_ADMIN_SUBSCRIPTIONS_EDIT_URL}?studentId=${row.student.id}&id=1`,
|
|
}] : []),
|
|
...(row.status === 3 ? [{
|
|
label: (
|
|
<>
|
|
<CheckCircle size={16} className="mr-2" /> Valider
|
|
</>
|
|
),
|
|
onClick: () => openModalAssociationEleve(row.student),
|
|
}] : []),
|
|
...(row.status === 5 ? [{
|
|
label: (
|
|
<>
|
|
<CheckCircle size={16} className="mr-2" /> Rattacher
|
|
</>
|
|
),
|
|
onClick: () => openModalAssociationEleve(row.student),
|
|
}] : []),
|
|
...(row.status !== 6 ? [{
|
|
label: (
|
|
<>
|
|
<Trash2 size={16} className="mr-2 text-red-700" /> Archiver
|
|
</>
|
|
),
|
|
onClick: () => archiveFicheInscription(row.student.id, row.student.last_name, row.student.first_name),
|
|
}] : []),
|
|
]}
|
|
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.student.last_name },
|
|
{ name: t('studentFistName'), transform: (row) => row.student.first_name },
|
|
{ name: t('lastUpdateDate'), transform: (row) => row.updated_date_formated},
|
|
{ name: t('class'), transform: (row) => row.student.first_name},
|
|
{ name: t('registrationFileStatus'), transform: (row) =>
|
|
(
|
|
<div className="flex justify-center items-center h-full">
|
|
<StatusLabel status={row.status} onChange={(newStatus) => updateStatusAction(row.student.id, newStatus)} showDropdown={false} />
|
|
</div>
|
|
)
|
|
},
|
|
{ name: t('files'), transform: (row) =>
|
|
(row.registration_file != null) &&(
|
|
<ul>
|
|
<li className="flex items-center gap-2">
|
|
<FileText size={16} />
|
|
<a href={ `${BASE_URL}${row.registration_file}`} target='_blank'>{row.registration_file?.split('/').pop()}</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.student)
|
|
},
|
|
{ label: (
|
|
<>
|
|
<Trash2 size={16} className="mr-2 text-red-700" /> Archiver
|
|
</>
|
|
),
|
|
onClick: () => archiveFicheInscription(row.student.id, row.student.last_name, row.student.first_name),
|
|
}
|
|
]}
|
|
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 tabs = [
|
|
{
|
|
id: 'pending',
|
|
label: t('pending'),
|
|
count: totalPending
|
|
},
|
|
{
|
|
id: 'subscribed',
|
|
label: t('subscribed'),
|
|
count: totalSubscribed
|
|
},
|
|
{
|
|
id: 'archived',
|
|
label: t('archived'),
|
|
count: totalArchives
|
|
}
|
|
];
|
|
|
|
if (isLoading) {
|
|
return <Loader />;
|
|
} else {
|
|
if (registrationForms.length === 0 && registrationFormsDataArchived.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 items-center 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')}
|
|
/>
|
|
</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">
|
|
<div className="relative flex-grow">
|
|
<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>
|
|
<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
|
|
key={`${currentPage}-${searchTerm}`}
|
|
data={
|
|
activeTab === 'pending'
|
|
? registrationFormsDataPending
|
|
: activeTab === 'subscribed'
|
|
? registrationFormsDataSubscribed
|
|
: registrationFormsDataArchived
|
|
}
|
|
columns={
|
|
activeTab === 'subscribed'
|
|
? columnsSubscribed
|
|
: columns
|
|
}
|
|
itemsPerPage={itemsPerPage}
|
|
currentPage={currentPage}
|
|
totalPages={totalPages}
|
|
onPageChange={handlePageChange}
|
|
/>
|
|
</div>
|
|
</React.Fragment>
|
|
) : null}
|
|
</div>
|
|
<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={"Nouveau dossier d'inscription"}
|
|
ContentComponent={() => (
|
|
<InscriptionForm students={students}
|
|
registrationDiscounts={registrationDiscounts}
|
|
tuitionDiscounts={tuitionDiscounts}
|
|
registrationFees={registrationFees.filter(fee => fee.is_active)}
|
|
tuitionFees={tuitionFees.filter(fee => fee.is_active)}
|
|
groups={groups}
|
|
onSubmit={createRF}
|
|
/>
|
|
)}
|
|
/>
|
|
)}
|
|
{isOpenAffectationClasse && (
|
|
<Modal
|
|
isOpen={isOpenAffectationClasse}
|
|
setIsOpen={setIsOpenAffectationClasse}
|
|
title="Affectation à une classe"
|
|
ContentComponent={() => (
|
|
<AffectationClasseForm
|
|
student={student}
|
|
onSubmit={affectationClassFormSubmitHandler}
|
|
classes={classes}
|
|
/>
|
|
)}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
} |