diff --git a/src/app/page.tsx b/src/app/[[...panel]]/page.tsx
similarity index 95%
rename from src/app/page.tsx
rename to src/app/[[...panel]]/page.tsx
index 34ec5ed..1bdfec0 100644
--- a/src/app/page.tsx
+++ b/src/app/[[...panel]]/page.tsx
@@ -1,6 +1,7 @@
'use client'
import { useEffect, useState } from 'react'
+import { usePathname } from 'next/navigation'
import { NavRail } from '@/components/layout/nav-rail'
import { HeaderBar } from '@/components/layout/header-bar'
import { LiveFeed } from '@/components/layout/live-feed'
@@ -39,7 +40,15 @@ import { useMissionControl } from '@/store'
export default function Home() {
const { connect } = useWebSocket()
- const { activeTab, setCurrentUser, setDashboardMode, setGatewayAvailable, setSubscription, liveFeedOpen, toggleLiveFeed } = useMissionControl()
+ const { activeTab, setActiveTab, setCurrentUser, setDashboardMode, setGatewayAvailable, setSubscription, liveFeedOpen, toggleLiveFeed } = useMissionControl()
+
+ // Sync URL → Zustand activeTab
+ const pathname = usePathname()
+ const panelFromUrl = pathname === '/' ? 'overview' : pathname.slice(1)
+
+ useEffect(() => {
+ setActiveTab(panelFromUrl)
+ }, [panelFromUrl, setActiveTab])
// Connect to SSE for real-time local DB events (tasks, agents, chat, etc.)
useServerEvents()
diff --git a/src/components/dashboard/dashboard.tsx b/src/components/dashboard/dashboard.tsx
index 1f76760..38ab1a9 100644
--- a/src/components/dashboard/dashboard.tsx
+++ b/src/components/dashboard/dashboard.tsx
@@ -2,6 +2,7 @@
import { useState, useCallback } from 'react'
import { useMissionControl } from '@/store'
+import { useNavigateToPanel } from '@/lib/navigation'
import { useSmartPoll } from '@/lib/use-smart-poll'
interface DbStats {
@@ -35,8 +36,8 @@ export function Dashboard() {
logs,
agents,
tasks,
- setActiveTab,
} = useMissionControl()
+ const navigateToPanel = useNavigateToPanel()
const isLocal = dashboardMode === 'local'
const subscriptionLabel = subscription?.type
? subscription.type.charAt(0).toUpperCase() + subscription.type.slice(1)
@@ -124,7 +125,7 @@ export function Dashboard() {
{isLocal ? (
<>
-
setActiveTab('sessions')}>
+
navigateToPanel('sessions')}>
-
setActiveTab('sessions')}>
+
navigateToPanel('sessions')}>
-
setActiveTab('tokens')}>
+
navigateToPanel('tokens')}>
-
setActiveTab('tokens')}>
+
navigateToPanel('tokens')}>
) : (
<>
-
setActiveTab('history')}>
+
navigateToPanel('history')}>
-
setActiveTab('agents')}>
+
navigateToPanel('agents')}>
-
setActiveTab('tasks')}>
+
navigateToPanel('tasks')}>
-
setActiveTab('logs')}>
+
navigateToPanel('logs')}>
setActiveTab('sessions')}>
+ navigateToPanel('sessions')}>
Claude Code Stats
@@ -305,7 +306,7 @@ export function Dashboard() {
) : (
- setActiveTab('audit')}>
+
navigateToPanel('audit')}>
Security & Audit
{dbStats && dbStats.audit.loginFailures > 0 && (
@@ -513,15 +514,15 @@ export function Dashboard() {
{/* Quick Actions */}
{!isLocal && (
- } setActiveTab={setActiveTab} />
+ } onNavigate={navigateToPanel} />
)}
- } setActiveTab={setActiveTab} />
- } setActiveTab={setActiveTab} />
- } setActiveTab={setActiveTab} />
+ } onNavigate={navigateToPanel} />
+ } onNavigate={navigateToPanel} />
+ } onNavigate={navigateToPanel} />
{isLocal ? (
- } setActiveTab={setActiveTab} />
+ } onNavigate={navigateToPanel} />
) : (
- } setActiveTab={setActiveTab} />
+ } onNavigate={navigateToPanel} />
)}
@@ -616,13 +617,13 @@ function StatusBadge({ connected }: { connected: boolean }) {
)
}
-function QuickAction({ label, desc, tab, icon, setActiveTab }: {
+function QuickAction({ label, desc, tab, icon, onNavigate }: {
label: string; desc: string; tab: string; icon: React.ReactNode
- setActiveTab: (tab: string) => void
+ onNavigate: (tab: string) => void
}) {
return (