Spaces:
Running
Running
| // Persons of interest — the mobile suspects list (own bottom-nav tab). Desktop shows | |
| // the suspect rail on the board instead, so this screen falls through to the Board there. | |
| import { useState } from 'preact/hooks' | |
| import { useGame } from '../store' | |
| import type { Suspect } from '../types' | |
| import { Checklist } from '../ui/checklist' | |
| import { BottomNav, Btn, Hud, Panel, SuspectCard } from '../ui/components' | |
| import { Board } from './board' | |
| export function SuspectsScreen() { | |
| const g = useGame() | |
| const [sel, setSel] = useState<string | null>(null) // before the early return: hook order survives a live resize | |
| if (g.mode === 'desktop') return <Board /> | |
| const c = g.case | |
| return ( | |
| <div class="app__view"> | |
| <Hud | |
| title="PERSONS OF INTEREST" | |
| sub={`${c.suspects.length} SUSPECTS · TAP, THEN INTERROGATE`} | |
| right={<Btn sm variant="ghost" onClick={() => g.nav('accuse')}>Accuse</Btn>} | |
| /> | |
| <Checklist slim /> | |
| <div class="screen-pad"> | |
| <div class="col" style={{ gap: 10 }}> | |
| {c.suspects.map((s: Suspect) => { | |
| const open = sel === s.id | |
| return ( | |
| <div key={s.id} onClick={() => setSel(open ? null : s.id)}> | |
| <SuspectCard s={s} active={open} /> | |
| {open && ( | |
| <div style={{ marginTop: -2 }}> | |
| <Panel variant="amber" style={{ padding: 10, marginTop: 4 }}> | |
| <div class="t-body" style={{ fontSize: 13, lineHeight: 1.4, marginBottom: 8 }}>{s.alibi}</div> | |
| <Btn variant="ox" className="grow" style={{ width: '100%' }} onClick={(e) => { e.stopPropagation(); g.nav('interro', { suspect: s.id }) }}> | |
| ▸ Interrogate {s.name.split(' ')[0]} | |
| </Btn> | |
| </Panel> | |
| </div> | |
| )} | |
| </div> | |
| ) | |
| })} | |
| </div> | |
| </div> | |
| <BottomNav /> | |
| </div> | |
| ) | |
| } | |