fix: Suppression de la top bar admin [#34]

This commit is contained in:
Luc SORIGNET
2025-05-17 12:23:56 +02:00
parent f252efdef4
commit 3990d75e52
7 changed files with 152 additions and 136 deletions

View File

@ -20,14 +20,17 @@ const Popup = ({
{/* Overlay noir semi-transparent */}
<div
className="fixed inset-0 bg-black bg-opacity-60 transition-opacity z-[9998]"
onClick={() => setIsOpen(false)}
onClick={() => {
if (setIsOpen) setIsOpen(false);
else if (onCancel) onCancel();
}}
/>
<div
className={`relative bg-white p-4 sm:p-6 rounded-xl shadow-2xl w-full max-w-xs sm:max-w-md ${popupClassName ? popupClassName : ''}`}
style={{ zIndex: 9999 }}
>
{/* Titre ou message */}
<div className="mb-6">
<div className="mb-6 text-center">
{isStringMessage
? messageLines.map((line, index) => (
<p key={index} className="text-gray-800 text-base">
@ -37,12 +40,13 @@ const Popup = ({
: message}
</div>
{/* Boutons d'action */}
<div className="flex justify-end space-x-4">
<div className="flex justify-center space-x-4 mt-8">
{!uniqueConfirmButton && (
<button
className="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 focus:outline-none transition"
onClick={() => {
setIsOpen(false);
if (setIsOpen) setIsOpen(false);
else if (onCancel) onCancel();
if (onCancel) onCancel();
}}
>
@ -52,7 +56,8 @@ const Popup = ({
<button
className="px-4 py-2 bg-emerald-500 text-white rounded-lg hover:bg-emerald-600 focus:outline-none transition"
onClick={() => {
setIsOpen(false);
if (setIsOpen) setIsOpen(false);
else if (onConfirm) onConfirm();
if (onConfirm) onConfirm();
}}
>

View File

@ -1,8 +1,13 @@
import React, { useState } from 'react';
import React, { useState, useContext } from 'react';
import { LogOut } from 'lucide-react';
import { disconnect } from '@/app/actions/authAction';
import { getGravatarUrl } from '@/utils/gravatar';
import { useEstablishment } from '@/context/EstablishmentContext';
import DropdownMenu from '@/components/DropdownMenu';
import { usePopup } from '@/context/PopupContext';
import { getRightStr } from '@/utils/rights';
import { ChevronDown } from 'lucide-react'; // Import de l'icône
import Image from 'next/image'; // Import du composant Image
const ProfileSelector = ({ onRoleChange, className = '' }) => {
const {
@ -14,6 +19,7 @@ const ProfileSelector = ({ onRoleChange, className = '' }) => {
user,
} = useEstablishment();
const [dropdownOpen, setDropdownOpen] = useState(false);
const { showPopup } = usePopup();
const handleRoleChange = (roleId) => {
// Pas bon quand on a plusieur role pour le même établissement
@ -28,52 +34,96 @@ const ProfileSelector = ({ onRoleChange, className = '' }) => {
setDropdownOpen(false); // Fermer le menu après sélection
};
// Si on a pas de rôle ou un seul rôle, on n'affiche pas le sélecteur
if (
!establishments ||
establishments.length === 0 ||
establishments.length === 1
) {
return null;
}
const handleDisconnect = () => {
setDropdownOpen(false);
setTimeout(() => {
showPopup &&
showPopup(
'Êtes-vous sûr(e) de vouloir vous déconnecter ?',
() => disconnect(),
undefined
);
}, 150);
};
const selectedEstablishment = establishments.find(
(est) => est.role_id === selectedRoleId
);
// Suppression du tronquage JS, on utilise uniquement CSS
const isSingleRole = establishments && establishments.length === 1;
return (
<div className={`relative ${className}`}>
<DropdownMenu
buttonContent={
<div className="h-16 flex items-center gap-2 cursor-pointer px-4 bg-white">
<div className="flex-1">
<div className="font-bold text-left">
{getRightStr(selectedEstablishment?.role_type) || ''}
<Image
src={getGravatarUrl(user?.email)}
alt="Profile"
className="w-8 h-8 rounded-full mr-2"
width={32}
height={32}
/>
<div className="flex-1 min-w-0">
<div
className="font-bold text-left truncate max-w-full"
title={user?.email}
>
{user?.email}
</div>
<div className="text-sm text-gray-500 text-left">
{selectedEstablishment?.name || 'Sélectionnez un établissement'}
<div
className="text-sm text-gray-500 text-left truncate max-w-full"
title={`${getRightStr(selectedEstablishment?.role_type) || ''}${selectedEstablishment?.name ? ', ' + selectedEstablishment.name : ''}`}
>
{getRightStr(selectedEstablishment?.role_type) || ''}
{selectedEstablishment?.name
? `, ${selectedEstablishment.name}`
: ''}
</div>
</div>
{/* Icône ChevronDown avec rotation conditionnelle */}
<ChevronDown
className={`w-5 h-5 transition-transform duration-200 ${
dropdownOpen ? 'rotate-180' : 'rotate-0'
}`}
className={`w-5 h-5 transition-transform duration-200 ${dropdownOpen ? 'rotate-180' : 'rotate-0'}`}
/>
</div>
}
items={establishments.map((establishment) => ({
type: 'item',
label: (
<div className="text-left">
<div className="font-bold">
{getRightStr(establishment.role_type)}
</div>
<div className="text-sm text-gray-500">{establishment.name}</div>
</div>
),
onClick: () => handleRoleChange(establishment.role_id),
}))}
items={
isSingleRole
? [
{
type: 'item',
label: 'Déconnexion',
onClick: handleDisconnect,
icon: LogOut,
},
]
: [
...establishments.map((establishment) => ({
type: 'item',
label: (
<div className="text-left">
<div className="font-bold">
{getRightStr(establishment.role_type)}
</div>
<div className="text-sm text-gray-500">
{establishment.name}
</div>
</div>
),
onClick: () => handleRoleChange(establishment.role_id),
})),
{
type: 'separator',
content: <hr className="my-2 border-gray-200" />,
},
{
type: 'item',
label: 'Déconnexion',
onClick: handleDisconnect,
icon: LogOut,
},
]
}
buttonClassName="w-full"
menuClassName="absolute mt-2 w-full bg-white border border-gray-200 rounded shadow-lg z-10"
dropdownOpen={dropdownOpen}

View File

@ -9,6 +9,7 @@ import { ClassesProvider } from '@/context/ClassesContext';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import logger from '@/utils/logger';
import { PopupProvider } from '@/context/PopupContext';
export default function Providers({ children, messages, locale, session }) {
if (!locale) {
@ -22,9 +23,11 @@ export default function Providers({ children, messages, locale, session }) {
<CsrfProvider>
<EstablishmentProvider>
<ClassesProvider>
<NextIntlClientProvider messages={messages} locale={locale}>
{children}
</NextIntlClientProvider>
<PopupProvider>
<NextIntlClientProvider messages={messages} locale={locale}>
{children}
</NextIntlClientProvider>
</PopupProvider>
</ClassesProvider>
</EstablishmentProvider>
</CsrfProvider>