58 lines
1.8 KiB
TypeScript
58 lines
1.8 KiB
TypeScript
import { ArrowLeft } from 'lucide-react'
|
|
import { Link, NavLink, Outlet } from 'react-router-dom'
|
|
import { cn } from '../../lib/utils'
|
|
|
|
const tabs = [
|
|
{ to: '/admin', label: 'Dashboard', end: true },
|
|
{ to: '/admin/topics', label: 'Topics' },
|
|
{ to: '/admin/tokens', label: 'API Tokens' },
|
|
{ to: '/admin/users', label: 'Users' },
|
|
{ to: '/admin/devices', label: 'Devices' },
|
|
{ to: '/admin/sources', label: 'Sources' },
|
|
{ to: '/admin/auth', label: 'Auth' },
|
|
{ to: '/admin/system', label: 'System' },
|
|
{ to: '/admin/backups', label: 'Backups' },
|
|
{ to: '/admin/audit-log', label: 'Audit Log' },
|
|
]
|
|
|
|
export function AdminLayout() {
|
|
return (
|
|
<div>
|
|
<div className="safe-top border-b border-base-border px-4 py-4 md:px-6 md:py-5">
|
|
<Link
|
|
to="/settings"
|
|
className="mb-2 inline-flex items-center gap-1.5 text-xs text-slate-500 transition-colors hover:text-slate-300"
|
|
>
|
|
<ArrowLeft className="h-3.5 w-3.5" />
|
|
Back to app
|
|
</Link>
|
|
<h1 className="text-lg font-semibold tracking-tight text-slate-100">Admin</h1>
|
|
</div>
|
|
|
|
<div className="scrollbar-none flex gap-1 overflow-x-auto border-b border-base-border px-4 md:px-6">
|
|
{tabs.map((tab) => (
|
|
<NavLink
|
|
key={tab.to}
|
|
to={tab.to}
|
|
end={tab.end}
|
|
className={({ isActive }) =>
|
|
cn(
|
|
'shrink-0 border-b-2 px-3 py-2.5 text-sm font-medium transition-colors',
|
|
isActive
|
|
? 'border-accent text-accent-bright'
|
|
: 'border-transparent text-slate-500 hover:text-slate-300',
|
|
)
|
|
}
|
|
>
|
|
{tab.label}
|
|
</NavLink>
|
|
))}
|
|
</div>
|
|
|
|
<div className="px-4 py-5 md:px-6">
|
|
<Outlet />
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|