Files
edr-platform/apps/edr-freight-web/backoffice/src/components/detail/EntityLink.tsx
2026-08-13 06:54:54 +00:00

64 lines
1.7 KiB
TypeScript

import type { ReactNode } from "react";
import type { LucideIcon } from "lucide-react";
import { ArrowUpRight } from "lucide-react";
import { Anchor, Group, Text } from "@mantine/core";
import { Link } from "react-router-dom";
export interface EntityLinkProps {
/** Route to the related record's detail page. Renders nothing if falsy — a
* link with no id would be a dead one (e.g. a government booking with no
* company). */
to?: string | null;
label: ReactNode;
icon?: LucideIcon;
/** Monospace label — for references/codes (e.g. "CT-2024-0117"). */
mono?: boolean;
size?: "xs" | "sm" | "md";
fw?: number;
className?: string;
}
/**
* Inline link to another record's detail page, with a small "go to" glyph so
* it reads as navigation rather than plain emphasis. `stopPropagation` matters
* wherever this sits inside a clickable table row (booking/invoice rows
* navigate on click) — without it a nested link races the row handler.
*/
export function EntityLink({
to,
label,
icon: Icon,
mono,
size = "sm",
fw = 600,
className,
}: EntityLinkProps) {
if (!to) {
return (
<Text size={size} fw={fw} c="dimmed" ff={mono ? "monospace" : undefined}>
{label}
</Text>
);
}
return (
<Anchor
component={Link}
to={to}
onClick={(e) => e.stopPropagation()}
underline="hover"
c="edr-green"
fw={fw}
fz={size}
ff={mono ? "monospace" : undefined}
className={className}
>
<Group gap={4} wrap="nowrap" component="span" style={{ display: "inline-flex" }}>
{Icon ? <Icon size={14} /> : null}
<span>{label}</span>
<ArrowUpRight size={13} style={{ flexShrink: 0 }} />
</Group>
</Anchor>
);
}