fix: Ajout du mode Visu

This commit is contained in:
N3WT DE COMPET
2025-05-04 14:32:06 +02:00
parent 4ecf25a6ab
commit e1c607308c
29 changed files with 531 additions and 414 deletions

View File

@ -143,69 +143,64 @@ export default function Layout({ children }) {
return (
<ProtectedRoute requiredRight={[RIGHTS.ADMIN, RIGHTS.TEACHER]}>
{/* Topbar */}
<header className="absolute top-0 left-0 right-0 h-16 bg-white border-b border-gray-200 px-4 md:px-8 flex items-center justify-between z-10 box-border">
<div className="flex items-center">
<button
className="mr-4 md:hidden text-gray-600 hover:text-gray-900"
onClick={toggleSidebar}
aria-label="Toggle menu"
>
{isSidebarOpen ? <X size={24} /> : <Menu size={24} />}
</button>
<div className="text-lg md:text-xl font-semibold">{headerTitle}</div>
</div>
<DropdownMenu
buttonContent={
<Image
src={getGravatarUrl(user?.email)}
alt="Profile"
className="w-8 h-8 rounded-full cursor-pointer"
width={32}
height={32}
/>
}
items={dropdownItems}
buttonClassName=""
menuClassName="absolute right-0 mt-2 w-64 bg-white border border-gray-200 rounded shadow-lg"
/>
</header>
{/* Sidebar */}
<div
className={`absolute top-16 bottom-16 left-0 z-30 w-64 bg-white border-r border-gray-200 box-border ${
isSidebarOpen ? 'block' : 'hidden md:block'
}`}
>
<Sidebar
establishments={establishments}
currentPage={currentPage}
items={Object.values(sidebarItems)}
onCloseMobile={toggleSidebar}
/>
</div>
{/* Overlay for mobile */}
{isSidebarOpen && (
<div
className="fixed inset-0 bg-black bg-opacity-50 z-20 md:hidden"
{/* Topbar */}
<header className="absolute top-0 left-0 right-0 h-16 bg-white border-b border-gray-200 px-4 md:px-8 flex items-center justify-between z-10 box-border">
<div className="flex items-center">
<button
className="mr-4 md:hidden text-gray-600 hover:text-gray-900"
onClick={toggleSidebar}
/>
)}
{/* Main container */}
<div className="absolute overflow-auto bg-gray-50 top-16 bottom-16 left-64 right-0 ">
{children}
aria-label="Toggle menu"
>
{isSidebarOpen ? <X size={24} /> : <Menu size={24} />}
</button>
<div className="text-lg md:text-xl font-semibold">{headerTitle}</div>
</div>
<DropdownMenu
buttonContent={
<Image
src={getGravatarUrl(user?.email)}
alt="Profile"
className="w-8 h-8 rounded-full cursor-pointer"
width={32}
height={32}
/>
}
items={dropdownItems}
buttonClassName=""
menuClassName="absolute right-0 mt-2 w-64 bg-white border border-gray-200 rounded shadow-lg"
/>
</header>
{/* Footer */}
{/* Sidebar */}
<div
className={`absolute top-16 bottom-16 left-0 z-30 w-64 bg-white border-r border-gray-200 box-border ${
isSidebarOpen ? 'block' : 'hidden md:block'
}`}
>
<Sidebar
establishments={establishments}
currentPage={currentPage}
items={Object.values(sidebarItems)}
onCloseMobile={toggleSidebar}
/>
</div>
<Footer
softwareName={softwareName}
softwareVersion={softwareVersion}
/>
{/* Overlay for mobile */}
{isSidebarOpen && (
<div
className="fixed inset-0 bg-black bg-opacity-50 z-20 md:hidden"
onClick={toggleSidebar}
/>
)}
{/* Main container */}
<div className="absolute overflow-auto bg-gray-50 top-16 bottom-16 left-64 right-0 ">
{children}
</div>
{/* Footer */}
<Footer softwareName={softwareName} softwareVersion={softwareVersion} />
<Popup
visible={isPopupVisible}

View File

@ -1,5 +1,9 @@
'use client';
import { PlanningModes, PlanningProvider, RecurrenceType } from '@/context/PlanningContext';
import {
PlanningModes,
PlanningProvider,
RecurrenceType,
} from '@/context/PlanningContext';
import Calendar from '@/components/Calendar/Calendar';
import EventModal from '@/components/Calendar/EventModal';
import ScheduleNavigation from '@/components/Calendar/ScheduleNavigation';
@ -47,7 +51,10 @@ export default function Page() {
};
return (
<PlanningProvider establishmentId={selectedEstablishmentId} modeSet={PlanningModes.PLANNING}>
<PlanningProvider
establishmentId={selectedEstablishmentId}
modeSet={PlanningModes.PLANNING}
>
{/* <div className="flex h-full overflow-hidden"> */}
<div className="flex h-full overflow-hidden">
<ScheduleNavigation />

View File

@ -60,7 +60,6 @@ export default function Page() {
// Fetch data for classes
handleClasses();
// Fetch data for registration discounts
handleRegistrationDiscounts();
@ -126,7 +125,6 @@ export default function Page() {
.catch((error) => logger.error('Error fetching classes:', error));
};
const handleRegistrationDiscounts = () => {
fetchRegistrationDiscounts(selectedEstablishmentId)
.then((data) => {
@ -336,12 +334,14 @@ export default function Page() {
];
return (
<>
<PlanningProvider establishmentId={selectedEstablishmentId} modeSet={PlanningModes.CLASS_SCHEDULE}>
<DjangoCSRFToken csrfToken={csrfToken} />
<SidebarTabs tabs={tabs} />
<>
<PlanningProvider
establishmentId={selectedEstablishmentId}
modeSet={PlanningModes.CLASS_SCHEDULE}
>
<DjangoCSRFToken csrfToken={csrfToken} />
<SidebarTabs tabs={tabs} />
</PlanningProvider>
</>
</>
);
}

View File

@ -5,7 +5,7 @@ import InscriptionFormShared from '@/components/Inscription/InscriptionFormShare
import { FE_ADMIN_SUBSCRIPTIONS_URL } from '@/utils/Url';
import { useCsrfToken } from '@/context/CsrfContext';
import { useEstablishment } from '@/context/EstablishmentContext';
import { editRegisterFormWithBinaryFile } from '@/app/actions/subscriptionAction';
import { editRegisterForm } from '@/app/actions/subscriptionAction';
import logger from '@/utils/logger';
import Loader from '@/components/Loader';

View File

@ -10,8 +10,8 @@ import logger from '@/utils/logger';
export default function Page() {
const searchParams = useSearchParams();
const idProfil = searchParams.get('id');
const studentId = searchParams.get('studentId');
const enable = searchParams.get('enabled') === 'true';
const router = useRouter();
const csrfToken = useCsrfToken();
const { selectedEstablishmentId } = useEstablishment();
@ -37,6 +37,7 @@ export default function Page() {
selectedEstablishmentId={selectedEstablishmentId}
onSubmit={handleSubmit}
cancelUrl={FE_PARENTS_HOME_URL}
enable={enable}
/>
);
}

View File

@ -17,7 +17,6 @@ import { useCsrfToken } from '@/context/CsrfContext';
export default function ParentHomePage() {
const [children, setChildren] = useState([]);
const [userId, setUserId] = useState(null);
const { user, selectedEstablishmentId } = useEstablishment();
const [uploadingStudentId, setUploadingStudentId] = useState(null); // ID de l'étudiant pour l'upload
const [uploadedFile, setUploadedFile] = useState(null); // Fichier uploadé
@ -29,7 +28,6 @@ export default function ParentHomePage() {
useEffect(() => {
if (user !== null) {
const userIdFromSession = user.user_id;
setUserId(userIdFromSession);
fetchChildren(userIdFromSession, selectedEstablishmentId).then((data) => {
setChildren(data);
});
@ -40,14 +38,14 @@ export default function ParentHomePage() {
function handleView(eleveId) {
logger.debug(`View dossier for student id: ${eleveId}`);
router.push(
`${FE_PARENTS_EDIT_INSCRIPTION_URL}?id=${userId}&studentId=${eleveId}&view=true`
`${FE_PARENTS_EDIT_INSCRIPTION_URL}?studentId=${eleveId}&enabled=false`
);
}
function handleEdit(eleveId) {
logger.debug(`Edit dossier for student id: ${eleveId}`);
router.push(
`${FE_PARENTS_EDIT_INSCRIPTION_URL}?id=${userId}&studentId=${eleveId}`
`${FE_PARENTS_EDIT_INSCRIPTION_URL}?studentId=${eleveId}&enabled=true`
);
}
@ -176,6 +174,19 @@ export default function ParentHomePage() {
</button>
</>
)}
{row.status === 5 && (
<button
className="text-purple-500 hover:text-purple-700"
onClick={(e) => {
e.stopPropagation();
handleView(row.student.id);
}}
aria-label="Visualiser le dossier"
>
<Eye className="h-5 w-5" />
</button>
)}
</div>
),
},

View File

@ -53,8 +53,11 @@ const removeDatas = (url, csrfToken) => {
}).then(requestResponseHandler);
};
export const fetchPlannings = (establishment_id=null,planningMode=null) => {
let url = `${BE_PLANNING_PLANNINGS_URL}`;
export const fetchPlannings = (
establishment_id = null,
planningMode = null
) => {
let url = `${BE_PLANNING_PLANNINGS_URL}`;
if (establishment_id) {
url += `?establishment_id=${establishment_id}`;
}
@ -80,7 +83,7 @@ export const deletePlanning = (id, csrfToken) => {
return removeDatas(`${BE_PLANNING_PLANNINGS_URL}/${id}`, csrfToken);
};
export const fetchEvents = (establishment_id=null, planningMode=null) => {
export const fetchEvents = (establishment_id = null, planningMode = null) => {
let url = `${BE_PLANNING_EVENTS_URL}`;
if (establishment_id) {
url += `?establishment_id=${establishment_id}`;
@ -90,7 +93,6 @@ export const fetchEvents = (establishment_id=null, planningMode=null) => {
}
return getData(url);
};
export const getEvent = (id) => {
@ -109,8 +111,8 @@ export const deleteEvent = (id, csrfToken) => {
return removeDatas(`${BE_PLANNING_EVENTS_URL}/${id}`, csrfToken);
};
export const fetchUpcomingEvents = (establishment_id=null) => {
let url = `${BE_PLANNING_EVENTS_URL}/upcoming`;
export const fetchUpcomingEvents = (establishment_id = null) => {
let url = `${BE_PLANNING_EVENTS_URL}/upcoming`;
if (establishment_id) {
url += `?establishment_id=${establishment_id}`;
}

View File

@ -28,7 +28,7 @@ export default async function RootLayout({ children, params }) {
return (
<html lang={locale}>
<body className='p-0 m-0'>
<body className="p-0 m-0">
<Providers messages={messages} locale={locale} session={params.session}>
{children}
</Providers>