Files
teatea-pension/modules/shared/components/AppBreadcrumbs.tsx

90 lines
3.0 KiB
TypeScript

"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { ChevronRight } from "lucide-react";
import { getWorkspaceHref, getWorkspacePathFromPathname, getWorkspaceSlugFromPathname } from "@/modules/shared/lib/workspace-routing";
type BreadcrumbItem = {
href?: string;
label: string;
};
const routeLabels: Record<string, string> = {
"/dashboard": "运营看板",
"/elders": "老人档案",
"/beds": "床位房间",
"/health": "健康照护",
"/care": "护理服务",
"/emergency": "安全应急",
"/devices": "设备运维",
"/notices": "公告通知",
"/alerts": "规则预警",
"/family": "家属服务",
"/settings/global": "全局配置",
"/settings/organizations": "机构管理",
"/settings/users": "用户管理",
"/settings/roles": "角色权限",
"/settings/health": "健康数据管理",
"/settings/audit": "审计日志",
"/settings/status": "运行状态",
};
function getBreadcrumbs(pathname: string): BreadcrumbItem[] {
const workspacePath = getWorkspacePathFromPathname(pathname);
const organizationSlug = getWorkspaceSlugFromPathname(pathname);
if (workspacePath === "/dashboard") {
return [{ label: "工作台" }];
}
if (workspacePath.startsWith("/settings/organizations/")) {
return [
{ href: getWorkspaceHref(organizationSlug, "/dashboard"), label: "工作台" },
{ href: getWorkspaceHref(organizationSlug, "/settings/users"), label: "管理系统" },
{ href: getWorkspaceHref(organizationSlug, "/settings/organizations"), label: "机构管理" },
{ label: "机构详情" },
];
}
if (workspacePath.startsWith("/settings")) {
return [
{ href: getWorkspaceHref(organizationSlug, "/dashboard"), label: "工作台" },
{ href: getWorkspaceHref(organizationSlug, "/settings/users"), label: "管理系统" },
{ label: routeLabels[workspacePath] ?? "设置" },
];
}
return [
{ href: getWorkspaceHref(organizationSlug, "/dashboard"), label: "工作台" },
{ label: routeLabels[workspacePath] ?? "工作区" },
];
}
export function AppBreadcrumbs(): React.ReactElement {
const pathname = usePathname();
const breadcrumbs = getBreadcrumbs(pathname);
return (
<nav aria-label="面包屑" className="flex min-w-0 items-center gap-1 text-sm">
{breadcrumbs.map((item, index) => {
const isLast = index === breadcrumbs.length - 1;
return (
<span className="flex min-w-0 items-center gap-1" key={`${item.label}-${index}`}>
{index > 0 ? <ChevronRight className="size-3.5 shrink-0 text-muted-foreground" aria-hidden="true" /> : null}
{item.href && !isLast ? (
<Link className="shrink-0 font-medium hover:text-primary" href={item.href}>
{item.label}
</Link>
) : (
<span className={isLast ? "min-w-0 truncate text-muted-foreground" : "shrink-0 font-medium"}>{item.label}</span>
)}
</span>
);
})}
</nav>
);
}