Skip to content

Add Summer 2026 to FutureEval carousel and AIB pages#4859

Open
CodexVeritas wants to merge 4 commits into
mainfrom
claude/issue-4857-summer-futureeval-additions
Open

Add Summer 2026 to FutureEval carousel and AIB pages#4859
CodexVeritas wants to merge 4 commits into
mainfrom
claude/issue-4857-summer-futureeval-additions

Conversation

@CodexVeritas

@CodexVeritas CodexVeritas commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

First pass on # 4857.

  • Add Summer 2026 to the FutureEval carousel (live), demote Spring 2026.
  • Add Summer 2026 to the AIB tournament pager.
  • Create /aib/2026/summer page + dedicated hero/cards/page-view components.
  • Repoint NextTournamentCard + Q1/Q2 2025 next-tournament links to Summer 2026.
  • Add FABSeasonSummer, FABStartDateMay4 i18n strings and update FABTournamentUnderway + startCompetingDescription.

Follow-ups listed in the issue comment: demote Spring 2026 to its own components, run the translation script, confirm image asset + copy/dates/prize, run bun run lint:types.

Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added Summer 2026 AI Benchmark Tournament with dedicated landing page and registration flow
    • Added May 4 tournament start date label
  • Updates

    • Updated all UI translations across multiple languages (English, Spanish, Portuguese, Czech, Simplified and Traditional Chinese) from Spring 2026 to Summer 2026
    • Updated navigation links to direct users to the new Summer 2026 tournament
    • Added Summer 2026 tournament card to tournament list

- Add Summer 2026 entry to the FutureEval carousel (now live, demote Spring 2026)
- Add Summer 2026 to the AIB tournament pager `TOURNAMENT_ITEMS`
- Create `/aib/2026/summer` page with dedicated hero / cards / page-view components
- Update `NextTournamentCard` and prior past-tournament pages (Q1/Q2 2025) to link to Summer 2026
- Add `FABSeasonSummer`, `FABStartDateMay4` i18n strings and update `FABTournamentUnderway` and `startCompetingDescription` for Summer 2026

Co-authored-by: Ben Wilson <CodexVeritas@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR transitions the active AI benchmarking tournament from Spring 2026 to Summer 2026, adding a new tournament route, components, and translations while updating all navigation links. The change is coordinated across six languages and includes server-side bot token resolution for authenticated users.

Changes

Summer 2026 Tournament Launch

Layer / File(s) Summary
Multilingual translation updates
front_end/messages/en.json, front_end/messages/cs.json, front_end/messages/es.json, front_end/messages/pt.json, front_end/messages/zh-TW.json, front_end/messages/zh.json
Season labels, tournament status, and prize-pool messaging updated from Spring to Summer across all six supported languages. Adds FABStartDateMay4 and FABSeasonSummer keys; updates FABTournamentUnderway and startCompetingDescription.
Tournament carousel data update
front_end/src/app/(futureeval)/futureeval/components/futureeval-tournaments.tsx
Marks "Summer 2026" tournament card as live (isLive: true) and removes the flag from "Spring 2026" in the carousel display.
Summer 2026 route handler
front_end/src/app/(main)/aib/2026/summer/page.tsx
Creates new page route with metadata export. Implements getPrimaryBotToken() server helper that checks user profile, determines user type (regular/bot), fetches bots if needed, and resolves the primary bot's API token or returns null. Passes resolved token to the page component.
Summer 2026 UI components
front_end/src/app/(main)/aib/components/hero-2026-summer.tsx, front_end/src/app/(main)/aib/components/cards-2026-summer.tsx
Introduces HeroSummer2026 with localized title, subtitle, and season label. Adds DatesSummer2026 and PrizeSummer2026 card components that render layout markup with responsive typography, conditioned on translation values.
Summer 2026 tournament page
front_end/src/app/(main)/aib/components/page-view-2026-summer.tsx
Implements main AiBenchmarkingTournamentPageSummer2026 client component. Conditionally renders three CTA blocks based on auth status (signup prompt, bot creation link, or token display). Includes tournament pager, hero, cards, informational links, banner image, and two modals for registration and token viewing.
Tournament navigation updates
front_end/src/app/(main)/aib/components/next-tournament-card.tsx, front_end/src/app/(main)/aib/components/page-view-2025-q1.tsx, front_end/src/app/(main)/aib/components/page-view-2025-q2.tsx, front_end/src/app/(main)/aib/components/tournament-pager.tsx
Updates navigation links across four pages from /aib/2026/spring to /aib/2026/summer. Adds Summer 2026 entry to the tournament pager navigation list.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Metaculus/metaculus#4272: Modifies the FutureEval tournaments carousel component rendering behavior alongside tournament card data updates.

Suggested reviewers

  • cemreinanc
  • elisescu

Poem

🐰 Hopping toward the summer sun,
Translations gleam in six languages spun,
Cards and heroes spring to life so bright,
Spring yields to summer's golden light!
☀️✨

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding Summer 2026 to FutureEval carousel and AIB pages, which aligns with the core modifications across translation files, components, and routing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/issue-4857-summer-futureeval-additions

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.

@CodexVeritas

Copy link
Copy Markdown
Contributor Author

@claude Please Make sure all the languages are properly translated

@claude

claude Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Claude finished @CodexVeritas's task in 4m 19s —— View job


Translation check for Summer 2026 PR

  • Read CLAUDE.md and explore translation setup
  • Identify new/changed strings in en.json
  • Check status across all other locale files
  • Add FABStartDateMay4 + FABSeasonSummer, and update FABTournamentUnderway + startCompetingDescription from "Spring 2026" → "Summer 2026" in cs/es/pt/zh/zh-TW
  • Commit translations (e033388)

Summary

The en.json diff in this PR introduced two new keys and modified two existing keys, but the other five locale files (cs.json, es.json, pt.json, zh.json, zh-TW.json) were missing the new keys entirely and still referenced "Spring 2026" in the modified ones. CLAUDE.md requires all six locale files to stay in sync, so I translated the four affected strings into each language:

Key cs es pt zh zh-TW
FABStartDateMay4 4. května 4 de mayo 4 de maio 5月4日 5月4日
FABSeasonSummer Léto Verano Verão 夏季 夏季
FABTournamentUnderway Turnaj Léto 2026 probíhá! ¡El torneo de Verano 2026 está en curso! O torneio do Verão 2026 está em andamento! 2026年夏季比赛正在进行中! 2026年夏季比賽正在進行中!
startCompetingDescription v létě 2026 en el verano de 2026 no verão de 2026 2026年夏季 2026年夏季

