From 5532a42ff61e501ff93e57580f9dbfdccff4d927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sat, 18 Jul 2026 03:12:58 +0200 Subject: [PATCH] fix(ui): mobile stacked intake history, icon-collapse bulk bar, ResponsiveSheet parity, tap-target floor Intake history stayed a 4-5 column table with two full datetime columns on mobile, forcing sideways scroll of a primary history surface; add the stacked card-list split below md (the measurement-list pattern) and lift the row kebab off a hard 32px box onto the size-11/size-9 floor. The documents bulk-action bar wrapped five labelled buttons into a 2-3 row floating slab at 360px; collapse to icon-only (aria-label carries the name) below sm, matching the document-detail-sheet footer's established pattern. Two coach/medication modals were still on raw Dialog while every sibling had moved to ResponsiveSheet: the schedule-era editor and the document attachment picker. Both now share the bottom-sheet-on-mobile primitive; the era editor's submit button associates to its form via the native `form` attribute since the footer slot sits outside the form's DOM subtree (the log-intake-dialog precedent). Tap-target floor: side-effect entry chips and the coach attachment-pill remove control were below the 44px floor; the chips get a min-h-11 flex-center, the pill remove gets an invisible hit-slop instead of growing the pill's visual footprint. Two insights empty-state CTAs were missing the existing `ctaSize="lg"` treatment already used by their sibling empty states. --- src/app/insights/page.tsx | 2 + .../documents/document-bulk-bar.tsx | 38 +- .../coach-panel/attachment-picker.tsx | 207 ++++---- .../insights/coach-panel/attachment-pills.tsx | 7 +- .../medications/intake-history-list-v2.tsx | 483 ++++++++++++------ .../scheduling/schedule-history-timeline.tsx | 223 ++++---- .../medications/side-effects-section.tsx | 2 +- 7 files changed, 565 insertions(+), 397 deletions(-) diff --git a/src/app/insights/page.tsx b/src/app/insights/page.tsx index 473b782df..4d8ea36cd 100644 --- a/src/app/insights/page.tsx +++ b/src/app/insights/page.tsx @@ -371,6 +371,7 @@ export default function InsightsPage() { icon={} title={t("insights.emptyTitle")} description={t("insights.emptyDescription")} + ctaSize="lg" action={ @@ -98,9 +110,16 @@ export function DocumentBulkBar({ {episodes.length > 0 ? ( - @@ -122,9 +141,10 @@ export function DocumentBulkBar({ disabled={busy} onClick={onShare} data-slot="document-bulk-share" + aria-label={t("documents.bulk.share")} > - {t("documents.bulk.share")} + {t("documents.bulk.share")} {/* Solid destructive (matching the detail sheet's Delete) — the @@ -135,9 +155,10 @@ export function DocumentBulkBar({ size="sm" disabled={busy} onClick={onDelete} + aria-label={t("documents.bulk.delete")} > - {t("documents.bulk.delete")} + {t("documents.bulk.delete")} diff --git a/src/components/insights/coach-panel/attachment-picker.tsx b/src/components/insights/coach-panel/attachment-picker.tsx index 5752523ec..f5a9de002 100644 --- a/src/components/insights/coach-panel/attachment-picker.tsx +++ b/src/components/insights/coach-panel/attachment-picker.tsx @@ -5,14 +5,7 @@ import { useQuery } from "@tanstack/react-query"; import { Check, Search } from "lucide-react"; import { Button } from "@/components/ui/button"; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, -} from "@/components/ui/dialog"; +import { ResponsiveSheet } from "@/components/ui/responsive-sheet"; import { Input } from "@/components/ui/input"; import { Skeleton } from "@/components/ui/skeleton"; import { apiGet } from "@/lib/api/api-fetch"; @@ -128,18 +121,39 @@ export function AttachmentPicker({ } return ( - - + + + + } + > +
- - {t("insights.coach.attach.pickerTitle")} - - {t("insights.coach.attach.pickerDescription")} - - -
-
- {list.isPending && open ? ( -
- {Array.from({ length: 4 }, (_, i) => ( - - ))} -
- ) : list.isError ? ( -

- {t("documents.list.loadError")} -

- ) : documents.length === 0 ? ( -

- {t("insights.coach.attach.pickerEmpty")} -

- ) : ( -
    - {documents.map((doc) => { - const isSelected = selected.includes(doc.id); - const selectable = doc.hasContentIndex; - const disabled = !selectable || (!isSelected && capReached); - const title = - doc.title ?? doc.filename ?? t("documents.card.untitled"); - const Icon = DOCUMENT_KIND_ICONS[doc.kind]; - return ( -
  • - -
  • - ); - })} -
- )} -
- - - - + + ); })} - - - -
+ + )} + + ); } diff --git a/src/components/insights/coach-panel/attachment-pills.tsx b/src/components/insights/coach-panel/attachment-pills.tsx index e4f548c1e..5c6cd5066 100644 --- a/src/components/insights/coach-panel/attachment-pills.tsx +++ b/src/components/insights/coach-panel/attachment-pills.tsx @@ -85,7 +85,12 @@ export function AttachmentPills({ title: item.title, })} title={t("insights.coach.attach.pillRemove", { title: item.title })} - className="text-muted-foreground hover:text-foreground size-5 shrink-0 rounded-full" + // v1.30 mobile audit (C-4) — the visible glyph stays a compact + // size-5 pill control, but the actual hit area extends to the + // 44px floor via an invisible `after` hit-slop (the same + // `measurement-list.tsx` checkbox trick) rather than growing the + // pill's visual footprint in the composer's attach row. + className="text-muted-foreground hover:text-foreground relative size-5 shrink-0 rounded-full after:absolute after:-inset-3" >