67 lines
2.0 KiB
TypeScript
67 lines
2.0 KiB
TypeScript
'use client';
|
|
|
|
import { ConnectedSelectionBadge } from '@/components/ui/treatment/ConnectedSelectionBadge';
|
|
import {
|
|
formatToothList,
|
|
prosthesisTypeColorFromCatalog,
|
|
} from '@/components/treatment/prosthesisTypeDisplay';
|
|
import type { ProsthesisCatalogEntry } from '@/types/treatment-catalog';
|
|
|
|
export type LabCaseProsthesisGroup = {
|
|
prosthesisTypeCode: string;
|
|
teeth: string[];
|
|
connected?: boolean;
|
|
selectionGroupId?: string;
|
|
};
|
|
|
|
interface LabCaseProsthesisGroupsListProps {
|
|
groups: LabCaseProsthesisGroup[];
|
|
prosthesisCatalog: readonly ProsthesisCatalogEntry[];
|
|
fallbackTeeth?: string[];
|
|
}
|
|
|
|
function prosthesisLabel(code: string, catalog: readonly ProsthesisCatalogEntry[]): string {
|
|
return catalog.find((entry) => entry.code === code)?.label ?? code;
|
|
}
|
|
|
|
export function LabCaseProsthesisGroupsList({
|
|
groups,
|
|
prosthesisCatalog,
|
|
fallbackTeeth = [],
|
|
}: LabCaseProsthesisGroupsListProps) {
|
|
if (groups.length > 0) {
|
|
return (
|
|
<ul className="space-y-0.5">
|
|
{groups.map((group) => (
|
|
<li
|
|
key={`${group.selectionGroupId ?? ''}-${group.prosthesisTypeCode}-${group.teeth.join(',')}`}
|
|
className="text-[11px] leading-snug"
|
|
style={{
|
|
color: prosthesisTypeColorFromCatalog(group.prosthesisTypeCode, prosthesisCatalog),
|
|
}}
|
|
>
|
|
<span className="font-medium">
|
|
{prosthesisLabel(group.prosthesisTypeCode, prosthesisCatalog)}
|
|
</span>
|
|
{group.teeth.length > 0 ? (
|
|
<span className="text-text-muted">
|
|
{' · '}
|
|
{formatToothList(group.teeth)}
|
|
</span>
|
|
) : null}
|
|
{group.connected ? (
|
|
<ConnectedSelectionBadge className="ms-1 align-middle text-[9px] px-1 py-px" />
|
|
) : null}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
);
|
|
}
|
|
|
|
if (fallbackTeeth.length > 0) {
|
|
return <p className="text-[11px] text-text-muted">{formatToothList(fallbackTeeth)}</p>;
|
|
}
|
|
|
|
return null;
|
|
}
|