sidebar.tsx 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. 'use client';
  2. import Link from 'next/link';
  3. import { usePathname } from 'next/navigation';
  4. import { Image, ImagePlus, Sparkles, Settings, Activity, Edit3 } from 'lucide-react';
  5. import { cn } from '@/lib/utils';
  6. /**
  7. * Sidebar - Navigation component
  8. *
  9. * Modern architecture:
  10. * - Simple, focused component with single responsibility
  11. * - No complex positioning logic - handled by parent grid layout
  12. * - TypeScript interfaces for navigation items
  13. * - Proper semantic HTML
  14. */
  15. interface NavigationItem {
  16. name: string;
  17. href: string;
  18. icon: React.ComponentType<{ className?: string }>;
  19. }
  20. const navigation: NavigationItem[] = [
  21. { name: 'Text to Image', href: '/text2img', icon: ImagePlus },
  22. { name: 'Image to Image', href: '/img2img', icon: Image },
  23. { name: 'Inpainting', href: '/inpainting', icon: Edit3 },
  24. { name: 'Upscaler', href: '/upscaler', icon: Sparkles },
  25. { name: 'Models', href: '/models', icon: Settings },
  26. { name: 'Queue', href: '/queue', icon: Activity },
  27. ];
  28. export function Sidebar() {
  29. const pathname = usePathname();
  30. return (
  31. <div className="flex h-full flex-col gap-2">
  32. {/* Logo */}
  33. <div className="flex h-16 items-center border-b border-border px-6">
  34. <Link href="/" className="flex items-center gap-2 font-semibold">
  35. <ImagePlus className="h-6 w-6" />
  36. <span>SD REST UI</span>
  37. </Link>
  38. </div>
  39. {/* Navigation */}
  40. <nav className="flex-1 space-y-1 px-3 py-4">
  41. {navigation.map((item) => {
  42. const isActive = pathname === item.href || pathname?.startsWith(item.href + '/');
  43. return (
  44. <Link
  45. key={item.name}
  46. href={item.href}
  47. className={cn(
  48. 'flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-colors',
  49. isActive
  50. ? 'bg-primary text-primary-foreground'
  51. : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground'
  52. )}
  53. >
  54. <item.icon className="h-5 w-5" />
  55. {item.name}
  56. </Link>
  57. );
  58. })}
  59. </nav>
  60. {/* Footer */}
  61. <div className="border-t border-border p-4">
  62. <p className="text-xs text-muted-foreground text-center">
  63. Stable Diffusion REST API
  64. </p>
  65. </div>
  66. </div>
  67. );
  68. }