case0 / web /src /screens /suspects.tsx
HusseinEid's picture
Per-case visuals, incident vignettes, guided play, no-repeat dealing, four new crime kinds (#4)
16ff49b
Raw
History Blame Contribute Delete
1.98 kB
// 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>
)
}