feat: improve docs layout

This commit is contained in:
Oleg Proskurin 2025-10-21 20:56:35 +07:00
parent 813e0b186c
commit da33f96c35
5 changed files with 162 additions and 108 deletions

View File

@ -4,16 +4,12 @@
* API Reference: Text to Image
*
* Refactored to use block components from @/components/docs/blocks
* Demonstrates API documentation patterns with semantic components
* Layout (SubsectionNav, DocsSidebar, Breadcrumb, TOC) handled by parent layout.tsx
* This page only provides TOC items and content.
*/
import { DocsLayout } from '@/components/docs/layout/DocsLayout';
import { DocsSidebar } from '@/components/docs/layout/DocsSidebar';
import { DocsTOC } from '@/components/docs/layout/DocsTOC';
import { SubsectionNav } from '@/components/shared/SubsectionNav';
import { TipBox } from '@/components/docs/shared/TipBox';
import { Table } from '@/components/docs/shared/Table';
import { Breadcrumb } from '@/components/docs/shared/Breadcrumb';
import { CodeBlock } from '@/components/docs/shared/CodeBlock';
import { InteractiveAPIWidget } from '@/components/docs/blocks/InteractiveAPIWidget';
import {
@ -24,6 +20,7 @@ import {
LinkCard,
LinkCardGrid,
} from '@/components/docs/blocks';
import { TocProvider } from '@/contexts/TocContext';
const tocItems = [
{ id: 'overview', text: 'Overview', level: 2 },
@ -35,12 +32,6 @@ const tocItems = [
{ id: 'next-steps', text: 'Next Steps', level: 2 },
];
const navItems = [
{ label: 'Documentation', href: '/docs' },
{ label: 'Demo', href: '/demo' },
{ label: 'Examples', href: '/docs/examples' },
];
const parameters = [
{ name: 'prompt', type: 'string', required: true, description: 'Text description of the image to generate' },
{ name: 'filename', type: 'string', required: false, description: 'Output filename (without extension)' },
@ -50,25 +41,7 @@ const parameters = [
export default function TextToImageAPIPage() {
return (
<>
{/* Subsection Navigation with API Key Input */}
<SubsectionNav
items={navItems}
currentPath="/docs/api/text-to-image"
showApiKeyInput={true}
/>
<DocsLayout
sidebar={<DocsSidebar currentPath="/docs/api/text-to-image" />}
toc={<DocsTOC items={tocItems} />}
>
<Breadcrumb
items={[
{ label: 'Documentation', href: '/docs' },
{ label: 'API Reference', href: '/docs/api' },
{ label: 'Text to Image' },
]}
/>
<TocProvider tocItems={tocItems}>
{/* Hero Section */}
<Hero
@ -247,7 +220,6 @@ export default function TextToImageAPIPage() {
/>
</LinkCardGrid>
</section>
</DocsLayout>
</>
</TocProvider>
);
}

View File

@ -1,23 +1,15 @@
'use client';
/**
* Authentication Guide - Final Variant
* Authentication Guide
*
* Features:
* - SubsectionNav at top
* - Prominent TipBox for security warnings
* - Compact TipBox for general tips
* - Enhanced tables for rate limits and key types
* - Simplified Next Steps
* Refactored to use block components from @/components/docs/blocks
* Layout (SubsectionNav, DocsSidebar, Breadcrumb, TOC) handled by parent layout.tsx
* This page only provides TOC items and content.
*/
import { DocsLayout } from '@/components/docs/layout/DocsLayout';
import { DocsSidebar } from '@/components/docs/layout/DocsSidebar';
import { DocsTOC } from '@/components/docs/layout/DocsTOC';
import { SubsectionNav } from '@/components/shared/SubsectionNav';
import { TipBox } from '@/components/docs/shared/TipBox';
import { Table } from '@/components/docs/shared/Table';
import { Breadcrumb } from '@/components/docs/shared/Breadcrumb';
import { CodeBlock } from '@/components/docs/shared/CodeBlock';
import {
Hero,
@ -26,6 +18,7 @@ import {
LinkCard,
LinkCardGrid,
} from '@/components/docs/blocks';
import { TocProvider } from '@/contexts/TocContext';
const tocItems = [
{ id: 'overview', text: 'Overview', level: 2 },
@ -38,34 +31,9 @@ const tocItems = [
{ id: 'next-steps', text: 'Next Steps', level: 2 },
];
const navItems = [
{ label: 'Documentation', href: '/docs' },
{ label: 'Demo', href: '/demo' },
{ label: 'Examples', href: '/docs/examples' },
];
export default function AuthenticationGuidePage() {
return (
<>
{/* Subsection Navigation */}
<SubsectionNav
items={navItems}
currentPath="/docs/guides/authentication"
ctaText="Join Beta"
ctaHref="/signup"
/>
<DocsLayout
sidebar={<DocsSidebar currentPath="/docs/guides/authentication" />}
toc={<DocsTOC items={tocItems} />}
>
<Breadcrumb
items={[
{ label: 'Documentation', href: '/docs' },
{ label: 'Guides', href: '/docs/guides' },
{ label: 'Authentication' },
]}
/>
<TocProvider tocItems={tocItems}>
{/* Hero Section */}
<Hero
@ -339,7 +307,6 @@ curl -X DELETE https://api.banatie.com/api/admin/keys/OLD_KEY_ID \\
/>
</LinkCardGrid>
</section>
</DocsLayout>
</>
</TocProvider>
);
}

View File

@ -1,22 +1,78 @@
'use client';
import { ReactNode } from 'react';
import { usePathname } from 'next/navigation';
import { SubsectionNav } from '@/components/shared/SubsectionNav';
import { DocsSidebar } from '@/components/docs/layout/DocsSidebar';
import { DocsTOC } from '@/components/docs/layout/DocsTOC';
import { Breadcrumb } from '@/components/docs/shared/Breadcrumb';
import { useToc } from '@/contexts/TocContext';
/**
* Root Documentation Layout
*
* Simple wrapper for all documentation pages.
* Each variant handles its own layout/navigation.
* Centralized layout for all documentation pages providing:
* - SubsectionNav at the top
* - Three-column layout (sidebar, content, TOC)
* - Automatic breadcrumb generation
* - Consistent background and styling
*
* Pages only need to:
* 1. Wrap content with <TocProvider tocItems={...}>
* 2. Provide their content
*
* Features:
* - Consistent background gradient matching landing page
* - No navigation/sidebars at this level
* - Children render their own layouts
* - Animated gradient background matching landing page
* - Automatic active page detection via pathname
* - Auto-generated breadcrumbs from URL structure
* - Responsive layout (mobile tablet desktop)
*/
interface DocsRootLayoutProps {
children: ReactNode;
}
const navItems = [
{ label: 'Documentation', href: '/docs' },
{ label: 'Demo', href: '/demo' },
{ label: 'Examples', href: '/docs/examples' },
];
// Generate breadcrumb items from pathname
const getBreadcrumbItems = (pathname: string): { label: string; href?: string }[] => {
const segments = pathname.split('/').filter(Boolean);
if (segments.length === 1 && segments[0] === 'docs') {
return [
{ label: 'Documentation', href: '/docs' },
{ label: 'Getting Started' },
];
}
const items: { label: string; href?: string }[] = [
{ label: 'Documentation', href: '/docs' },
];
if (segments.includes('guides')) {
items.push({ label: 'Guides', href: '/docs/guides' });
if (segments.includes('authentication')) {
items.push({ label: 'Authentication' });
}
} else if (segments.includes('api')) {
items.push({ label: 'API Reference', href: '/docs/api' });
if (segments.includes('text-to-image')) {
items.push({ label: 'Text to Image' });
}
}
return items;
};
export default function DocsRootLayout({ children }: DocsRootLayoutProps) {
const pathname = usePathname();
const { tocItems } = useToc();
const breadcrumbItems = getBreadcrumbItems(pathname);
return (
<div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950">
{/* Animated gradient background (matching landing page) */}
@ -25,8 +81,37 @@ export default function DocsRootLayout({ children }: DocsRootLayoutProps) {
<div className="absolute bottom-1/4 -right-1/4 w-96 h-96 bg-cyan-600/10 rounded-full blur-3xl animate-pulse delay-700"></div>
</div>
{/* Content */}
<div className="relative z-10">{children}</div>
{/* Subsection Navigation */}
<SubsectionNav
items={navItems}
currentPath={pathname}
ctaText="Join Beta"
ctaHref="/signup"
/>
{/* Three-column Documentation Layout */}
<div className="relative z-10 flex">
{/* Left Sidebar - Thin, minimal design */}
<aside className="hidden lg:block w-64 border-r border-white/10 bg-slate-950/50 backdrop-blur-sm sticky top-12 h-[calc(100vh-3rem)] overflow-y-auto">
<DocsSidebar currentPath={pathname} />
</aside>
{/* Main Content Area - Wide margins for comfortable reading */}
<main className="flex-1 min-w-0">
<div className="max-w-3xl mx-auto px-6 lg:px-12 py-12">
{/* Breadcrumb */}
<Breadcrumb items={breadcrumbItems} />
{/* Page Content */}
{children}
</div>
</main>
{/* Right TOC - Subtle and unobtrusive */}
<aside className="hidden xl:block w-56 border-l border-white/10 bg-slate-950/30 backdrop-blur-sm sticky top-12 h-[calc(100vh-3rem)] overflow-y-auto">
<DocsTOC items={tocItems} />
</aside>
</div>
</div>
);
}

View File

@ -4,16 +4,12 @@
* Getting Started Page - Production Documentation
*
* Refactored to use block components from @/components/docs/blocks
* Demonstrates composition of reusable semantic components
* Layout (SubsectionNav, DocsSidebar, Breadcrumb, TOC) handled by parent layout.tsx
* This page only provides TOC items and content.
*/
import { DocsLayout } from '@/components/docs/layout/DocsLayout';
import { DocsSidebar } from '@/components/docs/layout/DocsSidebar';
import { DocsTOC } from '@/components/docs/layout/DocsTOC';
import { SubsectionNav } from '@/components/shared/SubsectionNav';
import { TipBox } from '@/components/docs/shared/TipBox';
import { CodeBlock } from '@/components/docs/shared/CodeBlock';
import { Breadcrumb } from '@/components/docs/shared/Breadcrumb';
import {
Hero,
SectionHeader,
@ -21,6 +17,7 @@ import {
LinkCard,
LinkCardGrid,
} from '@/components/docs/blocks';
import { TocProvider } from '@/contexts/TocContext';
const tocItems = [
{ id: 'introduction', text: 'Introduction', level: 2 },
@ -31,28 +28,9 @@ const tocItems = [
{ id: 'next-steps', text: 'Next Steps', level: 2 },
];
const navItems = [
{ label: 'Documentation', href: '/docs' },
{ label: 'Demo', href: '/demo' },
{ label: 'Examples', href: '/docs/examples' },
];
export default function GettingStartedPage() {
return (
<>
{/* Subsection Navigation */}
<SubsectionNav
items={navItems}
currentPath="/docs"
ctaText="Join Beta"
ctaHref="/signup"
/>
<DocsLayout
sidebar={<DocsSidebar currentPath="/docs" />}
toc={<DocsTOC items={tocItems} />}
>
<Breadcrumb items={[{ label: 'Documentation', href: '/docs' }, { label: 'Getting Started' }]} />
<TocProvider tocItems={tocItems}>
{/* Hero Section */}
<Hero
@ -214,7 +192,6 @@ export BANATIE_API_KEY="bnt_your_key_here"`}
/>
</LinkCardGrid>
</section>
</DocsLayout>
</>
</TocProvider>
);
}

View File

@ -0,0 +1,53 @@
'use client';
/**
* Table of Contents Context
*
* Allows documentation pages to pass their TOC items up to the layout
* so the layout can render the TOC in the right sidebar.
*
* Usage in pages:
* ```tsx
* <TocProvider tocItems={[...]}>
* <page content>
* </TocProvider>
* ```
*
* Usage in layout:
* ```tsx
* const { tocItems } = useToc();
* return <DocsTOC items={tocItems} />;
* ```
*/
import { createContext, useContext, ReactNode } from 'react';
export interface TocItem {
id: string;
text: string;
level: number;
}
interface TocContextValue {
tocItems: TocItem[];
}
const TocContext = createContext<TocContextValue | undefined>(undefined);
interface TocProviderProps {
tocItems: TocItem[];
children: ReactNode;
}
export const TocProvider = ({ tocItems, children }: TocProviderProps) => {
return <TocContext.Provider value={{ tocItems }}>{children}</TocContext.Provider>;
};
export const useToc = (): TocContextValue => {
const context = useContext(TocContext);
if (!context) {
// Return empty array if no provider (allows layout to work without TOC)
return { tocItems: [] };
}
return context;
};