SPB Git

spb/autoscholar

Public
2.9 KB · 78 lines tsx
1import Link from "next/link";2import { redirect } from "next/navigation";3import type { ReactNode } from "react";4import { ThemeToggle } from "@/components/ThemeToggle";5import { currentSession } from "@/lib/server/session";6import { AdminNav } from "./AdminNav";7import { LogoutButton } from "./LogoutButton";89export const NAV: Array<[string, string, string]> = [10  ["/admin", "Overview", "⌂"],11  ["/admin/new", "New research", "+"],12  ["/admin/projects", "Projects", "▤"],13  ["/admin/runs", "Runs", "▶"],14  ["/admin/maclustr", "MacLustr", "◧"],15  ["/admin/manuscripts", "Manuscripts", "¶"],16  ["/admin/quality", "Quality", "✓"],17  ["/admin/publications", "Publications", "⊕"],18  ["/admin/templates", "Templates", "≡"],19  ["/admin/settings", "Settings & security", "⚙"],20];2122export default async function ConsoleLayout({ children }: { children: ReactNode }) {23  const sess = await currentSession();24  if (!sess) redirect("/admin/login");25  if (sess.mustChangePassword) redirect("/admin/change-password");26  return (27    <div className="min-h-dvh md:grid md:grid-cols-[15rem_1fr]">28      <a href="#admin-main" className="skip-link">29        Skip to content30      </a>31      <aside32        className="sticky top-0 z-30 border-b hairline md:h-dvh md:overflow-y-auto md:border-r md:border-b-0"33        style={{ background: "var(--bg-muted)", paddingTop: "var(--safe-t)" }}34      >35        <div className="flex items-center justify-between gap-2 px-4 py-3">36          <Link href="/admin" className="flex items-center gap-2 no-underline">37            <span38              aria-hidden="true"39              className="grid h-7 w-7 place-items-center rounded-md text-[11px] font-semibold"40              style={{ background: "var(--fg)", color: "var(--bg)", fontFamily: "var(--font-serif)" }}41            >42              As43            </span>44            <span className="serif font-medium">45              AutoScholar <span className="subtle text-xs font-normal">admin</span>46            </span>47          </Link>48          <div className="flex items-center gap-1">49            <ThemeToggle />50            <AdminNav items={NAV.map(([href, label]) => [href, label])} mobileOnly />51          </div>52        </div>53        <div className="hidden md:block">54          <AdminNav items={NAV.map(([href, label]) => [href, label])} />55          <div className="muted mt-4 border-t px-4 py-4 text-xs hairline">56            Signed in as <strong>{sess.username}</strong>57            <div className="mt-2">58              <LogoutButton />59            </div>60            <div className="mt-3">61              <Link href="/" className="text-xs">62                ← Public site63              </Link>64            </div>65          </div>66        </div>67      </aside>68      <main69        id="admin-main"70        className="min-w-0 px-4 py-6 sm:px-6 lg:px-8"71        style={{ paddingBottom: "calc(1.5rem + var(--safe-b))" }}72      >73        {children}74      </main>75    </div>76  );77}78
Files · main
Menu

Theme