mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
113 lines
2.8 KiB
TypeScript
113 lines
2.8 KiB
TypeScript
import { Badge, Card, Divider, Group, Stack, Text } from "@mantine/core";
|
|
import type { ReactNode } from "react";
|
|
|
|
export interface PersonField {
|
|
label: string;
|
|
value?: string | null;
|
|
}
|
|
|
|
export interface PersonCardProps {
|
|
/** OWNER / POA / CONTACT PERSON — the person's role, not their name. */
|
|
title: string;
|
|
icon?: ReactNode;
|
|
/**
|
|
* Identity state. `undefined` = this person has no identity check at all
|
|
* (contact person), so no badge is rendered rather than a misleading "not
|
|
* verified" one.
|
|
*/
|
|
verified?: boolean;
|
|
/** Extra pills after the verification badge (e.g. "Verifies for this company"). */
|
|
badges?: ReactNode;
|
|
/** Rendered between the header and the fields — alerts, match warnings. */
|
|
notice?: ReactNode;
|
|
fields: PersonField[];
|
|
/** Shown when the API returned nothing for every field. */
|
|
emptyMessage: string;
|
|
/** Attachments or anything else that belongs to this person. */
|
|
children?: ReactNode;
|
|
}
|
|
|
|
/**
|
|
* One person in the customer's people column: owner, power of attorney, contact
|
|
* person. Empty fields are dropped rather than rendered as "—", so a field the
|
|
* API stops sending simply disappears instead of leaving a dead row behind.
|
|
*/
|
|
export function PersonCard({
|
|
title,
|
|
icon,
|
|
verified,
|
|
badges,
|
|
notice,
|
|
fields,
|
|
emptyMessage,
|
|
children,
|
|
}: PersonCardProps) {
|
|
const filled = fields.filter(
|
|
(f) => f.value != null && String(f.value).trim(),
|
|
);
|
|
|
|
return (
|
|
<Card>
|
|
<Stack gap="sm">
|
|
<Group gap={8} wrap="wrap">
|
|
{icon}
|
|
<Text
|
|
size="xs"
|
|
fw={700}
|
|
c="edr-muted"
|
|
tt="uppercase"
|
|
style={{ letterSpacing: "0.06em" }}
|
|
>
|
|
{title}
|
|
</Text>
|
|
{verified !== undefined &&
|
|
(verified ? (
|
|
<Badge size="xs" color="edr-green" variant="light">
|
|
Fayda verified
|
|
</Badge>
|
|
) : (
|
|
<Badge size="xs" color="gray" variant="light">
|
|
Not verified
|
|
</Badge>
|
|
))}
|
|
{badges}
|
|
</Group>
|
|
|
|
{notice}
|
|
|
|
{filled.length > 0 ? (
|
|
<Stack gap="xs">
|
|
{filled.map((f) => (
|
|
<Stack key={f.label} gap={0}>
|
|
<Text size="xs" c="edr-muted">
|
|
{f.label}
|
|
</Text>
|
|
<Text
|
|
size="sm"
|
|
c="edr-text"
|
|
style={{ wordBreak: "break-word" }}
|
|
>
|
|
{f.value}
|
|
</Text>
|
|
</Stack>
|
|
))}
|
|
</Stack>
|
|
) : (
|
|
<Text size="sm" c="dimmed">
|
|
{emptyMessage}
|
|
</Text>
|
|
)}
|
|
|
|
{children && (
|
|
<>
|
|
<Divider />
|
|
{children}
|
|
</>
|
|
)}
|
|
</Stack>
|
|
</Card>
|
|
);
|
|
}
|
|
|
|
export default PersonCard;
|