diff --git a/components/truthtrance-knowledge.tsx b/components/truthtrance-knowledge.tsx new file mode 100644 index 00000000..6877f3eb --- /dev/null +++ b/components/truthtrance-knowledge.tsx @@ -0,0 +1,78 @@ +'use client'; + +import { useId } from 'react'; +import { FACTIONS } from '@/game/catalog'; +import type { TruthFact } from '@/game/truthtrance'; +import { knowledgeFactInputError } from '@/game/truthtrance-knowledge'; +import { Input } from '@/components/ui/input'; + +type KnowledgeFact = Extract; +type NumericKnowledgeFact = Exclude; +function isNumericKnowledgeFact(fact: KnowledgeFact): fact is NumericKnowledgeFact { + return fact.kind !== 'prediction' || fact.field === 'turn'; +} + +export function KnowledgeFactFields({ + value, + onChange, +}: { + value: KnowledgeFact; + onChange: (fact: KnowledgeFact) => void; +}) { + const id = useId(); + const isFaction = !isNumericKnowledgeFact(value); + const numericValue = isNumericKnowledgeFact(value) ? value : null; + const isTurn = numericValue?.kind === 'prediction' && numericValue.field === 'turn'; + const min = isTurn ? 1 : numericValue?.kind === 'stormForecast' ? 1 : 0; + const max = isTurn ? 10 : numericValue?.kind === 'stormForecast' ? 6 : 20; + const invalid = knowledgeFactInputError(value); + return ( + <> + {isFaction ? ( + + ) : numericValue && ( + <> + {(isTurn || numericValue.kind === 'stormDial' || numericValue.kind === 'stormForecast') && ( + + )} + +

+ This asks about an already recorded choice or a forecast the target currently knows. If no such value is available, the answer is I don’t know. Only the answer is published. +

+ + )} + {isFaction &&

This asks about an already recorded faction choice. If no such value is available, the answer is I don’t know. Only the answer is published.

} + {invalid && } + + ); +} diff --git a/components/truthtrance.tsx b/components/truthtrance.tsx index 9bd8bcd7..e014201d 100644 --- a/components/truthtrance.tsx +++ b/components/truthtrance.tsx @@ -2,6 +2,8 @@ import { TERRITORIES } from '@/game/board'; import { BattleClaimFields } from './battle-promises'; import { CardCountFields } from './truthtrance-card-count'; +import { KnowledgeFactFields } from './truthtrance-knowledge'; +import { isKnowledgeFact, knowledgeFactInputError } from '@/game/truthtrance-knowledge'; import type { PlanClaim } from '@/game/battle-promises'; import { useId, useState } from 'react'; import Link from 'next/link'; @@ -83,7 +85,7 @@ export function Truthtrance({ (!Number.isSafeInteger(fact.value) || fact.value < 0); const invalidFact = clauses .slice(0, join === 'single' ? 1 : 2) - .some(invalidSpice); + .some((fact) => invalidSpice(fact) || (isKnowledgeFact(fact) && !!knowledgeFactInputError(fact))); const leaderName = (id: string) => id === CHEAP_HERO_TRAITOR ? 'Cheap Hero / Heroine' @@ -312,7 +314,7 @@ export function Truthtrance({ onChange={(e) => setKind(e.target.value as typeof kind)} >