I followed the existing house style for each locale (e.g. Czech declension v létě, Spanish lowercase season verano inside running prose vs. capitalized Verano in the title-cased tournament name, Portuguese Verão, and the existing 2026年X季比赛/比賽 pattern in zh/zh-TW). Czech Léto is used in title case to match Jaro (the same key already used title-cased seasons), and v létě is the correct prepositional form to match the prior na jaře.

Notes / follow-ups

  • I did not run the repo's translation script — the four strings were small and unambiguous, so I translated them directly to keep the change minimal. If the script is preferred (per the PR follow-up list), it would only normalise wording.
  • I did not run bun run lint here — only messages/*.json was changed, so type checking is unaffected, but feel free to re-run locally as part of the existing follow-up checklist.
  • The original.json reference file was not modified, as it was not touched by the original PR either.
    • Branch: claude/issue-4857-summer-futureeval-additions • Commit: e033388

Adds FABStartDateMay4 and FABSeasonSummer to each non-English locale,
and updates FABTournamentUnderway + startCompetingDescription from
"Spring 2026" to "Summer 2026".

Co-authored-by: Ben Wilson <CodexVeritas@users.noreply.github.com>
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🚀 Preview Environment

Your preview environment is ready!

Resource Details
🌐 Preview URL https://metaculus-pr-4859-claude-issue-4857-summer-futur-preview.mtcl.cc
📦 Docker Image ghcr.io/metaculus/metaculus:claude-issue-4857-summer-futureeval-additions-e033388
🗄️ PostgreSQL NeonDB branch preview/pr-4859-claude-issue-4857-summer-futur
Redis Fly Redis mtc-redis-pr-4859-claude-issue-4857-summer-futur

Details

  • Commit: 4ff33c70168226ec97c5bade76d1acbdfc5ec47b
  • Branch: claude/issue-4857-summer-futureeval-additions
  • Fly App: metaculus-pr-4859-claude-issue-4857-summer-futur

ℹ️ Preview Environment Info

Isolation:

  • PostgreSQL and Redis are fully isolated from production
  • Each PR gets its own database branch and Redis instance
  • Changes pushed to this PR will trigger a new deployment

Limitations:

  • Background workers and cron jobs are not deployed in preview environments
  • If you need to test background jobs, use Heroku staging environments

Cleanup:

  • This preview will be automatically destroyed when the PR is closed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (3)
front_end/src/app/(main)/aib/components/tournament-pager.tsx (1)

173-181: 🏗️ Heavy lift

Refactor tournament item titles to i18n-backed values before adding more seasons.

The new entry continues a static-English pattern, so localized users still see English season labels in the pager. Consider replacing the exported static list with a translation-backed factory used inside the client component.

Based on learnings: Do not hardcode English strings in TSX components; prefer useTranslations() and i18n keys.

🤖 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 `@front_end/src/app/`(main)/aib/components/tournament-pager.tsx around lines
173 - 181, TOURNAMENT_ITEMS is currently a static array of English titles;
replace it with a factory that returns translated titles using the client-side
i18n hook (e.g., useTranslations) instead of exporting static strings. Change
the export to a function (e.g., getTournamentItems or buildTournamentItems) that
calls useTranslations() inside the component (or is invoked from the component)
to produce items with localized title values while keeping the href values the
same; update components that import TOURNAMENT_ITEMS to call the new factory
from client code so titles render localized labels.

Source: Learnings

front_end/src/app/(main)/aib/components/cards-2026-summer.tsx (2)

47-49: 💤 Low value

Unused conditional: "Coming Soon" check appears to be dead code.

The condition heading2 === "Coming Soon" on line 47 will never match because the actual values passed are "4 de mayo" (from translation) and "$58,000". This appears to be leftover code from a template.

♻️ Suggested cleanup

If the "Coming Soon" condition is not needed, simplify to a single responsive class:

         <div
           className={cn(
-            heading2 === "Coming Soon"
-              ? "text-xl md:text-3xl lg:text-4xl min-[1920px]:text-5xl"
-              : "text-2xl md:text-4xl lg:text-6xl min-[1920px]:text-7xl"
+            "text-2xl md:text-4xl lg:text-6xl min-[1920px]:text-7xl"
           )}
         >

Or retain the flexibility if future cards may use "Coming Soon".

🤖 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 `@front_end/src/app/`(main)/aib/components/cards-2026-summer.tsx around lines
47 - 49, The ternary checking heading2 === "Coming Soon" is dead code; remove
the conditional and replace the ternary expression with a single responsive
class string used for the element’s className (the JSX that currently computes
classes based on heading2). Locate the JSX where heading2 is used (variable
heading2 in the cards-2026-summer component) and update the class expression to
a single constant like "text-2xl md:text-4xl lg:text-6xl min-[1920px]:text-7xl"
(or choose the other size if preferred), or keep the conditional but
parameterize the match to a prop if you intend to support "Coming Soon" in
future.

24-24: ⚡ Quick win

Consider using a translation key for the prize value.

The prize amount "$58,000" is hardcoded, while other text uses translation keys. This could cause inconsistency if currency formatting varies by locale or if the prize value changes.

♻️ Suggested approach

Define a translation key like FABPrizeValueSummer2026 in all language files, then reference it:

 function PrizeSummer2026() {
   const t = useTranslations();
   return (
     <Card
       className="rounded-md border-olive-700 bg-olive-500/50 text-olive-800 dark:bg-olive-500/30 dark:text-olive-900-dark"
       heading1={t("FABPrizePool")}
-      heading2={"$58,000"}
+      heading2={t("FABPrizeValueSummer2026")}
     />
   );
 }
🤖 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 `@front_end/src/app/`(main)/aib/components/cards-2026-summer.tsx at line 24,
Replace the hardcoded prize string passed to the heading2 prop in the
cards-2026-summer.tsx component with a translation lookup (e.g., use
t('FABPrizeValueSummer2026')) and add the corresponding FABPrizeValueSummer2026
key to all locale files; ensure the translation value contains the properly
formatted currency (or use a localized number/currency formatter in the
component if you prefer dynamic formatting) so the heading2 prop receives the
translated/formatted prize instead of "$58,000".
🤖 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 `@front_end/messages/cs.json`:
- Line 2021: The Czech string for startCompetingDescription ends with
"dvoutýdenního" and relies on a separate miniBench key; fix by making
startCompetingDescription self-contained and grammatically correct: replace the
trailing "dvoutýdenního" with "dvoutýdenního MiniBench" (ensuring a single space
before "MiniBench" and correct capitalization), or alternatively keep
startCompetingDescription complete and stop concatenating with the
"miniBench"/"MiniBench" key; update the keys startCompetingDescription and/or
miniBench accordingly so the UI shows "… nebo se zúčastněte dvoutýdenního
MiniBench" as a complete phrase.

In `@front_end/messages/en.json`:
- Line 2078: The UI shows two different Summer 2026 prize amounts; make them
consistent by picking the correct prize value and updating all references:
either change the translation key startCompetingDescription to match the
hardcoded heading2 in the cards-2026-summer.tsx component, or change heading2 to
match the translation (and update the FABPrizeValue constant if that is meant to
be the canonical value); ensure startCompetingDescription, the heading2 prop in
the cards-2026-summer component, and FABPrizeValue all use the same dollar
amount string.

In `@front_end/src/app/`(main)/aib/2026/summer/page.tsx:
- Around line 12-35: Wrap the network calls inside getPrimaryBotToken in a
try/catch so any thrown error from ServerProfileApi.getMyProfile,
ServerAuthApi.getApiKey, ServerProfileApi.getMyBots, or
ServerProfileApi.getBotToken is caught and the function returns null instead of
letting the error bubble up; keep existing logic (check user.is_bot, find
primary bot, return token) inside the try block and in catch log the error
(optional) and return null as a graceful fallback.

In `@front_end/src/app/`(main)/aib/components/page-view-2026-summer.tsx:
- Around line 176-182: The Link elements in page-view-2026-summer.tsx that use
target="_blank" (the JSX fragments rendering terms and privacy links) are
missing rel attributes; update those Link usages to include rel="noopener
noreferrer" alongside target="_blank" to harden external links opened in a new
tab (locate the Link instances inside the terms and privacy render
functions/components and add the rel attribute).
- Around line 144-156: Replace the hardcoded CTA labels inside the JSX (the
"Summer 2026 Bot Tournament" and "MiniBench Tournaments" text nodes) with
localized strings using useTranslations(); e.g., import and call const t =
useTranslations('<appropriateNamespace>') at the top of the
page-view-2026-summer component and replace the span contents with
t('summer2026BotTournament') and t('miniBenchTournaments'); then add those keys
to the locale dictionaries so translations are available. Ensure you use the
same namespace as other AIB strings to keep consistency.

---

Nitpick comments:
In `@front_end/src/app/`(main)/aib/components/cards-2026-summer.tsx:
- Around line 47-49: The ternary checking heading2 === "Coming Soon" is dead
code; remove the conditional and replace the ternary expression with a single
responsive class string used for the element’s className (the JSX that currently
computes classes based on heading2). Locate the JSX where heading2 is used
(variable heading2 in the cards-2026-summer component) and update the class
expression to a single constant like "text-2xl md:text-4xl lg:text-6xl
min-[1920px]:text-7xl" (or choose the other size if preferred), or keep the
conditional but parameterize the match to a prop if you intend to support
"Coming Soon" in future.
- Line 24: Replace the hardcoded prize string passed to the heading2 prop in the
cards-2026-summer.tsx component with a translation lookup (e.g., use
t('FABPrizeValueSummer2026')) and add the corresponding FABPrizeValueSummer2026
key to all locale files; ensure the translation value contains the properly
formatted currency (or use a localized number/currency formatter in the
component if you prefer dynamic formatting) so the heading2 prop receives the
translated/formatted prize instead of "$58,000".

In `@front_end/src/app/`(main)/aib/components/tournament-pager.tsx:
- Around line 173-181: TOURNAMENT_ITEMS is currently a static array of English
titles; replace it with a factory that returns translated titles using the
client-side i18n hook (e.g., useTranslations) instead of exporting static
strings. Change the export to a function (e.g., getTournamentItems or
buildTournamentItems) that calls useTranslations() inside the component (or is
invoked from the component) to produce items with localized title values while
keeping the href values the same; update components that import TOURNAMENT_ITEMS
to call the new factory from client code so titles render localized labels.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 616151b8-66be-4d59-867c-21cde5c3e415

📥 Commits

Reviewing files that changed from the base of the PR and between f1b180b and e033388.

📒 Files selected for processing (15)
  • front_end/messages/cs.json
  • front_end/messages/en.json
  • front_end/messages/es.json
  • front_end/messages/pt.json
  • front_end/messages/zh-TW.json
  • front_end/messages/zh.json
  • front_end/src/app/(futureeval)/futureeval/components/futureeval-tournaments.tsx
  • front_end/src/app/(main)/aib/2026/summer/page.tsx
  • front_end/src/app/(main)/aib/components/cards-2026-summer.tsx
  • front_end/src/app/(main)/aib/components/hero-2026-summer.tsx
  • front_end/src/app/(main)/aib/components/next-tournament-card.tsx
  • front_end/src/app/(main)/aib/components/page-view-2025-q1.tsx
  • front_end/src/app/(main)/aib/components/page-view-2025-q2.tsx
  • front_end/src/app/(main)/aib/components/page-view-2026-summer.tsx
  • front_end/src/app/(main)/aib/components/tournament-pager.tsx

"botsVsHumansDescription": "Pořádáme sezónní a dvoutýdenní turnaje botů, otevřené pro všechny tvůrce. Boti soutěží proti sobě navzájem a jsou porovnáváni s nejlepšími lidskými předpovídači.",
"startCompeting": "Začněte soutěžit",
"startCompetingDescription": "Připojte se k více než 100 týmům a jednotlivým tvůrcům botů, kteří soutěží o cenový fond ve výši 50 000 dolarů na jaře 2026 nebo se zúčastněte dvoutýdenního",
"startCompetingDescription": "Připojte se k více než 100 týmům a jednotlivým tvůrcům botů, kteří soutěží o cenový fond ve výši 50 000 dolarů v létě 2026 nebo se zúčastněte dvoutýdenního",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

❓ Verification inconclusive

🏁 Script executed:

#!/bin/bash
# Check how other languages handle the startCompetingDescription ending

rg -A 1 '"startCompetingDescription"' front_end/messages/

Repository: Metaculus/metaculus

Length of output: 1429


🏁 Script executed:

#!/bin/bash
set -euo pipefail
# Inspect cs.json around the cited line and find miniBench value
nl -ba front_end/messages/cs.json | sed -n '2000,2050p'

# Find where startCompetingDescription is used and how miniBench is appended
rg -n --hidden --glob '!**/node_modules/**' 'startCompetingDescription' front_end | head -n 50

# Find usage of miniBench in front_end
rg -n --hidden --glob '!**/node_modules/**' 'miniBench' front_end | head -n 50

# Also inspect en.json around the same key to see if UI expects concatenation
nl -ba front_end/messages/en.json | sed -n '2000,2050p'

Repository: Metaculus/metaculus

Length of output: 106


🏁 Script executed:

#!/bin/bash
set -euo pipefail
# Inspect cs.json around the cited line and find miniBench value
nl -ba front_end/messages/cs.json | sed -n '2000,2050p'

# Find where startCompetingDescription is used and how miniBench is appended
rg -n --hidden --glob '!**/node_modules/**' 'startCompetingDescription' front_end | head -n 50

# Find usage of miniBench in front_end
rg -n --hidden --glob '!**/node_modules/**' 'miniBench' front_end | head -n 50

# Also inspect en.json around the same key to see if UI expects concatenation
nl -ba front_end/messages/en.json | sed -n '2000,2050p'

Repository: Metaculus/metaculus

Length of output: 106


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show cs.json around the relevant line (use sed without nl)
sed -n '2010,2035p' front_end/messages/cs.json

# Show en.json around the relevant key (same range)
sed -n '2010,2035p' front_end/messages/en.json

# Find where startCompetingDescription is referenced in the front_end code
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' 'startCompetingDescription' front_end | head -n 50

# Find where miniBench is referenced/concatenated
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' 'miniBench' front_end | head -n 80

Repository: Metaculus/metaculus

Length of output: 5273


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find code usage of the i18n keys (excluding message JSON files)
rg -n --glob '!front_end/messages/*.json' --glob '!front_end/messages/*' 'startCompetingDescription' front_end | head -n 50

rg -n --glob '!front_end/messages/*.json' --glob '!front_end/messages/*' 'miniBench' front_end | head -n 50

# Also search for string concatenation patterns involving the keys (if any)
rg -n --glob '!front_end/messages/*.json' --glob '!front_end/messages/*' 'startCompetingDescription.*miniBench|miniBench.*startCompetingDescription' front_end | head -n 50

Repository: Metaculus/metaculus

Length of output: 45


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Broader searches: exclude only the JSON message files, search everything else in front_end
rg -n --hidden --glob '!front_end/messages/*.json' 'startCompetingDescription' front_end | head -n 80

rg -n --hidden --glob '!front_end/messages/*.json' 'miniBench' front_end | head -n 80

# Search for rendering of the "miniBench" label near other localized strings
rg -n --hidden --glob '!front_end/messages/*.json' 'dvoutýdenn|dvoutýden' front_end | head -n 50

Repository: Metaculus/metaculus

Length of output: 45


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for other related keys outside the JSON message files
rg -n --hidden --glob '!front_end/messages/*.json' 'startCompeting' front_end | head -n 80

# Search for miniBench usage outside the JSON message files
rg -n --hidden --glob '!front_end/messages/*.json' 'MiniBench' front_end | head -n 80
rg -n --hidden --glob '!front_end/messages/*.json' '"miniBench"' front_end | head -n 80
rg -n --hidden --glob '!front_end/messages/*.json' 'miniBench' front_end | head -n 80

# Find the component/page that renders the "startCompetingDescription" content
rg -n --hidden --glob '!front_end/messages/*.json' 'startCompetingDescription' front_end | head -n 80
rg -n --hidden --glob '!front_end/messages/*.json' 'startCompetingDescription' . | head -n 80

Repository: Metaculus/metaculus

Length of output: 45


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search entire repo for exact key strings (excluding common generated dirs)
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' --glob '!**/.next/**' --glob '!**/coverage/**' '"startCompetingDescription"' . | head -n 50

rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' --glob '!**/.next/**' --glob '!**/coverage/**' '"miniBench"' . | head -n 50

# Also search for the end fragment shown in Czech to locate where it's used
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' --glob '!**/.next/**' 'dvoutýdenn' front_end . | head -n 50

Repository: Metaculus/metaculus

Length of output: 4434


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for components/strings referencing the feature (exclude message bundles)
rg -n --hidden --glob '!front_end/messages/**' --glob '!**/node_modules/**' 'startCompeting' front_end | head -n 80

rg -n --hidden --glob '!front_end/messages/**' --glob '!**/node_modules/**' 'miniBench' front_end | head -n 80
rg -n --hidden --glob '!front_end/messages/**' --glob '!**/node_modules/**' 'minibench' front_end | head -n 80

# Search for rendering of the "dvoutýdenního" fragment (should only appear in cs.json if not concatenated in code)
rg -n --hidden --glob '!front_end/messages/cs.json' --glob '!**/node_modules/**' 'dvoutýdenního' . | head -n 20

Repository: Metaculus/metaculus

Length of output: 45


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect nearby Czech strings around minibench keys
rg -n --hidden 'minibench|MiniBench|dvoutýdenn' front_end/messages/cs.json

# Check whether any Czech string already includes "dvoutýdenního MiniBench"
rg -n --hidden 'dvoutýdenn.*MiniBench|MiniBench.*dvoutýdenn' front_end/messages/cs.json

Repository: Metaculus/metaculus

Length of output: 2452


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate where the "MiniBench" label is rendered in the UI (outside message bundles)
rg -n --hidden --glob '!front_end/messages/*.json' --glob '!**/node_modules/**' 'MiniBench' front_end | head -n 80

# Locate components related to "tournaments" / "startCompeting" / "competing" in non-message code
rg -n --hidden --glob '!front_end/messages/*.json' --glob '!**/node_modules/**' 'startCompeting|startCompetingDescription|competing for|biweekly' front_end | head -n 80

# Find the i18n loader usage for front_end/messages
rg -n --hidden --glob '!**/node_modules/**' '(messages/cs\.json|front_end/messages|loadMessages|i18n|next-intl|react-intl|useTranslation|t\()' front_end | head -n 80

Repository: Metaculus/metaculus

Length of output: 9674


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect translations type to see how message keys are referenced in code
sed -n '1,200p' front_end/src/types/translations.ts

# Search for the page/component that likely renders the "startCompeting" copy around MiniBench
rg -n --hidden --glob '!front_end/messages/*.json' 'aibMiniBench|MiniBench|startCompeting' front_end/src/app front_end/src/components front_end/src | head -n 120

# Specifically inspect the likely AIB page(s) that might use startCompetingDescription
rg -n --hidden --glob '!front_end/messages/*.json' 't\(([^)]*startCompeting|startCompeting)' front_end/src | head -n 80
rg -n --hidden --glob '!front_end/messages/*.json' 'startCompetingDescription' front_end/src | head -n 80
rg -n --hidden --glob '!front_end/messages/*.json' 'miniBench' front_end/src | head -n 80

Repository: Metaculus/metaculus

Length of output: 2668


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the relevant AIB page view components around the reported lines
sed -n '120,220p' front_end/src/app/(main)/aib/components/page-view.tsx
sed -n '120,240p' front_end/src/app/(main)/aib/components/page-view-2026-summer.tsx

# Search for the translation keys as literals in these files
rg -n "startCompetingDescription|miniBench|startCompeting" front_end/src/app/(main)/aib/components/page-view.tsx
rg -n "startCompetingDescription|miniBench|startCompeting" front_end/src/app/(main)/aib/components/page-view-2026-summer.tsx

# Broader: search AIB pages/components for how the start section is rendered
rg -n "startCompetingDescription|startCompeting|miniBench" front_end/src/app/(main)/aib | head -n 80
rg -n "startCompetingDescription|startCompeting|miniBench" front_end/src/app | head -n 80

Repository: Metaculus/metaculus

Length of output: 125


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Quote paths containing parentheses
sed -n '120,220p' "front_end/src/app/(main)/aib/components/page-view.tsx"
sed -n '120,240p' "front_end/src/app/(main)/aib/components/page-view-2026-summer.tsx"

rg -n "startCompetingDescription|miniBench|startCompeting" "front_end/src/app/(main)/aib/components/page-view.tsx"
rg -n "startCompetingDescription|miniBench|startCompeting" "front_end/src/app/(main)/aib/components/page-view-2026-summer.tsx"

rg -n "startCompetingDescription|startCompeting|miniBench" "front_end/src/app/(main)/aib" | head -n 120

Repository: Metaculus/metaculus

Length of output: 8236


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for the exact keys in the AIB tournament components (quoted paths for parentheses)
rg -n "startCompetingDescription" "front_end/src/app/(main)/aib/components/page-view.tsx" "front_end/src/app/(main)/aib/components/page-view-2026-summer.tsx" || true

# Search the whole AIB components directory for those keys
rg -n "startCompetingDescription|miniBench\"|t\\(\"miniBench\"\\)|t\\.rich\\(\"miniBench\"|t\\(\"startCompeting\"\\)|t\\(\"startCompetingDescription\"\\)" "front_end/src/app/(main)/aib/components" || true

# If startCompetingDescription isn't referenced directly, look for "dvoutýdenního" fragment or "biweekly"/"MiniBench" concatenation logic
rg -n "dvoutýdenn|biweekly|bi-weekly|MiniBench|minibench" "front_end/src/app/(main)/aib/components" || true

# Show a larger slice around the start of the AiBenchmarkingTournamentPage components (may include where the description is rendered)
sed -n '1,220p' "front_end/src/app/(main)/aib/components/page-view.tsx"

Repository: Metaculus/metaculus

Length of output: 10109


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate where startCompetingDescription is used within the AIB components directory
rg -n "startCompetingDescription|startCompeting" "front_end/src/app/(main)/aib/components" || true
rg -n "startCompetingDescription|startCompeting" "front_end/src/app/(main)/aib" || true

# Inspect likely component that renders the start/competing description
ls -la "front_end/src/app/(main)/aib/components"
sed -n '1,220p' "front_end/src/app/(main)/aib/components/description.tsx" || true

# Also inspect other closely related components if present
for f in "hero.tsx" "cards.tsx" "tournament-pager.tsx" ; do
  if [ -f "front_end/src/app/(main)/aib/components/$f" ]; then
    echo "---- $f ----"
    sed -n '1,220p' "front_end/src/app/(main)/aib/components/$f"
  fi
done

Repository: Metaculus/metaculus

Length of output: 12131


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search non-message code for the key usage (should be near the place where Czech grammar matters)
rg -n --hidden --glob '!front_end/messages/*.json' 'startCompetingDescription' front_end/src | head -n 50

# If not referenced as a string, check for i18n type-safe usage patterns using the key name
rg -n --hidden --glob '!front_end/messages/*.json' 'startCompeting' front_end/src | head -n 100

# Search for where the "startCompeting" section might be rendered (tournament overview pages)
rg -n --hidden --glob '!front_end/messages/*.json' 'FABStart|FABCreate|GettingStarted|FABdesc' front_end/src/app/(main)/aib | head -n 120

# Inspect likely page(s) if the key is used in AIB 2026 spring/summer or related sections
rg -n --hidden --glob '!front_end/messages/*.json' 'FAB' front_end/src/app/(main)/aib | head -n 120

Repository: Metaculus/metaculus

Length of output: 45


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for substrings that might locate dynamic usage (excluding message bundles)
rg -n --hidden --glob '!front_end/messages/*.json' 'CompetingDescription' . | head -n 80
rg -n --hidden --glob '!front_end/messages/*.json' 'startCompeting' . | head -n 80

# Search for "biweekly" usage in code (to find where the English string is assembled)
rg -n --hidden --glob '!front_end/messages/*.json' 'biweekly' . | head -n 80

# Search for "zúčastněte se" usage or Czech-specific fragment
rg -n --hidden --glob '!front_end/messages/*.json' 'zúčastněte se' . | head -n 20

# Search for "miniBench" usage in non-message code (not just in messages)
rg -n --hidden --glob '!front_end/messages/*.json' 'miniBench' front_end/src | head -n 80

Repository: Metaculus/metaculus

Length of output: 45


Fix Czech string completeness/case for startCompetingDescription + miniBench.

front_end/messages/cs.json ends startCompetingDescription with "dvoutýdenního" while miniBench is a separate message key ("MiniBench"). If the UI concatenates these two pieces, the intended result should read "… nebo se zúčastněte dvoutýdenního MiniBench" (genitive after zúčastněte se). If the UI does not append miniBench (or appends with wrong spacing/case), this produces an incomplete sentence fragment and should be updated to include the noun in the same string (or adjust accordingly).

🤖 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 `@front_end/messages/cs.json` at line 2021, The Czech string for
startCompetingDescription ends with "dvoutýdenního" and relies on a separate
miniBench key; fix by making startCompetingDescription self-contained and
grammatically correct: replace the trailing "dvoutýdenního" with "dvoutýdenního
MiniBench" (ensuring a single space before "MiniBench" and correct
capitalization), or alternatively keep startCompetingDescription complete and
stop concatenating with the "miniBench"/"MiniBench" key; update the keys
startCompetingDescription and/or miniBench accordingly so the UI shows "… nebo
se zúčastněte dvoutýdenního MiniBench" as a complete phrase.

"botsVsHumansDescription": "We run seasonal and biweekly bot tournaments, open to all builders. Bots compete against each other and are benchmarked against top human forecasters.",
"startCompeting": "Start competing",
"startCompetingDescription": "Join 100+ teams and individual bot builders competing for a $50,000 prize pool in Spring 2026 or enter the biweekly",
"startCompetingDescription": "Join 100+ teams and individual bot builders competing for a $50,000 prize pool in Summer 2026 or enter the biweekly",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check for other prize pool references to understand context

echo "=== Searching for prize pool references in translation files ==="
rg -n "50,000|50000|\$50" front_end/messages/

echo -e "\n=== Searching for FABPrizeValue usage in codebase ==="
rg -n "FABPrizeValue" --type=ts --type=tsx

echo -e "\n=== Searching for startCompetingDescription usage ==="
rg -n "startCompetingDescription" --type=ts --type=tsx

Repository: Metaculus/metaculus

Length of output: 1143


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== FABPrizeValue references (translations + repo) ==="
rg -n "FABPrizeValue" front_end/messages/ || true
rg -n "FABPrizeValue" . || true

echo -e "\n=== startCompetingDescription references (translations + repo) ==="
rg -n "startCompetingDescription" front_end/messages/ || true
rg -n "startCompetingDescription" . || true

echo -e "\n=== Prize pool references near other tournament keys in en.json ==="
# Show the nearby context around the en.json occurrences of 50,000 / 30,000 if present
rg -n "50,000|\$50|30,000|\$30" front_end/messages/en.json || true

Repository: Metaculus/metaculus

Length of output: 3693


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== startCompetingDescription usage in front_end/src ==="
rg -n "t\\(\"startCompetingDescription\"\\)|startCompetingDescription" front_end/src --glob='*.ts' --glob='*.tsx' || true

echo -e "\n=== FABPrizeValue usage in front_end/src (components) ==="
sed -n '1,120p' front_end/src/app/(main)/aib/components/cards-q1.tsx
sed -n '1,120p' front_end/src/app/(main)/aib/components/cards-q2.tsx
sed -n '1,120p' front_end/src/app/(main)/aib/components/cards-q3.tsx
sed -n '1,120p' front_end/src/app/(main)/aib/components/cards-q4.tsx

Repository: Metaculus/metaculus

Length of output: 259


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== startCompetingDescription usage in front_end/src ==="
rg -n "startCompetingDescription" front_end/src --glob='*.ts' --glob='*.tsx' || true

echo -e "\n=== FABPrizeValue usage in front_end/src ==="
rg -n "FABPrizeValue" front_end/src --glob='*.ts' --glob='*.tsx' || true

echo -e "\n=== Locate cards-q*.tsx ==="
fd -a "cards-q*.tsx" front_end/src || true

echo -e "\n=== Show top + FABPrizeValue usage context in cards-q1..q4 ==="
for f in $(fd -a "cards-q[1-4].tsx" front_end/src | sort); do
  echo -e "\n--- $f ---"
  # print first 120 lines and any line containing FABPrizeValue
  nl -ba "$f" | head -n 140 | sed -n '1,140p'
  rg -n "FABPrizeValue" "$f" || true
done

Repository: Metaculus/metaculus

Length of output: 770


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== cards-q*.tsx files ==="
fd -a "cards-q[1-4].tsx" front_end/src | sort

for f in $(fd -a "cards-q[1-4].tsx" front_end/src | sort); do
  echo -e "\n--- $f (first 120 lines) ---"
  sed -n '1,120p' "$f"

  echo -e "\n--- $f (lines with FABPrizeValue + context) ---"
  rg -n "FABPrizeValue" "$f" || true

  # Show a small window around the occurrences
  # (get line numbers from rg output)
  while read -r line; do
    ln=$(echo "$line" | cut -d: -f2)
    start=$((ln-8))
    end=$((ln+12))
    echo -e "\nWindow around line $ln:"
    sed -n "${start},${end}p" "$f"
  done < <(rg -n "FABPrizeValue" "$f" || true)

done

Repository: Metaculus/metaculus

Length of output: 2292


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== en.json around FABPrizePool / FABPrizeValue ==="
sed -n '1085,1135p' front_end/messages/en.json

echo -e "\n=== en.json around startCompetingDescription ==="
sed -n '2055,2105p' front_end/messages/en.json

echo -e "\n=== startCompetingDescription usage in front_end/src (ts/tsx) ==="
rg -n "startCompetingDescription" front_end/src --glob='*.ts' --glob='*.tsx' || true

echo -e "\n=== FABPrizePool usage in front_end/src (ts/tsx) ==="
rg -n "FABPrizePool" front_end/src --glob='*.ts' --glob='*.tsx' || true

echo -e "\n=== Summer 2026 references in front_end/src ==="
rg -n "Summer 2026" front_end/src --glob='*.ts' --glob='*.tsx' || true

Repository: Metaculus/metaculus

Length of output: 8466


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== startCompetingDescription key usage across front_end ==="
rg -n "startCompetingDescription" front_end --glob='*.ts' --glob='*.tsx' --glob='*.js' --glob='*.jsx' --glob='*.md' --glob='*.json' --glob='*.html' || true

echo -e "\n=== startCompeting key usage ==="
rg -n "t\\(\"startCompetingDescription\"\\)|t\\(\"startCompeting\"\\)" front_end --glob='*.ts' --glob='*.tsx' --glob='*.js' --glob='*.jsx' || true

echo -e "\n=== Inspect cards-2026-summer.tsx ==="
sed -n '1,200p' front_end/src/app/(main)/aib/components/cards-2026-summer.tsx

echo -e "\n=== Inspect tournament-pager.tsx around Summer 2026 ==="
sed -n '140,230p' front_end/src/app/(main)/aib/components/tournament-pager.tsx

echo -e "\n=== Inspect page-view-2026-summer.tsx around where cards are rendered ==="
# show around mid file
sed -n '110,210p' front_end/src/app/(main)/aib/components/page-view-2026-summer.tsx

Repository: Metaculus/metaculus

Length of output: 1331


🏁 Script executed:

#!/bin/bash
set -euo pipefail

cards_base="front_end/src/app/(main)/aib/components"

echo "=== Inspect cards-2026-summer.tsx ==="
sed -n '1,220p' "${cards_base}/cards-2026-summer.tsx"

echo -e "\n=== Inspect tournament-pager.tsx around Summer 2026 ==="
sed -n '150,230p' "front_end/src/app/(main)/aib/components/tournament-pager.tsx"

echo -e "\n=== Inspect page-view-2026-summer.tsx around card rendering ==="
sed -n '120,240p' "front_end/src/app/(main)/aib/components/page-view-2026-summer.tsx"

Repository: Metaculus/metaculus

Length of output: 6832


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "startCompetingDescription" . || true

Repository: Metaculus/metaculus

Length of output: 1128


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Search for $58,000 / 58000 ==="
rg -n "\\$58,000|58000" . || true

echo -e "\n=== Search for $50,000 / 50000 ==="
rg -n "\\$50,000|50000" front_end/src front_end/messages . || true

echo -e "\n=== Search for Summer 2026 prize pool mentions ==="
rg -n "Summer 2026|2026/summer|2026-summer" front_end/src --glob='*.ts' --glob='*.tsx' || true

Repository: Metaculus/metaculus

Length of output: 103


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Search for \$58,000 ==="
rg -n '\$58,000' . || true

echo -e "\n=== Search for \$50,000 ==="
rg -n '\$50,000|50000' front_end/src front_end/messages . || true

echo -e "\n=== Search for Summer 2026 prize pool mentions ==="
rg -n 'Summer 2026|/aib/2026/summer|2026/summer' front_end/src --glob='*.ts' --glob='*.tsx' --glob='*.js' --glob='*.jsx' || true

Repository: Metaculus/metaculus

Length of output: 50377


Fix inconsistent Summer 2026 prize pool text

  • front_end/messages/en.json startCompetingDescription says “$50,000 prize pool in Summer 2026”.
  • The Summer 2026 prize card hardcodes heading2={"$58,000"} in front_end/src/app/(main)/aib/components/cards-2026-summer.tsx.
  • FABPrizeValue ($30,000) is used for the Q1–Q4 cards, so it doesn’t resolve the Summer 2026 mismatch.

Update whichever is wrong so the Summer 2026 prize amount is consistent across the UI and translation.

🤖 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 `@front_end/messages/en.json` at line 2078, The UI shows two different Summer
2026 prize amounts; make them consistent by picking the correct prize value and
updating all references: either change the translation key
startCompetingDescription to match the hardcoded heading2 in the
cards-2026-summer.tsx component, or change heading2 to match the translation
(and update the FABPrizeValue constant if that is meant to be the canonical
value); ensure startCompetingDescription, the heading2 prop in the
cards-2026-summer component, and FABPrizeValue all use the same dollar amount
string.

Comment on lines +12 to +35
async function getPrimaryBotToken() {
const user = await ServerProfileApi.getMyProfile();

if (!user) {
return null;
}

if (user.is_bot) {
const { key } = await ServerAuthApi.getApiKey();
return key;
}

const bots = await ServerProfileApi.getMyBots();
const primaryBot = bots.find((bot) => bot.is_primary_bot);

if (primaryBot) {
const { token: botToken } = await ServerProfileApi.getBotToken(
primaryBot.id
);
return botToken;
}

return null;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Handle token lookup failures with a graceful fallback.

A thrown error from any server call here can take down the entire page render. This path should degrade to null so users can still access the page when bot/token endpoints fail transiently.

Proposed fix
 async function getPrimaryBotToken() {
-  const user = await ServerProfileApi.getMyProfile();
+  try {
+    const user = await ServerProfileApi.getMyProfile();

-  if (!user) {
-    return null;
-  }
+    if (!user) {
+      return null;
+    }

-  if (user.is_bot) {
-    const { key } = await ServerAuthApi.getApiKey();
-    return key;
-  }
+    if (user.is_bot) {
+      const { key } = await ServerAuthApi.getApiKey();
+      return key;
+    }

-  const bots = await ServerProfileApi.getMyBots();
-  const primaryBot = bots.find((bot) => bot.is_primary_bot);
+    const bots = await ServerProfileApi.getMyBots();
+    const primaryBot = bots.find((bot) => bot.is_primary_bot);

-  if (primaryBot) {
-    const { token: botToken } = await ServerProfileApi.getBotToken(
-      primaryBot.id
-    );
-    return botToken;
-  }
+    if (primaryBot) {
+      const { token: botToken } = await ServerProfileApi.getBotToken(
+        primaryBot.id
+      );
+      return botToken;
+    }

-  return null;
+    return null;
+  } catch {
+    return null;
+  }
 }
📝 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.

Suggested change
async function getPrimaryBotToken() {
const user = await ServerProfileApi.getMyProfile();
if (!user) {
return null;
}
if (user.is_bot) {
const { key } = await ServerAuthApi.getApiKey();
return key;
}
const bots = await ServerProfileApi.getMyBots();
const primaryBot = bots.find((bot) => bot.is_primary_bot);
if (primaryBot) {
const { token: botToken } = await ServerProfileApi.getBotToken(
primaryBot.id
);
return botToken;
}
return null;
}
async function getPrimaryBotToken() {
try {
const user = await ServerProfileApi.getMyProfile();
if (!user) {
return null;
}
if (user.is_bot) {
const { key } = await ServerAuthApi.getApiKey();
return key;
}
const bots = await ServerProfileApi.getMyBots();
const primaryBot = bots.find((bot) => bot.is_primary_bot);
if (primaryBot) {
const { token: botToken } = await ServerProfileApi.getBotToken(
primaryBot.id
);
return botToken;
}
return null;
} catch {
return null;
}
}
🤖 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 `@front_end/src/app/`(main)/aib/2026/summer/page.tsx around lines 12 - 35, Wrap
the network calls inside getPrimaryBotToken in a try/catch so any thrown error
from ServerProfileApi.getMyProfile, ServerAuthApi.getApiKey,
ServerProfileApi.getMyBots, or ServerProfileApi.getBotToken is caught and the
function returns null instead of letting the error bubble up; keep existing
logic (check user.is_bot, find primary bot, return token) inside the try block
and in catch log the error (optional) and return null as a graceful fallback.

Comment on lines +144 to +156
Summer 2026 Bot Tournament
</span>
</Link>
<Link
href="/aib/minibench"
className="flex w-full items-center gap-4 rounded bg-white p-4 no-underline transition-all hover:bg-blue-500/40 dark:bg-blue-100-dark dark:hover:bg-blue-600/40 md:p-5 min-[1920px]:p-6"
>
<FontAwesomeIcon
icon={faChartBar}
className="text-2xl text-blue-700 dark:text-blue-700-dark md:text-3xl min-[1920px]:text-4xl"
/>
<span className="text-lg font-medium md:text-xl min-[1920px]:text-2xl">
MiniBench Tournaments

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the newly added CTA labels instead of hardcoding English.

These strings bypass locale dictionaries and will remain English in translated UIs.

Proposed fix
-                <span className="text-lg font-medium md:text-xl min-[1920px]:text-2xl">
-                  Summer 2026 Bot Tournament
-                </span>
+                <span className="text-lg font-medium md:text-xl min-[1920px]:text-2xl">
+                  {`${t("FABSeasonSummer")} 2026 ${t("Tournament")}`}
+                </span>
...
-                <span className="text-lg font-medium md:text-xl min-[1920px]:text-2xl">
-                  MiniBench Tournaments
-                </span>
+                <span className="text-lg font-medium md:text-xl min-[1920px]:text-2xl">
+                  {`${t("miniBench")} ${t("tournaments")}`}
+                </span>

Based on learnings: Do not hardcode English strings in TSX components; prefer useTranslations() and i18n keys.

📝 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.

Suggested change
Summer 2026 Bot Tournament
</span>
</Link>
<Link
href="/aib/minibench"
className="flex w-full items-center gap-4 rounded bg-white p-4 no-underline transition-all hover:bg-blue-500/40 dark:bg-blue-100-dark dark:hover:bg-blue-600/40 md:p-5 min-[1920px]:p-6"
>
<FontAwesomeIcon
icon={faChartBar}
className="text-2xl text-blue-700 dark:text-blue-700-dark md:text-3xl min-[1920px]:text-4xl"
/>
<span className="text-lg font-medium md:text-xl min-[1920px]:text-2xl">
MiniBench Tournaments
{`${t("FABSeasonSummer")} 2026 ${t("Tournament")}`}
</span>
</Link>
<Link
href="/aib/minibench"
className="flex w-full items-center gap-4 rounded bg-white p-4 no-underline transition-all hover:bg-blue-500/40 dark:bg-blue-100-dark dark:hover:bg-blue-600/40 md:p-5 min-[1920px]:p-6"
>
<FontAwesomeIcon
icon={faChartBar}
className="text-2xl text-blue-700 dark:text-blue-700-dark md:text-3xl min-[1920px]:text-4xl"
/>
<span className="text-lg font-medium md:text-xl min-[1920px]:text-2xl">
{`${t("miniBench")} ${t("tournaments")}`}
🤖 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 `@front_end/src/app/`(main)/aib/components/page-view-2026-summer.tsx around
lines 144 - 156, Replace the hardcoded CTA labels inside the JSX (the "Summer
2026 Bot Tournament" and "MiniBench Tournaments" text nodes) with localized
strings using useTranslations(); e.g., import and call const t =
useTranslations('<appropriateNamespace>') at the top of the
page-view-2026-summer component and replace the span contents with
t('summer2026BotTournament') and t('miniBenchTournaments'); then add those keys
to the locale dictionaries so translations are available. Ensure you use the
same namespace as other AIB strings to keep consistency.

Source: Learnings

Comment on lines +176 to +182
<Link target="_blank" href={"/terms-of-use/"}>
{chunks}
</Link>
),
privacy: (chunks) => (
<Link target="_blank" href={"/privacy-policy/"}>
{chunks}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Harden external links opened in a new tab.

Add rel="noopener noreferrer" wherever target="_blank" is used.

Proposed fix
-                  <Link target="_blank" href={"/terms-of-use/"}>
+                  <Link
+                    target="_blank"
+                    rel="noopener noreferrer"
+                    href={"/terms-of-use/"}
+                  >
                     {chunks}
                   </Link>
...
-                  <Link target="_blank" href={"/privacy-policy/"}>
+                  <Link
+                    target="_blank"
+                    rel="noopener noreferrer"
+                    href={"/privacy-policy/"}
+                  >
                     {chunks}
                   </Link>
📝 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.

Suggested change
<Link target="_blank" href={"/terms-of-use/"}>
{chunks}
</Link>
),
privacy: (chunks) => (
<Link target="_blank" href={"/privacy-policy/"}>
{chunks}
<Link
target="_blank"
rel="noopener noreferrer"
href={"/terms-of-use/"}
>
{chunks}
</Link>
),
privacy: (chunks) => (
<Link
target="_blank"
rel="noopener noreferrer"
href={"/privacy-policy/"}
>
{chunks}
</Link>
🤖 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 `@front_end/src/app/`(main)/aib/components/page-view-2026-summer.tsx around
lines 176 - 182, The Link elements in page-view-2026-summer.tsx that use
target="_blank" (the JSX fragments rendering terms and privacy links) are
missing rel attributes; update those Link usages to include rel="noopener
noreferrer" alongside target="_blank" to harden external links opened in a new
tab (locate the Link instances inside the terms and privacy render
functions/components and add the rel attribute).

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.

1 participant