Untitled

 avatar
unknown
plain_text
a month ago
8.5 kB
4
Indexable
"use client"

import * as React from "react"
import { 
  Home, 
  Image, 
  Trophy, 
  BarChart, 
  HelpCircle, 
  Settings, 
  ArrowUpDown, 
  LineChart, 
  Grid, 
  Archive, 
  BookOpen, 
  Moon, 
  Sun, 
  Trash2 
} from 'lucide-react'
import { useTheme } from "next-themes"
import { useSettings } from "@/hooks/useSettings"
import { useTranslation, type SupportedLanguages } from "@/utils/translations"
import { usePathname } from "next/navigation"

import {
  Sidebar,
  SidebarContent,
  SidebarGroup,
  SidebarHeader,
  SidebarMenu,
  SidebarMenuItem,
  SidebarMenuButton,
  SidebarMenuSub,
  SidebarMenuSubItem,
  SidebarMenuSubButton,
  SidebarRail,
  SidebarSeparator
} from "@/components/ui/sidebar"
import { Button } from "@/components/ui/button"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"

export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
  const { theme } = useTheme()
  const { settings, updateSettings } = useSettings()
  const { t } = useTranslation(settings?.language as SupportedLanguages || 'EN')
  const pathname = usePathname()

  const navData = React.useMemo(() => ({
    navMain: [
      {
        title: t('navigation.home'),
        url: "/",
        icon: Home,
        isDirectLink: true,
      },
      {
        title: t('navigation.gallery'),
        url: "/gallery",
        icon: Image,
        isDirectLink: true,
      },
      {
        title: t('navigation.achievements'),
        url: "/achievements",
        icon: Trophy,
        isDirectLink: true,
      },
      {
        title: t('navigation.statistics'),
        url: "#",
        icon: BarChart,
        items: [
          {
            title: t('navigation.sorting'),
            url: "/sorting",
            icon: ArrowUpDown,
          },
          {
            title: t('navigation.impact'),
            url: "/impact",
            icon: LineChart,
          },
          {
            title: t('navigation.patterns'),
            url: "/patterns",
            icon: Grid,
          },
          {
            title: t('navigation.bins'),
            url: "/bins",
            icon: Archive,
          },
        ],
      },
      {
        title: t('navigation.help'),
        url: "#",
        icon: HelpCircle,
        items: [
          {
            title: t('navigation.guide'),
            url: "/guide",
            icon: BookOpen,
          },
        ],
      },
      {
        title: t('navigation.settings'),
        url: "#",
        icon: Settings,
        items: [
          {
            title: t('navigation.placeholder'),
            url: "#",
            icon: Settings,
          },
          {
            title: t('navigation.placeholder'),
            url: "#",
            icon: Settings,
          },
          {
            title: t('navigation.placeholder'),
            url: "#",
            icon: Settings,
          },
        ],
      },
    ],
  }), [t]);

  const handleThemeToggle = () => {
    const newDarkMode = theme === "light" ? 1 : 0;
    updateSettings({ dark_mode: newDarkMode });
  };

  const handleLanguageChange = (value: string) => {
    updateSettings({ language: value });
  };

  // Check if a menu item is active
  const isActive = (url: string) => {
    if (url === "/" && pathname === "/") return true;
    if (url !== "/" && pathname.startsWith(url)) return true;
    return false;
  };

  // Function to check if any sub-item in a section is active
  const isSectionActive = (items: Array<{ url: string }>) => {
    return items?.some(item => isActive(item.url));
  };

  return (
    <Sidebar {...props}>
      <SidebarHeader className="border-b p-4 mb-2">
        <div className="flex items-center gap-3 px-2">
          <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-600 text-white">
            <Trash2 className="h-6 w-6" />
          </div>
          <div className="flex flex-col">
            <span className="text-lg font-semibold text-sidebar-foreground">SortiMate</span>
            <span className="text-xs text-sidebar-foreground/60">
              {t('common.aiAssistant')}
            </span>
          </div>
        </div>
      </SidebarHeader>
      
      <SidebarContent className="px-1">
        <SidebarGroup>
          <SidebarMenu className="space-y-1">
            {navData.navMain.map((item, index) => (
              item.isDirectLink ? (
                <SidebarMenuItem key={item.title} className="my-1">
                  <SidebarMenuButton 
                    asChild
                    isActive={isActive(item.url)}
                    className={`group flex items-center py-2.5 ${isActive(item.url) ? 'bg-sidebar-accent/30 text-sidebar-foreground font-medium' : ''}`}
                  >
                    <a href={item.url} className="flex items-center w-full">
                      <item.icon className="h-5 w-5 mx-3" />
                      <span>{item.title}</span>
                    </a>
                  </SidebarMenuButton>
                </SidebarMenuItem>
              ) : (
                <React.Fragment key={item.title}>
                  <div className="group mt-1">
                    <SidebarMenuItem>
                      <SidebarMenuButton 
                        className={`flex items-center py-2.5 ${isSectionActive(item.items || []) ? 'text-sidebar-foreground font-medium' : 'text-sidebar-foreground/80'}`}
                      >
                        <item.icon className="h-5 w-5 mx-3" />
                        <span className="text-[15px]">{item.title}</span>
                      </SidebarMenuButton>
                    </SidebarMenuItem>
                    {item.items?.length ? (
                      <SidebarMenuSub className="mt-0.5 space-y-0.5">
                        {item.items.map((subItem) => (
                          <SidebarMenuSubItem key={subItem.title}>
                            <SidebarMenuSubButton
                              asChild
                              isActive={isActive(subItem.url)}
                              className={`py-2 ${isActive(subItem.url) ? 'bg-sidebar-accent/20 text-sidebar-foreground font-medium' : 'text-sidebar-foreground/70'}`}
                            >
                              <a href={subItem.url} className="flex items-center">
                                <subItem.icon className="h-4 w-4 mx-4" />
                                <span className="text-[14px]">{subItem.title}</span>
                              </a>
                            </SidebarMenuSubButton>
                          </SidebarMenuSubItem>
                        ))}
                      </SidebarMenuSub>
                    ) : null}
                  </div>
                  {index < navData.navMain.length - 1 && (
                    <SidebarSeparator className="my-2 opacity-20" />
                  )}
                </React.Fragment>
              )
            ))}
          </SidebarMenu>
        </SidebarGroup>
      </SidebarContent>

      <div className="mt-auto border-t border-sidebar-border/30 p-4 space-y-3">
        <Button
          variant="ghost"
          size="sm"
          className="w-full justify-between text-sidebar-foreground/90"
          onClick={handleThemeToggle}
        >
          <span className="text-sm">{t('common.theme')}</span>
          <div className="flex items-center">
            <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
            <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
          </div>
        </Button>

        <Select
          value={settings?.language || "DE"}
          onValueChange={handleLanguageChange}
        >
          <SelectTrigger className="w-full text-sidebar-foreground/90">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="EN">{t('common.english')}</SelectItem>
            <SelectItem value="DE">{t('common.german')}</SelectItem>
          </SelectContent>
        </Select>
      </div>

      <SidebarRail />
    </Sidebar>
  );
}
Editor is loading...
Leave a Comment