Dashboard: Show stale-data reason inline using Trackbox status language #22

Closed
opened 2026-06-27 15:41:14 +02:00 by bullitt · 1 comment
Owner

Problem

The 'Stalled' badge appears on shipment cards next to the status badge, but its meaning is only revealed on hover via a title tooltip. On touch devices there is no hover, so the badge is completely opaque. In the live instance, 8 out of 10 active shipments show 'Stalled' — it is the dominant state yet the least explained.

Expected behavior

Users should understand without hovering what 'Stalled' means and why. There are two stall reasons:

  • scrape_failures — scraping was disabled after N consecutive failures
  • retention_expired — carrier tracking window has elapsed

Implementation

File: frontend/src/pages/Dashboard.tsx — the ShipmentCard component around line 72.

Replace the current badge:

<span
  className="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400 cursor-help"
  title={...}
>
  Stalled
</span>

With a badge that includes a short inline reason:

  • scrape_failures → show "Stalled · scrape errors"
  • retention_expired → show "Stalled · expired"
  • fallback → show "Stalled"

Use a or AlertTriangle lucide icon (h-3 w-3) before the text to reinforce the warning visually.

The title tooltip can remain for the longer explanation, but the badge text itself must convey the category without requiring hover.

Acceptance criteria

  • Badge reads "Stalled · scrape errors" or "Stalled · expired" depending on stall_reason
  • No hover required to understand the category
  • Works on mobile (no tooltip dependency)

Brand identity alignment

This issue should turn the current generic amber Stalled chip into a Trackbox-specific data transparency cue. The brand brief defines Trackbox as a calm logistics control plane: the UI must explain uncertainty and data staleness without alarmist or playful language.

Use the status-language direction from the brief:

  • Prefer Delivery may be delayed when the latest carrier event is older than expected.
  • Prefer Carrier data unavailable or No new events when scraping has stopped or no fresh source data exists.
  • Keep the short card badge compact, but pair color with text and an AlertTriangle icon so status is not color-only.

Brand-compliant implementation notes

  • Use neutral card treatment with a small amber semantic badge; do not make the whole shipment card amber.
  • Keep carrier badges secondary and avoid carrier-brand color emphasis.
  • Tooltip text should name the data source problem: Last sync failed, Carrier retention window expired, or No new carrier events.
  • If possible, expose the longer explanation in the detail page as Last sync / Source metadata, not only in the card tooltip.

Additional acceptance criteria

  • The badge uses calm operational copy, not the bare label Stalled alone.
  • The badge communicates the reason without hover on mobile.
  • Amber is used only as the semantic stale/delayed signal; default shipment surfaces remain neutral.

Migrated from GitHub issue #1: https://github.com/bullitt186/trackbox/issues/1
Original author: @bullitt186
Original created: 2026-06-27T13:22:06Z
Original labels: ux

## Problem The 'Stalled' badge appears on shipment cards next to the status badge, but its meaning is only revealed on hover via a `title` tooltip. On touch devices there is no hover, so the badge is completely opaque. In the live instance, 8 out of 10 active shipments show 'Stalled' — it is the dominant state yet the least explained. ## Expected behavior Users should understand without hovering what 'Stalled' means and why. There are two stall reasons: - `scrape_failures` — scraping was disabled after N consecutive failures - `retention_expired` — carrier tracking window has elapsed ## Implementation File: `frontend/src/pages/Dashboard.tsx` — the `ShipmentCard` component around line 72. Replace the current badge: ```tsx <span className="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400 cursor-help" title={...} > Stalled </span> ``` With a badge that includes a short inline reason: - `scrape_failures` → show "Stalled · scrape errors" - `retention_expired` → show "Stalled · expired" - fallback → show "Stalled" Use a `⚠` or `AlertTriangle` lucide icon (h-3 w-3) before the text to reinforce the warning visually. The `title` tooltip can remain for the longer explanation, but the badge text itself must convey the category without requiring hover. ## Acceptance criteria - Badge reads "Stalled · scrape errors" or "Stalled · expired" depending on `stall_reason` - No hover required to understand the category - Works on mobile (no tooltip dependency) ## Brand identity alignment This issue should turn the current generic amber `Stalled` chip into a Trackbox-specific data transparency cue. The brand brief defines Trackbox as a calm logistics control plane: the UI must explain uncertainty and data staleness without alarmist or playful language. Use the status-language direction from the brief: - Prefer `Delivery may be delayed` when the latest carrier event is older than expected. - Prefer `Carrier data unavailable` or `No new events` when scraping has stopped or no fresh source data exists. - Keep the short card badge compact, but pair color with text and an `AlertTriangle` icon so status is not color-only. ## Brand-compliant implementation notes - Use neutral card treatment with a small amber semantic badge; do not make the whole shipment card amber. - Keep carrier badges secondary and avoid carrier-brand color emphasis. - Tooltip text should name the data source problem: `Last sync failed`, `Carrier retention window expired`, or `No new carrier events`. - If possible, expose the longer explanation in the detail page as `Last sync` / `Source` metadata, not only in the card tooltip. ## Additional acceptance criteria - The badge uses calm operational copy, not the bare label `Stalled` alone. - The badge communicates the reason without hover on mobile. - Amber is used only as the semantic stale/delayed signal; default shipment surfaces remain neutral. --- Migrated from GitHub issue #1: https://github.com/bullitt186/trackbox/issues/1 Original author: @bullitt186 Original created: 2026-06-27T13:22:06Z Original labels: ux
bullitt changed title from Dashboard: Explain 'Stalled' badge inline — tooltip-only is not enough to Dashboard: Show stale-data reason inline using Trackbox status language 2026-06-27 15:46:21 +02:00
Author
Owner

Implemented in commit bd6b0e7. The stalled badge now shows inline reason text with an AlertTriangle icon — "Stalled · scrape errors" for scrape_failures, "Stalled · expired" for retention_expired, and "Stalled" otherwise. No hover required, works on touch devices. Brand-aligned: amber color only on the badge, operational language, no alarmism.

Implemented in commit bd6b0e7. The stalled badge now shows inline reason text with an AlertTriangle icon — "Stalled · scrape errors" for scrape_failures, "Stalled · expired" for retention_expired, and "Stalled" otherwise. No hover required, works on touch devices. Brand-aligned: amber color only on the badge, operational language, no alarmism.
Sign in to join this conversation.
No labels
arch
harness
security
ux
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
bullitt/trackbox#22
No description provided.