// ============================================================ // ADMIN PANEL — shell + access gate. // // The legacy admin page has 12+ sub-sections (users, feature flags, // announcement banner, OIDC, SMTP, AI model management, TTS/STT, // email templates, AI prompts, site-wide saved encounters, audit // logs, learning admin). Each is tied to /api/admin/* or // /api/admin/config endpoints and involves destructive operations // that need careful UX consideration (role revoke, feature-flag // toggles hit prod immediately, etc.). // // This first commit ships the access gate + a link to the legacy // admin viewer. Per-section React ports arrive as discrete commits // once the core React tree has settled. // ============================================================ import { useQuery } from '@tanstack/react-query'; import { api } from '@/lib/api'; import type { MeOk } from '@/shared/types'; const card = 'rounded-lg border border-border bg-card p-5 space-y-3'; const btnPrimary = 'rounded-md bg-primary text-primary-foreground px-4 py-2 text-sm font-medium'; export default function Admin() { const { data: me, isLoading } = useQuery({ queryKey: ['auth-me'], queryFn: () => api.get('/api/auth/me'), staleTime: 5 * 60_000, }); if (isLoading) { return (
Checking permissions…
); } if (me?.user.role !== 'admin') { return (

Admin only

This page is restricted to users with the admin role. If you believe this is a mistake, contact your site administrator.

); } return (

Admin Panel

Registration, users, feature flags, OIDC, email templates, AI prompts, SMTP, saved encounters (site-wide), AI model management, TTS/STT provider selection.

Admin sub-sections still live in the legacy viewer. Each one (user management, feature flags, announcements, OIDC config, SMTP, AI prompts, model management, TTS/STT) touches production state immediately when saved — those controls port in discrete follow-up commits with their own tests before they go live in the React tree.

Open admin in legacy viewer
); }