diff --git a/main-website/app/api/logout/route.ts b/main-website/app/api/logout/route.ts new file mode 100644 index 0000000..8db749c --- /dev/null +++ b/main-website/app/api/logout/route.ts @@ -0,0 +1,11 @@ +import {NextResponse} from 'next/server' + +export async function POST() { + const keycloakLogoutUrl = process.env.KEYCLOAK_LOGOUT_URL + + if (!keycloakLogoutUrl) { + return new NextResponse('Missing KEYCLOAK_LOGOUT_URL env variable', {status: 500}) + } + + return NextResponse.redirect(keycloakLogoutUrl, 302) +} diff --git a/main-website/app/layout.tsx b/main-website/app/layout.tsx index 9a5bfc9..e52968e 100644 --- a/main-website/app/layout.tsx +++ b/main-website/app/layout.tsx @@ -1,6 +1,8 @@ import type {Metadata} from "next"; import {Geist, Geist_Mono} from "next/font/google"; import "./globals.css"; +import ProfileDropdown from '@/components/ProfileDropdown' +import React from "react"; // <- Add this line const geistSans = Geist({ variable: "--font-geist-sans", @@ -24,10 +26,13 @@ export default function RootLayout({ }>) { return ( - - {children} + +
+
+ +
+ {children} +
); diff --git a/main-website/components/ProfileDropdown.tsx b/main-website/components/ProfileDropdown.tsx new file mode 100644 index 0000000..2a5308e --- /dev/null +++ b/main-website/components/ProfileDropdown.tsx @@ -0,0 +1,52 @@ +'use client' + +import {useState, useRef, useEffect} from 'react' +import {useRouter} from 'next/navigation' + +export default function ProfileDropdown() { + const [open, setOpen] = useState(false) + const dropdownRef = useRef(null) + const router = useRouter() + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { + setOpen(false) + } + } + + document.addEventListener('mousedown', handleClickOutside) + return () => document.removeEventListener('mousedown', handleClickOutside) + }, []) + + const handleLogout = async () => { + try { + await fetch('/logout', {method: 'POST'}) + router.push('/') // Or a dedicated post-logout landing page + } catch (e) { + console.error('Logout failed', e) + } + } + + return ( +
+ + + {open && ( +
+ +
+ )} +
+ ) +}