Skip to content

feat: update sponsor button style and improve leaderboard display logic#343

Merged
ViktorSvertoka merged 3 commits intodevelopfrom
feature/leaderboard-logic-update
Feb 18, 2026
Merged

feat: update sponsor button style and improve leaderboard display logic#343
ViktorSvertoka merged 3 commits intodevelopfrom
feature/leaderboard-logic-update

Conversation

@TiZorii
Copy link
Collaborator

@TiZorii TiZorii commented Feb 18, 2026

Updated Sponsor button color to match GitHub style

Changed leaderboard logic to display:

Top 15 users

Ellipsis when user is outside top 15

Contextual ranks (±2 around current user)

Summary by CodeRabbit

  • New Features

    • Hero heading now acts as a button and scrolls to the next section
    • Leaderboard shows contextual rows around non-top users with a new caption
  • Improvements

    • Sponsor color tokens added and applied across badges and buttons; sponsor CTA refined with responsive text and updated hover styling
    • Leaderboard top list tightened to 15; podium/table styling aligned to sponsor tokens
    • Profile card role/sponsor badges clarified
    • Accessibility/localization keys added for scrolling and context caption
  • Other

    • Leaderboard query capacity increased for broader results
    • Popup pointer-event behavior improved; scrollbar/theme styling refined

Updated Sponsor button color to match GitHub style

Changed leaderboard logic to display:

Top 15 users

Ellipsis when user is outside top 15

Contextual ranks (±2 around current user)
@netlify
Copy link

netlify bot commented Feb 18, 2026

Deploy Preview for develop-devlovers ready!

Name Link
🔨 Latest commit 8e3fed8
🔍 Latest deploy log https://app.netlify.com/projects/develop-devlovers/deploys/69963c27862a740007628ec5
😎 Deploy Preview https://deploy-preview-343--develop-devlovers.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel
Copy link
Contributor

vercel bot commented Feb 18, 2026

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

Project Deployment Actions Updated (UTC)
devlovers-net Ready Ready Preview, Comment Feb 18, 2026 10:26pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 18, 2026

📝 Walkthrough

Walkthrough

Adds sponsor color tokens and scrollbar styles to global CSS; applies sponsor tokens and responsive CTA adjustments in ProfileCard and leaderboard components; changes LeaderboardTable to show top-15 with contextual nearby rows and increases DB query limit; converts home hero wrapper to a clickable motion button that scrolls to the next section; adds localization keys.

Changes

Cohort / File(s) Summary
Design tokens & global styles
frontend/app/globals.css
Adds --sponsor and --sponsor-hover in light/dark scopes; extensive scrollbar/overflow styling and minor CSS normalization/formatting.
Dashboard ProfileCard
frontend/components/dashboard/ProfileCard.tsx
Separates role and sponsor badges; uses sponsor tokens for CTA styling; adds responsive two-span CTA text swap and updated markup.
Leaderboard styling & rendering
frontend/components/leaderboard/LeaderboardPodium.tsx, frontend/components/leaderboard/LeaderboardTable.tsx
Replaces hard-coded amber classes with --sponsor tokens; LeaderboardTable introduces TOP_COUNT = 15 and CONTEXT_RANGE = 2, renders contextual rows for non-top users, adds caption key, and switches user id checks to userId.
Leaderboard query
frontend/db/queries/leaderboard.ts
Increases query limit from 50 to 1000 (ordering by COALESCE(...) preserved).
Home hero interaction & accessibility
frontend/components/home/WelcomeHeroSection.tsx
Changes wrapper from <motion.div> to <motion.button>, adds onClick smooth-scroll to next step, ARIA label, and gradient class adjustments.
Localization
frontend/messages/en.json, frontend/messages/pl.json, frontend/messages/uk.json
Adds leaderboard.contextTableCaption and homepage.scrollToNextSection translation keys.
UI interactivity tweak
frontend/components/shared/OnlineCounterPopup.tsx
Adds pointer-events management to popup container and inner content for visibility/interaction control.

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant FrontendApp
  participant API
  participant Database
  Browser->>FrontendApp: Load leaderboard page
  FrontendApp->>API: GET /api/leaderboard?limit=1000
  API->>Database: Query top scores (limit=1000)
  Database-->>API: Results (ordered)
  API-->>FrontendApp: Leaderboard data
  FrontendApp->>FrontendApp: compute top15, isCurrentInTop?, contextRows (±2)
  FrontendApp-->>Browser: Render table with top rows and optional context rows, apply `--sponsor` tokens
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

