banatie-service/apps/landing/src/components/docs/final/DocsSidebarFinal.tsx

182 lines
5.8 KiB
TypeScript

'use client';
/**
* Documentation Sidebar - Final Variant
*
* Based on Variant A with FIXED active states
*
* Key Improvements:
* - Consistent active state styling for both parent and child items
* - Clean left border indicator (no background boxes)
* - Parent active: purple left border + white text
* - Child active: purple left border + white text (NO background)
*
* Features:
* - Thin sidebar with subtle hover states
* - Collapsible section groups
* - Minimal icons (chevron for expandable items)
* - Clean, uncluttered appearance
*
* Navigation Structure:
* - Getting Started
* - API Reference (collapsible)
* - Guides (collapsible)
* - Examples
*/
import { useState } from 'react';
interface NavItem {
label: string;
href: string;
icon?: string;
children?: NavItem[];
}
interface DocsSidebarFinalProps {
currentPath: string;
}
const navigationItems: NavItem[] = [
{
label: 'Getting Started',
href: '/docs/final',
icon: '🚀',
},
{
label: 'API Reference',
href: '/docs/final/api',
icon: '📚',
children: [
{ label: 'Text to Image', href: '/docs/final/api/text-to-image' },
{ label: 'Upload', href: '/docs/final/api/upload' },
{ label: 'Images', href: '/docs/final/api/images' },
],
},
{
label: 'Guides',
href: '/docs/final/guides',
icon: '📖',
children: [
{ label: 'Authentication', href: '/docs/final/guides/authentication' },
{ label: 'Error Handling', href: '/docs/final/guides/error-handling' },
{ label: 'Rate Limits', href: '/docs/final/guides/rate-limits' },
],
},
{
label: 'Examples',
href: '/docs/final/examples',
icon: '💡',
},
];
export const DocsSidebarFinal = ({ currentPath }: DocsSidebarFinalProps) => {
const [expandedSections, setExpandedSections] = useState<string[]>(['API Reference', 'Guides']);
const toggleSection = (label: string) => {
setExpandedSections((prev) =>
prev.includes(label) ? prev.filter((item) => item !== label) : [...prev, label]
);
};
const isActive = (href: string) => currentPath === href;
const isExpanded = (label: string) => expandedSections.includes(label);
return (
<nav className="p-6" aria-label="Documentation navigation">
{/* Logo/Title */}
<div className="mb-8">
<h2 className="text-lg font-semibold text-white">Documentation</h2>
<p className="text-xs text-gray-500 mt-1">Final: Production</p>
</div>
{/* Navigation Items */}
<ul className="space-y-1">
{navigationItems.map((item) => {
const hasChildren = item.children && item.children.length > 0;
const expanded = isExpanded(item.label);
const active = isActive(item.href);
return (
<li key={item.label}>
{/* Parent Item */}
<div className="relative">
{active && (
<div className="absolute left-0 top-0 bottom-0 w-0.5 bg-purple-500 rounded-r"></div>
)}
<a
href={item.href}
onClick={
hasChildren
? (e) => {
e.preventDefault();
toggleSection(item.label);
}
: undefined
}
className={`
flex items-center justify-between px-3 py-2 rounded-lg text-sm transition-colors
${active ? 'bg-purple-500/10 text-white font-medium' : 'text-gray-400 hover:text-white hover:bg-white/5'}
`}
>
<span className="flex items-center gap-2">
{item.icon && <span className="text-base">{item.icon}</span>}
<span>{item.label}</span>
</span>
{hasChildren && (
<svg
className={`w-4 h-4 transition-transform ${expanded ? 'rotate-90' : ''}`}
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
)}
</a>
</div>
{/* Children Items - FIXED ACTIVE STATE */}
{hasChildren && expanded && (
<ul className="ml-6 mt-1 space-y-1 border-l border-slate-800">
{item.children!.map((child) => {
const childActive = isActive(child.href);
return (
<li key={child.label}>
<a
href={child.href}
className={`
block px-3 py-1.5 text-sm rounded-lg transition-colors ml-[-2px]
${
childActive
? 'text-white font-medium border-l-2 border-purple-500 bg-transparent pl-4'
: 'text-gray-500 hover:text-gray-300 border-l-2 border-transparent pl-4'
}
`}
>
{child.label}
</a>
</li>
);
})}
</ul>
)}
</li>
);
})}
</ul>
{/* Bottom Links */}
<div className="mt-12 pt-6 border-t border-slate-800">
<ul className="space-y-2 text-sm">
<li>
<a href="/docs" className="text-gray-500 hover:text-gray-300 transition-colors">
Back to variants
</a>
</li>
</ul>
</div>
</nav>
);
};