Skip to content

fix(web): hide criteria with no scored product; no screen row for earbuds - #1554

Merged
JOY (JOY) merged 2 commits into
devfrom
fix/1553-empty-criteria
Oct 31, 2026
Merged

JOY (JOY) merged 2 commits into
devfrom
fix/1553-empty-criteria

Conversation

@JOY

@JOY JOY (JOY) commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Closes #1553

Problem

No published product has a criterion score yet (#1143). On the leaderboard:

  • every criterion tab and persona preset emptied the list ("(0)") without saying why;
  • earbud product pages still listed "Màn hình & hiển thị: Chưa có".

What changes

  • Leaderboard (LeaderboardExplorer.tsx):
    • A criterion shows up only when at least one product in the active category has a real score for it. That applies to its tab, its weight slider, its cell in each row and its bar on the podium cards.
    • When no criterion is scored, the "Gợi ý theo nhu cầu" presets and the weight sliders are hidden. An active persona resets.
    • A ?criterion= URL for an unscored criterion opens on the combined score, the same way ?cat=earbuds&criterion=screen already does.
    • No new text is added, per the "less text" rule.
  • Product page (JReviewsSection.tsx, smartphones/[slug]/page.tsx):
    • The review score block and each review's criterion chips use the category's criteria (leaderboardCriteriaForCategory), so earbuds have no screen row.
    • The heading drops its fixed "5": "Điểm chi tiết theo tiêu chí trải nghiệm".
    • The review form still asks for all five criteria. Per-category review forms belong with feat(shared-data): per-category rating criteria, weights and review form rules #1548's rules and are not in this PR.

Tests

  • e2e/selector-state.spec.ts:
    • New test: on /leaderboard?cat=smartphones&criterion=camera the criterion group has only its 3 overall buttons, "Điểm tổng hợp" is pressed, and the persona group and weight button are absent.
    • The selector-state test no longer covers the persona group and the sliders, because the seed has no criterion scores, the same as production today. Seeding a score would touch many specs and screenshots that use the seeded phones. When real criterion data exists, a seeded score can bring that coverage back.
  • pnpm test, tsc and eslint pass locally. E2E runs in CI, because Docker is not available here.

🤖 Generated with Claude Code


📌 TL;DR

This PR refines the leaderboard and product review UI to dynamically hide criteria, personas, and weight sliders when no products in the current category have valid scores for them, preventing empty states and misleading data. It also updates localization strings to remove hardcoded "5 criteria" references and passes category context to the review section for consistent filtering.

🎯 Type of Change

  • 🚀 New feature
  • 🐛 Bugfix
  • 🧹 Refactor
  • ⚡ Performance
  • 📚 Documentation
  • ⚙️ CI / Configuration

🔍 Changes Walkthrough

File Summary of Changes
apps/web/e2e/selector-state.spec.ts Updated E2E tests to reflect the removal of the "Gợi ý theo nhu cầu" (Persona) group and weight sliders when criteria are unscored. Added a new test case verifying that unscored criteria result in no tabs, personas, or sliders.
apps/web/locales/cs.json Updated criteriaMatrixHeading to remove the hardcoded "5" count, making it generic ("Scores by experience criterion").
apps/web/locales/en.json Updated criteriaMatrixHeading to remove the hardcoded "5" count.
apps/web/locales/vi.json Updated criteriaMatrixHeading to remove the hardcoded "5" count.
apps/web/src/app/[locale]/smartphones/[slug]/page.tsx Imported isCanonicalCategorySlug and passed the validated categorySlug to JReviewsSection to enable category-specific filtering.
apps/web/src/components/leaderboard/LeaderboardExplorer.tsx Introduced scoredCriteria memo to filter criteria based on actual product scores. Conditionally rendered persona presets, weight sliders, and mini-criteria bars only when hasScoredCriteria is true. Updated URL parameter handling to fallback to 'combined' if a specific criterion has no scores.
apps/web/src/components/reviews/JReviewsSection.tsx Added categorySlug prop. Created shownCriteriaMeta memo to filter criteria based on the category. Updated rendering logic for criteria averages and individual review criteria chips to use the filtered list.

📊 Architectural Flow

flowchart TD
    A[LeaderboardExplorer / JReviewsSection] --> B{Is Category Valid?}
    B -->|Yes| C[Compute Scored Criteria]
    C --> D{Do Products Have Scores for Criteria?}
    D -->|Yes| E[Render Tabs, Personas, Sliders, Bars]
    D -->|No| F[Hide Tabs, Personas, Sliders, Bars]
    F --> G[Show Combined Score Only]
    E --> H[Render UI Elements]
    G --> H
Loading

…buds

#1553: no published product has a criterion score yet, so every
criterion tab and persona emptied the leaderboard with no word why.
- The leaderboard shows a criterion tab, weight slider, row cell and
  podium bar only for a criterion that some product in the category has a
  real score for; with none, the persona presets and sliders are hidden
  and a criterion URL opens on the combined score.
- The product page's review score block and each review's criterion
  chips use the category's criteria: no screen row for earbuds. The
  heading drops its fixed "5". The review form is unchanged.

Closes #1553

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
rate Ready Ready Preview Oct 31, 2026 7:46pm UTC

Request Review

@claude claude 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.

⚠️ Code review skipped — your organization has no extra usage available to pay for this review.

If your organization's extra usage balance is empty, an organization admin can add extra usage credits at claude.ai/admin-settings/usage. If its monthly spend limit was reached, an admin can raise it on the same page. If neither applies, contact Anthropic support.

Once extra usage is available, someone with write access to this repository can comment @claude review on this pull request to trigger a review.

@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 9 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8e466311-43f4-4dae-9e52-fea7d0b2782d
Commits

Reviewing files that changed from the base of the PR and between 1a9cd84 and edf6e63.

Files selected for processing: 7
  • apps/web/e2e/selector-state.spec.ts
  • apps/web/locales/cs.json
  • apps/web/locales/en.json
  • apps/web/locales/vi.json
  • apps/web/src/app/[locale]/smartphones/[slug]/page.tsx
  • apps/web/src/components/leaderboard/LeaderboardExplorer.tsx
  • apps/web/src/components/reviews/JReviewsSection.tsx
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

dos[bot]
dos Bot approved these changes Oct 31, 2026

@dos dos 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.

⏱️ Code Review completed (7 eligible files · 28,425 chars · 2 model call(s) · 1 PR unit(s))

Whole diff with bounded context at base 1a9cd84 / head 6f445d1.

✅ CLEAN_PASS: Complete diff reviewed

Context investigation was bounded to the explicitly requested snapshot paths.

Review of #1554: the fallback to the combined tab ran after paint, so an
empty list flashed, and the URL kept the unscored criterion after a
category switch. It now runs as a layout effect and rewrites the URL.

Refs #1553

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dos[bot]
dos Bot approved these changes Oct 31, 2026

@dos dos 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.

⏱️ Code Review completed (7 eligible files · 28,920 chars · 1 model call(s) · 1 PR unit(s))

Whole diff with bounded context at base 1a9cd84 / head edf6e63.

✅ CLEAN_PASS: Complete diff reviewed

@JOY
JOY (JOY) merged commit 781e4a0 into dev Oct 31, 2026
15 checks passed
@JOY
JOY (JOY) deleted the fix/1553-empty-criteria branch October 31, 2026 19:54

This branch was successfully deployed

1 active deployment
Preview — edf6e630 Deployed Oct 31, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:frontend Frontend / Next.js / UI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(web): criterion tabs and personas show an empty list with no message; earbud product page keeps a screen row

1 participant