Untitled
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