import { ChevronRight } from "lucide-react"; // The collapsed record of an answered step, drawn as ONE ROW of a list rather than a cell of a grid. // Two variants, and the difference is load-bearing: // editable -> the whole row is a button, so the patient can change their answer // locked -> no control and a stated reason, because there was nothing to choose // A locked step that does not say why it is locked is the exact defect this redesign removes, so // `lockReason` is required to lock rather than optional - you cannot lock silently. export interface AnsweredLineProps { label: string; value: string; subtitle?: string; onEdit?: () => void; lockReason?: string; } // Spencer, 2026-09-09, walking the booking modal live. // // THE THREE-COLUMN GRID WAS ITSELF WHAT MADE THIS MODAL SPAN THE SCREEN. Three answers across a row // need the width of three answers, so the dialog grew to roughly 1750px on a desktop and each answer // got a third of it - which is why a free-text reason truncated at all. Collapsing to ONE COLUMN took // the dialog to 512px and removed the truncation that `title` existed to apologise for. // // LABEL LEFT, VALUE BESIDE IT. The old shape stacked label OVER value, so four answers cost eight // lines and the eye had to re-find the left edge on every one. Side by side, the labels form one scan // column and the values form another. // // THE ROW IS THE TAP TARGET, AND THE PENCILS ARE GONE. A pencil on every row was the loudest thing // in a block whose job is to be quiet, and on the patient portal each one also carried the 44px touch // floor - four invisible 44px targets stacked inside a summary. One chevron at the right edge says // "this opens" the way every other list row in the app does, and the row itself is what you press. const ROW = "grid items-start gap-x-3 py-2.5 min-w-0"; export default function AnsweredLine({ label, value, subtitle, onEdit, lockReason }: AnsweredLineProps) { const locked = Boolean(lockReason); // The label is uppercase via CSS rather than `.toUpperCase()` so textContent - and therefore screen // readers and the tests - still reads the natural-case word. const labelEl = ( {label} ); // The app's explanatory-text standard, muted, as the approved deck draws it (self-booking-modal `.lock`). // It was amber, which read as a warning on every line of a one-clinic practice, where each answer is // "the only" one. Nothing here is a caution: it says why there was nothing to choose. const note = (subtitle || lockReason) && ( {subtitle || lockReason} ); if (locked || !onEdit) { return (
{labelEl} {value} {note}
); } return ( ); }