feat: add real-time notification count to sidebar and implement dedicated admin notification management dashboard

This commit is contained in:
sazzadulalambd
2026-05-17 23:26:10 +06:00
parent aaf91255bb
commit 6870ca6b0f
2 changed files with 1437 additions and 2 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -42,6 +42,7 @@ type NavItem = { label: string; href: string; icon: any; isNotification?: boolea
const adminNavItems: NavItem[] = [ const adminNavItems: NavItem[] = [
{ label: 'Dashboard', href: '/admin', icon: BarChart3 }, { label: 'Dashboard', href: '/admin', icon: BarChart3 },
{ label: 'Notifications', href: '/admin/notifications', icon: Bell, isNotification: true },
{ label: 'KYC Requests', href: '/admin/kyc', icon: Shield }, { label: 'KYC Requests', href: '/admin/kyc', icon: Shield },
{ label: 'Rentals', href: '/admin/rentals', icon: FileText }, { label: 'Rentals', href: '/admin/rentals', icon: FileText },
{ label: 'Bikers', href: '/admin/bikers', icon: Users }, { label: 'Bikers', href: '/admin/bikers', icon: Users },
@@ -58,7 +59,6 @@ const adminNavItems: NavItem[] = [
{ label: 'Users Management', href: '/admin/users', icon: Users }, { label: 'Users Management', href: '/admin/users', icon: Users },
{ label: 'Roles & Permissions', href: '/admin/roles', icon: Shield }, { label: 'Roles & Permissions', href: '/admin/roles', icon: Shield },
{ label: 'Settings', href: '/admin/settings', icon: Settings }, { label: 'Settings', href: '/admin/settings', icon: Settings },
]; ];
const bikerNavItems: NavItem[] = [ const bikerNavItems: NavItem[] = [
@@ -89,9 +89,39 @@ export default function Sidebar() {
const [userName, setUserName] = useState('User'); const [userName, setUserName] = useState('User');
const [userRole, setUserRole] = useState('admin'); const [userRole, setUserRole] = useState('admin');
const [adminUnreadCount, setAdminUnreadCount] = useState(5);
const [investorUnreadCount, setInvestorUnreadCount] = useState(2);
useEffect(() => { useEffect(() => {
setUserName(getUserName() || 'User'); setUserName(getUserName() || 'User');
setUserRole(getUserRole() || 'staff'); setUserRole(getUserRole() || 'staff');
const updateCounts = () => {
const adminNotifs = localStorage.getItem('jaiben_admin_notifications');
if (adminNotifs) {
try {
const parsed = JSON.parse(adminNotifs);
setAdminUnreadCount(parsed.filter((n: any) => !n.read).length);
} catch (e) {}
}
const invNotifs = localStorage.getItem('jaiben_investor_notifications');
if (invNotifs) {
try {
const parsed = JSON.parse(invNotifs);
setInvestorUnreadCount(parsed.filter((n: any) => !n.read).length);
} catch (e) {}
}
};
updateCounts();
window.addEventListener('storage', updateCounts);
window.addEventListener('jaiben_notifications_update', updateCounts);
return () => {
window.removeEventListener('storage', updateCounts);
window.removeEventListener('jaiben_notifications_update', updateCounts);
};
}, []); }, []);
const isAdmin = pathname.startsWith('/admin'); const isAdmin = pathname.startsWith('/admin');
@@ -175,7 +205,9 @@ export default function Sidebar() {
<Icon className={`w-5 h-5 ${isActive ? 'text-white' : ''}`} /> <Icon className={`w-5 h-5 ${isActive ? 'text-white' : ''}`} />
<span>{item.label}</span> <span>{item.label}</span>
{isNotification && ( {isNotification && (
<span className="ml-auto px-2 py-0.5 bg-accent text-white text-xs font-bold rounded-full">2</span> <span className="ml-auto px-2 py-0.5 bg-red-500 text-white text-xs font-bold rounded-full">
{isAdmin ? adminUnreadCount : investorUnreadCount}
</span>
)} )}
</Link> </Link>
); );