Implement the 003-remove-combatant feature that adds the possibility to remove a combatant from an encounter

This commit is contained in:
Lukas
2026-03-03 23:46:47 +01:00
parent 9d7b174867
commit aed234de7b
16 changed files with 763 additions and 6 deletions

View File

@@ -9,11 +9,14 @@ function formatEvent(e: ReturnType<typeof useEncounter>["events"][number]) {
return `Round advanced to ${e.newRoundNumber}`;
case "CombatantAdded":
return `Added combatant: ${e.name}`;
case "CombatantRemoved":
return `Removed combatant: ${e.name}`;
}
}
export function App() {
const { encounter, events, advanceTurn, addCombatant } = useEncounter();
const { encounter, events, advanceTurn, addCombatant, removeCombatant } =
useEncounter();
const activeCombatant = encounter.combatants[encounter.activeIndex];
const [nameInput, setNameInput] = useState("");
@@ -37,7 +40,10 @@ export function App() {
<ul>
{encounter.combatants.map((c, i) => (
<li key={c.id}>
{i === encounter.activeIndex ? `${c.name}` : c.name}
{i === encounter.activeIndex ? `${c.name}` : c.name}{" "}
<button type="button" onClick={() => removeCombatant(c.id)}>
Remove
</button>
</li>
))}
</ul>

View File

@@ -2,8 +2,9 @@ import type { EncounterStore } from "@initiative/application";
import {
addCombatantUseCase,
advanceTurnUseCase,
removeCombatantUseCase,
} from "@initiative/application";
import type { DomainEvent, Encounter } from "@initiative/domain";
import type { CombatantId, DomainEvent, Encounter } from "@initiative/domain";
import {
combatantId,
createEncounter,
@@ -64,5 +65,24 @@ export function useEncounter() {
[makeStore],
);
return { encounter, events, advanceTurn, addCombatant } as const;
const removeCombatant = useCallback(
(id: CombatantId) => {
const result = removeCombatantUseCase(makeStore(), id);
if (isDomainError(result)) {
return;
}
setEvents((prev) => [...prev, ...result]);
},
[makeStore],
);
return {
encounter,
events,
advanceTurn,
addCombatant,
removeCombatant,
} as const;
}