import { useState } from 'react'
import { Panel } from '../components/ui'
import { Empty, Note, Toggle, btnGhost, btnPrimary, fieldCls } from '../components/form'
import {
CAPTURE_GATES,
GATE_LABELS,
decisionColor,
useCaptureReadiness,
useCaptureReview,
useRecordGate,
type CaptureGate,
type ReviewRow,
} from '../lib/capture'
// THE CAPTURE REVIEW.
//
// Every live pursuit, how far it has been taken through the gates, and what is unresolved. The number at the
// top is pursuits being worked with no recorded decision at any gate, which is the state this whole phase
// exists to make visible: work in flight that nobody has formally said yes to.
function GateCell({ row, gate }: { row: ReviewRow; gate: CaptureGate }) {
const d = row.latest?.[gate]
if (!d) {
return not decided
}
return (
{d.decision === 'go' ? 'go' : 'no go'}
)
}
function RecordForm({ row, onDone }: { row: ReviewRow; onDone: () => void }) {
const [gate, setGate] = useState('qualify')
const [decision, setDecision] = useState<'go' | 'no_go'>('go')
const [rationale, setRationale] = useState('')
const record = useRecordGate(row.opportunity_id)
// The advisory this decision is being made against. Read at the moment of deciding, shown on the form,
// and snapshotted into the record, so the number stored is the number somebody actually looked at.
const advisory = useCaptureReadiness(row.opportunity_id)
return (
{/* THE NUMBER THE DECISION IS BEING MADE AGAINST. Absent is stated as absent: a missing advisory is
never rendered as a zero, and the record stores nothing rather than a number nobody saw. */}
{advisory.isPending && 'Reading the capture advisory'}
{advisory.isError && 'No capture advisory is available for this pursuit. The decision is recorded without one.'}
{advisory.data && (
Capture readiness{' '}
{advisory.data.band ?? 'not banded'}
{advisory.data.score ? ` at ${advisory.data.score}` : ''}. This is what gets stored beside the
decision, as it stands now.
)}
A bid or no bid used to be a status, which recorded the outcome and never who decided, when, or
against what. Every decision here carries all three, and the advisory numbers are kept as they
stood at the time rather than recomputed, so a decision made in March still reads in June as the
decision that was actually made.