mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 16:03:21 +00:00
feat: Création d'un profile selector [#37,#38]
This commit is contained in:
@ -131,7 +131,6 @@ export default function Layout({
|
||||
if (roleIndex === -1) {
|
||||
roleIndex = 0;
|
||||
}
|
||||
setCurrentRoleIndex(roleIndex);
|
||||
const role = session.user.roles[roleIndex].role_type;
|
||||
setProfileRole(role);
|
||||
}}
|
||||
|
||||
@ -10,7 +10,7 @@ import logger from '@/utils/logger';
|
||||
import { fetchRegisterForms } from '@/app/actions/subscriptionAction';
|
||||
import { fetchUpcomingEvents } from '@/app/actions/planningAction';
|
||||
import { getSession } from 'next-auth/react';
|
||||
import { getCurrentRoleIndex } from '@/store/Store';
|
||||
import { useEstablishment } from '@/context/EstablishmentContext';
|
||||
|
||||
|
||||
// Composant EventCard pour afficher les événements
|
||||
@ -42,14 +42,11 @@ export default function DashboardPage() {
|
||||
|
||||
const [classes, setClasses] = useState([]);
|
||||
const [establishmentId, setEstablishmentId] = useState(null);
|
||||
|
||||
const { selectedEstablishmentId } = useEstablishment();
|
||||
useEffect(() => {
|
||||
getSession()
|
||||
.then(session => {
|
||||
if (session && session.user) {
|
||||
const establishmentId = session.user.roles[getCurrentRoleIndex()].establishment__id;
|
||||
setEstablishmentId(establishmentId);
|
||||
}
|
||||
setEstablishmentId(selectedEstablishmentId);
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error('Error fetching session:', err);
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
// src/components/Layout.js
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import DropdownMenu from '@/components/DropdownMenu';
|
||||
import ProfileSelector from '@/components/ProfileSelector';
|
||||
import { useRouter } from 'next/navigation'; // Ajout de l'importation
|
||||
import { User, MessageSquare, LogOut, Settings, Home } from 'lucide-react'; // Ajout de l'importation de l'icône Home
|
||||
import Logo from '@/components/Logo'; // Ajout de l'importation du composant Logo
|
||||
@ -11,11 +12,11 @@ import ProtectedRoute from '@/components/ProtectedRoute';
|
||||
import { disconnect } from '@/app/actions/authAction';
|
||||
import Popup from '@/components/Popup';
|
||||
import logger from '@/utils/logger';
|
||||
import { useSession } from 'next-auth/react';
|
||||
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
|
||||
import { getRightStr, RIGHTS } from '@/utils/rights';
|
||||
import { getGravatarUrl } from '@/utils/gravatar';
|
||||
import { useEstablishment } from '@/context/EstablishmentContext';
|
||||
import Image from 'next/image';
|
||||
import Footer from '@/components/Footer';
|
||||
|
||||
export default function Layout({
|
||||
children,
|
||||
@ -23,11 +24,12 @@ export default function Layout({
|
||||
|
||||
const router = useRouter(); // Définition de router
|
||||
const [messages, setMessages] = useState([]);
|
||||
const { data: session, status } = useSession();
|
||||
const [userId, setUserId] = useState(null);
|
||||
const [user, setUser] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isPopupVisible, setIsPopupVisible] = useState(false);
|
||||
const { profileRole, user } = useEstablishment();
|
||||
const softwareName = "N3WT School";
|
||||
const softwareVersion = `${process.env.NEXT_PUBLIC_APP_VERSION}`;
|
||||
|
||||
|
||||
const handleDisconnect = () => {
|
||||
setIsPopupVisible(true);
|
||||
@ -36,42 +38,15 @@ export default function Layout({
|
||||
const confirmDisconnect = () => {
|
||||
setIsPopupVisible(false);
|
||||
disconnect();
|
||||
};
|
||||
};
|
||||
|
||||
// useEffect(() => {
|
||||
// if (status === 'loading') return;
|
||||
// if (!session) {
|
||||
// router.push(`${FE_USERS_LOGIN_URL}`);
|
||||
// }
|
||||
|
||||
// const userIdFromSession = session.user.id;
|
||||
// setUserId(userIdFromSession);
|
||||
// setIsLoading(true);
|
||||
// fetchMessages(userId)
|
||||
// .then(data => {
|
||||
// if (data) {
|
||||
// setMessages(data);
|
||||
// }
|
||||
// logger.debug('Success :', data);
|
||||
// })
|
||||
// .catch(error => {
|
||||
// logger.error('Error fetching data:', error);
|
||||
// })
|
||||
// .finally(() => {
|
||||
// setIsLoading(false);
|
||||
// });
|
||||
// }, [userId]);
|
||||
|
||||
// if (isLoading) {
|
||||
// return <div>Loading...</div>;
|
||||
// }
|
||||
const dropdownItems = [
|
||||
{
|
||||
type: 'info',
|
||||
content: (
|
||||
<div className="px-4 py-2">
|
||||
<div className="font-medium">{user?.email || 'Utilisateur'}</div>
|
||||
<div className="text-xs text-gray-400">{getRightStr(user?.roles[0]?.role_type) || ''}</div>
|
||||
<div className="text-xs text-gray-400">{getRightStr(profileRole) || ''}</div>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
@ -91,11 +66,14 @@ const dropdownItems = [
|
||||
<ProtectedRoute requiredRight={RIGHTS.PARENT}>
|
||||
<div className="flex flex-col min-h-screen bg-gray-50">
|
||||
{/* Entête */}
|
||||
<header className="bg-white border-b border-gray-200 px-4 py-2 md:px-8 md:py-4 flex items-center justify-between fixed top-0 left-0 right-0 z-10">
|
||||
<header className="h-16 bg-white border-b border-gray-200 px-4 md:px-8 py-4 flex items-center justify-between fixed top-0 left-0 right-0 z-10">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Logo className="h-6 w-6 md:h-8 md:w-8" /> {/* Utilisation du composant Logo */}
|
||||
|
||||
<div className="text-lg md:text-xl font-semibold">Accueil</div>
|
||||
<div className="border-b border-gray-200 ">
|
||||
<ProfileSelector
|
||||
className="w-64 border-r"
|
||||
/>
|
||||
</div>
|
||||
<div className="text-lg md:text-xl p-2 font-semibold">Accueil</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2 md:space-x-4">
|
||||
<button
|
||||
@ -116,6 +94,7 @@ const dropdownItems = [
|
||||
<span className="absolute top-0 right-0 block h-2 w-2 rounded-full bg-emerald-600"></span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<DropdownMenu
|
||||
buttonContent={<Image
|
||||
src={getGravatarUrl(user?.email)}
|
||||
@ -135,6 +114,8 @@ const dropdownItems = [
|
||||
<div className="pt-16 md:pt-20 p-4 md:p-8 flex-1"> {/* Ajout de flex-1 pour utiliser toute la hauteur disponible */}
|
||||
{children}
|
||||
</div>
|
||||
{/* Footer responsive */}
|
||||
<Footer softwareName={softwareName} softwareVersion={softwareVersion} />
|
||||
</div>
|
||||
<Popup
|
||||
visible={isPopupVisible}
|
||||
|
||||
@ -7,51 +7,33 @@ import StatusLabel from '@/components/StatusLabel';
|
||||
import { FE_PARENTS_EDIT_INSCRIPTION_URL } from '@/utils/Url';
|
||||
import { fetchChildren } from '@/app/actions/subscriptionAction';
|
||||
import logger from '@/utils/logger';
|
||||
import { useSession } from 'next-auth/react';
|
||||
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
|
||||
import { useEstablishment } from '@/context/EstablishmentContext';
|
||||
import ProfileSelector from '@/components/ProfileSelector';
|
||||
|
||||
export default function ParentHomePage() {
|
||||
const [children, setChildren] = useState([]);
|
||||
const { data: session, status } = useSession();
|
||||
const [userId, setUserId] = useState(null);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [establishments, setEstablishments] = useState([]);
|
||||
const { selectedEstablishmentId, setSelectedEstablishmentId } = useEstablishment();
|
||||
const { user, setProfileRole, selectedEstablishmentId, setSelectedEstablishmentId, establishments } = useEstablishment();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (status === 'loading') return;
|
||||
|
||||
if (!session || !session.user) {
|
||||
router.push(`${FE_USERS_LOGIN_URL}`);
|
||||
} else {
|
||||
const userIdFromSession = session.user.user_id;
|
||||
const userIdFromSession = user.user_id;
|
||||
setUserId(userIdFromSession);
|
||||
|
||||
const userEstablishments = session.user.roles.map(role => ({
|
||||
id: role.establishment__id,
|
||||
name: role.establishment__name,
|
||||
role_type: role.role_type
|
||||
}));
|
||||
setEstablishments(userEstablishments);
|
||||
|
||||
if (!selectedEstablishmentId && userEstablishments.length > 0) {
|
||||
setSelectedEstablishmentId(userEstablishments[0].id);
|
||||
}
|
||||
console.log(selectedEstablishmentId)
|
||||
fetchChildren(userIdFromSession, selectedEstablishmentId).then(data => {
|
||||
setChildren(data);
|
||||
});
|
||||
}
|
||||
}, [status, session, selectedEstablishmentId]);
|
||||
|
||||
}, [ selectedEstablishmentId]);
|
||||
|
||||
const handleEstablishmentChange = (e) => {
|
||||
const establishmentId = parseInt(e.target.value, 10);
|
||||
setSelectedEstablishmentId(establishmentId);
|
||||
const role = establishments.find(est => est.id === establishmentId)?.role_type;
|
||||
setProfileRole(role);
|
||||
};
|
||||
|
||||
function handleEdit(eleveId) {
|
||||
// Logique pour éditer le dossier de l'élève
|
||||
logger.debug(`Edit dossier for student id: ${eleveId}`);
|
||||
@ -107,22 +89,6 @@ export default function ParentHomePage() {
|
||||
<Users className="h-6 w-6 text-emerald-600" />
|
||||
Enfants
|
||||
</h2>
|
||||
{establishments.length > 1 && (
|
||||
<div className="mb-4">
|
||||
<label className="block text-gray-700 text-sm font-bold mb-2">Sélectionnez un établissement :</label>
|
||||
<select
|
||||
value={selectedEstablishmentId}
|
||||
onChange={handleEstablishmentChange}
|
||||
className="block w-full mt-1 p-2 border border-gray-300 rounded-md"
|
||||
>
|
||||
{establishments.map((establishment, index) => (
|
||||
<option key={`${establishment.id}-${index}`} value={establishment.id}>
|
||||
{establishment.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
<div className="overflow-x-auto">
|
||||
<Table
|
||||
data={children}
|
||||
|
||||
@ -9,16 +9,16 @@ import Button from '@/components/Button'; // Importez le composant Button
|
||||
import { User, KeySquare } from 'lucide-react'; // Importez directement les icônes nécessaires
|
||||
import {
|
||||
FE_USERS_NEW_PASSWORD_URL,
|
||||
FE_ADMIN_SUBSCRIPTIONS_URL,
|
||||
FE_PARENTS_HOME_URL
|
||||
getRedirectUrlFromRole
|
||||
} from '@/utils/Url';
|
||||
import { login } from '@/app/actions/authAction';
|
||||
import { getSession } from 'next-auth/react';
|
||||
import { useCsrfToken } from '@/context/CsrfContext'; // Importez le hook useCsrfToken
|
||||
import logger from '@/utils/logger';
|
||||
import ProfileSelector from '@/components/ProfileSelector'; // Importez le composant ProfileSelector
|
||||
import { RIGHTS } from '@/utils/rights';
|
||||
import { setCurrentRoleIndex } from '@/store/Store';
|
||||
|
||||
|
||||
import { useEstablishment } from '@/context/EstablishmentContext';
|
||||
|
||||
|
||||
|
||||
export default function Page() {
|
||||
@ -26,8 +26,7 @@ export default function Page() {
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
const [userFieldError, setUserFieldError] = useState("")
|
||||
const [passwordFieldError, setPasswordFieldError] = useState("")
|
||||
const [selectedProfile, setSelectedProfile] = useState(1); // Par défaut, sélectionnez ADMIN
|
||||
|
||||
const { setUser } = useEstablishment();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const router = useRouter();
|
||||
@ -37,14 +36,15 @@ export default function Page() {
|
||||
return data.errorMessage === ""
|
||||
}
|
||||
|
||||
|
||||
|
||||
function handleFormLogin(formData) {
|
||||
setIsLoading(true);
|
||||
setErrorMessage("");
|
||||
|
||||
login({
|
||||
email: formData.get('login'),
|
||||
password: formData.get('password'),
|
||||
role_type: selectedProfile
|
||||
password: formData.get('password')
|
||||
}).then(result => {
|
||||
logger.debug('Sign In Result', result);
|
||||
|
||||
@ -58,18 +58,16 @@ export default function Page() {
|
||||
}
|
||||
const user = session.user;
|
||||
logger.debug('User Session:', user);
|
||||
|
||||
const roles = user.roles.filter(role => role.role_type === selectedProfile);
|
||||
if (roles.length > 0) {
|
||||
// Redirection en fonction du rôle
|
||||
// Ne pas désactiver le loader avant la redirection
|
||||
const currentRoleIndex = 0;
|
||||
setCurrentRoleIndex(currentRoleIndex);
|
||||
const role = roles[currentRoleIndex].role_type;
|
||||
if (role === RIGHTS.ADMIN || role === RIGHTS.TEACHER) {
|
||||
router.push(FE_ADMIN_SUBSCRIPTIONS_URL);
|
||||
} else if (role === RIGHTS.PARENT) {
|
||||
router.push(FE_PARENTS_HOME_URL);
|
||||
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;
|
||||
const url = getRedirectUrlFromRole(role);
|
||||
if (url) {
|
||||
router.push(url);
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
setErrorMessage('Type de rôle non géré');
|
||||
@ -104,7 +102,6 @@ export default function Page() {
|
||||
<DjangoCSRFToken csrfToken={csrfToken} />
|
||||
<InputTextIcon name="login" type="text" IconItem={User} label="Identifiant" placeholder="Identifiant" errorMsg={userFieldError} className="w-full mb-5" />
|
||||
<InputTextIcon name="password" type="password" IconItem={KeySquare} label="Mot de passe" placeholder="Mot de passe" errorMsg={passwordFieldError} className="w-full mb-5" />
|
||||
<ProfileSelector selectedProfile={selectedProfile} setSelectedProfile={setSelectedProfile} />
|
||||
<div className="input-group mb-4">
|
||||
</div>
|
||||
<label className="text-red-500">{errorMessage}</label>
|
||||
|
||||
Reference in New Issue
Block a user