bug, refactor

Suggested reviewers

  • ViktorSvertoka
  • AM1007

Poem

🐰 I hopped through tokens, colors new and bright,
Gave sponsor hues a cozy light,
Top fifteen lined, with neighbors in view,
A button that scrolls — a skip and a woo! 🎨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly summarizes the main changes: sponsor button styling updates and leaderboard display logic improvements, which align with the file changes across ProfileCard, LeaderboardTable, and related components.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/leaderboard-logic-update

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
frontend/components/leaderboard/LeaderboardTable.tsx (1)

109-134: ⚠️ Potential issue | 🟡 Minor

Context table is missing an accessible <caption>.

The main leaderboard table has <caption className="sr-only">{t('tableCaption')}</caption> for screen-reader identification. The context table has no caption, so assistive technologies cannot distinguish it from the main table.

♿ Suggested fix
             <table className="w-full table-fixed border-separate border-spacing-0 text-left">
+              <caption className="sr-only">{t('contextTableCaption')}</caption>
               <colgroup>

Add a corresponding i18n key (e.g., "contextTableCaption": "Your position on the leaderboard").

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/components/leaderboard/LeaderboardTable.tsx` around lines 109 - 134,
Add an accessible, screen-reader-only caption to the context table by inserting
a caption element using the translation key (e.g., t('contextTableCaption'))
inside the same <table> where contextRows is rendered; update the i18n files to
include "contextTableCaption": "Your position on the leaderboard" (or
equivalent) so the caption is available to the t() call and assistive tech can
distinguish this table from the main leaderboard.
frontend/db/queries/leaderboard.ts (1)

46-49: ⚠️ Potential issue | 🟠 Major

id field contains rank position, not user ID—ID-based matching will always fail silently.

The returned object sets id: index + 1 (rank: 1, 2, 3…) while CurrentUser.id is a string auth/session ID. In LeaderboardTable.tsx, the comparison String(u.id) === normalizedCurrentUserId converts the rank to a string and compares it against the user's actual auth ID, which will never match. User identification falls back entirely to the username match condition, leaving the ID branch as dead code across all four matching locations (lines 32, 43, 85, 119).

Consider using userId (which contains the actual DB ID u.id) instead of the rank for ID-based matching.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/db/queries/leaderboard.ts` around lines 46 - 49, The returned
leaderboard item currently sets id: index + 1 (rank) which breaks ID-based
matching in LeaderboardTable.tsx; change the object returned in
frontend/db/queries/leaderboard.ts so that id is set to the actual DB user id
(u.id or String(u.id) to match CurrentUser.id normalization) and keep a separate
rank field (rank: index + 1) — ensure the properties referenced in
LeaderboardTable.tsx (id and userId checks) use the real user id value rather
than the rank.
🧹 Nitpick comments (5)
frontend/components/leaderboard/LeaderboardTable.tsx (1)

40-54: Redundant findIndex — derive index from matchedUser directly.

matchedUser was already located via users.find() (lines 30–34) with the same predicate. A second O(n) findIndex scan is unnecessary; users.indexOf(matchedUser) gives the same index in O(1), or a single findIndex can replace both lookups.

