Repository navigation
PROJ-1285 Polish web-next homepage - #325
Conversation
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
WalkthroughThe PR refreshes the public ChangesHomepage refresh and navigation
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related issues
Possibly related PRs
Suggested labels: Sequence Diagram(s)sequenceDiagram
participant Visitor
participant AppPage as web-next/app/page.tsx
participant Hero as web-next/components/hero-section.tsx
participant GetStarted as web-next/components/get-started-section.tsx
participant LandingCTAs as web-next/components/landing-ctas.tsx
participant Bento as web-next/components/bento-section.tsx
participant Changelog as web-next/components/changelog-section.tsx
participant Footer as web-next/components/footer-section.tsx
Visitor->>AppPage: Load /
AppPage->>Hero: Render full-bleed hero
Hero->>LandingCTAs: Render DemoCTA
AppPage->>GetStarted: Render reviewer flow
GetStarted->>LandingCTAs: Render DemoCTA and SignInCTA
AppPage->>Bento: Render live snapshot features
AppPage->>Changelog: Render live changelog entries
AppPage->>Footer: Render real navigation links
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
Warning Review ran into problems🔥 ProblemsThese MCP integrations need to be re-authenticated in the Integrations settings: Notion, Linear Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@web-next/app/page.tsx`:
- Around line 55-57: The FAQ block is rendering duplicate faq-section IDs
because AnimatedSection forwards the id to its wrapper and FAQSection also sets
the same root id; keep the id on only one element in the
FAQSection/AnimatedSection composition so anchor lookups resolve predictably.
Update the page composition around AnimatedSection and FAQSection to ensure only
one DOM node owns faq-section, and add a regression test covering the FAQ anchor
target/getElementById behavior.
In `@web-next/components/bento-section.tsx`:
- Around line 4-19: `formatPercent` should use the same validation/clamping
behavior as `unitIntervalToPercent` so the VoteWeightsUI bar and label stay
consistent. Update `formatPercent` in `bento-section.tsx` to guard non-finite
values and clamp inputs to the valid 0–1 range before formatting, matching how
`unitIntervalToPercent` handles `item.value`. Keep the formatting logic aligned
for the shared `LIVE_METRICS_SNAPSHOT.weights` values used in `VoteWeightsUI`,
and add a test covering malformed inputs like `NaN` and `1.4` to verify both the
bar width and percent label render consistently.
In `@web-next/components/changelog-section.tsx`:
- Around line 4-31: The changelog badge tags in changelog-section are loosely
coupled, so a future tag typo or new category can break styling at runtime
without a TypeScript error. Tighten the relationship by introducing a shared
literal union or derived tag type for the entries array and use it to type
tagColors and entry.tag so the compiler enforces that every tag has a matching
color mapping and vice versa.
In `@web-next/components/cta-section.tsx`:
- Around line 22-40: The `/demo` and `/sign-in` CTA buttons in this section are
duplicated with identical labels, hrefs, and Tailwind styling, matching the
copies in `hero-section.tsx` and `get-started-section.tsx`. Extract the shared
button markup into reusable components such as `DemoCTA` and `SignInCTA` (or a
small primary/secondary CTA button pair), then replace the inline `Link` +
`Button` blocks here with those shared components so styling and behavior stay
centralized.
In `@web-next/components/dashboard-preview.tsx`:
- Around line 5-11: `clampScoreBarPercent` in `dashboard-preview.tsx` duplicates
the same percent-clamping logic already used by `unitIntervalToPercent` in
`bento-section.tsx`, so extract the shared behavior into a common utility and
have both call it. Create a reusable helper (for example in a shared util
module) that handles the `!Number.isFinite` guard and clamping to 0–100, with an
option to preserve the current `Math.abs` behavior for `clampScoreBarPercent` if
needed. Update both `clampScoreBarPercent` and `unitIntervalToPercent` to use
the shared helper so the implementations stay aligned.
In `@web-next/components/footer-section.tsx`:
- Around line 60-62: The footer Audit log link in footer-section.tsx is pointing
to the dashboard summary instead of the full audit log; update the Link used for
“Audit log” to target the full history route or change the label to match the
dashboard scope. Use the FooterSection component’s Link entry for this item, and
add/update a footer link test to assert the Audit log text and href stay
aligned.
In `@web-next/components/hero-section.tsx`:
- Around line 9-22: The hero background SVG in hero-section.tsx does not cover
the widened 1440px viewBox, leaving a gap on the right. Update the SVG mask
dimensions and the grid generation logic inside the hero background markup so
the masked grid, row loop, and any gradient/end coordinates extend to the full
1440-width canvas. Use the existing SVG background section and its row/column
loop as the place to adjust coverage, then verify the pattern spans the entire
hero at wide desktop sizes.
In `@web-next/components/social-proof.tsx`:
- Around line 13-16: Replace the external GitHub URL usage in the social-proof
link rendering with a plain anchor instead of next/link, following the same
pattern as hero-section.tsx for external destinations. Update the social-proof
component’s link markup so the href to github.com uses an ordinary <a> with the
existing label and external link behavior, and keep the change consistent for
the other mentioned occurrence as well.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2ef0ca08-22da-4fc7-b8a3-d7558759ef38
📒 Files selected for processing (12)
CHANGELOG.mdtests/web-next-demo-fixtures.test.tsweb-next/app/page.tsxweb-next/components/bento-section.tsxweb-next/components/changelog-section.tsxweb-next/components/cta-section.tsxweb-next/components/dashboard-preview.tsxweb-next/components/footer-section.tsxweb-next/components/get-started-section.tsxweb-next/components/hero-section.tsxweb-next/components/sign-in-dialog.tsxweb-next/components/social-proof.tsx
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
0b5ea52 to
8b379cf
Compare
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/web-next-homepage-anchors.test.ts`:
- Around line 13-19: The current test in web-next-homepage-anchors is brittle
because it inspects raw source strings instead of the rendered DOM. Update the
check around Page and FAQSection so it renders the component tree (for example,
via a JSDOM/testing-library test) and asserts that
document.querySelectorAll('`#faq-section`') returns exactly one element, ensuring
the invariant is verified by behavior rather than literal source matching.
- Around line 21-26: The footer audit log test is using two independent
substring checks, so it does not verify that “Audit log” is actually linked to
"/history". Update the test in web-next-homepage-anchors.test.ts to assert the
href and label belong to the same Link in footer-section.tsx, using the existing
footer content fixture and the footer link markup around the Audit log anchor.
This should make the assertion target the specific footer-section.tsx link
rather than any separate occurrence of the text.
In `@tests/web-next-percent.test.ts`:
- Around line 8-23: The percent helper tests in web-next percent helpers are
missing important edge cases and direct coverage of the lowest-level helper.
Update the test file to import and assert clampPercentValue directly, and add
boundary/Infinity cases for unitIntervalToPercentValue and
formatUnitIntervalPercent at 0, 1, Infinity, and -Infinity alongside the
existing NaN/out-of-range checks. Also verify the .5 rounding behavior through
clampPercentValue so the helper chain is covered from the bottom up.
In `@web-next/components/landing-ctas.tsx`:
- Around line 9-22: The landing CTA components currently wrap Button inside
Link, creating nested interactive elements. Update both DemoCTA and SignInCTA in
landing-ctas.tsx to use Button with asChild so the Link becomes the actual
rendered control. Then add a regression test covering both CTA variants to
verify the rendered markup does not include a nested button inside an anchor.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 77c8dbfa-ddf2-4ed7-92ae-0b5071b7c071
📒 Files selected for processing (13)
tests/web-next-homepage-anchors.test.tstests/web-next-percent.test.tsweb-next/app/page.tsxweb-next/components/bento-section.tsxweb-next/components/changelog-section.tsxweb-next/components/cta-section.tsxweb-next/components/dashboard-preview.tsxweb-next/components/footer-section.tsxweb-next/components/get-started-section.tsxweb-next/components/hero-section.tsxweb-next/components/landing-ctas.tsxweb-next/components/social-proof.tsxweb-next/lib/percent.ts
8b379cf to
ec56b2a
Compare
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@web-next/components/bento-section.tsx`:
- Around line 5-8: formatScore currently formats NaN/Infinity as a misleading
signed string, so add a non-finite guard to this helper in bento-section.tsx and
make it fail safely like the percent formatters. Update the
ScoreBreakdownUI/MixedFeedUI rendering path to use the guarded formatScore
behavior, and add a test or story that feeds NaN and Infinity through
LIVE_RANK_ONE_EXPLANATION.totalScore to verify the receipt still renders a sane
fallback value instead of "-NaN".
In `@web-next/components/dashboard-preview.tsx`:
- Around line 6-14: The score sign/absolute formatting is duplicated in
DashboardPreview and the existing formatScore helper in BentoSection, so move
this logic into a shared helper next to percent.ts. Add a reusable
formatSignedScore-style function there, then update DashboardPreview and
bento-section.tsx to import it and use it for component values and
totalScorePrefix. Keep the helper as the single source of truth so future
NaN/formatting changes stay consistent across both call sites.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: ac9b2405-d2aa-4802-b0f8-a46433114604
📒 Files selected for processing (16)
CHANGELOG.mdtests/web-next-demo-fixtures.test.tstests/web-next-homepage-anchors.test.tstests/web-next-percent.test.tsweb-next/app/page.tsxweb-next/components/bento-section.tsxweb-next/components/changelog-section.tsxweb-next/components/cta-section.tsxweb-next/components/dashboard-preview.tsxweb-next/components/footer-section.tsxweb-next/components/get-started-section.tsxweb-next/components/hero-section.tsxweb-next/components/landing-ctas.tsxweb-next/components/sign-in-dialog.tsxweb-next/components/social-proof.tsxweb-next/lib/percent.ts
ec56b2a to
a067e75
Compare
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@web-next/components/landing-ctas.tsx`:
- Around line 9-40: Add regression tests for the shared CTA components in
landing-ctas.tsx by covering DemoCTA and SignInCTA rendering through Button
asChild with Link, asserting each produces a single anchor with the correct href
(/demo and /sign-in) and no nested button element. Also verify the className
prop passed into LandingCTAProps is merged with the base styles from cn without
dropping the required layout/classes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: e62349c8-8f08-4daa-a246-143d05044e95
📒 Files selected for processing (15)
tests/web-next-homepage-anchors.test.tstests/web-next-percent.test.tstests/web-next-score.test.tsweb-next/app/page.tsxweb-next/components/bento-section.tsxweb-next/components/changelog-section.tsxweb-next/components/cta-section.tsxweb-next/components/dashboard-preview.tsxweb-next/components/footer-section.tsxweb-next/components/get-started-section.tsxweb-next/components/hero-section.tsxweb-next/components/landing-ctas.tsxweb-next/components/social-proof.tsxweb-next/lib/percent.tsweb-next/lib/score.ts
a067e75 to
5aa554f
Compare
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/web-next-landing-ctas-render.test.tsx`:
- Around line 1-2: The test imports are using hardcoded relative node_modules
paths, which breaks resolution in CI when dependencies are hoisted or deduped.
Update the imports in tests/web-next-landing-ctas-render.test.tsx to use bare
package specifiers for react and react-dom/server so Vitest can resolve them
correctly; locate and replace the imports at the top of the file.
- Around line 34-56: The CTA render tests only cover the happy path, so add an
edge-case around className merging for DemoCTA and SignInCTA. In web-next
landing CTA tests, assert that required base classes from the CTA components
still remain when a conflicting or overriding className is passed, using the
DemoCTA and SignInCTA symbols to locate the render paths. Focus the new coverage
on cn() merge behavior so consumer-supplied classes cannot remove essential
layout/style classes like rounded-full and bg-primary.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 593d47b6-bbf0-4414-a03d-86313114ea25
📒 Files selected for processing (17)
tests/web-next-homepage-anchors.test.tstests/web-next-landing-ctas-render.test.tsxtests/web-next-percent.test.tstests/web-next-score.test.tsvitest.config.tsweb-next/app/page.tsxweb-next/components/bento-section.tsxweb-next/components/changelog-section.tsxweb-next/components/cta-section.tsxweb-next/components/dashboard-preview.tsxweb-next/components/footer-section.tsxweb-next/components/get-started-section.tsxweb-next/components/hero-section.tsxweb-next/components/landing-ctas.tsxweb-next/components/social-proof.tsxweb-next/lib/percent.tsweb-next/lib/score.ts
5aa554f to
c514546
Compare
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/web-next-score.test.ts`:
- Around line 14-27: Add an explicit boundary assertion in the web-next score
tests for the zero sign behavior in formatSignedScore, since its branch uses
normalizedValue >= 0. Extend the existing test in tests/web-next-score.test.ts
to verify that formatSignedScore(-0) returns "+0.00" alongside the current
non-finite and rounding cases, so the zero/-0 boundary is covered even if the
implementation of formatSignedScore or normalizeScoreValue changes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: d28048fe-eb12-4322-8139-f277f66f7b5b
📒 Files selected for processing (17)
tests/web-next-homepage-anchors.test.tstests/web-next-landing-ctas-render.test.tsxtests/web-next-percent.test.tstests/web-next-score.test.tsvitest.config.tsweb-next/app/page.tsxweb-next/components/bento-section.tsxweb-next/components/changelog-section.tsxweb-next/components/cta-section.tsxweb-next/components/dashboard-preview.tsxweb-next/components/footer-section.tsxweb-next/components/get-started-section.tsxweb-next/components/hero-section.tsxweb-next/components/landing-ctas.tsxweb-next/components/social-proof.tsxweb-next/lib/percent.tsweb-next/lib/score.ts
c514546 to
1a372d8
Compare
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
1a372d8 to
76b609c
Compare
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web-next/components/hero-section.tsx (1)
157-161: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winNested
<button>inside<a>on secondary CTA — invalid HTML, same issue already fixed forDemoCTA/SignInCTA.
Link href="#features-section"wrapsButton variant="ghost", producing a<button>nested inside an<a>. This is invalid HTML and creates ambiguous/duplicate interactive targets for screen readers and keyboard nav (Tab lands on two controls for one action). This exact pattern was already flagged and fixed elsewhere in this PR by switchingDemoCTA/SignInCTAtoButton asChild; this remaining instance sits in the same CTA row and should get the same treatment.🔧 Proposed fix
- <Link href="`#features-section`"> - <Button variant="ghost" className="text-foreground/70 hover:text-foreground px-5 py-3 rounded-full font-medium text-base"> - See how ranking works → - </Button> - </Link> + <Button asChild variant="ghost" className="text-foreground/70 hover:text-foreground px-5 py-3 rounded-full font-medium text-base"> + <Link href="`#features-section`"> + See how ranking works → + </Link> + </Button>Consider adding a test case (alongside the existing
landing-ctasrender tests) asserting this hero CTA row renders no nested<button>inside<a>.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web-next/components/hero-section.tsx` around lines 157 - 161, The secondary CTA in hero-section still nests a Button inside a Link, creating invalid anchor/button markup. Update the CTA in the hero section to use the same Button asChild pattern already applied to DemoCTA and SignInCTA so the link is rendered without an inner button. Use the Link and Button usage in the hero CTA row to locate and align this fix, and add a render test in the existing landing-ctas coverage to ensure this CTA does not produce a nested button inside an anchor.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/web-next-landing-ctas-render.test.tsx`:
- Around line 96-136: Add a test case in web-next landing CTAs coverage that
renders DemoCTA and SignInCTA without passing className, since
LandingCTAProps.className is optional. Use the existing DemoCTA and SignInCTA
symbols from the test file and assert the default markup still includes the
required base classes such as inline-flex, rounded-full, and bg-primary,
confirming cn(baseClasses, undefined) works for the default render path.
In `@web-next/components/bento-section.tsx`:
- Around line 203-210: The receipt CTA in BentoSection points to a /demo hash
that does not exist, so add the matching anchor to the demo receipt/explanation
block in DemoPage and make sure it uses the same rank-based id pattern as
LIVE_RANK_ONE_EXPLANATION.rank. Update the relevant JSX in
web-next/app/demo/page.tsx so the rendered receipt section includes
id="snapshot-rank-${rank}", and add a test that verifies the anchor is present
for the rendered rank.
---
Outside diff comments:
In `@web-next/components/hero-section.tsx`:
- Around line 157-161: The secondary CTA in hero-section still nests a Button
inside a Link, creating invalid anchor/button markup. Update the CTA in the hero
section to use the same Button asChild pattern already applied to DemoCTA and
SignInCTA so the link is rendered without an inner button. Use the Link and
Button usage in the hero CTA row to locate and align this fix, and add a render
test in the existing landing-ctas coverage to ensure this CTA does not produce a
nested button inside an anchor.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 241683ed-6860-437e-bc5f-1732c21fbf0a
📒 Files selected for processing (20)
CHANGELOG.mdtests/web-next-demo-fixtures.test.tstests/web-next-homepage-anchors.test.tstests/web-next-landing-ctas-render.test.tsxtests/web-next-percent.test.tstests/web-next-score.test.tsvitest.config.tsweb-next/app/page.tsxweb-next/components/bento-section.tsxweb-next/components/changelog-section.tsxweb-next/components/cta-section.tsxweb-next/components/dashboard-preview.tsxweb-next/components/footer-section.tsxweb-next/components/get-started-section.tsxweb-next/components/hero-section.tsxweb-next/components/landing-ctas.tsxweb-next/components/sign-in-dialog.tsxweb-next/components/social-proof.tsxweb-next/lib/percent.tsweb-next/lib/score.ts
| describe('web-next landing CTAs', () => { | ||
| it('renders DemoCTA as one demo anchor without a nested button', () => { | ||
| const markup = renderToStaticMarkup(createElement(DemoCTA, { className: 'qa-demo-class' })); | ||
|
|
||
| expect(countMatches(markup, /<a\b/g)).toBe(1); | ||
| expect(markup).toContain('href="/demo"'); | ||
| expect(markup).not.toContain('<button'); | ||
| expect(markup).toContain('qa-demo-class'); | ||
| expect(markup).toContain('inline-flex'); | ||
| expect(markup).toContain('rounded-full'); | ||
| expect(markup).toContain('bg-primary'); | ||
| }); | ||
|
|
||
| it('renders SignInCTA as one sign-in anchor without a nested button', () => { | ||
| const markup = renderToStaticMarkup(createElement(SignInCTA, { className: 'qa-sign-in-class' })); | ||
|
|
||
| expect(countMatches(markup, /<a\b/g)).toBe(1); | ||
| expect(markup).toContain('href="/sign-in"'); | ||
| expect(markup).not.toContain('<button'); | ||
| expect(markup).toContain('qa-sign-in-class'); | ||
| expect(markup).toContain('inline-flex'); | ||
| expect(markup).toContain('rounded-full'); | ||
| }); | ||
|
|
||
| it('keeps required base CTA classes when optional className adds layout tokens', () => { | ||
| const demoMarkup = renderToStaticMarkup(createElement(DemoCTA, { className: 'qa-demo-wide sm:px-8' })); | ||
| const signInMarkup = renderToStaticMarkup(createElement(SignInCTA, { className: 'qa-sign-in-wide sm:px-6' })); | ||
|
|
||
| expect(demoMarkup).toContain('qa-demo-wide'); | ||
| expect(demoMarkup).toContain('sm:px-8'); | ||
| expect(demoMarkup).toContain('inline-flex'); | ||
| expect(demoMarkup).toContain('rounded-full'); | ||
| expect(demoMarkup).toContain('bg-primary'); | ||
|
|
||
| expect(signInMarkup).toContain('qa-sign-in-wide'); | ||
| expect(signInMarkup).toContain('sm:px-6'); | ||
| expect(signInMarkup).toContain('inline-flex'); | ||
| expect(signInMarkup).toContain('rounded-full'); | ||
| expect(signInMarkup).toContain('hover:text-foreground'); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win
Missing edge case: default render with no className prop.
All three tests pass a className. LandingCTAProps.className is optional (per landing-ctas.tsx), so add a case rendering DemoCTA/SignInCTA with no className at all to confirm cn(baseClasses, undefined) doesn't throw and still emits the required base classes (bg-primary, rounded-full, inline-flex) — this is the actual default homepage render path and isn't currently covered.
🧪 Suggested test case
it('keeps required base CTA classes when optional className adds layout tokens', () => {
...
});
+
+ it('renders DemoCTA and SignInCTA with base classes when no className is provided', () => {
+ const demoMarkup = renderToStaticMarkup(createElement(DemoCTA, {}));
+ const signInMarkup = renderToStaticMarkup(createElement(SignInCTA, {}));
+
+ expect(demoMarkup).toContain('inline-flex');
+ expect(demoMarkup).toContain('rounded-full');
+ expect(demoMarkup).toContain('bg-primary');
+ expect(signInMarkup).toContain('inline-flex');
+ expect(signInMarkup).toContain('rounded-full');
+ });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| describe('web-next landing CTAs', () => { | |
| it('renders DemoCTA as one demo anchor without a nested button', () => { | |
| const markup = renderToStaticMarkup(createElement(DemoCTA, { className: 'qa-demo-class' })); | |
| expect(countMatches(markup, /<a\b/g)).toBe(1); | |
| expect(markup).toContain('href="/demo"'); | |
| expect(markup).not.toContain('<button'); | |
| expect(markup).toContain('qa-demo-class'); | |
| expect(markup).toContain('inline-flex'); | |
| expect(markup).toContain('rounded-full'); | |
| expect(markup).toContain('bg-primary'); | |
| }); | |
| it('renders SignInCTA as one sign-in anchor without a nested button', () => { | |
| const markup = renderToStaticMarkup(createElement(SignInCTA, { className: 'qa-sign-in-class' })); | |
| expect(countMatches(markup, /<a\b/g)).toBe(1); | |
| expect(markup).toContain('href="/sign-in"'); | |
| expect(markup).not.toContain('<button'); | |
| expect(markup).toContain('qa-sign-in-class'); | |
| expect(markup).toContain('inline-flex'); | |
| expect(markup).toContain('rounded-full'); | |
| }); | |
| it('keeps required base CTA classes when optional className adds layout tokens', () => { | |
| const demoMarkup = renderToStaticMarkup(createElement(DemoCTA, { className: 'qa-demo-wide sm:px-8' })); | |
| const signInMarkup = renderToStaticMarkup(createElement(SignInCTA, { className: 'qa-sign-in-wide sm:px-6' })); | |
| expect(demoMarkup).toContain('qa-demo-wide'); | |
| expect(demoMarkup).toContain('sm:px-8'); | |
| expect(demoMarkup).toContain('inline-flex'); | |
| expect(demoMarkup).toContain('rounded-full'); | |
| expect(demoMarkup).toContain('bg-primary'); | |
| expect(signInMarkup).toContain('qa-sign-in-wide'); | |
| expect(signInMarkup).toContain('sm:px-6'); | |
| expect(signInMarkup).toContain('inline-flex'); | |
| expect(signInMarkup).toContain('rounded-full'); | |
| expect(signInMarkup).toContain('hover:text-foreground'); | |
| }); | |
| }); | |
| describe('web-next landing CTAs', () => { | |
| it('renders DemoCTA as one demo anchor without a nested button', () => { | |
| const markup = renderToStaticMarkup(createElement(DemoCTA, { className: 'qa-demo-class' })); | |
| expect(countMatches(markup, /<a\b/g)).toBe(1); | |
| expect(markup).toContain('href="/demo"'); | |
| expect(markup).not.toContain('<button'); | |
| expect(markup).toContain('qa-demo-class'); | |
| expect(markup).toContain('inline-flex'); | |
| expect(markup).toContain('rounded-full'); | |
| expect(markup).toContain('bg-primary'); | |
| }); | |
| it('renders SignInCTA as one sign-in anchor without a nested button', () => { | |
| const markup = renderToStaticMarkup(createElement(SignInCTA, { className: 'qa-sign-in-class' })); | |
| expect(countMatches(markup, /<a\b/g)).toBe(1); | |
| expect(markup).toContain('href="/sign-in"'); | |
| expect(markup).not.toContain('<button'); | |
| expect(markup).toContain('qa-sign-in-class'); | |
| expect(markup).toContain('inline-flex'); | |
| expect(markup).toContain('rounded-full'); | |
| }); | |
| it('keeps required base CTA classes when optional className adds layout tokens', () => { | |
| const demoMarkup = renderToStaticMarkup(createElement(DemoCTA, { className: 'qa-demo-wide sm:px-8' })); | |
| const signInMarkup = renderToStaticMarkup(createElement(SignInCTA, { className: 'qa-sign-in-wide sm:px-6' })); | |
| expect(demoMarkup).toContain('qa-demo-wide'); | |
| expect(demoMarkup).toContain('sm:px-8'); | |
| expect(demoMarkup).toContain('inline-flex'); | |
| expect(demoMarkup).toContain('rounded-full'); | |
| expect(demoMarkup).toContain('bg-primary'); | |
| expect(signInMarkup).toContain('qa-sign-in-wide'); | |
| expect(signInMarkup).toContain('sm:px-6'); | |
| expect(signInMarkup).toContain('inline-flex'); | |
| expect(signInMarkup).toContain('rounded-full'); | |
| expect(signInMarkup).toContain('hover:text-foreground'); | |
| }); | |
| it('renders DemoCTA and SignInCTA with base classes when no className is provided', () => { | |
| const demoMarkup = renderToStaticMarkup(createElement(DemoCTA, {})); | |
| const signInMarkup = renderToStaticMarkup(createElement(SignInCTA, {})); | |
| expect(demoMarkup).toContain('inline-flex'); | |
| expect(demoMarkup).toContain('rounded-full'); | |
| expect(demoMarkup).toContain('bg-primary'); | |
| expect(signInMarkup).toContain('inline-flex'); | |
| expect(signInMarkup).toContain('rounded-full'); | |
| }); | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/web-next-landing-ctas-render.test.tsx` around lines 96 - 136, Add a
test case in web-next landing CTAs coverage that renders DemoCTA and SignInCTA
without passing className, since LandingCTAProps.className is optional. Use the
existing DemoCTA and SignInCTA symbols from the test file and assert the default
markup still includes the required base classes such as inline-flex,
rounded-full, and bg-primary, confirming cn(baseClasses, undefined) works for
the default render path.
Source: Path instructions
| id: "receipt", | ||
| headline: "Every top post keeps an anonymized receipt.", | ||
| description: | ||
| "The public page can show why a post ranked without leaking raw handles, DIDs, or post URIs. Score components, weights, and totals stay inspectable while the sensitive production content stays redacted.", | ||
| cta: "Open the live receipt", | ||
| href: `/demo#snapshot-rank-${LIVE_RANK_ONE_EXPLANATION.rank}`, | ||
| UI: ScoreBreakdownUI, | ||
| }, |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Confirm the demo page renders an anchor matching snapshot-rank-<rank>.
rg -n 'snapshot-rank-' web-next/app -g '*.tsx'Repository: andrewnordstrom-eng/bluesky-community-feed
Length of output: 318
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the demo page and inspect the snapshot-rank anchor usage.
ast-grep outline web-next/app/demo/page.tsx --view expanded || true
echo '--- lines 60-120 ---'
cat -n web-next/app/demo/page.tsx | sed -n '60,120p'
echo '--- search for id/snapshot-rank in demo page ---'
rg -n 'snapshot-rank|id:\s*["'\'']snapshot-rank|id=\{?`?snapshot-rank' web-next/app/demo/page.tsxRepository: andrewnordstrom-eng/bluesky-community-feed
Length of output: 3709
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- StepFeed / nearby render lines ---'
cat -n web-next/app/demo/page.tsx | sed -n '206,370p'
echo '--- all id assignments in demo page ---'
rg -n 'id\s*=|id:' web-next/app/demo/page.tsx
echo '--- all uses of post.uri / snapshotPostUrl in demo page ---'
rg -n 'post\.uri|snapshotPostUrl|snapshot-rank-' web-next/app/demo/page.tsxRepository: andrewnordstrom-eng/bluesky-community-feed
Length of output: 10623
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- repo-wide snapshot-rank references ---'
rg -n 'snapshot-rank-' .
echo '--- repo-wide anchor/id patterns for snapshot-rank ---'
rg -n 'id\s*=\s*["'"'"']snapshot-rank-|id:\s*["'"'"']snapshot-rank-' .Repository: andrewnordstrom-eng/bluesky-community-feed
Length of output: 531
Add the matching /demo anchor for the receipt link. href points to /demo#snapshot-rank-${LIVE_RANK_ONE_EXPLANATION.rank}, but the demo page doesn’t render any element with that id, so the CTA scrolls nowhere. Add id="snapshot-rank-${rank}" to the receipt/explanation block in web-next/app/demo/page.tsx, and add a test that the anchor exists for the rendered rank.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@web-next/components/bento-section.tsx` around lines 203 - 210, The receipt
CTA in BentoSection points to a /demo hash that does not exist, so add the
matching anchor to the demo receipt/explanation block in DemoPage and make sure
it uses the same rank-based id pattern as LIVE_RANK_ONE_EXPLANATION.rank. Update
the relevant JSX in web-next/app/demo/page.tsx so the rendered receipt section
includes id="snapshot-rank-${rank}", and add a test that verifies the anchor is
present for the rendered rank.
Summary
Polishes the public
web-nexthomepage toward the v2 design rhythm while preserving reviewer-safe live snapshot data, anonymized receipt copy, static export behavior, and production header/menu behavior.Changes
/into the v2 rhythm: hero, receipt preview, social proof, feature rows, get-started, proof/changelog, FAQ, CTA, footer.LIVE_METRICS_SNAPSHOT,LIVE_RANK_ONE_EXPLANATION, andLIVE_FEED_POSTS./demoand keeps sign-in/account connection secondary.href="#"residue.Verification
cd web-next && npm run lintcd web-next && npx tsc --noEmitcd web-next && npm run buildnpx vitest tests/web-next-demo-fixtures.test.ts --runnpx vitest tests/web-next-landing-ctas-render.test.tsx tests/web-next-score.test.ts --runnpx vitest tests/web-next-landing-ctas-render.test.tsx tests/web-next-score.test.ts tests/web-next-demo-fixtures.test.ts tests/web-next-percent.test.ts tests/web-next-homepage-anchors.test.ts --runnpm run verifywith non-secret dummy test env outside sandbox because local socket tests hit sandbox EPERMBrowser QA
overflowX: 0./api/governance/auth/session404 because the backend API is not mounted when servingweb-next/outdirectly.Production Smoke Before Merge
Current deployed production routes were checked before this PR merges:
/,/demo/,/dashboard/,/vote/,/post/returned 200 and unknown route returned 404. HTML returnedcache-control: no-cache; a_next/static/chunks/*.jsasset returnedpublic, max-age=31536000, immutable;/health/readyreturned ready./api/transparency/statsstill timed out after 10s and is treated as an existing runtime blocker outside this landing polish.CodeRabbit Audit
76b609c541a1250fc6bf36eff91328842c334e0bhas no live current-head CodeRabbit threads and no stale/superseded residue.coderabbit-statusreportsreview_state=APPROVEDonreview_sha=76b609c541a1250fc6bf36eff91328842c334e0b,threads_open=0, andsignal_state=pending/signal_message="Review in progress"while the rawCodeRabbitstatus context remains pending.coderabbit-truth-gate --mode threads --head-sha 76b609c541a1250fc6bf36eff91328842c334e0bpassed with zero live current-head CodeRabbit threads.resolve-coderabbit-threads --jsonfound no eligible residue and reported all non-CodeRabbit checks green. Localnpm run verifypassed after the rebase with 109 test files and 990 tests; GitHub backend, frontend, docs, report scripts, quality, CodeQL, Aikido, secret scan, security, Dependabot, Linear, and internal hygiene checks passed on head76b609c541a1250fc6bf36eff91328842c334e0b.coderabbit:exemptlabel if CodeRabbit later posts current-head actionable findings before merge; treat any new current-head HIGH/MEDIUM findings as blocking.Checklist
npm run verifypasses locallyCHANGELOG.mdupdated under## [Unreleased](perRELEASING.md)npm run docs:verifypasses) — no docs/API/config changeRefs PROJ-1285