feat(i18n): localize shell and common UI
This commit is contained in:
@@ -22,60 +22,84 @@ import {
|
||||
SidebarMenuItem,
|
||||
} from "@/components/ui/sidebar"
|
||||
import type { UserRole } from "@/generated/prisma/client"
|
||||
import type { Dictionary } from "@/i18n/dictionaries"
|
||||
|
||||
import { SidebarSection } from "./sidebar/sidebarSection"
|
||||
|
||||
const items = [
|
||||
type SidebarCopy = Dictionary["layout"]["sidebar"]
|
||||
|
||||
type SidebarLabelKey = keyof SidebarCopy
|
||||
|
||||
type SidebarItem =
|
||||
| {
|
||||
type: "item"
|
||||
labelKey: SidebarLabelKey
|
||||
url: string
|
||||
icon: React.ElementType
|
||||
}
|
||||
| {
|
||||
type: "section"
|
||||
labelKey: SidebarLabelKey
|
||||
url: string
|
||||
icon: React.ElementType
|
||||
items: { labelKey: SidebarLabelKey; url: string }[]
|
||||
}
|
||||
|
||||
const items: SidebarItem[] = [
|
||||
{
|
||||
type: "item",
|
||||
title: "Home",
|
||||
labelKey: "home",
|
||||
url: "/",
|
||||
icon: Home,
|
||||
},
|
||||
{
|
||||
type: "section",
|
||||
title: "Inventory",
|
||||
labelKey: "inventory",
|
||||
url: "#",
|
||||
icon: Package,
|
||||
items: [
|
||||
{
|
||||
title: "Items",
|
||||
labelKey: "items",
|
||||
url: "/inventory/items",
|
||||
},
|
||||
{
|
||||
title: "Categories",
|
||||
labelKey: "categories",
|
||||
url: "/inventory/categories",
|
||||
},
|
||||
{
|
||||
title: "Assets",
|
||||
labelKey: "assets",
|
||||
url: "/inventory/assets",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "item",
|
||||
title: "Recipients",
|
||||
labelKey: "recipients",
|
||||
url: "/recipients",
|
||||
icon: User,
|
||||
},
|
||||
{
|
||||
type: "item",
|
||||
title: "Movements",
|
||||
labelKey: "movements",
|
||||
url: "/movements",
|
||||
icon: BarChart,
|
||||
},
|
||||
{
|
||||
type: "item",
|
||||
title: "Assignments",
|
||||
labelKey: "assignments",
|
||||
url: "/assignments",
|
||||
icon: Clipboard,
|
||||
},
|
||||
]
|
||||
|
||||
export default function AppSidebar({
|
||||
copy,
|
||||
userRole,
|
||||
...props
|
||||
}: React.ComponentProps<typeof Sidebar> & { userRole?: UserRole }) {
|
||||
}: React.ComponentProps<typeof Sidebar> & {
|
||||
copy: SidebarCopy
|
||||
userRole?: UserRole
|
||||
}) {
|
||||
const pathname = usePathname()
|
||||
const visibleItems =
|
||||
userRole === "ADMIN"
|
||||
@@ -83,10 +107,10 @@ export default function AppSidebar({
|
||||
...items,
|
||||
{
|
||||
type: "item",
|
||||
title: "Users",
|
||||
labelKey: "users",
|
||||
url: "/admin/users",
|
||||
icon: Shield,
|
||||
},
|
||||
} satisfies SidebarItem,
|
||||
]
|
||||
: items
|
||||
|
||||
@@ -110,11 +134,11 @@ export default function AppSidebar({
|
||||
: pathname.startsWith(item.url)
|
||||
|
||||
return (
|
||||
<SidebarMenuItem key={`item-${item.title}`}>
|
||||
<SidebarMenuItem key={`item-${item.labelKey}`}>
|
||||
<SidebarMenuButton asChild isActive={isActive}>
|
||||
<Link href={item.url}>
|
||||
<item.icon className="mr-2 h-4 w-4" />
|
||||
<span>{item.title}</span>
|
||||
<span>{copy[item.labelKey]}</span>
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
@@ -123,10 +147,13 @@ export default function AppSidebar({
|
||||
if (item.type === "section") {
|
||||
return (
|
||||
<SidebarSection
|
||||
key={`section-${item.title}`}
|
||||
title={item.title}
|
||||
key={`section-${item.labelKey}`}
|
||||
title={copy[item.labelKey]}
|
||||
icon={item.icon}
|
||||
items={item.items}
|
||||
items={item.items.map((subItem) => ({
|
||||
title: copy[subItem.labelKey],
|
||||
url: subItem.url,
|
||||
}))}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user