chore: enhance sidebar navigation and localization features
- Refactor the `SidebarMain` component to improve active link detection and enhance user experience with collapsible menus. - Introduce `useLocalePathname` for better path management and implement functions to check active states for sidebar items. - Update `SidebarUser` component layout for improved readability and consistency in locale display. - Replace `UserIcon` with `User2Icon` in the `UserAvatar` component for a more modern appearance.
This commit is contained in:
parent
f7e5297589
commit
03f00c7d37
@ -7,7 +7,6 @@ import {
|
||||
} from '@/components/ui/collapsible';
|
||||
import {
|
||||
SidebarGroup,
|
||||
SidebarGroupLabel,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
@ -16,27 +15,41 @@ import {
|
||||
SidebarMenuSubItem
|
||||
} from '@/components/ui/sidebar';
|
||||
import { getSidebarMainLinks } from '@/config';
|
||||
import { LocaleLink } from '@/i18n/navigation';
|
||||
import { LocaleLink, useLocalePathname } from '@/i18n/navigation';
|
||||
import { createTranslator } from '@/i18n/translator';
|
||||
import { MenuItem } from '@/types';
|
||||
import { ChevronRight } from 'lucide-react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import * as React from 'react';
|
||||
|
||||
export function SidebarMain() {
|
||||
const t = useTranslations();
|
||||
const translator = createTranslator(t);
|
||||
const sidebarMainLinks = getSidebarMainLinks(translator);
|
||||
const pathname = useLocalePathname();
|
||||
|
||||
// Function to check if a path is active
|
||||
const isActive = (href: string | undefined): boolean => {
|
||||
if (!href) return false;
|
||||
return pathname === href || pathname.startsWith(href + '/');
|
||||
};
|
||||
|
||||
// Function to check if any sub-item in a collapsible menu is active
|
||||
const hasActiveChild = (items: MenuItem[]): boolean => {
|
||||
if (!items?.length) return false;
|
||||
return items.some(item => isActive(item.href));
|
||||
};
|
||||
|
||||
return (
|
||||
<SidebarGroup>
|
||||
{/* <SidebarGroupLabel>Platform</SidebarGroupLabel> */}
|
||||
<SidebarMenu>
|
||||
{sidebarMainLinks.map((item) => (
|
||||
<>
|
||||
<React.Fragment key={item.title}>
|
||||
{item.items?.length ? (
|
||||
<Collapsible
|
||||
key={item.title}
|
||||
asChild
|
||||
defaultOpen={false}
|
||||
defaultOpen={hasActiveChild(item.items)}
|
||||
className="group/collapsible"
|
||||
>
|
||||
<SidebarMenuItem>
|
||||
@ -53,7 +66,10 @@ export function SidebarMain() {
|
||||
<SidebarMenuSub>
|
||||
{item.items?.map((subItem) => (
|
||||
<SidebarMenuSubItem key={subItem.title}>
|
||||
<SidebarMenuSubButton asChild>
|
||||
<SidebarMenuSubButton
|
||||
asChild
|
||||
isActive={isActive(subItem.href)}
|
||||
>
|
||||
<LocaleLink href={subItem.href || ''}>
|
||||
{subItem.icon ? subItem.icon : null}
|
||||
<span>{subItem.title}</span>
|
||||
@ -67,16 +83,19 @@ export function SidebarMain() {
|
||||
</Collapsible>
|
||||
) : (
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton asChild tooltip={item.title}>
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
tooltip={item.title}
|
||||
isActive={isActive(item.href)}
|
||||
>
|
||||
<LocaleLink href={item.href || ''}>
|
||||
{item.icon ? item.icon : null}
|
||||
<span>{item.title}</span>
|
||||
</LocaleLink>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
)
|
||||
}
|
||||
</>
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
</SidebarGroup>
|
||||
|
||||
@ -175,8 +175,12 @@ export function SidebarUser() {
|
||||
onClick={() => setLocale(localeOption)}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
<span className="mr-2 text-md">{LOCALE_LIST[localeOption].flag}</span>
|
||||
<span className="text-sm">{LOCALE_LIST[localeOption].name}</span>
|
||||
<span className="mr-2 text-md">
|
||||
{LOCALE_LIST[localeOption].flag}
|
||||
</span>
|
||||
<span className="text-sm">
|
||||
{LOCALE_LIST[localeOption].name}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuSubContent>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
||||
import type { AvatarProps } from '@radix-ui/react-avatar';
|
||||
import { UserIcon } from 'lucide-react';
|
||||
import { User2Icon } from 'lucide-react';
|
||||
|
||||
interface UserAvatarProps extends AvatarProps {
|
||||
name?: string;
|
||||
@ -25,8 +25,8 @@ export function UserAvatar({ name, image, ...props }: UserAvatarProps) {
|
||||
/>
|
||||
<AvatarFallback>
|
||||
<span className="sr-only">{name}</span>
|
||||
<UserIcon className="size-4" />
|
||||
{/* {getInitials(name)} */}
|
||||
<User2Icon className="size-4" />
|
||||
{/* {getInitials(name || '')} */}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user