import type { ReactNode } from "react"; /** * The words a list row carries under or beside its title: when it is due, whether it is urgent, and * what state it is in. All three are text, never a pill, so the state is read rather than decoded * from a colour. Styles live in index.css beside `.ahr-list-card`. */ const DUE_LABEL = /^(Due by:|Cancelled on:)\s*(.*)$/; /** "Due by: Fri Sep 5" / "Cancelled on: May 28, 2026" with only the label amber. Any other wording renders whole, in regular ink. */ export const DueLine = ({ text }: { text: string }) => { const match = DUE_LABEL.exec(text); return ( {match ? ( <> {match[1]} {match[2]} ) : ( text )} ); }; const PRIORITY_WORD: Record = { urgent: "Urgent", asap: "ASAP", stat: "STAT", }; /** What staff choose from when assigning a task by hand: routine, then the words its row shows. */ export const TASK_PRIORITY_OPTIONS: { label: string; value: string }[] = [ { label: "Routine", value: "routine" }, ...Object.entries(PRIORITY_WORD).map(([value, label]) => ({ label, value })), ]; /** The priority word for anything above routine; routine and unknown render nothing. */ export const priorityWord = (priority: string | undefined | null): string | undefined => priority ? PRIORITY_WORD[priority.toLowerCase()] : undefined; export const RowPriority = ({ priority }: { priority: string | undefined | null }) => { const word = priorityWord(priority); return word ? {word} : null; }; export type RowStatusTone = "plain" | "attention" | "done" | "ended" | "danger"; /** A status in plain italic words. The tone only repeats what the words already say. */ export const RowStatus = ({ tone = "plain", children }: { tone?: RowStatusTone; children: ReactNode }) => ( {children} );