notifications
This commit is contained in:
parent
5c9f68b080
commit
4efcd22107
@ -1,6 +1,6 @@
|
||||
import React, { memo, useState } from 'react';
|
||||
import React, { memo, useState, useEffect } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Bell, Check, ExternalLink } from 'lucide-react';
|
||||
import { Bell, Check, ExternalLink, AlertCircle } from 'lucide-react';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { useNotifications } from '@/hooks/use-notifications';
|
||||
import { Button } from '@/components/ui/button';
|
||||
@ -19,11 +19,22 @@ interface NotificationBadgeProps {
|
||||
|
||||
// Use React.memo to prevent unnecessary re-renders
|
||||
export const NotificationBadge = memo(function NotificationBadge({ className }: NotificationBadgeProps) {
|
||||
const { notifications, notificationCount, markAsRead, markAllAsRead } = useNotifications();
|
||||
const { notifications, notificationCount, markAsRead, markAllAsRead, fetchNotifications, loading, error } = useNotifications();
|
||||
const hasUnread = notificationCount.unread > 0;
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
console.log('[NOTIFICATION_BADGE] Current notification count:', notificationCount);
|
||||
console.log('[NOTIFICATION_BADGE] Current notifications:', notifications.length > 0 ? `${notifications.length} loaded` : 'none loaded');
|
||||
console.log('[NOTIFICATION_BADGE] Loading state:', loading);
|
||||
console.log('[NOTIFICATION_BADGE] Error state:', error);
|
||||
|
||||
// Fetch notifications when dropdown is opened
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
console.log('[NOTIFICATION_BADGE] Dropdown opened, fetching notifications');
|
||||
fetchNotifications(1, 10);
|
||||
}
|
||||
}, [isOpen, fetchNotifications]);
|
||||
|
||||
const handleMarkAsRead = async (notificationId: string) => {
|
||||
await markAsRead(notificationId);
|
||||
@ -34,12 +45,27 @@ export const NotificationBadge = memo(function NotificationBadge({ className }:
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
// Force fetch when component mounts
|
||||
useEffect(() => {
|
||||
console.log('[NOTIFICATION_BADGE] Component mounted, fetching initial notifications');
|
||||
fetchNotifications(1, 10);
|
||||
}, [fetchNotifications]);
|
||||
|
||||
// Take the latest 10 notifications for the dropdown
|
||||
const recentNotifications = notifications.slice(0, 10);
|
||||
|
||||
const handleOpenChange = (open: boolean) => {
|
||||
setIsOpen(open);
|
||||
if (open) {
|
||||
// Fetch fresh notifications when dropdown opens
|
||||
console.log('[NOTIFICATION_BADGE] Dropdown opened via handleOpenChange, fetching notifications');
|
||||
fetchNotifications(1, 10);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`relative ${className || ''}`}>
|
||||
<DropdownMenu open={isOpen} onOpenChange={setIsOpen}>
|
||||
<DropdownMenu open={isOpen} onOpenChange={handleOpenChange}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="icon" className="text-white/80 hover:text-white relative p-0">
|
||||
<Bell className='w-5 h-5' />
|
||||
@ -47,7 +73,7 @@ export const NotificationBadge = memo(function NotificationBadge({ className }:
|
||||
<Badge
|
||||
variant="notification"
|
||||
size="notification"
|
||||
className="absolute -top-2 -right-2"
|
||||
className="absolute -top-2 -right-2 z-50"
|
||||
>
|
||||
{notificationCount.unread > 99 ? '99+' : notificationCount.unread}
|
||||
</Badge>
|
||||
@ -67,8 +93,21 @@ export const NotificationBadge = memo(function NotificationBadge({ className }:
|
||||
</div>
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
{notifications.length === 0 ? (
|
||||
<div className="py-4 px-3 text-center">
|
||||
{loading ? (
|
||||
<div className="py-8 px-4 text-center">
|
||||
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 mx-auto mb-2"></div>
|
||||
<p className="text-sm text-muted-foreground">Loading notifications...</p>
|
||||
</div>
|
||||
) : error ? (
|
||||
<div className="py-8 px-4 text-center">
|
||||
<AlertCircle className="h-8 w-8 text-red-500 mx-auto mb-2" />
|
||||
<p className="text-sm text-red-500 mb-2">{error}</p>
|
||||
<Button variant="outline" size="sm" onClick={() => fetchNotifications(1, 10)}>
|
||||
Retry
|
||||
</Button>
|
||||
</div>
|
||||
) : notifications.length === 0 ? (
|
||||
<div className="py-8 px-4 text-center">
|
||||
<p className="text-sm text-muted-foreground">No notifications</p>
|
||||
</div>
|
||||
) : (
|
||||
@ -120,4 +159,4 @@ export const NotificationBadge = memo(function NotificationBadge({ className }:
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user