mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 16:03:21 +00:00
chore: application prettier
This commit is contained in:
@ -1,6 +1,10 @@
|
||||
'use client'
|
||||
'use client';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { fetchProfileRoles, updateProfileRoles, deleteProfileRoles } from '@/app/actions/authAction';
|
||||
import {
|
||||
fetchProfileRoles,
|
||||
updateProfileRoles,
|
||||
deleteProfileRoles,
|
||||
} from '@/app/actions/authAction';
|
||||
import { dissociateGuardian } from '@/app/actions/subscriptionAction';
|
||||
import logger from '@/utils/logger';
|
||||
import { useEstablishment } from '@/context/EstablishmentContext';
|
||||
@ -24,21 +28,23 @@ export default function Page() {
|
||||
|
||||
const handleProfiles = () => {
|
||||
fetchProfileRoles(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setProfileRoles(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching profileRoles:', error));
|
||||
setReloadFetch(false);
|
||||
.catch((error) => logger.error('Error fetching profileRoles:', error));
|
||||
setReloadFetch(false);
|
||||
};
|
||||
|
||||
const handleEdit = (profileRole) => {
|
||||
const updatedData = { ...profileRole, is_active: !profileRole.is_active };
|
||||
return updateProfileRoles(profileRole.id, updatedData, csrfToken)
|
||||
.then(data => {
|
||||
setProfileRoles(prevState => prevState.map(item => item.id === profileRole.id ? data : item));
|
||||
.then((data) => {
|
||||
setProfileRoles((prevState) =>
|
||||
prevState.map((item) => (item.id === profileRole.id ? data : item))
|
||||
);
|
||||
return data;
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
logger.error('Error editing data:', error);
|
||||
throw error;
|
||||
});
|
||||
@ -47,10 +53,12 @@ export default function Page() {
|
||||
const handleDelete = (id) => {
|
||||
return deleteProfileRoles(id, csrfToken)
|
||||
.then(() => {
|
||||
setProfileRoles(prevState => prevState.filter(item => item.id !== id));
|
||||
logger.debug("Profile deleted successfully:", id);
|
||||
setProfileRoles((prevState) =>
|
||||
prevState.filter((item) => item.id !== id)
|
||||
);
|
||||
logger.debug('Profile deleted successfully:', id);
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
logger.error('Error deleting profile:', error);
|
||||
throw error;
|
||||
});
|
||||
@ -59,49 +67,58 @@ export default function Page() {
|
||||
const handleDissociate = (studentId, guardianId) => {
|
||||
return dissociateGuardian(studentId, guardianId)
|
||||
.then((response) => {
|
||||
logger.debug("Guardian dissociated successfully:", guardianId);
|
||||
|
||||
logger.debug('Guardian dissociated successfully:', guardianId);
|
||||
|
||||
// Vérifier si le Guardian a été supprimé
|
||||
const isGuardianDeleted = response?.isGuardianDeleted;
|
||||
|
||||
|
||||
// Mettre à jour le modèle profileRoles
|
||||
setProfileRoles(prevState =>
|
||||
prevState.map(profileRole => {
|
||||
if (profileRole.associated_person?.id === guardianId) {
|
||||
if (isGuardianDeleted) {
|
||||
// Si le Guardian est supprimé, retirer le profileRole
|
||||
return null;
|
||||
} else {
|
||||
// Si le Guardian n'est pas supprimé, mettre à jour les élèves associés
|
||||
const updatedStudents = profileRole.associated_person.students.filter(
|
||||
student => student.id !== studentId
|
||||
);
|
||||
return {
|
||||
...profileRole,
|
||||
associated_person: {
|
||||
...profileRole.associated_person,
|
||||
students: updatedStudents, // Mettre à jour les élèves associés
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
setReloadFetch(true);
|
||||
return profileRole; // Conserver les autres profileRoles
|
||||
}).filter(Boolean) // Supprimer les entrées nulles
|
||||
setProfileRoles(
|
||||
(prevState) =>
|
||||
prevState
|
||||
.map((profileRole) => {
|
||||
if (profileRole.associated_person?.id === guardianId) {
|
||||
if (isGuardianDeleted) {
|
||||
// Si le Guardian est supprimé, retirer le profileRole
|
||||
return null;
|
||||
} else {
|
||||
// Si le Guardian n'est pas supprimé, mettre à jour les élèves associés
|
||||
const updatedStudents =
|
||||
profileRole.associated_person.students.filter(
|
||||
(student) => student.id !== studentId
|
||||
);
|
||||
return {
|
||||
...profileRole,
|
||||
associated_person: {
|
||||
...profileRole.associated_person,
|
||||
students: updatedStudents, // Mettre à jour les élèves associés
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
setReloadFetch(true);
|
||||
return profileRole; // Conserver les autres profileRoles
|
||||
})
|
||||
.filter(Boolean) // Supprimer les entrées nulles
|
||||
);
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
logger.error('Error dissociating guardian:', error);
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='p-8'>
|
||||
<div className="p-8">
|
||||
<DjangoCSRFToken csrfToken={csrfToken} />
|
||||
|
||||
<div className="w-full p-4">
|
||||
<ProfileDirectory profileRoles={profileRoles} handleActivateProfile={handleEdit} handleDeleteProfile={handleDelete} handleDissociateGuardian={handleDissociate} />
|
||||
<ProfileDirectory
|
||||
profileRoles={profileRoles}
|
||||
handleActivateProfile={handleEdit}
|
||||
handleDeleteProfile={handleDelete}
|
||||
handleDissociateGuardian={handleDissociate}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
'use client'
|
||||
'use client';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className='p-8'>
|
||||
<h1 className='heading-section'>Statistiques</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="p-8">
|
||||
<h1 className="heading-section">Statistiques</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
'use client'
|
||||
'use client';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import Sidebar from '@/components/Sidebar';
|
||||
import { usePathname } from 'next/navigation';
|
||||
@ -14,7 +14,7 @@ import {
|
||||
Settings,
|
||||
LogOut,
|
||||
Menu,
|
||||
X
|
||||
X,
|
||||
} from 'lucide-react';
|
||||
import DropdownMenu from '@/components/DropdownMenu';
|
||||
|
||||
@ -26,7 +26,7 @@ import {
|
||||
FE_ADMIN_DIRECTORY_URL,
|
||||
FE_ADMIN_GRADES_URL,
|
||||
FE_ADMIN_PLANNING_URL,
|
||||
FE_ADMIN_SETTINGS_URL
|
||||
FE_ADMIN_SETTINGS_URL,
|
||||
} from '@/utils/Url';
|
||||
|
||||
import { disconnect } from '@/app/actions/authAction';
|
||||
@ -38,25 +38,63 @@ import { getRightStr, RIGHTS } from '@/utils/rights';
|
||||
import logger from '@/utils/logger';
|
||||
import { useEstablishment } from '@/context/EstablishmentContext';
|
||||
|
||||
export default function Layout({
|
||||
children,
|
||||
}) {
|
||||
export default function Layout({ children }) {
|
||||
const t = useTranslations('sidebar');
|
||||
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
|
||||
const { data: session } = useSession();
|
||||
const { selectedEstablishmentId, setSelectedEstablishmentId, profileRole, setProfileRole, establishments, user } = useEstablishment();
|
||||
|
||||
|
||||
const {
|
||||
selectedEstablishmentId,
|
||||
setSelectedEstablishmentId,
|
||||
profileRole,
|
||||
setProfileRole,
|
||||
establishments,
|
||||
user,
|
||||
} = useEstablishment();
|
||||
|
||||
// Déplacer le reste du code ici...
|
||||
const sidebarItems = {
|
||||
"admin": { "id": "admin", "name": t('dashboard'), "url": FE_ADMIN_HOME_URL, "icon": LayoutDashboard },
|
||||
"subscriptions": { "id": "subscriptions", "name": t('subscriptions'), "url": FE_ADMIN_SUBSCRIPTIONS_URL, "icon": FileText },
|
||||
"structure": { "id": "structure", "name": t('structure'), "url": FE_ADMIN_STRUCTURE_URL, "icon": School },
|
||||
"directory": { "id": "directory", "name": t('directory'), "url": FE_ADMIN_DIRECTORY_URL, "icon": Users },
|
||||
"grades": { "id": "grades", "name": t('grades'), "url": FE_ADMIN_GRADES_URL, "icon": Award },
|
||||
"planning": { "id": "planning", "name": t('events'), "url": FE_ADMIN_PLANNING_URL, "icon": Calendar },
|
||||
"settings": { "id": "settings", "name": t('settings'), "url": FE_ADMIN_SETTINGS_URL, "icon": Settings }
|
||||
admin: {
|
||||
id: 'admin',
|
||||
name: t('dashboard'),
|
||||
url: FE_ADMIN_HOME_URL,
|
||||
icon: LayoutDashboard,
|
||||
},
|
||||
subscriptions: {
|
||||
id: 'subscriptions',
|
||||
name: t('subscriptions'),
|
||||
url: FE_ADMIN_SUBSCRIPTIONS_URL,
|
||||
icon: FileText,
|
||||
},
|
||||
structure: {
|
||||
id: 'structure',
|
||||
name: t('structure'),
|
||||
url: FE_ADMIN_STRUCTURE_URL,
|
||||
icon: School,
|
||||
},
|
||||
directory: {
|
||||
id: 'directory',
|
||||
name: t('directory'),
|
||||
url: FE_ADMIN_DIRECTORY_URL,
|
||||
icon: Users,
|
||||
},
|
||||
grades: {
|
||||
id: 'grades',
|
||||
name: t('grades'),
|
||||
url: FE_ADMIN_GRADES_URL,
|
||||
icon: Award,
|
||||
},
|
||||
planning: {
|
||||
id: 'planning',
|
||||
name: t('events'),
|
||||
url: FE_ADMIN_PLANNING_URL,
|
||||
icon: Calendar,
|
||||
},
|
||||
settings: {
|
||||
id: 'settings',
|
||||
name: t('settings'),
|
||||
url: FE_ADMIN_SETTINGS_URL,
|
||||
icon: Settings,
|
||||
},
|
||||
};
|
||||
|
||||
const [isPopupVisible, setIsPopupVisible] = useState(false);
|
||||
@ -66,7 +104,7 @@ export default function Layout({
|
||||
|
||||
const headerTitle = sidebarItems[currentPage]?.name || t('dashboard');
|
||||
|
||||
const softwareName = "N3WT School";
|
||||
const softwareName = 'N3WT School';
|
||||
const softwareVersion = `${process.env.NEXT_PUBLIC_APP_VERSION}`;
|
||||
|
||||
const handleDisconnect = () => {
|
||||
@ -84,13 +122,15 @@ export default function Layout({
|
||||
content: (
|
||||
<div className="px-4 py-2">
|
||||
<div className="font-medium">{user?.email || 'Utilisateur'}</div>
|
||||
<div className="text-xs text-gray-400">{getRightStr(profileRole) || ''}</div>
|
||||
<div className="text-xs text-gray-400">
|
||||
{getRightStr(profileRole) || ''}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
),
|
||||
},
|
||||
{
|
||||
type: 'separator',
|
||||
content: <hr className="my-2 border-gray-200" />
|
||||
content: <hr className="my-2 border-gray-200" />,
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
@ -126,7 +166,9 @@ export default function Layout({
|
||||
onEstablishmentChange={(establishmentId) => {
|
||||
const parsedEstablishmentId = parseInt(establishmentId, 10);
|
||||
setSelectedEstablishmentId(parsedEstablishmentId);
|
||||
let roleIndex = session.user.roles.findIndex(role => role.establishment__id === parsedEstablishmentId)
|
||||
let roleIndex = session.user.roles.findIndex(
|
||||
(role) => role.establishment__id === parsedEstablishmentId
|
||||
);
|
||||
if (roleIndex === -1) {
|
||||
roleIndex = 0;
|
||||
}
|
||||
@ -155,7 +197,9 @@ export default function Layout({
|
||||
>
|
||||
{isSidebarOpen ? <X size={24} /> : <Menu size={24} />}
|
||||
</button>
|
||||
<div className="text-lg md:text-xl font-semibold">{headerTitle}</div>
|
||||
<div className="text-lg md:text-xl font-semibold">
|
||||
{headerTitle}
|
||||
</div>
|
||||
</div>
|
||||
<DropdownMenu
|
||||
buttonContent={
|
||||
@ -175,11 +219,12 @@ export default function Layout({
|
||||
{/* Main Content */}
|
||||
<div className="flex-1 flex flex-col">
|
||||
{/* Content avec scroll si nécessaire */}
|
||||
<div className="flex-1 overflow-auto p-4 md:p-6">
|
||||
{children}
|
||||
</div>
|
||||
<div className="flex-1 overflow-auto p-4 md:p-6">{children}</div>
|
||||
{/* Footer responsive */}
|
||||
<Footer softwareName={softwareName} softwareVersion={softwareVersion} />
|
||||
<Footer
|
||||
softwareName={softwareName}
|
||||
softwareVersion={softwareVersion}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -192,5 +237,3 @@ export default function Layout({
|
||||
</ProtectedRoute>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
'use client';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { Users, Clock, CalendarCheck, School, TrendingUp, UserCheck } from 'lucide-react';
|
||||
import { Users, Clock, CalendarCheck, School, TrendingUp } from 'lucide-react';
|
||||
import Loader from '@/components/Loader';
|
||||
import ClasseDetails from '@/components/ClasseDetails';
|
||||
import { fetchClasses } from '@/app/actions/schoolAction';
|
||||
@ -11,7 +11,6 @@ import { fetchRegisterForms } from '@/app/actions/subscriptionAction';
|
||||
import { fetchUpcomingEvents } from '@/app/actions/planningAction';
|
||||
import { useEstablishment } from '@/context/EstablishmentContext';
|
||||
|
||||
|
||||
// Composant EventCard pour afficher les événements
|
||||
const EventCard = ({ title, date, description, type }) => (
|
||||
<div className="bg-white p-4 rounded-lg shadow-sm border border-gray-100 mb-4">
|
||||
@ -35,10 +34,9 @@ export default function DashboardPage() {
|
||||
const [upcomingEvents, setUpcomingEvents] = useState([]);
|
||||
const [monthlyStats, setMonthlyStats] = useState({
|
||||
inscriptions: [],
|
||||
completionRate: 0
|
||||
completionRate: 0,
|
||||
});
|
||||
|
||||
|
||||
const [classes, setClasses] = useState([]);
|
||||
const { selectedEstablishmentId } = useEstablishment();
|
||||
|
||||
@ -49,35 +47,41 @@ export default function DashboardPage() {
|
||||
|
||||
// Fetch des classes
|
||||
fetchClasses(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setClasses(data);
|
||||
logger.info('Classes fetched:', data);
|
||||
|
||||
const nbMaxStudents = data.reduce((acc, classe) => acc + classe.number_of_students, 0);
|
||||
const nbStudents = data.reduce((acc, classe) => acc + classe.students.length, 0);
|
||||
const nbMaxStudents = data.reduce(
|
||||
(acc, classe) => acc + classe.number_of_students,
|
||||
0
|
||||
);
|
||||
const nbStudents = data.reduce(
|
||||
(acc, classe) => acc + classe.students.length,
|
||||
0
|
||||
);
|
||||
setStructureCapacity(nbMaxStudents);
|
||||
setTotalStudents(nbStudents);
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
logger.error('Error fetching classes:', error);
|
||||
});
|
||||
|
||||
// Fetch des formulaires d'inscription
|
||||
fetchRegisterForms()
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
logger.info('Pending registrations fetched:', data);
|
||||
setPendingRegistration(data.count);
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
logger.error('Error fetching pending registrations:', error);
|
||||
});
|
||||
|
||||
// Fetch des événements à venir
|
||||
fetchUpcomingEvents()
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setUpcomingEvents(data);
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
logger.error('Error fetching upcoming events:', error);
|
||||
})
|
||||
.finally(() => {
|
||||
@ -110,9 +114,9 @@ export default function DashboardPage() {
|
||||
icon={<School className="text-green-500" size={24} />}
|
||||
color="emerald"
|
||||
/>
|
||||
<StatCard
|
||||
<StatCard
|
||||
title={t('capacityRate')}
|
||||
value={`${(totalStudents/structureCapacity * 100).toFixed(1)}%`}
|
||||
value={`${((totalStudents / structureCapacity) * 100).toFixed(1)}%`}
|
||||
icon={<School className="text-orange-500" size={24} />}
|
||||
color="orange"
|
||||
/>
|
||||
@ -122,7 +126,9 @@ export default function DashboardPage() {
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
|
||||
{/* Graphique des inscriptions */}
|
||||
<div className="lg:col-span-2 bg-white p-6 rounded-lg shadow-sm border border-gray-100">
|
||||
<h2 className="text-lg font-semibold mb-4">{t('inscriptionTrends')}</h2>
|
||||
<h2 className="text-lg font-semibold mb-4">
|
||||
{t('inscriptionTrends')}
|
||||
</h2>
|
||||
{/* Insérer ici un composant de graphique */}
|
||||
<div className="h-64 bg-gray-50 rounded flex items-center justify-center">
|
||||
<TrendingUp size={48} className="text-gray-300" />
|
||||
@ -140,11 +146,14 @@ export default function DashboardPage() {
|
||||
|
||||
<div className="flex flex-wrap">
|
||||
{classes.map((classe) => (
|
||||
<div key={classe.id} className="lg:col-span-2 bg-white p-6 rounded-lg shadow-sm border border-gray-100 mr-4">
|
||||
<ClasseDetails classe={classe} />
|
||||
<div
|
||||
key={classe.id}
|
||||
className="lg:col-span-2 bg-white p-6 rounded-lg shadow-sm border border-gray-100 mr-4"
|
||||
>
|
||||
<ClasseDetails classe={classe} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
'use client'
|
||||
'use client';
|
||||
import { PlanningProvider } from '@/context/PlanningContext';
|
||||
import Calendar from '@/components/Calendar';
|
||||
import EventModal from '@/components/EventModal';
|
||||
@ -19,7 +19,7 @@ export default function Page() {
|
||||
recurrenceEnd: '',
|
||||
customInterval: 1,
|
||||
customUnit: 'days',
|
||||
viewType: 'week' // Ajouter la vue semaine par défaut
|
||||
viewType: 'week', // Ajouter la vue semaine par défaut
|
||||
});
|
||||
|
||||
const initializeNewEvent = (date = new Date()) => {
|
||||
@ -37,7 +37,7 @@ export default function Page() {
|
||||
selectedDays: [],
|
||||
recurrenceEnd: '',
|
||||
customInterval: 1,
|
||||
customUnit: 'days'
|
||||
customUnit: 'days',
|
||||
});
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
@ -62,4 +62,4 @@ export default function Page() {
|
||||
</div>
|
||||
</PlanningProvider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
'use client'
|
||||
'use client';
|
||||
import React, { useState } from 'react';
|
||||
import Tab from '@/components/Tab';
|
||||
import TabContent from '@/components/TabContent';
|
||||
@ -85,18 +85,49 @@ export default function SettingsPage() {
|
||||
<div className="mt-4">
|
||||
<TabContent isActive={activeTab === 'structure'}>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<InputText label="Email" value={email} onChange={handleEmailChange} />
|
||||
<InputText label="Mot de passe" type="password" value={password} onChange={handlePasswordChange} />
|
||||
<InputText label="Confirmer le mot de passe" type="password" value={confirmPassword} onChange={handleConfirmPasswordChange} />
|
||||
<InputText
|
||||
label="Email"
|
||||
value={email}
|
||||
onChange={handleEmailChange}
|
||||
/>
|
||||
<InputText
|
||||
label="Mot de passe"
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={handlePasswordChange}
|
||||
/>
|
||||
<InputText
|
||||
label="Confirmer le mot de passe"
|
||||
type="password"
|
||||
value={confirmPassword}
|
||||
onChange={handleConfirmPasswordChange}
|
||||
/>
|
||||
<Button type="submit" primary text="Mettre à jour"></Button>
|
||||
</form>
|
||||
</TabContent>
|
||||
<TabContent isActive={activeTab === 'smtp'}>
|
||||
<form onSubmit={handleSmtpSubmit}>
|
||||
<InputText label="Serveur SMTP" value={smtpServer} onChange={handleSmtpServerChange} />
|
||||
<InputText label="Port SMTP" value={smtpPort} onChange={handleSmtpPortChange} />
|
||||
<InputText label="Utilisateur SMTP" value={smtpUser} onChange={handleSmtpUserChange} />
|
||||
<InputText label="Mot de passe SMTP" type="password" value={smtpPassword} onChange={handleSmtpPasswordChange} />
|
||||
<InputText
|
||||
label="Serveur SMTP"
|
||||
value={smtpServer}
|
||||
onChange={handleSmtpServerChange}
|
||||
/>
|
||||
<InputText
|
||||
label="Port SMTP"
|
||||
value={smtpPort}
|
||||
onChange={handleSmtpPortChange}
|
||||
/>
|
||||
<InputText
|
||||
label="Utilisateur SMTP"
|
||||
value={smtpUser}
|
||||
onChange={handleSmtpUserChange}
|
||||
/>
|
||||
<InputText
|
||||
label="Mot de passe SMTP"
|
||||
type="password"
|
||||
value={smtpPassword}
|
||||
onChange={handleSmtpPasswordChange}
|
||||
/>
|
||||
<Button type="submit" primary text="Mettre à jour"></Button>
|
||||
</form>
|
||||
</TabContent>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
'use client'
|
||||
'use client';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import StructureManagement from '@/components/Structure/Configuration/StructureManagement';
|
||||
import ScheduleManagement from '@/components/Structure/Planning/ScheduleManagement';
|
||||
@ -6,26 +6,27 @@ import FeesManagement from '@/components/Structure/Tarification/FeesManagement';
|
||||
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
|
||||
import { useCsrfToken } from '@/context/CsrfContext';
|
||||
import { ClassesProvider } from '@/context/ClassesContext';
|
||||
import {
|
||||
createDatas,
|
||||
updateDatas,
|
||||
removeDatas,
|
||||
fetchSpecialities,
|
||||
fetchTeachers,
|
||||
fetchClasses,
|
||||
fetchSchedules,
|
||||
fetchRegistrationDiscounts,
|
||||
fetchTuitionDiscounts,
|
||||
fetchRegistrationFees,
|
||||
fetchTuitionFees,
|
||||
fetchRegistrationPaymentPlans,
|
||||
fetchTuitionPaymentPlans,
|
||||
fetchRegistrationPaymentModes,
|
||||
fetchTuitionPaymentModes } from '@/app/actions/schoolAction';
|
||||
import {
|
||||
createDatas,
|
||||
updateDatas,
|
||||
removeDatas,
|
||||
fetchSpecialities,
|
||||
fetchTeachers,
|
||||
fetchClasses,
|
||||
fetchSchedules,
|
||||
fetchRegistrationDiscounts,
|
||||
fetchTuitionDiscounts,
|
||||
fetchRegistrationFees,
|
||||
fetchTuitionFees,
|
||||
fetchRegistrationPaymentPlans,
|
||||
fetchTuitionPaymentPlans,
|
||||
fetchRegistrationPaymentModes,
|
||||
fetchTuitionPaymentModes,
|
||||
} from '@/app/actions/schoolAction';
|
||||
import { fetchProfileRoles, fetchProfiles } from '@/app/actions/authAction';
|
||||
import SidebarTabs from '@/components/SidebarTabs';
|
||||
import FilesGroupsManagement from '@/components/Structure/Files/FilesGroupsManagement';
|
||||
import { fetchRegistrationTemplateMaster } from "@/app/actions/registerFileGroupAction";
|
||||
import { fetchRegistrationTemplateMaster } from '@/app/actions/registerFileGroupAction';
|
||||
import logger from '@/utils/logger';
|
||||
import { useEstablishment } from '@/context/EstablishmentContext';
|
||||
|
||||
@ -76,10 +77,10 @@ export default function Page() {
|
||||
|
||||
// Fetch data for registration file templates
|
||||
fetchRegistrationTemplateMaster()
|
||||
.then((data)=> {
|
||||
setFichiers(data)
|
||||
.then((data) => {
|
||||
setFichiers(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching files:', error));
|
||||
.catch((error) => logger.error('Error fetching files:', error));
|
||||
|
||||
// Fetch data for registration payment plans
|
||||
handleRegistrationPaymentPlans();
|
||||
@ -94,145 +95,161 @@ export default function Page() {
|
||||
handleTuitionPaymentModes();
|
||||
|
||||
fetchProfiles()
|
||||
.then(data => {
|
||||
setProfiles(data);
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('Error fetching profileRoles:', error);
|
||||
})
|
||||
.then((data) => {
|
||||
setProfiles(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('Error fetching profileRoles:', error);
|
||||
});
|
||||
}
|
||||
}, [selectedEstablishmentId]);
|
||||
|
||||
const handleSpecialities = () => {
|
||||
fetchSpecialities(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setSpecialities(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching specialities:', error));
|
||||
.catch((error) => logger.error('Error fetching specialities:', error));
|
||||
};
|
||||
|
||||
const handleTeachers = () => {
|
||||
fetchTeachers(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setTeachers(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching teachers:', error));
|
||||
.catch((error) => logger.error('Error fetching teachers:', error));
|
||||
};
|
||||
|
||||
const handleClasses = () => {
|
||||
fetchClasses(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setClasses(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching classes:', error));
|
||||
.catch((error) => logger.error('Error fetching classes:', error));
|
||||
};
|
||||
|
||||
const handleSchedules = () => {
|
||||
fetchSchedules()
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setSchedules(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching schedules:', error));
|
||||
.catch((error) => logger.error('Error fetching schedules:', error));
|
||||
};
|
||||
|
||||
const handleRegistrationDiscounts = () => {
|
||||
fetchRegistrationDiscounts(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setRegistrationDiscounts(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching registration discounts:', error));
|
||||
.catch((error) =>
|
||||
logger.error('Error fetching registration discounts:', error)
|
||||
);
|
||||
};
|
||||
|
||||
const handleTuitionDiscounts = () => {
|
||||
fetchTuitionDiscounts(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setTuitionDiscounts(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching tuition discounts:', error));
|
||||
.catch((error) =>
|
||||
logger.error('Error fetching tuition discounts:', error)
|
||||
);
|
||||
};
|
||||
|
||||
const handleRegistrationFees = () => {
|
||||
fetchRegistrationFees(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setRegistrationFees(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching registration fees:', error));
|
||||
.catch((error) =>
|
||||
logger.error('Error fetching registration fees:', error)
|
||||
);
|
||||
};
|
||||
|
||||
const handleTuitionFees = () => {
|
||||
fetchTuitionFees(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setTuitionFees(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching tuition fees', error));
|
||||
.catch((error) => logger.error('Error fetching tuition fees', error));
|
||||
};
|
||||
|
||||
const handleRegistrationPaymentPlans = () => {
|
||||
fetchRegistrationPaymentPlans(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setRegistrationPaymentPlans(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching registration payment plans:', error));
|
||||
.catch((error) =>
|
||||
logger.error('Error fetching registration payment plans:', error)
|
||||
);
|
||||
};
|
||||
|
||||
const handleTuitionPaymentPlans = () => {
|
||||
fetchTuitionPaymentPlans(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setTuitionPaymentPlans(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching tuition payment plans:', error));
|
||||
.catch((error) =>
|
||||
logger.error('Error fetching tuition payment plans:', error)
|
||||
);
|
||||
};
|
||||
|
||||
const handleRegistrationPaymentModes = () => {
|
||||
fetchRegistrationPaymentModes(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setRegistrationPaymentModes(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching registration payment modes:', error));
|
||||
.catch((error) =>
|
||||
logger.error('Error fetching registration payment modes:', error)
|
||||
);
|
||||
};
|
||||
|
||||
const handleTuitionPaymentModes = () => {
|
||||
fetchTuitionPaymentModes(selectedEstablishmentId)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
setTuitionPaymentModes(data);
|
||||
})
|
||||
.catch(error => logger.error('Error fetching tuition payment modes:', error));
|
||||
.catch((error) =>
|
||||
logger.error('Error fetching tuition payment modes:', error)
|
||||
);
|
||||
};
|
||||
|
||||
const handleCreate = (url, newData, setDatas) => {
|
||||
return createDatas(url, newData, csrfToken)
|
||||
.then(data => {
|
||||
setDatas(prevState => [...prevState, data]);
|
||||
return data;
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('Error creating data:', error);
|
||||
throw error;
|
||||
});
|
||||
.then((data) => {
|
||||
setDatas((prevState) => [...prevState, data]);
|
||||
return data;
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('Error creating data:', error);
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
|
||||
const handleEdit = (url, id, updatedData, setDatas) => {
|
||||
return updateDatas(url, id, updatedData, csrfToken)
|
||||
.then(data => {
|
||||
setDatas(prevState => prevState.map(item => item.id === id ? data : item));
|
||||
return data;
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('Error editing data:', error);
|
||||
throw error;
|
||||
});
|
||||
.then((data) => {
|
||||
setDatas((prevState) =>
|
||||
prevState.map((item) => (item.id === id ? data : item))
|
||||
);
|
||||
return data;
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('Error editing data:', error);
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
|
||||
const handleDelete = (url, id, setDatas) => {
|
||||
return removeDatas(url, id, csrfToken)
|
||||
.then(data => {
|
||||
setDatas(prevState => prevState.filter(item => item.id !== id));
|
||||
return data;
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('Error deleting data:', error);
|
||||
throw error;
|
||||
});
|
||||
.then((data) => {
|
||||
setDatas((prevState) => prevState.filter((item) => item.id !== id));
|
||||
return data;
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('Error deleting data:', error);
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
|
||||
const handleUpdatePlanning = (url, planningId, updatedData) => {
|
||||
@ -240,19 +257,19 @@ export default function Page() {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': csrfToken
|
||||
'X-CSRFToken': csrfToken,
|
||||
},
|
||||
body: JSON.stringify(updatedData),
|
||||
credentials: 'include'
|
||||
credentials: 'include',
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
logger.debug('Planning mis à jour avec succès :', data);
|
||||
//setDatas(data);
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('Erreur :', error);
|
||||
});
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
logger.debug('Planning mis à jour avec succès :', data);
|
||||
//setDatas(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('Erreur :', error);
|
||||
});
|
||||
};
|
||||
|
||||
const tabs = [
|
||||
@ -272,7 +289,7 @@ export default function Page() {
|
||||
handleEdit={handleEdit}
|
||||
handleDelete={handleDelete}
|
||||
/>
|
||||
)
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'Schedule',
|
||||
@ -284,7 +301,7 @@ export default function Page() {
|
||||
classes={classes}
|
||||
/>
|
||||
</ClassesProvider>
|
||||
)
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'Fees',
|
||||
@ -311,23 +328,27 @@ export default function Page() {
|
||||
handleEdit={handleEdit}
|
||||
handleDelete={handleDelete}
|
||||
/>
|
||||
)
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'Files',
|
||||
label: 'Documents d\'inscription',
|
||||
content: <FilesGroupsManagement csrfToken={csrfToken} selectedEstablishmentId={selectedEstablishmentId} />
|
||||
}
|
||||
label: "Documents d'inscription",
|
||||
content: (
|
||||
<FilesGroupsManagement
|
||||
csrfToken={csrfToken}
|
||||
selectedEstablishmentId={selectedEstablishmentId}
|
||||
/>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className='p-8'>
|
||||
<div className="p-8">
|
||||
<DjangoCSRFToken csrfToken={csrfToken} />
|
||||
|
||||
<div className="w-full p-4">
|
||||
<SidebarTabs tabs={tabs} />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
'use client'
|
||||
'use client';
|
||||
import React, { useState } from 'react';
|
||||
import { useSearchParams, useRouter } from 'next/navigation';
|
||||
import InscriptionFormShared from '@/components/Inscription/InscriptionFormShared';
|
||||
@ -9,41 +9,37 @@ import { editRegisterForm } from '@/app/actions/subscriptionAction';
|
||||
import logger from '@/utils/logger';
|
||||
|
||||
export default function Page() {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const studentId = searchParams.get('studentId'); // Changé de codeDI à studentId
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const studentId = searchParams.get('studentId'); // Changé de codeDI à studentId
|
||||
|
||||
const [formErrors, setFormErrors] = useState({});
|
||||
const csrfToken = useCsrfToken();
|
||||
const { selectedEstablishmentId } = useEstablishment();
|
||||
const [formErrors, setFormErrors] = useState({});
|
||||
const csrfToken = useCsrfToken();
|
||||
const { selectedEstablishmentId } = useEstablishment();
|
||||
|
||||
const handleSubmit = (data) => {
|
||||
editRegisterForm(studentId, data, csrfToken)
|
||||
.then((result) => {
|
||||
logger.debug('Success:', result);
|
||||
router.push(FE_ADMIN_SUBSCRIPTIONS_URL);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('Error:', error.message);
|
||||
if (error.details) {
|
||||
logger.error('Form errors:', error.details);
|
||||
setFormErrors(error.details);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleSubmit = (data) => {
|
||||
|
||||
editRegisterForm(studentId, data, csrfToken)
|
||||
|
||||
.then((result) => {
|
||||
logger.debug('Success:', result);
|
||||
router.push(FE_ADMIN_SUBSCRIPTIONS_URL);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('Error:', error.message);
|
||||
if (error.details) {
|
||||
logger.error('Form errors:', error.details);
|
||||
setFormErrors(error.details);
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<InscriptionFormShared
|
||||
studentId={studentId}
|
||||
csrfToken={csrfToken}
|
||||
selectedEstablishmentId={selectedEstablishmentId}
|
||||
onSubmit={handleSubmit}
|
||||
cancelUrl={FE_ADMIN_SUBSCRIPTIONS_URL}
|
||||
errors={formErrors}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<InscriptionFormShared
|
||||
studentId={studentId}
|
||||
csrfToken={csrfToken}
|
||||
selectedEstablishmentId={selectedEstablishmentId}
|
||||
onSubmit={handleSubmit}
|
||||
cancelUrl={FE_ADMIN_SUBSCRIPTIONS_URL}
|
||||
errors={formErrors}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,11 @@
|
||||
'use client'
|
||||
'use client';
|
||||
import React from 'react';
|
||||
import { useSearchParams, useRouter } from 'next/navigation';
|
||||
import ValidateSubscription from '@/components/Inscription/ValidateSubscription';
|
||||
import { sendSEPARegisterForm } from "@/app/actions/subscriptionAction"
|
||||
import { sendSEPARegisterForm } from '@/app/actions/subscriptionAction';
|
||||
import { useCsrfToken } from '@/context/CsrfContext';
|
||||
import logger from '@/utils/logger';
|
||||
import { FE_ADMIN_SUBSCRIPTIONS_URL} from '@/utils/Url';
|
||||
import { FE_ADMIN_SUBSCRIPTIONS_URL } from '@/utils/Url';
|
||||
|
||||
export default function Page() {
|
||||
const searchParams = useSearchParams();
|
||||
@ -23,11 +23,11 @@ export default function Page() {
|
||||
const handleAcceptRF = (data) => {
|
||||
logger.debug('Mise à jour du RF avec les données:', data);
|
||||
|
||||
const {status, sepa_file} = data
|
||||
const { status, sepa_file } = data;
|
||||
const formData = new FormData();
|
||||
formData.append('status', status); // Ajoute le statut
|
||||
formData.append('sepa_file', sepa_file); // Ajoute le fichier SEPA
|
||||
|
||||
|
||||
// Appeler l'API pour mettre à jour le RF
|
||||
sendSEPARegisterForm(studentId, formData, csrfToken)
|
||||
.then((response) => {
|
||||
@ -39,7 +39,7 @@ export default function Page() {
|
||||
logger.error('Erreur lors de la mise à jour du RF:', error);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<ValidateSubscription
|
||||
studentId={studentId}
|
||||
@ -50,4 +50,4 @@ export default function Page() {
|
||||
onAccept={handleAcceptRF}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user