import { memo } from 'react' import { Handle, Position, NodeProps } from 'reactflow' import type { StepStatus } from '../types' export interface StepNodeData { label: string status: StepStatus isGate?: boolean workflowId: string stepId: string onGateApprove?: (workflowId: string, stepId: string) => void } const STATUS_COLORS: Record = { done: '#22c55e', gate: '#f59e0b', fail: '#ef4444', 'in-progress': '#6366f1', pending: '#2a2a2a', partial: '#f97316', blocked: '#6b7280', } const STATUS_BORDER: Record = { done: '#16a34a', gate: '#d97706', fail: '#dc2626', 'in-progress': '#4f46e5', pending: '#3f3f3f', partial: '#ea580c', blocked: '#4b5563', } const STATUS_LABELS: Record = { done: 'DONE', gate: 'GATE', fail: 'FAIL', 'in-progress': 'IN PROGRESS', pending: 'PENDING', partial: 'PARTIAL', blocked: 'BLOCKED', } function StepNode({ data }: NodeProps) { const { label, status, isGate, workflowId, stepId, onGateApprove } = data const bg = STATUS_COLORS[status] const border = STATUS_BORDER[status] const isClickable = isGate && (status === 'gate' || status === 'pending') && onGateApprove const handleClick = () => { if (isClickable) { onGateApprove!(workflowId, stepId) } } if (isGate) { // Diamond shape via CSS transform on a square const size = 64 return ( <>
{label}
) } return ( <>
{label} {STATUS_LABELS[status]}
) } export default memo(StepNode)