54 lines
2.4 KiB
TypeScript
54 lines
2.4 KiB
TypeScript
'use client';
|
|
|
|
import { TERRITORIES } from '@/game/board';
|
|
|
|
/** This public question never includes a concealed token identity or value. */
|
|
export type NoFieldShipmentInput = {
|
|
kind: 'noField';
|
|
territory?: string;
|
|
sector?: number;
|
|
};
|
|
|
|
/** Author one No-Field leaf inside the ordinary shipment expression. */
|
|
export function TruthNoFieldShipmentFields({ id, value, disabled, onChange }: {
|
|
id: string;
|
|
value: NoFieldShipmentInput;
|
|
disabled: boolean;
|
|
onChange: (value: NoFieldShipmentInput) => void;
|
|
}) {
|
|
const destination = TERRITORIES.find(territory => territory.id === value.territory);
|
|
return <>
|
|
<label htmlFor={`${id}-no-field-territory`}>No-Field shipment destination</label>
|
|
<select id={`${id}-no-field-territory`} value={value.territory ?? ''} disabled={disabled}
|
|
aria-invalid={value.territory !== undefined && !destination} onChange={event => {
|
|
if (disabled) return;
|
|
const territory = event.currentTarget.value;
|
|
if (territory === '') onChange({ kind: 'noField' });
|
|
else if (TERRITORIES.some(candidate => candidate.id === territory))
|
|
onChange({ kind: 'noField', territory });
|
|
}}>
|
|
<option value="">Any destination</option>
|
|
{TERRITORIES.map(territory => <option key={territory.id} value={territory.id}>{territory.name}</option>)}
|
|
</select>
|
|
{destination && <>
|
|
<label htmlFor={`${id}-no-field-sector`}>No-Field shipment sector</label>
|
|
<select id={`${id}-no-field-sector`} value={value.sector === undefined ? '' : String(value.sector)}
|
|
disabled={disabled} aria-invalid={value.sector !== undefined && !destination.sectors.includes(value.sector)}
|
|
onChange={event => {
|
|
if (disabled) return;
|
|
const selected = event.currentTarget.value;
|
|
if (selected === '') onChange({ kind: 'noField', territory: destination.id });
|
|
else {
|
|
const sector = Number(selected);
|
|
if (destination.sectors.includes(sector)) onChange({ kind: 'noField', territory: destination.id, sector });
|
|
}
|
|
}}>
|
|
<option value="">Any sector in this territory</option>
|
|
{destination.sectors.map(sector => <option key={sector} value={sector}>Sector {sector}</option>)}
|
|
</select>
|
|
</>}
|
|
<p className="fine">Ask whether the player ships an owned No-Field from reserves this turn.
|
|
The question does not identify its token or value. A physical-force minimum is a separate condition.</p>
|
|
</>;
|
|
}
|