diff --git a/apps/dashboard/src/app/router.tsx b/apps/dashboard/src/app/router.tsx
index f40ea0d..c18af73 100644
--- a/apps/dashboard/src/app/router.tsx
+++ b/apps/dashboard/src/app/router.tsx
@@ -2,7 +2,7 @@ import { createBrowserRouter, type RouteObject } from 'react-router-dom';
import { AppShell } from './app-shell.js';
import { OverviewPage } from '../features/overview/overview-page.js';
import { ConversationRoute } from '../features/conversations/conversation-route.js';
-import { MediaPage } from '../features/media/media-page.js';
+import { MediaRoute } from '../features/media/media-route.js';
import { OperationsPage } from '../features/operations/operations-page.js';
import { PerformancePage } from '../features/performance/performance-page.js';
import { SettingsRoute } from '../features/settings/settings-route.js';
@@ -18,7 +18,7 @@ export function createDashboardRoutes(): RouteObject[] {
{ index: true, element: },
{ path: 'conversations', element: },
{ path: 'conversations/:conversationId', element: },
- { path: 'media', element: },
+ { path: 'media', element: },
{ path: 'performance', element: },
{ path: 'operations', element: },
{ path: 'settings', element: },
diff --git a/tests/dashboard/app.test.tsx b/tests/dashboard/app.test.tsx
index 24acd76..33a7c5f 100644
--- a/tests/dashboard/app.test.tsx
+++ b/tests/dashboard/app.test.tsx
@@ -91,6 +91,52 @@ describe('dashboard foundation', () => {
expect(screen.getByRole('heading', { name: 'Operations' })).toBeInTheDocument();
});
+ it('hydrates media filters from the routed URL', async () => {
+ installSuccessfulApi();
+ server.use(
+ http.get('/api/media', () => HttpResponse.json([{
+ id: 'media-1',
+ chatUsername: 'alice',
+ chatRoomId: 'room-1',
+ sender: 'alice',
+ timestamp: Date.now(),
+ originalUrl: 'https://example.test/reaction.gif',
+ fileName: 'reaction.gif',
+ relativePath: 'reaction.gif',
+ createdAt: Date.now(),
+ urlPath: '/media/reaction.gif',
+ }])),
+ http.get('/api/media/sync', () => HttpResponse.json({
+ isSyncing: false,
+ lastSyncAt: null,
+ lastSyncDurationMs: null,
+ lastSyncChats: null,
+ lastError: null,
+ nextSyncAt: null,
+ })),
+ http.get('/api/login/status', () => HttpResponse.json({
+ ready: true,
+ loggedIn: true,
+ status: 'authenticated',
+ })),
+ http.get('/api/chats/sync', () => HttpResponse.json({
+ syncing: false,
+ syncingKind: null,
+ lastFullSyncAt: null,
+ lastDeltaSyncAt: null,
+ hasEverFullSynced: false,
+ cachedChats: 0,
+ progress: null,
+ })),
+ );
+
+ renderDashboard('/media?conversation=alice&type=gif&range=7d');
+
+ expect(await screen.findByRole('combobox', { name: 'Conversation' })).toHaveValue('alice');
+ expect(screen.getByRole('combobox', { name: 'Media type' })).toHaveValue('gif');
+ expect(screen.getByRole('combobox', { name: 'Date range' })).toHaveValue('7d');
+ });
+
it('shows loading then renders stats, timers, and an explicit empty activity state', async () => {
let resolveStats: ((response: Response) => void) | undefined;
server.use(