/**
* NotificationBell Component
*
* Bell icon with unread badge, opens notification panel on click.
* On mobile/tablet: Uses SwipeableDrawer for better UX.
* On desktop: Uses dropdown panel.
*/
'use client';
import { useState, useRef, useEffect } from 'react';
import { Bell } from 'lucide-react';
import { useNotifications } from '@/hooks/useNotifications';
import { NotificationsPanel } from './NotificationsPanel';
import { Button } from '@/components/ui/button';
import { useMobileDetect } from '@/hooks/useMobileDetect';
import { SwipeableDrawer } from '@/components/mobile/SwipeableDrawer';
export function NotificationBell() {
const { unreadCount } = useNotifications();
const [isOpen, setIsOpen] = useState(false);
const panelRef = useRef<HTMLDivElement>(null);
const buttonRef = useRef<HTMLButtonElement>(null);
const { isMobile, isTablet } = useMobileDetect();
// Close panel on outside click (desktop only)
useEffect(() => {
// Skip for mobile/tablet - drawer handles its own close behavior
if (isMobile || isTablet) return;
function handleClickOutside(event: MouseEvent) {
if (
panelRef.current &&
!panelRef.current.contains(event.target as Node) &&
buttonRef.current &&
!buttonRef.current.contains(event.target as Node)
) {
setIsOpen(false);
}
}
if (isOpen) {
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}
}, [isOpen, isMobile, isTablet]);
return (
<div className="relative">
<Button
ref={buttonRef}
variant="ghost"
size="icon"
onClick={() => setIsOpen(!isOpen)}
className="relative"
aria-label="Notifications"
>
<Bell className="h-5 w-5" />
{unreadCount > 0 && (
<span className="absolute -top-1 -right-1 flex h-5 w-5 items-center justify-center rounded-full bg-red-500 text-xs font-bold text-white">
{unreadCount > 9 ? '9+' : unreadCount}
</span>
)}
</Button>
{/* Mobile/Tablet: Use SwipeableDrawer */}
{(isMobile || isTablet) ? (
<SwipeableDrawer
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Notifications"
height="auto"
>
<NotificationsPanel onClose={() => setIsOpen(false)} variant="inline" />
</SwipeableDrawer>
) : (
/* Desktop: Standard dropdown */
isOpen && (
<div ref={panelRef}>
<NotificationsPanel onClose={() => setIsOpen(false)} variant="dropdown" />
</div>
)
)}
</div>
);
}