sidebar layout change #2

This commit is contained in:
Oliver Kieselbach
2026-03-18 02:32:48 +01:00
parent 89c24f6152
commit fca0e5b21e
8 changed files with 56 additions and 38 deletions
@@ -267,9 +267,10 @@ export default function AdminConfigurationPage() {
return (
<ProtectedRoute requireGalacticAdmin>
<div className="min-h-screen bg-gray-50 dark:bg-gray-900">
<UnifiedSidebar items={adminSections} mode="scroll-spy" title="Admin">
{/* Header */}
<header className="bg-white dark:bg-gray-800 shadow dark:shadow-gray-700">
<div className="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<div className="py-6 px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between">
<div>
<button
@@ -288,8 +289,7 @@ export default function AdminConfigurationPage() {
</header>
{/* Main Content */}
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<UnifiedSidebar items={adminSections} mode="scroll-spy" title="Admin">
<main className="px-4 sm:px-6 lg:px-8 py-8">
<div className="space-y-6">
{/* Success Message */}
{successMessage && (
@@ -406,8 +406,8 @@ export default function AdminConfigurationPage() {
/>
</div>
</div>
</UnifiedSidebar>
</main>
</UnifiedSidebar>
</div>
</ProtectedRoute>
);
@@ -1,5 +1,6 @@
"use client";
import { useRouter } from "next/navigation";
import { UnifiedSidebar, SidebarItem } from "../../components/UnifiedSidebar";
import { NAV_SECTIONS } from "./docsNavSections";
import {
@@ -34,16 +35,35 @@ const docsItems: SidebarItem[] = NAV_SECTIONS.map((s) => ({
}));
export function DocsSidebar({ children }: { children: React.ReactNode }) {
const router = useRouter();
return (
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<UnifiedSidebar items={docsItems} mode="route" title="Contents">
<div className="space-y-8">
{children}
<div className="text-center text-sm text-gray-500 pb-4">
<p>Autopilot Monitor v1.0.0</p>
<UnifiedSidebar items={docsItems} mode="route" title="Contents">
{/* Page header */}
<header className="bg-white shadow-sm border-b border-gray-200 sticky top-14 z-10">
<div className="px-4 sm:px-6 lg:px-8 py-4">
<div className="flex items-center justify-between">
<button
onClick={() => router.back()}
className="flex items-center space-x-2 text-gray-600 hover:text-gray-900 transition-colors"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
<span>Back</span>
</button>
<h1 className="text-2xl font-bold text-blue-600">Documentation</h1>
</div>
</div>
</UnifiedSidebar>
</div>
</header>
{/* Content */}
<div className="px-4 sm:px-6 lg:px-8 py-8 space-y-8">
{children}
<div className="text-center text-sm text-gray-500 pb-4">
<p>Autopilot Monitor v1.0.0</p>
</div>
</div>
</UnifiedSidebar>
);
}
@@ -1,6 +1,5 @@
import type { Metadata } from "next";
import { PublicSiteNavbar } from "../../components/PublicSiteNavbar";
import { PublicPageHeader } from "../../components/PublicPageHeader";
import { DocsSidebar } from "./DocsSidebar";
export const metadata: Metadata = {
@@ -38,7 +37,6 @@ export default function DocsLayout({ children }: { children: React.ReactNode })
return (
<div className="min-h-screen bg-gray-50">
<PublicSiteNavbar showSectionLinks={false} />
<PublicPageHeader title="Documentation" />
<DocsSidebar>{children}</DocsSidebar>
</div>
);
@@ -737,9 +737,22 @@ export default function SessionDetailPage() {
return (
<ProtectedRoute>
<div className="min-h-screen bg-gray-50">
<UnifiedSidebar items={(() => {
const s: SidebarItem[] = [];
if (session) s.push({ id: "section-session-info", label: "Session Info", icon: <InformationCircleIcon /> });
if (!isGatherRulesSession) s.push({ id: "section-device-details", label: "Device Details", icon: <ComputerDesktopIcon /> });
if (!isGatherRulesSession && session) s.push({ id: "section-enrollment-progress", label: "Enrollment Progress", icon: <PlayCircleIcon /> });
if (!isGatherRulesSession) s.push({ id: "section-analysis", label: "Analysis", icon: <SparklesIcon /> });
if (!isGatherRulesSession) s.push({ id: "section-performance", label: "Performance", icon: <ChartBarIcon /> });
if (!isGatherRulesSession) s.push({ id: "section-scripts", label: "Script Executions", icon: <CodeBracketIcon /> });
if (!isGatherRulesSession) s.push({ id: "section-downloads", label: "Downloads", icon: <ArrowDownTrayIcon /> });
if (!isGatherRulesSession) s.push({ id: "section-install-progress", label: "Install Progress", icon: <ListBulletIcon /> });
s.push({ id: "section-event-timeline", label: "Event Timeline", icon: <ClockIcon /> });
return s;
})()} mode="scroll-spy" title="Sections">
{/* Header */}
<header className="bg-white shadow">
<div className="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8 flex items-center justify-between">
<div className="py-6 px-4 sm:px-6 lg:px-8 flex items-center justify-between">
<div>
<button
onClick={() => router.push('/dashboard')}
@@ -814,20 +827,7 @@ export default function SessionDetailPage() {
</div>
</header>
<UnifiedSidebar items={(() => {
const s: SidebarItem[] = [];
if (session) s.push({ id: "section-session-info", label: "Session Info", icon: <InformationCircleIcon /> });
if (!isGatherRulesSession) s.push({ id: "section-device-details", label: "Device Details", icon: <ComputerDesktopIcon /> });
if (!isGatherRulesSession && session) s.push({ id: "section-enrollment-progress", label: "Enrollment Progress", icon: <PlayCircleIcon /> });
if (!isGatherRulesSession) s.push({ id: "section-analysis", label: "Analysis", icon: <SparklesIcon /> });
if (!isGatherRulesSession) s.push({ id: "section-performance", label: "Performance", icon: <ChartBarIcon /> });
if (!isGatherRulesSession) s.push({ id: "section-scripts", label: "Script Executions", icon: <CodeBracketIcon /> });
if (!isGatherRulesSession) s.push({ id: "section-downloads", label: "Downloads", icon: <ArrowDownTrayIcon /> });
if (!isGatherRulesSession) s.push({ id: "section-install-progress", label: "Install Progress", icon: <ListBulletIcon /> });
s.push({ id: "section-event-timeline", label: "Event Timeline", icon: <ClockIcon /> });
return s;
})()} mode="scroll-spy" title="Sections">
<main className="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
<main className="py-6 px-4 sm:px-6 lg:px-8">
<div className="px-4 py-6 sm:px-0">
{/* Session Info Card */}
{session && (
@@ -943,9 +943,10 @@ export default function SettingsPage() {
return (
<ProtectedRoute>
<div className="min-h-screen bg-gray-50">
<UnifiedSidebar items={settingsSections} mode="scroll-spy" title="Settings">
{/* Header */}
<header className="bg-white shadow">
<div className="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<div className="py-6 px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between">
<div>
<button
@@ -982,14 +983,13 @@ export default function SettingsPage() {
</header>
{/* Main Content */}
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<main className="px-4 sm:px-6 lg:px-8 py-8">
{loading ? (
<div className="bg-white rounded-lg shadow p-8 text-center">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-indigo-600 mx-auto"></div>
<p className="mt-4 text-gray-600">Loading configuration...</p>
</div>
) : (
<UnifiedSidebar items={settingsSections} mode="scroll-spy" title="Settings">
<div className="space-y-6">
{/* Success Message */}
{successMessage && (
@@ -1217,9 +1217,9 @@ export default function SettingsPage() {
)}
</div>
</UnifiedSidebar>
)}
</main>
</UnifiedSidebar>
</div>
<UnsavedChangesModal
@@ -170,7 +170,7 @@ export default function Navbar() {
if (!isAdminOrOperator && !user?.isGalacticAdmin) {
return (
<nav className="bg-white border-b border-gray-200 shadow-sm sticky top-0 z-30">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-14">
<div className="flex items-center">
<Link href="/progress" className="flex items-center space-x-2.5">
@@ -22,7 +22,7 @@ interface UnifiedSidebarProps {
// Sidebar pixel widths
const SIDEBAR_PX: Record<CollapseState, number> = {
full: 208, // w-52
full: 224, // w-56
icons: 56, // w-14
hidden: 0,
};
@@ -120,7 +120,7 @@ export function UnifiedSidebar({
const activeLabel = items.find((i) => i.id === activeId)?.label ?? title;
const sidebarWidthClass: Record<CollapseState, string> = {
full: "w-52",
full: "w-56",
icons: "w-14",
hidden: "w-0",
};
@@ -318,7 +318,7 @@ export function UnifiedSidebar({
{/* ===== Desktop: chevron toggle — vertically centered at sidebar edge ===== */}
<button
onClick={collapseState === "hidden" ? () => setCollapseState("full") : cycleCollapseState}
className="hidden md:flex fixed z-20 top-1/2 -translate-y-1/2 items-center justify-center w-4 h-8 rounded-r-md text-gray-300 transition-all duration-200 hover:text-gray-500 dark:text-gray-600 dark:hover:text-gray-400"
className="hidden md:flex fixed z-20 top-1/2 -translate-y-1/2 items-center justify-center w-4 h-8 rounded-r-md bg-gray-100/80 text-gray-400 transition-all duration-200 hover:bg-gray-200 hover:text-gray-600 dark:bg-gray-700/60 dark:text-gray-500 dark:hover:bg-gray-600 dark:hover:text-gray-300"
style={{ left: SIDEBAR_PX[collapseState] }}
aria-label={collapseState === "hidden" ? "Show sidebar" : "Collapse sidebar"}
title={
File diff suppressed because one or more lines are too long