From 9ad1df85d2b0440b0e10370c8168061d9844e402 Mon Sep 17 00:00:00 2001 From: Matt Ciaccio Date: Sun, 3 May 2026 17:24:58 +0200 Subject: [PATCH] fix(residential): mobile card list alongside the desktop table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both the residential-clients and residential-interests pages rendered plain HTML s with 5–6 columns directly. At 390px viewport the header columns clipped at the right edge — "Sour..." for the clients page, no header for the interests page either. Adds a parallel mobile card list: -
stays inside `hidden lg:block` (unchanged at lg+) - new card list inside `lg:hidden` mirrors the row data: - Clients: name + status pill on top, then email · phone · residence · source as a wrap-friendly meta row. - Interests: stage label as headline, updated-at on the right, preferences (line-clamp-2) and notes (line-clamp-1) below, source small at the bottom. - Each card is a Link to the detail page (matching the row click target on desktop). - Empty + loading states render as a centered card on mobile. This is the same `hidden lg:block` / `lg:hidden` pattern used for the main /clients and /interests pages. Doesn't refactor to the full DataView primitive (would mean rebuilding the residential data layer on TanStack Table) — keeps the change tightly scoped to the visible output. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../residential/residential-clients-list.tsx | 50 ++++++++++++++++++- .../residential-interests-list.tsx | 44 +++++++++++++++- 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/components/residential/residential-clients-list.tsx b/src/components/residential/residential-clients-list.tsx index 9f0cb16..123a2b9 100644 --- a/src/components/residential/residential-clients-list.tsx +++ b/src/components/residential/residential-clients-list.tsx @@ -18,6 +18,7 @@ import { SubdivisionCombobox } from '@/components/shared/subdivision-combobox'; import { PhoneInput, type PhoneInputValue } from '@/components/shared/phone-input'; import { useRealtimeInvalidation } from '@/hooks/use-realtime-invalidation'; import { apiFetch } from '@/lib/api/client'; +import { cn } from '@/lib/utils'; import type { CountryCode } from '@/lib/i18n/countries'; interface ResidentialClientRow { @@ -85,7 +86,9 @@ export function ResidentialClientsList() { /> -
+ {/* Desktop: table layout. Hidden below lg because the 6 columns clip + off the viewport at phone widths. */} +
@@ -137,6 +140,51 @@ export function ResidentialClientsList() {
+ {/* Mobile: card list. Each card mirrors the table row data with + name + status pill on top, then meta line(s) below. */} +
+ {isLoading && ( +
+ Loading… +
+ )} + {!isLoading && data?.data.length === 0 && ( +
+ No residential clients yet. +
+ )} + {data?.data.map((c) => ( + +
+

{c.fullName}

+ + {STATUS_LABELS[c.status] ?? c.status} + +
+
+ {c.email ? {c.email} : null} + {c.phone ? {c.phone} : null} + {c.placeOfResidence ? {c.placeOfResidence} : null} + {c.source ? · {c.source} : null} +
+ + ))} +
+ ); diff --git a/src/components/residential/residential-interests-list.tsx b/src/components/residential/residential-interests-list.tsx index 1f1291d..637dca8 100644 --- a/src/components/residential/residential-interests-list.tsx +++ b/src/components/residential/residential-interests-list.tsx @@ -94,7 +94,8 @@ export function ResidentialInterestsList() { -
+ {/* Desktop: table layout. Hidden below lg; mobile renders cards. */} +
@@ -149,6 +150,47 @@ export function ResidentialInterestsList() {
+ + {/* Mobile: card list. Stage as the headline (it's the most actionable + field for triage), preferences/notes truncated below. */} +
+ {isLoading && ( +
+ Loading… +
+ )} + {!isLoading && data?.data.length === 0 && ( +
+ No interests match. +
+ )} + {data?.data.map((i) => ( + +
+

+ {STAGE_LABELS[i.pipelineStage] ?? i.pipelineStage} +

+ + {new Date(i.updatedAt).toLocaleDateString()} + +
+ {i.preferences ? ( +

{i.preferences}

+ ) : null} + {i.notes ? ( +

{i.notes}

+ ) : null} + {i.source ? ( +

{i.source}

+ ) : null} + + ))} +
); }