142 lines
4.7 KiB
TypeScript
142 lines
4.7 KiB
TypeScript
|
|
import { Button } from "@repo/shadcn-ui/components/button";
|
||
|
|
import {
|
||
|
|
Building2Icon,
|
||
|
|
ChevronRightIcon,
|
||
|
|
DatabaseIcon,
|
||
|
|
HomeIcon,
|
||
|
|
SettingsIcon,
|
||
|
|
TicketIcon,
|
||
|
|
WrenchIcon,
|
||
|
|
} from "@repo/shadcn-ui/lib/icons";
|
||
|
|
import type { ComponentProps } from "react";
|
||
|
|
import { useTranslation } from "react-i18next";
|
||
|
|
|
||
|
|
import type { WorkspaceContent } from "./workspace-content";
|
||
|
|
import type { WorkspaceLocation } from "./workspace-location";
|
||
|
|
export function WorkspaceSidebar({
|
||
|
|
companies,
|
||
|
|
current,
|
||
|
|
catalog,
|
||
|
|
onNavigate,
|
||
|
|
onSelectCompany,
|
||
|
|
onSelectCatalog,
|
||
|
|
onSettings,
|
||
|
|
}: {
|
||
|
|
companies: readonly { id: string; name: string }[];
|
||
|
|
onNavigate: (location: WorkspaceLocation) => void;
|
||
|
|
onSelectCompany: (id: string) => void;
|
||
|
|
current: WorkspaceLocation;
|
||
|
|
catalog: ComponentProps<typeof WorkspaceContent>["catalog"];
|
||
|
|
onSelectCatalog: (catalog: ComponentProps<typeof WorkspaceContent>["catalog"]) => void;
|
||
|
|
onSettings: () => void;
|
||
|
|
}) {
|
||
|
|
const { t } = useTranslation("companies");
|
||
|
|
const { t: coreTranslation } = useTranslation("core");
|
||
|
|
const { t: resourceTranslation } = useTranslation("resources");
|
||
|
|
const { t: assetTranslation } = useTranslation("assets");
|
||
|
|
const { t: accessTranslation } = useTranslation("access");
|
||
|
|
return (
|
||
|
|
<aside className="desk-sidebar">
|
||
|
|
<div className="desk-brand">
|
||
|
|
<svg aria-hidden="true" viewBox="0 0 36 30">
|
||
|
|
<path
|
||
|
|
d="M5 24 13 7l9 17 9-18"
|
||
|
|
fill="none"
|
||
|
|
stroke="currentColor"
|
||
|
|
strokeLinecap="round"
|
||
|
|
strokeLinejoin="round"
|
||
|
|
strokeWidth="7"
|
||
|
|
/>
|
||
|
|
</svg>
|
||
|
|
<span>Metis Desk</span>
|
||
|
|
</div>
|
||
|
|
<nav aria-label={t("companySpaces")} className="desk-company-rail">
|
||
|
|
{(
|
||
|
|
[
|
||
|
|
["home", "dashboard.title", HomeIcon],
|
||
|
|
["directory", "title", Building2Icon],
|
||
|
|
["catalogs", "shell.catalogs", DatabaseIcon],
|
||
|
|
["tickets", "shell.tickets", TicketIcon],
|
||
|
|
["interventions", "shell.interventions", WrenchIcon],
|
||
|
|
] as const
|
||
|
|
).map(([area, label, Icon]) => (
|
||
|
|
<Button
|
||
|
|
aria-label={t(label)}
|
||
|
|
aria-pressed={current.area === area}
|
||
|
|
className="desk-space-button"
|
||
|
|
key={area}
|
||
|
|
onClick={() => onNavigate({ area })}
|
||
|
|
variant="ghost"
|
||
|
|
>
|
||
|
|
<Icon aria-hidden="true" />
|
||
|
|
<span>{t(label)}</span>
|
||
|
|
{area === "catalogs" && (
|
||
|
|
<ChevronRightIcon aria-hidden="true" className="desk-nav-chevron" />
|
||
|
|
)}
|
||
|
|
</Button>
|
||
|
|
))}
|
||
|
|
{current.area === "catalogs" && (
|
||
|
|
<nav aria-label={t("globalCatalogs")} className="desk-catalog-navigation">
|
||
|
|
<>
|
||
|
|
<Button
|
||
|
|
aria-pressed={catalog === "access"}
|
||
|
|
onClick={() => onSelectCatalog("access")}
|
||
|
|
variant="ghost"
|
||
|
|
>
|
||
|
|
{accessTranslation("catalogTitle")}
|
||
|
|
</Button>
|
||
|
|
<Button
|
||
|
|
aria-pressed={catalog === "assets"}
|
||
|
|
onClick={() => onSelectCatalog("assets")}
|
||
|
|
variant="ghost"
|
||
|
|
>
|
||
|
|
{assetTranslation("title")}
|
||
|
|
</Button>
|
||
|
|
<Button
|
||
|
|
aria-pressed={catalog === "intervention-templates"}
|
||
|
|
onClick={() => onSelectCatalog("intervention-templates")}
|
||
|
|
variant="ghost"
|
||
|
|
>
|
||
|
|
{t("interventionTemplates.title")}
|
||
|
|
</Button>
|
||
|
|
<Button
|
||
|
|
aria-pressed={catalog === "brands"}
|
||
|
|
onClick={() => onSelectCatalog("brands")}
|
||
|
|
variant="ghost"
|
||
|
|
>
|
||
|
|
{assetTranslation("brands.title")}
|
||
|
|
</Button>
|
||
|
|
<Button
|
||
|
|
aria-pressed={catalog === "resources"}
|
||
|
|
onClick={() => onSelectCatalog("resources")}
|
||
|
|
variant="ghost"
|
||
|
|
>
|
||
|
|
{resourceTranslation("title")}
|
||
|
|
</Button>
|
||
|
|
</>
|
||
|
|
</nav>
|
||
|
|
)}
|
||
|
|
<Button className="desk-space-button" onClick={onSettings} variant="ghost">
|
||
|
|
<SettingsIcon aria-hidden="true" />
|
||
|
|
<span>{coreTranslation("shell.settings")}</span>
|
||
|
|
</Button>
|
||
|
|
<div className="desk-rail-separator" />
|
||
|
|
{companies.map((company) => (
|
||
|
|
<Button
|
||
|
|
aria-label={company.name}
|
||
|
|
aria-pressed={current.area === "company" && current.id === company.id}
|
||
|
|
className="desk-space-button"
|
||
|
|
key={company.id}
|
||
|
|
onClick={() => onSelectCompany(company.id)}
|
||
|
|
title={company.name}
|
||
|
|
variant="ghost"
|
||
|
|
>
|
||
|
|
<Building2Icon aria-hidden="true" />
|
||
|
|
<span>{company.name}</span>
|
||
|
|
</Button>
|
||
|
|
))}
|
||
|
|
</nav>
|
||
|
|
</aside>
|
||
|
|
);
|
||
|
|
}
|