import React from 'react'; import { Button, Typography } from 'antd'; import MatchSelector from './MatchSelector'; import { GAP, LEFT_WIDTH, ROW_HEIGHT } from './JinshujuMatchModal.types'; import type { JinshujuEntryRow, MatchDecision, StudentOption } from './JinshujuMatchModal.types'; const { Text } = Typography; interface MatchStepProps { entries: JinshujuEntryRow[]; studentOptions: StudentOption[]; getDecision: (serial: number) => MatchDecision | undefined; onDecisionChange: (serial: number, d: MatchDecision) => void; onClear: () => void; leftRef: React.RefObject; rightRef: React.RefObject; onScroll: (source: 'left' | 'right') => void; total: number; matched: number; } const MatchStep: React.FC = ({ entries, studentOptions, getDecision, onDecisionChange, onClear, leftRef, rightRef, onScroll, total, matched, }) => { const svgHeight = entries.length * ROW_HEIGHT; const lines: React.ReactNode[] = []; entries.forEach((entry, i) => { const y = i * ROW_HEIGHT + ROW_HEIGHT / 2; const d = getDecision(entry.serialNumber); const isMatched = d?.action === 'match'; const color = isMatched ? '#1677ff' : '#d9d9d9'; lines.push( , ); }); return (
共 {total} 条,已匹配 {matched} 条
{lines}
onScroll('left')} style={{ width: LEFT_WIDTH, maxHeight: 480, overflowY: 'auto', flexShrink: 0 }} > {entries.map((entry, i) => { const d = getDecision(entry.serialNumber); const isMatched = d?.action === 'match'; return (
{entry.name || 无姓名} {entry.phone && ( {entry.phone} )} #{entry.serialNumber}
); })}
onScroll('right')} style={{ flex: 1, maxHeight: 480, overflowY: 'auto' }} > {entries.map((entry) => (
onDecisionChange(entry.serialNumber, newD)} />
))}
); }; export default MatchStep;