frontend: clinical UI fixes + chat/composer polish

- chat composer: attach works with text (sr-only file input); lighter
  bordered input box
- messages: defer "+" menu actions past close so file/appointment pickers fire
- tasks: top-level New task button
- chat: condensed appointment card with "View in calendar" deep-link;
  appointments page auto-opens the month calendar from ?calendar=&date=
- lab: work-queue rows expand to show task detail + complete
- inventory: clickable item detail dialog
- pharmacy: Dispense action records a dispense + "Recently dispensed" feed;
  expiring badge uses endDate and only flags <=2 days left
- prescriptions: keyboard nav in patient search, inventory-backed medication
  combobox (free-text fallback), optional start/end dates; thread dates through
- sidebar: whole nav scrolls as one
- i18n keys for all new strings

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalid Abdi
2026-06-16 20:45:30 +03:00
parent f0fe501d62
commit 307cc3cc64
18 changed files with 866 additions and 101 deletions
+15 -3
View File
@@ -626,12 +626,15 @@ export function MessagesView() {
</div>
)}
<div className="flex items-center gap-2">
{/* Visually hidden (not `display:none`) so the programmatic
`.click()` reliably opens the picker across browsers. */}
<input
aria-label={t("messages.attach.file")}
className="hidden"
className="sr-only"
multiple
onChange={onPickFiles}
ref={fileInputRef}
tabIndex={-1}
type="file"
/>
<Menu>
@@ -649,11 +652,20 @@ export function MessagesView() {
<Plus className="size-4" />
</MenuTrigger>
<MenuPopup align="start" side="top">
<MenuItem onClick={() => fileInputRef.current?.click()}>
{/* Defer past the menu's close/unmount so the file picker
and the appointment dialog aren't swallowed by the
closing overlay's focus handling. */}
<MenuItem
onClick={() =>
requestAnimationFrame(() => fileInputRef.current?.click())
}
>
<FileText className="size-4 text-muted-foreground" />
{t("messages.attach.file")}
</MenuItem>
<MenuItem onClick={openApptPicker}>
<MenuItem
onClick={() => requestAnimationFrame(openApptPicker)}
>
<CalendarClock className="size-4 text-muted-foreground" />
{t("messages.attach.appointment")}
</MenuItem>