feat(ui): NEXT TURN button (bottom-right) + turn counter; empty queue is a free skip (#44)

This commit is contained in:
2026-10-02 20:04:38 +00:00
parent 1084f4e099
commit 07c1508999
2 changed files with 69 additions and 1 deletions
+15 -1
View File
@@ -13,6 +13,7 @@ import { CrewPanel } from '@/components/crew-panel'
import { EventLogPanel } from '@/components/event-log'
import { LocalSystemPanel } from '@/components/local-system'
import { MissionPanel } from '@/components/missions'
import { NextTurnButton } from '@/components/next-turn-button'
import { ShipSystemsPanel } from '@/components/ship-systems'
import { SkillTreePanel } from '@/components/skill-tree'
import { WorldMapPanel } from '@/components/world-map'
@@ -62,7 +63,12 @@ export function MissionControl() {
// #38 — admin DB CRUD overlay, opened from the header.
const [adminOpen, setAdminOpen] = useState(false)
useEffect(() => {
// #44 — the four mount fetches, extracted into a callback so the NEXT TURN button (5b) can
// re-run them after /api/turn: a tick can change all four snapshots (the turn always; inventory
// on an explore resolve, system on a jump resolve, the roster on a recruit, tech on a research
// completion) — a strict superset of refreshSystem, which stays for the jump callback. Same
// failure policy as the mount fetch — keep the old state on error.
const refreshAll = useCallback(() => {
let cancelled = false
fetch('/api/ship')
.then(async (res) => {
@@ -105,6 +111,9 @@ export function MissionControl() {
}
}, [])
// The effect returns refreshAll's cleanup, so unmount still cancels the in-flight setStates.
useEffect(() => refreshAll(), [refreshAll])
useEffect(() => {
const id = setInterval(() => setTick((t) => t + 1), 1000)
return () => clearInterval(id)
@@ -548,6 +557,11 @@ export function MissionControl() {
<Badge variant="ACTIVE">SYS ONLINE</Badge>
</footer>
{/* #44 — the manual tick control (5b): fixed bottom-right, outside the tab grid so it
stays visible on every tab (Radix unmounts inactive tabs — the button only refreshes
the snapshots this shell owns) */}
<NextTurnButton turn={ship?.turn ?? null} onTicked={refreshAll} />
</div>
)
}