66 lines
2.0 KiB
React
66 lines
2.0 KiB
React
import { useState, useEffect, useCallback } from 'react'
|
|
import Sidebar from './components/Sidebar.jsx'
|
|
import Dashboard from './components/Dashboard.jsx'
|
|
import LiveTracking from './components/LiveTracking.jsx'
|
|
import Trips from './components/Trips.jsx'
|
|
import Records from './components/Records.jsx'
|
|
import RiskAudit from './components/RiskAudit.jsx'
|
|
import PreTravel from './components/PreTravel.jsx'
|
|
import Notifications from './components/Notifications.jsx'
|
|
import { fetchNotifications } from './lib/pocketbase.js'
|
|
|
|
/**
|
|
* App — root layout component.
|
|
* Implements a two-panel CSS Grid: fixed sidebar + scrollable main viewport.
|
|
* Owns the active-page state so sidebar navigation drives content rendering.
|
|
*/
|
|
export default function App() {
|
|
const [activePage, setActivePage] = useState('dashboard')
|
|
const [unreadNotifCount, setUnreadNotifCount] = useState(0)
|
|
|
|
const refreshUnreadCount = useCallback(async () => {
|
|
try {
|
|
const notifs = await fetchNotifications()
|
|
const unread = (notifs || []).filter((n) => !n.is_read && !n.is_archived).length
|
|
setUnreadNotifCount(unread)
|
|
} catch {
|
|
// Fallback for bridge unready or offline state
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
refreshUnreadCount()
|
|
}, [refreshUnreadCount, activePage])
|
|
|
|
function renderPage() {
|
|
switch (activePage) {
|
|
case 'live-tracking': return <LiveTracking />
|
|
case 'trips': return <Trips />
|
|
case 'records': return <Records />
|
|
case 'risk-audit': return <RiskAudit />
|
|
case 'pre-travel': return <PreTravel />
|
|
case 'notifications':
|
|
return (
|
|
<Notifications
|
|
onNavigate={setActivePage}
|
|
onUnreadCountChange={setUnreadNotifCount}
|
|
/>
|
|
)
|
|
default: return <Dashboard />
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="app-shell">
|
|
<Sidebar
|
|
activePage={activePage}
|
|
onNavigate={setActivePage}
|
|
unreadNotifCount={unreadNotifCount}
|
|
/>
|
|
<main className="main-viewport">
|
|
{renderPage()}
|
|
</main>
|
|
</div>
|
|
)
|
|
}
|