fixers 10/22
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
|
||||
"use client"
|
||||
|
||||
import { Fragment } from "react"
|
||||
import Link from "next/link"
|
||||
import { usePathname } from "next/navigation"
|
||||
|
||||
import { Breadcrumb, BreadcrumbItem, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb"
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from "@/components/ui/breadcrumb"
|
||||
|
||||
// Per-segment display labels. Deliberately separate from Header.tsx's
|
||||
// titleFromPath (which resolves one *full* path to a page title) — a
|
||||
// breadcrumb needs a label per *segment*, including grouping segments that
|
||||
// have no page of their own (e.g. "receiving", "grn").
|
||||
const SEGMENT_LABELS: Record<string, string> = {
|
||||
dashboard: "Dashboard",
|
||||
products: "Items",
|
||||
@@ -48,55 +50,81 @@ const SEGMENT_LABELS: Record<string, string> = {
|
||||
"owner-report": "Day-End Owner Report",
|
||||
}
|
||||
|
||||
function labelFor(segment: string): string {
|
||||
if (SEGMENT_LABELS[segment]) return SEGMENT_LABELS[segment]
|
||||
if (/^[0-9]+$/.test(segment)) return `#${segment}`
|
||||
return segment.charAt(0).toUpperCase() + segment.slice(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Grouping paths with no page of their own (no page.tsx), mapped to where their menu lands — the
|
||||
* same `landingHref`s as the sidebar. Linking the raw path would 404. (HRM has its own hub page now.)
|
||||
*/
|
||||
const GROUP_LANDING: Record<string, string> = {
|
||||
"/dashboard/production": "/dashboard/production/runs",
|
||||
"/dashboard/receiving": "/dashboard/receiving/grn",
|
||||
"/dashboard/sales/bundles": "/dashboard/sales/bundles/templates",
|
||||
"/dashboard/sales/bundles":
|
||||
"/dashboard/sales/bundles/templates",
|
||||
"/dashboard/help/tickets": "/dashboard/help",
|
||||
}
|
||||
|
||||
const linkClass =
|
||||
"truncate transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-sm"
|
||||
function labelFor(segment: string): string {
|
||||
if (SEGMENT_LABELS[segment]) {
|
||||
return SEGMENT_LABELS[segment]
|
||||
}
|
||||
|
||||
if (/^[0-9]+$/.test(segment)) {
|
||||
return `#${segment}`
|
||||
}
|
||||
|
||||
return segment
|
||||
.split("-")
|
||||
.map(
|
||||
(word) =>
|
||||
word.charAt(0).toUpperCase() + word.slice(1)
|
||||
)
|
||||
.join(" ")
|
||||
}
|
||||
|
||||
export function Breadcrumbs() {
|
||||
const pathname = usePathname() || "/dashboard"
|
||||
const segments = pathname.split("/").filter(Boolean)
|
||||
|
||||
// Nothing to show above the dashboard root itself.
|
||||
if (segments.length <= 1) return null
|
||||
if (segments.length <= 1) {
|
||||
return null
|
||||
}
|
||||
|
||||
const crumbs = segments.map((segment, i) => {
|
||||
const path = "/" + segments.slice(0, i + 1).join("/")
|
||||
return { key: path, href: GROUP_LANDING[path] ?? path, label: labelFor(segment) }
|
||||
const crumbs = segments.map((segment, index) => {
|
||||
const path = `/${segments
|
||||
.slice(0, index + 1)
|
||||
.join("/")}`
|
||||
|
||||
return {
|
||||
key: path,
|
||||
href: GROUP_LANDING[path] ?? path,
|
||||
label: labelFor(segment),
|
||||
}
|
||||
})
|
||||
|
||||
// Remove consecutive duplicate labels, e.g. Sales > Sales.
|
||||
const uniqueCrumbs = crumbs.filter(
|
||||
(crumb, index, array) =>
|
||||
index === 0 ||
|
||||
crumb.label.toLowerCase() !==
|
||||
array[index - 1].label.toLowerCase()
|
||||
)
|
||||
|
||||
return (
|
||||
<Breadcrumb className="mb-4 print:hidden">
|
||||
<BreadcrumbList>
|
||||
{crumbs.map((crumb, i) => {
|
||||
const isLast = i === crumbs.length - 1
|
||||
{uniqueCrumbs.map((crumb, index) => {
|
||||
const isLast = index === uniqueCrumbs.length - 1
|
||||
|
||||
return (
|
||||
<Fragment key={crumb.key}>
|
||||
{index > 0 && <BreadcrumbSeparator />}
|
||||
|
||||
<BreadcrumbItem>
|
||||
{isLast ? (
|
||||
<BreadcrumbPage>{crumb.label}</BreadcrumbPage>
|
||||
) : (
|
||||
<Link href={crumb.href} className={linkClass}>
|
||||
<BreadcrumbPage>
|
||||
{crumb.label}
|
||||
</Link>
|
||||
</BreadcrumbPage>
|
||||
) : (
|
||||
<span className="truncate text-muted-foreground">
|
||||
{crumb.label}
|
||||
</span>
|
||||
)}
|
||||
</BreadcrumbItem>
|
||||
{!isLast && <BreadcrumbSeparator />}
|
||||
</Fragment>
|
||||
)
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user