FleetOS UI/UX Overhaul — PRD for Claude Code

February 7, 2026 | Sprint 2: Dashboard & In-App Views

How to use this: Drop this file + the reference JSX into your repo, then tell Claude Code:

Read docs/PRD-UI-Overhaul.md and the reference component at docs/design-specs/fleetos-preview.jsx.
Start with Phase 0: Audit. Report current state before changing anything.

1. CONTEXT

What is FleetOS?

FleetOS is a fleet maintenance coordination platform. A fleet manager creates a service request, a supplier gets notified via WhatsApp magic link, taps it, sees the job, accepts with a quote, provides an ETA, and later marks the job complete with a final cost. No app download required for suppliers.

Tech Stack

  • Frontend: Vite + React + TypeScript

  • Backend: Supabase (Auth, DB, RLS, Realtime)

  • Hosting: Vercel

  • Live URL: https://fleetos.us

  • Repo: ZBO19/FleetOS

What happened in Sprint 1 (Feb 7)

Sprint 1 focused on:

  • ✅ Quote/cost tracking fields in Supabase schema

  • ✅ Step-based flow for magic link (external supplier view): VIEW → QUOTE → ETA → CONFIRMED

  • ✅ Status filters on dashboard

  • ⚠️ Final cost on magic link (COMPLETE step) — needs verification

  • ⚠️ Cost summary on fleet dashboard — needs verification

  • ❌ In-app supplier view — still uses old cramped layout (7+ buttons on one screen)

  • ⚠️ Mobile responsiveness — not fully tested

What Sprint 2 fixes

The in-app experience for both fleet managers and suppliers. We have a complete reference design (fleetos-preview.jsx) that shows exactly how both dashboards should look and behave. This PRD tells you how to implement it.


2. REFERENCE DESIGN SPECIFICATION

The file docs/design-specs/fleetos-preview.jsx is the target UI. Study it carefully. Here's what it defines:

2.1 App Structure

2.2 Fleet Manager View ("Today's Dispatch")

Summary Metrics Row (4 columns):

Metric
Source
Highlight Color

Unassigned

Count of status=UNASSIGNED

Red if > 0

Awaiting

Count of status=SENT

Yellow if > 0

Active

Count of ACCEPTED/EN_ROUTE/IN_PROGRESS

Slate

Today ($)

Sum of finalCost or quotedAmount

Slate

Filter Pills: All | Urgent | Today | Active | Done — each with count badge

Job Card (collapsed):

  • Urgency tag (URGENT/TODAY/SCHEDULED) + ETA if available

  • Job title (bold, 15px)

  • Vehicle + Location

  • Status badge (top-right)

  • Person chips: Supplier, Technician, Owner

  • Cost line: quoted (struck through if final exists) → final + diff (+/- colored)

  • Notes preview (truncated, single line)

  • Expand chevron

Job Card (expanded):

  • Full notes in a padded card

  • Audit Trail timeline with dot indicators and timestamps

  • Context-appropriate action buttons:

    • If status != COMPLETED: "Call Tech" + "WhatsApp" (small, secondary)

    • No other buttons for fleet manager — they observe, suppliers act

2.3 Supplier View ("My Jobs")

Summary Metrics Row (4 columns):

Metric
Source
Highlight Color

Action

Count of PENDING_RESPONSE

Yellow if > 0

Active

Count of ACCEPTED/EN_ROUTE/IN_PROGRESS

Slate

Done

Count of COMPLETED

Slate

Earned ($)

Sum of finalCost on completed jobs

Slate

Filter Pills: All | Action Needed | Active | Done — each with count badge

Job Card — PENDING_RESPONSE (Action Needed):

  • Auto-expanded (card starts open)

  • Shows: Respond to this request panel

    • Technician name input

    • Currency selector + Quote input (side by side)

    • Accept (green, primary) + Decline (red outline, secondary)

Job Card — IN_PROGRESS (Can Complete):

  • Expanded shows: Mark complete panel

    • Currency display + Final cost input (pre-filled with quoted amount)

    • Note input (optional)

    • "Complete Job" button (green, full width)

Job Card — Other statuses:

  • Same as fleet view but:

    • "Contact" label instead of "Owner" for the overseer

    • "Call Fleet" instead of "Call Tech" for action buttons

2.4 Design System (MUST MATCH)

Colors:

Status Badge Styles:

Status
Label
Color
Background

UNASSIGNED

Unassigned

Red

rgba(212,86,78,0.1)

SENT

Awaiting Reply

Yellow

rgba(250,204,21,0.10)

ACCEPTED

Accepted

Green

rgba(16,185,129,0.08)

EN_ROUTE

En Route

Yellow

rgba(250,204,21,0.10)

IN_PROGRESS

In Progress

Yellow

rgba(250,204,21,0.10)

COMPLETED

Done

Green

rgba(16,185,129,0.08)

PENDING_RESPONSE

Action Needed

Yellow

rgba(250,204,21,0.10)

Typography:

  • Font: system stack (-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif)

  • Page title: 20px, weight 800, -0.02em tracking

  • Card title: 15px, weight 700

  • Labels: 9-10px, weight 700, uppercase, 0.06-0.1em tracking

  • Body: 11-12px

  • Metrics: 18px monospace, weight 800

