cleaning hard 2
This commit is contained in:
parent
080984ec71
commit
7497121d60
@ -36,21 +36,6 @@ import {
|
|||||||
} from "@/components/ui/dropdown-menu";
|
} from "@/components/ui/dropdown-menu";
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { fr } from 'date-fns/locale';
|
import { fr } from 'date-fns/locale';
|
||||||
import dynamic from "next/dynamic";
|
|
||||||
|
|
||||||
// Dynamically import heavy components
|
|
||||||
const UserMenu = dynamic(() => import("./navbar/user-menu"), {
|
|
||||||
ssr: true,
|
|
||||||
loading: () => <div className="w-10 h-10 rounded-full bg-gray-200" />
|
|
||||||
});
|
|
||||||
|
|
||||||
const SidebarComponent = dynamic(() => import("./sidebar").then(mod => ({ default: mod.Sidebar })), {
|
|
||||||
ssr: false
|
|
||||||
});
|
|
||||||
|
|
||||||
const NavigationItems = dynamic(() => import("./navbar/navigation-items"), {
|
|
||||||
ssr: true
|
|
||||||
});
|
|
||||||
|
|
||||||
const requestNotificationPermission = async () => {
|
const requestNotificationPermission = async () => {
|
||||||
try {
|
try {
|
||||||
@ -235,42 +220,178 @@ export function MainNav() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<header className="sticky top-0 z-40 w-full bg-white dark:bg-gray-950 border-b">
|
<div className="fixed top-0 left-0 right-0 z-50 bg-black">
|
||||||
<div className="container flex h-16 items-center px-4 sm:px-8">
|
<div className="flex items-center justify-between px-4 py-1">
|
||||||
<button
|
{/* Left side */}
|
||||||
onClick={() => setIsSidebarOpen(!isSidebarOpen)}
|
<div className="flex items-center space-x-4">
|
||||||
className="mr-4 p-2 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-md"
|
<button
|
||||||
aria-label="Toggle menu"
|
onClick={() => setIsSidebarOpen(true)}
|
||||||
>
|
className="text-white/80 hover:text-white"
|
||||||
<Menu className="h-5 w-5" />
|
>
|
||||||
</button>
|
<Menu className="w-5 h-5" />
|
||||||
|
</button>
|
||||||
<div className="flex items-center">
|
<Link href='/'>
|
||||||
<Link href="/" className="flex items-center">
|
|
||||||
<Image
|
<Image
|
||||||
src="/logo.png"
|
src='/Neahv2 logo W.png'
|
||||||
alt="Neah Logo"
|
alt='Neah Logo'
|
||||||
width={28}
|
width={40}
|
||||||
height={28}
|
height={13}
|
||||||
className="mr-2"
|
className='text-white'
|
||||||
/>
|
/>
|
||||||
<span className="font-bold text-xl">Neah</span>
|
</Link>
|
||||||
|
<Link href='/agenda' className='text-white/80 hover:text-white'>
|
||||||
|
<Calendar className='w-5 h-5' />
|
||||||
|
</Link>
|
||||||
|
<Link href='/timetracker' className='text-white/80 hover:text-white'>
|
||||||
|
<Clock className='w-5 h-5' />
|
||||||
|
<span className="sr-only">TimeTracker</span>
|
||||||
|
</Link>
|
||||||
|
<Link href='/notes' className='text-white/80 hover:text-white'>
|
||||||
|
<PenLine className='w-5 h-5' />
|
||||||
|
<span className="sr-only">Notes</span>
|
||||||
|
</Link>
|
||||||
|
<Link href='/alma' className='text-white/80 hover:text-white'>
|
||||||
|
<Robot className='w-5 h-5' />
|
||||||
|
<span className="sr-only">ALMA</span>
|
||||||
|
</Link>
|
||||||
|
<Link href='/vision' className='text-white/80 hover:text-white'>
|
||||||
|
<Video className='w-5 h-5' />
|
||||||
|
<span className="sr-only">Vision</span>
|
||||||
|
</Link>
|
||||||
|
<Link href='/observatory' className='text-white/80 hover:text-white'>
|
||||||
|
<Telescope className='w-5 h-5' />
|
||||||
|
<span className="sr-only">Observatory</span>
|
||||||
|
</Link>
|
||||||
|
<Link href='/radio' className='text-white/80 hover:text-white'>
|
||||||
|
<RadioIcon className='w-5 h-5' />
|
||||||
|
<span className="sr-only">Radio</span>
|
||||||
|
</Link>
|
||||||
|
<Link href='/announcement' className='text-white/80 hover:text-white'>
|
||||||
|
<Megaphone className='w-5 h-5' />
|
||||||
|
<span className="sr-only">Announcement</span>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="ml-auto flex items-center space-x-4">
|
{/* Right side */}
|
||||||
<NavigationItems session={session} />
|
<div className="flex items-center space-x-8">
|
||||||
<UserMenu session={session} status={status} />
|
{/* Date and Time with smaller text */}
|
||||||
|
<div className="text-white/80 text-sm">
|
||||||
|
<span className="mr-2">{formattedDate}</span>
|
||||||
|
<span>{formattedTime}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
href='/notifications'
|
||||||
|
className='text-white/80 hover:text-white'
|
||||||
|
>
|
||||||
|
<Bell className='w-5 h-5' />
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{status === "authenticated" && session?.user ? (
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger className="outline-none">
|
||||||
|
<div className="w-8 h-8 rounded-full bg-blue-600 flex items-center justify-center text-white cursor-pointer hover:bg-blue-700 transition-colors">
|
||||||
|
{getUserInitials()}
|
||||||
|
</div>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent align="end" className="w-56 bg-black/90 border-gray-700">
|
||||||
|
<DropdownMenuLabel className="text-white/80">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<span>{getDisplayName()}</span>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger className="outline-none">
|
||||||
|
<div className="flex items-center space-x-1 text-sm">
|
||||||
|
<Circle className={`h-3 w-3 ${statusConfig[userStatus].color}`} />
|
||||||
|
<span className="text-gray-400">{statusConfig[userStatus].label}</span>
|
||||||
|
</div>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent className="bg-black/90 border-gray-700">
|
||||||
|
<DropdownMenuItem
|
||||||
|
className="text-white/80 hover:text-white hover:bg-black/50 cursor-pointer"
|
||||||
|
onClick={() => handleStatusChange('online')}
|
||||||
|
>
|
||||||
|
<Circle className="h-3 w-3 text-green-500 mr-2" />
|
||||||
|
<span>Online</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem
|
||||||
|
className="text-white/80 hover:text-white hover:bg-black/50 cursor-pointer"
|
||||||
|
onClick={() => handleStatusChange('busy')}
|
||||||
|
>
|
||||||
|
<Circle className="h-3 w-3 text-orange-500 mr-2" />
|
||||||
|
<span>Busy</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem
|
||||||
|
className="text-white/80 hover:text-white hover:bg-black/50 cursor-pointer"
|
||||||
|
onClick={() => handleStatusChange('away')}
|
||||||
|
>
|
||||||
|
<Circle className="h-3 w-3 text-gray-500 mr-2" />
|
||||||
|
<span>Away</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
|
</DropdownMenuLabel>
|
||||||
|
<DropdownMenuSeparator className="bg-gray-700" />
|
||||||
|
{visibleMenuItems.map((item) => (
|
||||||
|
<DropdownMenuItem
|
||||||
|
key={item.title}
|
||||||
|
className="text-white/80 hover:text-white hover:bg-black/50 cursor-pointer"
|
||||||
|
onClick={() => window.location.href = item.href}
|
||||||
|
>
|
||||||
|
<item.icon className="mr-2 h-4 w-4" />
|
||||||
|
<span>{item.title}</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
))}
|
||||||
|
<DropdownMenuItem
|
||||||
|
className="text-white/80 hover:text-white hover:bg-black/50 cursor-pointer"
|
||||||
|
onClick={async () => {
|
||||||
|
try {
|
||||||
|
// First sign out from NextAuth
|
||||||
|
await signOut({
|
||||||
|
callbackUrl: '/signin',
|
||||||
|
redirect: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// Then redirect to Keycloak logout with proper parameters
|
||||||
|
const keycloakLogoutUrl = new URL(
|
||||||
|
`${process.env.NEXT_PUBLIC_KEYCLOAK_ISSUER}/protocol/openid-connect/logout`
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add required parameters
|
||||||
|
keycloakLogoutUrl.searchParams.append(
|
||||||
|
'post_logout_redirect_uri',
|
||||||
|
window.location.origin
|
||||||
|
);
|
||||||
|
keycloakLogoutUrl.searchParams.append(
|
||||||
|
'id_token_hint',
|
||||||
|
session?.accessToken || ''
|
||||||
|
);
|
||||||
|
|
||||||
|
// Redirect to Keycloak logout
|
||||||
|
window.location.href = keycloakLogoutUrl.toString();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error during logout:', error);
|
||||||
|
// Fallback to simple redirect if something goes wrong
|
||||||
|
window.location.href = '/signin';
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<LogOut className="mr-2 h-4 w-4" />
|
||||||
|
<span>Déconnexion</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
) : (
|
||||||
|
<div className='cursor-pointer text-white/80 hover:text-white'>
|
||||||
|
<span onClick={() => signIn("keycloak", { callbackUrl: "/" })}>
|
||||||
|
Login
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</div>
|
||||||
|
<Sidebar isOpen={isSidebarOpen} onClose={() => setIsSidebarOpen(false)} />
|
||||||
{isSidebarOpen && (
|
|
||||||
<SidebarComponent
|
|
||||||
isOpen={isSidebarOpen}
|
|
||||||
onClose={() => setIsSidebarOpen(false)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,78 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import {
|
|
||||||
Calendar,
|
|
||||||
MessageSquare,
|
|
||||||
Bell,
|
|
||||||
Clock,
|
|
||||||
PenLine,
|
|
||||||
Telescope
|
|
||||||
} from "lucide-react";
|
|
||||||
import Link from "next/link";
|
|
||||||
import { Session } from "next-auth";
|
|
||||||
|
|
||||||
interface NavigationItemsProps {
|
|
||||||
session: Session | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function NavigationItems({ session }: NavigationItemsProps) {
|
|
||||||
const isAuthenticated = !!session?.user;
|
|
||||||
|
|
||||||
// Only show navigation items if user is authenticated
|
|
||||||
if (!isAuthenticated) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const navItems = [
|
|
||||||
{
|
|
||||||
href: '/agenda',
|
|
||||||
icon: Calendar,
|
|
||||||
label: 'Calendar'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
href: '/messages',
|
|
||||||
icon: MessageSquare,
|
|
||||||
label: 'Messages'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
href: '/timetracker',
|
|
||||||
icon: Clock,
|
|
||||||
label: 'Time Tracker'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
href: '/notes',
|
|
||||||
icon: PenLine,
|
|
||||||
label: 'Notes'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
href: '/observatory',
|
|
||||||
icon: Telescope,
|
|
||||||
label: 'Observatory'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="hidden md:flex items-center space-x-2">
|
|
||||||
{navItems.map((item) => (
|
|
||||||
<Link
|
|
||||||
key={item.href}
|
|
||||||
href={item.href}
|
|
||||||
className="p-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
||||||
aria-label={item.label}
|
|
||||||
>
|
|
||||||
<item.icon className="h-5 w-5" />
|
|
||||||
</Link>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Link
|
|
||||||
href="/notifications"
|
|
||||||
className="p-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
||||||
aria-label="Notifications"
|
|
||||||
>
|
|
||||||
<Bell className="h-5 w-5" />
|
|
||||||
</Link>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user