fix: Correction du Establishment context au refresh

This commit is contained in:
Luc SORIGNET
2025-05-01 12:19:07 +02:00
parent 31fdc612b1
commit 43e301ed64
9 changed files with 136 additions and 86 deletions

View File

@ -40,14 +40,8 @@ import { useEstablishment } from '@/context/EstablishmentContext';
export default function Layout({ children }) {
const t = useTranslations('sidebar');
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
const {
setSelectedRoleId,
setSelectedEstablishmentId,
profileRole,
setProfileRole,
establishments,
user,
} = useEstablishment();
const { profileRole, establishments, user, clearContext } =
useEstablishment();
// Déplacer le reste du code ici...
const sidebarItems = {
@ -112,6 +106,7 @@ export default function Layout({ children }) {
const confirmDisconnect = () => {
setIsPopupVisible(false);
disconnect();
clearContext();
};
const dropdownItems = [
@ -161,18 +156,6 @@ export default function Layout({ children }) {
currentPage={currentPage}
items={Object.values(sidebarItems)}
onCloseMobile={toggleSidebar}
onRoleChange={(roleId) => {
let parsedRoleId = parseInt(roleId, 10);
if (parsedRoleId === -1) {
parsedRoleId = 0;
}
const role = user.roles[parsedRoleId].role_type;
const establishmentId =
user.roles[parsedRoleId].establishment__id;
setProfileRole(role);
setSelectedRoleId(parsedRoleId);
setSelectedEstablishmentId(establishmentId);
}}
/>
</div>

View File

@ -25,9 +25,8 @@ import Footer from '@/components/Footer';
export default function Layout({ children }) {
const router = useRouter(); // Définition de router
const [messages, setMessages] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [isPopupVisible, setIsPopupVisible] = useState(false);
const { profileRole, user } = useEstablishment();
const { profileRole, user, clearContext } = useEstablishment();
const softwareName = 'N3WT School';
const softwareVersion = `${process.env.NEXT_PUBLIC_APP_VERSION}`;
@ -38,6 +37,7 @@ export default function Layout({ children }) {
const confirmDisconnect = () => {
setIsPopupVisible(false);
disconnect();
clearContext();
};
const dropdownItems = [

View File

@ -19,7 +19,7 @@ export default function Page() {
const [errorMessage, setErrorMessage] = useState('');
const [userFieldError, setUserFieldError] = useState('');
const [passwordFieldError, setPasswordFieldError] = useState('');
const { setUser } = useEstablishment();
const { initializeContextWithSession } = useEstablishment();
const [isLoading, setIsLoading] = useState(false);
const router = useRouter();
@ -40,35 +40,18 @@ export default function Page() {
setErrorMessage(result.error);
setIsLoading(false);
} else {
// On initialise le contexte establishement avec la session
getSession()
.then((session) => {
if (!session || !session.user) {
throw new Error('Session not found');
}
const user = session.user;
logger.debug('User Session:', user);
setUser(session.user);
if (session.user.roles && session.user.roles.length > 0) {
let roleIndex = 0;
if (
session.user.roles.length > session.user.roleIndexLoginDefault
) {
roleIndex = session.user.roleIndexLoginDefault;
}
const role = session.user.roles[roleIndex].role_type;
initializeContextWithSession(session, (role) => {
const url = getRedirectUrlFromRole(role);
if (url) {
router.push(url);
} else {
setIsLoading(false);
setErrorMessage('Type de rôle non géré');
}
} else {
});
setIsLoading(false);
setErrorMessage(
'Aucun rôle trouvé pour le profil sélectionné.'
);
}
})
.catch((error) => {
logger.error(

View File

@ -17,11 +17,11 @@ const ProfileSelector = ({ onRoleChange, className = '' }) => {
const handleRoleChange = (roleId) => {
// Pas bon quand on a plusieur role pour le même établissement
setSelectedRoleId(roleId);
const role = user.roles[roleId].role_type;
setProfileRole(role);
const establishmentId = user.roles[roleId].establishment__id;
setProfileRole(role);
setSelectedEstablishmentId(establishmentId);
setSelectedRoleId(roleId);
if (onRoleChange) {
onRoleChange(roleId);
}

View File

@ -1,33 +1,47 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useEstablishment } from '@/context/EstablishmentContext';
import { FE_USERS_LOGIN_URL, getRedirectUrlFromRole } from '@/utils/Url';
import logger from '@/utils/logger';
const ProtectedRoute = ({ children, requiredRight }) => {
const { user, profileRole } = useEstablishment();
const router = useRouter();
let hasRequiredRight = false;
if (requiredRight && Array.isArray(requiredRight)) {
// Vérifier si l'utilisateur a le droit requis
hasRequiredRight = requiredRight.some((right) => profileRole === right);
} else {
hasRequiredRight = profileRole === requiredRight;
}
const [hasRequiredRight, setHasRequiredRight] = useState(false);
// Vérifier si l'utilisateur a au moins un rôle correspondant au requiredRight
useEffect(() => {
if (user) {
logger.debug({
user,
profileRole,
requiredRight,
hasRequiredRight,
});
if (user && profileRole) {
let requiredRightChecked = false;
if (requiredRight && Array.isArray(requiredRight)) {
// Vérifier si l'utilisateur a le droit requis
requiredRightChecked = requiredRight.some(
(right) => profileRole === right
);
} else {
requiredRightChecked = profileRole === requiredRight;
}
setHasRequiredRight(requiredRightChecked);
// Vérifier si l'utilisateur a le droit requis mais pas le bon role on le redirige la page d'accueil associé au role
if (!hasRequiredRight) {
if (!requiredRightChecked) {
const redirectUrl = getRedirectUrlFromRole(profileRole);
if (redirectUrl !== null) {
router.push(`${redirectUrl}`);
}
}
} else {
// User non authentifié
router.push(`${FE_USERS_LOGIN_URL}`);
}
}, [profileRole]);
}, [user]);
// Autoriser l'affichage si authentifié et rôle correct
return hasRequiredRight ? children : null;

View File

@ -17,7 +17,7 @@ const SidebarItem = ({ icon: Icon, text, active, url, onClick }) => (
</div>
);
function Sidebar({ currentPage, items, onCloseMobile, onRoleChange }) {
function Sidebar({ currentPage, items, onCloseMobile }) {
const router = useRouter();
const [selectedItem, setSelectedItem] = useState(currentPage);
@ -37,7 +37,7 @@ function Sidebar({ currentPage, items, onCloseMobile, onRoleChange }) {
return (
<div className="w-64 bg-white border-r h-full border-gray-200">
<div className="border-b border-gray-200 ">
<ProfileSelector onRoleChange={onRoleChange} className="border-none" />
<ProfileSelector className="border-none" />
</div>
<nav className="space-y-1 px-4 py-6">
{items.map((item) => (

View File

@ -4,17 +4,71 @@ import logger from '@/utils/logger';
const EstablishmentContext = createContext();
export const EstablishmentProvider = ({ children }) => {
const [selectedEstablishmentId, setSelectedEstablishmentId] = useState(null);
const [selectedRoleId, setSelectedRoleId] = useState(null);
const [profileRole, setProfileRole] = useState(null);
const [establishments, setEstablishments] = useState([]);
const [user, setUser] = useState(null);
const [selectedEstablishmentId, setSelectedEstablishmentIdState] = useState(
() => {
const storedEstablishmentId = +sessionStorage.getItem(
'selectedEstablishmentId'
);
return storedEstablishmentId;
}
);
const [selectedRoleId, setSelectedRoleIdState] = useState(() => {
const storedRoleId = +sessionStorage.getItem('selectedRoleId');
return storedRoleId;
});
const [profileRole, setProfileRoleState] = useState(() => {
const storedProfileRole = +sessionStorage.getItem('profileRole');
return storedProfileRole;
});
const [establishments, setEstablishmentsState] = useState(() => {
const storedEstablishments = sessionStorage.getItem('establishments');
return storedEstablishments ? JSON.parse(storedEstablishments) : [];
});
const [user, setUserState] = useState(() => {
const storedUser = sessionStorage.getItem('user');
return storedUser ? JSON.parse(storedUser) : null;
});
useEffect(() => {
if (user) {
// Sauvegarder dans sessionStorage à chaque mise à jour
const setSelectedEstablishmentId = (id) => {
setSelectedEstablishmentIdState(id);
logger.debug('setSelectedEstablishmentId', id);
sessionStorage.setItem('selectedEstablishmentId', id);
};
const setSelectedRoleId = (id) => {
setSelectedRoleIdState(id);
sessionStorage.setItem('selectedRoleId', id);
};
const setProfileRole = (role) => {
setProfileRoleState(role);
sessionStorage.setItem('profileRole', role);
};
const setEstablishments = (establishments) => {
setEstablishmentsState(establishments);
sessionStorage.setItem('establishments', JSON.stringify(establishments));
};
const setUser = (user) => {
setUserState(user);
sessionStorage.setItem('user', JSON.stringify(user));
};
/**
* Fonction d'initialisation du contexte avec la session (appelée lors du login)
* @param {*} session
* @param {*} endInitFunctionHandler
*/
const initializeContextWithSession = (session, endInitFunctionHandler) => {
if (!session || !session.user) {
throw new Error('Session not found');
}
const user = session.user;
logger.debug('User Session:', user);
setUser(user);
logger.debug('Establishments User= ', user);
// Au changement de l'utilisateur on sette par défaut le premier établissement
// et le premier rôle
const userEstablishments = user.roles.map((role, i) => ({
id: role.establishment__id,
name: role.establishment__name,
@ -23,23 +77,39 @@ export const EstablishmentProvider = ({ children }) => {
}));
setEstablishments(userEstablishments);
logger.debug('Establishments', user.roleIndexLoginDefault);
if (user.roles && user.roles.length > 0) {
let roleIndexDefault = 0;
user.roleIndexLoginDefault;
// Sélectionner l'établissement au login par défaut
if (userEstablishments.length > user.roleIndexLoginDefault) {
roleIndexDefault = user.roleIndexLoginDefault;
}
setSelectedRoleId(roleIndexDefault);
if (userEstablishments.length > 0) {
setSelectedEstablishmentId(userEstablishments[roleIndexDefault].id);
setProfileRole(userEstablishments[roleIndexDefault].role_type);
}
setSelectedRoleId(roleIndexDefault);
if (endInitFunctionHandler) {
const role = session.user.roles[roleIndexDefault].role_type;
endInitFunctionHandler(role);
}
}, [user]);
} else {
setErrorMessage('Aucun rôle trouvé pour le profil sélectionné.');
}
};
const clearContext = () => {
setSelectedEstablishmentIdState(null);
setSelectedRoleIdState(null);
setProfileRoleState(null);
setEstablishmentsState([]);
setUserState(null);
sessionStorage.clear();
};
return (
<EstablishmentContext.Provider
value={{
initializeContextWithSession,
clearContext,
selectedEstablishmentId,
setSelectedEstablishmentId,
selectedRoleId,
@ -47,8 +117,9 @@ export const EstablishmentProvider = ({ children }) => {
profileRole,
setProfileRole,
establishments,
setUser,
setEstablishments,
user,
setUser,
}}
>
{children}

View File

@ -10,7 +10,6 @@ import {
} from '@/app/actions/planningAction';
import { useCsrfToken } from './CsrfContext';
import logger from '@/utils/logger';
import { useSession } from 'next-auth/react';
import { useEstablishment } from '@/context/EstablishmentContext';
/**

View File

@ -119,6 +119,6 @@ export function getRedirectUrlFromRole(role) {
case RIGHTS.PARENT:
return FE_PARENTS_HOME_URL;
default:
return null;
return '';
}
}