fix(ui): move NEXT TURN into the right pane — full width, no longer overlapped (#52)
This commit is contained in:
@@ -529,6 +529,14 @@ export function MissionControl() {
|
|||||||
)}
|
)}
|
||||||
</PanelContent>
|
</PanelContent>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
||||||
|
{/* #52 — the manual tick control (5b), moved in from the fixed bottom-right overlay:
|
||||||
|
last child of the pane's flex column — full width, size MD, pinned to the pane
|
||||||
|
bottom when the content is short (the wrapper's marginTop:auto) and scrolling
|
||||||
|
with the pane when the cargo list is long. In normal flow, the active-tasks strip
|
||||||
|
can no longer paint over it; the pane (unlike the tab content) is outside Radix's
|
||||||
|
unmount, so it stays visible on every tab. */}
|
||||||
|
<NextTurnButton turn={ship?.turn ?? null} onTicked={refreshAll} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -567,13 +575,9 @@ export function MissionControl() {
|
|||||||
<Badge variant="ACTIVE">SYS ONLINE</Badge>
|
<Badge variant="ACTIVE">SYS ONLINE</Badge>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
{/* #44 — the manual tick control (5b): fixed bottom-right, outside the tab grid so it
|
{/* #44 — the active-tasks strip: fixed bottom-left, outside the tab grid so it stays
|
||||||
stays visible on every tab (Radix unmounts inactive tabs — the button only refreshes
|
visible on every tab. (#52 moved the NEXT TURN button out of this fixed-overlay area
|
||||||
the snapshots this shell owns) */}
|
and into the right pane, so the two can no longer overlap.) Data: the shell's system
|
||||||
<NextTurnButton turn={ship?.turn ?? null} onTicked={refreshAll} />
|
|
||||||
|
|
||||||
{/* #44 — the active-tasks strip: fixed bottom-left (same mount convention as the button —
|
|
||||||
outside the tab grid so it stays visible on every tab). Data: the shell's system
|
|
||||||
snapshot (JC-15) — refreshAll re-runs /api/system on every turn, so it updates on
|
snapshot (JC-15) — refreshAll re-runs /api/system on every turn, so it updates on
|
||||||
every shell refresh with no fetch of its own. */}
|
every shell refresh with no fetch of its own. */}
|
||||||
<TaskStrip tasks={system?.tasks ?? []} />
|
<TaskStrip tasks={system?.tasks ?? []} />
|
||||||
|
|||||||
@@ -3,12 +3,16 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
|
|
||||||
// NEXT TURN — the manual tick control (5b): a fixed bottom-right button + the current turn from
|
// NEXT TURN — the manual tick control (5b): a normal-flow block in the right pane (#52) carrying
|
||||||
// the ship snapshot the shell holds. One click = POST /api/turn (no body); on success the shell
|
// the current turn from the ship snapshot the shell holds. One click = POST /api/turn (no body);
|
||||||
// re-fetches its snapshots. Review Focus 4: the button is NEVER disabled by game state — an
|
// on success the shell re-fetches its snapshots. Review Focus 4: the button is NEVER disabled by
|
||||||
// empty queue is a FREE SKIP (the route always returns 200) — and the only transient is an
|
// game state — an empty queue is a FREE SKIP (the route always returns 200) — and the only
|
||||||
// in-flight request, which the handler ignores. `disabled` is never set, so the cva
|
// transient is an in-flight request, which the handler ignores. `disabled` is never set, so the
|
||||||
// disabled:opacity-40 styling never applies either.
|
// cva disabled:opacity-40 styling never applies either.
|
||||||
|
// #52 — the fixed bottom-right overlay became the right pane's last flex child (mission-control):
|
||||||
|
// full width, size MD, pinned to the pane bottom when the content is short (marginTop:auto) and
|
||||||
|
// scrolling with the pane when the cargo list is long. No position/zIndex any more — so the
|
||||||
|
// active-tasks strip can no longer paint over it.
|
||||||
|
|
||||||
export function NextTurnButton({ turn, onTicked }: { turn: number | null; onTicked: () => void }) {
|
export function NextTurnButton({ turn, onTicked }: { turn: number | null; onTicked: () => void }) {
|
||||||
const [inFlight, setInFlight] = useState(false)
|
const [inFlight, setInFlight] = useState(false)
|
||||||
@@ -30,14 +34,11 @@ export function NextTurnButton({ turn, onTicked }: { turn: number | null; onTick
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
position: 'fixed',
|
|
||||||
right: '1rem',
|
|
||||||
bottom: '1rem',
|
|
||||||
zIndex: 60, // above the header/footer's 50
|
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
alignItems: 'flex-end',
|
gap: '0.5rem',
|
||||||
gap: '0.375rem',
|
width: '100%',
|
||||||
|
marginTop: 'auto',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{error && (
|
{error && (
|
||||||
@@ -46,7 +47,7 @@ export function NextTurnButton({ turn, onTicked }: { turn: number | null; onTick
|
|||||||
<span style={{ fontSize: '0.62rem', color: 'var(--text-muted)', letterSpacing: '0.12em' }}>
|
<span style={{ fontSize: '0.62rem', color: 'var(--text-muted)', letterSpacing: '0.12em' }}>
|
||||||
TURN {turn ?? '—'}
|
TURN {turn ?? '—'}
|
||||||
</span>
|
</span>
|
||||||
<Button variant="EXEC" size="SM" onClick={tick}>
|
<Button variant="EXEC" size="MD" className="w-full" onClick={tick}>
|
||||||
NEXT TURN
|
NEXT TURN
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user