feat: enhance dropdown components by integrating useClickOutside hook for improved user experience and accessibility in NewWorkshopDropdown and WorkshopTabs
This commit is contained in:
@@ -4,15 +4,20 @@ import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { useSession, signOut } from 'next-auth/react';
|
||||
import { useTheme } from '@/contexts/ThemeContext';
|
||||
import { useState } from 'react';
|
||||
import { useState, useRef } from 'react';
|
||||
import { Avatar, RocketIcon } from '@/components/ui';
|
||||
import { WORKSHOPS } from '@/lib/workshops';
|
||||
import { useClickOutside } from '@/hooks/useClickOutside';
|
||||
|
||||
export function Header() {
|
||||
const { theme, toggleTheme } = useTheme();
|
||||
const { data: session, status } = useSession();
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const [workshopsOpen, setWorkshopsOpen] = useState(false);
|
||||
const workshopsDropdownRef = useRef<HTMLDivElement>(null);
|
||||
const userMenuRef = useRef<HTMLDivElement>(null);
|
||||
useClickOutside(workshopsDropdownRef, () => setWorkshopsOpen(false), workshopsOpen);
|
||||
useClickOutside(userMenuRef, () => setMenuOpen(false), menuOpen);
|
||||
const pathname = usePathname();
|
||||
|
||||
const isActiveLink = (path: string) => pathname.startsWith(path);
|
||||
@@ -61,10 +66,9 @@ export function Header() {
|
||||
</Link>
|
||||
|
||||
{/* New Workshop Dropdown */}
|
||||
<div className="relative">
|
||||
<div className="relative" ref={workshopsDropdownRef}>
|
||||
<button
|
||||
onClick={() => setWorkshopsOpen(!workshopsOpen)}
|
||||
onBlur={() => setTimeout(() => setWorkshopsOpen(false), 150)}
|
||||
className={`flex items-center gap-1 text-sm font-medium transition-colors ${
|
||||
WORKSHOPS.some((w) => isActiveLink(w.path))
|
||||
? 'text-primary'
|
||||
@@ -120,7 +124,7 @@ export function Header() {
|
||||
{status === 'loading' ? (
|
||||
<div className="h-9 w-20 animate-pulse rounded-lg bg-card-hover" />
|
||||
) : status === 'authenticated' && session?.user ? (
|
||||
<div className="relative">
|
||||
<div ref={userMenuRef} className="relative">
|
||||
<button
|
||||
onClick={() => setMenuOpen(!menuOpen)}
|
||||
className="flex h-9 items-center gap-2 rounded-lg border border-border bg-card pl-1.5 pr-3 transition-colors hover:bg-card-hover"
|
||||
@@ -145,9 +149,7 @@ export function Header() {
|
||||
</button>
|
||||
|
||||
{menuOpen && (
|
||||
<>
|
||||
<div className="fixed inset-0 z-10" onClick={() => setMenuOpen(false)} />
|
||||
<div className="absolute right-0 z-20 mt-2 w-48 rounded-lg border border-border bg-card py-1 shadow-lg">
|
||||
<div className="absolute right-0 z-20 mt-2 w-48 rounded-lg border border-border bg-card py-1 shadow-lg">
|
||||
<div className="border-b border-border px-4 py-2">
|
||||
<p className="text-xs text-muted">Connecté en tant que</p>
|
||||
<p className="truncate text-sm font-medium text-foreground">
|
||||
@@ -175,7 +177,6 @@ export function Header() {
|
||||
Se déconnecter
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user