feat(i18n): localize shell and common UI

This commit is contained in:
2026-06-11 17:54:56 +02:00
parent c3cf4182ad
commit 2fa6611719
15 changed files with 477 additions and 136 deletions
+44 -17
View File
@@ -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,
}))}
/>
)
}