Fix admin sidebar missing on /curator/* routes

- Extract AdminShell component (sidebar + wrapper)
- admin/layout.tsx uses AdminShell
- curator/layout.tsx uses AdminShell for admin role (was rendering children only)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-07 14:59:51 +05:00
parent ec51dd34bb
commit 97f4c1ec24
3 changed files with 45 additions and 47 deletions
+2 -45
View File
@@ -1,55 +1,12 @@
import { headers } from "next/headers"; import { headers } from "next/headers";
import { auth } from "@/lib/auth"; import { auth } from "@/lib/auth";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
import { AdminNav } from "@/components/admin/admin-nav"; import { AdminShell } from "@/components/admin/admin-shell";
import { LogoutButton } from "@/components/layout/logout-button";
export default async function AdminLayout({ children }: { children: React.ReactNode }) { export default async function AdminLayout({ children }: { children: React.ReactNode }) {
const session = await auth.api.getSession({ headers: await headers() }); const session = await auth.api.getSession({ headers: await headers() });
if (!session) redirect("/login"); if (!session) redirect("/login");
if (session.user.role !== "admin") redirect("/dashboard"); if (session.user.role !== "admin") redirect("/dashboard");
return ( return <AdminShell userName={session.user.name}>{children}</AdminShell>;
<div className="min-h-screen flex">
{/* Sidebar */}
<aside
className="w-52 flex flex-col shrink-0 fixed h-full z-10"
style={{ backgroundColor: "var(--sidebar-bg)", color: "var(--sidebar-text)" }}
>
{/* Logo */}
<div
className="px-5 py-5"
style={{ borderBottom: "2px solid var(--sidebar-border)" }}
>
<p className="font-bold text-base tracking-wide" style={{ color: "#E8F0D8" }}>
Second Brain
</p>
<p className="text-xs mt-0.5 uppercase tracking-widest" style={{ color: "var(--sidebar-text)", fontSize: "0.6rem" }}>
Администратор
</p>
</div>
{/* Navigation */}
<nav className="flex-1 px-2 py-4 space-y-0.5 overflow-y-auto">
<AdminNav />
</nav>
{/* User info */}
<div
className="px-4 py-4"
style={{ borderTop: "2px solid var(--sidebar-border)" }}
>
<p className="text-xs mb-3 truncate" style={{ color: "var(--sidebar-text)" }}>
{session.user.name}
</p>
<LogoutButton />
</div>
</aside>
{/* Main content */}
<div className="ml-52 flex-1 min-h-screen" style={{ backgroundColor: "var(--background)" }}>
{children}
</div>
</div>
);
} }
+3 -2
View File
@@ -3,15 +3,16 @@ import { auth } from "@/lib/auth";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
import Link from "next/link"; import Link from "next/link";
import { LogoutButton } from "@/components/layout/logout-button"; import { LogoutButton } from "@/components/layout/logout-button";
import { AdminShell } from "@/components/admin/admin-shell";
export default async function CuratorLayout({ children }: { children: React.ReactNode }) { export default async function CuratorLayout({ children }: { children: React.ReactNode }) {
const session = await auth.api.getSession({ headers: await headers() }); const session = await auth.api.getSession({ headers: await headers() });
if (!session) redirect("/login"); if (!session) redirect("/login");
if (session.user.role !== "curator" && session.user.role !== "admin") redirect("/dashboard"); if (session.user.role !== "curator" && session.user.role !== "admin") redirect("/dashboard");
// Admin uses their own layout — render content only // Admin uses the admin shell with sidebar
if (session.user.role === "admin") { if (session.user.role === "admin") {
return <>{children}</>; return <AdminShell userName={session.user.name}>{children}</AdminShell>;
} }
return ( return (
+40
View File
@@ -0,0 +1,40 @@
import { AdminNav } from "@/components/admin/admin-nav";
import { LogoutButton } from "@/components/layout/logout-button";
export function AdminShell({
children,
userName,
}: {
children: React.ReactNode;
userName: string;
}) {
return (
<div className="min-h-screen flex">
<aside
className="w-52 flex flex-col shrink-0 fixed h-full z-10"
style={{ backgroundColor: "var(--sidebar-bg)", color: "var(--sidebar-text)" }}
>
<div className="px-5 py-5" style={{ borderBottom: "2px solid var(--sidebar-border)" }}>
<p className="font-bold text-base tracking-wide" style={{ color: "#E8F0D8" }}>
Second Brain
</p>
<p className="text-xs mt-0.5 uppercase tracking-widest" style={{ color: "var(--sidebar-text)", fontSize: "0.6rem" }}>
Администратор
</p>
</div>
<nav className="flex-1 px-2 py-4 space-y-0.5 overflow-y-auto">
<AdminNav />
</nav>
<div className="px-4 py-4" style={{ borderTop: "2px solid var(--sidebar-border)" }}>
<p className="text-xs mb-3 truncate" style={{ color: "var(--sidebar-text)" }}>
{userName}
</p>
<LogoutButton />
</div>
</aside>
<div className="ml-52 flex-1 min-h-screen" style={{ backgroundColor: "var(--background)" }}>
{children}
</div>
</div>
);
}