'use client'; import type { GameView } from '@/game/engine'; import { TERRITORIES } from '@/game/board'; import type { MixedActionExpression } from '@/game/mixed-action-question'; import { MOVEMENT_EXPRESSION_MAX_DEPTH, MOVEMENT_EXPRESSION_MAX_LEAVES } from '@/game/movement-expression-promises'; import { parseMovementClaim, type MovementClaim } from '@/game/movement-promises'; import { MixedActionFields, mixedActionInputError, type MixedActionConfig } from './mixed-action-fields'; import { Input } from './ui/input'; type MixedMovementExpression = MixedActionExpression; const config: MixedActionConfig = { prefix: 'mixed-movement', legend: 'Mixed current-fact / future ground-movement claim', actionLabel: 'ground-movement condition', actionTiming: 'Future ground move ยท this turn', actionHelp: <>Each movement condition needs one actual future ground move after the answer, before your Movement turn ends this round. You may name an exact sector. Smaller moves never add together. Prior moves and shipments do not count. The claim grants no extra movement opportunity., fallbackError: 'Choose a current fact and a future ground-movement condition.', maxLeaves: MOVEMENT_EXPRESSION_MAX_LEAVES, maxDepth: MOVEMENT_EXPRESSION_MAX_DEPTH, newAction: () => ({ territory: 'carthag', minimum: 1 }), parseAction: parseMovementClaim, renderAction: ({ value, id, disabled, onChange }) => <> 20} onChange={event => onChange({ ...value, minimum: event.currentTarget.valueAsNumber })} /> , }; /** Keep the movement API and rendered control identifiers stable. */ export function mixedMovementInputError(value: unknown, game: GameView, target: string): string | null { return mixedActionInputError(value, game, target, config); } export function MixedMovementFields(props: { value: MixedMovementExpression; game: GameView; target: string; disabled: boolean; onChange: (expression: MixedMovementExpression) => void; }) { return MixedActionFields({ ...props, config }); }