♻️ Proposed refactor
-  const matchedUser = users.find(
-    u =>
-      String(u.id) === normalizedCurrentUserId ||
-      (currentUsername && u.username === currentUsername)
-  );
+  const matchedUserIndex = users.findIndex(
+    u =>
+      String(u.id) === normalizedCurrentUserId ||
+      (currentUsername && u.username === currentUsername)
+  );
+  const matchedUser = matchedUserIndex !== -1 ? users[matchedUserIndex] : undefined;

   const currentUserRank = matchedUser?.rank || 0;
   const isUserInTop = currentUserRank > 0 && currentUserRank <= TOP_COUNT;

   const contextRows: User[] = [];
   if (!isUserInTop && matchedUser) {
-    const userIndex = users.findIndex(
-      u =>
-        String(u.id) === normalizedCurrentUserId ||
-        (currentUsername && u.username === currentUsername)
-    );
-
-    if (userIndex !== -1) {
-      const start = Math.max(TOP_COUNT, userIndex - CONTEXT_RANGE);
-      const end = Math.min(users.length - 1, userIndex + CONTEXT_RANGE);
+    if (matchedUserIndex !== -1) {
+      const start = Math.max(TOP_COUNT, matchedUserIndex - CONTEXT_RANGE);
+      const end = Math.min(users.length - 1, matchedUserIndex + CONTEXT_RANGE);
       for (let i = start; i <= end; i++) {
         contextRows.push(users[i]);
       }
     }
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/components/leaderboard/LeaderboardTable.tsx` around lines 40 - 54,
The code redundantly re-scans users with findIndex even though matchedUser was
already found; replace the second O(n) lookup by deriving the index via
users.indexOf(matchedUser) (inside the existing if (!isUserInTop && matchedUser)
block) and use that userIndex for computing start/end and pushing into
contextRows (preserving TOP_COUNT and CONTEXT_RANGE logic); ensure you still
check userIndex !== -1 before building the contextRows.
frontend/db/queries/leaderboard.ts (1)

35-35: Unbounded query — consider a reasonable upper cap.

Removing limit(50) means every cache miss (once per hour) fetches every row in the users table. The 3600 s cache mitigates DB load, but cache payload size and cold-start latency grow linearly with user count. The UI only ever renders 15 + ±2 rows, so only a bounded superset (e.g., top ~500 or top 1000) is needed.

💡 Suggested cap
-      .orderBy(desc(sql`COALESCE(pt_valid.total, 0)`));
+      .orderBy(desc(sql`COALESCE(pt_valid.total, 0)`))
+      .limit(500);   // generous cap; adjust to anticipated user growth
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/db/queries/leaderboard.ts` at line 35, The query currently ends with
.orderBy(desc(sql`COALESCE(pt_valid.total, 0)`)) and is unbounded; add a
reasonable upper cap (e.g., .limit(500) or .limit(1000)) to the same query chain
to avoid fetching the entire users table on cache miss. Locate the leaderboard
query in frontend/db/queries/leaderboard.ts (the chain that calls
orderBy(desc(sql`COALESCE(pt_valid.total, 0)`))) and append a .limit(...) before
executing/returning the query so the cache payload stays bounded while still
covering the UI’s needs.
frontend/components/leaderboard/LeaderboardPodium.tsx (1)

120-120: dark:text-(--sponsor) is redundant.

--sponsor is already redefined inside .dark {} in globals.css, so text-(--sponsor) resolves to the dark-mode color automatically. Only dark:bg-(--sponsor)/15 (which changes the opacity) has a meaningful effect. The same redundancy appears in LeaderboardTable.tsx line 204 and ProfileCard.tsx line 69.

🧹 Suggested cleanup
-                  className="mt-0.5 inline-flex items-center gap-1 rounded-full bg-(--sponsor)/10 px-2 py-0.5 text-[10px] font-bold text-(--sponsor) transition-colors hover:bg-(--sponsor)/20 dark:bg-(--sponsor)/15 dark:text-(--sponsor) dark:hover:bg-(--sponsor)/25"
+                  className="mt-0.5 inline-flex items-center gap-1 rounded-full bg-(--sponsor)/10 px-2 py-0.5 text-[10px] font-bold text-(--sponsor) transition-colors hover:bg-(--sponsor)/20 dark:bg-(--sponsor)/15 dark:hover:bg-(--sponsor)/25"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/components/leaderboard/LeaderboardPodium.tsx` at line 120, Remove
the redundant "dark:text-(--sponsor)" utility from the component classNames
where the CSS custom property --sponsor is already redefined inside the .dark
selector; specifically edit the className in LeaderboardPodium (the inline class
string containing dark:bg-(--sponsor)/15) to drop dark:text-(--sponsor), and
make the same removal in LeaderboardTable (the className at the table row/cell
around line with text-(--sponsor)) and ProfileCard (the className that includes
text-(--sponsor)); keep the dark:bg-(--sponsor)/15 opacity modifier and any
other relevant classes intact so only the redundant dark:text-(--sponsor) token
is removed.
frontend/components/home/WelcomeHeroSection.tsx (1)

63-75: Scroll indicator icons don't respond to button's hover color.

The inner animated dot (bg-gray-400) and ChevronDown (text-gray-400 dark:text-white/50) have explicit color classes that override the parent button's hover:text-(--accent-primary). On hover, the button text color changes but the icons stay gray.

✨ Proposed fix — use `currentColor`/`group-hover` instead of hard-coded grays

Add group to the button and replace the static color classes:

-        className="absolute bottom-8 left-1/2 -translate-x-1/2 flex cursor-pointer flex-col items-center gap-2 text-gray-400 transition-colors hover:text-(--accent-primary) dark:text-white/50 dark:hover:text-(--accent-primary)"
+        className="group absolute bottom-8 left-1/2 -translate-x-1/2 flex cursor-pointer flex-col items-center gap-2 text-gray-400 transition-colors hover:text-(--accent-primary) dark:text-white/50 dark:hover:text-(--accent-primary)"
-           className="mx-auto h-1.5 w-1 rounded-full bg-gray-400 dark:bg-white/70"
+           className="mx-auto h-1.5 w-1 rounded-full bg-current"
-            <ChevronDown className="h-4 w-4 text-gray-400 dark:text-white/50" />
+            <ChevronDown className="h-4 w-4 text-current" />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/components/home/WelcomeHeroSection.tsx` around lines 63 - 75, The
scroll indicator's inner dot (motion.div with class "mx-auto h-1.5 w-1
rounded-full bg-gray-400 dark:bg-white/70") and the ChevronDown icon
(ChevronDown element with "text-gray-400 dark:text-white/50") use hard-coded
colors, so they don't inherit the button hover color; make the parent button a
"group" and replace the dot's background class with a current-color style (use
bg-current) and the ChevronDown's color with text-current so both inherit the
parent's text color (which should already toggle via
hover:text-(--accent-primary) on the button/group).
frontend/app/globals.css (1)

