feat: add notification bell polling to dashboard shell
- Poll /api/me/notifications/unread-count every 30 seconds - Show orange dot badge when unread count > 0 - Matches PRD requirement for real-time notifications
This commit is contained in:
parent
bbf11b91e1
commit
eee2c367ca
1 changed files with 53 additions and 12 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
* Used for pages that need actual backend connectivity
|
* Used for pages that need actual backend connectivity
|
||||||
* (My Profile, My Portfolio, Verification) instead of the preview mock.
|
* (My Profile, My Portfolio, Verification) instead of the preview mock.
|
||||||
*/
|
*/
|
||||||
import { For, JSX, Show, createMemo } from 'solid-js';
|
import { For, JSX, Show, createMemo, createSignal, onMount } from 'solid-js';
|
||||||
import {
|
import {
|
||||||
User, Briefcase, LayoutDashboard, FolderOpen, MapPin, Star,
|
User, Briefcase, LayoutDashboard, FolderOpen, MapPin, Star,
|
||||||
CreditCard, Globe, ShieldCheck, HelpCircle, Settings,
|
CreditCard, Globe, ShieldCheck, HelpCircle, Settings,
|
||||||
|
|
@ -65,6 +65,33 @@ export default function DashboardShell(props: Props) {
|
||||||
return k.charAt(0).toUpperCase() + k.slice(1).toLowerCase();
|
return k.charAt(0).toUpperCase() + k.slice(1).toLowerCase();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [unreadCount, setUnreadCount] = createSignal(0);
|
||||||
|
|
||||||
|
// Fetch unread notification count
|
||||||
|
const fetchUnreadCount = async () => {
|
||||||
|
try {
|
||||||
|
const token = typeof window !== 'undefined' ? window.sessionStorage.getItem('nxtgauge_access_token') || '' : '';
|
||||||
|
if (!token) return;
|
||||||
|
const res = await fetch('/api/me/notifications/unread-count', {
|
||||||
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
|
credentials: 'include',
|
||||||
|
});
|
||||||
|
if (res.ok) {
|
||||||
|
const data = await res.json();
|
||||||
|
setUnreadCount(data.unread_count || 0);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to fetch unread count:', e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start polling on mount
|
||||||
|
onMount(() => {
|
||||||
|
fetchUnreadCount();
|
||||||
|
const interval = setInterval(fetchUnreadCount, 30000);
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
|
@ -160,17 +187,31 @@ export default function DashboardShell(props: Props) {
|
||||||
<p style={{ margin: '0', 'font-size': '15px', 'font-weight': '700', color: NAVY }}>
|
<p style={{ margin: '0', 'font-size': '15px', 'font-weight': '700', color: NAVY }}>
|
||||||
{props.activeSidebar}
|
{props.activeSidebar}
|
||||||
</p>
|
</p>
|
||||||
<div style={{ display: 'flex', 'align-items': 'center', gap: '12px' }}>
|
<div style={{ display: 'flex', 'align-items': 'center', gap: '12px' }}>
|
||||||
<Bell size={18} style={{ color: '#9CA3AF' }} />
|
<button type="button" style={{ position: 'relative', border: 'none', background: 'transparent', cursor: 'pointer', display: 'flex', 'align-items': 'center', 'justify-content': 'center', padding: 0 }}>
|
||||||
<div style={{
|
<Bell size={18} style={{ color: '#9CA3AF' }} />
|
||||||
width: '32px', height: '32px', 'border-radius': '999px',
|
<Show when={unreadCount() > 0}>
|
||||||
background: ORANGE, color: '#fff', display: 'flex',
|
<span style={{
|
||||||
'align-items': 'center', 'justify-content': 'center',
|
position: 'absolute',
|
||||||
'font-size': '13px', 'font-weight': '700',
|
top: '-2px',
|
||||||
}}>
|
right: '-2px',
|
||||||
{(props.userName || 'U').charAt(0).toUpperCase()}
|
width: '8px',
|
||||||
</div>
|
height: '8px',
|
||||||
</div>
|
background: '#FF5E13',
|
||||||
|
'border-radius': '50%',
|
||||||
|
border: '1px solid white'
|
||||||
|
}}></span>
|
||||||
|
</Show>
|
||||||
|
</button>
|
||||||
|
<div style={{
|
||||||
|
width: '32px', height: '32px', 'border-radius': '999px',
|
||||||
|
background: ORANGE, color: '#fff', display: 'flex',
|
||||||
|
'align-items': 'center', 'justify-content': 'center',
|
||||||
|
'font-size': '13px', 'font-weight': '700',
|
||||||
|
}}>
|
||||||
|
{(props.userName || 'U').charAt(0).toUpperCase()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{/* Page content */}
|
{/* Page content */}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue