Files
IdP/apps/docs/components/docs-shell.tsx
2026-06-25 13:51:53 +03:00

110 lines
4.1 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { BookOpen, ExternalLink, Moon, Sun } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { usePublicSettings } from '@/providers/public-settings-provider';
import { useTheme } from '@/providers/theme-provider';
import { getApiBaseUrl } from '@/lib/api';
import { cn } from '@/lib/utils';
export function DocsHeader() {
const { projectName } = usePublicSettings();
const { resolvedTheme, setTheme } = useTheme();
const apiUrl = getApiBaseUrl();
return (
<header className="sticky top-0 z-50 w-full border-b border-zinc-200 bg-white/80 backdrop-blur dark:border-zinc-800 dark:bg-zinc-950/80">
<div className="mx-auto flex h-14 max-w-screen-2xl items-center justify-between gap-4 px-4 lg:px-8">
<Link href="/docs" className="flex items-center gap-2 font-semibold tracking-tight">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-zinc-900 text-white dark:bg-zinc-50 dark:text-zinc-900">
<BookOpen className="h-4 w-4" />
</div>
<span className="hidden sm:inline">{projectName}</span>
<span className="text-zinc-400 font-normal hidden sm:inline">Docs</span>
</Link>
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm" asChild className="hidden md:inline-flex">
<a href={`${apiUrl}/docs`} target="_blank" rel="noreferrer">
Swagger
<ExternalLink className="h-3.5 w-3.5" />
</a>
</Button>
<Button
variant="outline"
size="icon"
aria-label="Переключить тему"
onClick={() => setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')}
>
{resolvedTheme === 'dark' ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
</Button>
</div>
</div>
</header>
);
}
export function DocsSidebar({ groups }: { groups: Array<[string, Array<{ slug: string; title: string }>]> }) {
const pathname = usePathname();
return (
<nav className="space-y-6">
<Link
href="/docs"
className={cn(
'block rounded-lg px-3 py-2 text-sm font-medium transition-colors',
pathname === '/docs'
? 'bg-zinc-100 text-zinc-900 dark:bg-zinc-800 dark:text-zinc-50'
: 'text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-900 dark:hover:text-zinc-50'
)}
>
Главная
</Link>
{groups.map(([group, items]) => (
<div key={group}>
<p className="mb-2 px-2 text-xs font-semibold uppercase tracking-wider text-zinc-500">{group}</p>
<div className="space-y-1">
{items.map((item) => {
const href = `/docs/${item.slug}`;
const active = pathname === href;
return (
<Link
key={item.slug}
href={href}
className={cn(
'block rounded-lg px-3 py-2 text-sm transition-colors',
active
? 'bg-zinc-100 font-medium text-zinc-900 dark:bg-zinc-800 dark:text-zinc-50'
: 'text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-900 dark:hover:text-zinc-50'
)}
>
{item.title}
</Link>
);
})}
</div>
</div>
))}
</nav>
);
}
export function DocsToc({ sections }: { sections: Array<{ id: string; title: string }> }) {
return (
<nav className="space-y-2 text-sm">
<p className="mb-3 font-semibold">На этой странице</p>
{sections.map((section) => (
<a
key={section.id}
href={`#${section.id}`}
className="block text-zinc-500 transition-colors hover:text-zinc-900 dark:hover:text-zinc-50"
>
{section.title}
</a>
))}
</nav>
);
}