73-75: --sponsor-hover is defined but not consumed.

All sponsor badge and button hover states in this PR use opacity modifiers on --sponsor (e.g., hover:bg-(--sponsor)/20) rather than var(--sponsor-hover). The token is unused. Either wire it up to the hover states or defer its definition until it's actually needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/app/globals.css` around lines 73 - 75, The CSS variable
--sponsor-hover is defined but never used; update the hover rules that currently
apply opacity modifiers to var(--sponsor) to instead reference
var(--sponsor-hover) (or remove the --sponsor-hover declaration if you prefer
the opacity approach). Locate usages of --sponsor in hover styles (e.g.,
hover:bg-(--sponsor)/20 patterns) and change them to use var(--sponsor-hover)
for hover background/fill/border where a distinct hover color is intended, or
delete the --sponsor-hover token from globals.css if you decide to keep the
opacity-based hover implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@frontend/components/leaderboard/LeaderboardTable.tsx`:
- Around line 109-134: Add an accessible, screen-reader-only caption to the
context table by inserting a caption element using the translation key (e.g.,
t('contextTableCaption')) inside the same <table> where contextRows is rendered;
update the i18n files to include "contextTableCaption": "Your position on the
leaderboard" (or equivalent) so the caption is available to the t() call and
assistive tech can distinguish this table from the main leaderboard.

In `@frontend/db/queries/leaderboard.ts`:
- Around line 46-49: The returned leaderboard item currently sets id: index + 1
(rank) which breaks ID-based matching in LeaderboardTable.tsx; change the object
returned in frontend/db/queries/leaderboard.ts so that id is set to the actual
DB user id (u.id or String(u.id) to match CurrentUser.id normalization) and keep
a separate rank field (rank: index + 1) — ensure the properties referenced in
LeaderboardTable.tsx (id and userId checks) use the real user id value rather
than the rank.

---

Nitpick comments:
In `@frontend/app/globals.css`:
- Around line 73-75: The CSS variable --sponsor-hover is defined but never used;
update the hover rules that currently apply opacity modifiers to var(--sponsor)
to instead reference var(--sponsor-hover) (or remove the --sponsor-hover
declaration if you prefer the opacity approach). Locate usages of --sponsor in
hover styles (e.g., hover:bg-(--sponsor)/20 patterns) and change them to use
var(--sponsor-hover) for hover background/fill/border where a distinct hover
color is intended, or delete the --sponsor-hover token from globals.css if you
decide to keep the opacity-based hover implementation.

In `@frontend/components/home/WelcomeHeroSection.tsx`:
- Around line 63-75: The scroll indicator's inner dot (motion.div with class
"mx-auto h-1.5 w-1 rounded-full bg-gray-400 dark:bg-white/70") and the
ChevronDown icon (ChevronDown element with "text-gray-400 dark:text-white/50")
use hard-coded colors, so they don't inherit the button hover color; make the
parent button a "group" and replace the dot's background class with a
current-color style (use bg-current) and the ChevronDown's color with
text-current so both inherit the parent's text color (which should already
toggle via hover:text-(--accent-primary) on the button/group).

In `@frontend/components/leaderboard/LeaderboardPodium.tsx`:
- Line 120: Remove the redundant "dark:text-(--sponsor)" utility from the
component classNames where the CSS custom property --sponsor is already
redefined inside the .dark selector; specifically edit the className in
LeaderboardPodium (the inline class string containing dark:bg-(--sponsor)/15) to
drop dark:text-(--sponsor), and make the same removal in LeaderboardTable (the
className at the table row/cell around line with text-(--sponsor)) and
ProfileCard (the className that includes text-(--sponsor)); keep the
dark:bg-(--sponsor)/15 opacity modifier and any other relevant classes intact so
only the redundant dark:text-(--sponsor) token is removed.

In `@frontend/components/leaderboard/LeaderboardTable.tsx`:
- Around line 40-54: The code redundantly re-scans users with findIndex even
though matchedUser was already found; replace the second O(n) lookup by deriving
the index via users.indexOf(matchedUser) (inside the existing if (!isUserInTop
&& matchedUser) block) and use that userIndex for computing start/end and
pushing into contextRows (preserving TOP_COUNT and CONTEXT_RANGE logic); ensure
you still check userIndex !== -1 before building the contextRows.

In `@frontend/db/queries/leaderboard.ts`:
- Line 35: The query currently ends with
.orderBy(desc(sql`COALESCE(pt_valid.total, 0)`)) and is unbounded; add a
reasonable upper cap (e.g., .limit(500) or .limit(1000)) to the same query chain
to avoid fetching the entire users table on cache miss. Locate the leaderboard
query in frontend/db/queries/leaderboard.ts (the chain that calls
orderBy(desc(sql`COALESCE(pt_valid.total, 0)`))) and append a .limit(...) before
executing/returning the query so the cache payload stays bounded while still
covering the UI’s needs.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/components/home/WelcomeHeroSection.tsx`:
- Line 61: The aria-label on the scroll button in WelcomeHeroSection is
hardcoded; route it through the i18n layer by adding a key (e.g.
"scrollToNextSection") to the homepage messages and replacing the hardcoded
string with t('homepage.scrollToNextSection') (use the existing t() import in
WelcomeHeroSection) so the aria-label is translated like the other user-facing
strings.

