import { useMemo } from "react"; import { Link, useLocation } from "react-router-dom"; import { useTranslation } from "react-i18next"; import { Breadcrumb, BreadcrumbList } from "@/shared/common/ui/breadcrumb"; import { ChevronRight, Home } from "lucide-react"; import { capitalize } from "@/shared/lib/utils"; interface BreadcrumbNode { label: string; path: string; isActive: boolean; isEllipsis?: boolean; } const MODULE_LANDING_PATHS = new Set([ "/record-management/dashboard", "/objective-management/plan-years", "/performance-management/plan-years", "/dms/dashboard", ]); // Module roots and plan-year list pages are reachable from the sidebar/module // switcher — omit them from breadcrumbs to avoid redundant navigation. const HIDDEN_BREADCRUMB_SEGMENTS = new Set([ "plan-years", "record-management", "objective-management", "performance-management", "dms", "user-management", ]); const isDynamicId = (segment: string) => /^[0-9a-f]{8,}$/i.test(segment) || /^[0-9]+$/.test(segment); const makeReadableLabel = (segment: string) => { const withSpaces = segment .replace(/([a-z])([A-Z])/g, "$1 $2") .replace(/[_-]/g, " "); return capitalize(withSpaces); }; export function DynamicBreadcrumb() { const location = useLocation(); const { t } = useTranslation(); const breadcrumbs = useMemo(() => { if (MODULE_LANDING_PATHS.has(location.pathname)) { return [] as BreadcrumbNode[]; } const pathSegments = location.pathname.split("/").filter(Boolean); if (pathSegments.length === 0) return [] as BreadcrumbNode[]; const labelMap: Record = { dashboard: t("header.navigation.dashboard"), userRecords: t("header.navigation.outgoing"), userIncoming: t("header.navigation.incoming"), delegation: t("header.navigation.delegation"), approval: t("header.navigation.approval"), pending: t("header.navigation.pending"), collaborations: t("header.navigation.collaborations"), recordOfficer: "Record Officer", incoming: t("header.navigation.incoming"), outgoing: t("header.navigation.outgoing"), add: t("common.create"), new: t("common.create"), edit: t("common.Edit"), profile: t("profile.profile"), "update-profile": t("profile.updateProfile"), "change-password": t("header.changePassword"), uploadTeeterandSignature: t("header.addTeeter"), viewDelegationLetter: t("delegation.viewLetter"), editDelegation: t("delegation.editDelegation"), incomingHistory: "Incoming History", incomingNonSmartExternal: "External Incoming", viewIncoming: "View Incoming", goals: t("organization.Goals", "Goals"), "detail-task": t("organization.detail_task", "Detail Task"), "Major-Task": t("organization.Major Task", "Major Task"), expectations: t("organization.expectations", "Expectations"), "employee-expectations": t( "organization.employeeExpectations", "Employee Expectations", ), achievements: t("organization.achievements", "Achievements"), "additional-tasks": t("organization.additionalTasks", "Additional Tasks"), "signature-settings": t( "organization.Signature Settings", "Signature Settings", ), }; let currentPath = ""; const items: BreadcrumbNode[] = []; for (const segment of pathSegments) { currentPath += `/${segment}`; if (HIDDEN_BREADCRUMB_SEGMENTS.has(segment) || isDynamicId(segment)) { continue; } const baseLabel = labelMap[segment] || makeReadableLabel(segment); items.push({ label: baseLabel, path: currentPath, isActive: false, }); } if (items.length > 0) { items[items.length - 1].isActive = true; } return items; }, [location.pathname, t]); if (!breadcrumbs.length) { return null; } const compactBreadcrumbs = breadcrumbs; return (
{compactBreadcrumbs.map((breadcrumb, index) => (
{index > 0 && ( )} {breadcrumb.isEllipsis ? ( ... ) : breadcrumb.isActive ? ( {breadcrumb.label} ) : ( {index === 0 && } {breadcrumb.label} )}
))}
); }