diff --git a/DECISIONS.md b/DECISIONS.md index 9df2e1a..9a8f77d 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -587,3 +587,9 @@ Implementation decisions not spelled out in `memory-bank/implementation-plan.md` - **The map was already reachable during the tutorial** (its tab exists from the first screen); this step adds the lock and reachability. - **Locked locations are labelled "🔒 Name"** on the canvas (they were dimmed already), replacing the earlier "Name?". - **Reachability uses sim `checkRoute` (range and landing) from Earth at the current server time,** over `content.purchasableShipModels`, so it changes as planets move. When nothing can reach it the panel says so. + +## Step 10A.17 + +- **The summary lists every goal currently ready to claim,** not only ones that became ready since the last visit. The server does not track when a goal became ready, and an unclaimed ready goal is worth pointing out on any return. +- **"Claim on HQ" acknowledges the deliveries and navigates to `/#goals`.** +- **Web tests wait up to 3 s for elements** (`asyncUtilTimeout`); the 1 s default occasionally ran out under a fully parallel run. diff --git a/apps/web/src/components/AwaySummary.tsx b/apps/web/src/components/AwaySummary.tsx index 79db38b..e10eb4e 100644 --- a/apps/web/src/components/AwaySummary.tsx +++ b/apps/web/src/components/AwaySummary.tsx @@ -1,5 +1,6 @@ import { content } from "@deadhead/content"; import { useState } from "react"; +import { useNavigate } from "react-router"; import { formatCredits, locationName } from "../format"; import { useGameAction, useLoadedPlayer } from "../state/actions"; @@ -10,7 +11,13 @@ export function AwaySummary() { // Hide as soon as the player dismisses; the refetch clears the list for real. const [dismissed, setDismissed] = useState>(new Set()); + const navigate = useNavigate(); const summaries = state.summaries.filter((s) => !dismissed.has(s.dispatchId)); + // Goals waiting to be claimed (Step 10A.17). + const readyGoals = state.goals + .filter((g) => g.status === "ready") + .map((g) => content.onboardingGoal(g.id)) + .filter((g) => g !== undefined); if (summaries.length === 0) return null; const shipName = (shipId: string, tutorial: boolean) => @@ -68,6 +75,28 @@ export function AwaySummary() { ))} + {readyGoals.length > 0 && ( +
+

Goals ready to claim

+ + +
+ )}