Component Patterns:

  • Border radius: 14px on cards, 10px on action panels, 8px on inputs, 20px on filter pills

  • Status badges: 16px border-radius (pill), 10px font, 700 weight

  • Urgency tags: 10px, 800 weight, 0.08em tracking, color only (no background)

  • Inputs: dark bg (rgba(17,24,39,0.6)), 1px border rgba(100,116,139,0.15), 13px font

  • Primary buttons: #10b981 bg, black text, 14px font, 700 weight

  • Secondary buttons: transparent bg, 1px border, slate text

2.5 Sort Order

Jobs are sorted by priority:

  1. UNASSIGNED / PENDING_RESPONSE (action needed — top)

  2. SENT (awaiting reply)

  3. EN_ROUTE

  4. IN_PROGRESS

  5. ACCEPTED

  6. COMPLETED (bottom)

Within same status, sort by urgency: URGENT → TODAY → SCHEDULED

2.6 Cost Display Logic

The CostLine component shows:

  • If only quotedAmount: show it in monospace, color #94a3b8

  • If both quotedAmount and finalCost: show quoted with strikethrough in #475569, then final in bold #e2e8f0

  • If finalCost differs from quoted: show diff in red (over) or green (under)

  • Currency prefix before amount

  • Format: {currency} {amount.toLocaleString()}

2.7 Audit Trail

Each job has a timeline array of events. Display as:

  • Vertical line on left (1px, rgba(100,116,139,0.12))

  • Dot per event (6px circle)

  • Last event dot is brighter (#94a3b8), others are dimmer

  • Event text + "by" attribution + timestamp (right-aligned)

  • Section header: "Audit Trail" in 9px uppercase


3. IMPLEMENTATION PHASES

Phase 0: Audit (DO THIS FIRST — DO NOT SKIP)

Phase 1: Data Layer Verification

Phase 2: Shared Components

Phase 3: Dashboard Layout

Phase 4: Job Card Component

Phase 5: Data Integration

Phase 6: Mobile Responsiveness

Phase 7: Polish & Cleanup


4. ACCEPTANCE CRITERIA

Sprint 2 is DONE when:

  1. ✅ Dashboard has working Fleet Manager / Supplier toggle

  2. ✅ Summary metrics compute correctly from real job data

  3. ✅ Filter pills work and show accurate counts

  4. ✅ Job cards expand/collapse with all fields visible

  5. ✅ Audit trail renders for every job

  6. ✅ Cost display shows quoted vs final with diff

  7. ✅ Supplier can accept a PENDING_RESPONSE job with technician + quote

  8. ✅ Supplier can complete an IN_PROGRESS job with final cost

  9. ✅ All actions persist to Supabase

  10. ✅ Everything renders correctly at 375px width

  11. ✅ Page loads in < 3 seconds on mobile

  12. ✅ No Robo-Hub references in FleetOS UI


5. WHAT NOT TO DO

  • ❌ Do NOT change the magic link (external supplier view) — it already works

  • ❌ Do NOT change the request creation flow — it works

  • ❌ Do NOT change Supabase auth or RLS policies unless required for a specific feature

  • ❌ Do NOT add new features not listed here (CSV export, analytics = Sprint 3)

  • ❌ Do NOT refactor to a different state management library

  • ❌ Do NOT change the routing structure

  • ❌ Do NOT touch T420 token, portal, Robo-Hub, or Robo-Dapp code

  • ❌ Do NOT introduce new npm dependencies unless absolutely necessary

  • ❌ Do NOT split components into separate CSS files — keep styles co-located (inline or Tailwind)

  • ❌ Do NOT change the Vercel deployment configuration


6. REFERENCE FILES

File
Purpose

docs/design-specs/fleetos-preview.jsx

THE TARGET UI — study this thoroughly

docs/PRD-UI-Overhaul.md

This document

Previous: docs/design-specs/supplier-view-reference.jsx

Magic link design (Sprint 1, already implemented)

Previous: docs/PRD-Feb7.md

Sprint 1 PRD (for context on what was already done)


7. HOW TO USE THIS PRD

For Zane (in terminal):

For Claude Code (reading this):

  1. Read the reference JSX first. Every component, every style, every interaction pattern is defined there. Your implementation should look and behave identically.

  2. Audit before building. Phase 0 exists because Sprint 1 may have already implemented some of these pieces. Don't rebuild what exists — extend and refine.

  3. One commit per phase. This keeps the git history clean and makes rollback easy if something breaks.

  4. Preserve existing API integration. The app already talks to Supabase. Don't rewrite the data layer — wire the new UI to existing services (QueryService, ContactService, etc.).

  5. Test at 375px. Open DevTools, set to iPhone SE width, verify every screen. This is the primary device for suppliers in the field.


PRD Version 2.0 | February 7, 2026 | Sprint 2: Dashboard & In-App Views Reference design: fleetos-preview.jsx (559 lines) Created by Claude Opus 4.6 for Zane/T420

Last updated

Was this helpful?