sidebar.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. 'use client';
  2. import Link from 'next/link';
  3. import { usePathname } from 'next/navigation';
  4. import { Image, ImagePlus, Sparkles, Settings, Activity } 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: 'Upscaler', href: '/upscaler', icon: Sparkles },
  24. { name: 'Models', href: '/models', icon: Settings },
  25. { name: 'Queue', href: '/queue', icon: Activity },
  26. ];
  27. export function Sidebar() {
  28. const pathname = usePathname();
  29. return (
  30. <div className="flex h-full flex-col gap-2">
  31. {/* Logo */}
  32. <div className="flex h-16 items-center border-b border-border px-6">
  33. <Link href="/" className="flex items-center gap-2 font-semibold">
  34. <ImagePlus className="h-6 w-6" />
  35. <span>SD REST UI</span>
  36. </Link>
  37. </div>
  38. {/* Navigation */}
  39. <nav className="flex-1 space-y-1 px-3 py-4">
  40. {navigation.map((item) => {
  41. const isActive = pathname === item.href || pathname?.startsWith(item.href + '/');
  42. return (
  43. <Link
  44. key={item.name}
  45. href={item.href}
  46. className={cn(
  47. 'flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-colors',
  48. isActive
  49. ? 'bg-primary text-primary-foreground'
  50. : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground'
  51. )}
  52. >
  53. <item.icon className="h-5 w-5" />
  54. {item.name}
  55. </Link>
  56. );
  57. })}
  58. </nav>
  59. {/* Footer */}
  60. <div className="border-t border-border p-4">
  61. <p className="text-xs text-muted-foreground text-center">
  62. Stable Diffusion REST API
  63. </p>
  64. </div>
  65. </div>
  66. );
  67. }