Skip to content

feat(resources): add beta banner CTA for watch pages#8496

Closed
lumberman wants to merge 7 commits intomainfrom
codex/vm-25-add-non-dismissable-beta-banner
Closed

feat(resources): add beta banner CTA for watch pages#8496
lumberman wants to merge 7 commits intomainfrom
codex/vm-25-add-non-dismissable-beta-banner

Conversation

@lumberman
Copy link
Copy Markdown
Contributor

@lumberman lumberman commented Dec 10, 2025

Summary

  • add a BetaBanner component that appears on watch routes with a full-width clickable CTA to set the EXPERIMENTAL cookie
  • render the banner at the top of the app layout and localize its copy in the apps-resources namespace
  • document the implementation notes for this branch in the resources PRD folder

Testing

  • not run (not requested)

Codex Task

Summary by CodeRabbit

  • New Features

    • Beta banner appears on Watch routes with keyboard/click activation; opting in sets the experiment and reloads to enable the experimental experience.
    • Animated particle background and responsive messaging for mobile/desktop.
  • Localization

    • Added translations for new banner text across many locales.
  • Documentation

    • Added docs describing banner behavior, user flows, and verification.
  • Tests

    • New tests cover rendering, accessibility, and opt-in interaction.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 10, 2025

Walkthrough

Adds a BetaBanner React component (route-gated for /watch*) with a canvas particle background and activation that sets EXPERIMENTAL=true cookie and reloads; integrates it into the app shell, adds tests and docs, and injects four new translation keys across many locale files.

Changes

Cohort / File(s) Summary
BetaBanner component
apps/resources/src/components/BetaBanner/BetaBanner.tsx, apps/resources/src/components/BetaBanner/index.ts
New exported React component rendering a full-width interactive banner on /watch* routes with a canvas particle background, keyboard/click activation that sets EXPERIMENTAL=true cookie and reloads, resize handling, RAF animation loop, and accessibility attributes.
App integration
apps/resources/pages/_app.tsx
Imports and renders <BetaBanner /> inside the ThemeProvider tree, before InstantSearchProvider.
Tests & Test setup
apps/resources/src/components/BetaBanner/BetaBanner.test.tsx, apps/resources/setupTests.tsx
New test suite for BetaBanner (mocks canvas/context/RAF, router, cookie behavior, accessibility, interaction flow) and added mock for next/compat/router in test setup.
Localization files
libs/locales/*/apps-resources.json
Examples: libs/locales/en/apps-resources.json, libs/locales/ar-SA/apps-resources.json, libs/locales/de-DE/apps-resources.json, libs/locales/es-ES/apps-resources.json, libs/locales/fr-FR/apps-resources.json, libs/locales/pt-BR/apps-resources.json, libs/locales/zh-Hans-CN/apps-resources.json, libs/locales/…
Adds four new translation keys ("Better search…", "Better search, languages…", "Try the new design.", "New Design") to many locale JSON files; minor punctuation edits (trailing commas) to append entries.
Documentation
prds/resources/work.md
New documentation describing BetaBanner goals, implementation, user flows, tests, and follow-up ideas.
Repository guidance
apps/resources/AGENTS.md
Minor edits replacing Tailwind/shadcn-specific guidance with broader "styling" terminology and cleanup of related instructions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Pay attention to apps/resources/src/components/BetaBanner/BetaBanner.tsx: router readiness gating, cookie domain/path/expiry, RAF animation lifecycle and cleanup, resize listener behavior, and accessibility (keyboard handlers, roles).
  • Review BetaBanner.test.tsx for robust mocking of canvas/context/RAF and correctness of interaction expectations.
  • Confirm _app.tsx insertion point and rendering order relative to ThemeProvider and InstantSearchProvider.
  • Spot-check several locale files for valid JSON syntax (commas/formatting) after additions.

Suggested reviewers

  • mikeallisonJS
  • kiran-redhat

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ 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 'feat(resources): add beta banner CTA for watch pages' directly and accurately summarizes the primary change: introducing a beta banner component with a call-to-action for watch pages.
✨ 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 codex/vm-25-add-non-dismissable-beta-banner

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.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 10, 2025

Fails
🚫 Please assign someone to merge this PR.
Warnings
⚠️ ❗ Big PR (601 changes)

(change count - 601): Pull Request size seems relatively large. If Pull Request contains multiple changes, split each into separate PR will helps faster, easier review.

Generated by 🚫 dangerJS against 906946e

@nx-cloud
Copy link
Copy Markdown

nx-cloud bot commented Dec 10, 2025

View your CI Pipeline Execution ↗ for commit 906946e

Command Status Duration Result
nx run journeys-admin-e2e:e2e ✅ Succeeded 3m 38s View ↗
nx run journeys-e2e:e2e ✅ Succeeded 24s View ↗
nx run resources-e2e:e2e ✅ Succeeded 12s View ↗
nx run watch-e2e:e2e ✅ Succeeded 12s View ↗
nx run videos-admin-e2e:e2e ✅ Succeeded 5s View ↗
nx run watch-modern-e2e:e2e ✅ Succeeded 4s View ↗
nx run-many --target=vercel-alias --projects=watch ✅ Succeeded 2s View ↗
nx run-many --target=upload-sourcemaps --projec... ✅ Succeeded 10s View ↗
Additional runs (16) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2025-12-11 23:57:41 UTC

@github-actions github-actions bot temporarily deployed to Preview - videos-admin December 10, 2025 22:36 Inactive
@github-actions github-actions bot temporarily deployed to Preview - resources December 10, 2025 22:36 Inactive
@github-actions github-actions bot temporarily deployed to Preview - watch-modern December 10, 2025 22:36 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys December 10, 2025 22:36 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin December 10, 2025 22:36 Inactive
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 10, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
watch-modern ✅ Ready watch-modern preview Fri Dec 12 12:47:21 NZDT 2025

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 10, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
journeys ✅ Ready journeys preview Fri Dec 12 12:47:41 NZDT 2025

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 10, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
videos-admin ✅ Ready videos-admin preview Fri Dec 12 12:48:07 NZDT 2025

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 10, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
watch ✅ Ready watch preview Fri Dec 12 12:49:24 NZDT 2025

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 10, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
resources ✅ Ready resources preview Fri Dec 12 12:48:38 NZDT 2025

Copy link
Copy Markdown
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: 1

🧹 Nitpick comments (4)
prds/resources/work.md (1)

1-24: PRD content is clear and aligned with the feature behavior

The goals, implementation strategy, and user flow match the BetaBanner implementation. You might later expand “Test Coverage” with concrete manual steps or acceptance criteria once behavior is validated, but nothing blocks merge here.

libs/locales/en/apps-resources.json (1)

94-98: Locale entries match component usage

The betaBanner object shape (message, cta) lines up with t('betaBanner.message') / t('betaBanner.cta') in the component. Just ensure any other supported locales mirror this nested structure so translations stay in sync.

apps/resources/src/components/BetaBanner/BetaBanner.tsx (2)

13-23: Align event handler naming with handle* convention and separate handler from effect

activateExperimentalMode is wired directly to onClick but isn’t named with a handle* prefix, while handleKeyDown is. To match the handler convention and distinguish the effect from the handler, consider:

-  const activateExperimentalMode = (): void => {
+  const activateExperimentalMode = (): void => {
     document.cookie = 'EXPERIMENTAL=true; path=/'
     window.location.reload()
   }
 
-  const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {
+  const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {
     if (event.key === 'Enter' || event.key === ' ') {
       event.preventDefault()
-      activateExperimentalMode()
+      handleActivateExperimentalMode()
     }
   }
+
+  const handleActivateExperimentalMode = (): void => {
+    activateExperimentalMode()
+  }

and then:

-      onClick={activateExperimentalMode}
+      onClick={handleActivateExperimentalMode}

This keeps handlers prefixed with handle* while centralizing the activation logic.

As per coding guidelines, event functions should be named with a handle prefix.

Also applies to: 30-31


7-7: Update t(...) usage to inline human-readable copy instead of key-based strings

Guidelines for apps/resources/src/**/* recommend calling t with the human-readable copy (with placeholders when needed), e.g. t('Switch to {{localeName}}', { ... }), rather than abstract keys. Here you could adjust to:

aria-label={t('Switch to beta')}
...
{t('Try the new Watch beta experience.')}{' '}
<Box component="span" sx={{ fontWeight: 700 }}>
  {t('Switch to beta')}
</Box>

and update the locale file to use those strings as keys, keeping translations consistent while following the “inline copy” pattern.

As per coding guidelines, t(...) should be called with the user-facing copy, not a named key.

Also applies to: 32-32, 50-52

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ff1fd50 and 535d740.

📒 Files selected for processing (5)
  • apps/resources/pages/_app.tsx (2 hunks)
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx (1 hunks)
  • apps/resources/src/components/BetaBanner/index.ts (1 hunks)
  • libs/locales/en/apps-resources.json (1 hunks)
  • prds/resources/work.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

**/*.{ts,tsx,js,jsx}: Use early returns whenever possible to make the code more readable.
Use descriptive variable and function/const names.
Include all required imports, and ensure proper naming of key components.

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/pages/_app.tsx
  • apps/resources/src/components/BetaBanner/index.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

Define a type if possible.

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/pages/_app.tsx
  • apps/resources/src/components/BetaBanner/index.ts
apps/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/apps.mdc)

apps/**/*.{js,jsx,ts,tsx}: Always use MUI over HTML elements; avoid using CSS or tags.
Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown.
Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/pages/_app.tsx
  • apps/resources/src/components/BetaBanner/index.ts
apps/resources/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

