fix: application des recommandations linter es pour générer un build de prod

This commit is contained in:
Luc SORIGNET
2025-02-15 13:02:16 +01:00
parent 9716373fa2
commit d1aa8b54fb
23 changed files with 131 additions and 91 deletions

View File

@ -5,12 +5,31 @@ const withNextIntl = createNextIntlPlugin();
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
output: 'standalone',
webpack: (config, { isServer }) => {
// Configuration pour améliorer le hot reload dans Docker
config.watchOptions = {
poll: 1000,
aggregateTimeout: 300,
}
return config
},
experimental: { experimental: {
instrumentationHook: true, instrumentationHook: true,
}, },
env: { env: {
NEXT_PUBLIC_APP_VERSION: pkg.version, NEXT_PUBLIC_APP_VERSION: pkg.version,
}, },
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'i.pravatar.cc',
port: '',
pathname: '/**',
},
],
},
}; };
export default withNextIntl(nextConfig); export default withNextIntl(nextConfig);

View File

@ -26,6 +26,7 @@ import {
import { disconnect } from '@/app/lib/authAction'; import { disconnect } from '@/app/lib/authAction';
import { fetchEstablishment } from '@/app/lib/schoolAction'; import { fetchEstablishment } from '@/app/lib/schoolAction';
import Image from 'next/image';
export default function Layout({ export default function Layout({
children, children,
@ -81,7 +82,7 @@ export default function Layout({
<header className="h-16 bg-white border-b border-gray-200 px-8 py-4 flex items-center justify-between z-9"> <header className="h-16 bg-white border-b border-gray-200 px-8 py-4 flex items-center justify-between z-9">
<div className="text-xl font-semibold">{headerTitle}</div> <div className="text-xl font-semibold">{headerTitle}</div>
<DropdownMenu <DropdownMenu
buttonContent={<img src="https://i.pravatar.cc/32" alt="Profile" className="w-8 h-8 rounded-full cursor-pointer" />} buttonContent={<Image src="https://i.pravatar.cc/32" alt="Profile" className="w-8 h-8 rounded-full cursor-pointer" width={150} height={150} />}
items={dropdownItems} items={dropdownItems}
buttonClassName="" buttonClassName=""
menuClassName="absolute right-0 mt-2 w-48 bg-white border border-gray-200 rounded shadow-lg" menuClassName="absolute right-0 mt-2 w-48 bg-white border border-gray-200 rounded shadow-lg"

View File

@ -154,8 +154,8 @@ export default function DashboardPage() {
<div className="flex flex-wrap"> <div className="flex flex-wrap">
{classes.map((classe) => ( {classes.map((classe) => (
<div className="lg:col-span-2 bg-white p-6 rounded-lg shadow-sm border border-gray-100 mr-4"> <div key={classe.id} className="lg:col-span-2 bg-white p-6 rounded-lg shadow-sm border border-gray-100 mr-4">
<ClasseDetails key={classe.id} classe={classe} /> <ClasseDetails classe={classe} />
</div> </div>
))} ))}
</div> </div>

View File

@ -239,7 +239,7 @@ const registerFormArchivedDataHandler = (data) => {
fetchDataAndSetState(); fetchDataAndSetState();
}, [reloadFetch, currentPage]); }, [reloadFetch, itemsPerPage, currentPage,activeTab, searchTerm]);
useEffect(() => { useEffect(() => {
const fetchDataAndSetState = () => { const fetchDataAndSetState = () => {
@ -271,7 +271,7 @@ const timeoutId = setTimeout(() => {
fetchDataAndSetState(); fetchDataAndSetState();
}, 500); // Debounce la recherche }, 500); // Debounce la recherche
return () => clearTimeout(timeoutId); return () => clearTimeout(timeoutId);
}, [searchTerm]); }, [currentPage,itemsPerPage,searchTerm]);
/** /**
* UseEffect to update page count of tab * UseEffect to update page count of tab
@ -284,7 +284,7 @@ useEffect(()=>{
} else if (activeTab === 'archived') { } else if (activeTab === 'archived') {
setTotalPages(Math.ceil(totalArchives / itemsPerPage)); setTotalPages(Math.ceil(totalArchives / itemsPerPage));
} }
},[currentPage]); },[currentPage,activeTab,itemsPerPage,totalPending,totalSubscribed,totalArchives]);
/** /**
* Archives a registration form after user confirmation. * Archives a registration form after user confirmation.
* *

View File

@ -35,7 +35,7 @@ export default function Layout({
.finally(() => { .finally(() => {
setIsLoading(false); setIsLoading(false);
}); });
}, [userId]); }, [setUserId, userId]);
if (isLoading) { if (isLoading) {
return <div>Loading...</div>; return <div>Loading...</div>;

View File

@ -1,6 +1,7 @@
'use client' 'use client'
import React, { useState, useRef, useEffect } from 'react'; import React, { useState, useRef, useEffect } from 'react';
import { SendHorizontal } from 'lucide-react'; import { SendHorizontal } from 'lucide-react';
import Image from 'next/image';
const contacts = [ const contacts = [
{ id: 1, name: 'Facturation', profilePic: 'https://i.pravatar.cc/32' }, { id: 1, name: 'Facturation', profilePic: 'https://i.pravatar.cc/32' },
@ -61,7 +62,7 @@ export default function MessageriePage() {
className={`p-2 cursor-pointer ${selectedContact?.id === contact.id ? 'bg-gray-200' : ''}`} className={`p-2 cursor-pointer ${selectedContact?.id === contact.id ? 'bg-gray-200' : ''}`}
onClick={() => setSelectedContact(contact)} onClick={() => setSelectedContact(contact)}
> >
<img src={contact.profilePic} alt={`${contact.name}'s profile`} className="w-8 h-8 rounded-full inline-block mr-2" /> <Image src={contact.profilePic} alt={`${contact.name}'s profile`} className="w-8 h-8 rounded-full inline-block mr-2" width={150} height={150} />
{contact.name} {contact.name}
</div> </div>
))} ))}
@ -75,7 +76,7 @@ export default function MessageriePage() {
style={{ borderRadius: message.isResponse ? '20px 20px 0 20px' : '20px 20px 20px 0', minWidth: '25%' }} style={{ borderRadius: message.isResponse ? '20px 20px 0 20px' : '20px 20px 20px 0', minWidth: '25%' }}
> >
<div className="flex items-center mb-1"> <div className="flex items-center mb-1">
<img src={selectedContact.profilePic} alt={`${selectedContact.name}'s profile`} className="w-8 h-8 rounded-full inline-block mr-2" /> <Image src={selectedContact.profilePic} alt={`${selectedContact.name}'s profile`} className="w-8 h-8 rounded-full inline-block mr-2" width={150} height={150}/>
<span className="text-xs text-gray-600">{selectedContact.name}</span> <span className="text-xs text-gray-600">{selectedContact.name}</span>
<span className="text-xs text-gray-400 ml-2">{new Date(message.date).toLocaleTimeString()}</span> <span className="text-xs text-gray-400 ml-2">{new Date(message.date).toLocaleTimeString()}</span>
</div> </div>

View File

@ -52,7 +52,7 @@ export default function Page() {
console.error('Error fetching data:', error); console.error('Error fetching data:', error);
}); });
} }
}, []); }, [uuid]);
function validate(formData) { function validate(formData) {
if (useFakeData) { if (useFakeData) {

View File

@ -0,0 +1,17 @@
'use client';
import Link from 'next/link';
import Logo from '@/components/Logo';
export default function Error() {
return (
<div className='flex items-center justify-center min-h-screen bg-emerald-500'>
<div className='text-center p-6'>
<Logo className="w-32 h-32 mx-auto mb-4" />
<h2 className='text-2xl font-bold text-emerald-900 mb-4'>Une erreur est survenue</h2>
<p className='text-emerald-900 mb-4'>Désolé, une erreur s&apos;est produite.</p>
<Link className="text-gray-900 hover:underline" href="/">Retour Accueil</Link>
</div>
</div>
);
}

View File

@ -1,15 +1,17 @@
import Link from 'next/link' 'use client';
import Logo from '../components/Logo'
import Link from 'next/link';
import Logo from '@/components/Logo';
export default function NotFound() { export default function NotFound() {
return ( return (
<div className='flex items-center justify-center min-h-screen bg-emerald-500'> <div className='flex items-center justify-center min-h-screen bg-emerald-500'>
<div className='text-center p-6 '> <div className='text-center p-6'>
<Logo className="w-32 h-32 mx-auto mb-4" /> <Logo className="w-32 h-32 mx-auto mb-4" />
<h2 className='text-2xl font-bold text-emerald-900 mb-4'>404 | Page non trouvée</h2> <h2 className='text-2xl font-bold text-emerald-900 mb-4'>404 | Page non trouvée</h2>
<p className='text-emerald-900 mb-4'>La ressource que vous souhaitez consulter n'existe pas ou plus.</p> <p className='text-emerald-900 mb-4'>La ressource que vous souhaitez consulter n&apos;existe pas ou plus.</p>
<Link className="text-gray-900 hover:underline" href="/">Retour Accueil</Link> <Link className="text-gray-900 hover:underline" href="/">Retour Accueil</Link>
</div> </div>
</div> </div>
) );
} }

View File

@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { NextIntlClientProvider } from 'next-intl'; import { NextIntlClientProvider } from 'next-intl';
import {getMessages} from 'next-intl/server'; import {getMessages} from 'next-intl/server';
import "@/css/tailwind.css"; import "@/css/tailwind.css";
@ -22,12 +21,13 @@ export const metadata = {
}; };
export default async function RootLayout({ children, params: { locale } }) { export default async function RootLayout({ children, params: { locale } }) {
const messages = await getMessages();
const messages = await getMessages(locale);
return ( return (
<html lang={locale}> <html lang={locale}>
<body> <body>
<NextIntlClientProvider messages={messages}> <NextIntlClientProvider messages={messages} locale={locale}>
{children} {children}
</NextIntlClientProvider> </NextIntlClientProvider>
</body> </body>

View File

@ -75,7 +75,7 @@ const Calendar = ({ onDateClick, onEventClick }) => {
onClick={() => setCurrentDate(new Date())} onClick={() => setCurrentDate(new Date())}
className="px-3 py-1.5 text-sm font-medium text-gray-700 hover:text-gray-900 bg-gray-100 hover:bg-gray-200 rounded-md transition-colors" className="px-3 py-1.5 text-sm font-medium text-gray-700 hover:text-gray-900 bg-gray-100 hover:bg-gray-200 rounded-md transition-colors"
> >
Aujourd'hui Aujourd&apos;hui
</button> </button>
<button onClick={() => navigateDate('prev')} className="p-2 hover:bg-gray-100 rounded-full"> <button onClick={() => navigateDate('prev')} className="p-2 hover:bg-gray-100 rounded-full">
<ChevronLeft className="w-5 h-5" /> <ChevronLeft className="w-5 h-5" />

View File

@ -11,18 +11,20 @@ const DropdownMenu = ({ buttonContent, items, buttonClassName, menuClassName, dr
const actualSetDropdownOpen = isControlled ? propSetDropdownOpen : setDropdownOpen; const actualSetDropdownOpen = isControlled ? propSetDropdownOpen : setDropdownOpen;
useEffect(() => {
const handleClickOutside = (event) => { const handleClickOutside = (event) => {
if (menuRef.current && !menuRef.current.contains(event.target)) { if (menuRef.current && !menuRef.current.contains(event.target)) {
actualSetDropdownOpen(false); actualSetDropdownOpen(false);
} }
}; };
useEffect(() => {
document.addEventListener('mousedown', handleClickOutside); document.addEventListener('mousedown', handleClickOutside);
return () => { return () => {
document.removeEventListener('mousedown', handleClickOutside); document.removeEventListener('mousedown', handleClickOutside);
}; };
}, []); }, [actualSetDropdownOpen]);
return ( return (
<div className="relative" ref={menuRef}> <div className="relative" ref={menuRef}>
<button className={buttonClassName} onClick={() => actualSetDropdownOpen(!actualDropdownOpen)}> <button className={buttonClassName} onClick={() => actualSetDropdownOpen(!actualDropdownOpen)}>
@ -33,7 +35,7 @@ const DropdownMenu = ({ buttonContent, items, buttonClassName, menuClassName, dr
{items.map((item, index) => ( {items.map((item, index) => (
<button <button
key={index} key={index}
className="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 flex items-center gap-2" className="w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 flex items-center gap-2"
onClick={() => { onClick={() => {
item.onClick(); item.onClick();
actualSetDropdownOpen(false); actualSetDropdownOpen(false);

View File

@ -14,7 +14,7 @@ export default function EventModal({ isOpen, onClose, eventData, setEventData })
color: schedules[0].color color: schedules[0].color
})); }));
} }
}, [schedules, eventData.scheduleId]); }, [schedules, eventData.scheduleId,setEventData]);
if (!isOpen) return null; if (!isOpen) return null;

View File

@ -23,7 +23,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
selectedTuitionDiscounts: [], selectedTuitionDiscounts: [],
selectedTuitionFees: [], selectedTuitionFees: [],
selectedFileGroup: null // Ajout du groupe de fichiers sélectionné selectedFileGroup: null // Ajout du groupe de fichiers sélectionné
}); }, [registrationFees, registrationDiscounts]);
const [step, setStep] = useState(currentStep || 1); const [step, setStep] = useState(currentStep || 1);
const [selectedStudent, setSelectedEleve] = useState(''); const [selectedStudent, setSelectedEleve] = useState('');
@ -79,7 +79,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
); );
setTotalRegistrationAmount(initialTotalRegistrationAmount); setTotalRegistrationAmount(initialTotalRegistrationAmount);
}, [registrationDiscounts, registrationFees]); }, [registrationDiscounts, registrationFees,calculateFinalRegistrationAmount]);
useEffect(() => { useEffect(() => {
setStep(currentStep || 1); setStep(currentStep || 1);
@ -176,7 +176,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
}); });
}; };
const calculateFinalRegistrationAmount = (selectedRegistrationFees, selectedRegistrationDiscounts) => { const calculateFinalRegistrationAmount = useCallback((selectedRegistrationFees, selectedRegistrationDiscounts) => {
const totalFees = selectedRegistrationFees.reduce((sum, feeId) => { const totalFees = selectedRegistrationFees.reduce((sum, feeId) => {
const fee = registrationFees.find(f => f.id === feeId); const fee = registrationFees.find(f => f.id === feeId);
if (fee && !isNaN(parseFloat(fee.base_amount))) { if (fee && !isNaN(parseFloat(fee.base_amount))) {
@ -200,7 +200,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
const finalAmount = totalFees - totalDiscounts; const finalAmount = totalFees - totalDiscounts;
return finalAmount.toFixed(2); return finalAmount.toFixed(2);
}; },[registrationDiscounts, registrationFees]);
const calculateFinalTuitionAmount = (selectedTuitionFees, selectedTuitionDiscounts) => { const calculateFinalTuitionAmount = (selectedTuitionFees, selectedTuitionDiscounts) => {
const totalFees = selectedTuitionFees.reduce((sum, feeId) => { const totalFees = selectedTuitionFees.reduce((sum, feeId) => {
@ -385,7 +385,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
) : ( ) : (
<p className="bg-orange-100 border border-orange-400 text-orange-700 px-4 py-3 rounded relative" role="alert"> <p className="bg-orange-100 border border-orange-400 text-orange-700 px-4 py-3 rounded relative" role="alert">
<strong className="font-bold">Information</strong> <strong className="font-bold">Information</strong>
<span className="block sm:inline"> Aucune réduction n'a été créée sur les frais d'inscription.</span> <span className="block sm:inline"> Aucune réduction n&apos;a été créée sur les frais d&apos;inscription.</span>
</p> </p>
)} )}
</div> </div>
@ -408,7 +408,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
) : ( ) : (
<p className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert"> <p className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
<strong className="font-bold">Attention!</strong> <strong className="font-bold">Attention!</strong>
<span className="block sm:inline"> Aucun frais d'inscription n'a été créé.</span> <span className="block sm:inline"> Aucun frais d&apos;inscription n&apos;a été créé.</span>
</p> </p>
)} )}
</div> </div>
@ -440,7 +440,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
) : ( ) : (
<p className="bg-orange-100 border border-orange-400 text-orange-700 px-4 py-3 rounded relative" role="alert"> <p className="bg-orange-100 border border-orange-400 text-orange-700 px-4 py-3 rounded relative" role="alert">
<strong className="font-bold">Information</strong> <strong className="font-bold">Information</strong>
<span className="block sm:inline"> Aucune réduction n'a été créée sur les frais de scolarité.</span> <span className="block sm:inline"> Aucune réduction n&apos;a été créée sur les frais de scolarité.</span>
</p> </p>
)} )}
</div> </div>
@ -463,7 +463,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
) : ( ) : (
<p className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert"> <p className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
<strong className="font-bold">Attention!</strong> <strong className="font-bold">Attention!</strong>
<span className="block sm:inline"> Aucun frais de scolarité n'a été créé.</span> <span className="block sm:inline"> Aucun frais de scolarité n&apos;a été créé.</span>
</p> </p>
)} )}
</div> </div>
@ -501,7 +501,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
) : ( ) : (
<p className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert"> <p className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
<strong className="font-bold">Attention!</strong> <strong className="font-bold">Attention!</strong>
<span className="block sm:inline"> Aucun groupe de documents n'a été créé.</span> <span className="block sm:inline"> Aucun groupe de documents n&apos;a été créé.</span>
</p> </p>
)} )}
</div> </div>

View File

@ -249,7 +249,7 @@ export default function InscriptionFormShared({
<DjangoCSRFToken csrfToken={csrfToken}/> <DjangoCSRFToken csrfToken={csrfToken}/>
{/* Section Élève */} {/* Section Élève */}
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200"> <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">Informations de l'élève</h2> <h2 className="text-xl font-bold mb-4 text-gray-800">Informations de l&apos;élève</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<InputText <InputText
name="last_name" name="last_name"

View File

@ -49,9 +49,6 @@ const PaymentPlanSelector = ({ paymentPlans, setPaymentPlans, handleEdit, type }
}, [paymentPlans]); }, [paymentPlans]);
useEffect(() => { useEffect(() => {
updateDefaultDay();
}, [dates, selectedFrequency]);
const updateDefaultDay = () => { const updateDefaultDay = () => {
const currentDates = dates[selectedFrequency]; const currentDates = dates[selectedFrequency];
if (currentDates && currentDates.length > 0) { if (currentDates && currentDates.length > 0) {
@ -68,6 +65,9 @@ const PaymentPlanSelector = ({ paymentPlans, setPaymentPlans, handleEdit, type }
} }
}; };
updateDefaultDay();
}, [dates, selectedFrequency]);
const handleActivationChange = (value) => { const handleActivationChange = (value) => {
const selectedPlan = paymentPlans.find(plan => plan.frequency === paymentPlansOptions.find(p => p.id === value)?.frequency); const selectedPlan = paymentPlans.find(plan => plan.frequency === paymentPlansOptions.find(p => p.id === value)?.frequency);
if (!selectedPlan) return; if (!selectedPlan) return;

View File

@ -10,7 +10,7 @@ export default function RegistrationFileGroupList() {
return ( return (
<div> <div>
<h2>Groupes de fichiers d'inscription</h2> <h2>Groupes de fichiers d&apos;inscription</h2>
<ul> <ul>
{groups.map(group => ( {groups.map(group => (
<li key={group.id}>{group.name}</li> <li key={group.id}>{group.name}</li>

View File

@ -7,7 +7,8 @@ import SelectChoice from '@/components/SelectChoice';
import TeacherItem from '@/components/Structure/Configuration/TeacherItem'; import TeacherItem from '@/components/Structure/Configuration/TeacherItem';
import MultiSelect from '@/components/MultiSelect'; import MultiSelect from '@/components/MultiSelect';
import LevelLabel from '@/components/CustomLabels/LevelLabel'; import LevelLabel from '@/components/CustomLabels/LevelLabel';
import { DndProvider, HTML5Backend, useDrop } from 'react-dnd'; import { DndProvider, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { ESTABLISHMENT_ID } from '@/utils/Url'; import { ESTABLISHMENT_ID } from '@/utils/Url';
const ItemTypes = { const ItemTypes = {
@ -17,16 +18,13 @@ const ItemTypes = {
const TeachersDropZone = ({ classe, handleTeachersChange, teachers, isEditing }) => { const TeachersDropZone = ({ classe, handleTeachersChange, teachers, isEditing }) => {
const [localTeachers, setLocalTeachers] = useState(classe.teachers_details || []); const [localTeachers, setLocalTeachers] = useState(classe.teachers_details || []);
useEffect(() => {
}, [teachers]);
useEffect(() => { useEffect(() => {
setLocalTeachers(classe.teachers_details || []); setLocalTeachers(classe.teachers_details || []);
}, [classe.teachers_details]); }, [classe.teachers_details]);
useEffect(() => { useEffect(() => {
handleTeachersChange(localTeachers.map(teacher => teacher.id)); handleTeachersChange(localTeachers.map(teacher => teacher.id));
}, [localTeachers]); }, [handleTeachersChange, localTeachers]);
const [{ isOver, canDrop }, drop] = useDrop({ const [{ isOver, canDrop }, drop] = useDrop({
accept: ItemTypes.TEACHER, accept: ItemTypes.TEACHER,

View File

@ -27,7 +27,7 @@ const SpecialitiesDropZone = ({ teacher, handleSpecialitiesChange, specialities,
useEffect(() => { useEffect(() => {
handleSpecialitiesChange(localSpecialities.map(speciality => speciality.id)); handleSpecialitiesChange(localSpecialities.map(speciality => speciality.id));
}, [localSpecialities]); }, [localSpecialities,handleSpecialitiesChange]);
const [{ isOver, canDrop }, drop] = useDrop({ const [{ isOver, canDrop }, drop] = useDrop({
accept: ItemTypes.SPECIALITY, accept: ItemTypes.SPECIALITY,

View File

@ -21,7 +21,7 @@ const PlanningClassView = ({ schedule, onDrop, selectedLevel, handleUpdatePlanni
if (schedule?.emploiDuTemps) { if (schedule?.emploiDuTemps) {
setCurrentPeriod(determineInitialPeriod(schedule.emploiDuTemps)); setCurrentPeriod(determineInitialPeriod(schedule.emploiDuTemps));
} }
}, [schedule]); }, [schedule, determineInitialPeriod]);
if (!schedule || !schedule.emploiDuTemps) { if (!schedule || !schedule.emploiDuTemps) {
return ( return (

View File

@ -22,7 +22,7 @@ const ScheduleManagement = ({ handleUpdatePlanning, classes }) => {
const [schedule, setSchedule] = useState(null); const [schedule, setSchedule] = useState(null);
const { getNiveauxTabs } = useClasses(); const { getNiveauxTabs } = useClasses();
const niveauxLabels = Array.isArray(selectedClass?.levels) ? getNiveauxTabs(selectedClass.levels) : []; const niveauxLabels = useMemo(() => Array.isArray(selectedClass?.levels) ? getNiveauxTabs(selectedClass.levels) : [], [selectedClass, getNiveauxTabs]);
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const handleOpenModal = () => setIsModalOpen(true); const handleOpenModal = () => setIsModalOpen(true);
@ -38,7 +38,7 @@ const ScheduleManagement = ({ handleUpdatePlanning, classes }) => {
const currentPlanning = selectedClass.plannings_read?.find(planning => planning.niveau === niveau); const currentPlanning = selectedClass.plannings_read?.find(planning => planning.niveau === niveau);
setSchedule(currentPlanning ? currentPlanning.planning : {}); setSchedule(currentPlanning ? currentPlanning.planning : {});
} }
}, [selectedClass, niveauxLabels]); }, [selectedClass, niveauxLabels, selectedLevel]);
useEffect(() => { useEffect(() => {
if (selectedClass && selectedLevel) { if (selectedClass && selectedLevel) {

View File

@ -47,7 +47,7 @@ const FeesManagement = ({ registrationDiscounts,
return ( return (
<div className="w-full mx-auto p-2 mt-6 space-y-6"> <div className="w-full mx-auto p-2 mt-6 space-y-6">
<div className="bg-white p-2 rounded-lg shadow-md"> <div className="bg-white p-2 rounded-lg shadow-md">
<h2 className="text-2xl font-semibold mb-4">Frais d'inscription</h2> <h2 className="text-2xl font-semibold mb-4">Frais d&apos;inscription</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="col-span-1 p-6 rounded-lg shadow-inner mt-4"> <div className="col-span-1 p-6 rounded-lg shadow-inner mt-4">
<FeesSection <FeesSection

View File

@ -21,7 +21,7 @@ const useCsrfToken = () => {
.catch(error => { .catch(error => {
console.error('Error fetching CSRF token:', error); console.error('Error fetching CSRF token:', error);
}); });
}, []); }, [token]);
return token; return token;
}; };