Skip to content

feat(dashboard): add the track record section to the panel - #2126

Closed
brunod-e wants to merge 48 commits into
feat/panel-v2.1-table-scrollfrom
feat/panel-v2.1-case-studies
Closed

feat(dashboard): add the track record section to the panel#2126
brunod-e wants to merge 48 commits into
feat/panel-v2.1-table-scrollfrom
feat/panel-v2.1-case-studies

Conversation

@brunod-e

@brunod-e brunod-e commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Part 4/6 of the Panel v2.1 stack (DEV-1148). Base: feat/panel-v2.1-table-scroll (#2125).

What changes

Section 4 of the spec — TRACK RECORD (the section title the design settled on, closing the spec's open question):

  • TrackRecordSection.tsx (new) — three outcome-framed case cards (ENS, Uniswap, Arbitrum) with the spec's final copy, each linking out to the blog.
  • TestimonialCarousel.tsx (new, client) — quote + avatar + name/role centred between two ghost prev/next IconButtons; the quote block links to the tweet it came from.
  • ClickableCard (design system) — gains an optional href (+ openInNewTab) so it renders as a Link instead of a button. The Figma component is named "Clickable Card" and annotated "These are links that take the user to the blog post", and a > button isn't valid, so the DS component needed the affordance. Same classes either way; existing onClick callers are unaffected.
  • shared/constants/track-record.ts (new) — the case and testimonial data.

Figma: 3633:96810.

Testimonials

Five, straight from the X mentions audit (Growth doc 2ky4wrw9-39373, re-verified Aug 2026) — wording verbatim, each entry linking to its source tweet:

Author Quote Source
Ethereum Foundation "using the Anticapture dashboard to break down what actually matters in practice" @ethereumfndn
Lefteris Karapetsas "makes it so easy to see when governance changes" @LefterisJP
@blockbanzai "Massively impressed by the @blockful_io team's @anticapture dashboard" @blockbanzai
@cupOJoseph "Blockful is doing the lords work keeping DAOs safe" @CupOJoseph
ENS DAO "@anticapture reports show ENS governance security improving" @ENS_DAO

All five are from the doc's Tier 1–2 ("usable social proof") pages and none appear on its do-not-use list. The placeholder Vitalik quote from the mockup is not shipped: his verified wording ("more recently @walletbeat @anticapture and others have been doing") is a sentence fragment that doesn't read as a testimonial. Say the word if you want it in anyway. @LoringHarkness was also skipped — the audit flags the same tweet as disputing the "attack" framing.

Two smaller gaps

  1. Avatars — no image assets for the handles, so the author block uses a neutral avatar placeholder. Drop in real images and the layout takes them as-is.
  2. Arbitrum icon — Arbitrum isn't in DaoIdEnum and there's no ArbitrumIcon in the repo; the Figma avatar is a Code-Connect component instance, not an exported asset, so there was nothing to download. ENS and Uniswap use DaoAvatarIcon; Arbitrum falls back to an initial. Needs an SVG from design.

Case URLs: only the ENS write-up has a published post; Uniswap and Arbitrum point at the publication root until theirs are live.

Verification

tsc --noEmit clean · eslint clean (pre-existing .stories.tsx default-export warnings only) · 527 tests / 54 suites pass · rendered locally at 1440px.

brunod-e and others added 4 commits August 13, 2026 13:19
The panel's TheSectionLayout title/description is replaced by the two-card
hero from the Panel v2.1 spec: a judgment headline, a subhead framing the
Stage system, and a link to the framework docs beside a "Governance risk,
right now" card.

DaoProtectionLevels moves from vertical Recharts bars to the horizontal
Stage 0/1/2 bars in the design, sized against the busiest stage, with the
per-stage hover kept on the design-system tooltip. Treasury Monitoring and
Delegated Supply History are retired with no replacement cards, per spec.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A one-line strip between the hero and the Monitored DAOs table: the LATEST
FINDING label, the finding sentence, and a link out to the case write-up.

The sentence and its URL come from a mock for now — swapping in a fetch of
the newest Paragraph publication only has to replace the two fields the
ticker reads.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The v2.1 panel is a scrolling page, not a single viewport: drop the table's
fillHeight and the min-h-0/flex-1 chain that made it scroll inside the
section, and let main scroll on desktop the way it already does on mobile.

The table itself is untouched — same columns, tooltips, and sorting.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three outcome-framed case cards (ENS, Uniswap, Arbitrum) that link out to
the write-ups, and a testimonial carousel below them.

ClickableCard grows an optional href so the Figma "Clickable Card" can be
what the design annotates it as — a link — instead of a button.

Case copy is final; only the ENS post has a published URL, and the
testimonial set carries just the wording already verified in the X mentions
audit. Both are marked for follow-up rather than filled with invented
attributions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
anticapture-storybook Ready Ready Preview Aug 17, 2026 4:20pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
anticapture Ignored Ignored Aug 17, 2026 4:20pm

Request Review

Isadora pointed at the source: the X mentions audit already carries the
verified wording, handles and links, so the carousel now ships five real
testimonials — Ethereum Foundation, Lefteris Karapetsas, @blockbanzai,
@cupOJoseph and ENS DAO — instead of one entry waiting on sign-off.

Nothing about this data is mocked any more, so it moves out of
mocked-data/ into shared/constants/track-record.ts. Each entry keeps the
tweet it was lifted from as its link.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
brunod-e and others added 7 commits August 13, 2026 19:18
Three pixel-level gaps found by measuring the rendered page against the
Figma frame:

- the hero cards split 597/565 instead of 582/582, because flex items
  default to `min-width: auto` and the left card's content set the floor;
- the row came out 184px tall against the design's 186px;
- the mono card title tracked at 0.72px, the fixed value behind
  `tracking-wider`, where 13px Alternative/Small calls for 0.78px (the
  token is right for the 12px labels, wrong one step up).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Same one-step-off letter-spacing as the hero card title: `tracking-wider`
resolves to a fixed 0.72px, which is the 12px value, not the 0.78px the
13px Alternative/Small style calls for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Figma card carries the same 1px borders/default outline as the case
cards above it; the class was there but the border width never was, so it
rendered flush against the background. Section label tracking corrected to
0.78px alongside.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ng it

Adds --tracking-alternative-sm alongside the existing --tracking-wider, so
the two mono label sizes both have a named value: 0.72px at 12px, 0.78px at
13px. Both are the same 6% the type styles specify — CSS letter-spacing
just can't take the percentage.

Drops the fixed hero height too. The remaining 2px against the frame comes
from the chart card's own rhythm, and pinning it would trade one magic
number for another.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
brunod-e and others added 6 commits August 13, 2026 19:43
The hero wrapped DaoProtectionLevels in a bare flex div only to hand it
min-w-0 flex-1. The card is used in exactly one place, so fold those
classes into the card itself and drop the wrapper.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…aws it

Two divergences from the hero frame, both in the stage chart.

The count was in a fixed third grid column, so it hugged the right edge of
the card no matter how long its bar was. Figma sizes every bar but the
widest one to its own content and lets the count follow immediately, so
only Stage 0 was landing where the design puts it. Bar and count now share
a flex track and the bar scales against that track less the count and its
gap, which reproduces the design's 418px widest bar exactly.

The title-to-chart gap was 12px against the design's 14. Figma gets there
by pinning the card to 186px and letting justify-between leave the slack;
gap-3.5 hits the same 186 without the fixed height. That also settles the
2px noted in fd7e9e0: with the card at 186 the hero's left column
stretches to match, putting its text-to-link gap on the design's 24px.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The ticker shipped a hardcoded finding pointing at the publication index, so
"Read the case" never opened the post it described. Paragraph exposes no JSON
API for a blog's posts, so the newest publication now comes off the public RSS
feed, revalidated hourly, falling back to the publication index whenever the
feed is unreachable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Uniswap and Arbitrum cards pointed at the publication index instead of
their own write-ups, Arbitrum fell back to an initial because it is not a
monitored DAO, and every testimonial rendered the generic person glyph.

- Uniswap and Arbitrum cards link to their Paragraph posts.
- ArbitrumIcon carries the avatar the Figma card draws, so cases can supply an
  icon without a daoConfig entry.
- Testimonials ship the profile picture of the account each quote is lifted
  from, as the design draws them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
brunod-e and others added 4 commits August 14, 2026 15:49
The cases, testimonials and their links are panel copy — the track record
section and the testimonial carousel are the only readers, and nothing outside
the feature has a reason to become one. Sitting in shared/constants it invited
that dependency; under features/panel it stays where the section that owns it
lives.

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 30a7fdd191

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/dashboard/features/panel/components/TestimonialCarousel.tsx Outdated
brunod-e and others added 2 commits August 14, 2026 16:18
…eset

The changeset still said the finding sentence was mocked pending a Paragraph
integration, but the same diff ships `getLatestParagraphPost()` reading the
publication's RSS feed server-side with a timeout and a publication-index
fallback. Changesets copies this text verbatim into the published CHANGELOG, so
leaving it would ship a release note telling readers the feature is a placeholder
when it is already live.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Activating an arrow keeps focus on that arrow and swaps the quote and author
underneath it. Nothing in the markup told assistive tech that region had
changed, so a screen-reader user pressed the button and heard silence — the
control read as broken unless they navigated back through the slide by hand.
The quote and its author now sit in a polite live region, atomic so the pair
announces as one testimonial instead of two loose text changes, and the strip
identifies itself as a labelled carousel.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
brunod-e and others added 7 commits August 17, 2026 10:57
The panel table container stops being a scrollport on desktop
(containerClassName escape hatch on the DS Table), so the sticky header
resolves against main, the page scroller. Mobile keeps the inner
horizontal scroll: the header never pinned there and HeaderMobile is
fixed with no specified offset to pin under.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The hero replaced the old Panel h4 and description, so the smoke test
asserted copy that no longer renders. CI did not catch it because the
Dashboard E2E job was skipped on this stack (gateful preview failure).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Measured at 1024px the table runs 58px wider than its container, so
lg:overflow-visible leaked a page-level horizontal scrollbar in the
1024-1279px band; the inner scrollport stays below xl. The pin test now
stubs the session like its sibling, re-scrolls on every poll tick since
metric cells stream in and grow the page, and measures the header in
the same evaluation as its precondition.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d5cbca34f8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/dashboard/features/panel/components/TestimonialCarousel.tsx Outdated
brunod-e and others added 5 commits August 17, 2026 12:26
…p range

Column headers wrap between lg and xl, removing the 58px table overflow
that forced the pin to xl, so the container can stop being a scrollport
from lg up. The pin e2e test now runs at 1024px and 1920px and asserts
main gains no horizontal overflow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…creen readers

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…p range

Column headers wrap between lg and xl, removing the 58px table overflow
that forced the pin to xl, so the container can stop being a scrollport
from lg up. The pin e2e test now runs at 1024px and 1920px and asserts
main gains no horizontal overflow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-studies

# Conflicts:
#	apps/dashboard/e2e/panel.spec.ts
@brunod-e

Copy link
Copy Markdown
Collaborator Author

Superseded by #2137, which combines the whole panel v2.1 stack into a single PR against dev.

@brunod-e brunod-e closed this Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants