diff --git a/src/components/dashboard/DashboardLayout.tsx b/src/components/dashboard/DashboardLayout.tsx index dc31bbc..46f497b 100644 --- a/src/components/dashboard/DashboardLayout.tsx +++ b/src/components/dashboard/DashboardLayout.tsx @@ -1,6 +1,6 @@ -import { Component, Show, createEffect, For, createSignal, onMount } from 'solid-js'; +import { Component, Show, createEffect, For, createSignal, onMount, onCleanup } from 'solid-js'; import { useNavigate, A, useSearchParams } from '@solidjs/router'; -import { authState, logout, switchRole, bootstrapAuth, setMockRuntimeConfig, isModuleLocked } from '~/lib/auth'; +import { authState, logout, switchRole, bootstrapAuth, setMockRuntimeConfig, isModuleLocked, getAuthHeader } from '~/lib/auth'; import { shouldShowRoleSwitcher, getRoleLabel } from '~/lib/auth-flow'; import { getRoleTourStorageKey, @@ -340,6 +340,22 @@ export default function DashboardLayout(props: { children: any }) { const [tourKind, setTourKind] = createSignal(null); const [tourStepIndex, setTourStepIndex] = createSignal(0); const [authReady, setAuthReady] = createSignal(false); + const [unreadCount, setUnreadCount] = createSignal(0); + + const API = import.meta.env.VITE_API_URL ?? 'http://localhost:8000'; + + async function fetchUnreadCount() { + const auth = getAuthHeader(); + if (!auth.Authorization) return; + try { + const res = await fetch(`${API}/api/me/notifications?page=1&limit=1`, { headers: auth }); + if (!res.ok) return; + const data = await res.json(); + setUnreadCount(data.unread_count ?? 0); + } catch { + // ignore + } + } // Restore session or inject mock preview config onMount(async () => { @@ -350,6 +366,10 @@ export default function DashboardLayout(props: { children: any }) { await bootstrapAuth(); } setAuthReady(true); + // Poll for unread notification count every 60 seconds + await fetchUnreadCount(); + const notifTimer = setInterval(fetchUnreadCount, 60_000); + onCleanup(() => clearInterval(notifTimer)); }); createEffect(() => { @@ -580,8 +600,29 @@ export default function DashboardLayout(props: { children: any }) { - + + 0}> + + {unreadCount() > 99 ? '99+' : unreadCount()} + +
{rc()?.user?.full_name ?? 'User'}