apps/resources/src/**/*.{ts,tsx}: Do not introduce new MUI usage even though the lint rule is relaxed; new shadcn work should coexist with core shells/wrappers that are still using MUI until explicit migration tasks retire them
Use Shadcn/ui components as the primary choice for all UI needs; if shadcn/ui doesn't exist, build with Tailwind CSS; use Semantic HTML + Tailwind only for basic elements when neither above applies
Use semantic HTML elements: <header>, <main>, <footer>
Keep handlers prefixed with handle* (e.g., handleClick, handleKeyDown); type everything explicitly; lean on generated GraphQL helpers (ResultOf, VariablesOf)
Compose UI with shadcn/ui primitives or semantic HTML styled via Tailwind; use the shared cn helper for conditional classes
Tailwind utilities should stay semantically grouped—Prettier sorts the lists, but ensure responsive and state variants remain readable
Use descriptive variable and function/const names; event functions should be named with 'handle' prefix, like 'handleClick' for onClick and 'handleKeyDown' for onKeyDown
Implement accessibility features on elements: tags should have tabindex='0', aria-label, on:click, on:keydown, and similar attributes; build accessible experiences as part of every component
Verify that every clickable element has cursor:pointer defined
When calling t(...), inline the human-readable copy with interpolation placeholders (e.g., t('Switch to {{localeName}}', { localeName: localeDetails.nativeName })) instead of referencing stored translation keys
All components and functions must be fully typed with TypeScript
Use alphabetical order for imports and exports
Follow a server-first architecture: use 'use client' components only when necessary
Use semantic HTML forms with proper action/method and graceful fallbacks for interactive features
Apollo hooks should use generated types alongside colocated documents; useVideoChildren is the reference pattern
useWatch dispatches should tar...

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/index.ts
apps/resources/src/components/**/*.tsx

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

Component naming format: Use UiType prefix (e.g., Modal, Button, Footer, Page) + ComponentFunction (e.g., LanguageSwitch, MainVideo); omit ComponentFunction for basic primitives; use PascalCase for all component names

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
apps/resources/src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

Component props should use optional props with sensible defaults; include className prop for extensibility; use ReactNode for children and content slots; name interfaces with component name prefix (e.g., ComponentNameProps)

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/index.ts
apps/resources/src/**/index.ts

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

Export all components through index.ts files

Files:

  • apps/resources/src/components/BetaBanner/index.ts
🧠 Learnings (16)
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/src/**/*.{tsx} : Navigation: design link-based content discovery through components

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • prds/resources/work.md
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Dialogs/Modals prefixed with 'Dialog', Sections with 'Section', Layout components with 'Layout'

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/pages/_app.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/src/**/*.{tsx} : Compose UI with shadcn/ui primitives or semantic HTML styled via Tailwind; do not introduce new MUI usage

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/pages/_app.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Use semantic HTML elements (header, main, footer)

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/pages/_app.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Compose UI with shadcn/ui primitives or semantic HTML styled via Tailwind; use the shared `cn` helper for conditional classes

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/pages/_app.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Optimize bundles via tree-shaking and code splitting in component design

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Use semantic HTML elements: `<header>`, `<main>`, `<footer>`

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/pages/_app.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/src/**/index.ts : Export all components via index.ts files in their folders

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/index.ts
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Keep browser-only logic minimal and isolated (media controls, complex form state, browser APIs)

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Follow React component naming rule: %UiType%%ComponentFunction% in PascalCase (e.g., ModalLogin, PageHome)

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/libs/ui/**/*.{ts,tsx} : Add shadcn components to the root of the repo in /core/libs/ui/ (monorepo structure), not in the app directory

Applied to files:

  • apps/resources/pages/_app.tsx
  • apps/resources/src/components/BetaBanner/index.ts
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/components/**/*Video*.{ts,tsx} : Components like `VideoContentHero` depend on the full provider stack (VideoProvider, WatchProvider, PlayerProvider) plus video.js and mux metadata; preserve existing contracts for autoplay, subtitles, and analytics

Applied to files:

  • apps/resources/pages/_app.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/index.ts : Export all components through index.ts files

Applied to files:

  • apps/resources/pages/_app.tsx
  • apps/resources/src/components/BetaBanner/index.ts
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/core/libs/ui/**/*.{ts,tsx} : Add new shadcn components only under /core/libs/ui/ at repo root

Applied to files:

  • apps/resources/pages/_app.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Use Shadcn/ui components as the primary choice for all UI needs; if shadcn/ui doesn't exist, build with Tailwind CSS; use Semantic HTML + Tailwind only for basic elements when neither above applies

Applied to files:

  • apps/resources/pages/_app.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Use alphabetical order for imports and exports

Applied to files:

  • apps/resources/src/components/BetaBanner/index.ts
🧬 Code graph analysis (2)
apps/resources/src/components/BetaBanner/BetaBanner.tsx (1)
apps/resources/src/components/BetaBanner/index.ts (1)
  • BetaBanner (1-1)
apps/resources/pages/_app.tsx (2)
apps/resources/src/components/BetaBanner/BetaBanner.tsx (1)
  • BetaBanner (6-58)