In `@frontend/components/leaderboard/LeaderboardTable.tsx`:
- Around line 39-50: The current logic building contextRows can produce a
contiguous block starting at rank TOP_COUNT+1 (e.g., userIndex == TOP_COUNT),
which makes the rendered ellipsis misleading; update the rendering condition (or
the determination of whether to show the ellipsis) to only show the `• • •` when
there is a real gap between the top list and contextRows — for example check the
computed start (or contextRows[0].rank) and only render the ellipsis when start
> TOP_COUNT (or contextRows[0].rank > TOP_COUNT + 1); keep the existing
contextRows construction (variables: contextRows, isUserInTop, matchedUser,
userIndex, TOP_COUNT, CONTEXT_RANGE, start, end) but gate the ellipsis display
behind that gap check.
- Around line 114-127: In the contextRows mapping, the isMe calculation uses the
wrong property (String(user.id)) so the current user is never marked; change the
comparison to use user.userId (i.e., compare user.userId to
normalizedCurrentUserId) while keeping the existing fallback that checks
currentUsername against user.username and pass the result into TableRow via
isCurrentUser; update the isMe expression inside the contextRows.map block to
reference user.userId and leave TableRow, t, and other props unchanged.

…ter click blocking

  - Scrollbar: minimal custom scrollbar (no arrows, dark/light theme, Chrome/Edge/Firefox)
  - Horizontal scroll: overflow-x: hidden on html prevents About page overflow
  - Leaderboard: fix contextRows user ID matching, conditional ellipsis when no gap
  - Footer: fix OnlineCounterPopup blocking clicks via pointer-events-none
  - i18n: translate scroll indicator aria-label and context table caption
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
frontend/components/home/WelcomeHeroSection.tsx (1)

53-56: Index-based DOM lookup for the scroll target is fragile.

steps[1] implicitly relies on the rendering order of all [data-home-step] elements in the document. If any sibling component conditionally renders a data-home-step element before the intended target, the scroll destination shifts silently. A named attribute value (data-home-step="features") is more resilient:

♻️ Suggested refactor
-          const steps = document.querySelectorAll<HTMLElement>('[data-home-step]');
-          if (steps[1]) steps[1].scrollIntoView({ behavior: 'smooth' });
+          const target = document.querySelector<HTMLElement>('[data-home-step="features"]');
+          target?.scrollIntoView({ behavior: 'smooth' });

Then update the target section's attribute to data-home-step="features" (or whichever semantic name fits).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/components/home/WelcomeHeroSection.tsx` around lines 53 - 56, The
current onClick handler in WelcomeHeroSection uses
document.querySelectorAll<HTMLElement>('[data-home-step]') and then
steps[1].scrollIntoView(...), which is fragile; change it to select the target
by a named attribute value (e.g.
document.querySelector<HTMLElement>('[data-home-step="features"]')) and call
scrollIntoView on that element instead, and update the corresponding target
section to have data-home-step="features" (or another semantic name) so the
selector reliably finds the correct element.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@frontend/components/home/WelcomeHeroSection.tsx`:
- Line 61: The aria-label in WelcomeHeroSection.tsx is already internationalized
by using aria-label={t('scrollToNextSection')}, so no code change is required;
leave the aria-label as-is and approve the change (verify the translation key
'scrollToNextSection' exists in the i18n files and is used by the t function).

In `@frontend/components/leaderboard/LeaderboardTable.tsx`:
- Around line 116-119: The isMe check in the contextRows.map callback correctly
uses user.userId for comparison; confirm the condition in the anonymous function
(contextRows.map -> isMe) compares user.userId to normalizedCurrentUserId and
falls back to comparing user.username to currentUsername (user.userId,
normalizedCurrentUserId, currentUsername, user.username), keep this logic as-is
and ensure there are no other places still comparing a different id field for
context rows.

---

Nitpick comments:
In `@frontend/components/home/WelcomeHeroSection.tsx`:
- Around line 53-56: The current onClick handler in WelcomeHeroSection uses
document.querySelectorAll<HTMLElement>('[data-home-step]') and then
steps[1].scrollIntoView(...), which is fragile; change it to select the target
by a named attribute value (e.g.
document.querySelector<HTMLElement>('[data-home-step="features"]')) and call
scrollIntoView on that element instead, and update the corresponding target
section to have data-home-step="features" (or another semantic name) so the
selector reliably finds the correct element.

@ViktorSvertoka ViktorSvertoka merged commit 561842f into develop Feb 18, 2026
11 checks passed
@ViktorSvertoka ViktorSvertoka deleted the feature/leaderboard-logic-update branch February 18, 2026 22:40
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