index.tsx raw
1 import { Suspense, lazy, useState } from 'react'
2 import { cn } from '@/lib/utils'
3
4 const ExportTab = lazy(() => import('./ExportTab'))
5 const ImportTab = lazy(() => import('./ImportTab'))
6 const LogsTab = lazy(() => import('./LogsTab'))
7 const SprocketTab = lazy(() => import('./SprocketTab'))
8 const PolicyTab = lazy(() => import('./PolicyTab'))
9 const CurationTab = lazy(() => import('./CurationTab'))
10 const ManagedACLTab = lazy(() => import('./ManagedACLTab'))
11 const BlossomAdminTab = lazy(() => import('./BlossomAdminTab'))
12 const EventBrowserTab = lazy(() => import('./EventBrowserTab'))
13 const RecoveryTab = lazy(() => import('./RecoveryTab'))
14
15 const TABS = [
16 { id: 'events', label: 'Events' },
17 { id: 'export', label: 'Export' },
18 { id: 'import', label: 'Import' },
19 { id: 'policy', label: 'Policy' },
20 { id: 'curation', label: 'Curation' },
21 { id: 'acl', label: 'Managed ACL' },
22 { id: 'sprocket', label: 'Sprockets' },
23 { id: 'logs', label: 'Logs' },
24 { id: 'blossom', label: 'Blossom' },
25 { id: 'recovery', label: 'Recovery' }
26 ] as const
27
28 type TabId = (typeof TABS)[number]['id']
29
30 function TabContent({ tab }: { tab: TabId }) {
31 switch (tab) {
32 case 'events':
33 return <EventBrowserTab />
34 case 'export':
35 return <ExportTab />
36 case 'import':
37 return <ImportTab />
38 case 'policy':
39 return <PolicyTab />
40 case 'curation':
41 return <CurationTab />
42 case 'acl':
43 return <ManagedACLTab />
44 case 'sprocket':
45 return <SprocketTab />
46 case 'logs':
47 return <LogsTab />
48 case 'blossom':
49 return <BlossomAdminTab />
50 case 'recovery':
51 return <RecoveryTab />
52 }
53 }
54
55 export default function RelayAdminPanel() {
56 const [activeTab, setActiveTab] = useState<TabId>('events')
57
58 return (
59 <div className="w-full">
60 <div className="flex items-center gap-1 overflow-x-auto border-b border-border px-2 py-1">
61 {TABS.map((tab) => (
62 <button
63 key={tab.id}
64 onClick={() => setActiveTab(tab.id)}
65 className={cn(
66 'whitespace-nowrap rounded-md px-3 py-1.5 text-sm transition-colors',
67 activeTab === tab.id
68 ? 'bg-primary text-primary-foreground font-medium'
69 : 'text-muted-foreground hover:bg-muted hover:text-foreground'
70 )}
71 >
72 {tab.label}
73 </button>
74 ))}
75 </div>
76 <Suspense
77 fallback={
78 <div className="flex items-center justify-center py-12 text-muted-foreground">
79 Loading...
80 </div>
81 }
82 >
83 <TabContent tab={activeTab} />
84 </Suspense>
85 </div>
86 )
87 }
88