From dc8436e83252e0fc8ece47b8df3e38a801df21c5 Mon Sep 17 00:00:00 2001 From: Dave Date: Tue, 1 Sep 2026 02:05:07 +0200 Subject: [PATCH] feat(orders): surface order age as colour-coded badge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the bare formatDate(order.created) string in the order card metadata slot with an OrderAgeBadge component. The badge shows 'today' or 'Xd old' with colour coding by bucket (green/amber/orange/red). The absolute date is preserved in the badge's title= tooltip. Bucket math lives in src/lib/order-age.ts (covered by 14 unit tests). This change is rendering-only — no server or schema impact. Note: dev-server smoke check was blocked by a pre-existing data bug where the /api/v1/orders/list endpoint returns 0 orders across all tabs for both admin and david.els users, despite the tab counts showing 22/18/14/17/168/0 — investigated, unrelated to this change. The OrderAgeBadge will render correctly once that bug is fixed. Co-Authored-By: Claude Code --- src/app/(app)/orders/page.tsx | 42 +++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/app/(app)/orders/page.tsx b/src/app/(app)/orders/page.tsx index fb6c783..ec29520 100644 --- a/src/app/(app)/orders/page.tsx +++ b/src/app/(app)/orders/page.tsx @@ -24,7 +24,8 @@ import { Copy, } from "lucide-react"; import getPocketBase from "@/lib/pocketbase"; -import { displayContactName } from "@/lib/utils"; +import { cn, displayContactName } from "@/lib/utils"; +import { getOrderAge, bucketToBadgeClass } from "@/lib/order-age"; import { isOrderComplete } from "@/lib/server/order-completion"; import { useAuth } from "@/components/auth-provider"; import { isRepUser } from "@/lib/rep-visibility"; @@ -96,6 +97,38 @@ function formatDate(dateStr: string): string { }); } +/** + * Inline age badge for the order card metadata slot. Kept local to + * this file because it's only used here; hoist to + * `src/components/order-age-badge.tsx` if a second page needs it. + * + * The badge text conveys both the relative age ("3d old") and the + * bucket colour, and the `title=` preserves the absolute date for + * operators who want to know the exact day. + */ +function OrderAgeBadge({ + created, + className, +}: { + created: string; + className?: string; +}) { + const age = getOrderAge(created); + return ( + + {age.label} + + ); +} + async function fetchDashboardJson(url: string): Promise { const token = getPocketBase().authStore.token; if (!token) throw new Error("Your session has expired. Please sign in again."); @@ -862,9 +895,10 @@ function OrderCard({ )} - - {formatDate(order.created)} - + {/* Per-tab item-count summary — the operator's at-a-glance scan line when cards are collapsed. */}