Files
backerup-website/frontend/app/admin/layout.tsx
T
Anders Böttcher 984b282a95 feat: add admin links management and updaterup page
- Implemented AdminLinksPage for managing link entries with admin role check.
- Created API routes for fetching, updating, and deleting link entries.
- Added ProductTabs component for navigation between Backerup and Updaterup.
- Developed UpdaterupPage with detailed features, setup instructions, and statistics.
- Introduced links database functionality for runtime-editable link overrides.
2026-05-13 10:53:21 +02:00

50 lines
2.5 KiB
TypeScript

import { redirect } from 'next/navigation'
import { getSession } from '@/lib/session'
import Link from 'next/link'
export default async function AdminLayout({ children }: { children: React.ReactNode }) {
const session = await getSession()
if (!session || session.role !== 'admin') {
redirect('/')
}
return (
<div className="mx-auto max-w-3xl px-4 py-12">
{/* Header */}
<div className="mb-8">
<div className="flex items-center gap-3 mb-6">
<div
className="w-9 h-9 rounded-xl flex items-center justify-center shrink-0"
style={{ background: 'linear-gradient(135deg, #a78bfa, #7c3aed)' }}
>
<svg viewBox="0 0 20 20" fill="currentColor" className="w-4 h-4 text-white" aria-hidden="true">
<path fillRule="evenodd" d="M8.34 1.804A1 1 0 019.32 1h1.36a1 1 0 01.98.804l.295 1.473c.497.144.971.342 1.416.587l1.25-.834a1 1 0 011.262.125l.962.962a1 1 0 01.125 1.262l-.834 1.25c.245.445.443.919.587 1.416l1.473.294a1 1 0 01.804.98v1.361a1 1 0 01-.804.98l-1.473.295a6.95 6.95 0 01-.587 1.416l.834 1.25a1 1 0 01-.125 1.262l-.962.962a1 1 0 01-1.262.125l-1.25-.834a6.953 6.953 0 01-1.416.587l-.294 1.473a1 1 0 01-.98.804H9.32a1 1 0 01-.98-.804l-.295-1.473a6.957 6.957 0 01-1.416-.587l-1.25.834a1 1 0 01-1.262-.125l-.962-.962a1 1 0 01-.125-1.262l.834-1.25a6.957 6.957 0 01-.587-1.416l-1.473-.294A1 1 0 011 10.68V9.32a1 1 0 01.804-.98l1.473-.295c.144-.497.342-.971.587-1.416l-.834-1.25a1 1 0 01.125-1.262l.962-.962A1 1 0 015.38 3.03l1.25.834a6.957 6.957 0 011.416-.587l.294-1.473zM10 13a3 3 0 100-6 3 3 0 000 6z" clipRule="evenodd" />
</svg>
</div>
<div>
<h1 className="text-xl font-bold text-white">Admin</h1>
<p className="text-sm text-slate-400">Site management</p>
</div>
</div>
{/* Tab nav */}
<div className="flex items-center gap-1 rounded-xl border border-white/8 bg-white/2 p-1 w-fit">
<AdminTabLink href="/admin" label="Users" exact />
<AdminTabLink href="/admin/links" label="Links" />
</div>
</div>
{children}
</div>
)
}
function AdminTabLink({ href, label, exact }: { href: string; label: string; exact?: boolean }) {
// This is a server component but Next.js doesn't give us pathname here easily.
// We use a client wrapper below.
return <AdminTabLinkClient href={href} label={label} exact={exact} />
}
// Small client component just for active-state detection
import AdminTabLinkClient from './AdminTabLinkClient'