Skip to content

feat(inbox): restyle to match target design — LIVE real, ROADMAP honestly dimmed (#112)#82

Merged
Omarear merged 2 commits into
mainfrom
feat/inbox-restyle
Jun 24, 2026
Merged

feat(inbox): restyle to match target design — LIVE real, ROADMAP honestly dimmed (#112)#82
Omarear merged 2 commits into
mainfrom
feat/inbox-restyle

Conversation

@Omarear

@Omarear Omarear commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Styling/layout pass over the inbox to match the attached target mockup, holding the LIVE/ROADMAP honesty contract — real data or honest empty states, never fabricated; features we don't have render visibly dimmed/"soon" and non-functional, never wired. No backend/feature/data changes. Branched from main (independent of PR #80).

Reconciliation (mockup element → what shipped)

Mockup Decision
Left-pane filter stack (Inbox+count · search · FILTER BY TAG · STATUS) BuiltListFilters (new)
FILTER BY TAG chip row (All / orders / …) LIVE — All + one chip per real workspace tag, drives the existing tagIds engine (closes the audit's cosmetic gap; replaces the popover)
STATUS Open / Unassigned / AI-handled / Closed Ours LIVE (Open/Resolved/Escalated/All) + Unassigned/AI-handled dimmed ROADMAP
Thread-header actions: Archive · Delete · Assign · Resolve Resolve/Reopen + Delete LIVE (moved here, confirm dialog intact); Assign dimmed. archive==resolve for us → single Resolve, no fake Archive
Contact panel: Copy email · fields · CSAT · Tags · Visitor context Copy email / Email-IP-Device-Started-Messages / CSAT / Tags add-remove all LIVE; Visitor context = honest "Not captured yet" em-dashes
Composer: Reply · Internal note · Suggest with AI · attach Reply + Send LIVE; Internal note / Suggest with AI / attach dimmed
Top-bar ⌘K search (pilled ROADMAP) Untouched — it's LIVE (shipped #81) and is shell, not inbox
Sample data ("Jordan Reese", "#4821", "32 total", "CSAT 4.0", rows) None shipped — real data only; sparse → honest empty states
Green LIVE / amber ROADMAP annotation pills Not shipped (design annotations only)

Notable, intentional changes (flagging, not silent)

  • Stat-card strip removed to match the mockup (which shows only a total). The real total is shown in the list header; per-conversation CSAT stays in the contact panel. The project-wide escalated / resolved / avg-rating aggregates are no longer displayed — surfaced by the adversarial review and kept dropped to match the design. Easy to re-add if you want them back.
  • Tags moved from the thread header to the contact panel; Resolve/Delete moved from the contact panel to the thread header — both per the mockup.
  • Deleted InboxToolbar / InboxStats / TagFilter (+ tests), superseded by ListFilters.

Honesty rail — enforced by tests

New/updated tests pin the contract: ListFilters.test (4 real status radios; Unassigned/AI-handled are NOT radios/buttons; data-driven tag chips; Manage gated to admin), ThreadActions.test (Resolve/Delete live + confirm; Assign is not a button), DetailPanel.test (real fields, visitor-context em-dashes never a value, Copy email, tags, no Resolve/Delete), ReplyComposer.test (Send live; Internal note / Suggest with AI / attach are not buttons), page.test (chip-filter end-to-end, Inbox heading, deep-link).

Adversarial review

3 parallel reviewers (honesty · layout/overflow/dark-tokens · correctness) → per-finding verification. Honesty: 0 findings (no fabricated data, every roadmap control is an inert aria-disabled span with no handler, no annotation pills ship). Layout: 0 findings (flex-wrap chip/pill rows, truncation everywhere, three-pane bounded min-h-0/overflow-y-auto chain intact, all ck/ds tokens so Light/Dark flip). Correctness flagged the (intentional) stats drop + a missing ReplyComposer test — test added.

⚠️ Screenshots — could not capture in this environment

I could not produce the requested CDP screenshots here: this sandbox's headless Chromium renders DOM (--dump-dom) but the screenshot rasterizer fails (no GPU/SwiftShader) and a resident CDP server won't stay up. I did not fabricate any. Verification instead rests on the adversarial honesty/layout review + the 409-test dashboard suite. To eyeball both themes locally: dashboard is at http://localhost:3001/inbox (sign in admin@example.com/admin@example.com), toggle theme via the mode switch. Before/after screenshots to be added by the reviewer.

Gates

dashboard 409 tests pass · tsc clean · lint 7/7 · prettier clean.

Deploy note: dashboard preview runs the kind: nextjs builder; if it fails No executable pnpm found, that's the known transient Ploy flake — re-trigger once.

🤖 Generated with Claude Code

…stly dimmed (#112)

Layout/styling pass over the inbox to match the target mockup while holding the
LIVE/ROADMAP honesty contract (real data or honest empty states — never
fabricated; unbuilt features render dimmed/"soon", non-functional, never wired).

Left pane (ListFilters, new): "Inbox" + real total → conversation search →
FILTER-BY-TAG chip row (All + each real workspace tag, replaces the popover —
drives the same tagIds engine) → STATUS pills (LIVE Open/Resolved/Escalated/All
+ dimmed ROADMAP Unassigned/AI-handled).

Thread header (ThreadActions, new): LIVE Resolve/Reopen + Delete (confirm,
non-optimistic) moved here from the contact panel; Assign rendered dimmed/inert.

Contact panel (DetailPanel): Copy email (LIVE) + merged CONTACT fields
(Email/IP/Device/Started/Messages) + CSAT (real) + Tags add/remove (moved here)
+ Visitor-context kept as the honest "Not captured yet" em-dash block.

Composer (ReplyComposer): Reply (LIVE) vs Internal-note (dimmed); Suggest-with-AI
and attach dimmed/inert; Send live.

- removed the stat-card strip + horizontal toolbar to match the mockup; the real
  total is shown in the list header (per-conversation CSAT stays). The
  escalated/resolved/avg aggregates are intentionally dropped (mockup has none).
- top-bar ⌘K search left untouched: it's LIVE (#81) and shell, not inbox.
- inbox project switcher kept (our per-project filter); archive==resolve so a
  single Resolve, not a fake Archive. No LIVE/ROADMAP annotation pills ship.
- deleted InboxToolbar / InboxStats / TagFilter (+ tests), superseded.

Adversarial review: honesty + layout reviewers found 0 issues; correctness flagged
the (intentional) stats drop + a missing ReplyComposer test — test added. Gates:
dashboard 409 tests, tsc + lint + prettier clean. Three-pane bounded layout intact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@meet-ploy

meet-ploy Bot commented Jun 24, 2026

Copy link
Copy Markdown

✅ All deployments successful!

Project Deployment Branch Preview Commit Preview
llmchat-api Ready Preview Preview
llmchat-dashboard Ready Preview Preview
llmchat-marketing Ready Preview Preview
llmchat-showcase Ready Preview Preview

Deployed with Ploy

…(#112)

Two placement fixes on the inbox restyle; honesty rail + ROADMAP dimming
unchanged.

1. Search moved to the CENTER of the top bar as a wide box ("Search
   conversations & projects… ⌘K"), matching the target — was top-right. Pure
   reposition/restyle of the trigger; the ⌘K palette logic (#81) is untouched
   (still opens + routes). Mobile keeps the icon trigger.
2. Restored the stats panel dropped by the restyle (Conversations / Escalated /
   Resolved / Avg rating) — real server aggregates, honest 0s when empty. Placed
   as a compact 2-col grid at the top of the list pane (fits the narrow column)
   and replaces the redundant "N total" line. This was a regression, not a cut.

Tests: top-bar.test (centered trigger fires onOpenSearch + ⌘K hint/placeholder);
InboxStats restored with its test; ListFilters.test updated for the stats prop.
Gates: dashboard 415 tests, tsc + lint + prettier clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@steebchen steebchen temporarily deployed to llmchat-dashboard--preview June 24, 2026 20:21 — with Meet Ploy Inactive
@steebchen steebchen temporarily deployed to llmchat-marketing--preview June 24, 2026 20:21 — with Meet Ploy Inactive
@steebchen steebchen temporarily deployed to llmchat-showcase--preview June 24, 2026 20:21 — with Meet Ploy Inactive
@Omarear

Omarear commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator Author

Reconciliation (mockup element → what shipped)

Mockup Decision
Left-pane filter stack (Inbox+count · search · FILTER BY TAG · STATUS) BuiltListFilters (new)
FILTER BY TAG chip row (All / orders / …) LIVE — All + one chip per real workspace tag, drives the existing tagIds engine (closes the audit's cosmetic gap; replaces the popover)
STATUS Open / Unassigned / AI-handled / Closed Ours LIVE (Open/Resolved/Escalated/All) + Unassigned/AI-handled dimmed ROADMAP
Thread-header actions: Archive · Delete · Assign · Resolve Resolve/Reopen + Delete LIVE (moved here, confirm dialog intact); Assign dimmed. archive==resolve for us → single Resolve, no fake Archive
Contact panel: Copy email · fields · CSAT · Tags · Visitor context Copy email / Email-IP-Device-Started-Messages / CSAT / Tags add-remove all LIVE; Visitor context = honest "Not captured yet" em-dashes
Composer: Reply · Internal note · Suggest with AI · attach Reply + Send LIVE; Internal note / Suggest with AI / attach dimmed
Top-bar ⌘K search (pilled ROADMAP) Untouched — it's LIVE (shipped #81) and is shell, not inbox
Sample data ("Jordan Reese", "#4821", "32 total", "CSAT 4.0", rows) None shipped — real data only; sparse → honest empty states
Green LIVE / amber ROADMAP annotation pills Not shipped (design annotations only)

Notable, intentional changes (flagging, not silent)

  • Stat-card strip removed to match the mockup (which shows only a total). The real total is shown in the list header; per-conversation CSAT stays in the contact panel. The project-wide escalated / resolved / avg-rating aggregates are no longer displayed — surfaced by the adversarial review and kept dropped to match the design. Easy to re-add if you want them back.
  • Tags moved from the thread header to the contact panel; Resolve/Delete moved from the contact panel to the thread header — both per the mockup.
  • Deleted InboxToolbar / InboxStats / TagFilter (+ tests), superseded by ListFilters.

Honesty rail — enforced by tests

New/updated tests pin the contract: ListFilters.test (4 real status radios; Unassigned/AI-handled are NOT radios/buttons; data-driven tag chips; Manage gated to admin), ThreadActions.test (Resolve/Delete live + confirm; Assign is not a button), DetailPanel.test (real fields, visitor-context em-dashes never a value, Copy email, tags, no Resolve/Delete), ReplyComposer.test (Send live; Internal note / Suggest with AI / attach are not buttons), page.test (chip-filter end-to-end, Inbox heading, deep-link).

Adversarial review

3 parallel reviewers (honesty · layout/overflow/dark-tokens · correctness) → per-finding verification. Honesty: 0 findings (no fabricated data, every roadmap control is an inert aria-disabled span with no handler, no annotation pills ship). Layout: 0 findings (flex-wrap chip/pill rows, truncation everywhere, three-pane bounded min-h-0/overflow-y-auto chain intact, all ck/ds tokens so Light/Dark flip). Correctness flagged the (intentional) stats drop + a missing ReplyComposer test — test added.

⚠️ Screenshots — could not capture in this environment

I could not produce the requested CDP screenshots here: this sandbox's headless Chromium renders DOM (--dump-dom) but the screenshot rasterizer fails (no GPU/SwiftShader) and a resident CDP server won't stay up. I did not fabricate any. Verification instead rests on the adversarial honesty/layout review + the 409-test dashboard suite. To eyeball both themes locally: dashboard is at http://localhost:3001/inbox (sign in admin@example.com/admin@example.com), toggle theme via the mode switch. Before/after screenshots to be added by the reviewer.

Gates

dashboard 409 tests pass · tsc clean · lint 7/7 · prettier clean.

Deploy note: dashboard preview runs the kind: nextjs builder; if it fails No executable pnpm found, that's the known transient Ploy flake — re-trigger once.

🤖 Generated with Claude Code


Update — two placement fixes (commit 276d2bb)

Per review feedback; honesty rail + ROADMAP dimming unchanged.

  1. Search moved to the CENTER of the top bar — now a wide box ("Search conversations & projects… ⌘K"), matching the target (was top-right). Pure reposition/restyle of the trigger; the ⌘K palette logic (feat(search): ⌘K workspace-wide global search + inbox deep-link (#101) #81) is untouched — still opens + routes; mobile keeps the icon trigger. Covered by a new top-bar.test.
  2. Restored the LIVE stats panel (Conversations / Escalated / Resolved / Avg rating) that the restyle had dropped — real server aggregates, honest 0s when empty (this corrects the intentional-cut note above; it is restored). Placed as a compact 2-col grid at the top of the list pane (fits the narrow column), replacing the redundant "N total" line. InboxStats restored with its test.

Gates after fixes: dashboard 415 tests · tsc + lint + prettier clean. (CDP screenshots still not capturable in this sandbox — see note above; verify locally at :3001/inbox.)

@steebchen steebchen temporarily deployed to llmchat-api--preview June 24, 2026 20:24 — with Meet Ploy Inactive
@Omarear Omarear merged commit d425618 into main Jun 24, 2026
1 check passed
@Omarear Omarear deleted the feat/inbox-restyle branch June 24, 2026 20:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants