Introduce DevBreadcrumbs component for navigation and replace headers in /dev pages with breadcrumb navigation. Adjust spacing for consistent layout.
This commit is contained in:
@@ -9,6 +9,7 @@ import { promises as fs } from 'fs';
|
||||
import path from 'path';
|
||||
import matter from 'gray-matter';
|
||||
import { MarkdownContent } from '@/components/docs/MarkdownContent';
|
||||
import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs';
|
||||
|
||||
interface DocPageProps {
|
||||
params: Promise<{ slug: string[] }>;
|
||||
@@ -56,11 +57,24 @@ export default async function DocPage({ params }: DocPageProps) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
// Extract title from first heading or use filename
|
||||
const title = doc.content.match(/^#\s+(.+)$/m)?.[1] || slug[slug.length - 1];
|
||||
|
||||
return (
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
<div className="bg-background">
|
||||
{/* Breadcrumbs */}
|
||||
<DevBreadcrumbs
|
||||
items={[
|
||||
{ label: 'Documentation', href: '/dev/docs' },
|
||||
{ label: title }
|
||||
]}
|
||||
/>
|
||||
|
||||
<div className="container mx-auto px-4 py-12">
|
||||
<div className="mx-auto max-w-4xl">
|
||||
<MarkdownContent content={doc.content} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { BookOpen, Sparkles, Layout, Palette, Code2, FileCode, Accessibility, Li
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs';
|
||||
|
||||
interface DocItem {
|
||||
title: string;
|
||||
@@ -98,8 +99,11 @@ const referencesDocs: DocItem[] = [
|
||||
export default function DocsHub() {
|
||||
return (
|
||||
<div className="bg-background">
|
||||
{/* Breadcrumbs */}
|
||||
<DevBreadcrumbs items={[{ label: 'Documentation' }]} />
|
||||
|
||||
{/* Hero Section */}
|
||||
<section className="border-b bg-gradient-to-b from-background to-muted/20 py-16">
|
||||
<section className="border-b bg-gradient-to-b from-background to-muted/20 py-12">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="mx-auto max-w-3xl text-center">
|
||||
<h2 className="text-4xl font-bold tracking-tight mb-4">
|
||||
|
||||
@@ -11,8 +11,9 @@ import Link from 'next/link';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { z } from 'zod';
|
||||
import { ArrowLeft, CheckCircle2, Loader2 } from 'lucide-react';
|
||||
import { CheckCircle2, Loader2 } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs';
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
@@ -94,26 +95,12 @@ export default function FormsPage() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Header */}
|
||||
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
||||
<div className="container mx-auto flex h-16 items-center gap-4 px-4">
|
||||
<Link href="/dev">
|
||||
<Button variant="ghost" size="icon" aria-label="Back to hub">
|
||||
<ArrowLeft className="h-5 w-5" />
|
||||
</Button>
|
||||
</Link>
|
||||
<div>
|
||||
<h1 className="text-xl font-bold">Form Patterns</h1>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
react-hook-form + Zod validation examples
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div className="bg-background">
|
||||
{/* Breadcrumbs */}
|
||||
<DevBreadcrumbs items={[{ label: 'Forms' }]} />
|
||||
|
||||
{/* Content */}
|
||||
<main className="container mx-auto px-4 py-8">
|
||||
<main className="container mx-auto px-4 py-12">
|
||||
<div className="space-y-12">
|
||||
{/* Introduction */}
|
||||
<div className="max-w-3xl space-y-4">
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import { ArrowLeft, Grid3x3 } from 'lucide-react';
|
||||
import { Grid3x3 } from 'lucide-react';
|
||||
import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
Card,
|
||||
@@ -26,26 +27,12 @@ export const metadata: Metadata = {
|
||||
|
||||
export default function LayoutsPage() {
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Header */}
|
||||
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
||||
<div className="container mx-auto flex h-16 items-center gap-4 px-4">
|
||||
<Link href="/dev">
|
||||
<Button variant="ghost" size="icon" aria-label="Back to hub">
|
||||
<ArrowLeft className="h-5 w-5" />
|
||||
</Button>
|
||||
</Link>
|
||||
<div>
|
||||
<h1 className="text-xl font-bold">Layout Patterns</h1>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Essential patterns for pages, dashboards, and forms
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div className="bg-background">
|
||||
{/* Breadcrumbs */}
|
||||
<DevBreadcrumbs items={[{ label: 'Layouts' }]} />
|
||||
|
||||
{/* Content */}
|
||||
<main className="container mx-auto px-4 py-8">
|
||||
<main className="container mx-auto px-4 py-12">
|
||||
<div className="space-y-12">
|
||||
{/* Introduction */}
|
||||
<div className="max-w-3xl space-y-4">
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
import type { Metadata } from 'next';
|
||||
import dynamic from 'next/dynamic';
|
||||
import Link from 'next/link';
|
||||
import { ArrowLeft, Ruler } from 'lucide-react';
|
||||
import { Ruler } from 'lucide-react';
|
||||
import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
Card,
|
||||
@@ -41,26 +42,12 @@ export const metadata: Metadata = {
|
||||
|
||||
export default function SpacingPage() {
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Header */}
|
||||
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
||||
<div className="container mx-auto flex h-16 items-center gap-4 px-4">
|
||||
<Link href="/dev">
|
||||
<Button variant="ghost" size="icon" aria-label="Back to hub">
|
||||
<ArrowLeft className="h-5 w-5" />
|
||||
</Button>
|
||||
</Link>
|
||||
<div>
|
||||
<h1 className="text-xl font-bold">Spacing Patterns</h1>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Parent-controlled spacing philosophy
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div className="bg-background">
|
||||
{/* Breadcrumbs */}
|
||||
<DevBreadcrumbs items={[{ label: 'Spacing' }]} />
|
||||
|
||||
{/* Content */}
|
||||
<main className="container mx-auto px-4 py-8">
|
||||
<main className="container mx-auto px-4 py-12">
|
||||
<div className="space-y-12">
|
||||
{/* Introduction */}
|
||||
<div className="max-w-3xl space-y-4">
|
||||
|
||||
@@ -67,6 +67,7 @@ import {
|
||||
TableRow,
|
||||
} from '@/components/ui/table';
|
||||
import { Example, ExampleGrid, ExampleSection } from './Example';
|
||||
import { DevBreadcrumbs } from './DevBreadcrumbs';
|
||||
|
||||
/**
|
||||
* Component showcase
|
||||
@@ -76,8 +77,11 @@ export function ComponentShowcase() {
|
||||
|
||||
return (
|
||||
<div className="bg-background">
|
||||
{/* Breadcrumbs */}
|
||||
<DevBreadcrumbs items={[{ label: 'Components' }]} />
|
||||
|
||||
{/* Content */}
|
||||
<main className="container mx-auto px-4 py-8">
|
||||
<main className="container mx-auto px-4 py-12">
|
||||
<div className="space-y-12">
|
||||
{/* Colors */}
|
||||
<ExampleSection
|
||||
|
||||
64
frontend/src/components/dev/DevBreadcrumbs.tsx
Normal file
64
frontend/src/components/dev/DevBreadcrumbs.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
/* istanbul ignore file */
|
||||
|
||||
/**
|
||||
* DevBreadcrumbs Component
|
||||
* Breadcrumb navigation for dev pages
|
||||
* This file is excluded from coverage as it's a development tool
|
||||
*/
|
||||
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { ChevronRight, Home } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
interface Breadcrumb {
|
||||
label: string;
|
||||
href?: string;
|
||||
}
|
||||
|
||||
interface DevBreadcrumbsProps {
|
||||
items: Breadcrumb[];
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function DevBreadcrumbs({ items, className }: DevBreadcrumbsProps) {
|
||||
return (
|
||||
<nav
|
||||
className={cn('bg-muted/30 border-b', className)}
|
||||
aria-label="Breadcrumb"
|
||||
>
|
||||
<div className="container mx-auto px-4 py-3">
|
||||
<ol className="flex items-center gap-2 text-sm">
|
||||
{/* Home link */}
|
||||
<li>
|
||||
<Link
|
||||
href="/dev"
|
||||
className="inline-flex items-center gap-1.5 text-muted-foreground hover:text-foreground transition-colors"
|
||||
>
|
||||
<Home className="h-4 w-4" />
|
||||
<span>Hub</span>
|
||||
</Link>
|
||||
</li>
|
||||
|
||||
{/* Breadcrumb items */}
|
||||
{items.map((item, index) => (
|
||||
<li key={index} className="flex items-center gap-2">
|
||||
<ChevronRight className="h-4 w-4 text-muted-foreground" />
|
||||
{item.href ? (
|
||||
<Link
|
||||
href={item.href}
|
||||
className="text-muted-foreground hover:text-foreground transition-colors"
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
) : (
|
||||
<span className="text-foreground font-medium">{item.label}</span>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user