diff --git a/client/api.js b/client/api.js index 48bd432..16d63f9 100644 --- a/client/api.js +++ b/client/api.js @@ -137,6 +137,8 @@ export const api = { // Tracker tracker: (y, m, params = {}) => get(`/tracker${queryString({ year: y, month: m, ...params })}`), upcomingBills: (days = 30) => get(`/tracker/upcoming?days=${days}`), + overdueCount: () => get('/tracker/overdue-count'), + snoozeOverdue: (id, data) => put(`/bills/${id}/monthly-state`, data), // Calendar calendar: (y, m) => get(`/calendar?year=${y}&month=${m}`), diff --git a/client/components/layout/NavPill.jsx b/client/components/layout/NavPill.jsx index cb5c4e7..8ca4c7a 100644 --- a/client/components/layout/NavPill.jsx +++ b/client/components/layout/NavPill.jsx @@ -2,7 +2,7 @@ import React, { useMemo } from 'react'; import { NavLink } from 'react-router-dom'; import { cn } from '@/lib/utils'; -export const NavPill = React.memo(function NavPill({ item, onNavigate }) { +export const NavPill = React.memo(function NavPill({ item, onNavigate, badge }) { const Icon = useMemo(() => item.icon, [item.icon]); const to = useMemo(() => item.to, [item.to]); const end = useMemo(() => item.end, [item.end]); @@ -23,6 +23,11 @@ export const NavPill = React.memo(function NavPill({ item, onNavigate }) { > {label} + {badge > 0 && ( + + {badge > 99 ? '99+' : badge} + + )} ); }); diff --git a/client/components/layout/Sidebar.jsx b/client/components/layout/Sidebar.jsx index 30d8b15..44850bd 100644 --- a/client/components/layout/Sidebar.jsx +++ b/client/components/layout/Sidebar.jsx @@ -7,6 +7,7 @@ import { } from 'lucide-react'; import { cn } from '@/lib/utils'; import { useAuth } from '@/hooks/useAuth'; +import { useOverdueCount } from '@/hooks/useQueries'; import { ThemeToggle } from '@/components/ui/theme-toggle'; import { Button } from '@/components/ui/button'; import { @@ -42,7 +43,7 @@ const trackerItems = [ { to: '/snowball', icon: TrendingDown, label: 'Snowball' }, ]; -function TrackerMenu({ onNavigate }) { +function TrackerMenu({ onNavigate, badge }) { const location = useLocation(); const navigate = useNavigate(); const isTrackerActive = useMemo(() => trackerItems.some(item => ( @@ -65,6 +66,11 @@ function TrackerMenu({ onNavigate }) { > Tracker + {badge > 0 && ( + + {badge > 99 ? '99+' : badge} + + )} @@ -169,6 +175,8 @@ export default function Sidebar({ adminMode = false }) { const [mobileOpen, setMobileOpen] = useState(false); const { user } = useAuth(); const items = useMemo(() => adminMode ? adminNavItems : userNavItems, [adminMode]); + const { data: overdueData } = useOverdueCount(); + const overdueCount = (!adminMode && overdueData?.count) ? overdueData.count : 0; return (
@@ -176,7 +184,7 @@ export default function Sidebar({ adminMode = false }) {