apps/resources/src/components/BetaBanner/index.ts (1)
  • BetaBanner (1-1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Deploy Preview (journeys, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (journeys-admin, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (watch, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (resources, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (watch-modern, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (videos-admin, 8496/merge, pull_request, 22)
  • GitHub Check: test (22, 3/3)
  • GitHub Check: test (22, 2/3)
  • GitHub Check: test (22, 1/3)
  • GitHub Check: build (22)
  • GitHub Check: lint (22)
🔇 Additional comments (2)
apps/resources/src/components/BetaBanner/index.ts (1)

1-1: Index re-export follows the expected barrel pattern

Re-exporting BetaBanner from ./BetaBanner matches the index.ts convention for components and keeps imports clean.

apps/resources/pages/_app.tsx (1)

21-21: BetaBanner wiring into _app looks correct

Importing BetaBanner and rendering it inside ThemeProvider but above InstantSearchProvider / <Component /> cleanly injects the banner across pages while keeping it visually on top of Watch content and respecting existing providers.

Also applies to: 162-163

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 10, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
journeys-admin ✅ Ready journeys-admin preview Fri Dec 12 12:49:08 NZDT 2025

@blacksmith-sh

This comment has been minimized.

- Added particle animation effect to the BetaBanner for a dynamic visual experience on watch pages.
- Implemented responsive design adjustments for mobile users.
- Updated localization files to include new text for the banner in multiple languages.
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin December 11, 2025 02:52 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys December 11, 2025 02:52 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin December 11, 2025 02:52 Inactive
@github-actions github-actions bot temporarily deployed to Preview - resources December 11, 2025 02:52 Inactive
@github-actions github-actions bot temporarily deployed to Preview - watch-modern December 11, 2025 02:52 Inactive
Copy link
Copy Markdown
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

♻️ Duplicate comments (1)
apps/resources/src/components/BetaBanner/BetaBanner.tsx (1)

1-1: MUI usage should be replaced with shadcn/Tailwind for apps/resources/src.

As per coding guidelines, apps/resources/src/**/* should use shadcn/ui components or semantic HTML + Tailwind, not new MUI usage. Consider refactoring to use semantic elements styled with Tailwind.

🧹 Nitpick comments (2)
apps/resources/src/components/BetaBanner/BetaBanner.tsx (2)

133-140: Semantic concern: role="button" on a <section> element.

Using role="button" on a component="section" is semantically conflicting. A <section> represents a thematic grouping of content, while role="button" indicates an interactive control. Screen readers may announce this inconsistently.

Consider using a more appropriate semantic structure:

     <Box
-      role="button"
+      role="banner"
       tabIndex={0}
-      component="section"
+      component="div"
       onClick={activateExperimentalMode}
       onKeyDown={handleKeyDown}
       aria-label={t('Try the new design.')}

Alternatively, wrap the content in a focusable <button> element within the banner for clearer semantics.


50-55: Consider reducing particle count or making it configurable for performance.

Creating 350 particles with continuous animation may impact performance on lower-end devices. Consider reducing the count or using requestIdleCallback for initialization.

 const initParticles = () => {
   particlesRef.current = []
-  for (let i = 0; i < 350; i++) {
+  const particleCount = isMobile ? 150 : 350
+  for (let i = 0; i < particleCount; i++) {
     particlesRef.current.push(createParticle())
   }
 }

Note: This would require passing isMobile into the effect or using a ref to access it.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 535d740 and 4a85b80.

📒 Files selected for processing (8)
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx (1 hunks)
  • libs/locales/ar-SA/apps-resources.json (1 hunks)
  • libs/locales/de-DE/apps-resources.json (1 hunks)
  • libs/locales/en/apps-resources.json (1 hunks)
  • libs/locales/es-ES/apps-resources.json (1 hunks)
  • libs/locales/fr-FR/apps-resources.json (1 hunks)
  • libs/locales/pt-BR/apps-resources.json (1 hunks)
  • libs/locales/zh-Hans-CN/apps-resources.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • libs/locales/de-DE/apps-resources.json
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

**/*.{ts,tsx,js,jsx}: Use early returns whenever possible to make the code more readable.
Use descriptive variable and function/const names.
Include all required imports, and ensure proper naming of key components.

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

Define a type if possible.

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
apps/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/apps.mdc)

apps/**/*.{js,jsx,ts,tsx}: Always use MUI over HTML elements; avoid using CSS or tags.
Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown.
Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
apps/resources/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

apps/resources/src/**/*.{ts,tsx}: Do not introduce new MUI usage even though the lint rule is relaxed; new shadcn work should coexist with core shells/wrappers that are still using MUI until explicit migration tasks retire them
Use Shadcn/ui components as the primary choice for all UI needs; if shadcn/ui doesn't exist, build with Tailwind CSS; use Semantic HTML + Tailwind only for basic elements when neither above applies
Use semantic HTML elements: <header>, <main>, <footer>
Keep handlers prefixed with handle* (e.g., handleClick, handleKeyDown); type everything explicitly; lean on generated GraphQL helpers (ResultOf, VariablesOf)
Compose UI with shadcn/ui primitives or semantic HTML styled via Tailwind; use the shared cn helper for conditional classes
Tailwind utilities should stay semantically grouped—Prettier sorts the lists, but ensure responsive and state variants remain readable
Use descriptive variable and function/const names; event functions should be named with 'handle' prefix, like 'handleClick' for onClick and 'handleKeyDown' for onKeyDown
Implement accessibility features on elements: tags should have tabindex='0', aria-label, on:click, on:keydown, and similar attributes; build accessible experiences as part of every component
Verify that every clickable element has cursor:pointer defined
When calling t(...), inline the human-readable copy with interpolation placeholders (e.g., t('Switch to {{localeName}}', { localeName: localeDetails.nativeName })) instead of referencing stored translation keys
All components and functions must be fully typed with TypeScript
Use alphabetical order for imports and exports
Follow a server-first architecture: use 'use client' components only when necessary
Use semantic HTML forms with proper action/method and graceful fallbacks for interactive features
Apollo hooks should use generated types alongside colocated documents; useVideoChildren is the reference pattern
useWatch dispatches should tar...

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
apps/resources/src/components/**/*.tsx

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

Component naming format: Use UiType prefix (e.g., Modal, Button, Footer, Page) + ComponentFunction (e.g., LanguageSwitch, MainVideo); omit ComponentFunction for basic primitives; use PascalCase for all component names

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
apps/resources/src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

Component props should use optional props with sensible defaults; include className prop for extensibility; use ReactNode for children and content slots; name interfaces with component name prefix (e.g., ComponentNameProps)

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
🧠 Learnings (18)
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/src/**/*.{tsx} : Navigation: design link-based content discovery through components

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Optimize bundles via tree-shaking and code splitting in component design

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/src/**/*.{tsx} : Compose UI with shadcn/ui primitives or semantic HTML styled via Tailwind; do not introduce new MUI usage

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Dialogs/Modals prefixed with 'Dialog', Sections with 'Section', Layout components with 'Layout'

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Use semantic HTML elements (header, main, footer)

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/components/**/*.{ts,tsx} : Component props should use optional props with sensible defaults; include className prop for extensibility; use ReactNode for children and content slots; name interfaces with component name prefix (e.g., ComponentNameProps)

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/components/**/*Video*.{ts,tsx} : Components like `VideoContentHero` depend on the full provider stack (VideoProvider, WatchProvider, PlayerProvider) plus video.js and mux metadata; preserve existing contracts for autoplay, subtitles, and analytics

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-07-27T21:59:10.507Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/watch-modern.mdc:0-0
Timestamp: 2025-07-27T21:59:10.507Z
Learning: Applies to apps/watch-modern/**/*.{tsx,jsx} : Prefer shadcn/ui components over custom implementations or raw HTML elements. If a shadcn/ui component does not exist, use semantic HTML and Tailwind CSS, and document the reason.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Maintain high visual polish using Tailwind (typography, spacing, animations)

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/src/**/index.ts : Export all components via index.ts files in their folders

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Do not introduce new MUI usage even if lint allows; continue migration to shadcn/Tailwind

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Use Shadcn/ui components as the primary choice for all UI needs; if shadcn/ui doesn't exist, build with Tailwind CSS; use Semantic HTML + Tailwind only for basic elements when neither above applies

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-07-27T21:59:04.362Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/apps.mdc:0-0
Timestamp: 2025-07-27T21:59:04.362Z
Learning: Applies to apps/**/*.{js,jsx,ts,tsx} : Always use MUI over HTML elements; avoid using CSS or tags.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Compose UI with shadcn/ui primitives or semantic HTML styled via Tailwind; use the shared `cn` helper for conditional classes

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Do not introduce new MUI usage even though the lint rule is relaxed; new shadcn work should coexist with core shells/wrappers that are still using MUI until explicit migration tasks retire them

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-06-27T04:23:33.639Z
Learnt from: Kneesal
Repo: JesusFilm/core PR: 6806
File: apps/watch/src/components/VideoContentPage/VideoHero/VideoPlayer/VideoTitle/VideoTitle.tsx:21-54
Timestamp: 2025-06-27T04:23:33.639Z
Learning: The watch project (apps/watch) is in the process of being migrated to Tailwind CSS, so suggestions should favor Tailwind CSS over MUI components for HTML elements and styling.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-13T15:13:07.389Z
Learnt from: lumberman
Repo: JesusFilm/core PR: 7657
File: apps/watch/src/components/NewVideoContentPage/VideoCarousel/VideoCarousel.tsx:112-112
Timestamp: 2025-09-13T15:13:07.389Z
Learning: For apps/watch specifically, prefer Tailwind CSS over MUI components. The watch project is migrating away from MUI to Tailwind CSS for styling and components.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Use semantic HTML elements: `<header>`, `<main>`, `<footer>`

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
🧬 Code graph analysis (1)
apps/resources/src/components/BetaBanner/BetaBanner.tsx (1)
apps/resources/src/components/BetaBanner/index.ts (1)
  • BetaBanner (1-1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: Deploy Preview (watch-modern, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (resources, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (journeys-admin, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (watch, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (journeys, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (videos-admin, 8496/merge, pull_request, 22)
  • GitHub Check: test (22, 2/3)
  • GitHub Check: test (22, 1/3)
  • GitHub Check: test (22, 3/3)
  • GitHub Check: build (22)
  • GitHub Check: lint (22)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (9)
libs/locales/es-ES/apps-resources.json (1)

96-100: Spanish translations look accurate and well-formatted.

The four new beta banner translations are idiomatically correct and consistent with the file's existing patterns. The trailing comma added on line 96 properly maintains JSON validity. All entries follow the existing key-naming convention (English phrase as key) and the Spanish translations appropriately reflect the English source text.

To ensure consistency across all locale files, please verify that these same four keys have been added to other language translation files (e.g., en, fr, de, pt, etc.) with equivalent translations.

libs/locales/fr-FR/apps-resources.json (1)

96-100: JSON syntax is correct; French translations are appropriate.

The trailing comma on line 96 is correct, and the four new translation entries use idiomatic French with proper grammar. No syntax issues detected.

libs/locales/pt-BR/apps-resources.json (2)

96-96: Clarify the modification to line 96.

The AI summary states "No existing translations were modified," but line 96 is marked as changed. Please confirm whether this represents a substantive change or only formatting adjustment.


97-100: Add the missing beta banner translations to the remaining 17 locale files.

The new translations in lines 97–100 for the pt-BR locale are properly formatted, but verification reveals that only 7 of 24 locale files have been updated with these keys (en, de-DE, es-ES, fr-FR, ar-SA, pt-BR, zh-Hans-CN). The following locales are missing these translation keys and need to be updated:

am-ET, bn-BD, hi-IN, id-ID, ja-JP, ko-KR, ms-MY, my-MM, ne-NP, ru-RU, th-TH, tl-PH, tr-TR, ur-PK, vi-VN, zh-Hant-TW

Either add the missing translations to all remaining locales or remove these keys from the partially-updated files to maintain consistency across the localization namespace.

⛔ Skipped due to learnings
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7659
File: libs/locales/pt-BR/apps-journeys-admin.json:512-526
Timestamp: 2025-09-16T00:30:59.827Z
Learning: The team uses Crowdin with DeepL and Google Translate for translations. Do not recommend translation corrections or improvements for locale files as they have an established translation workflow.
libs/locales/zh-Hans-CN/apps-resources.json (1)

95-99: LGTM!

Translation keys are consistent with the English source and other locale files. The Simplified Chinese translations appear appropriate.

libs/locales/ar-SA/apps-resources.json (1)

100-104: LGTM!

Arabic translations are properly added and consistent with the other locale files in this PR.

libs/locales/en/apps-resources.json (1)

99-102: LGTM!

The flat translation keys are correctly added and match the keys used in the BetaBanner component.

apps/resources/src/components/BetaBanner/BetaBanner.tsx (2)

175-183: LGTM!

Translation calls correctly use inline human-readable copy as per coding guidelines. The responsive text switching between mobile and desktop variants is well implemented.


126-131: LGTM!

Keyboard handler follows the handle* naming convention and correctly handles both Enter and Space keys for accessibility compliance.

- Remove the nested betaBanner object that was inconsistent with other locale files
- Confirmed no references to betaBanner.message or betaBanner.cta exist in codebase
- English locale now matches the flat translation key structure used elsewhere
- Refactored BetaBanner to improve accessibility and styling, replacing the button with a more semantic structure.
- Adjusted particle animation logic and reduced particle count for performance.
- Updated localization files to include new translation keys for the banner in multiple languages.
- Removed redundant tech stack details from AGENTS.md and streamlined workspace setup instructions.
@github-actions github-actions bot temporarily deployed to Preview - resources December 11, 2025 16:56 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin December 11, 2025 16:56 Inactive
@github-actions github-actions bot temporarily deployed to Preview - watch-modern December 11, 2025 16:56 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys December 11, 2025 16:56 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin December 11, 2025 16:56 Inactive
Copy link
Copy Markdown
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: 10

♻️ Duplicate comments (5)
libs/locales/ru-RU/apps-resources.json (1)

99-102: Incomplete localization: English strings in Russian locale.

The Beta banner strings are untranslated in the Russian (ru-RU) locale file. Russian users will see English text.

This is the same localization issue as noted in id-ID/apps-resources.json. Please provide Russian translations for these four keys or track as follow-up work.

libs/locales/ja-JP/apps-resources.json (1)

96-99: Incomplete localization: English strings in Japanese locale.

Japanese (ja-JP) locale has untranslated Beta banner strings. Please provide Japanese translations or track as follow-up work.

libs/locales/ur-PK/apps-resources.json (1)

65-68: Incomplete localization: English strings in Urdu locale.

Urdu (ur-PK) locale has untranslated Beta banner strings. Please provide Urdu translations or track as follow-up work.

libs/locales/th-TH/apps-resources.json (1)

96-99: Incomplete localization: English strings in Thai locale.

Thai (th-TH) locale has untranslated Beta banner strings. Please provide Thai translations or track as follow-up work.

apps/resources/src/components/BetaBanner/BetaBanner.tsx (1)

1-8: Refactor away from new MUI usage in apps/resources/src toward shadcn/Tailwind

This component introduces new MUI primitives (Box, Container, Typography) and relies on sx styling, but apps/resources/src/**/* guidelines explicitly call for shadcn/ui or semantic HTML + Tailwind, and to avoid introducing new MUI usage in this area.

Consider:

  • Replacing the layout primitives with semantic elements (e.g., <section>, <div>, <button>) styled via Tailwind (using the shared cn helper).
  • Using existing shadcn/ui primitives (e.g., Button, layout components) for the CTA and text instead of MUI components.
  • Handling mobile vs desktop text via Tailwind responsive utilities (hidden md:inline, etc.) instead of MUI’s theme + useMediaQuery.

Example sketch for the CTA button (not exhaustive):

-import Box from '@mui/material/Box'
-import Container from '@mui/material/Container'
-import Typography from '@mui/material/Typography'
+import { cn } from '@/apps/resources/src/lib/cn'
+import { Button } from '@/apps/resources/src/components/ui/button'
...
-    <Box
-      role="banner"
-      component="section"
-      sx={{ /* MUI styling */ }}
-    >
+    <section
+      role="banner"
+      className={cn('w-full bg-primary text-primary-foreground relative overflow-hidden')}
+    >
...
-      <Container
-        sx={{ py: 1.5, display: 'flex', alignItems: 'center', justifyContent: 'center', textAlign: 'center' }}
-      >
+      <div className="py-1.5 flex items-center justify-center text-center">
...
-        <Box
-          component="button"
-          ...
-        >
-          <Typography variant="h6">
+        <Button variant="ghost" className="w-full justify-center focus-visible:outline-white">
+          <span className="text-base md:text-lg font-semibold">
             ...
-          </Typography>
-        </Box>
-      </Container>
-    </Box>
+          </span>
+        </Button>
+      </div>
+    </section>

As per coding guidelines for apps/resources/src/**/*, new UI work here should be shadcn/Tailwind-based, not MUI-based.

Also applies to: 142-211

🧹 Nitpick comments (2)
apps/resources/src/components/BetaBanner/BetaBanner.test.tsx (1)

114-127: Keyboard interaction testing is incomplete.

The accessibility test verifies the button is focusable but doesn't test actual keyboard activation with Enter or Space keys. The comment on line 126 mentions this limitation due to window.location.reload not being implemented in JSDOM.

Consider mocking window.location.reload to test keyboard activation:

   describe('Accessibility', () => {
+    beforeEach(() => {
+      delete window.location
+      window.location = { reload: jest.fn() } as any
+    })
+
     it('should have proper ARIA label', () => {
       mockRouter.setCurrentUrl('/watch/some-video')
       mockRouter.isReady = true

       render(<BetaBanner />)

       const button = screen.getByRole('button')
       expect(button).toHaveAttribute('aria-label', 'Try the new design.')
     })

-    it('should be keyboard accessible with Enter key', () => {
+    it('should activate on Enter key', () => {
       mockRouter.setCurrentUrl('/watch/some-video')
       mockRouter.isReady = true

       render(<BetaBanner />)

       const button = screen.getByRole('button')
-      button.focus()
+      fireEvent.keyDown(button, { key: 'Enter' })

-      expect(button).toHaveFocus()
+      expect(document.cookie).toContain('EXPERIMENTAL=true')
+      expect(window.location.reload).toHaveBeenCalled()
+    })

-      // Note: Testing keyDown would trigger window.location.reload which is not implemented in JSDOM
-      // So we just test that the button is focusable
+    it('should activate on Space key', () => {
+      mockRouter.setCurrentUrl('/watch/some-video')
+      mockRouter.isReady = true
+
+      render(<BetaBanner />)
+
+      const button = screen.getByRole('button')
+      fireEvent.keyDown(button, { key: ' ' })
+
+      expect(document.cookie).toContain('EXPERIMENTAL=true')
+      expect(window.location.reload).toHaveBeenCalled()
     })
   })

This would provide complete accessibility coverage for keyboard users.

apps/resources/src/components/BetaBanner/BetaBanner.tsx (1)

37-52: Normalize particle coordinates with devicePixelRatio scaling

resizeCanvas multiplies canvas.width/canvas.height by window.devicePixelRatio and calls ctx.scale(window.devicePixelRatio, window.devicePixelRatio), but particle positions and bounds are computed directly against canvas.width/canvas.height. This effectively uses physical pixels for coordinates on a context that’s already scaled, so many particles will be off-screen and edge wrapping runs in device-space, not CSS-space.

To keep things predictable and easier to tune, consider:

  • Working in CSS pixels (rect width/height) for all particle math.
  • Using ctx.setTransform instead of mixing raw canvas.width with an extra scale.

For example:

-    const resizeCanvas = () => {
-      const rect = canvas.getBoundingClientRect()
-      canvas.width = rect.width * window.devicePixelRatio
-      canvas.height = rect.height * window.devicePixelRatio
-      ctx.scale(window.devicePixelRatio, window.devicePixelRatio)
-    }
+    const resizeCanvas = () => {
+      const rect = canvas.getBoundingClientRect()
+      const dpr = window.devicePixelRatio || 1
+      canvas.width = rect.width * dpr
+      canvas.height = rect.height * dpr
+      ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
+    }
...
-    const createParticle = (): Particle => ({
-      x: Math.random() * canvas.width,
-      y: Math.random() * canvas.height,
+    const createParticle = (): Particle => {
+      const rect = canvas.getBoundingClientRect()
+      return {
+        x: Math.random() * rect.width,
+        y: Math.random() * rect.height,
         ...
-      life: Math.random() * 200 + 100 // Longer life for slower movement
-    })
+      }
+    }
...
-      ctx.clearRect(0, 0, canvas.width, canvas.height)
+      const rect = canvas.getBoundingClientRect()
+      ctx.clearRect(0, 0, rect.width, rect.height)
...
-        if (particle.x < -10) particle.x = canvas.width + 10
-        if (particle.x > canvas.width + 10) particle.x = -10
-        if (particle.y < -10) particle.y = canvas.height + 10
-        if (particle.y > canvas.height + 10) particle.y = -10
+        const rect = canvas.getBoundingClientRect()
+        if (particle.x < -10) particle.x = rect.width + 10
+        if (particle.x > rect.width + 10) particle.x = -10
+        if (particle.y < -10) particle.y = rect.height + 10
+        if (particle.y > rect.height + 10) particle.y = -10

This keeps the animation tuned to CSS pixels and avoids double-scaling artifacts.

Also applies to: 61-76, 85-96

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4a85b80 and 9c89f6c.

📒 Files selected for processing (21)
  • apps/resources/AGENTS.md (5 hunks)
  • apps/resources/pages/_app.tsx (2 hunks)
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx (1 hunks)
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx (1 hunks)
  • libs/locales/am-ET/apps-resources.json (1 hunks)
  • libs/locales/bn-BD/apps-resources.json (1 hunks)
  • libs/locales/en/apps-resources.json (1 hunks)
  • libs/locales/hi-IN/apps-resources.json (1 hunks)
  • libs/locales/id-ID/apps-resources.json (1 hunks)
  • libs/locales/ja-JP/apps-resources.json (1 hunks)
  • libs/locales/ko-KR/apps-resources.json (1 hunks)
  • libs/locales/ms-MY/apps-resources.json (1 hunks)
  • libs/locales/my-MM/apps-resources.json (1 hunks)
  • libs/locales/ne-NP/apps-resources.json (1 hunks)
  • libs/locales/ru-RU/apps-resources.json (1 hunks)
  • libs/locales/th-TH/apps-resources.json (1 hunks)
  • libs/locales/tl-PH/apps-resources.json (1 hunks)
  • libs/locales/tr-TR/apps-resources.json (1 hunks)
  • libs/locales/ur-PK/apps-resources.json (1 hunks)
  • libs/locales/vi-VN/apps-resources.json (1 hunks)
  • libs/locales/zh-Hant-TW/apps-resources.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • libs/locales/ko-KR/apps-resources.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • libs/locales/en/apps-resources.json
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

**/*.{ts,tsx,js,jsx}: Use early returns whenever possible to make the code more readable.
Use descriptive variable and function/const names.
Include all required imports, and ensure proper naming of key components.

Files:

  • apps/resources/pages/_app.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

Define a type if possible.

Files:

  • apps/resources/pages/_app.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
apps/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/apps.mdc)

apps/**/*.{js,jsx,ts,tsx}: Always use MUI over HTML elements; avoid using CSS or tags.
Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown.
Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.

Files:

  • apps/resources/pages/_app.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
apps/resources/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

apps/resources/src/**/*.{ts,tsx}: Do not introduce new MUI usage even though the lint rule is relaxed; new shadcn work should coexist with core shells/wrappers that are still using MUI until explicit migration tasks retire them
Use Shadcn/ui components as the primary choice for all UI needs; if shadcn/ui doesn't exist, build with Tailwind CSS; use Semantic HTML + Tailwind only for basic elements when neither above applies
Use semantic HTML elements: <header>, <main>, <footer>
Keep handlers prefixed with handle* (e.g., handleClick, handleKeyDown); type everything explicitly; lean on generated GraphQL helpers (ResultOf, VariablesOf)
Compose UI with shadcn/ui primitives or semantic HTML styled via Tailwind; use the shared cn helper for conditional classes
Tailwind utilities should stay semantically grouped—Prettier sorts the lists, but ensure responsive and state variants remain readable
Use descriptive variable and function/const names; event functions should be named with 'handle' prefix, like 'handleClick' for onClick and 'handleKeyDown' for onKeyDown
Implement accessibility features on elements: tags should have tabindex='0', aria-label, on:click, on:keydown, and similar attributes; build accessible experiences as part of every component
Verify that every clickable element has cursor:pointer defined
When calling t(...), inline the human-readable copy with interpolation placeholders (e.g., t('Switch to {{localeName}}', { localeName: localeDetails.nativeName })) instead of referencing stored translation keys
All components and functions must be fully typed with TypeScript
Use alphabetical order for imports and exports
Follow a server-first architecture: use 'use client' components only when necessary
Use semantic HTML forms with proper action/method and graceful fallbacks for interactive features
Apollo hooks should use generated types alongside colocated documents; useVideoChildren is the reference pattern
useWatch dispatches should tar...

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
apps/resources/src/components/**/*.tsx

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

Component naming format: Use UiType prefix (e.g., Modal, Button, Footer, Page) + ComponentFunction (e.g., LanguageSwitch, MainVideo); omit ComponentFunction for basic primitives; use PascalCase for all component names

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
apps/resources/src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

Component props should use optional props with sensible defaults; include className prop for extensibility; use ReactNode for children and content slots; name interfaces with component name prefix (e.g., ComponentNameProps)

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
apps/**/*.test.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/apps.mdc)

Use '@testing-library/react' npm package for frontend tests.

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
🧠 Learnings (52)
📓 Common learnings
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Optimize bundles via tree-shaking and code splitting in component design
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/src/**/*.{tsx} : Navigation: design link-based content discovery through components
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/components/**/*Video*.{ts,tsx} : Components like `VideoContentHero` depend on the full provider stack (VideoProvider, WatchProvider, PlayerProvider) plus video.js and mux metadata; preserve existing contracts for autoplay, subtitles, and analytics

Applied to files:

  • apps/resources/pages/_app.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Use semantic HTML elements: `<header>`, `<main>`, `<footer>`

Applied to files:

  • apps/resources/pages/_app.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/index.ts : Export all components through index.ts files

Applied to files:

  • apps/resources/pages/_app.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Compose UI with shadcn/ui primitives or semantic HTML styled via Tailwind; use the shared `cn` helper for conditional classes

Applied to files:

  • apps/resources/pages/_app.tsx
  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/libs/ui/**/*.{ts,tsx} : Add shadcn components to the root of the repo in /core/libs/ui/ (monorepo structure), not in the app directory

Applied to files:

  • apps/resources/pages/_app.tsx
  • apps/resources/AGENTS.md
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/src/**/*.{tsx} : Compose UI with shadcn/ui primitives or semantic HTML styled via Tailwind; do not introduce new MUI usage

Applied to files:

  • apps/resources/pages/_app.tsx
  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Dialogs/Modals prefixed with 'Dialog', Sections with 'Section', Layout components with 'Layout'

Applied to files:

  • apps/resources/pages/_app.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Optimize bundles via tree-shaking and code splitting in component design

Applied to files:

  • apps/resources/pages/_app.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Use semantic HTML elements (header, main, footer)

Applied to files:

  • apps/resources/pages/_app.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/pages/**/*.{ts,tsx} : Prefer SSR (`getServerSideProps`) or SSG (`getStaticProps`) for content and SEO where appropriate; use `<Link>` for navigation instead of custom click handlers; ensure core flows work without client JS where feasible

Applied to files:

  • apps/resources/pages/_app.tsx
  • apps/resources/AGENTS.md
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/**/AGENTS : Whenever uncovering faster workflows or new standards, update the `AGENTS` file with short, precise entries; after completing tasks requiring more than three iterations, document key learnings targeting Senior Developer audience

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Use Shadcn/ui components as the primary choice for all UI needs; if shadcn/ui doesn't exist, build with Tailwind CSS; use Semantic HTML + Tailwind only for basic elements when neither above applies

Applied to files:

  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-07-27T21:59:10.507Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/watch-modern.mdc:0-0
Timestamp: 2025-07-27T21:59:10.507Z
Learning: Applies to apps/watch-modern/**/*.{tsx,jsx} : Prefer shadcn/ui components over custom implementations or raw HTML elements. If a shadcn/ui component does not exist, use semantic HTML and Tailwind CSS, and document the reason.

Applied to files:

  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Maintain high visual polish using Tailwind (typography, spacing, animations)

Applied to files:

  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/apps/resources-e2e/**/*.{ts,tsx} : Extend Playwright scenarios when UI behavior shifts, and capture console logs/screenshots for regressions; document executed test suite, notable scenarios, and any skipped checks in `/prds/resources/`

Applied to files:

  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Do not introduce new MUI usage even though the lint rule is relaxed; new shadcn work should coexist with core shells/wrappers that are still using MUI until explicit migration tasks retire them

Applied to files:

  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Do not introduce new MUI usage even if lint allows; continue migration to shadcn/Tailwind

Applied to files:

  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/src/**/*.{tsx} : Navigation: design link-based content discovery through components

Applied to files:

  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.spec.{ts,tsx} : Reuse the shared Jest setup in `apps/resources/setupTests.tsx`; it already boots MSW, the Next router mock, and longer async timeout; wrap component specs with `MockedProvider`, `VideoProvider`, and `WatchProvider` when touching those contexts

Applied to files:

  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : UI flows are expected to sit inside `VideoProvider`, `WatchProvider`, and `PlayerProvider` contexts; mirror that wiring when composing features and when writing tests

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/setupTests.tsx : Reuse shared Jest setup that boots MSW, Next router mock, and longer timeouts

Applied to files:

  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Keep handlers prefixed with `handle*` (e.g., handleClick, handleKeyDown); type everything explicitly; lean on generated GraphQL helpers (`ResultOf`, `VariablesOf`)

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/core/libs/ui/**/*.{ts,tsx} : Add new shadcn components only under /core/libs/ui/ at repo root

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Use shared cn helper for conditional Tailwind classes; keep utilities semantically grouped and readable

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Run quality gate checks before opening a PR: format check with `pnpm run prettier`, resources lint with `pnpm dlx nx run resources:lint`, resources type-check with `pnpm dlx nx run resources:type-check`, resources unit tests with `pnpm dlx nx run resources:test`

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Run Prettier, lint, type-check, unit and e2e before PR; ensure no new violations introduced

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: After editing GraphQL documents, run `pnpm dlx nx run resources:codegen` to regenerate `apps/resources/__generated__` artifacts

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Tailwind utilities should stay semantically grouped—Prettier sorts the lists, but ensure responsive and state variants remain readable

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Install dependencies with pnpm (required package manager); install Playwright browsers with `pnpm exec playwright install --with-deps` (local-only; do not commit artifacts)

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-07-22T18:37:24.555Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/base.mdc:0-0
Timestamp: 2025-07-22T18:37:24.555Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Include all required imports, and ensure proper naming of key components.

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-07-15T03:19:53.274Z
Learnt from: Kneesal
Repo: JesusFilm/core PR: 7171
File: apps/watch/src/components/LanguageSwitchDialog/SubtitlesSelect/SubtitlesSelect.spec.tsx:125-125
Timestamp: 2025-07-15T03:19:53.274Z
Learning: The team has a specific approach for testing icons that differs from using data-testid or role/aria-label attributes. Need to learn their established pattern for icon testing in test files.

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-07-27T21:59:04.362Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/apps.mdc:0-0
Timestamp: 2025-07-27T21:59:04.362Z
Learning: Applies to apps/**/*.{js,jsx,ts,tsx} : Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-07-27T21:59:10.507Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/watch-modern.mdc:0-0
Timestamp: 2025-07-27T21:59:10.507Z
Learning: Applies to apps/watch-modern/**/*.{tsx,jsx} : Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Implement accessibility (ARIA, keyboard, focus states); ensure interactive elements have tabindex/aria/onClick/onKeyDown as needed

Applied to files:

  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Implement accessibility features on elements: tags should have tabindex='0', aria-label, on:click, on:keydown, and similar attributes; build accessible experiences as part of every component

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.spec.{ts,tsx} : Always propose and implement unit or integration tests covering edge cases and failure paths; co-locate React Testing Library specs under `*.spec.ts(x)`; mock network traffic with MSW handlers

Applied to files:

  • apps/resources/AGENTS.md
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Ensure every clickable element shows cursor:pointer

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/components/**/*.{ts,tsx} : Component props should use optional props with sensible defaults; include className prop for extensibility; use ReactNode for children and content slots; name interfaces with component name prefix (e.g., ComponentNameProps)

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-07-27T21:59:04.362Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/apps.mdc:0-0
Timestamp: 2025-07-27T21:59:04.362Z
Learning: Applies to apps/**/*.{js,jsx,ts,tsx} : Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown.

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Use descriptive variable and function/const names; event functions should be named with 'handle' prefix, like 'handleClick' for onClick and 'handleKeyDown' for onKeyDown

Applied to files:

  • apps/resources/AGENTS.md
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/src/**/index.ts : Export all components via index.ts files in their folders

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-07-27T21:59:04.362Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/apps.mdc:0-0
Timestamp: 2025-07-27T21:59:04.362Z
Learning: Applies to apps/**/*.{js,jsx,ts,tsx} : Always use MUI over HTML elements; avoid using CSS or tags.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-06-27T04:23:33.639Z
Learnt from: Kneesal
Repo: JesusFilm/core PR: 6806
File: apps/watch/src/components/VideoContentPage/VideoHero/VideoPlayer/VideoTitle/VideoTitle.tsx:21-54
Timestamp: 2025-06-27T04:23:33.639Z
Learning: The watch project (apps/watch) is in the process of being migrated to Tailwind CSS, so suggestions should favor Tailwind CSS over MUI components for HTML elements and styling.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-13T15:13:07.389Z
Learnt from: lumberman
Repo: JesusFilm/core PR: 7657
File: apps/watch/src/components/NewVideoContentPage/VideoCarousel/VideoCarousel.tsx:112-112
Timestamp: 2025-09-13T15:13:07.389Z
Learning: For apps/watch specifically, prefer Tailwind CSS over MUI components. The watch project is migrating away from MUI to Tailwind CSS for styling and components.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.spec.{ts,tsx} : Enclose SWR-based hooks in `TestSWRConfig` to isolate cache state between assertions

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{spec.ts,spec.tsx} : Co-locate React Testing Library specs under *.spec.ts(x)

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/test/TestSWRConfig.tsx : Enclose SWR-based hooks in TestSWRConfig to isolate cache between assertions

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-07-27T21:59:10.507Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/watch-modern.mdc:0-0
Timestamp: 2025-07-27T21:59:10.507Z
Learning: Applies to apps/watch-modern/**/*.test.{tsx,jsx} : Use 'testing-library/react' npm package for frontend tests.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-11-16T21:30:53.412Z
Learnt from: Kneesal
Repo: JesusFilm/core PR: 8309
File: apps/journeys-admin/setupTests.tsx:47-51
Timestamp: 2025-11-16T21:30:53.412Z
Learning: In apps/journeys-admin/setupTests.tsx, the `document.clearImmediate` mock is required for tests involving the mux upload provider, as an underlying library uses clearImmediate for timeout management to prevent race conditions and unnecessary polling calls.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{spec.ts,spec.tsx} : Wrap component specs with MockedProvider, VideoProvider, and WatchProvider when touching those contexts

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-07-27T21:59:04.362Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/apps.mdc:0-0
Timestamp: 2025-07-27T21:59:04.362Z
Learning: Applies to apps/**/*.test.{js,jsx,ts,tsx} : Use 'testing-library/react' npm package for frontend tests.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
🧬 Code graph analysis (2)
apps/resources/pages/_app.tsx (2)
apps/resources/src/components/BetaBanner/BetaBanner.tsx (1)
  • BetaBanner (20-213)
apps/resources/src/components/BetaBanner/index.ts (1)
  • BetaBanner (1-1)
apps/resources/src/components/BetaBanner/BetaBanner.test.tsx (1)
apps/resources/src/components/BetaBanner/BetaBanner.tsx (1)
  • BetaBanner (20-213)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: test (22, 2/3)
  • GitHub Check: build (22)
  • GitHub Check: test (22, 1/3)
  • GitHub Check: test (22, 3/3)
  • GitHub Check: lint (22)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (8)
libs/locales/tr-TR/apps-resources.json (1)

97-100: Translation keys missing across multiple locales, including Turkish.

Lines 97–100 contain four new BetaBanner keys that lack proper translations in many locale files. The Turkish file (tr-TR) and at least 15 other locales (zh-Hant-TW, vi-VN, ur-PK, tl-PH, th-TH, ru-RU, ne-NP, my-MM, ms-MY, ko-KR, ja-JP, id-ID, hi-IN, bn-BD, am-ET) fall back to English text instead of providing native language translations. This breaks the user experience for speakers of these languages.

Only a few locales (pt-BR, fr-FR, de-DE, es-ES, ar-SA, zh-Hans-CN) have proper translations for these keys. The remaining locales must be updated with appropriate translations:

  • "Better search. Better language support. Better collections."
  • "Better search, languages, and collections."
  • "Try the new design."
  • "New Design"
⛔ Skipped due to learnings
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7659
File: libs/locales/pt-BR/apps-journeys-admin.json:512-526
Timestamp: 2025-09-16T00:30:59.827Z
Learning: The team uses Crowdin with DeepL and Google Translate for translations. Do not recommend translation corrections or improvements for locale files as they have an established translation workflow.
libs/locales/hi-IN/apps-resources.json (2)

65-68: Clarify the purpose of duplicated strings.

Two pairs of similar strings appear in the additions:

  • "Better search. Better language support. Better collections." (line 65) vs. "Better search, languages, and collections." (line 66)
  • "Try the new design." (line 67) vs. "New Design" (line 68)

It's unclear why both variants exist. Are they for different UI placements (e.g., one for heading, one for subtext), or is one redundant? Please clarify the usage context.


65-68: > Likely an incorrect or invalid review comment.

apps/resources/pages/_app.tsx (1)

21-21: LGTM: BetaBanner integration follows best practices.

The BetaBanner import and placement are appropriate:

  • Positioned after ThemeProvider (for theme access) and before InstantSearchProvider (unrelated feature)
  • Component self-gates to render only on /watch routes, returning null elsewhere
  • No props required per the component's public signature

Minor note: The component mounts on every page load but the conditional logic (pathname check + early return) is lightweight and follows a common React pattern for route-specific UI.

Also applies to: 162-162

apps/resources/src/components/BetaBanner/BetaBanner.test.tsx (1)

33-191: LGTM: Comprehensive test coverage for BetaBanner.

The test suite covers all critical functionality:

  • ✓ Route-based rendering conditions (watch vs non-watch routes)
  • ✓ Router readiness gating
  • ✓ Cookie setting logic with correct attributes
  • ✓ ARIA labeling for accessibility
  • ✓ Banner structure and canvas presence
  • ✓ Integration flow from render to activation

The mock setup (document.cookie, canvas context, requestAnimationFrame) follows established testing patterns. As per coding guidelines and learnings, the tests properly use @testing-library/react and cover edge cases effectively.

apps/resources/AGENTS.md (1)

221-221: LGTM: Improved translation key guidance.

The updated guidance to use direct English strings in t() calls (e.g., t('Welcome back')) instead of translation keys (e.g., t('welcomeBack')) aligns with modern i18n best practices and improves code readability.

This approach makes the code self-documenting and reduces the cognitive overhead of looking up translation keys.

apps/resources/src/components/BetaBanner/BetaBanner.tsx (1)

28-31: Route gating and animation cleanup look correct

The isWatchRoute check plus the early return null and useEffect guard ensure:

  • The banner only renders and the animation only runs on /watch routes.
  • The resize listener and animation frame are properly cleaned up on route change/unmount via the effect cleanup.

This matches the PR intent and avoids leaking the animation into non-watch pages.

Also applies to: 98-121, 123-123

libs/locales/zh-Hant-TW/apps-resources.json (1)

96-99: Add Traditional Chinese translations for BetaBanner strings.

Lines 96–99 contain untranslated English values. Users viewing the app in Traditional Chinese will see English text instead of localized content. These four entries require translations:

  "Better search. Better language support. Better collections.": "[Chinese translation needed]",
  "Better search, languages, and collections.": "[Chinese translation needed]",
  "Try the new design.": "[Chinese translation needed]",
  "New Design": "[Chinese translation needed]"

Note: The same untranslated strings appear in other locale files including ja-JP, bn-BD, ko-KR, and others, suggesting a broader localization gap that may require coordinated translation efforts across multiple languages.

⛔ Skipped due to learnings
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7659
File: libs/locales/pt-BR/apps-journeys-admin.json:512-526
Timestamp: 2025-09-16T00:30:59.827Z
Learning: The team uses Crowdin with DeepL and Google Translate for translations. Do not recommend translation corrections or improvements for locale files as they have an established translation workflow.

@blacksmith-sh

This comment has been minimized.

@lumberman lumberman changed the title Add beta banner CTA for watch pages feat(resources): add beta banner CTA for watch pages Dec 11, 2025
- Translate bn-BD banner entries to Bengali
- Add banner translations for am-ET, hi-IN, id-ID, ja-JP, ko-KR, ms-MY, my-MM, ne-NP, ru-RU, th-TH, tl-PH, tr-TR, ur-PK, vi-VN, zh-Hant-TW
- All JSON files validated for syntax correctness
- Updated BetaBanner component to check for router readiness before rendering.
- Improved HTMLCanvasElement mock to return null for unsupported context IDs.
- Added mock for next/compat/router to ensure compatibility with testing environment.
@github-actions github-actions bot temporarily deployed to Preview - journeys December 11, 2025 23:45 Inactive
@github-actions github-actions bot temporarily deployed to Preview - watch-modern December 11, 2025 23:45 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin December 11, 2025 23:45 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin December 11, 2025 23:45 Inactive
@github-actions github-actions bot temporarily deployed to Preview - resources December 11, 2025 23:45 Inactive
Copy link
Copy Markdown
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: 0

🧹 Nitpick comments (4)
apps/resources/src/components/BetaBanner/BetaBanner.test.tsx (2)

119-132: Consider adding keyboard event verification.

The test documents that window.location.reload isn't available in JSDOM, but you could still verify that the cookie is set when pressing Enter or Space without relying on the reload. This would provide stronger coverage of handleKeyDown.

     it('should be keyboard accessible with Enter key', () => {
       mockRouter.setCurrentUrl('/watch/some-video')
       mockRouter.isReady = true

       render(<BetaBanner />)

       const button = screen.getByRole('button')
       button.focus()

       expect(button).toHaveFocus()

-      // Note: Testing keyDown would trigger window.location.reload which is not implemented in JSDOM
-      // So we just test that the button is focusable
+      // Mock reload to prevent JSDOM error
+      const reloadMock = jest.fn()
+      Object.defineProperty(window, 'location', {
+        value: { ...window.location, reload: reloadMock, protocol: 'https:' },
+        writable: true
+      })
+
+      fireEvent.keyDown(button, { key: 'Enter' })
+
+      expect(document.cookie).toContain('EXPERIMENTAL=true')
+      expect(reloadMock).toHaveBeenCalled()
     })

38-42: Consider resetting window.location.reload mock in beforeEach.

If you add keyboard event tests that mock window.location.reload, ensure the mock is reset in beforeEach to maintain test isolation.

apps/resources/src/components/BetaBanner/BetaBanner.tsx (2)

37-42: Canvas coordinate system may cause visual inconsistency after resize.

After resizeCanvas, canvas.width and canvas.height are scaled by devicePixelRatio, but createParticle (lines 44-52) spawns particles using these scaled dimensions. However, getBoundingClientRect() returns CSS pixels. This means on HiDPI displays, particles may appear to spawn and move in a smaller visual area than intended.

Consider storing the logical (CSS) dimensions separately:

+    let logicalWidth = 0
+    let logicalHeight = 0
+
     const resizeCanvas = () => {
       const rect = canvas.getBoundingClientRect()
+      logicalWidth = rect.width
+      logicalHeight = rect.height
       canvas.width = rect.width * window.devicePixelRatio
       canvas.height = rect.height * window.devicePixelRatio
       ctx.scale(window.devicePixelRatio, window.devicePixelRatio)
     }

     const createParticle = (): Particle => ({
-      x: Math.random() * canvas.width,
-      y: Math.random() * canvas.height,
+      x: Math.random() * logicalWidth,
+      y: Math.random() * logicalHeight,
       // ... rest unchanged
     })

And similarly update edge-wrapping bounds in updateParticles to use logicalWidth/logicalHeight.


84-96: clearRect uses scaled dimensions while drawing uses logical coordinates.

After ctx.scale(devicePixelRatio, devicePixelRatio), all drawing operations are automatically scaled. However, clearRect(0, 0, canvas.width, canvas.height) uses the raw canvas dimensions (scaled), which is larger than needed after the context scale transform. This works but is inefficient.

Consider clearing using logical dimensions:

     const drawParticles = () => {
-      ctx.clearRect(0, 0, canvas.width, canvas.height)
+      ctx.clearRect(0, 0, logicalWidth, logicalHeight)

This pairs with the coordinate fix suggested above.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9c89f6c and 906946e.

📒 Files selected for processing (19)
  • apps/resources/setupTests.tsx (1 hunks)
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx (1 hunks)
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx (1 hunks)
  • libs/locales/am-ET/apps-resources.json (1 hunks)
  • libs/locales/bn-BD/apps-resources.json (1 hunks)
  • libs/locales/hi-IN/apps-resources.json (1 hunks)
  • libs/locales/id-ID/apps-resources.json (1 hunks)
  • libs/locales/ja-JP/apps-resources.json (1 hunks)
  • libs/locales/ko-KR/apps-resources.json (1 hunks)
  • libs/locales/ms-MY/apps-resources.json (1 hunks)
  • libs/locales/my-MM/apps-resources.json (1 hunks)
  • libs/locales/ne-NP/apps-resources.json (1 hunks)
  • libs/locales/ru-RU/apps-resources.json (1 hunks)
  • libs/locales/th-TH/apps-resources.json (1 hunks)
  • libs/locales/tl-PH/apps-resources.json (1 hunks)
  • libs/locales/tr-TR/apps-resources.json (1 hunks)
  • libs/locales/ur-PK/apps-resources.json (1 hunks)
  • libs/locales/vi-VN/apps-resources.json (1 hunks)
  • libs/locales/zh-Hant-TW/apps-resources.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (11)
  • libs/locales/tr-TR/apps-resources.json
  • libs/locales/hi-IN/apps-resources.json
  • libs/locales/ja-JP/apps-resources.json
  • libs/locales/bn-BD/apps-resources.json
  • libs/locales/zh-Hant-TW/apps-resources.json
  • libs/locales/ne-NP/apps-resources.json
  • libs/locales/my-MM/apps-resources.json
  • libs/locales/th-TH/apps-resources.json
  • libs/locales/tl-PH/apps-resources.json
  • libs/locales/ur-PK/apps-resources.json
  • libs/locales/am-ET/apps-resources.json
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

**/*.{ts,tsx,js,jsx}: Use early returns whenever possible to make the code more readable.
Use descriptive variable and function/const names.
Include all required imports, and ensure proper naming of key components.

Files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

Define a type if possible.

Files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
apps/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/apps.mdc)

apps/**/*.{js,jsx,ts,tsx}: Always use MUI over HTML elements; avoid using CSS or tags.
Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown.
Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.

Files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
apps/resources/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

apps/resources/src/**/*.{ts,tsx}: Do not introduce new MUI usage even though the lint rule is relaxed; new shadcn work should coexist with core shells/wrappers that are still using MUI until explicit migration tasks retire them
Use Shadcn/ui components as the primary choice for all UI needs; if shadcn/ui doesn't exist, build with Tailwind CSS; use Semantic HTML + Tailwind only for basic elements when neither above applies
Use semantic HTML elements: <header>, <main>, <footer>
Keep handlers prefixed with handle* (e.g., handleClick, handleKeyDown); type everything explicitly; lean on generated GraphQL helpers (ResultOf, VariablesOf)
Compose UI with shadcn/ui primitives or semantic HTML styled via Tailwind; use the shared cn helper for conditional classes
Tailwind utilities should stay semantically grouped—Prettier sorts the lists, but ensure responsive and state variants remain readable
Use descriptive variable and function/const names; event functions should be named with 'handle' prefix, like 'handleClick' for onClick and 'handleKeyDown' for onKeyDown
Implement accessibility features on elements: tags should have tabindex='0', aria-label, on:click, on:keydown, and similar attributes; build accessible experiences as part of every component
Verify that every clickable element has cursor:pointer defined
When calling t(...), inline the human-readable copy with interpolation placeholders (e.g., t('Switch to {{localeName}}', { localeName: localeDetails.nativeName })) instead of referencing stored translation keys
All components and functions must be fully typed with TypeScript
Use alphabetical order for imports and exports
Follow a server-first architecture: use 'use client' components only when necessary
Use semantic HTML forms with proper action/method and graceful fallbacks for interactive features
Apollo hooks should use generated types alongside colocated documents; useVideoChildren is the reference pattern
useWatch dispatches should tar...

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
apps/resources/src/components/**/*.tsx

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

Component naming format: Use UiType prefix (e.g., Modal, Button, Footer, Page) + ComponentFunction (e.g., LanguageSwitch, MainVideo); omit ComponentFunction for basic primitives; use PascalCase for all component names

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
apps/resources/src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/resources/AGENTS.md)

Component props should use optional props with sensible defaults; include className prop for extensibility; use ReactNode for children and content slots; name interfaces with component name prefix (e.g., ComponentNameProps)

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
apps/**/*.test.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/apps.mdc)

Use '@testing-library/react' npm package for frontend tests.

Files:

  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
🧠 Learnings (34)
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/setupTests.tsx : Reuse shared Jest setup that boots MSW, Next router mock, and longer timeouts

Applied to files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.spec.{ts,tsx} : Reuse the shared Jest setup in `apps/resources/setupTests.tsx`; it already boots MSW, the Next router mock, and longer async timeout; wrap component specs with `MockedProvider`, `VideoProvider`, and `WatchProvider` when touching those contexts

Applied to files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.spec.{ts,tsx} : Always propose and implement unit or integration tests covering edge cases and failure paths; co-locate React Testing Library specs under `*.spec.ts(x)`; mock network traffic with MSW handlers

Applied to files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.spec.{ts,tsx} : Enclose SWR-based hooks in `TestSWRConfig` to isolate cache state between assertions

Applied to files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-11-16T21:30:53.412Z
Learnt from: Kneesal
Repo: JesusFilm/core PR: 8309
File: apps/journeys-admin/setupTests.tsx:47-51
Timestamp: 2025-11-16T21:30:53.412Z
Learning: In apps/journeys-admin/setupTests.tsx, the `document.clearImmediate` mock is required for tests involving the mux upload provider, as an underlying library uses clearImmediate for timeout management to prevent race conditions and unnecessary polling calls.

Applied to files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{spec.ts,spec.tsx} : Wrap component specs with MockedProvider, VideoProvider, and WatchProvider when touching those contexts

Applied to files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/apps/resources-e2e/**/*.{ts,tsx} : Extend Playwright scenarios when UI behavior shifts, and capture console logs/screenshots for regressions; document executed test suite, notable scenarios, and any skipped checks in `/prds/resources/`

Applied to files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/test/**/* : Mock network with MSW handlers under apps/watch/test

Applied to files:

  • apps/resources/setupTests.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{spec.ts,spec.tsx} : Co-locate React Testing Library specs under *.spec.ts(x)

Applied to files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-07-27T21:59:10.507Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/watch-modern.mdc:0-0
Timestamp: 2025-07-27T21:59:10.507Z
Learning: Applies to apps/watch-modern/**/*.test.{tsx,jsx} : Use 'testing-library/react' npm package for frontend tests.

Applied to files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-08-29T20:37:40.965Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7573
File: libs/shared/ui/tsconfig.spec.json:6-6
Timestamp: 2025-08-29T20:37:40.965Z
Learning: For Jest 30 compatibility, both injectGlobals: true in jest.config.ts files and "jest/globals" in the types array of tsconfig.spec.json files are required together, even though this appears redundant in earlier Jest versions.

Applied to files:

  • apps/resources/setupTests.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/test/TestSWRConfig.tsx : Enclose SWR-based hooks in TestSWRConfig to isolate cache between assertions

Applied to files:

  • apps/resources/setupTests.tsx
  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/src/**/*.{tsx} : Navigation: design link-based content discovery through components

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Optimize bundles via tree-shaking and code splitting in component design

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/src/**/*.{tsx} : Compose UI with shadcn/ui primitives or semantic HTML styled via Tailwind; do not introduce new MUI usage

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Implement accessibility (ARIA, keyboard, focus states); ensure interactive elements have tabindex/aria/onClick/onKeyDown as needed

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Use semantic HTML elements (header, main, footer)

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Dialogs/Modals prefixed with 'Dialog', Sections with 'Section', Layout components with 'Layout'

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Use semantic HTML elements: `<header>`, `<main>`, `<footer>`

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Compose UI with shadcn/ui primitives or semantic HTML styled via Tailwind; use the shared `cn` helper for conditional classes

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Applies to apps/watch/**/*.{tsx} : Maintain high visual polish using Tailwind (typography, spacing, animations)

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/components/**/*Video*.{ts,tsx} : Components like `VideoContentHero` depend on the full provider stack (VideoProvider, WatchProvider, PlayerProvider) plus video.js and mux metadata; preserve existing contracts for autoplay, subtitles, and analytics

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-19T18:48:41.906Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-09-19T18:48:41.906Z
Learning: Do not introduce new MUI usage even if lint allows; continue migration to shadcn/Tailwind

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-07-27T21:59:10.507Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/watch-modern.mdc:0-0
Timestamp: 2025-07-27T21:59:10.507Z
Learning: Applies to apps/watch-modern/**/*.{tsx,jsx} : Prefer shadcn/ui components over custom implementations or raw HTML elements. If a shadcn/ui component does not exist, use semantic HTML and Tailwind CSS, and document the reason.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-11T23:22:42.107Z
Learnt from: lumberman
Repo: JesusFilm/core PR: 8496
File: apps/resources/AGENTS.md:6-6
Timestamp: 2025-12-11T23:22:42.107Z
Learning: The Resources app (apps/resources) should continue using MUI components for UI, not shadcn/ui or Tailwind CSS. This is the established architectural direction for this specific app.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Use Shadcn/ui components as the primary choice for all UI needs; if shadcn/ui doesn't exist, build with Tailwind CSS; use Semantic HTML + Tailwind only for basic elements when neither above applies

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-07-27T21:59:04.362Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/apps.mdc:0-0
Timestamp: 2025-07-27T21:59:04.362Z
Learning: Applies to apps/**/*.{js,jsx,ts,tsx} : Always use MUI over HTML elements; avoid using CSS or tags.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Do not introduce new MUI usage even though the lint rule is relaxed; new shadcn work should coexist with core shells/wrappers that are still using MUI until explicit migration tasks retire them

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-06-27T04:23:33.639Z
Learnt from: Kneesal
Repo: JesusFilm/core PR: 6806
File: apps/watch/src/components/VideoContentPage/VideoHero/VideoPlayer/VideoTitle/VideoTitle.tsx:21-54
Timestamp: 2025-06-27T04:23:33.639Z
Learning: The watch project (apps/watch) is in the process of being migrated to Tailwind CSS, so suggestions should favor Tailwind CSS over MUI components for HTML elements and styling.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-09-13T15:13:07.389Z
Learnt from: lumberman
Repo: JesusFilm/core PR: 7657
File: apps/watch/src/components/NewVideoContentPage/VideoCarousel/VideoCarousel.tsx:112-112
Timestamp: 2025-09-13T15:13:07.389Z
Learning: For apps/watch specifically, prefer Tailwind CSS over MUI components. The watch project is migrating away from MUI to Tailwind CSS for styling and components.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-12-03T15:21:24.876Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-03T15:21:24.876Z
Learning: Applies to apps/resources/src/**/*.{ts,tsx} : Implement accessibility features on elements: tags should have tabindex='0', aria-label, on:click, on:keydown, and similar attributes; build accessible experiences as part of every component

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-07-27T21:59:04.362Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/apps.mdc:0-0
Timestamp: 2025-07-27T21:59:04.362Z
Learning: Applies to apps/**/*.{js,jsx,ts,tsx} : Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-07-27T21:59:10.507Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/watch-modern.mdc:0-0
Timestamp: 2025-07-27T21:59:10.507Z
Learning: Applies to apps/watch-modern/**/*.{tsx,jsx} : Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.tsx
📚 Learning: 2025-07-27T21:59:04.362Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/apps.mdc:0-0
Timestamp: 2025-07-27T21:59:04.362Z
Learning: Applies to apps/**/*.test.{js,jsx,ts,tsx} : Use 'testing-library/react' npm package for frontend tests.

Applied to files:

  • apps/resources/src/components/BetaBanner/BetaBanner.test.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Deploy Preview (watch, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (resources, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (journeys, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (videos-admin, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (watch-modern, 8496/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (journeys-admin, 8496/merge, pull_request, 22)
  • GitHub Check: build (22)
🔇 Additional comments (14)
libs/locales/id-ID/apps-resources.json (1)

96-99: Properly localized translations address previous incomplete localization concern.

The four new keys (lines 96–99) now include complete Indonesian translations, resolving the prior review comment that flagged these entries as English-only strings in the Indonesian locale file. The translations appear contextually appropriate for the beta banner feature.

Note: The AI-generated summary claims no new keys were added, but the annotated code clearly shows four new translation entries here, which is an inconsistency in the summary.

libs/locales/vi-VN/apps-resources.json (1)

96-99: ✅ Addresses previous critical issue: BetaBanner translations now present.

The four new BetaBanner keys added in lines 96–99 are now translated to Vietnamese, resolving the earlier flag about missing translations. JSON structure is valid, punctuation aligns with English originals, and the format matches the pattern applied to other locales in this PR.

To confirm translation quality and ensure consistency across all 17+ locales mentioned in the previous review, you may want to verify:

  • Are the Vietnamese phrasing and idiom appropriate for the target audience?
  • Have all other locales (am-ET, bn-BD, en, id-ID, hi-IN, ms-MY, my-MM, ne-NP, th-TH, tl-PH, tr-TR, ur-PK, zh-Hant-TW, ja-JP, ko-KR, ru-RU) also received translations to prevent English fallback?
libs/locales/ms-MY/apps-resources.json (1)

95-99: All banner string translations are now complete across all non-English locales.

The ms-MY locale file now includes proper Malay translations for all four banner strings (lines 96–99), and verification confirms that all 13 other non-English locales (ur-PK, tr-TR, vi-VN, th-TH, my-MM, ru-RU, ne-NP, ja-JP, id-ID, bn-BD, hi-IN, ko-KR, am-ET) have also been updated with equivalent translations. Users in all supported languages will now see properly localized banner copy instead of untranslated English text.

apps/resources/setupTests.tsx (1)

29-30: LGTM!

The next/compat/router mock correctly mirrors the existing next/router mock pattern and is required since BetaBanner imports useRouter from next/compat/router. This ensures test compatibility across both router APIs.

libs/locales/ru-RU/apps-resources.json (1)

98-102: LGTM!

The four new translation keys align with the BetaBanner component's usage and follow the existing locale file structure. The Russian translations appear grammatically correct.

libs/locales/ko-KR/apps-resources.json (1)

95-99: LGTM!

The Korean locale additions are complete with all four required translation keys for the BetaBanner feature, following the existing file structure.

apps/resources/src/components/BetaBanner/BetaBanner.test.tsx (2)

1-4: LGTM!

Imports are well-organized with testing-library/react and proper component import path.


6-36: Mocks are well-structured for test isolation.

The cookie, canvas context, and animation frame mocks provide comprehensive browser API simulation for the component's functionality. Using configurable: true for the cookie property allows proper reset between tests.

apps/resources/src/components/BetaBanner/BetaBanner.tsx (6)

1-8: LGTM!

Imports are well-organized and appropriate. Using MUI is correct for the Resources app per the established architectural direction. Based on learnings, the Resources app should continue using MUI components.


10-18: Well-defined interface.

The Particle interface provides clear type safety for the animation system.


125-129: Cookie security attributes are properly implemented.

The cookie correctly includes max-age, path, SameSite=Lax, and conditionally adds Secure for HTTPS. This addresses the previous review feedback.


131-140: Event handlers follow naming conventions.

Handlers are properly prefixed with handle* as per coding guidelines, and keyboard handling correctly supports both Enter and Space keys.


159-172: Canvas accessibility properly addressed.

The decorative canvas correctly includes aria-hidden="true", role="presentation", and tabIndex={-1} to hide it from assistive technologies.


182-212: Accessible button implementation.

The button includes proper tabIndex, aria-label, onClick, onKeyDown, cursor: pointer, and visible focus states. This meets the accessibility requirements from the coding guidelines.

@lumberman lumberman closed this Dec 12, 2025
@github-actions github-actions bot requested a deployment to Preview - watch-modern December 12, 2025 00:25 Pending
@github-actions github-actions bot requested a deployment to Preview - journeys-admin December 12, 2025 00:25 Pending
@github-actions github-actions bot requested a deployment to Preview - videos-admin December 12, 2025 00:25 Pending
@github-actions github-actions bot deleted the codex/vm-25-add-non-dismissable-beta-banner branch March 19, 2026 02:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant