import { memo } from 'react' import { Handle, Position } from '@xyflow/react' import { resolveRoleIcon } from './roleIcons' export interface StructureCanvasNodeData { [key: string]: unknown roleId: string name: string responsibility: string icon: string | null employeeCount: number /** Names of the actual recruited (non-placeholder) people staffed on this role. */ employeeNames: string[] isOwner: boolean isSelected: boolean isDropTarget: boolean } /** * Canvas node — single-accent refined card. * Outer
always carries .oc-canvas-node (plus optional state * modifiers) — this is the E2E anchor. Icon is rendered via CSS * `mask-image` so its tint can track the active theme's --accent; * the card reads consistently under Paper, OpenOPC, etc. */ export const StructureCanvasNode = memo(function StructureCanvasNode({ data }: { data: StructureCanvasNodeData }) { const stateClass = [ 'oc-canvas-node', data.isOwner && 'is-owner', data.isSelected && 'is-selected', data.isDropTarget && 'is-drop-target', ].filter(Boolean).join(' ') const iconSrc = resolveRoleIcon(data.icon) return (
{data.name}
{data.employeeNames.length > 0 ? ( {data.employeeNames[0]} {data.employeeNames.length > 1 ? ` +${data.employeeNames.length - 1}` : ''} ) : ( {data.roleId} )} {data.employeeCount > 0 && ( {data.employeeCount} )}
) })