Skip to content

Conversation

@afifvdin
Copy link
Collaborator

@afifvdin afifvdin commented Oct 28, 2025

Summary

Closes: QF-3593

As a guest use or logged in user
I want to user the navigation bar and the burger menu
So that I can navigate between pages easily

Acceptance criteria:

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Test plan

Language Selector Tests

  • Updated navigation flow: open drawer → click language button → use language container
  • Changed from menuitem to button role for language items
  • Scoped assertions to language-container test ID
  • Files: language-selector.spec.ts, language-content.spec.ts, language-persistance.spec.ts

Settings Drawer Tests

  • Replaced CSS selector #settings-drawer-body with getByTestId('settings-drawer-body')
  • Updated test ID from settings-drawer-container to settings-drawer-body
  • Files: settings-gear.spec.ts, settings-drawer.spec.ts, language-content.spec.ts

Navigation Drawer Tests

  • Fixed async handling: call waitForEvent('page') before click action
  • Files: navigation-drawer.spec.ts

Component Fixes

  • Fixed Collapsible component behavior
  • Fixed language container dispatcher
  • Updated drawer IDs for consistency
  • Components: Collapsible.tsx, LanguageContainer.tsx, Drawer/index.tsx,
    SettingsDrawer.tsx

Test Strategy

  • Use data-testid instead of CSS selectors
  • Consistent naming: *-drawer-body for drawer content
  • Test complete user flows (open drawer → click → interact)
  • Proper async handling for navigation events
  • Use semantic roles (button, menuitem) appropriately

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • My changes generate no new warnings
  • Any dependent changes have been merged and published in downstream modules
  • I have commented on my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Screenshots or videos

Before After
2025-10-28_12-24-41 2025-10-28_12-25-27

Summary by CodeRabbit

  • New Features

    • Language selection panel in the navigation drawer with persistence and undo-on-error; drawer now dims and inerts background when open.
    • Theme switcher (Light/Dark/Sepia) with icons and loading state.
    • Updated navigation: Read, Learn, My Quran, Quran Radio, Reciters, About, continue-reading shortcut, plus expanded "More" and "Our Projects" sections and a My Quran profile menu item.
  • Localization

    • Added strings: Change Theme, Learn, My Quran, Read, Select Language.
  • Style

    • New button variants, accent icon styling, and a subtle flat shadow token.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 28, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds new navigation-drawer UI (language picker, theme switcher, collapsibles, consolidated list), drawer state selector and continue-reading hook, new URL constants, button/icon/collapsible variants and styles, accessibility/inert handling, and test selector updates. All changes are additive and presentational.

Changes

Cohort / File(s) Summary
Localization
locales/en/common.json
Added top-level translation keys: change-theme, learn, my-quran, read, select-language.
Navigation Drawer — New Components
src/components/Navbar/NavigationDrawer/LanguageContainer.tsx, src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss, src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx, src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx, src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx, src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx, src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
Added LanguageContainer (locale list, setLanguage, cookie, user-pref persistence + Undo toast), MoreMenuCollapsible and OurProjectsCollapsible (collapsibles with logging), NavigationDrawerList (consolidated nav items), and ThemeSwitcher (popover, dispatch, logging).
Navigation Drawer — Body & Layout
src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx, src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss, src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx, src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss, src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss, src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
Moved drawer to right, added id="navigation-drawer", header includes ProfileAvatarButton (portalling off), language container toggle and CTA area, refactored list rendering, and added optional titleClassName? prop plus styling adjustments.
Navbar & Avatar
src/components/Navbar/NavbarBody/index.tsx, src/components/Navbar/NavbarBody/NavbarBody.module.scss, src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
Login-aware rendering changes, added isPopoverPortalled prop to ProfileAvatarButton (default true), added "My Quran" menu item, changed login button variant to SimplifiedAccent, and applied dimming overlay + inert/aria-hidden when drawer open.
App Content Overlay
src/components/AppContent/AppContent.tsx, src/components/AppContent/AppContent.module.scss
Wraps main content in a dimmable container driven by selectIsNavigationDrawerOpen; adds fullscreen overlay pseudo-element, toggles .dimmed, and sets inert/aria-hidden when dimmed.
Buttons, Icons & Collapsible
src/components/dls/Button/Button.tsx, src/components/dls/Button/Button.module.scss, src/components/dls/IconContainer/IconContainer.tsx, src/components/dls/IconContainer/IconContainer.module.scss, src/components/dls/Collapsible/Collapsible.tsx, src/components/dls/Collapsible/Collapsible.module.scss
Button converted to forwardRef and gains SimplifiedAccent/Accent variants with styles; IconColor gains accent and styling; Collapsible adds id?, shouldRotateSuffixOnToggle?, shouldSuffixTrigger? and suffix interaction/keyboard handling.
New Hook & Utilities
src/hooks/useGetContinueReadingUrl.ts, src/utils/navigation.ts, src/redux/slices/navbar.ts
Added useGetContinueReadingUrl() hook, new EXTERNAL_ROUTES and exported URL constants, and selector selectIsNavigationDrawerOpen.
Styling & Theme variables
src/styles/themes/_dark.scss, src/styles/themes/_light.scss, src/styles/themes/_sepia.scss, src/styles/theme.scss, src/styles/reset.scss
Added --shadow-flat, new spacing/font-size tokens, minor sepia color tweak, standardized quote usage in SCSS/selectors, and other presentational CSS updates.
Drawer & Misc props
src/components/Navbar/Drawer/index.tsx, src/components/Navbar/SearchDrawer/SearchDrawer.tsx, src/components/Navbar/SettingsDrawer/SettingsDrawer.tsx, src/components/Search/SearchBodyContainer.tsx
Drawer accepts optional id?: string and uses it for id/testid; Search/Settings drawers given ids/test-ids; SettingsDrawer renders a body wrapper and conditionally renders views inside.
Tests
tests/**/* (multiple specs changed)
Updated many Playwright tests to new selectors and flows: language selection via LanguageContainer, assertions for duplicated profile/sign-in elements, settings/search drawer test-id changes, donation link text and drawer link expectations, and other selector adjustments.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Navbar
    participant Drawer
    participant LanguageContainer
    participant i18n
    participant PrefService
    participant Toast

    User->>Navbar: Open navigation & click language trigger
    Navbar->>Drawer: show LanguageContainer
    User->>LanguageContainer: Select locale
    LanguageContainer->>i18n: setLanguage(locale)
    LanguageContainer->>PrefService: persist user pref (async)
    alt persist fails
        PrefService-->>LanguageContainer: Error
        LanguageContainer->>Toast: show warning (Undo / Continue)
        User->>Toast: choose Undo
        Toast->>i18n: setLanguage(previousLocale)
    else persist ok
        PrefService-->>LanguageContainer: OK
    end
    LanguageContainer->>Drawer: onBack()
Loading
sequenceDiagram
    participant User
    participant Drawer
    participant Redux
    participant AppContent
    participant Navbar

    User->>Drawer: Open drawer
    Drawer->>Redux: dispatch(setIsNavigationDrawerOpen(true))
    Redux-->>AppContent: selectIsNavigationDrawerOpen = true
    Redux-->>Navbar: selectIsNavigationDrawerOpen = true
    AppContent->>AppContent: apply dimmed overlay + inert/aria-hidden
    Navbar->>Navbar: apply dimmed overlay on items
    User->>Drawer: Close drawer
    Drawer->>Redux: dispatch(setIsNavigationDrawerOpen(false))
    AppContent->>AppContent: remove dimming
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Focus areas:
    • LanguageContainer: async persistence, undo toast and error-handling paths.
    • ThemeSwitcher: dispatch side-effects and font-face reset behavior.
    • Accessibility: inert/aria-hidden usage and new keyboard interactions for collapsible suffix.
    • Button API change (forwardRef) and new variants — update consumer usages and styles.
    • Tests: widespread selector/flow updates — validate stability.

Possibly related PRs

Suggested reviewers

  • osamasayed
  • AhmedCodeGuy

"🐇
I hopped through code with nimble paws—
I added themes, languages, and tidy laws.
Drawers that dim and menus that sing,
Bookmarks, icons, and a little swing.
A hop, a tweak — the interface springs!"

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'QF-3593 Update the burger menu' is directly related to the main change in the changeset, which comprehensively redesigns the navigation bar and burger menu layout, placement, and contents.
Description check ✅ Passed The PR description provides comprehensive coverage of the changes, including acceptance criteria, detailed menu structure, type of change, test plan, and checklist items, substantially addressing the template structure.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 QF-3593

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

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 29

Caution

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

⚠️ Outside diff range comments (7)
locales/en/common.json (1)

440-441: TODO: Fix grammar in themes.system-desc.

“adopts to your light/dark mode settings” → “adapts to your light/dark mode settings”. Small polish for UI copy.

src/components/dls/IconContainer/IconContainer.module.scss (1)

8-12: RTL selector scope and icon color strategy

  • The selector .container[dir='rtl'] only matches if dir is on the same element. If dir is on <html>/root, the flip won’t apply. Prefer a global dir scope.
  • Color application mixes color and fill across classes and uses !important. This can lead to inconsistent rendering depending on whether icons rely on currentColor or path fills.

Suggested fix for RTL:

-.container[dir='rtl'][data-auto-flip-icon='true'] {
+:global([dir='rtl']) .container[data-auto-flip-icon='true'] {
   > svg {
     transform: scaleX(-1);
   }
 }

Also consider standardizing on either:

  • currentColor-based icons: set color on > svg and avoid path fill, or
  • path-fill icons: set fill on > svg path.

Reduce !important where possible.

Also applies to: 32-37, 39-44

src/components/dls/Collapsible/Collapsible.tsx (4)

50-53: Fix controlled-state bug: guard undefined shouldOpen

shouldOpen is optional; setIsOpen(shouldOpen) can pass undefined, violating the boolean state type and flipping Root from controlled to uncontrolled.

Apply:

-  useEffect(() => {
-    setIsOpen(shouldOpen);
-  }, [shouldOpen]);
+  useEffect(() => {
+    if (typeof shouldOpen === 'boolean') setIsOpen(shouldOpen);
+  }, [shouldOpen]);

54-57: Remove suffix click interceptor; breaks toggle and a11y

Stopping propagation on the suffix prevents header toggle and triggers a11y lint errors on a static div.

Apply:

-  const onSuffixClicked = (e) => {
-    e.preventDefault();
-    e.stopPropagation();
-  };
+  // Allow suffix clicks to toggle via Radix Trigger; no interception needed.

...
-                    onClick={onSuffixClicked}

Additionally, remove the top a11y disable comments if no other violations remain.

Also applies to: 83-83


34-47: Type the component as React.FC

Aligns with repo guidelines for src/components/**/*.tsx.

Apply:

-const Collapsible = ({
+const Collapsible: React.FC<Props> = ({

104-106: Replace CollapsiblePrimitive.CollapsibleContent with CollapsiblePrimitive.Content

@radix-ui/react-collapsible v1.x exports Root, Trigger, and Content. The codebase uses ^1.1.0, so lines 104–106 in src/components/dls/Collapsible/Collapsible.tsx must use the correct export name:

      <CollapsiblePrimitive.Content>
        {isOpen && children({ isOpen })}
      </CollapsiblePrimitive.Content>
src/components/Navbar/NavbarBody/index.tsx (1)

50-60: Use action creators instead of raw { type, payload }

Improves type-safety and prevents typos.

Apply:

-    dispatch({ type: setIsNavigationDrawerOpen.type, payload: true });
+    dispatch(setIsNavigationDrawerOpen(true));
...
-    dispatch({ type: setIsSearchDrawerOpen.type, payload: true });
+    dispatch(setIsSearchDrawerOpen(true));
-    dispatch({ type: setDisableSearchDrawerTransition.type, payload: false });
+    dispatch(setDisableSearchDrawerTransition(false));
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a198d2 and e74a268.

⛔ Files ignored due to path filters (5)
  • public/icons/about.svg is excluded by !**/*.svg
  • public/icons/arrow-left.svg is excluded by !**/*.svg
  • public/icons/arrow-right.svg is excluded by !**/*.svg
  • public/icons/school.svg is excluded by !**/*.svg
  • public/icons/square-more.svg is excluded by !**/*.svg
📒 Files selected for processing (30)
  • locales/en/common.json (5 hunks)
  • src/components/AppContent/AppContent.module.scss (1 hunks)
  • src/components/AppContent/AppContent.tsx (4 hunks)
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss (1 hunks)
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (6 hunks)
  • src/components/Navbar/NavbarBody/index.tsx (4 hunks)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss (1 hunks)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss (2 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx (2 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss (2 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss (2 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx (3 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss (1 hunks)
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx (1 hunks)
  • src/components/dls/Button/Button.module.scss (1 hunks)
  • src/components/dls/Button/Button.tsx (2 hunks)
  • src/components/dls/Collapsible/Collapsible.module.scss (2 hunks)
  • src/components/dls/Collapsible/Collapsible.tsx (3 hunks)
  • src/components/dls/IconContainer/IconContainer.module.scss (2 hunks)
  • src/components/dls/IconContainer/IconContainer.tsx (2 hunks)
  • src/hooks/useGetContinueReadingUrl.ts (1 hunks)
  • src/styles/reset.scss (6 hunks)
  • src/styles/themes/_dark.scss (2 hunks)
  • src/styles/themes/_light.scss (2 hunks)
  • src/styles/themes/_sepia.scss (2 hunks)
🧰 Additional context used
📓 Path-based instructions (16)
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

If you encounter a bug in existing code, or the instructions lead to suboptimal or buggy code, add comments starting with "TODO:" outlining the problems.

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Conditional Classes: Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly, and when you do, make them meaningful.
Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.
Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.
Provide meaningful information about the function's behavior and explain unusual behavior and potential pitfalls.

**/*.*: Write short functions that only do one thing.
Follow the single responsibility principle (SRP), which means that a function should have one purpose and perform it effectively.
If a function becomes too long or complex, consider breaking it into smaller, more manageable functions.

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing.
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted.

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior.
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used.

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/styles/themes/_sepia.scss
  • src/components/dls/Button/Button.module.scss
  • src/hooks/useGetContinueReadingUrl.ts
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/styles/themes/_dark.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/styles/reset.scss
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/AppContent/AppContent.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/dls/IconContainer/IconContainer.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • locales/en/common.json
  • src/components/dls/Collapsible/Collapsible.module.scss
  • src/styles/themes/_light.scss
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Rely on Next.js Pages Router for state changes.
Minimize 'use client' usage: Prefer server components and Next.js SSR features.
Minimize 'use client' usage: Use 'use client' only for Web API access in small components.
Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

**/*.{js,jsx,ts,tsx}: Optimize Web Vitals (LCP, CLS, FID)
Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/hooks/useGetContinueReadingUrl.ts
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks.
Use React.FC for functional components with props.

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components
Keep components small and focused
Extract reusable logic into custom hooks
Use composition over inheritance
Split large components into smaller, focused ones
Follow the Rules of Hooks
Use custom hooks for reusable logic
Use appropriate dependency arrays in useEffect
Implement cleanup in useEffect when needed
Avoid nested hooks
Use useState for local component state
Avoid prop drilling through proper state management
Implement proper memoization (useMemo, useCallback)
Use React.memo for expensive components
Avoid unnecessary re-renders
Implement proper lazy loading
Use proper key props in lists
Profile and optimize render performance
Show appropriate loading and error states
Handle async errors properly
Show user-friendly error messages
Implement proper fallback UI
Log errors appropriately
Handle edge cases gracefully
Use semantic HTML elements
Implement proper ARIA attributes
Ensure keyboard navigation
Handle focus management
Provide proper alt text for images
Use proper imports/exports
Document complex component logic

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
**/*.tsx

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

Implement proper prop types with TypeScript

**/*.tsx: Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Implement proper error boundaries

React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
**/*.{ts,tsx}

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

Use xstate for complex state logic

**/*.{ts,tsx}: TypeScript: prefer interfaces over type aliases for object shapes; avoid any; add explicit return types for public functions
Error handling: define and use custom error types; use async/await correctly; show user-friendly error messages
Use Redux Toolkit for state management and XState for complex state machines
Implement i18n with next-translate in components and utilities

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/hooks/useGetContinueReadingUrl.ts
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid using any, prefer unknown for unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/hooks/useGetContinueReadingUrl.ts
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
{src,types}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript throughout the codebase with strict configuration

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/hooks/useGetContinueReadingUrl.ts
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer React functional components for UI implementation

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
{src,types}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use path aliases @/ for src and @/dls/* for design system imports

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/hooks/useGetContinueReadingUrl.ts
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize React components by feature and place DLS components under src/components/dls

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Order imports: React first, then external, then internal; alphabetize within groups with blank lines between groups
Naming: camelCase for variables/functions; PascalCase for types, interfaces, and React components; UPPER_CASE for constants
Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/hooks/useGetContinueReadingUrl.ts
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier formatting: single quotes, 2-space indentation, 100-character line width, and trailing commas

Files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
  • src/styles/themes/_sepia.scss
  • src/components/dls/Button/Button.module.scss
  • src/hooks/useGetContinueReadingUrl.ts
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/AppContent/AppContent.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/styles/themes/_dark.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/styles/reset.scss
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/AppContent/AppContent.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/dls/IconContainer/IconContainer.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/dls/Collapsible/Collapsible.module.scss
  • src/styles/themes/_light.scss
src/**/*.module.scss

📄 CodeRabbit inference engine (CLAUDE.md)

Use SCSS Modules for component-specific styling

Files:

  • src/components/dls/Button/Button.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/AppContent/AppContent.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/dls/IconContainer/IconContainer.module.scss
  • src/components/dls/Collapsible/Collapsible.module.scss
**/*.module.scss

📄 CodeRabbit inference engine (AGENTS.md)

Use SCSS modules for component styling

Files:

  • src/components/dls/Button/Button.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/AppContent/AppContent.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/dls/IconContainer/IconContainer.module.scss
  • src/components/dls/Collapsible/Collapsible.module.scss
locales/**

📄 CodeRabbit inference engine (CLAUDE.md)

Keep translation files under locales/[lang]/ using next-translate conventions

Files:

  • locales/en/common.json
🧠 Learnings (1)
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/styles/_breakpoints.scss : Use responsive breakpoints defined in src/styles/_breakpoints.scss

Applied to files:

  • src/components/dls/IconContainer/IconContainer.module.scss
🧬 Code graph analysis (10)
src/hooks/useGetContinueReadingUrl.ts (1)
src/utils/navigation.ts (1)
  • getChapterWithStartingVerseUrl (70-73)
src/components/AppContent/AppContent.tsx (1)
src/redux/slices/navbar.ts (1)
  • selectNavbar (85-85)
src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx (2)
src/utils/eventLogger.ts (1)
  • logButtonClick (44-46)
src/utils/navigation.ts (1)
  • getProfileNavigationUrl (387-389)
src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (2)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (1)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/components/Navbar/NavbarBody/index.tsx (2)
src/redux/slices/navbar.ts (1)
  • selectNavbar (85-85)
src/utils/auth/login.ts (1)
  • isLoggedIn (15-15)
src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (2)
src/utils/eventLogger.ts (1)
  • logButtonClick (44-46)
src/utils/navigation.ts (2)
  • getProfileNavigationUrl (387-389)
  • getLoginNavigationUrl (402-403)
src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (7)
src/redux/slices/defaultSettings.ts (1)
  • selectIsUsingDefaultSettings (47-48)
src/components/dls/Toast/Toast.tsx (1)
  • useToast (86-96)
src/utils/cookies.ts (1)
  • setLocaleCookie (6-11)
src/utils/eventLogger.ts (1)
  • logValueChange (74-85)
src/utils/auth/login.ts (1)
  • isLoggedIn (15-15)
src/utils/auth/api.ts (1)
  • addOrUpdateUserPreference (393-403)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx (2)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logValueChange (74-85)
src/components/Navbar/SettingsDrawer/ThemeSection.tsx (1)
  • themeIcons (20-25)
🪛 Biome (2.1.2)
src/components/dls/Collapsible/Collapsible.tsx

[error] 79-84: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 79-84: Static Elements should not be interactive.

To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.

(lint/a11y/noStaticElementInteractions)

🪛 ESLint
src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx

[error] 155-155: Expected an assignment or function call and instead saw an expression.

(no-unused-expressions)

🔇 Additional comments (34)
src/components/Navbar/NavbarBody/NavbarBody.module.scss (2)

1-1: Good: Prettier formatting applied to import statement.

The import syntax has been correctly updated to use single quotes, aligning with Prettier configuration.


10-10: Overlay implementation looks solid; verify click handling in component.

The fullscreen overlay pattern is well-implemented:

  • position: relative on container establishes proper positioning context
  • ::before pseudo-element creates a fixed, fullscreen overlay with smooth opacity transition
  • .dimmed state correctly enables the overlay by toggling opacity and pointer-events
  • Proper use of CSS variables for theming and z-index layering

However, since the overlay is a pseudo-element (no direct DOM node), ensure the corresponding component file attaches a click handler to .itemsContainer or implements overlay-dismissal logic when the .dimmed state is active.

Please verify that the NavbarBody component handles click events on the overlay to dismiss the drawer when .dimmed is active.

Also applies to: 12-31

src/styles/themes/_light.scss (2)

1-1: Quote style updated for Prettier consistency.

Import statement now uses single quotes, aligning with project Prettier configuration.


68-70: --shadow-flat is properly consumed by the codebase.

Verification confirms the CSS variable is actively used in src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss (lines 14 and 36), and is defined across all three theme files (_light.scss, _dark.scss, _sepia.scss). No further action needed.

src/styles/themes/_sepia.scss (1)

1-1: Quote style updated for Prettier consistency.

Import statement now uses single quotes, aligning with project Prettier configuration.

src/styles/themes/_dark.scss (2)

1-1: Quote style updated for Prettier consistency.

Import statement now uses single quotes, aligning with project Prettier configuration.


62-63: --shadow-flat is actively used and shadow value is appropriate.

Verification confirms the variable is properly defined in the dark theme and actively consumed by the ThemeSwitcher component in the navigation redesign (src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss lines 14 and 36). The shadow value using var(--shade-9) is consistent with the pattern across all theme files.

src/styles/reset.scss (2)

140-146: Quote style normalization is consistent with project standards.

The standardization of attribute selectors from double to single quotes (e.g., input[type="search"]input[type='search']) aligns with the project's Prettier configuration (single quotes). These changes have no functional impact and improve consistency.

Also applies to: 148-154, 364-365, 381-381, 393-394


495-497: Add comment explaining SVG clip-path override and verify selector scope is intentional.

The rule svg g { clip-path: none !important; } lacks context about its purpose. While the selector is broad and uses !important, evidence suggests most SVG icons in the codebase are imported as React components (not rendered as DOM SVG), which limits practical impact. However, the rule will affect any actual inline SVG with <g> elements—including potential future components.

The concerns raised are valid:

  • Selector scope is global and could have unintended effects
  • Missing explanation of why this override is needed
  • !important bypasses normal CSS specificity

Add the suggested comment explaining the purpose and consider whether scoping to .navbar svg g or similar is appropriate if this truly targets only specific components.

src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss (1)

30-31: Width: 100% on .centerVertically — confirm no unintended wrapping.

Ensure child containers don’t wrap/overlap on small widths; add min-widths or flex constraints if needed.

src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss (1)

25-30: Add a clear :focus-visible style for accessibility parity with :hover.

Currently .containerStale only styles :hover. Add :focus-visible so keyboard users get the same affordance. As per coding guidelines.

Apply:

 .containerStale {
   &:hover {
     background: var(--color-background-alternative-medium);
   }
 }
+
+// Keyboard focus parity
+.containerStale:focus-visible {
+  outline: none;
+  background: var(--color-background-alternative-medium);
+}

Likely an incorrect or invalid review comment.

src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx (1)

27-27: Fix missing 'use client' directive and verify popover overflow/focus handling.

NavigationDrawer uses Redux useSelector hook (line 22) but is missing the 'use client' directive. With Next.js App Router, components using client-only APIs must be marked as client components.

Additionally, isPopoverPortalled={false} (line 32) on ProfileAvatarButton can cause the popover to be clipped if the header container or Drawer applies overflow constraints or transforms. This also risks z-index conflicts with the Drawer overlay.

Required:

  • Add 'use client' directive at the top of NavigationDrawer.tsx to satisfy the Redux hook requirement.

Verify manually:

  • Open drawer and click avatar: popover displays fully, not cut off by Drawer bounds.
  • Tab/Shift+Tab through header: focus management stays correct.
  • Press Esc: popover closes first, then Drawer (focus trap behavior).
  • Consider portalling the popover (isPopoverPortalled={true}) if overflow issues occur.
src/components/dls/Collapsible/Collapsible.module.scss (1)

13-33: LGTM! Clean transition implementation.

The addition of transform transitions to both prefix and suffix containers enables smooth rotation animations. The new .suffixRotated class mirrors the existing .prefixRotated pattern, maintaining consistency in the component's styling API.

src/components/AppContent/AppContent.tsx (2)

32-32: Good use of shallowEqual for performance optimization.

Using shallowEqual as the equality function prevents unnecessary re-renders when other navbar state properties change but isNavigationDrawerOpen remains the same.


42-48: LGTM! Standard overlay dimming pattern.

The conditional dimming overlay follows a common UX pattern for drawer/modal interactions. The implementation correctly applies the dimmed style only when the navigation drawer is open.

src/components/dls/IconContainer/IconContainer.tsx (1)

14-15: LGTM! Consistent extension of the color variant system.

The new quaternary and accent color variants follow the established pattern and integrate cleanly with the existing conditional styling logic.

Also applies to: 49-50

src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx (2)

17-17: LGTM! Good addition of styling flexibility.

The titleClassName prop enables external customization of the title styling while maintaining the base styles, following the composition pattern for component flexibility.

Also applies to: 26-26, 40-40


37-37: Icon color variant updated to quaternary.

The change from IconColor.secondary to IconColor.quaternary aligns with the new theming system introduced in this PR.

src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss (2)

4-23: LGTM! Solid slide-in animation with RTL support.

The slide-in panel animation is well-implemented with:

  • Smooth transitions using CSS variables
  • Proper RTL support that reverses the slide direction
  • Appropriate z-index layering

43-50: Good scrollable list implementation.

The language list properly handles overflow with overflow-y: auto and flex: 1, ensuring long language lists remain accessible without breaking the layout.

src/hooks/useGetContinueReadingUrl.ts (1)

22-36: LGTM! Well-structured fallback logic with proper memoization.

The hook implements a clear priority waterfall:

  1. Most recent reading session → 2. Redux state → 3. First surah default

The dependencies in useMemo are correct, and the optional chaining at line 24 safely handles empty arrays. The JSDoc comment clearly explains the behavior.

src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx (2)

35-42: Theme change logic with font reset is appropriate.

The conditional font face reset (line 38-41) only triggers when the theme actually changes, preventing unnecessary work. This is good defensive coding even though onThemeSelected is typically called only when a different theme is clicked.


63-78: LGTM! Clean theme option rendering with proper selection state.

The theme options are rendered with:

  • Proper selected state indication
  • Icons from the reused themeIcons mapping
  • Dividers between items for visual separation
  • Auto-close on selection via shouldCloseMenuAfterClick
src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx (2)

52-80: Centralize route URLs (optional)

Hardcoded paths like /learning-plans, /radio, /reciters, /about-us can drift. Consider moving them to utils/navigation (like getProfileNavigationUrl) for one‑source‑of‑truth.

⛔ Skipped due to learnings
Learnt from: yousefdergham
PR: quran/quran.com-frontend-next#2547
File: tests/integration/learning-plans/guest-access.spec.ts:3-5
Timestamp: 2025-10-22T20:39:29.339Z
Learning: Repository: quran/quran.com-frontend-next
Context: tests/integration/learning-plans/guest-access.spec.ts and similar focused integration tests
Learning: For focused integration tests that validate specific route behavior, maintainers prefer hard-coded route paths (e.g., LP_URL, FIRST_LESSON_URL) over environment-based URLs to avoid unnecessary complexity.

34-50: Remove the suggested fallback—the hook already guarantees a string return

The useGetContinueReadingUrl() hook explicitly returns type string and implements a three-tier fallback chain that ensures it always returns a valid URL:

  1. Recent reading session
  2. Redux lastReadVerse
  3. Default to chapter 1, verse 1

There is no code path where the hook returns undefined or an empty string. The proposed guard continueReadingUrl ?? '/' is unnecessary.

Likely an incorrect or invalid review comment.

src/components/dls/Collapsible/Collapsible.tsx (2)

22-22: Prop addition looks good

The optional shouldRotateSuffixOnToggle prop is a sensible extension and mirrors prefix behavior.


61-66: Let Radix drive open state; drop manual header onClick

Using CollapsiblePrimitive.Trigger and also toggling via onHeaderClicked duplicates logic and risks inconsistencies. Wire onOpenChange to setIsOpen and remove the header div’s onClick.
[ suggest_essential_refactor ]
Apply:

-  const onHeaderClicked = () => setIsOpen((preValue) => !preValue);
+  const handleOpenChange = (nextOpen: boolean) => {
+    setIsOpen(nextOpen);
+    onOpenChange?.(nextOpen);
+  };
...
-    <CollapsiblePrimitive.Root onOpenChange={onOpenChange} open={isOpen}>
+    <CollapsiblePrimitive.Root onOpenChange={handleOpenChange} open={isOpen}>
...
-        <div className={classNames(styles.header, headerClassName)} onClick={onHeaderClicked}>
+        <div className={classNames(styles.header, headerClassName)}>

This preserves analytics while enabling keyboard interactions via Radix.

src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (2)

20-35: Event logging is clean and minimal

onOpenChange expansion/collapse logging and per-item click logging follow utils/eventLogger conventions.

Confirm that Collapsible’s onOpenChange is fired after applying the Collapsible refactor; otherwise analytics won’t emit.


41-49: Good use of shouldRotateSuffixOnToggle

Passing the caret-down suffix with rotation keeps the UI consistent with other sections.

src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1)

49-57: Structure and analytics look consistent

Expansion/collapse + per-item click events match conventions and i18n usage is correct.

Also applies to: 61-137

src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1)

59-67: No changes required—the code is correct as written.

The constant LOCALE_COOKIE_PERSISTENCE_PERIOD_MS is explicitly documented as "maximum milliseconds-since-the-epoch value," not a duration. The code correctly uses setTime() with an absolute epoch value to set the cookie expiry to the far future (year 278915), effectively making it persistent. No refactoring needed.

Likely an incorrect or invalid review comment.

src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (2)

101-101: Popover portalling prop is correctly plumbed

isPopoverPortalledPopoverMenu.isPortalled looks good; enables in-drawer rendering when needed.


150-150: UI variant change: SimplifiedAccent

Looks fine. Please confirm contrast meets AA in Light/Dark and that snapshots/visual tests are updated if applicable.

src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1)

1-1: I need to verify if the parent component has the "use client" directive. Let me check that now.

Now I need to check if the parent component NavigationDrawer.tsx has "use client" anywhere, and confirm if this is an App Router codebase.

Now let me check if the parent component NavigationDrawer.tsx has "use client" directive anywhere in the file, and confirm if this is an App Router codebase:

Let me run a script to check if the parent NavigationDrawer.tsx has "use client" directive anywhere in the file:

Based on my verification through the script execution and web searches, I have confirmed the following:

  1. By default, every component in the Next.js App Router will be a Server Component
  2. You can't use hooks in React Server Components, and the NavigationDrawerBody component uses useState
  3. Once a file is marked with "use client", all its imports and child components are considered part of the client bundle, so you don't need to add the directive to every component that is intended for the client

The script output shows that NavigationDrawerBody is dynamically imported with ssr: false in the parent component, but dynamic(..., { ssr:false }) skips server HTML — it does not mark the component as a client component in the App Router sense.

Since the verification scripts showed no "use client" directive in NavigationDrawerBody/index.tsx (first 5 lines checked) and the parent NavigationDrawer.tsx needs to be examined, the review comment's concern about ensuring proper client component marking is valid.


Add "use client" directive to enable hooks usage.

This component uses useState hook. In App Router, if none of its parents are marked with "use client", they're Server Components by default. Either add "use client" to the top of this file, or confirm that the parent NavigationDrawer.tsx has the directive. Using dynamic(..., { ssr: false }) alone does not mark a component as client-side in the App Router.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 11

Caution

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

⚠️ Outside diff range comments (1)
src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (1)

1-1: Fix TS typing: import React type and use interface for props

React.FC requires React in type space; also prefer interface per guidelines.

-import { useState } from 'react';
+import { useState } from 'react';
+import type React from 'react';

-type ProfileAvatarButtonProps = {
-  isPopoverPortalled?: boolean;
-};
+interface ProfileAvatarButtonProps {
+  isPopoverPortalled?: boolean;
+}
 
-const ProfileAvatarButton: React.FC<ProfileAvatarButtonProps> = ({ isPopoverPortalled = true }) => {
+const ProfileAvatarButton: React.FC<ProfileAvatarButtonProps> = ({
+  isPopoverPortalled = true,
+}) => {

As per coding guidelines.

Also applies to: 33-38

♻️ Duplicate comments (2)
src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (1)

150-156: Good catch: the onClick now calls the handler

This resolves the prior no-op and ensures analytics + sidebar close run.

src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss (1)

5-9: Add 100vh fallback before 100dvh

Ensure older browsers that don’t support dvh still cap height correctly.

 .listItemsContainer {
   height: 100%;
   position: relative;
   overflow: hidden !important;
-  max-height: calc(100dvh - var(--navbar-height));
+  /* Fallback for browsers without dynamic viewport units */
+  max-height: calc(100vh - var(--navbar-height));
+  /* Override where supported */
+  max-height: calc(100dvh - var(--navbar-height));
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e74a268 and f98fb93.

📒 Files selected for processing (14)
  • src/components/AppContent/AppContent.module.scss (1 hunks)
  • src/components/AppContent/AppContent.tsx (4 hunks)
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss (1 hunks)
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (6 hunks)
  • src/components/Navbar/NavbarBody/index.tsx (4 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss (2 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss (1 hunks)
  • src/components/dls/Button/Button.module.scss (4 hunks)
  • src/components/dls/Button/Button.tsx (4 hunks)
  • src/components/dls/Link/Link.tsx (1 hunks)
  • src/redux/slices/navbar.ts (1 hunks)
  • src/styles/themes/_sepia.scss (2 hunks)
🧰 Additional context used
📓 Path-based instructions (18)
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

If you encounter a bug in existing code, or the instructions lead to suboptimal or buggy code, add comments starting with "TODO:" outlining the problems.

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Conditional Classes: Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly, and when you do, make them meaningful.
Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.
Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.
Provide meaningful information about the function's behavior and explain unusual behavior and potential pitfalls.

**/*.*: Write short functions that only do one thing.
Follow the single responsibility principle (SRP), which means that a function should have one purpose and perform it effectively.
If a function becomes too long or complex, consider breaking it into smaller, more manageable functions.

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing.
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted.

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior.
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used.

Files:

  • src/components/AppContent/AppContent.module.scss
  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/redux/slices/navbar.ts
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Button/Button.module.scss
  • src/styles/themes/_sepia.scss
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
src/**/*.module.scss

📄 CodeRabbit inference engine (CLAUDE.md)

Use SCSS Modules for component-specific styling

Files:

  • src/components/AppContent/AppContent.module.scss
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Button/Button.module.scss
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier formatting: single quotes, 2-space indentation, 100-character line width, and trailing commas

Files:

  • src/components/AppContent/AppContent.module.scss
  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/redux/slices/navbar.ts
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Button/Button.module.scss
  • src/styles/themes/_sepia.scss
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.module.scss

📄 CodeRabbit inference engine (AGENTS.md)

Use SCSS modules for component styling

Files:

  • src/components/AppContent/AppContent.module.scss
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Button/Button.module.scss
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Rely on Next.js Pages Router for state changes.
Minimize 'use client' usage: Prefer server components and Next.js SSR features.
Minimize 'use client' usage: Use 'use client' only for Web API access in small components.
Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

**/*.{js,jsx,ts,tsx}: Optimize Web Vitals (LCP, CLS, FID)
Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/redux/slices/navbar.ts
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks.
Use React.FC for functional components with props.

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components
Keep components small and focused
Extract reusable logic into custom hooks
Use composition over inheritance
Split large components into smaller, focused ones
Follow the Rules of Hooks
Use custom hooks for reusable logic
Use appropriate dependency arrays in useEffect
Implement cleanup in useEffect when needed
Avoid nested hooks
Use useState for local component state
Avoid prop drilling through proper state management
Implement proper memoization (useMemo, useCallback)
Use React.memo for expensive components
Avoid unnecessary re-renders
Implement proper lazy loading
Use proper key props in lists
Profile and optimize render performance
Show appropriate loading and error states
Handle async errors properly
Show user-friendly error messages
Implement proper fallback UI
Log errors appropriately
Handle edge cases gracefully
Use semantic HTML elements
Implement proper ARIA attributes
Ensure keyboard navigation
Handle focus management
Provide proper alt text for images
Use proper imports/exports
Document complex component logic

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.tsx

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

Implement proper prop types with TypeScript

**/*.tsx: Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Implement proper error boundaries

React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.{ts,tsx}

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

Use xstate for complex state logic

**/*.{ts,tsx}: TypeScript: prefer interfaces over type aliases for object shapes; avoid any; add explicit return types for public functions
Error handling: define and use custom error types; use async/await correctly; show user-friendly error messages
Use Redux Toolkit for state management and XState for complex state machines
Implement i18n with next-translate in components and utilities

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/redux/slices/navbar.ts
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid using any, prefer unknown for unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/redux/slices/navbar.ts
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
{src,types}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript throughout the codebase with strict configuration

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/redux/slices/navbar.ts
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer React functional components for UI implementation

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
{src,types}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use path aliases @/ for src and @/dls/* for design system imports

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/redux/slices/navbar.ts
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize React components by feature and place DLS components under src/components/dls

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Order imports: React first, then external, then internal; alphabetize within groups with blank lines between groups
Naming: camelCase for variables/functions; PascalCase for types, interfaces, and React components; UPPER_CASE for constants
Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/redux/slices/navbar.ts
  • src/components/dls/Link/Link.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/{store,redux}/**/*.{ts,tsx}

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

Implement Redux Toolkit for efficient Redux development for medium-complex state logic

Files:

  • src/redux/slices/navbar.ts
src/redux/**/*

📄 CodeRabbit inference engine (.cursor/rules/redux-folder-structure.mdc)

Follow this folder structure: src/redux/actions/, src/redux/slices/, src/redux/RootState.ts, src/redux/store.ts, src/redux/migrations.ts

Files:

  • src/redux/slices/navbar.ts
src/redux/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/redux-toolkit-best-practices.mdc)

src/redux/**/*.ts: Use Redux Toolkit for efficient Redux development.
Implement slice pattern for organizing Redux code.
Use selectors for accessing state in components.
Use Redux hooks (useSelector, useDispatch) in components.
Follow Redux style guide for naming conventions

Use Redux Toolkit for state management and persistence (redux-persist) within the redux layer

Files:

  • src/redux/slices/navbar.ts
🧠 Learnings (6)
📚 Learning: 2025-10-18T11:22:53.139Z
Learnt from: jonybekov
PR: quran/quran.com-frontend-next#2537
File: src/redux/slices/session.ts:36-42
Timestamp: 2025-10-18T11:22:53.139Z
Learning: In Redux selectors, avoid calling functions that read from external state (cookies, localStorage, etc.) like `isLoggedIn()` from utils/auth/login. Instead, use reactive hooks like `useIsLoggedIn` directly in components and keep selectors focused only on Redux state to ensure proper memoization.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:15.592Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/performance-optimization-rules.mdc:0-0
Timestamp: 2025-08-01T08:50:15.592Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use dynamic loading for non-critical components using src/components/dls/Spinner/Spinner.tsx

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle focus management

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Ensure keyboard navigation

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:22.602Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/react-functional-components.mdc:0-0
Timestamp: 2025-08-01T08:50:22.602Z
Learning: Applies to src/components/**/*.tsx : Use React.FC for functional components with props.

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.tsx : Prefix interfaces for React props with 'Props' (e.g., ButtonProps)

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
🧬 Code graph analysis (5)
src/components/AppContent/AppContent.tsx (1)
src/redux/slices/navbar.ts (1)
  • selectNavbar (85-85)
src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/components/Navbar/NavbarBody/index.tsx (2)
src/redux/slices/navbar.ts (1)
  • selectIsNavigationDrawerOpen (87-88)
src/utils/auth/login.ts (1)
  • isLoggedIn (15-15)
src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (2)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (2)
src/utils/eventLogger.ts (1)
  • logButtonClick (44-46)
src/utils/navigation.ts (2)
  • getProfileNavigationUrl (387-389)
  • getLoginNavigationUrl (402-403)
🔇 Additional comments (22)
src/components/Navbar/NavbarBody/NavbarBody.module.scss (1)

1-29: Solid overlay implementation following design system patterns.

The overlay layer is well-structured with proper use of design system variables (colors, spacing, z-index, opacity, transitions) and follows standard CSS practices for fullscreen backdrops. The .dimmed modifier correctly toggles visibility by managing opacity and pointer-events. Prettier formatting is consistent throughout (single quotes, proper indentation).

src/styles/themes/_sepia.scss (1)

1-1: Past review comment on shadow ordering resolved; quote style updated.

The --shadow-flat variable is now correctly positioned after --shadow-small for consistency across theme files, and the import statement uses single quotes per formatting guidelines. Both changes align with the prior review feedback and project standards.

Also applies to: 63-63

src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss (2)

1-1: Shadow variable integration correct; transition syntax fixed from past review.

The module properly references the newly-added --shadow-flat variable in both .popoverContent (line 14) and .popoverItem checked state (line 36), and the SVG path transition syntax at line 96 now correctly uses comma-separated properties, resolving the prior critical issue.

Also applies to: 14-14, 36-36


3-99: Well-structured styling with proper state management and accessibility handling.

The module follows SCSS best practices:

  • Single-quoted import and consistent use of CSS variables.
  • Clear separation of concerns: base, hover, focus, and checked states.
  • Dark mode adjustments via @include theme.dark.
  • Smooth transitions on color and stroke properties.

No issues identified.

src/components/dls/Link/Link.tsx (2)

63-63: Excellent security enhancement!

Adding noopener alongside noreferrer is a security best practice that prevents reverse tabnabbing attacks by ensuring the new page cannot access the window.opener property. This change aligns with modern web security standards.


1-1: <!-- [scratchpad_start]
[task review_file_1/1 review_verification_1/1]
Verify whether eslint-disable comment on line 1 is still necessary.

[observations]

  • First eslint command produced no output (inconclusive)
  • Need to directly examine the file to see current state
  • Need to verify: (1) current rel attribute value, (2) presence of eslint-disable comment, (3) whether rule would pass

[analysis]

  • No output from eslint could mean: rule passed, command failed, or eslint not available
  • Cannot determine if comment is necessary without understanding actual file state
  • Need direct file inspection

[pending]

  • Examine file content at src/components/dls/Link/Link.tsx
  • Verify line 1 has eslint-disable comment
  • Verify line 63 has updated rel attribute with 'noopener noreferrer'
  • Determine if rule would pass without the disable comment

[actions]

  1. Use cat/rg to examine the file directly
  2. Look for the eslint-disable comment and the rel attribute
  3. Check for any instances of target="_blank" without proper rel
src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1)

85-85: Trailing spaces have been fixed.

The previously reported trailing spaces in the Play Store and App Store URLs have been corrected.

Also applies to: 93-93

src/components/dls/Button/Button.module.scss (2)

3-7: LGTM: Improved readability.

The multi-line formatting improves readability and aligns with the 100-character line width guideline.


190-190: LGTM: Quote style normalization.

Aligning attribute selectors to single quotes is consistent with the Prettier configuration.

src/components/dls/Button/Button.tsx (5)

26-37: LGTM: Clear documentation.

The JSDoc comment effectively explains the semantic purpose of button types and their color theming behavior.


39-60: LGTM: Comprehensive variant documentation.

The JSDoc clearly explains variant behavior and explicitly documents compatible combinations, helping developers avoid the type+variant conflicts flagged in past reviews.


62-80: LGTM: Well-structured compatibility rules.

The INCOMPATIBLE_COMBINATIONS mapping is clear, comprehensive, and directly supports the validation logic. The JSDoc effectively explains the supported combinations.


169-181: LGTM: Validation properly integrated.

The validation logic is correctly invoked and safeType is consistently used for all type-based className assignments, addressing past concerns about unguarded type+variant combinations.


199-200: LGTM: New variant mappings added correctly.

The className mappings for SimplifiedAccent and Accent variants are properly implemented and align with the SCSS module classes.

src/redux/slices/navbar.ts (1)

87-88: Selector addition looks good

Typed, focused selector aligns with Redux Toolkit best practices and reduces re-renders in consumers. Nice.

src/components/Navbar/NavbarBody/index.tsx (2)

48-50: Good: narrow selector + single isLoggedIn read

Selecting only isNavigationDrawerOpen reduces re-renders; computing isLoggedIn once per render avoids duplicate cookie reads.


63-69: Verify inert support across target browsers

inert is ideal; ensure a polyfill is present for older Safari/Firefox versions if still supported by the app.

Do you ship an inert polyfill globally (e.g., WICG/element-inert)? If not, consider adding one or fallback to aria-hidden on background + focus trap in the drawer.

src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (2)

19-22: Nice: defer ThemeSwitcher with dynamic import

Good perf win; aligns with “dynamic loading for non‑critical components” guideline.


81-92: Security measure already implemented — no action required

The DLS Link component already correctly sets rel="noopener noreferrer" when isNewTab is true (line 63 of Link.tsx). The Button component properly delegates to this Link implementation, so the open-in-new-tab security concern is already addressed in the codebase.

src/components/AppContent/AppContent.module.scss (1)

1-22: LGTM! Previous review concerns fully addressed.

The overlay implementation correctly uses:

  • inset: 0 for modern, concise positioning
  • var(--color-background-backdrop) for theme-aware backdrop color
  • Proper z-index layering verified in previous review
  • Clean transition behavior with the .dimmed modifier

The SCSS follows all coding guidelines and integrates well with the drawer state management in AppContent.tsx.

src/components/AppContent/AppContent.tsx (2)

1-7: LGTM! Clean import additions.

The new imports are properly organized following the project's import ordering guidelines (React/Next, external libraries, internal modules with blank lines between groups). All imports are utilized appropriately for the drawer dimming functionality.


42-49: I'll verify the TypeScript and browser compatibility requirements for the inert attribute by searching the codebase and the web.Add TypeScript type declaration or upgrade @types/react to support the inert attribute.

The code correctly implements inert={isNavigationDrawerOpen || undefined} to prevent interaction with background content. However, React 19 adds support for the inert property as a boolean, but if you're using React 18 or earlier, the type hasn't been added yet to the React TypeScript definitions, and you'll encounter a TypeScript compilation error.

Required action: Either:

  1. Verify your project uses React 19+, or
  2. Add a type declaration in your declarations.d.ts or globals.d.ts:
    declare module 'react' {
      interface HTMLAttributes<T> {
        inert?: boolean | undefined;
      }
    }

Browser compatibility: Inert support in browsers is currently extremely good, with critical assistive technologies also supporting it well, so no polyfill is required for modern browser targets.

…or accessibility and improve project links handling in OurProjectsCollapsible.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

Caution

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

⚠️ Outside diff range comments (1)
src/components/AppContent/AppContent.tsx (1)

21-33: Type props explicitly and add an explicit return type

Avoid any and align with guidelines. Also prefer React.FC per project conventions.

+import React from 'react';
 import classNames from 'classnames';
@@
-interface AppContentProps {
-  Component: any;
-  pageProps: any;
-}
+interface AppContentProps {
+  Component: React.ComponentType<Record<string, unknown>>;
+  pageProps: Record<string, unknown>;
+}
@@
-function AppContent({ Component, pageProps }: AppContentProps) {
+const AppContent: React.FC<AppContentProps> = ({ Component, pageProps }) => {
@@
-}
+};
♻️ Duplicate comments (3)
src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1)

50-54: Verify drawer a11y: role="dialog", aria-modal, focus trap, Escape, focus restore

LanguageContainer should behave like a modal drawer: set role="dialog" and aria-modal, trap focus on open, move focus in, close on Escape, and restore focus to the trigger on close. The trigger exists here; wire a ref to restore focus.

#!/bin/bash
# Check LanguageContainer for dialog semantics and focus management
rg -nC2 -e 'role="dialog"|aria-modal' -e 'focus\(|autoFocus' -e 'Escape' \
  src/components/Navbar/NavigationDrawer/LanguageContainer.tsx

# Optional: find a focus-lock/focus-trap usage
rg -n 'focus-lock|focus-trap' src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (2)

153-156: Fix confirmed: onTriggerClicked is now invoked

The previous no-op was corrected; click now logs and closes as intended.


62-67: Optional: DRY repeated “log + push + close” handlers

onMyQuranClicked duplicates other handlers. Consider a small helper (navigateFromPopover) to reduce repetition. Previously suggested.

+const navigateFromPopover = (url: string, eventName: string) => {
+  logButtonClick(eventName);
+  void router.push(url).then(() => setIsOpen(false));
+};
...
-const onMyQuranClicked = () => {
-  logButtonClick('profile_avatar_my_quran');
-  router.push(getProfileNavigationUrl()).then(() => {
-    setIsOpen(false);
-  });
-};
+const onMyQuranClicked = () => navigateFromPopover(getProfileNavigationUrl(), 'profile_avatar_my_quran');
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f98fb93 and e61d20c.

📒 Files selected for processing (9)
  • src/components/AppContent/AppContent.tsx (4 hunks)
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss (1 hunks)
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (6 hunks)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss (2 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1 hunks)
  • src/components/dls/Button/Button.module.scss (4 hunks)
  • src/components/dls/Button/Button.tsx (4 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

If you encounter a bug in existing code, or the instructions lead to suboptimal or buggy code, add comments starting with "TODO:" outlining the problems.

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Conditional Classes: Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly, and when you do, make them meaningful.
Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.
Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.
Provide meaningful information about the function's behavior and explain unusual behavior and potential pitfalls.

**/*.*: Write short functions that only do one thing.
Follow the single responsibility principle (SRP), which means that a function should have one purpose and perform it effectively.
If a function becomes too long or complex, consider breaking it into smaller, more manageable functions.

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing.
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted.

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior.
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used.

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Button/Button.module.scss
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Rely on Next.js Pages Router for state changes.
Minimize 'use client' usage: Prefer server components and Next.js SSR features.
Minimize 'use client' usage: Use 'use client' only for Web API access in small components.
Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

**/*.{js,jsx,ts,tsx}: Optimize Web Vitals (LCP, CLS, FID)
Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Button/Button.tsx
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks.
Use React.FC for functional components with props.

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Button/Button.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components
Keep components small and focused
Extract reusable logic into custom hooks
Use composition over inheritance
Split large components into smaller, focused ones
Follow the Rules of Hooks
Use custom hooks for reusable logic
Use appropriate dependency arrays in useEffect
Implement cleanup in useEffect when needed
Avoid nested hooks
Use useState for local component state
Avoid prop drilling through proper state management
Implement proper memoization (useMemo, useCallback)
Use React.memo for expensive components
Avoid unnecessary re-renders
Implement proper lazy loading
Use proper key props in lists
Profile and optimize render performance
Show appropriate loading and error states
Handle async errors properly
Show user-friendly error messages
Implement proper fallback UI
Log errors appropriately
Handle edge cases gracefully
Use semantic HTML elements
Implement proper ARIA attributes
Ensure keyboard navigation
Handle focus management
Provide proper alt text for images
Use proper imports/exports
Document complex component logic

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Button/Button.tsx
**/*.tsx

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

Implement proper prop types with TypeScript

**/*.tsx: Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Implement proper error boundaries

React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Button/Button.tsx
**/*.{ts,tsx}

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

Use xstate for complex state logic

**/*.{ts,tsx}: TypeScript: prefer interfaces over type aliases for object shapes; avoid any; add explicit return types for public functions
Error handling: define and use custom error types; use async/await correctly; show user-friendly error messages
Use Redux Toolkit for state management and XState for complex state machines
Implement i18n with next-translate in components and utilities

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Button/Button.tsx
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid using any, prefer unknown for unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Button/Button.tsx
{src,types}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript throughout the codebase with strict configuration

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Button/Button.tsx
src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer React functional components for UI implementation

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Button/Button.tsx
{src,types}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use path aliases @/ for src and @/dls/* for design system imports

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Button/Button.tsx
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize React components by feature and place DLS components under src/components/dls

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Button/Button.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Order imports: React first, then external, then internal; alphabetize within groups with blank lines between groups
Naming: camelCase for variables/functions; PascalCase for types, interfaces, and React components; UPPER_CASE for constants
Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Button/Button.tsx
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier formatting: single quotes, 2-space indentation, 100-character line width, and trailing commas

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Button/Button.module.scss
src/**/*.module.scss

📄 CodeRabbit inference engine (CLAUDE.md)

Use SCSS Modules for component-specific styling

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/dls/Button/Button.module.scss
**/*.module.scss

📄 CodeRabbit inference engine (AGENTS.md)

Use SCSS modules for component styling

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/dls/Button/Button.module.scss
🧠 Learnings (6)
📚 Learning: 2025-08-01T08:50:15.592Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/performance-optimization-rules.mdc:0-0
Timestamp: 2025-08-01T08:50:15.592Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use dynamic loading for non-critical components using src/components/dls/Spinner/Spinner.tsx

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle focus management

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Ensure keyboard navigation

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:22.602Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/react-functional-components.mdc:0-0
Timestamp: 2025-08-01T08:50:22.602Z
Learning: Applies to src/components/**/*.tsx : Use React.FC for functional components with props.

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.tsx : Prefix interfaces for React props with 'Props' (e.g., ButtonProps)

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-10-28T06:07:39.419Z
Learnt from: afifvdin
PR: quran/quran.com-frontend-next#2556
File: src/components/Navbar/NavigationDrawer/LanguageContainer.tsx:68-74
Timestamp: 2025-10-28T06:07:39.419Z
Learning: In the quran.com-frontend-next codebase, when calling addOrUpdateUserPreference for language preferences, the established pattern is to pass PreferenceGroup.LANGUAGE (which resolves to the string 'language') as both the key and group parameters. This is valid because PreferenceGroup is a string enum and this pattern is used consistently across the codebase (e.g., LanguageSelector.tsx).

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
🧬 Code graph analysis (5)
src/components/AppContent/AppContent.tsx (1)
src/redux/slices/navbar.ts (1)
  • selectIsNavigationDrawerOpen (87-88)
src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (2)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (2)
src/utils/eventLogger.ts (1)
  • logButtonClick (44-46)
src/utils/navigation.ts (2)
  • getProfileNavigationUrl (387-389)
  • getLoginNavigationUrl (402-403)
src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (7)
src/redux/slices/defaultSettings.ts (1)
  • selectIsUsingDefaultSettings (47-48)
src/components/dls/Toast/Toast.tsx (1)
  • useToast (86-96)
src/utils/cookies.ts (1)
  • setLocaleCookie (6-11)
src/utils/eventLogger.ts (1)
  • logValueChange (74-85)
src/utils/auth/login.ts (1)
  • isLoggedIn (15-15)
src/utils/auth/api.ts (1)
  • addOrUpdateUserPreference (393-403)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
🔇 Additional comments (6)
src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1)

87-96: Confirm external link new-tab and rel behavior

Ensure NavigationDrawerItem opens external links in a new tab and sets rel="noopener noreferrer" for security. If not, pass isNewTab and rel through here or enforce in the item component.

src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1)

68-74: Language preference persistence call looks correct

Passing PreferenceGroup.LANGUAGE as both key and group matches the codebase convention and types.

Based on learnings

src/components/dls/Button/Button.tsx (1)

62-109: LGTM: variant/type guard and new variants are wired correctly

validateTypeVariantCombination safely falls back to Primary in dev for incompatible pairs; variant class mapping aligns with SCSS counterparts.

If not already, ensure Button.module.scss includes .simplified_accent and .accent with hover/focus-visible states and accessible contrast.

Also applies to: 162-175, 186-194

src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1)

34-46: LGTM: memoized handlers + centralized event names

Callbacks are stable and event names centralized—good for perf and consistency.

src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (1)

33-37: Props typed as interface + React.FC — good

Matches TS/React conventions for component props.

src/components/dls/Button/Button.module.scss (1)

223-231: CSS token --border-radius-rounded is defined; no changes required.

The token is defined globally at src/styles/theme.scss:67 as 15px and is already in use across 60+ components. Both .simplified_base and .accent blocks correctly reference this token, and the border radius will apply as intended. No action needed.

… Update aria attributes and improve project link handling in OurProjectsCollapsible. Adjust SCSS for better viewport handling and transition effects.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1)

55-61: Verify inert attribute TypeScript compatibility (duplicate)

Similar to AppContent.tsx, the inert attribute may cause TypeScript errors as it's not part of React's standard JSX types.

Check for TypeScript compatibility:

#!/bin/bash
# Check for TypeScript errors related to inert
npx tsc --noEmit src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx 2>&1 | grep -i "inert\|Property.*does not exist" || echo "No TypeScript errors found"

If issues arise, use the ref-based approach shown in the AppContent.tsx review comment.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e61d20c and 79b7964.

📒 Files selected for processing (5)
  • src/components/AppContent/AppContent.tsx (4 hunks)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss (2 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

If you encounter a bug in existing code, or the instructions lead to suboptimal or buggy code, add comments starting with "TODO:" outlining the problems.

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Conditional Classes: Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly, and when you do, make them meaningful.
Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.
Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.
Provide meaningful information about the function's behavior and explain unusual behavior and potential pitfalls.

**/*.*: Write short functions that only do one thing.
Follow the single responsibility principle (SRP), which means that a function should have one purpose and perform it effectively.
If a function becomes too long or complex, consider breaking it into smaller, more manageable functions.

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing.
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted.

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior.
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used.

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Rely on Next.js Pages Router for state changes.
Minimize 'use client' usage: Prefer server components and Next.js SSR features.
Minimize 'use client' usage: Use 'use client' only for Web API access in small components.
Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

**/*.{js,jsx,ts,tsx}: Optimize Web Vitals (LCP, CLS, FID)
Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks.
Use React.FC for functional components with props.

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components
Keep components small and focused
Extract reusable logic into custom hooks
Use composition over inheritance
Split large components into smaller, focused ones
Follow the Rules of Hooks
Use custom hooks for reusable logic
Use appropriate dependency arrays in useEffect
Implement cleanup in useEffect when needed
Avoid nested hooks
Use useState for local component state
Avoid prop drilling through proper state management
Implement proper memoization (useMemo, useCallback)
Use React.memo for expensive components
Avoid unnecessary re-renders
Implement proper lazy loading
Use proper key props in lists
Profile and optimize render performance
Show appropriate loading and error states
Handle async errors properly
Show user-friendly error messages
Implement proper fallback UI
Log errors appropriately
Handle edge cases gracefully
Use semantic HTML elements
Implement proper ARIA attributes
Ensure keyboard navigation
Handle focus management
Provide proper alt text for images
Use proper imports/exports
Document complex component logic

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
**/*.tsx

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

Implement proper prop types with TypeScript

**/*.tsx: Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Implement proper error boundaries

React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
**/*.{ts,tsx}

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

Use xstate for complex state logic

**/*.{ts,tsx}: TypeScript: prefer interfaces over type aliases for object shapes; avoid any; add explicit return types for public functions
Error handling: define and use custom error types; use async/await correctly; show user-friendly error messages
Use Redux Toolkit for state management and XState for complex state machines
Implement i18n with next-translate in components and utilities

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid using any, prefer unknown for unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
{src,types}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript throughout the codebase with strict configuration

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer React functional components for UI implementation

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
{src,types}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use path aliases @/ for src and @/dls/* for design system imports

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize React components by feature and place DLS components under src/components/dls

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Order imports: React first, then external, then internal; alphabetize within groups with blank lines between groups
Naming: camelCase for variables/functions; PascalCase for types, interfaces, and React components; UPPER_CASE for constants
Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier formatting: single quotes, 2-space indentation, 100-character line width, and trailing commas

Files:

  • src/components/AppContent/AppContent.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
src/**/*.module.scss

📄 CodeRabbit inference engine (CLAUDE.md)

Use SCSS Modules for component-specific styling

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
**/*.module.scss

📄 CodeRabbit inference engine (AGENTS.md)

Use SCSS modules for component styling

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
🧠 Learnings (5)
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper ARIA attributes

Applied to files:

  • src/components/AppContent/AppContent.tsx
📚 Learning: 2025-08-01T08:50:15.592Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/performance-optimization-rules.mdc:0-0
Timestamp: 2025-08-01T08:50:15.592Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use dynamic loading for non-critical components using src/components/dls/Spinner/Spinner.tsx

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle focus management

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
PR: quran/quran.com-frontend-next#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper key props in lists

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-10-28T06:07:39.419Z
Learnt from: afifvdin
PR: quran/quran.com-frontend-next#2556
File: src/components/Navbar/NavigationDrawer/LanguageContainer.tsx:68-74
Timestamp: 2025-10-28T06:07:39.419Z
Learning: In the quran.com-frontend-next codebase, when calling addOrUpdateUserPreference for language preferences, the established pattern is to pass PreferenceGroup.LANGUAGE (which resolves to the string 'language') as both the key and group parameters. This is valid because PreferenceGroup is a string enum and this pattern is used consistently across the codebase (e.g., LanguageSelector.tsx).

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
🧬 Code graph analysis (4)
src/components/AppContent/AppContent.tsx (1)
src/redux/slices/navbar.ts (1)
  • selectIsNavigationDrawerOpen (87-88)
src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (2)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (7)
src/redux/slices/defaultSettings.ts (1)
  • selectIsUsingDefaultSettings (47-48)
src/components/dls/Toast/Toast.tsx (1)
  • useToast (86-96)
src/utils/cookies.ts (1)
  • setLocaleCookie (6-11)
src/utils/eventLogger.ts (1)
  • logValueChange (74-85)
src/utils/auth/login.ts (1)
  • isLoggedIn (15-15)
src/utils/auth/api.ts (1)
  • addOrUpdateUserPreference (393-403)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
🔇 Additional comments (5)
src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1)

59-77: LGTM - proper async handling and error recovery

The language change flow is well-structured:

  • Awaits the language change before updating the cookie
  • Persists to the server asynchronously without blocking the UI
  • Provides user-friendly error recovery via the toast

The use of PreferenceGroup.LANGUAGE for both key and group parameters is correct per the established codebase pattern.

src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1)

23-126: Excellent refactoring - clean data-driven approach

The component effectively addresses previous code duplication concerns:

  • Centralized projects array eliminates repetitive JSX
  • Stable eventName keys for list items
  • Consistent event logging via the curried handler
  • Proper i18n integration with Trans component

The implementation is maintainable and follows DRY principles.

src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss (1)

4-89: Well-structured SCSS with progressive enhancement

The styling successfully addresses previous review feedback:

  • Dual max-height rules provide fallback for browsers without dvh support
  • min-height: 0 on grid items enables proper inner scrolling
  • overscroll-behavior: contain prevents unwanted scroll chaining
  • Clear, semantic class names for all UI elements
src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1)

72-84: Comprehensive ARIA implementation

The language trigger button has excellent accessibility attributes:

  • aria-expanded announces the drawer state
  • aria-controls links to the panel
  • aria-haspopup="dialog" indicates the interaction pattern
  • Fallback text ensures the button always has a label

Combined with aria-hidden on the background content, this provides a solid accessible experience.

src/components/AppContent/AppContent.tsx (1)

42-50: The inert attribute handling is correct and requires no changes

The verification confirms TypeScript has no issues with the inert attribute. The current implementation using inert={isNavigationDrawerOpen || undefined} is a valid React pattern that correctly:

  • Sets inert="true" when the navigation drawer is open (disabling interaction)
  • Omits the attribute when closed (removing the inert behavior)

The same pattern applies to aria-hidden. No ref-based approach or type augmentations are needed.

@afifvdin afifvdin requested a review from osamasayed October 28, 2025 08:38
@afifvdin afifvdin changed the title Update navbar and navigation drawer with new icons, language selection and theme switcher [QF-3593] Update the burger menu Oct 28, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (3)
src/components/dls/Collapsible/Collapsible.tsx (3)

87-93: Consider conditional rendering for consistency.

For consistency with the Left direction pattern (lines 63-71), the prefix container in the Right direction should also be conditionally rendered to avoid an empty DOM node when prefix is not provided.

Apply this diff:

-              <div
-                className={classNames(styles.prefixContainer, {
-                  [styles.prefixRotated]: shouldRotatePrefixOnToggle && isOpen,
-                })}
-              >
-                {prefix}
-              </div>
+              {prefix && (
+                <div
+                  className={classNames(styles.prefixContainer, {
+                    [styles.prefixRotated]: shouldRotatePrefixOnToggle && isOpen,
+                  })}
+                >
+                  {prefix}
+                </div>
+              )}

50-52: Fix type safety issue with shouldOpen handling.

When shouldOpen is undefined or changes to/from undefined, setIsOpen(shouldOpen) sets the state to undefined, violating the boolean type from useState<boolean>. This creates a type safety issue and could cause unexpected behavior.

Apply this diff:

  useEffect(() => {
-    setIsOpen(shouldOpen);
+    if (shouldOpen !== undefined) {
+      setIsOpen(shouldOpen);
+    }
  }, [shouldOpen]);

10-12: Use interface instead of type for object definitions.

Per coding guidelines, prefer interface over type for object definitions. Both ChildrenRenderProps and Props should be defined as interfaces.

As per coding guidelines.

Apply this diff:

-type ChildrenRenderProps = {
+interface ChildrenRenderProps {
  isOpen: boolean;
-};
+}

-type Props = {
+interface CollapsibleProps {
  title?: React.ReactNode;
  prefix?: React.ReactNode;
  suffix?: React.ReactNode;
  children: ({ isOpen }: ChildrenRenderProps) => React.ReactNode;
  isDefaultOpen?: boolean;
  shouldOpen?: boolean;
  shouldRotatePrefixOnToggle?: boolean;
  shouldRotateSuffixOnToggle?: boolean;
  onOpenChange?: (isOpen: boolean) => void;
  direction?: CollapsibleDirection;
  headerClassName?: string;
  headerLeftClassName?: string;
-};
+}

Then update the component signature on line 34:

-}: Props) => {
+}: CollapsibleProps) => {

Also applies to: 14-27

♻️ Duplicate comments (1)
locales/en/common.json (1)

103-373: Propagate new drawer strings to every locale

The new keys (change-theme, learn, my-quran, read, select-language) only exist in locales/en. All other locales will now surface raw English fallback strings in the drawer, which regresses the experience for non‑English users. Please add these keys to the remaining common.json files (or reuse existing ones if appropriate) before shipping.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 79b7964 and a03bdce.

📒 Files selected for processing (16)
  • locales/en/common.json (5 hunks)
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss (1 hunks)
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (6 hunks)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss (1 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss (1 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss (2 hunks)
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss (1 hunks)
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx (1 hunks)
  • src/components/dls/Button/Button.module.scss (4 hunks)
  • src/components/dls/Button/Button.tsx (2 hunks)
  • src/components/dls/Collapsible/Collapsible.tsx (3 hunks)
  • src/styles/reset.scss (5 hunks)
  • src/styles/theme.scss (5 hunks)
  • src/utils/navigation.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (16)
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

If you encounter a bug in existing code, or the instructions lead to suboptimal or buggy code, add comments starting with "TODO:" outlining the problems.

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Conditional Classes: Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly, and when you do, make them meaningful.
Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.
Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.
Provide meaningful information about the function's behavior and explain unusual behavior and potential pitfalls.

**/*.*: Write short functions that only do one thing.
Follow the single responsibility principle (SRP), which means that a function should have one purpose and perform it effectively.
If a function becomes too long or complex, consider breaking it into smaller, more manageable functions.

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing.
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted.

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior.
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used.

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • locales/en/common.json
  • src/components/dls/Button/Button.module.scss
  • src/styles/reset.scss
  • src/utils/navigation.ts
  • src/styles/theme.scss
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Rely on Next.js Pages Router for state changes.
Minimize 'use client' usage: Prefer server components and Next.js SSR features.
Minimize 'use client' usage: Use 'use client' only for Web API access in small components.
Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

**/*.{js,jsx,ts,tsx}: Optimize Web Vitals (LCP, CLS, FID)
Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks.
Use React.FC for functional components with props.

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components
Keep components small and focused
Extract reusable logic into custom hooks
Use composition over inheritance
Split large components into smaller, focused ones
Follow the Rules of Hooks
Use custom hooks for reusable logic
Use appropriate dependency arrays in useEffect
Implement cleanup in useEffect when needed
Avoid nested hooks
Use useState for local component state
Avoid prop drilling through proper state management
Implement proper memoization (useMemo, useCallback)
Use React.memo for expensive components
Avoid unnecessary re-renders
Implement proper lazy loading
Use proper key props in lists
Profile and optimize render performance
Show appropriate loading and error states
Handle async errors properly
Show user-friendly error messages
Implement proper fallback UI
Log errors appropriately
Handle edge cases gracefully
Use semantic HTML elements
Implement proper ARIA attributes
Ensure keyboard navigation
Handle focus management
Provide proper alt text for images
Use proper imports/exports
Document complex component logic

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.tsx

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

Implement proper prop types with TypeScript

**/*.tsx: Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Implement proper error boundaries

React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.{ts,tsx}

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

Use xstate for complex state logic

**/*.{ts,tsx}: TypeScript: prefer interfaces over type aliases for object shapes; avoid any; add explicit return types for public functions
Error handling: define and use custom error types; use async/await correctly; show user-friendly error messages
Use Redux Toolkit for state management and XState for complex state machines
Implement i18n with next-translate in components and utilities

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid using any, prefer unknown for unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
{src,types}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript throughout the codebase with strict configuration

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer React functional components for UI implementation

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
{src,types}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use path aliases @/ for src and @/dls/* for design system imports

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize React components by feature and place DLS components under src/components/dls

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Order imports: React first, then external, then internal; alphabetize within groups with blank lines between groups
Naming: camelCase for variables/functions; PascalCase for types, interfaces, and React components; UPPER_CASE for constants
Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier formatting: single quotes, 2-space indentation, 100-character line width, and trailing commas

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/dls/Button/Button.module.scss
  • src/styles/reset.scss
  • src/utils/navigation.ts
  • src/styles/theme.scss
src/**/*.module.scss

📄 CodeRabbit inference engine (CLAUDE.md)

Use SCSS Modules for component-specific styling

Files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/dls/Button/Button.module.scss
**/*.module.scss

📄 CodeRabbit inference engine (AGENTS.md)

Use SCSS modules for component styling

Files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/dls/Button/Button.module.scss
locales/**

📄 CodeRabbit inference engine (CLAUDE.md)

Keep translation files under locales/[lang]/ using next-translate conventions

Files:

  • locales/en/common.json
🧠 Learnings (59)
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.tsx : Prefix interfaces for React props with 'Props' (e.g., ButtonProps)

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/components/**/*.{ts,tsx} : Organize React components by feature and place DLS components under src/components/dls

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-10-12T20:12:36.619Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2528
File: src/components/HomePage/ExploreTopicsSection/ExploreTopicsSection.module.scss:40-47
Timestamp: 2025-10-12T20:12:36.619Z
Learning: In `src/components/HomePage/ExploreTopicsSection/ExploreTopicsSection.module.scss`, the `.container` uses `overflow-x: scroll` intentionally. This section is designed as a horizontal carousel that always overflows (even at 700px width), and more topics will be added in the future. The scrollbar-hiding CSS provides the desired UX while maintaining consistent layout behavior.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*Form*.tsx : Implement proper accessibility for forms

Applied to files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Button/Button.module.scss
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Avoid type assertions unless necessary

Applied to files:

  • src/components/dls/Button/Button.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Keep styles close to components

Applied to files:

  • src/components/dls/Button/Button.tsx
📚 Learning: 2025-07-31T15:31:22.667Z
Learnt from: AhmedCodeGuy
Repo: quran/quran.com-frontend-next PR: 2477
File: src/components/QuranReader/TranslationView/TranslationViewCell.module.scss:204-207
Timestamp: 2025-07-31T15:31:22.667Z
Learning: AhmedCodeGuy suggested that the Separator component should be refactored in the future to avoid needing !important declarations for width overrides in contexts like .verseSeparator in TranslationViewCell.module.scss.

Applied to files:

  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Button/Button.module.scss
  • src/styles/reset.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper fallback UI

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/**/*.tsx : Prefer React functional components for UI implementation

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-10-28T09:59:48.894Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2557
File: src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx:88-0
Timestamp: 2025-10-28T09:59:48.894Z
Learning: In src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx, the empty `<div className={styles.separatorContainer} />` rendered when `isModal` is true is required for maintaining consistent spacing in modal view and should not be removed.

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
📚 Learning: 2025-10-07T08:38:28.343Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T08:38:28.343Z
Learning: Applies to **/*.tsx : React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Extract reusable logic into custom hooks

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use custom hooks for reusable logic

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:51:05.924Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/redux-toolkit-best-practices.mdc:0-0
Timestamp: 2025-08-01T08:51:05.924Z
Learning: Applies to src/redux/**/*.ts : Use Redux hooks (useSelector, useDispatch) in components.

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
📚 Learning: 2025-08-01T08:50:22.602Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react-functional-components.mdc:0-0
Timestamp: 2025-08-01T08:50:22.602Z
Learning: Applies to src/components/**/*.tsx : Always use React functional components with hooks.

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Document complex component logic

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use functional components over class components

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-10-18T11:22:53.139Z
Learnt from: jonybekov
Repo: quran/quran.com-frontend-next PR: 2537
File: src/redux/slices/session.ts:36-42
Timestamp: 2025-10-18T11:22:53.139Z
Learning: In Redux selectors, avoid calling functions that read from external state (cookies, localStorage, etc.) like `isLoggedIn()` from utils/auth/login. Instead, use reactive hooks like `useIsLoggedIn` directly in components and keep selectors focused only on Redux state to ensure proper memoization.

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx
📚 Learning: 2025-08-01T08:50:15.592Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/performance-optimization-rules.mdc:0-0
Timestamp: 2025-08-01T08:50:15.592Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use dynamic loading for non-critical components using src/components/dls/Spinner/Spinner.tsx

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:03.171Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/next-js-conventions.mdc:0-0
Timestamp: 2025-08-01T08:50:03.171Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Minimize 'use client' usage: Prefer server components and Next.js SSR features.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper lazy loading

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:03.171Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/next-js-conventions.mdc:0-0
Timestamp: 2025-08-01T08:50:03.171Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Use explicit return types for public functions

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-10-07T08:38:28.343Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T08:38:28.343Z
Learning: Applies to **/*.{ts,tsx} : TypeScript: prefer interfaces over type aliases for object shapes; avoid any; add explicit return types for public functions

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.tsx : Implement proper prop types with TypeScript

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use semantic HTML elements

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:22.602Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react-functional-components.mdc:0-0
Timestamp: 2025-08-01T08:50:22.602Z
Learning: Applies to src/components/**/*.tsx : Use React.FC for functional components with props.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Ensure keyboard navigation

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle focus management

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/use*.{tsx,jsx} : Keep hooks focused and simple

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper ARIA attributes

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Button/Button.module.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Test user interactions

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper memoization (useMemo, useCallback)

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Use arrow functions for callbacks and methods

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid unnecessary re-renders

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-09-19T13:56:15.026Z
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/auth.tsx:189-191
Timestamp: 2025-09-19T13:56:15.026Z
Learning: In the Quran.com frontend codebase, the `resolveSafeRedirect` function in `src/utils/url.ts` is intentionally designed to validate and allow external URLs, particularly for SSO (Single Sign-On) functionality where cross-domain redirects between platforms are required. This is not a security vulnerability but intended behavior for the SSO authentication flow.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/utils/navigation.ts
📚 Learning: 2025-10-22T20:33:55.176Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:44-49
Timestamp: 2025-10-22T20:33:55.176Z
Learning: Preference: In quran.com-frontend-next, keep concise “why” comments for analytics/UX decision points (e.g., guest vs enrolled click handlers) but avoid verbose JSDoc that repeats params/types. Convert multi-line JSDoc to brief inline rationale comments, especially in src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx and similar analytics handlers.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-10-20T15:16:53.776Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx:14-23
Timestamp: 2025-10-20T15:16:53.776Z
Learning: In the quran.com-frontend-next codebase, the `direction` property should be typed as `string` rather than using union types like `'ltr' | 'rtl'` to maintain consistency with the established codebase pattern (e.g., LanguageData interface in src/utils/locale.ts).

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-10-07T08:38:28.343Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T08:38:28.343Z
Learning: Applies to **/*.{ts,tsx} : Implement i18n with next-translate in components and utilities

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper key props in lists

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid prop drilling through proper state management

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Use React Testing Library

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle edge cases gracefully

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-10-22T20:42:09.214Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx:35-59
Timestamp: 2025-10-22T20:42:09.214Z
Learning: Preference for quran.com-frontend-next: keep single-use, page-specific components inline. Example: NotEnrolledMessage in src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx should remain inline; extract only if reused elsewhere.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:49:45.154Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/next-js-app-router-rule.mdc:0-0
Timestamp: 2025-08-01T08:49:45.154Z
Learning: Applies to app/**/*.tsx : Follow Next.js documentation for best practices in data fetching, rendering, and routing

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-10-07T08:38:28.343Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T08:38:28.343Z
Learning: Applies to **/*.module.scss : Use SCSS modules for component styling

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Button/Button.module.scss
  • src/styles/theme.scss
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/**/*.module.scss : Use SCSS Modules for component-specific styling

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Button/Button.module.scss
  • src/styles/theme.scss
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/styles/_constants.scss : Define and import design tokens from src/styles/_constants.scss

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Button/Button.module.scss
  • src/styles/reset.scss
  • src/styles/theme.scss
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/styles/_breakpoints.scss : Use responsive breakpoints defined in src/styles/_breakpoints.scss

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/styles/theme.scss
📚 Learning: 2025-07-31T15:27:27.014Z
Learnt from: AhmedCodeGuy
Repo: quran/quran.com-frontend-next PR: 2477
File: src/components/QuranReader/TranslationView/TranslationViewCell.module.scss:204-207
Timestamp: 2025-07-31T15:27:27.014Z
Learning: The Separator component has base width styles that need to be overridden with !important when used in specific contexts like .verseSeparator in TranslationViewCell.module.scss.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.tsx : Implement proper error boundaries

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-11-02T06:23:21.127Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2554
File: src/components/QuranReader/ContextMenu/styles/ContextMenu.module.scss:137-147
Timestamp: 2025-11-02T06:23:21.127Z
Learning: In quran.com-frontend-next, at exactly 768px, both tablet (min-width: 768px) and smallerThanTablet (max-width: 768px) breakpoint media queries match. CSS cascade order matters: rules inside smallerThanTablet that come after tablet rules will override. This pattern is intentionally used (e.g., .settingsNextToChapter in src/components/QuranReader/ContextMenu/styles/ContextMenu.module.scss) to ensure elements remain visible at the 768px boundary by having smallerThanTablet re-declare display properties after tablet hides them.
<!-- [add_learning]
In src/components/QuranReader/ContextMenu/styles/ContextMenu.module.scss, the .settingsNextToChapter class uses a smallerThanTablet breakpoint after the tablet breakpoint specifically to handle the edge case at exactly 768px where both media queries match. This prevents the settings button from being hidden at that exact viewport width.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Prefer interfaces over types for object definitions

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-10-26T10:22:52.381Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx:60-60
Timestamp: 2025-10-26T10:22:52.381Z
Learning: In src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx, verse references displayed alongside chapter names should use English/Western numerals only, not localized numerals, as per design specifications.

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-10-19T11:34:07.609Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/Verse/PlainVerseText/index.tsx:4-4
Timestamp: 2025-10-19T11:34:07.609Z
Learning: In src/components/Verse/PlainVerseText/index.tsx, the translation for verse titles should be wired directly to the component using next-translate rather than passed as props from parent components, as this ensures the wording from locales is centralized and only needs to be changed in one place.

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:49:10.050Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/comment-usage.mdc:0-0
Timestamp: 2025-08-01T08:49:10.050Z
Learning: Applies to **/*.* : Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.

Applied to files:

  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
📚 Learning: 2025-08-01T08:48:40.766Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/clean-code.mdc:0-0
Timestamp: 2025-08-01T08:48:40.766Z
Learning: Use comments to explain why something is done a certain way

Applied to files:

  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
📚 Learning: 2025-08-01T08:49:10.050Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/comment-usage.mdc:0-0
Timestamp: 2025-08-01T08:49:10.050Z
Learning: Applies to **/*.* : Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.

Applied to files:

  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
📚 Learning: 2025-10-22T20:39:29.339Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: tests/integration/learning-plans/guest-access.spec.ts:3-5
Timestamp: 2025-10-22T20:39:29.339Z
Learning: Repository: quran/quran.com-frontend-next
Context: tests/integration/learning-plans/guest-access.spec.ts and similar focused integration tests
Learning: For focused integration tests that validate specific route behavior, maintainers prefer hard-coded route paths (e.g., LP_URL, FIRST_LESSON_URL) over environment-based URLs to avoid unnecessary complexity.

Applied to files:

  • src/utils/navigation.ts
🧬 Code graph analysis (4)
src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx (2)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logValueChange (74-85)
src/components/Navbar/SettingsDrawer/ThemeSection.tsx (1)
  • themeIcons (20-25)
src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (3)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
src/utils/apiPaths.ts (1)
  • makeDonatePageUrl (301-306)
src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (2)
src/utils/navigation.ts (8)
  • getQuranUrl (46-48)
  • getQuranAndroidUrl (50-52)
  • getQuranIosUrl (54-56)
  • getQuranReflectUrl (42-44)
  • getSunnahUrl (58-60)
  • getNuqayahUrl (62-64)
  • getLegacyQuranUrl (66-68)
  • getCorpusQuranUrl (70-72)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (2)
src/utils/eventLogger.ts (1)
  • logButtonClick (44-46)
src/utils/navigation.ts (2)
  • getProfileNavigationUrl (419-421)
  • getLoginNavigationUrl (434-435)
🔇 Additional comments (25)
src/components/dls/Collapsible/Collapsible.tsx (2)

22-22: Good addition, but note Right direction limitation.

The new shouldRotateSuffixOnToggle prop mirrors the existing prefix rotation pattern, which is good for consistency. However, be aware that suffix rendering is only supported in the Left direction (lines 73-81). The Right direction path (lines 84-95) doesn't render suffix at all, so this prop will have no effect when direction === CollapsibleDirection.Right.

Consider documenting this limitation in a comment or extending Right direction to support suffix rendering for full symmetry.


63-81: Excellent improvement with conditional rendering!

The conditional rendering of prefix and suffix containers prevents empty DOM nodes from being rendered when these props are not provided. This improves both performance and DOM cleanliness. The rotation logic for suffix (shouldRotateSuffixOnToggle && isOpen) nicely mirrors the existing prefix rotation pattern.

src/styles/reset.scss (1)

140-148: LGTM! Quote style normalization is consistent with the PR.

The attribute selector quote changes from double to single quotes align with the broader SCSS quote style normalization across the codebase.

Also applies to: 364-365, 381-381, 393-394

src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss (1)

1-63: LGTM! Proper use of pixel-suffixed variables and solid RTL support.

The module correctly uses -px suffixed CSS variables throughout (e.g., --spacing-medium-px, --font-size-small-px) as per the team's agreement. RTL support is properly implemented with translateX direction flipping.

src/components/Navbar/NavbarBody/NavbarBody.module.scss (2)

1-2: LGTM! Backdrop overlay implementation is sound.

The quote style normalization, positioning context, and overlay implementation align with the navigation drawer dimming requirements. The backdrop uses proper z-index layering and smooth transitions.

Also applies to: 10-10, 12-29


31-33: Verify that clip-path override doesn't break intended icon rendering within NavbarBody.

The svg g { clip-path: none !important; } rule is correctly scoped to .itemsContainer through the SCSS module system and affects SVGs rendered within NavbarBody, including those in ProfileAvatarButton, SearchDrawer, and NavigationDrawer. This impacts multiple icons (menu, search, profile actions, drawer navigation). Manually verify that removing clip-path from all g elements doesn't inadvertently break clipping or masking effects on any of these icons—particularly profile menu icons and drawer navigation items.

src/components/dls/Button/Button.module.scss (2)

3-7: LGTM! Quote style normalization.

The single-quote updates align with the broader SCSS style consistency improvements across the PR.

Also applies to: 190-190


223-271: LGTM! New button variants implemented consistently.

The new .simplified_base, .simplified, .simplified_accent, and .accent variants follow the existing pattern in this file. The use of -px suffixed variables (lines 257-258) complies with the team's guideline for pixel-perfect implementation matching Figma designs.

src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1)

85-95: LGTM! Solid implementation with proper analytics and React patterns.

The component follows React best practices with proper event logging, conditional rendering, and key usage. The data-driven approach with the PROJECTS array and handleProjectClick factory eliminates duplication.

Also applies to: 121-131

src/components/Navbar/NavigationDrawer/NavigationDrawerItem.module.scss (1)

1-1: LGTM! Quote normalization and typography update.

The import quote style change aligns with the PR-wide SCSS consistency improvements, and the semibold font-weight addition enhances the navigation drawer item typography.

Also applies to: 24-24

src/styles/theme.scss (2)

1-4: LGTM! Quote style normalization is consistent.

The single-quote updates in imports, font-family, and data-theme selectors align with the broader SCSS style consistency improvements across the codebase.

Also applies to: 64-64, 113-113, 118-118, 123-123


27-27: LGTM! New design tokens extend the system properly.

The new --spacing-large2-px and --font-size-xxsmall-px custom properties follow the existing naming convention with the -px suffix, supporting pixel-perfect implementations that match Figma designs.

As per coding guidelines

Also applies to: 41-41

src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx (1)

20-87: Nice persistence wiring

Thanks for reusing usePersistPreferenceGroup so theme selections stay synced and logged—this keeps the drawer in line with the settings drawer behaviour.

src/components/dls/Button/Button.tsx (1)

35-128: Variants look consistent

The SimplifiedAccent/Accent variants hook cleanly into the existing class map and stay isolated from type styles. Looks good.

src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss (1)

1-99: Good state coverage

Appreciate the thorough hover/focus checked states and dark-mode overrides here—keeps the theme menu accessible.

src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1)

88-99: Double-check donor link targets the monthly flow

makeDonatePageUrl() defaults to the one-time path in other call sites. Since this CTA says “Become A Monthly Donor”, can you confirm the generated URL lands on the recurring donation checkout? If not, please pass the appropriate flag (or call the monthly helper) so copy and behaviour stay aligned.

src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (3)

33-37: LGTM: Props interface and component typing follow guidelines.

The props are correctly defined as an interface with proper naming (ProfileAvatarButtonProps), and the component is properly typed with React.FC. Default value handling in destructuring is clean and idiomatic.

Based on learnings and coding guidelines.


103-149: LGTM: PopoverMenu implementation is clean and follows DLS patterns.

The popover structure properly wires the new isPopoverPortalled prop, all menu items use consistent handler patterns, and the "My Quran" item correctly integrates IconContainer with IconColor.accent per DLS conventions. The i18n key usage is correct for the English locale.


152-165: LGTM: Login button implementation is accessible and properly wired.

The button includes proper accessibility attributes (tooltip, ariaLabel), the variant change to SimplifiedAccent aligns with the PR's visual updates, and the onClick handler correctly closes the drawer and logs analytics.

src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss (6)

1-2: LGTM: Imports use modern @use syntax.

The imports correctly use @use instead of deprecated @import. The breakpoints import is present but not visibly used in the current code, which suggests it may be used in other parts of the file not shown or reserved for future responsive adjustments.


4-12: LGTM: Viewport height fallback correctly implemented.

The container properly implements the 100vh/100dvh fallback pattern to handle mobile browser chrome issues. The !important on overflow is acceptable here as it needs to override potential conflicting styles from parent components.


14-27: LGTM: Grid layout with proper scrolling fix and transition.

The grid setup with min-height: 0 correctly addresses CSS Grid scrolling issues (as resolved in past comments). The .hide modifier efficiently handles visibility with both opacity and pointer-events, and the transition uses a design token for consistency.


29-38: LGTM: Scrolling behavior and spacing correctly implemented.

The scroll container properly implements min-height: 0, overflow-y: auto, and overscroll-behavior: contain (as resolved in past comments). All spacing uses pixel tokens per project requirements, and logical properties ensure proper RTL support.


40-44: LGTM: Typography and spacing use correct pixel tokens.

The class correctly uses pixel-suffixed design tokens for font-size and spacing, as required by project conventions. Logical properties ensure proper RTL support.


46-89: LGTM: Accordion, CTA, and language trigger styles follow design system conventions.

All classes correctly use:

  • Pixel-suffixed spacing tokens per project requirements
  • Design tokens for colors, borders, and font-weights
  • Logical properties for RTL support
  • Appropriate CSS Grid and Flexbox patterns

The !important on align-items (line 48) is acceptable for overriding accordion component defaults. The SVG path stroke rule (lines 86-88) properly ensures themed icon colors.

@osamasayed osamasayed self-requested a review November 2, 2025 21:54
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (2)
src/components/dls/Collapsible/Collapsible.tsx (2)

50-52: Add undefined check before updating state.

The effect sets isOpen to shouldOpen even when shouldOpen is undefined, which can break the open/closed state when the prop isn't provided.

   useEffect(() => {
-    setIsOpen(shouldOpen);
+    if (shouldOpen !== undefined) {
+      setIsOpen(shouldOpen);
+    }
   }, [shouldOpen]);

14-27: Consider aligning with coding guidelines for types.

The coding guidelines recommend:

  1. Using React.FC for functional components with props.
  2. Prefixing prop interfaces with the component name (e.g., CollapsibleProps instead of just Props).

Based on learnings and coding guidelines.

-type Props = {
+interface CollapsibleProps {
   title?: React.ReactNode;
   // ... rest of props
-};
+}

-const Collapsible = ({
+const Collapsible: React.FC<CollapsibleProps> = ({
   // ... props destructuring
-}: Props) => {
+}) => {

Also applies to: 34-47

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a03bdce and 22274db.

📒 Files selected for processing (1)
  • src/components/dls/Collapsible/Collapsible.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

If you encounter a bug in existing code, or the instructions lead to suboptimal or buggy code, add comments starting with "TODO:" outlining the problems.

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Conditional Classes: Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly, and when you do, make them meaningful.
Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.
Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.
Provide meaningful information about the function's behavior and explain unusual behavior and potential pitfalls.

**/*.*: Write short functions that only do one thing.
Follow the single responsibility principle (SRP), which means that a function should have one purpose and perform it effectively.
If a function becomes too long or complex, consider breaking it into smaller, more manageable functions.

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing.
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted.

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior.
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used.

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Rely on Next.js Pages Router for state changes.
Minimize 'use client' usage: Prefer server components and Next.js SSR features.
Minimize 'use client' usage: Use 'use client' only for Web API access in small components.
Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

**/*.{js,jsx,ts,tsx}: Optimize Web Vitals (LCP, CLS, FID)
Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks.
Use React.FC for functional components with props.

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components
Keep components small and focused
Extract reusable logic into custom hooks
Use composition over inheritance
Split large components into smaller, focused ones
Follow the Rules of Hooks
Use custom hooks for reusable logic
Use appropriate dependency arrays in useEffect
Implement cleanup in useEffect when needed
Avoid nested hooks
Use useState for local component state
Avoid prop drilling through proper state management
Implement proper memoization (useMemo, useCallback)
Use React.memo for expensive components
Avoid unnecessary re-renders
Implement proper lazy loading
Use proper key props in lists
Profile and optimize render performance
Show appropriate loading and error states
Handle async errors properly
Show user-friendly error messages
Implement proper fallback UI
Log errors appropriately
Handle edge cases gracefully
Use semantic HTML elements
Implement proper ARIA attributes
Ensure keyboard navigation
Handle focus management
Provide proper alt text for images
Use proper imports/exports
Document complex component logic

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
**/*.tsx

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

Implement proper prop types with TypeScript

**/*.tsx: Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Implement proper error boundaries

React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{ts,tsx}

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

Use xstate for complex state logic

**/*.{ts,tsx}: TypeScript: prefer interfaces over type aliases for object shapes; avoid any; add explicit return types for public functions
Error handling: define and use custom error types; use async/await correctly; show user-friendly error messages
Use Redux Toolkit for state management and XState for complex state machines
Implement i18n with next-translate in components and utilities

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid using any, prefer unknown for unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
{src,types}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript throughout the codebase with strict configuration

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer React functional components for UI implementation

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
{src,types}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use path aliases @/ for src and @/dls/* for design system imports

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize React components by feature and place DLS components under src/components/dls

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Order imports: React first, then external, then internal; alphabetize within groups with blank lines between groups
Naming: camelCase for variables/functions; PascalCase for types, interfaces, and React components; UPPER_CASE for constants
Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier formatting: single quotes, 2-space indentation, 100-character line width, and trailing commas

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
🧠 Learnings (3)
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/components/**/*.{ts,tsx} : Organize React components by feature and place DLS components under src/components/dls

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.tsx : Prefix interfaces for React props with 'Props' (e.g., ButtonProps)

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Split large components into smaller, focused ones

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
🪛 Biome (2.1.2)
src/components/dls/Collapsible/Collapsible.tsx

[error] 63-63: Static Elements should not be interactive.

To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.

(lint/a11y/noStaticElementInteractions)


[error] 63-63: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 78-83: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 78-83: Static Elements should not be interactive.

To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.

(lint/a11y/noStaticElementInteractions)

🔇 Additional comments (3)
src/components/dls/Collapsible/Collapsible.tsx (3)

22-22: LGTM! Prop addition follows existing pattern.

The shouldRotateSuffixOnToggle prop mirrors the existing shouldRotatePrefixOnToggle pattern and enables consistent rotation behavior for both prefix and suffix elements.


67-75: LGTM! Conditional rendering improves DOM cleanliness.

Wrapping the prefix in a conditional check prevents rendering empty containers when the prefix isn't provided, improving both performance and DOM cleanliness.


77-86: Good conditional rendering, but accessibility concerns remain.

The conditional rendering and rotation logic for the suffix are well-implemented and consistent with the prefix pattern.

However, the static element with onClick lacks keyboard navigation support. The eslint-disable directives at the top suppress these warnings, but the coding guidelines require proper keyboard navigation and ARIA attributes for interactive elements.

As per coding guidelines, interactive elements should be keyboard-accessible. Consider whether this component should support keyboard interaction for the suffix, or if the current approach is acceptable given the wrapping CollapsiblePrimitive.Trigger handles keyboard events for the overall header.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/components/dls/Collapsible/Collapsible.tsx (1)

56-68: Critical: Double-toggle bug still present (duplicate of previous review).

The manual onHeaderClicked handler on line 68 conflicts with CollapsiblePrimitive.Trigger (line 67). Radix's Trigger already toggles the collapsible when clicked, so the additional onClick={onHeaderClicked} causes double-toggling—each click toggles twice, canceling out the action. The collapsible won't open or close.

Remove the manual toggle logic and rely solely on Radix's built-in behavior:

-  const onHeaderClicked = () => setIsOpen((preValue) => !preValue);
-
   const onSuffixClicked = (e: React.MouseEvent<HTMLDivElement>) => {
     e.preventDefault();
     if (!shouldSuffixTrigger) {
       e.stopPropagation();
     }
   };
       <CollapsiblePrimitive.Trigger asChild>
-        <div className={classNames(styles.header, headerClassName)} onClick={onHeaderClicked}>
+        <div className={classNames(styles.header, headerClassName)}>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22274db and 150e600.

📒 Files selected for processing (3)
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1 hunks)
  • src/components/dls/Collapsible/Collapsible.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

If you encounter a bug in existing code, or the instructions lead to suboptimal or buggy code, add comments starting with "TODO:" outlining the problems.

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Conditional Classes: Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly, and when you do, make them meaningful.
Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.
Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.
Provide meaningful information about the function's behavior and explain unusual behavior and potential pitfalls.

**/*.*: Write short functions that only do one thing.
Follow the single responsibility principle (SRP), which means that a function should have one purpose and perform it effectively.
If a function becomes too long or complex, consider breaking it into smaller, more manageable functions.

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing.
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted.

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior.
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used.

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Rely on Next.js Pages Router for state changes.
Minimize 'use client' usage: Prefer server components and Next.js SSR features.
Minimize 'use client' usage: Use 'use client' only for Web API access in small components.
Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

**/*.{js,jsx,ts,tsx}: Optimize Web Vitals (LCP, CLS, FID)
Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks.
Use React.FC for functional components with props.

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components
Keep components small and focused
Extract reusable logic into custom hooks
Use composition over inheritance
Split large components into smaller, focused ones
Follow the Rules of Hooks
Use custom hooks for reusable logic
Use appropriate dependency arrays in useEffect
Implement cleanup in useEffect when needed
Avoid nested hooks
Use useState for local component state
Avoid prop drilling through proper state management
Implement proper memoization (useMemo, useCallback)
Use React.memo for expensive components
Avoid unnecessary re-renders
Implement proper lazy loading
Use proper key props in lists
Profile and optimize render performance
Show appropriate loading and error states
Handle async errors properly
Show user-friendly error messages
Implement proper fallback UI
Log errors appropriately
Handle edge cases gracefully
Use semantic HTML elements
Implement proper ARIA attributes
Ensure keyboard navigation
Handle focus management
Provide proper alt text for images
Use proper imports/exports
Document complex component logic

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
**/*.tsx

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

Implement proper prop types with TypeScript

**/*.tsx: Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Implement proper error boundaries

React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{ts,tsx}

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

Use xstate for complex state logic

**/*.{ts,tsx}: TypeScript: prefer interfaces over type aliases for object shapes; avoid any; add explicit return types for public functions
Error handling: define and use custom error types; use async/await correctly; show user-friendly error messages
Use Redux Toolkit for state management and XState for complex state machines
Implement i18n with next-translate in components and utilities

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid using any, prefer unknown for unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
{src,types}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript throughout the codebase with strict configuration

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer React functional components for UI implementation

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
{src,types}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use path aliases @/ for src and @/dls/* for design system imports

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize React components by feature and place DLS components under src/components/dls

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Order imports: React first, then external, then internal; alphabetize within groups with blank lines between groups
Naming: camelCase for variables/functions; PascalCase for types, interfaces, and React components; UPPER_CASE for constants
Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier formatting: single quotes, 2-space indentation, 100-character line width, and trailing commas

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
🧠 Learnings (8)
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Split large components into smaller, focused ones

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/components/**/*.{ts,tsx} : Organize React components by feature and place DLS components under src/components/dls

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-10-22T20:33:55.176Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:44-49
Timestamp: 2025-10-22T20:33:55.176Z
Learning: Preference: In quran.com-frontend-next, keep concise “why” comments for analytics/UX decision points (e.g., guest vs enrolled click handlers) but avoid verbose JSDoc that repeats params/types. Convert multi-line JSDoc to brief inline rationale comments, especially in src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx and similar analytics handlers.

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-10-22T20:42:09.214Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx:35-59
Timestamp: 2025-10-22T20:42:09.214Z
Learning: Preference for quran.com-frontend-next: keep single-use, page-specific components inline. Example: NotEnrolledMessage in src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx should remain inline; extract only if reused elsewhere.

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper key props in lists

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid unnecessary re-renders

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Profile and optimize render performance

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.tsx : Prefix interfaces for React props with 'Props' (e.g., ButtonProps)

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
🧬 Code graph analysis (2)
src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (1)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (2)
src/utils/navigation.ts (8)
  • getQuranUrl (46-48)
  • getQuranAndroidUrl (50-52)
  • getQuranIosUrl (54-56)
  • getQuranReflectUrl (42-44)
  • getSunnahUrl (58-60)
  • getNuqayahUrl (62-64)
  • getLegacyQuranUrl (66-68)
  • getCorpusQuranUrl (70-72)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
🪛 Biome (2.1.2)
src/components/dls/Collapsible/Collapsible.tsx

[error] 68-68: Static Elements should not be interactive.

To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.

(lint/a11y/noStaticElementInteractions)


[error] 68-68: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 83-88: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 83-88: Static Elements should not be interactive.

To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.

(lint/a11y/noStaticElementInteractions)

🔇 Additional comments (7)
src/components/dls/Collapsible/Collapsible.tsx (1)

72-91: LGTM: Clean conditional rendering for prefix and suffix.

The conditional rendering ensures prefix and suffix containers are only created when needed, and the rotation styling is applied correctly based on isOpen state. This is a good improvement over unconditional rendering.

src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (2)

20-90: LGTM: Well-structured component with clean separation of concerns.

The component follows React best practices:

  • Functional component with proper TypeScript typing
  • Translation setup with next-translate
  • Event logging for analytics
  • Clean separation between header and content
  • Individual click handlers provide clarity for each action

42-49: Verify collapsible behavior after fixing the double-toggle bug.

This component sets shouldSuffixTrigger={true}, expecting the caret icon to trigger the toggle. However, due to the critical double-toggle bug in Collapsible.tsx (see review comments on that file), the collapsible likely won't open or close correctly. Once the bug is fixed in the base component, verify this component behaves as expected.

src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (4)

33-74: LGTM: Excellent use of static constant and centralized URLs.

The PROJECTS array is correctly placed at module scope to prevent re-creation on every render, and all URLs use the centralized helper functions from src/utils/navigation.ts. This follows best practices for performance and maintainability.

Based on learnings.


76-138: LGTM: Clean component structure with proper data-driven rendering.

The component demonstrates good practices:

  • Module-scoped static data
  • TypeScript interfaces for props
  • Translation integration
  • Event logging for analytics
  • Data-driven rendering with .map() and proper key props
  • Centralized URL management

98-105: Verify collapsible behavior after fixing the double-toggle bug.

This component sets shouldSuffixTrigger={true}, expecting the caret icon to trigger the toggle. However, due to the critical double-toggle bug in Collapsible.tsx (see review comments on that file), the collapsible likely won't open or close correctly. Once the bug is fixed in the base component, verify this component behaves as expected—particularly the interaction mentioned in past reviews where clicking the collapsible tip should toggle the state.


85-91: Apply early return pattern per coding guidelines.

The conditional logic can be simplified using early returns for better readability.

As per coding guidelines.

   const onOpenChange = (isOpen: boolean) => {
-    if (isOpen) {
+    if (!isOpen) {
+      logEvent('navigation_drawer_our_projects_collapsed');
+      return;
+    }
-      logEvent('navigation_drawer_our_projects_expanded');
-      return;
-    }
-    logEvent('navigation_drawer_our_projects_collapsed');
+    logEvent('navigation_drawer_our_projects_expanded');
   };
⛔ Skipped due to learnings
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/coding-guidelines---early-returns-and-conditionals.mdc:0-0
Timestamp: 2025-08-01T08:49:03.227Z
Learning: Applies to **/*.* : Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T08:38:28.343Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Use arrow functions for callbacks and methods

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (2)
src/components/Navbar/NavbarBody/index.tsx (2)

51-61: Wrap callbacks in useCallback to prevent unnecessary re-renders.

The openNavigationDrawer and openSearchDrawer functions are recreated on every render. Since they're passed to child Button components, this can cause unnecessary re-renders.

Apply this diff to memoize the callbacks:

+import { memo, useCallback } from 'react';
-import { memo } from 'react';

-  const openNavigationDrawer = () => {
+  const openNavigationDrawer = useCallback(() => {
     logDrawerOpenEvent('navigation');
     dispatch({ type: setIsNavigationDrawerOpen.type, payload: true });
-  };
+  }, [dispatch]);

-  const openSearchDrawer = () => {
+  const openSearchDrawer = useCallback(() => {
     logDrawerOpenEvent('search');
     dispatch({ type: setIsSearchDrawerOpen.type, payload: true });
     // reset the disable transition state
     dispatch({ type: setDisableSearchDrawerTransition.type, payload: false });
-  };
+  }, [dispatch]);

As per coding guidelines.


45-104: Consider splitting this component to meet the 30-line function guideline.

The NavbarBody component is approximately 60 lines, exceeding the coding guideline of ≤30 lines per function. While the logic is straightforward, consider extracting sub-components or hooks to improve maintainability:

  • Extract the right CTA section into a separate NavbarRightCTA component
  • Move drawer-opening logic into a custom hook (e.g., useNavbarDrawers)

As per coding guidelines.

♻️ Duplicate comments (1)
src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (1)

34-40: Apply early return pattern per coding guidelines.

The onOpenChange handler can be simplified by inverting the condition to log the collapsed event first when isOpen is false, then proceed with the expanded event.

As per coding guidelines.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 095846c and 3b7336b.

📒 Files selected for processing (8)
  • src/components/Navbar/NavbarBody/index.tsx (3 hunks)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss (1 hunks)
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss (2 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1 hunks)
  • src/components/dls/IconContainer/IconContainer.tsx (2 hunks)
  • src/utils/navigation.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

If you encounter a bug in existing code, or the instructions lead to suboptimal or buggy code, add comments starting with "TODO:" outlining the problems.

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Conditional Classes: Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly, and when you do, make them meaningful.
Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.
Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.
Provide meaningful information about the function's behavior and explain unusual behavior and potential pitfalls.

**/*.*: Write short functions that only do one thing.
Follow the single responsibility principle (SRP), which means that a function should have one purpose and perform it effectively.
If a function becomes too long or complex, consider breaking it into smaller, more manageable functions.

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing.
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted.

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior.
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used.

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/utils/navigation.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
  • src/components/dls/IconContainer/IconContainer.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Rely on Next.js Pages Router for state changes.
Minimize 'use client' usage: Prefer server components and Next.js SSR features.
Minimize 'use client' usage: Use 'use client' only for Web API access in small components.
Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

**/*.{js,jsx,ts,tsx}: Optimize Web Vitals (LCP, CLS, FID)
Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/utils/navigation.ts
  • src/components/dls/IconContainer/IconContainer.tsx
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks.
Use React.FC for functional components with props.

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components
Keep components small and focused
Extract reusable logic into custom hooks
Use composition over inheritance
Split large components into smaller, focused ones
Follow the Rules of Hooks
Use custom hooks for reusable logic
Use appropriate dependency arrays in useEffect
Implement cleanup in useEffect when needed
Avoid nested hooks
Use useState for local component state
Avoid prop drilling through proper state management
Implement proper memoization (useMemo, useCallback)
Use React.memo for expensive components
Avoid unnecessary re-renders
Implement proper lazy loading
Use proper key props in lists
Profile and optimize render performance
Show appropriate loading and error states
Handle async errors properly
Show user-friendly error messages
Implement proper fallback UI
Log errors appropriately
Handle edge cases gracefully
Use semantic HTML elements
Implement proper ARIA attributes
Ensure keyboard navigation
Handle focus management
Provide proper alt text for images
Use proper imports/exports
Document complex component logic

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
**/*.tsx

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

Implement proper prop types with TypeScript

**/*.tsx: Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Implement proper error boundaries

React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
**/*.{ts,tsx}

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

Use xstate for complex state logic

**/*.{ts,tsx}: TypeScript: prefer interfaces over type aliases for object shapes; avoid any; add explicit return types for public functions
Error handling: define and use custom error types; use async/await correctly; show user-friendly error messages
Use Redux Toolkit for state management and XState for complex state machines
Implement i18n with next-translate in components and utilities

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/utils/navigation.ts
  • src/components/dls/IconContainer/IconContainer.tsx
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid using any, prefer unknown for unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/utils/navigation.ts
  • src/components/dls/IconContainer/IconContainer.tsx
{src,types}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript throughout the codebase with strict configuration

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/utils/navigation.ts
  • src/components/dls/IconContainer/IconContainer.tsx
src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer React functional components for UI implementation

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
{src,types}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use path aliases @/ for src and @/dls/* for design system imports

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/utils/navigation.ts
  • src/components/dls/IconContainer/IconContainer.tsx
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize React components by feature and place DLS components under src/components/dls

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/IconContainer/IconContainer.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Order imports: React first, then external, then internal; alphabetize within groups with blank lines between groups
Naming: camelCase for variables/functions; PascalCase for types, interfaces, and React components; UPPER_CASE for constants
Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/utils/navigation.ts
  • src/components/dls/IconContainer/IconContainer.tsx
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier formatting: single quotes, 2-space indentation, 100-character line width, and trailing commas

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/utils/navigation.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
  • src/components/dls/IconContainer/IconContainer.tsx
src/**/*.module.scss

📄 CodeRabbit inference engine (CLAUDE.md)

Use SCSS Modules for component-specific styling

Files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
**/*.module.scss

📄 CodeRabbit inference engine (AGENTS.md)

Use SCSS modules for component styling

Files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
🧠 Learnings (26)
📓 Common learnings
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T08:38:28.343Z
Learning: Applies to **/*.{ts,tsx} : Implement i18n with next-translate in components and utilities
📚 Learning: 2025-10-18T11:22:53.139Z
Learnt from: jonybekov
Repo: quran/quran.com-frontend-next PR: 2537
File: src/redux/slices/session.ts:36-42
Timestamp: 2025-10-18T11:22:53.139Z
Learning: In Redux selectors, avoid calling functions that read from external state (cookies, localStorage, etc.) like `isLoggedIn()` from utils/auth/login. Instead, use reactive hooks like `useIsLoggedIn` directly in components and keep selectors focused only on Redux state to ensure proper memoization.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid unnecessary re-renders

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-08-01T08:51:05.924Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/redux-toolkit-best-practices.mdc:0-0
Timestamp: 2025-08-01T08:51:05.924Z
Learning: Applies to src/redux/**/*.ts : Use selectors for accessing state in components.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-10-07T08:38:28.343Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T08:38:28.343Z
Learning: Applies to **/*.tsx : React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/use*.{tsx,jsx} : Keep hooks focused and simple

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper memoization (useMemo, useCallback)

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid prop drilling through proper state management

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:51:05.924Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/redux-toolkit-best-practices.mdc:0-0
Timestamp: 2025-08-01T08:51:05.924Z
Learning: Applies to src/redux/**/*.ts : Use Redux hooks (useSelector, useDispatch) in components.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Split large components into smaller, focused ones

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
📚 Learning: 2025-08-01T08:49:03.227Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/coding-guidelines---early-returns-and-conditionals.mdc:0-0
Timestamp: 2025-08-01T08:49:03.227Z
Learning: Applies to **/*.* : Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
📚 Learning: 2025-10-07T08:38:28.343Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T08:38:28.343Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/components/**/*.{ts,tsx} : Organize React components by feature and place DLS components under src/components/dls

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-10-22T20:33:55.176Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:44-49
Timestamp: 2025-10-22T20:33:55.176Z
Learning: Preference: In quran.com-frontend-next, keep concise “why” comments for analytics/UX decision points (e.g., guest vs enrolled click handlers) but avoid verbose JSDoc that repeats params/types. Convert multi-line JSDoc to brief inline rationale comments, especially in src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx and similar analytics handlers.

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-10-22T20:42:09.214Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx:35-59
Timestamp: 2025-10-22T20:42:09.214Z
Learning: Preference for quran.com-frontend-next: keep single-use, page-specific components inline. Example: NotEnrolledMessage in src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx should remain inline; extract only if reused elsewhere.

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper key props in lists

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Profile and optimize render performance

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-10-22T20:39:29.339Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: tests/integration/learning-plans/guest-access.spec.ts:3-5
Timestamp: 2025-10-22T20:39:29.339Z
Learning: Repository: quran/quran.com-frontend-next
Context: tests/integration/learning-plans/guest-access.spec.ts and similar focused integration tests
Learning: For focused integration tests that validate specific route behavior, maintainers prefer hard-coded route paths (e.g., LP_URL, FIRST_LESSON_URL) over environment-based URLs to avoid unnecessary complexity.

Applied to files:

  • src/utils/navigation.ts
📚 Learning: 2025-09-19T13:56:15.026Z
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/auth.tsx:189-191
Timestamp: 2025-09-19T13:56:15.026Z
Learning: In the Quran.com frontend codebase, the `resolveSafeRedirect` function in `src/utils/url.ts` is intentionally designed to validate and allow external URLs, particularly for SSO (Single Sign-On) functionality where cross-domain redirects between platforms are required. This is not a security vulnerability but intended behavior for the SSO authentication flow.

Applied to files:

  • src/utils/navigation.ts
📚 Learning: 2025-10-12T20:12:36.619Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2528
File: src/components/HomePage/ExploreTopicsSection/ExploreTopicsSection.module.scss:40-47
Timestamp: 2025-10-12T20:12:36.619Z
Learning: In `src/components/HomePage/ExploreTopicsSection/ExploreTopicsSection.module.scss`, the `.container` uses `overflow-x: scroll` intentionally. This section is designed as a horizontal carousel that always overflows (even at 700px width), and more topics will be added in the future. The scrollbar-hiding CSS provides the desired UX while maintaining consistent layout behavior.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Keep styles close to components

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/**/*.module.scss : Use SCSS Modules for component-specific styling

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
📚 Learning: 2025-08-01T08:48:57.410Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/codequality.mdc:0-0
Timestamp: 2025-08-01T08:48:57.410Z
Learning: Don't suggest whitespace changes.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
📚 Learning: 2025-07-31T15:31:22.667Z
Learnt from: AhmedCodeGuy
Repo: quran/quran.com-frontend-next PR: 2477
File: src/components/QuranReader/TranslationView/TranslationViewCell.module.scss:204-207
Timestamp: 2025-07-31T15:31:22.667Z
Learning: AhmedCodeGuy suggested that the Separator component should be refactored in the future to avoid needing !important declarations for width overrides in contexts like .verseSeparator in TranslationViewCell.module.scss.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/styles/_breakpoints.scss : Use responsive breakpoints defined in src/styles/_breakpoints.scss

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
📚 Learning: 2025-11-02T06:23:21.137Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2554
File: src/components/QuranReader/ContextMenu/styles/ContextMenu.module.scss:137-147
Timestamp: 2025-11-02T06:23:21.137Z
Learning: In quran.com-frontend-next, at exactly 768px, both tablet (min-width: 768px) and smallerThanTablet (max-width: 768px) breakpoint media queries match. CSS cascade order matters: rules inside smallerThanTablet that come after tablet rules will override. This pattern is intentionally used (e.g., .settingsNextToChapter in src/components/QuranReader/ContextMenu/styles/ContextMenu.module.scss) to ensure elements remain visible at the 768px boundary by having smallerThanTablet re-declare display properties after tablet hides them.
<!-- [add_learning]
In src/components/QuranReader/ContextMenu/styles/ContextMenu.module.scss, the .settingsNextToChapter class uses a smallerThanTablet breakpoint after the tablet breakpoint specifically to handle the edge case at exactly 768px where both media queries match. This prevents the settings button from being hidden at that exact viewport width.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss
🧬 Code graph analysis (4)
src/components/Navbar/NavbarBody/index.tsx (2)
src/redux/slices/navbar.ts (1)
  • selectIsNavigationDrawerOpen (87-88)
src/utils/auth/login.ts (1)
  • isLoggedIn (15-15)
src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (2)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/utils/navigation.ts (4)
  • DEVELOPERS_URL (61-61)
  • PRODUCT_UPDATES_URL (62-62)
  • EXTERNAL_ROUTES (42-54)
  • SUPPORT_URL (63-63)
src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx (2)
src/utils/navigation.ts (5)
  • LEARNING_PLANS_URL (57-57)
  • getProfileNavigationUrl (442-444)
  • RADIO_URL (58-58)
  • RECITERS_URL (59-59)
  • ABOUT_US_URL (60-60)
src/utils/eventLogger.ts (1)
  • logButtonClick (44-46)
src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (2)
src/utils/navigation.ts (2)
  • QURAN_URL (56-56)
  • EXTERNAL_ROUTES (42-54)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
🔇 Additional comments (12)
src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss (1)

16-22: LGTM!

Pixel-value variables (all -px suffixed) are correctly applied throughout, per the coding guidelines. RTL transform behavior is properly implemented with the [dir='rtl'] selector flip. The .show state correctly snapshots the container into view.

src/components/dls/IconContainer/IconContainer.tsx (1)

14-14: LGTM! Clean addition following established patterns.

The new accent color option is correctly integrated:

  • Enum value follows naming convention (line 14)
  • Conditional class logic matches the pattern used for secondary and tertiary colors, requiring shouldForceSetColors (line 48)
  • Type-safe and purely additive change

Also applies to: 48-48

src/utils/navigation.ts (2)

42-54: LGTM! EXTERNAL_ROUTES centralizes external URLs effectively.

This object successfully consolidates external project URLs in one location, improving maintainability and reducing duplication across the codebase.


65-95: Remove unused getter functions that return only hardcoded string literals.

These eight getter functions (lines 65–95) are not used anywhere in the codebase and return only hardcoded values without parameters or logic. They create unnecessary duplication with existing constants and should be removed:

  • getQuranReflectUrl() duplicates EXTERNAL_ROUTES.QURAN_REFLECT (with inconsistent trailing slash)
  • getQuranUrl() duplicates QURAN_URL constant (line 56)
  • Remaining functions (getQuranAndroidUrl, getQuranIosUrl, getSunnahUrl, getNuqayahUrl, getLegacyQuranUrl, getCorpusQuranUrl) duplicate values in EXTERNAL_ROUTES (lines 42–54)

Since these functions have zero usages elsewhere in the codebase, they can be safely removed. Replace any internal references with the existing EXTERNAL_ROUTES object or QURAN_URL constant directly.

⛔ Skipped due to learnings
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: tests/integration/learning-plans/guest-access.spec.ts:3-5
Timestamp: 2025-10-22T20:39:29.339Z
Learning: Repository: quran/quran.com-frontend-next
Context: tests/integration/learning-plans/guest-access.spec.ts and similar focused integration tests
Learning: For focused integration tests that validate specific route behavior, maintainers prefer hard-coded route paths (e.g., LP_URL, FIRST_LESSON_URL) over environment-based URLs to avoid unnecessary complexity.
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:44-49
Timestamp: 2025-10-22T20:33:55.176Z
Learning: Preference: In quran.com-frontend-next, keep concise “why” comments for analytics/UX decision points (e.g., guest vs enrolled click handlers) but avoid verbose JSDoc that repeats params/types. Convert multi-line JSDoc to brief inline rationale comments, especially in src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx and similar analytics handlers.
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/auth.tsx:189-191
Timestamp: 2025-09-19T13:56:15.026Z
Learning: In the Quran.com frontend codebase, the `resolveSafeRedirect` function in `src/utils/url.ts` is intentionally designed to validate and allow external URLs, particularly for SSO (Single Sign-On) functionality where cross-domain redirects between platforms are required. This is not a security vulnerability but intended behavior for the SSO authentication flow.
src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx (2)

61-72: Verify duplicate icon usage for "Quran Radio" and "Reciters".

Both navigation items use the same IconHeadphones icon:

  • Line 63: "Quran Radio" → IconHeadphones
  • Line 69: "Reciters" → IconHeadphones

While both features are audio-related and this may be intentional, it could cause visual confusion in the UI. Please confirm this is the intended design.

If different icons are needed, consider using distinct icons to improve visual differentiation between these two menu items.


81-106: LGTM! Component structure and composition are well-organized.

The component correctly:

  • Maps over navigation items with proper keys
  • Logs click events for analytics
  • Composes collapsible sections with forwarded styling props
  • Uses appropriate hooks for dynamic content
src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (2)

24-65: LGTM! PROJECTS array is correctly placed at module scope.

The PROJECTS constant is properly defined outside the component at module scope, preventing unnecessary recreation on every render. This addresses the performance concern raised in previous reviews.

Based on learnings.


76-82: Apply early return pattern per coding guidelines.

The onOpenChange handler should invert the condition to avoid the nested structure and improve readability.

As per coding guidelines.

Apply this diff:

   const onOpenChange = (isOpen: boolean) => {
-    if (isOpen) {
+    if (!isOpen) {
+      logEvent('navigation_drawer_our_projects_collapsed');
+      return;
+    }
-      logEvent('navigation_drawer_our_projects_expanded');
-      return;
-    }
-    logEvent('navigation_drawer_our_projects_collapsed');
+    logEvent('navigation_drawer_our_projects_expanded');
   };
⛔ Skipped due to learnings
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T08:38:28.343Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:44-49
Timestamp: 2025-10-22T20:33:55.176Z
Learning: Preference: In quran.com-frontend-next, keep concise “why” comments for analytics/UX decision points (e.g., guest vs enrolled click handlers) but avoid verbose JSDoc that repeats params/types. Convert multi-line JSDoc to brief inline rationale comments, especially in src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx and similar analytics handlers.
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Keep components small and focused
src/components/Navbar/NavigationDrawer/NavigationDrawer.module.scss (2)

1-2: LGTM! Quote style aligns with Prettier configuration.

The change from double to single quotes in @use statements is consistent with the project's Prettier configuration.


28-30: No issues found. The change is appropriate for drawer header layout.

CSS Modules scope .centerVertically to the NavigationDrawer component exclusively. Adding width: 100% ensures the drawer header flex container spans its full parent width—consistent with the drawer's .headerContentContainer which already uses width: 100%. This is an intentional design choice for the drawer header, not an unintended side effect. The separate NavbarBody module remains unaffected.

src/components/Navbar/NavbarBody/index.tsx (2)

48-49: Excellent improvements addressing past feedback!

Using the scoped selectIsNavigationDrawerOpen selector and computing loggedIn once per render properly addresses the previous review comments about avoiding unnecessary re-renders and duplicate function calls.


64-69: Address missing type support and browser compatibility for the inert attribute.

The code compiles without errors because strict: false in tsconfig.json suppresses TypeScript errors, but this masks an underlying issue:

  1. React 18 lacks native inert support — The attribute will cause type errors if strict mode is enabled or on TypeScript/React updates
  2. Browser support mismatchinert requires Chrome 102+, Firefox 112+, Safari 15.5+, but the project targets es5 (ancient browsers), creating a compatibility gap
  3. No type augmentation — The proper fix is to add type augmentation to HTMLAttributes or use a polyfill

Recommended actions:

  • Add type augmentation for inert in types/global.d.ts or use @types/wicg-inert
  • Verify target browsers actually support inert (or add polyfill)
  • Consider upgrading to React 19 for native inert support
  • Update target from es5 to a modern ES version if browser support allows
⛔ Skipped due to learnings
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper ARIA attributes
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Test user interactions
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.tsx : Implement proper prop types with TypeScript
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Ensure keyboard navigation
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper fallback UI
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*Form*.tsx : Implement proper accessibility for forms
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use semantic HTML elements
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T08:38:28.343Z
Learning: Applies to **/*.tsx : React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper key props in lists
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2557
File: src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx:88-0
Timestamp: 2025-10-28T09:59:48.894Z
Learning: In src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx, the empty `<div className={styles.separatorContainer} />` rendered when `isModal` is true is required for maintaining consistent spacing in modal view and should not be removed.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss (1)

4-7: Simplify redundant positioning properties.

inset: 0 combined with position: absolute already sets top: 0; right: 0; bottom: 0; left: 0, making the explicit top: 0 and height: 100% redundant. Remove the redundant properties to simplify the rule.

 .languageContainer {
-  top: 0;
-  height: 100%;
   position: absolute;
   inset: 0;
src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (2)

62-68: Wrap onOpenChange in useCallback for proper memoization.

The early return pattern is already correctly implemented. However, per coding guidelines on memoization, this callback should be wrapped in useCallback to prevent unnecessary re-renders of the Collapsible component.

Based on learnings.

+const onOpenChange = useCallback((isOpen: boolean) => {
-const onOpenChange = (isOpen: boolean) => {
   if (isOpen) {
     logEvent('navigation_drawer_more_menu_expanded');
     return;
   }
   logEvent('navigation_drawer_more_menu_collapsed');
-};
+}, []);

Note: The past review comment about inverting the condition is a duplicate—both implementations follow the early return pattern equally well.


71-79: Consider making the entire header clickable.

The shouldSuffixTrigger prop limits the clickable area to only the caret icon. As noted in the existing review comment, the entire header item should ideally be clickable to improve user experience and meet user expectations.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3b7336b and 332be7d.

📒 Files selected for processing (2)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss (1 hunks)
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

If you encounter a bug in existing code, or the instructions lead to suboptimal or buggy code, add comments starting with "TODO:" outlining the problems.

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Conditional Classes: Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly, and when you do, make them meaningful.
Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.
Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.
Provide meaningful information about the function's behavior and explain unusual behavior and potential pitfalls.

**/*.*: Write short functions that only do one thing.
Follow the single responsibility principle (SRP), which means that a function should have one purpose and perform it effectively.
If a function becomes too long or complex, consider breaking it into smaller, more manageable functions.

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing.
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted.

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior.
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used.

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Rely on Next.js Pages Router for state changes.
Minimize 'use client' usage: Prefer server components and Next.js SSR features.
Minimize 'use client' usage: Use 'use client' only for Web API access in small components.
Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

**/*.{js,jsx,ts,tsx}: Optimize Web Vitals (LCP, CLS, FID)
Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks.
Use React.FC for functional components with props.

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components
Keep components small and focused
Extract reusable logic into custom hooks
Use composition over inheritance
Split large components into smaller, focused ones
Follow the Rules of Hooks
Use custom hooks for reusable logic
Use appropriate dependency arrays in useEffect
Implement cleanup in useEffect when needed
Avoid nested hooks
Use useState for local component state
Avoid prop drilling through proper state management
Implement proper memoization (useMemo, useCallback)
Use React.memo for expensive components
Avoid unnecessary re-renders
Implement proper lazy loading
Use proper key props in lists
Profile and optimize render performance
Show appropriate loading and error states
Handle async errors properly
Show user-friendly error messages
Implement proper fallback UI
Log errors appropriately
Handle edge cases gracefully
Use semantic HTML elements
Implement proper ARIA attributes
Ensure keyboard navigation
Handle focus management
Provide proper alt text for images
Use proper imports/exports
Document complex component logic

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
**/*.tsx

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

Implement proper prop types with TypeScript

**/*.tsx: Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Implement proper error boundaries

React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
**/*.{ts,tsx}

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

Use xstate for complex state logic

**/*.{ts,tsx}: TypeScript: prefer interfaces over type aliases for object shapes; avoid any; add explicit return types for public functions
Error handling: define and use custom error types; use async/await correctly; show user-friendly error messages
Use Redux Toolkit for state management and XState for complex state machines
Implement i18n with next-translate in components and utilities

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid using any, prefer unknown for unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
{src,types}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript throughout the codebase with strict configuration

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer React functional components for UI implementation

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
{src,types}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use path aliases @/ for src and @/dls/* for design system imports

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize React components by feature and place DLS components under src/components/dls

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Order imports: React first, then external, then internal; alphabetize within groups with blank lines between groups
Naming: camelCase for variables/functions; PascalCase for types, interfaces, and React components; UPPER_CASE for constants
Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier formatting: single quotes, 2-space indentation, 100-character line width, and trailing commas

Files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
src/**/*.module.scss

📄 CodeRabbit inference engine (CLAUDE.md)

Use SCSS Modules for component-specific styling

Files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
**/*.module.scss

📄 CodeRabbit inference engine (AGENTS.md)

Use SCSS modules for component styling

Files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
🧠 Learnings (10)
📚 Learning: 2025-08-01T08:49:03.227Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/coding-guidelines---early-returns-and-conditionals.mdc:0-0
Timestamp: 2025-08-01T08:49:03.227Z
Learning: Applies to **/*.* : Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
📚 Learning: 2025-10-07T08:38:28.343Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T08:38:28.343Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Functions should be <= 30 lines, prefer early returns, single responsibility, and descriptive names

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
📚 Learning: 2025-10-07T08:38:28.343Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T08:38:28.343Z
Learning: Applies to **/*.tsx : React: use functional components only; extract reusable logic into custom hooks; apply proper memoization (React.memo/useMemo/useCallback)

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper memoization (useMemo, useCallback)

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
📚 Learning: 2025-10-19T11:34:07.609Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/Verse/PlainVerseText/index.tsx:4-4
Timestamp: 2025-10-19T11:34:07.609Z
Learning: In src/components/Verse/PlainVerseText/index.tsx, the translation for verse titles should be wired directly to the component using next-translate rather than passed as props from parent components, as this ensures the wording from locales is centralized and only needs to be changed in one place.

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid unnecessary re-renders

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/styles/_breakpoints.scss : Use responsive breakpoints defined in src/styles/_breakpoints.scss

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper imports/exports

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
📚 Learning: 2025-10-12T20:12:36.619Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2528
File: src/components/HomePage/ExploreTopicsSection/ExploreTopicsSection.module.scss:40-47
Timestamp: 2025-10-12T20:12:36.619Z
Learning: In `src/components/HomePage/ExploreTopicsSection/ExploreTopicsSection.module.scss`, the `.container` uses `overflow-x: scroll` intentionally. This section is designed as a horizontal carousel that always overflows (even at 700px width), and more topics will be added in the future. The scrollbar-hiding CSS provides the desired UX while maintaining consistent layout behavior.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Keep styles close to components

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
🧬 Code graph analysis (1)
src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (2)
src/utils/navigation.ts (4)
  • DEVELOPERS_URL (61-61)
  • PRODUCT_UPDATES_URL (62-62)
  • EXTERNAL_ROUTES (42-54)
  • SUPPORT_URL (63-63)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
🔇 Additional comments (2)
src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss (2)

1-1: Verify utility import usage.

The utility module is imported but no utilities appear to be used in this file (no mixins, functions, or utilities referenced). Confirm this import is necessary or remove it if unused.


3-62: Overall structure looks solid.

Good use of pixel-suffixed design tokens (e.g., --spacing-medium-px, --font-size-small-px), proper RTL support via transform flip, and well-organized state management with the .show modifier. Layout and list item styling are appropriate for the use case.

@afifvdin afifvdin self-assigned this Nov 20, 2025
@osamasayed osamasayed requested a review from Copilot November 23, 2025 12:47
Copilot finished reviewing on behalf of osamasayed November 23, 2025 12:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements a comprehensive redesign of the navigation menu (burger menu), repositioning it from the left to the right side of the navbar and introducing a richer, more organized menu structure with collapsible sections, theme switching, and language selection capabilities.

Key Changes

  • Moved navigation drawer from left to right side with backdrop dimming effect when open
  • Added new menu structure with collapsible "More" and "Our Projects" sections, plus integrated theme switcher and language selector
  • Updated profile dropdown with "My Quran" menu item and reorganized navigation items to include Read, Learn, My Quran, Quran Radio, and Reciters

Reviewed changes

Copilot reviewed 33 out of 38 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
src/utils/navigation.ts Added external route constants and URL helper functions for navigation items
src/styles/themes/*.scss Added new shadow variable (--shadow-flat) and updated quote styles across all themes
src/styles/theme.scss Added new spacing and font-size variables for UI consistency
src/styles/reset.scss Normalized quote styles to use single quotes
src/redux/slices/navbar.ts Added selector for navigation drawer open state
src/hooks/useGetContinueReadingUrl.ts New hook to determine continue reading URL from multiple sources
src/components/dls/IconContainer/* Added new 'accent' color variant for icons
src/components/dls/Collapsible/* Enhanced with suffix rotation and trigger control options
src/components/dls/Button/* Added SimplifiedAccent and Accent button variants with new styling
src/components/Navbar/NavigationDrawer/ThemeSwitcher.tsx New component for theme selection in navigation drawer
src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx New collapsible section listing Quran Foundation projects
src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx New collapsible section for additional menu items
src/components/Navbar/NavigationDrawer/NavigationDrawerList.tsx Main navigation list component with all drawer items
src/components/Navbar/NavigationDrawer/NavigationDrawerItem.tsx Updated to use accent color icons and support custom title styling
src/components/Navbar/NavigationDrawer/LanguageContainer.tsx New slide-in panel for language selection
src/components/Navbar/NavigationDrawer/NavigationDrawerBody/* Refactored to use grid layout with language/theme controls at bottom
src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx Changed drawer side to right and added profile button to header
src/components/Navbar/NavbarBody/* Reordered navigation items and added backdrop dimming when drawer opens
src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx Added "My Quran" menu item and updated login button styling
src/components/AppContent/* Added dimming overlay support for navigation drawer
public/icons/*.svg Added new icon assets for menu items
locales/en/common.json Added new translation keys for menu items

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

♻️ Duplicate comments (1)
src/components/Navbar/NavbarBody/NavbarBody.module.scss (1)

31-34: Add a comment explaining why SVG clip-path must be reset.

The SVG clip-path reset is unusual and likely a workaround for specific SVG rendering behavior within the navbar. Per the coding guidelines, comments should explain the 'why' behind unusual behavior and potential pitfalls. A minimal comment would clarify the intent:

// Reset SVG clip-path to prevent rendering artifacts within navbar
svg,
g {
  clip-path: none;
}

Alternatively, if this addresses a specific upstream SVG component or rendering quirk (similar to the Separator component pattern noted in learnings), consider noting which component or context requires this reset.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 332be7d and 22e4d05.

📒 Files selected for processing (10)
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss (1 hunks)
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (6 hunks)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss (1 hunks)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss (1 hunks)
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss (1 hunks)
  • src/components/dls/Collapsible/Collapsible.tsx (3 hunks)
  • src/utils/navigation.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

If you encounter a bug in existing code, or the instructions lead to suboptimal or buggy code, add comments starting with "TODO:" outlining the problems.

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Conditional Classes: Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly, and when you do, make them meaningful.
Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.
Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.
Provide meaningful information about the function's behavior and explain unusual behavior and potential pitfalls.

**/*.*: Write short functions that only do one thing.
Follow the single responsibility principle (SRP), which means that a function should have one purpose and perform it effectively.
If a function becomes too long or complex, consider breaking it into smaller, more manageable functions.

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing.
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted.

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior.
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used.

Files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
src/**/*.module.scss

📄 CodeRabbit inference engine (CLAUDE.md)

Use SCSS Modules for component-specific styling

Files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Rely on Next.js Pages Router for state changes.
Minimize 'use client' usage: Prefer server components and Next.js SSR features.
Minimize 'use client' usage: Use 'use client' only for Web API access in small components.
Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

**/*.{js,jsx,ts,tsx}: Optimize Web Vitals (LCP, CLS, FID)
Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks.
Use React.FC for functional components with props.

Files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components
Keep components small and focused
Extract reusable logic into custom hooks
Use composition over inheritance
Split large components into smaller, focused ones
Follow the Rules of Hooks
Use custom hooks for reusable logic
Use appropriate dependency arrays in useEffect
Implement cleanup in useEffect when needed
Avoid nested hooks
Use useState for local component state
Avoid prop drilling through proper state management
Implement proper memoization (useMemo, useCallback)
Use React.memo for expensive components
Avoid unnecessary re-renders
Implement proper lazy loading
Use proper key props in lists
Profile and optimize render performance
Show appropriate loading and error states
Handle async errors properly
Show user-friendly error messages
Implement proper fallback UI
Log errors appropriately
Handle edge cases gracefully
Use semantic HTML elements
Implement proper ARIA attributes
Ensure keyboard navigation
Handle focus management
Provide proper alt text for images
Use proper imports/exports
Document complex component logic

Files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.tsx

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

Implement proper prop types with TypeScript

**/*.tsx: Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Implement proper error boundaries

Files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
**/*.{ts,tsx}

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

Use xstate for complex state logic

Files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid using any, prefer unknown for unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly

Files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
{src,types}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript throughout the codebase with strict configuration

Files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer React functional components for UI implementation

Files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
{src,types}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use path aliases @/ for src and @/dls/* for design system imports

Files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize React components by feature and place DLS components under src/components/dls

Files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
🧠 Learnings (48)
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/**/*.module.scss : Use SCSS Modules for component-specific styling

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-11-17T07:24:45.226Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2567
File: src/components/ReadingProgressPage/ReadingProgressPage.module.scss:208-213
Timestamp: 2025-11-17T07:24:45.226Z
Learning: In the quran.com-frontend-next repository, when the Button component from `src/components/dls/Button/Button.tsx` is used, interactive states (:hover, :focus-visible, :active) are handled by the Button component's internal styles in `src/components/dls/Button/Button.module.scss`. Module-specific SCSS classes applied to Button instances should not duplicate these interactive states.

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-07-31T15:31:22.667Z
Learnt from: AhmedCodeGuy
Repo: quran/quran.com-frontend-next PR: 2477
File: src/components/QuranReader/TranslationView/TranslationViewCell.module.scss:204-207
Timestamp: 2025-07-31T15:31:22.667Z
Learning: AhmedCodeGuy suggested that the Separator component should be refactored in the future to avoid needing !important declarations for width overrides in contexts like .verseSeparator in TranslationViewCell.module.scss.

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-07-31T15:27:27.014Z
Learnt from: AhmedCodeGuy
Repo: quran/quran.com-frontend-next PR: 2477
File: src/components/QuranReader/TranslationView/TranslationViewCell.module.scss:204-207
Timestamp: 2025-07-31T15:27:27.014Z
Learning: The Separator component has base width styles that need to be overridden with !important when used in specific contexts like .verseSeparator in TranslationViewCell.module.scss.

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-11-02T06:23:21.137Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2554
File: src/components/QuranReader/ContextMenu/styles/ContextMenu.module.scss:137-147
Timestamp: 2025-11-02T06:23:21.137Z
Learning: In quran.com-frontend-next, at exactly 768px, both tablet (min-width: 768px) and smallerThanTablet (max-width: 768px) breakpoint media queries match. CSS cascade order matters: rules inside smallerThanTablet that come after tablet rules will override. This pattern is intentionally used (e.g., .settingsNextToChapter in src/components/QuranReader/ContextMenu/styles/ContextMenu.module.scss) to ensure elements remain visible at the 768px boundary by having smallerThanTablet re-declare display properties after tablet hides them.
<!-- [add_learning]
In src/components/QuranReader/ContextMenu/styles/ContextMenu.module.scss, the .settingsNextToChapter class uses a smallerThanTablet breakpoint after the tablet breakpoint specifically to handle the edge case at exactly 768px where both media queries match. This prevents the settings button from being hidden at that exact viewport width.

Applied to files:

  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/components/**/*.{ts,tsx} : Organize React components by feature and place DLS components under src/components/dls

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-10-22T20:33:55.176Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:44-49
Timestamp: 2025-10-22T20:33:55.176Z
Learning: Preference: In quran.com-frontend-next, keep concise “why” comments for analytics/UX decision points (e.g., guest vs enrolled click handlers) but avoid verbose JSDoc that repeats params/types. Convert multi-line JSDoc to brief inline rationale comments, especially in src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx and similar analytics handlers.

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/utils/navigation.ts
📚 Learning: 2025-10-22T20:42:09.214Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx:35-59
Timestamp: 2025-10-22T20:42:09.214Z
Learning: Preference for quran.com-frontend-next: keep single-use, page-specific components inline. Example: NotEnrolledMessage in src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx should remain inline; extract only if reused elsewhere.

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper key props in lists

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid unnecessary re-renders

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Profile and optimize render performance

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Split large components into smaller, focused ones

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:49:03.227Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/coding-guidelines---early-returns-and-conditionals.mdc:0-0
Timestamp: 2025-08-01T08:49:03.227Z
Learning: Applies to **/*.* : Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Use arrow functions for callbacks and methods

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-10-19T11:34:07.609Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/Verse/PlainVerseText/index.tsx:4-4
Timestamp: 2025-10-19T11:34:07.609Z
Learning: In src/components/Verse/PlainVerseText/index.tsx, the translation for verse titles should be wired directly to the component using next-translate rather than passed as props from parent components, as this ensures the wording from locales is centralized and only needs to be changed in one place.

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper memoization (useMemo, useCallback)

Applied to files:

  • src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx
📚 Learning: 2025-08-01T08:49:10.050Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/comment-usage.mdc:0-0
Timestamp: 2025-08-01T08:49:10.050Z
Learning: Applies to **/*.* : Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.

Applied to files:

  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
📚 Learning: 2025-08-01T08:48:40.766Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/clean-code.mdc:0-0
Timestamp: 2025-08-01T08:48:40.766Z
Learning: Use comments to explain why something is done a certain way

Applied to files:

  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
📚 Learning: 2025-08-01T08:49:10.050Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/comment-usage.mdc:0-0
Timestamp: 2025-08-01T08:49:10.050Z
Learning: Applies to **/*.* : Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.

Applied to files:

  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
📚 Learning: 2025-10-12T20:12:36.619Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2528
File: src/components/HomePage/ExploreTopicsSection/ExploreTopicsSection.module.scss:40-47
Timestamp: 2025-10-12T20:12:36.619Z
Learning: In `src/components/HomePage/ExploreTopicsSection/ExploreTopicsSection.module.scss`, the `.container` uses `overflow-x: scroll` intentionally. This section is designed as a horizontal carousel that always overflows (even at 700px width), and more topics will be added in the future. The scrollbar-hiding CSS provides the desired UX while maintaining consistent layout behavior.

Applied to files:

  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-10-28T09:59:48.894Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2557
File: src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx:88-0
Timestamp: 2025-10-28T09:59:48.894Z
Learning: In src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx, the empty `<div className={styles.separatorContainer} />` rendered when `isModal` is true is required for maintaining consistent spacing in modal view and should not be removed.

Applied to files:

  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/styles/_breakpoints.scss : Use responsive breakpoints defined in src/styles/_breakpoints.scss

Applied to files:

  • src/components/Navbar/NavbarBody/NavbarBody.module.scss
  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper fallback UI

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-10-28T06:07:39.429Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/LanguageContainer.tsx:68-74
Timestamp: 2025-10-28T06:07:39.429Z
Learning: In the quran.com-frontend-next codebase, when calling addOrUpdateUserPreference for language preferences, the established pattern is to pass PreferenceGroup.LANGUAGE (which resolves to the string 'language') as both the key and group parameters. This is valid because PreferenceGroup is a string enum and this pattern is used consistently across the codebase (e.g., LanguageSelector.tsx).

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-10-20T15:16:53.776Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx:14-23
Timestamp: 2025-10-20T15:16:53.776Z
Learning: In the quran.com-frontend-next codebase, the `direction` property should be typed as `string` rather than using union types like `'ltr' | 'rtl'` to maintain consistency with the established codebase pattern (e.g., LanguageData interface in src/utils/locale.ts).

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-11-23T09:25:11.475Z
Learnt from: al-imam
Repo: quran/quran.com-frontend-next PR: 2593
File: src/components/Verse/TranslationFeedback/TranslationFeedbackModal.tsx:57-84
Timestamp: 2025-11-23T09:25:11.475Z
Learning: In src/components/Verse/TranslationFeedback/TranslationFeedbackModal.tsx, when the user has no preferred translations, the correct UX per spec is to show a single disabled option with the label "No translations in your preferences" in the Select dropdown. The form validation should remain in place to surface this state to the user, rather than silently disabling the textarea and submit button.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-11-23T10:08:59.766Z
Learnt from: al-imam
Repo: quran/quran.com-frontend-next PR: 2593
File: src/components/Verse/TranslationFeedback/TranslationPreview.tsx:62-62
Timestamp: 2025-11-23T10:08:59.766Z
Learning: In src/components/Verse/TranslationFeedback/TranslationPreview.tsx, the non-null assertion on translation.languageId is safe because the useVerseAndTranslation hook explicitly requests translationFields: 'resource_name,language_id' in its API params, guaranteeing that language_id will always be present in the returned translation data.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper ARIA attributes

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Ensure keyboard navigation

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*Form*.tsx : Implement proper accessibility for forms

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Provide proper alt text for images

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.tsx : Prefix interfaces for React props with 'Props' (e.g., ButtonProps)

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle focus management

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Test user interactions

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper imports/exports

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Keep styles close to components

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss
📚 Learning: 2025-08-01T08:50:22.602Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react-functional-components.mdc:0-0
Timestamp: 2025-08-01T08:50:22.602Z
Learning: Applies to src/components/**/*.tsx : Use React.FC for functional components with props.

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.tsx : Implement proper prop types with TypeScript

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/**/*.tsx : Prefer React functional components for UI implementation

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use functional components over class components

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Prefer interfaces over types for object definitions

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:22.602Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react-functional-components.mdc:0-0
Timestamp: 2025-08-01T08:50:22.602Z
Learning: Applies to src/components/**/*.tsx : Always use React functional components with hooks.

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use semantic HTML elements

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-10-26T10:22:52.381Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx:60-60
Timestamp: 2025-10-26T10:22:52.381Z
Learning: In src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx, verse references displayed alongside chapter names should use English/Western numerals only, not localized numerals, as per design specifications.

Applied to files:

  • src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx
📚 Learning: 2025-10-22T20:39:29.339Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: tests/integration/learning-plans/guest-access.spec.ts:3-5
Timestamp: 2025-10-22T20:39:29.339Z
Learning: Repository: quran/quran.com-frontend-next
Context: tests/integration/learning-plans/guest-access.spec.ts and similar focused integration tests
Learning: For focused integration tests that validate specific route behavior, maintainers prefer hard-coded route paths (e.g., LP_URL, FIRST_LESSON_URL) over environment-based URLs to avoid unnecessary complexity.

Applied to files:

  • src/utils/navigation.ts
📚 Learning: 2025-09-19T13:56:15.026Z
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/auth.tsx:189-191
Timestamp: 2025-09-19T13:56:15.026Z
Learning: In the Quran.com frontend codebase, the `resolveSafeRedirect` function in `src/utils/url.ts` is intentionally designed to validate and allow external URLs, particularly for SSO (Single Sign-On) functionality where cross-domain redirects between platforms are required. This is not a security vulnerability but intended behavior for the SSO authentication flow.

Applied to files:

  • src/utils/navigation.ts
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/styles/_constants.scss : Define and import design tokens from src/styles/_constants.scss

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.tsx : Implement proper error boundaries

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
🧬 Code graph analysis (3)
src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (2)
src/utils/navigation.ts (4)
  • DEVELOPERS_URL (61-61)
  • PRODUCT_UPDATES_URL (62-62)
  • EXTERNAL_ROUTES (42-54)
  • SUPPORT_URL (63-63)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (7)
src/redux/slices/defaultSettings.ts (1)
  • selectIsUsingDefaultSettings (47-48)
src/components/dls/Toast/Toast.tsx (1)
  • useToast (86-96)
src/utils/cookies.ts (1)
  • setLocaleCookie (6-11)
src/utils/eventLogger.ts (1)
  • logValueChange (74-85)
src/utils/auth/login.ts (1)
  • isLoggedIn (17-17)
src/utils/auth/api.ts (1)
  • addOrUpdateUserPreference (384-394)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (2)
src/utils/eventLogger.ts (1)
  • logButtonClick (44-46)
src/utils/navigation.ts (2)
  • getProfileNavigationUrl (410-412)
  • getLoginNavigationUrl (428-429)
🪛 Biome (2.1.2)
src/components/dls/Collapsible/Collapsible.tsx

[error] 88-93: Static Elements should not be interactive.

To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.

(lint/a11y/noStaticElementInteractions)


[error] 88-93: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)

🔇 Additional comments (21)
src/components/Navbar/NavbarBody/NavbarBody.module.scss (1)

10-29: Backdrop overlay and dimming state implementation looks solid.

The position: relative on .itemsContainer correctly establishes a stacking context for the fixed ::before pseudo-element. The backdrop's initial state (opacity: 0, pointer-events: none) is sound, and the .dimmed modifier cleanly toggles visibility and interaction. The comment on line 12 explains the overlay's purpose, which aligns with the coding guidelines.

src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss (1)

1-99: Excellent work addressing all prior review feedback.

All previously identified issues have been resolved:

  • ✅ Transition syntax corrected (line 96: comma-separated properties)
  • ✅ Pixel-based spacing uses -px suffix throughout (e.g., var(--spacing-small-px))
  • ✅ Removed !important declaration from min-width

The styling is well-structured, follows SCSS module best practices, and properly integrates dark mode support. State management for checked/selected/hover/focus states is comprehensive and accessible.

src/components/Navbar/NavbarBody/ProfileAvatarButton.tsx (5)

33-37: LGTM! Props interface and component typing correctly implemented.

The conversion to interface for props and React.FC typing has been properly applied, conforming to TypeScript and React guidelines.


10-10: New imports are correct and properly used.

The added imports (IconContainer, IconColor, BookmarkIcon, setIsNavigationDrawerOpen) support the new My Quran menu item and navigation drawer close behavior.

Also applies to: 13-13, 20-20


62-67: Handler logic is correct.

Both onMyQuranClicked and onLoginButtonClicked properly sequence analytics logging, navigation/state updates, and popover/drawer closing. The temporary routing of My Quran to the profile URL is appropriate until the dedicated feature is implemented.

Also applies to: 97-101


125-133: Menu item implementation is correct.

The updated profile menu item (now using IconPerson) and the new My Quran menu item are properly structured with correct icons, colors, click handlers, and translation keys.


107-107: Login button and popover configuration changes are correct.

The isPopoverPortalled prop is properly propagated to PopoverMenu, and the login button correctly uses ButtonVariant.SimplifiedAccent with the new onLoginButtonClicked handler that sequences drawer closing and login flow initiation.

Also applies to: 157-160

src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss (2)

4-44: ✅ Excellent adherence to pixel value design tokens per osamasayed's requirement.

All new CSS correctly uses pixel-valued design tokens with the -px suffix (e.g., --spacing-medium3-px, --font-size-xxsmall-px, --spacing-large-px). This ensures the code matches Figma specifications exactly.


7-7: The !important declarations are architectural, not due to specificity conflicts—no changes needed.

Verification reveals these declarations are intentional for nested scroll containment. The Drawer has overflow-y: auto !important, the inner NavigationDrawerBody uses overflow: hidden !important to clip scrolling at that level, and the innermost .listItems has overflow-y: auto for the actual scrollable content. This is a deliberate layered scroll pattern, not a symptom of CSS architecture issues. No conflicting rules were found elsewhere, and the grid layout with min-height: 0 follows standard practices for scrollable grid content. The !important flags serve a specific purpose here rather than working around specificity problems.

Likely an incorrect or invalid review comment.

src/components/Navbar/NavigationDrawer/LanguageContainer.module.scss (1)

1-60: LGTM! Clean SCSS module with proper pixel values.

The styling correctly uses pixel-suffixed custom properties as requested, includes proper RTL support, and implements smooth transitions for the slide-in/out behavior. The language list is appropriately scrollable with clear visual states for hover and selection.

src/utils/navigation.ts (1)

42-63: LGTM! Centralized URL constants improve maintainability.

The new EXTERNAL_ROUTES object and URL constants successfully centralize navigation targets, making them reusable across the navigation drawer components and easier to update in the future.

src/components/Navbar/NavigationDrawer/MoreMenuCollapsible.tsx (3)

34-60: LGTM! Static menu configuration at module scope.

The MENUS array is correctly defined at module scope to prevent recreation on every render. The structure uses translation keys that are resolved at render time, following the established pattern.


70-76: LGTM! Early return pattern correctly applied.

The onOpenChange handler properly uses early returns to avoid nested conditions, improving readability per coding guidelines.


79-109: LGTM! Clean collapsible implementation with proper event logging.

The component correctly integrates with the Collapsible design system component, using shouldRotateSuffixOnToggle and shouldSuffixTrigger props for the desired interaction behavior. Event logging is properly wired for all menu items.

src/components/dls/Collapsible/Collapsible.tsx (2)

52-71: LGTM! Proper state management with Radix integration.

The handleOpenChange correctly centralizes state updates and delegates to the parent's onOpenChange callback, fixing the previous double-toggle bug by removing the manual header click handler.


63-68: LGTM! Conditional propagation for suffix clicks.

The onSuffixClicked handler correctly prevents default behavior and conditionally stops propagation based on shouldSuffixTrigger, allowing the suffix to optionally trigger the collapsible toggle.

src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (2)

30-71: LGTM! Clean static configuration with centralized URLs.

The PROJECTS array is correctly defined at module scope and uses the centralized EXTERNAL_ROUTES and QURAN_URL constants, improving maintainability and avoiding recreation on every render.


107-137: LGTM! Data-driven rendering with proper translations.

The component correctly uses a data-driven approach with .map() to render project links, includes proper translation handling via Trans with an embedded external link, and logs analytics events for each project click.

src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (3)

36-57: LGTM! Robust error handling with user-friendly recovery options.

The handleLanguagePersistError provides clear error feedback with actionable Undo/Continue buttons, allowing users to revert or proceed when server persistence fails. This is excellent UX for handling transient failures.


59-77: LGTM! Well-structured language change flow.

The onLanguageChange function correctly orchestrates the language update sequence:

  1. Resets default settings if applicable
  2. Logs the change for analytics
  3. Updates UI language and cookie
  4. Persists to server for logged-in users (with error handling)
  5. Closes the drawer

The fire-and-forget approach for server persistence is appropriate given the error handling and local changes are applied first.


79-123: LGTM! Accessible dialog with proper ARIA attributes.

The language container correctly implements dialog semantics with role="dialog", aria-modal, and aria-labelledby. Language buttons include aria-current to indicate the selected language, improving accessibility for screen reader users.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22e4d05 and 248e666.

📒 Files selected for processing (6)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss (1 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss (1 hunks)
  • src/components/dls/Button/Button.tsx (4 hunks)
  • src/components/dls/Collapsible/Collapsible.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

If you encounter a bug in existing code, or the instructions lead to suboptimal or buggy code, add comments starting with "TODO:" outlining the problems.

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Conditional Classes: Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly, and when you do, make them meaningful.
Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.
Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.
Provide meaningful information about the function's behavior and explain unusual behavior and potential pitfalls.

**/*.*: Write short functions that only do one thing.
Follow the single responsibility principle (SRP), which means that a function should have one purpose and perform it effectively.
If a function becomes too long or complex, consider breaking it into smaller, more manageable functions.

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing.
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted.

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior.
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used.

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Rely on Next.js Pages Router for state changes.
Minimize 'use client' usage: Prefer server components and Next.js SSR features.
Minimize 'use client' usage: Use 'use client' only for Web API access in small components.
Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

**/*.{js,jsx,ts,tsx}: Optimize Web Vitals (LCP, CLS, FID)
Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks.
Use React.FC for functional components with props.

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components
Keep components small and focused
Extract reusable logic into custom hooks
Use composition over inheritance
Split large components into smaller, focused ones
Follow the Rules of Hooks
Use custom hooks for reusable logic
Use appropriate dependency arrays in useEffect
Implement cleanup in useEffect when needed
Avoid nested hooks
Use useState for local component state
Avoid prop drilling through proper state management
Implement proper memoization (useMemo, useCallback)
Use React.memo for expensive components
Avoid unnecessary re-renders
Implement proper lazy loading
Use proper key props in lists
Profile and optimize render performance
Show appropriate loading and error states
Handle async errors properly
Show user-friendly error messages
Implement proper fallback UI
Log errors appropriately
Handle edge cases gracefully
Use semantic HTML elements
Implement proper ARIA attributes
Ensure keyboard navigation
Handle focus management
Provide proper alt text for images
Use proper imports/exports
Document complex component logic

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
**/*.tsx

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

Implement proper prop types with TypeScript

**/*.tsx: Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Implement proper error boundaries

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{ts,tsx}

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

Use xstate for complex state logic

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid using any, prefer unknown for unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
{src,types}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript throughout the codebase with strict configuration

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer React functional components for UI implementation

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
{src,types}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use path aliases @/ for src and @/dls/* for design system imports

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize React components by feature and place DLS components under src/components/dls

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
src/**/*.module.scss

📄 CodeRabbit inference engine (CLAUDE.md)

Use SCSS Modules for component-specific styling

Files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
🧠 Learnings (51)
📚 Learning: 2025-08-01T08:50:15.592Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/performance-optimization-rules.mdc:0-0
Timestamp: 2025-08-01T08:50:15.592Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use dynamic loading for non-critical components using src/components/dls/Spinner/Spinner.tsx

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:03.171Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/next-js-conventions.mdc:0-0
Timestamp: 2025-08-01T08:50:03.171Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Minimize 'use client' usage: Prefer server components and Next.js SSR features.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper lazy loading

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:03.171Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/next-js-conventions.mdc:0-0
Timestamp: 2025-08-01T08:50:03.171Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Use explicit return types for public functions

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.tsx : Implement proper prop types with TypeScript

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/**/*.tsx : Prefer React functional components for UI implementation

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Button/Button.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use semantic HTML elements

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Button/Button.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use functional components over class components

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Button/Button.tsx
📚 Learning: 2025-08-01T08:50:22.602Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react-functional-components.mdc:0-0
Timestamp: 2025-08-01T08:50:22.602Z
Learning: Applies to src/components/**/*.tsx : Use React.FC for functional components with props.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Document complex component logic

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Button/Button.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Ensure keyboard navigation

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper fallback UI

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle focus management

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/use*.{tsx,jsx} : Keep hooks focused and simple

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper ARIA attributes

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-11-17T07:24:45.226Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2567
File: src/components/ReadingProgressPage/ReadingProgressPage.module.scss:208-213
Timestamp: 2025-11-17T07:24:45.226Z
Learning: In the quran.com-frontend-next repository, when the Button component from `src/components/dls/Button/Button.tsx` is used, interactive states (:hover, :focus-visible, :active) are handled by the Button component's internal styles in `src/components/dls/Button/Button.module.scss`. Module-specific SCSS classes applied to Button instances should not duplicate these interactive states.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Test user interactions

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*Form*.tsx : Implement proper accessibility for forms

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-11-23T09:25:11.475Z
Learnt from: al-imam
Repo: quran/quran.com-frontend-next PR: 2593
File: src/components/Verse/TranslationFeedback/TranslationFeedbackModal.tsx:57-84
Timestamp: 2025-11-23T09:25:11.475Z
Learning: In src/components/Verse/TranslationFeedback/TranslationFeedbackModal.tsx, when the user has no preferred translations, the correct UX per spec is to show a single disabled option with the label "No translations in your preferences" in the Select dropdown. The form validation should remain in place to surface this state to the user, rather than silently disabling the textarea and submit button.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper memoization (useMemo, useCallback)

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Use arrow functions for callbacks and methods

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use custom hooks for reusable logic

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Extract reusable logic into custom hooks

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid unnecessary re-renders

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper key props in lists

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-10-28T09:59:48.894Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2557
File: src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx:88-0
Timestamp: 2025-10-28T09:59:48.894Z
Learning: In src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx, the empty `<div className={styles.separatorContainer} />` rendered when `isModal` is true is required for maintaining consistent spacing in modal view and should not be removed.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-09-19T13:56:15.026Z
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/auth.tsx:189-191
Timestamp: 2025-09-19T13:56:15.026Z
Learning: In the Quran.com frontend codebase, the `resolveSafeRedirect` function in `src/utils/url.ts` is intentionally designed to validate and allow external URLs, particularly for SSO (Single Sign-On) functionality where cross-domain redirects between platforms are required. This is not a security vulnerability but intended behavior for the SSO authentication flow.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-10-22T20:33:55.176Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:44-49
Timestamp: 2025-10-22T20:33:55.176Z
Learning: Preference: In quran.com-frontend-next, keep concise “why” comments for analytics/UX decision points (e.g., guest vs enrolled click handlers) but avoid verbose JSDoc that repeats params/types. Convert multi-line JSDoc to brief inline rationale comments, especially in src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx and similar analytics handlers.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-10-20T15:16:53.776Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx:14-23
Timestamp: 2025-10-20T15:16:53.776Z
Learning: In the quran.com-frontend-next codebase, the `direction` property should be typed as `string` rather than using union types like `'ltr' | 'rtl'` to maintain consistency with the established codebase pattern (e.g., LanguageData interface in src/utils/locale.ts).

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-11-23T10:08:59.766Z
Learnt from: al-imam
Repo: quran/quran.com-frontend-next PR: 2593
File: src/components/Verse/TranslationFeedback/TranslationPreview.tsx:62-62
Timestamp: 2025-11-23T10:08:59.766Z
Learning: In src/components/Verse/TranslationFeedback/TranslationPreview.tsx, the non-null assertion on translation.languageId is safe because the useVerseAndTranslation hook explicitly requests translationFields: 'resource_name,language_id' in its API params, guaranteeing that language_id will always be present in the returned translation data.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid prop drilling through proper state management

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Use React Testing Library

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle edge cases gracefully

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Avoid using `any`, prefer `unknown` for unknown types

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Avoid type assertions unless necessary

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Button/Button.tsx
📚 Learning: 2025-10-22T20:42:09.214Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx:35-59
Timestamp: 2025-10-22T20:42:09.214Z
Learning: Preference for quran.com-frontend-next: keep single-use, page-specific components inline. Example: NotEnrolledMessage in src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx should remain inline; extract only if reused elsewhere.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/**/*.module.scss : Use SCSS Modules for component-specific styling

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/styles/_constants.scss : Define and import design tokens from src/styles/_constants.scss

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.tsx : Implement proper error boundaries

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-10-12T20:12:36.619Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2528
File: src/components/HomePage/ExploreTopicsSection/ExploreTopicsSection.module.scss:40-47
Timestamp: 2025-10-12T20:12:36.619Z
Learning: In `src/components/HomePage/ExploreTopicsSection/ExploreTopicsSection.module.scss`, the `.container` uses `overflow-x: scroll` intentionally. This section is designed as a horizontal carousel that always overflows (even at 700px width), and more topics will be added in the future. The scrollbar-hiding CSS provides the desired UX while maintaining consistent layout behavior.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-07-31T15:31:22.667Z
Learnt from: AhmedCodeGuy
Repo: quran/quran.com-frontend-next PR: 2477
File: src/components/QuranReader/TranslationView/TranslationViewCell.module.scss:204-207
Timestamp: 2025-07-31T15:31:22.667Z
Learning: AhmedCodeGuy suggested that the Separator component should be refactored in the future to avoid needing !important declarations for width overrides in contexts like .verseSeparator in TranslationViewCell.module.scss.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/dls/Button/Button.tsx
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
📚 Learning: 2025-07-31T15:27:27.014Z
Learnt from: AhmedCodeGuy
Repo: quran/quran.com-frontend-next PR: 2477
File: src/components/QuranReader/TranslationView/TranslationViewCell.module.scss:204-207
Timestamp: 2025-07-31T15:27:27.014Z
Learning: The Separator component has base width styles that need to be overridden with !important when used in specific contexts like .verseSeparator in TranslationViewCell.module.scss.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/styles/_breakpoints.scss : Use responsive breakpoints defined in src/styles/_breakpoints.scss

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
📚 Learning: 2025-11-02T06:23:21.137Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2554
File: src/components/QuranReader/ContextMenu/styles/ContextMenu.module.scss:137-147
Timestamp: 2025-11-02T06:23:21.137Z
Learning: In quran.com-frontend-next, at exactly 768px, both tablet (min-width: 768px) and smallerThanTablet (max-width: 768px) breakpoint media queries match. CSS cascade order matters: rules inside smallerThanTablet that come after tablet rules will override. This pattern is intentionally used (e.g., .settingsNextToChapter in src/components/QuranReader/ContextMenu/styles/ContextMenu.module.scss) to ensure elements remain visible at the 768px boundary by having smallerThanTablet re-declare display properties after tablet hides them.
<!-- [add_learning]
In src/components/QuranReader/ContextMenu/styles/ContextMenu.module.scss, the .settingsNextToChapter class uses a smallerThanTablet breakpoint after the tablet breakpoint specifically to handle the edge case at exactly 768px where both media queries match. This prevents the settings button from being hidden at that exact viewport width.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss
  • src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Profile and optimize render performance

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.tsx : Prefix interfaces for React props with 'Props' (e.g., ButtonProps)

Applied to files:

  • src/components/dls/Button/Button.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Keep styles close to components

Applied to files:

  • src/components/dls/Button/Button.tsx
📚 Learning: 2025-08-01T08:50:22.602Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react-functional-components.mdc:0-0
Timestamp: 2025-08-01T08:50:22.602Z
Learning: Applies to src/components/**/*.tsx : Always use React functional components with hooks.

Applied to files:

  • src/components/dls/Button/Button.tsx
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/components/**/*.{ts,tsx} : Organize React components by feature and place DLS components under src/components/dls

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Split large components into smaller, focused ones

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
🪛 Biome (2.1.2)
src/components/dls/Collapsible/Collapsible.tsx

[error] 103-113: Static Elements should not be interactive.

To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.

(lint/a11y/noStaticElementInteractions)


[error] 103-113: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)

🔇 Additional comments (7)
src/components/Navbar/NavigationDrawer/ThemeSwitcher.module.scss (3)

22-79: Hover state mixin and interactive states are well-designed.

The popoverItemHoverState mixin (lines 22–33) consolidates duplicate hover styling and correctly applies theme-aware color/stroke updates. The interaction state selectors (checked, hover, focus) properly layer and chain with minimal duplication. Transitions are correctly specified with comma-separated properties on line 76.


1-20: Incorrect review comment — the suggested design token does not exist.

The codebase does not have a --border-width-hairline-px or any border-width design token. The 1px value is intentional and consistent across the entire design system. Review of 100+ component files shows this is the established convention for hairline borders (e.g., reset.scss line 261, form components, modals, navigation elements). The hardcoded 1px is not a deviation but rather the standardized approach in this codebase.

Likely an incorrect or invalid review comment.


9-14: Based on my investigation, I can now verify the review comment:

Key Findings:

  • PopoverMenu defines .content { min-width: calc(12 * var(--spacing-large)); } at the component level
  • ThemeSwitcher applies contentClassName={styles.popoverContent} directly to this same element
  • Both classes have equal CSS specificity (single class selectors)
  • The min-width: unset; override works via CSS cascade order without !important because equal-specificity rules are resolved by source order

Why the Override Exists:
The override is necessary to allow the theme switcher popover to be narrower and responsive, versus PopoverMenu's default minimum width which is sized for broader menu use cases.

Assessment:
The review comment's concern is valid but the code isn't broken. The override works reliably because:

  1. SCSS modules ensure proper scoping
  2. Both selectors have equal specificity
  3. CSS cascade order resolves the conflict

However, the absence of !important or a clarifying comment makes the intent implicit. Adding a brief comment explaining the override would improve maintainability and prevent future developers from misunderstanding or "fixing" this as a bug.


Document the intent of min-width: unset; to clarify the cascade override.

Add a comment above line 11 explaining why PopoverMenu's default min-width is being reset. Example: /* Override PopoverMenu's default min-width to allow responsive sizing */

This override relies on CSS cascade order (equal specificity) rather than !important, which is acceptable here since both selectors are single classes. A comment will prevent future confusion about whether this is intentional.

src/components/dls/Button/Button.tsx (1)

35-43: New variants and forwardRef wiring look correct

Variant enums map cleanly to SCSS classes, and the forwardRef conversion correctly exposes the underlying <button> ref while preserving existing href vs button behavior. No further changes needed here.

Also applies to: 71-132, 139-207

src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1)

1-4: Drawer body state, a11y wiring, and analytics integration look solid

Language drawer toggling, focus restoration, background hiding (aria-hidden + inert), dynamic ThemeSwitcher loading, and donate CTA logging all align with the intended UX and accessibility requirements. No issues spotted in this component.

Also applies to: 20-29, 31-55, 56-108

src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1)

30-71: Data-driven projects collapsible is clean and maintainable

Static PROJECTS config, centralized URLs, per-item analytics, and render-prop early return on !isOpen make this component straightforward and efficient. The suffix-trigger + rotation props integrate well with the shared Collapsible behavior.

Also applies to: 73-138

src/components/Navbar/NavigationDrawer/NavigationDrawerBody/NavigationDrawerBody.module.scss (1)

3-37: Drawer layout and scroll styling align with the new structure

Grid + inner scrolling with min-height: 0, dvh fallback, pixel-based spacing tokens, and CTA/language trigger classes all look appropriate for the updated drawer UI and respect the Button’s built-in interactive states.

Also applies to: 39-88

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 248e666 and a552946.

📒 Files selected for processing (1)
  • src/components/dls/Collapsible/Collapsible.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

If you encounter a bug in existing code, or the instructions lead to suboptimal or buggy code, add comments starting with "TODO:" outlining the problems.

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Conditional Classes: Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly, and when you do, make them meaningful.
Don't comment on obvious things. Excessive or unclear comments can clutter the codebase and become outdated.
Use comments to convey the 'why' behind specific actions or explain unusual behavior and potential pitfalls.
Provide meaningful information about the function's behavior and explain unusual behavior and potential pitfalls.

**/*.*: Write short functions that only do one thing.
Follow the single responsibility principle (SRP), which means that a function should have one purpose and perform it effectively.
If a function becomes too long or complex, consider breaking it into smaller, more manageable functions.

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing.
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted.

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior.
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used.

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Rely on Next.js Pages Router for state changes.
Minimize 'use client' usage: Prefer server components and Next.js SSR features.
Minimize 'use client' usage: Use 'use client' only for Web API access in small components.
Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

**/*.{js,jsx,ts,tsx}: Optimize Web Vitals (LCP, CLS, FID)
Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks.
Use React.FC for functional components with props.

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components
Keep components small and focused
Extract reusable logic into custom hooks
Use composition over inheritance
Split large components into smaller, focused ones
Follow the Rules of Hooks
Use custom hooks for reusable logic
Use appropriate dependency arrays in useEffect
Implement cleanup in useEffect when needed
Avoid nested hooks
Use useState for local component state
Avoid prop drilling through proper state management
Implement proper memoization (useMemo, useCallback)
Use React.memo for expensive components
Avoid unnecessary re-renders
Implement proper lazy loading
Use proper key props in lists
Profile and optimize render performance
Show appropriate loading and error states
Handle async errors properly
Show user-friendly error messages
Implement proper fallback UI
Log errors appropriately
Handle edge cases gracefully
Use semantic HTML elements
Implement proper ARIA attributes
Ensure keyboard navigation
Handle focus management
Provide proper alt text for images
Use proper imports/exports
Document complex component logic

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
**/*.tsx

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

Implement proper prop types with TypeScript

**/*.tsx: Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Implement proper error boundaries

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{ts,tsx}

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

Use xstate for complex state logic

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid using any, prefer unknown for unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
{src,types}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript throughout the codebase with strict configuration

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer React functional components for UI implementation

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
{src,types}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use path aliases @/ for src and @/dls/* for design system imports

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize React components by feature and place DLS components under src/components/dls

Files:

  • src/components/dls/Collapsible/Collapsible.tsx
🧠 Learnings (19)
📓 Common learnings
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx:33-45
Timestamp: 2025-11-24T12:16:47.248Z
Learning: In src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx, focus restoration on language container close is implemented using languageButtonRef with useEffect (lines 48-52), which correctly restores focus to the trigger button when showLanguageContainer becomes false.
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/components/**/*.{ts,tsx} : Organize React components by feature and place DLS components under src/components/dls

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.tsx : Prefix interfaces for React props with 'Props' (e.g., ButtonProps)

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Split large components into smaller, focused ones

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Ensure keyboard navigation

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper ARIA attributes

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*Form*.tsx : Implement proper accessibility for forms

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper key props in lists

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle focus management

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Test user interactions

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper fallback UI

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid unnecessary re-renders

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-11-17T07:24:45.226Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2567
File: src/components/ReadingProgressPage/ReadingProgressPage.module.scss:208-213
Timestamp: 2025-11-17T07:24:45.226Z
Learning: In the quran.com-frontend-next repository, when the Button component from `src/components/dls/Button/Button.tsx` is used, interactive states (:hover, :focus-visible, :active) are handled by the Button component's internal styles in `src/components/dls/Button/Button.module.scss`. Module-specific SCSS classes applied to Button instances should not duplicate these interactive states.

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement cleanup in useEffect when needed

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid prop drilling through proper state management

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use useState for local component state

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use appropriate dependency arrays in useEffect

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle edge cases gracefully

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-11-24T12:16:47.248Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx:33-45
Timestamp: 2025-11-24T12:16:47.248Z
Learning: In src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx, focus restoration on language container close is implemented using languageButtonRef with useEffect (lines 48-52), which correctly restores focus to the trigger button when showLanguageContainer becomes false.

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
🪛 Biome (2.1.2)
src/components/dls/Collapsible/Collapsible.tsx

[error] 104-114: Static Elements should not be interactive.

To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.

(lint/a11y/noStaticElementInteractions)


[error] 104-114: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)

🔇 Additional comments (7)
src/components/dls/Collapsible/Collapsible.tsx (7)

22-23: LGTM: New props follow conventions.

The new shouldRotateSuffixOnToggle and shouldSuffixTrigger props are well-named and properly typed. The default of shouldSuffixTrigger = false is a safe choice for backward compatibility.

Also applies to: 42-43


52-57: LGTM: State synchronization is correct.

The handleOpenChange function properly synchronizes internal state with the optional external callback, allowing the component to work in both controlled and uncontrolled modes.


59-62: LGTM: Type guard prevents undefined state.

The type guard correctly prevents syncing when shouldOpen is undefined, preserving the component's uncontrolled/default-open behavior when the prop is omitted.


64-69: LGTM: Mouse event propagation control is correct.

The onSuffixClicked handler correctly controls event propagation based on shouldSuffixTrigger: stopping propagation when false (suffix is decorative) and allowing it to bubble to the Trigger when true (suffix should toggle).


87-87: LGTM: Root component properly wired.

The CollapsiblePrimitive.Root correctly uses handleOpenChange to manage both internal state and external callbacks.


89-89: LGTM: Header click handling is correct.

Removing the manual onClick handler resolves the double-toggling issue. Radix's Trigger with asChild properly adds interactive event handlers (including keyboard support) to the header element.


103-117: Static analysis false positive on accessibility.

The linter flags this element for missing keyboard handlers, but this is a false positive. The code correctly uses conditional spread (lines 109-113) to add onKeyDown, role="button", and tabIndex={0} only when shouldSuffixTrigger={true}. Static analysis tools cannot evaluate this runtime condition.

When shouldSuffixTrigger={false}, the suffix is not focusable (no tabIndex) and the onClick only serves to stop event propagation—it's not making the element interactive.

Note: The keyboard handler implementation itself has a bug (flagged separately in lines 71-84), but the conditional application of accessibility attributes here is correct.

Based on coding guidelines, the accessibility implementation follows proper patterns.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

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

⚠️ Outside diff range comments (1)
tests/integration/navigation-and-general-structure/navbar-and-header/general.spec.ts (1)

38-41: Breadcrumb assertion is ineffective; missing matcher and potential null handling

expect(currentSurahInfoText.includes('76. Al-Insan')); does not use any matcher, so the test will not fail even if the text is wrong. Also, textContent() can return null.

Consider something like:

-  const currentSurahInfoText = await currentSurahInfo.textContent();
-  expect(currentSurahInfoText.includes('76. Al-Insan'));
+  const currentSurahInfoText = await currentSurahInfo.textContent();
+  expect(currentSurahInfoText).not.toBeNull();
+  expect(currentSurahInfoText).toContain('76. Al-Insan');

(or use await expect(currentSurahInfo).toContainText('76. Al-Insan'); directly).

♻️ Duplicate comments (1)
src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1)

97-108: Fix rel attribute to include both noopener and noreferrer.

The Link component (src/components/dls/Link/Link.tsx, line 63) currently sets rel='noreferrer' for new tab links, but it should include 'noopener' as well. When target="_blank", the rel attribute must be 'noopener noreferrer' for proper security—noopener prevents the opened page from accessing window.opener.

Update line 63 to:

rel={isNewTab ? 'noopener noreferrer' : undefined}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a552946 and 9f73625.

📒 Files selected for processing (25)
  • src/components/Navbar/Drawer/index.tsx (4 hunks)
  • src/components/Navbar/NavbarBody/index.tsx (4 hunks)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx (2 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1 hunks)
  • src/components/Navbar/SearchDrawer/Header/index.tsx (1 hunks)
  • src/components/Navbar/SearchDrawer/SearchDrawer.tsx (2 hunks)
  • src/components/Navbar/SettingsDrawer/SettingsDrawer.tsx (1 hunks)
  • src/components/Search/SearchBodyContainer.tsx (1 hunks)
  • src/components/dls/Collapsible/Collapsible.tsx (3 hunks)
  • tests/auth.setup.ts (1 hunks)
  • tests/integration/authentification/login.spec.ts (1 hunks)
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts (4 hunks)
  • tests/integration/language/language-content.spec.ts (5 hunks)
  • tests/integration/language/language-persistance.spec.ts (1 hunks)
  • tests/integration/language/language-selector.spec.ts (3 hunks)
  • tests/integration/loggedin/profile.spec.ts (1 hunks)
  • tests/integration/navigation-and-general-structure/navbar-and-header/general.spec.ts (1 hunks)
  • tests/integration/navigation-and-general-structure/navbar-and-header/settings-drawer.spec.ts (3 hunks)
  • tests/integration/navigation-and-general-structure/navbar-and-header/sign-in-button.spec.ts (1 hunks)
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts (4 hunks)
  • tests/integration/quran-reader/settings-gear.spec.ts (3 hunks)
  • tests/integration/search-and-navigation/search-functionality/dedicated-search-page.spec.ts (2 hunks)
  • tests/integration/search-and-navigation/search-functionality/search-drawer-history.spec.ts (4 hunks)
🧰 Additional context used
🧠 Learnings (57)
📓 Common learnings
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx:33-45
Timestamp: 2025-11-24T12:16:47.248Z
Learning: In src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx, focus restoration on language container close is implemented using languageButtonRef with useEffect (lines 48-52), which correctly restores focus to the trigger button when showLanguageContainer becomes false.
📚 Learning: 2025-10-22T20:39:29.339Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: tests/integration/learning-plans/guest-access.spec.ts:3-5
Timestamp: 2025-10-22T20:39:29.339Z
Learning: Repository: quran/quran.com-frontend-next
Context: tests/integration/learning-plans/guest-access.spec.ts and similar focused integration tests
Learning: For focused integration tests that validate specific route behavior, maintainers prefer hard-coded route paths (e.g., LP_URL, FIRST_LESSON_URL) over environment-based URLs to avoid unnecessary complexity.

Applied to files:

  • tests/integration/navigation-and-general-structure/navbar-and-header/general.spec.ts
  • tests/integration/language/language-selector.spec.ts
  • tests/integration/search-and-navigation/search-functionality/search-drawer-history.spec.ts
  • tests/integration/quran-reader/settings-gear.spec.ts
  • tests/integration/language/language-content.spec.ts
  • tests/integration/navigation-and-general-structure/navbar-and-header/sign-in-button.spec.ts
  • tests/integration/language/language-persistance.spec.ts
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Test user interactions

Applied to files:

  • tests/integration/navigation-and-general-structure/navbar-and-header/general.spec.ts
  • tests/integration/language/language-selector.spec.ts
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
  • tests/integration/authentification/login.spec.ts
  • tests/integration/search-and-navigation/search-functionality/search-drawer-history.spec.ts
  • src/components/Navbar/SearchDrawer/Header/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • tests/integration/quran-reader/settings-gear.spec.ts
  • tests/integration/language/language-content.spec.ts
  • tests/integration/loggedin/profile.spec.ts
  • src/components/Navbar/Drawer/index.tsx
  • tests/integration/navigation-and-general-structure/navbar-and-header/sign-in-button.spec.ts
  • tests/integration/language/language-persistance.spec.ts
  • tests/integration/navigation-and-general-structure/navbar-and-header/settings-drawer.spec.ts
  • src/components/dls/Collapsible/Collapsible.tsx
  • tests/integration/search-and-navigation/search-functionality/dedicated-search-page.spec.ts
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
📚 Learning: 2025-10-09T11:21:33.919Z
Learnt from: zonetecde
Repo: quran/quran.com-frontend-next PR: 2523
File: src/components/QuranicCalendar/MyProgress/MonthCard.tsx:48-49
Timestamp: 2025-10-09T11:21:33.919Z
Learning: In the Quran in a Year calendar feature (src/components/QuranicCalendar/MyProgress/MonthCard.tsx), instant scrolling (window.scrollTo({ top: 0 }) without smooth behavior) is preferred over smooth scrolling when selecting a week. This is because instant scrolling provides immediate visual feedback of the verses and date changing, whereas smooth scrolling makes it look like nothing is changing during the animation.

Applied to files:

  • tests/integration/navigation-and-general-structure/navbar-and-header/general.spec.ts
📚 Learning: 2025-11-24T12:16:47.248Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx:33-45
Timestamp: 2025-11-24T12:16:47.248Z
Learning: In src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx, focus restoration on language container close is implemented using languageButtonRef with useEffect (lines 48-52), which correctly restores focus to the trigger button when showLanguageContainer becomes false.

Applied to files:

  • tests/integration/language/language-selector.spec.ts
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
  • tests/integration/search-and-navigation/search-functionality/search-drawer-history.spec.ts
  • src/components/Navbar/SearchDrawer/Header/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • tests/integration/quran-reader/settings-gear.spec.ts
  • tests/integration/language/language-content.spec.ts
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Search/SearchBodyContainer.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/SettingsDrawer/SettingsDrawer.tsx
  • src/components/Navbar/Drawer/index.tsx
  • tests/integration/language/language-persistance.spec.ts
  • tests/integration/navigation-and-general-structure/navbar-and-header/settings-drawer.spec.ts
  • src/components/Navbar/SearchDrawer/SearchDrawer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
📚 Learning: 2025-11-23T09:25:11.475Z
Learnt from: al-imam
Repo: quran/quran.com-frontend-next PR: 2593
File: src/components/Verse/TranslationFeedback/TranslationFeedbackModal.tsx:57-84
Timestamp: 2025-11-23T09:25:11.475Z
Learning: In src/components/Verse/TranslationFeedback/TranslationFeedbackModal.tsx, when the user has no preferred translations, the correct UX per spec is to show a single disabled option with the label "No translations in your preferences" in the Select dropdown. The form validation should remain in place to surface this state to the user, rather than silently disabling the textarea and submit button.

Applied to files:

  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper fallback UI

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:15.592Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/performance-optimization-rules.mdc:0-0
Timestamp: 2025-08-01T08:50:15.592Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use dynamic loading for non-critical components using src/components/dls/Spinner/Spinner.tsx

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:03.171Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/next-js-conventions.mdc:0-0
Timestamp: 2025-08-01T08:50:03.171Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Minimize 'use client' usage: Prefer server components and Next.js SSR features.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper lazy loading

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:03.171Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/next-js-conventions.mdc:0-0
Timestamp: 2025-08-01T08:50:03.171Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Use explicit return types for public functions

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.tsx : Implement proper prop types with TypeScript

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/**/*.tsx : Prefer React functional components for UI implementation

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use semantic HTML elements

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use functional components over class components

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:22.602Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react-functional-components.mdc:0-0
Timestamp: 2025-08-01T08:50:22.602Z
Learning: Applies to src/components/**/*.tsx : Use React.FC for functional components with props.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Document complex component logic

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Ensure keyboard navigation

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle focus management

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/use*.{tsx,jsx} : Keep hooks focused and simple

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper ARIA attributes

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-11-17T07:24:45.226Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2567
File: src/components/ReadingProgressPage/ReadingProgressPage.module.scss:208-213
Timestamp: 2025-11-17T07:24:45.226Z
Learning: In the quran.com-frontend-next repository, when the Button component from `src/components/dls/Button/Button.tsx` is used, interactive states (:hover, :focus-visible, :active) are handled by the Button component's internal styles in `src/components/dls/Button/Button.module.scss`. Module-specific SCSS classes applied to Button instances should not duplicate these interactive states.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*Form*.tsx : Implement proper accessibility for forms

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper memoization (useMemo, useCallback)

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Use arrow functions for callbacks and methods

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use custom hooks for reusable logic

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Extract reusable logic into custom hooks

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid unnecessary re-renders

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-10-28T09:59:48.894Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2557
File: src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx:88-0
Timestamp: 2025-10-28T09:59:48.894Z
Learning: In src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx, the empty `<div className={styles.separatorContainer} />` rendered when `isModal` is true is required for maintaining consistent spacing in modal view and should not be removed.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • tests/integration/quran-reader/settings-gear.spec.ts
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Search/SearchBodyContainer.tsx
  • src/components/Navbar/SettingsDrawer/SettingsDrawer.tsx
📚 Learning: 2025-09-19T13:56:15.026Z
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/auth.tsx:189-191
Timestamp: 2025-09-19T13:56:15.026Z
Learning: In the Quran.com frontend codebase, the `resolveSafeRedirect` function in `src/utils/url.ts` is intentionally designed to validate and allow external URLs, particularly for SSO (Single Sign-On) functionality where cross-domain redirects between platforms are required. This is not a security vulnerability but intended behavior for the SSO authentication flow.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-10-22T20:33:55.176Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:44-49
Timestamp: 2025-10-22T20:33:55.176Z
Learning: Preference: In quran.com-frontend-next, keep concise “why” comments for analytics/UX decision points (e.g., guest vs enrolled click handlers) but avoid verbose JSDoc that repeats params/types. Convert multi-line JSDoc to brief inline rationale comments, especially in src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx and similar analytics handlers.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-11-23T10:08:59.766Z
Learnt from: al-imam
Repo: quran/quran.com-frontend-next PR: 2593
File: src/components/Verse/TranslationFeedback/TranslationPreview.tsx:62-62
Timestamp: 2025-11-23T10:08:59.766Z
Learning: In src/components/Verse/TranslationFeedback/TranslationPreview.tsx, the non-null assertion on translation.languageId is safe because the useVerseAndTranslation hook explicitly requests translationFields: 'resource_name,language_id' in its API params, guaranteeing that language_id will always be present in the returned translation data.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper key props in lists

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid prop drilling through proper state management

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Use React Testing Library

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle edge cases gracefully

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Avoid using `any`, prefer `unknown` for unknown types

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Avoid type assertions unless necessary

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-10-22T20:42:09.214Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx:35-59
Timestamp: 2025-10-22T20:42:09.214Z
Learning: Preference for quran.com-frontend-next: keep single-use, page-specific components inline. Example: NotEnrolledMessage in src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx should remain inline; extract only if reused elsewhere.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/integration/**/*.{test,spec}.{tsx,jsx} : Implement integration tests for complex flows

Applied to files:

  • tests/integration/language/language-content.spec.ts
📚 Learning: 2025-10-20T15:16:53.776Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx:14-23
Timestamp: 2025-10-20T15:16:53.776Z
Learning: In the quran.com-frontend-next codebase, the `direction` property should be typed as `string` rather than using union types like `'ltr' | 'rtl'` to maintain consistency with the established codebase pattern (e.g., LanguageData interface in src/utils/locale.ts).

Applied to files:

  • tests/integration/language/language-content.spec.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-10-18T11:22:53.139Z
Learnt from: jonybekov
Repo: quran/quran.com-frontend-next PR: 2537
File: src/redux/slices/session.ts:36-42
Timestamp: 2025-10-18T11:22:53.139Z
Learning: In Redux selectors, avoid calling functions that read from external state (cookies, localStorage, etc.) like `isLoggedIn()` from utils/auth/login. Instead, use reactive hooks like `useIsLoggedIn` directly in components and keep selectors focused only on Redux state to ensure proper memoization.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:51:05.924Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/redux-toolkit-best-practices.mdc:0-0
Timestamp: 2025-08-01T08:51:05.924Z
Learning: Applies to src/redux/**/*.ts : Use selectors for accessing state in components.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-10-26T03:27:28.728Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2545
File: src/pages/reading-goal/index.tsx:31-35
Timestamp: 2025-10-26T03:27:28.728Z
Learning: In src/pages/reading-goal/index.tsx, the initialExampleKey is intentionally computed only when isLoggedIn() is true. This is by design: guest users can interact with the page and select options manually, but the example URL parameter only pre-selects an option for logged-in users (typically after being redirected back from login). The example selection is preserved through the authentication redirect flow.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:51:05.924Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/redux-toolkit-best-practices.mdc:0-0
Timestamp: 2025-08-01T08:51:05.924Z
Learning: Applies to src/redux/**/*.ts : Use Redux hooks (useSelector, useDispatch) in components.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use React.memo for expensive components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-10-28T06:07:39.429Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/LanguageContainer.tsx:68-74
Timestamp: 2025-10-28T06:07:39.429Z
Learning: In the quran.com-frontend-next codebase, when calling addOrUpdateUserPreference for language preferences, the established pattern is to pass PreferenceGroup.LANGUAGE (which resolves to the string 'language') as both the key and group parameters. This is valid because PreferenceGroup is a string enum and this pattern is used consistently across the codebase (e.g., LanguageSelector.tsx).

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-10-19T11:34:07.609Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/Verse/PlainVerseText/index.tsx:4-4
Timestamp: 2025-10-19T11:34:07.609Z
Learning: In src/components/Verse/PlainVerseText/index.tsx, the translation for verse titles should be wired directly to the component using next-translate rather than passed as props from parent components, as this ensures the wording from locales is centralized and only needs to be changed in one place.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-07-31T15:31:22.667Z
Learnt from: AhmedCodeGuy
Repo: quran/quran.com-frontend-next PR: 2477
File: src/components/QuranReader/TranslationView/TranslationViewCell.module.scss:204-207
Timestamp: 2025-07-31T15:31:22.667Z
Learning: AhmedCodeGuy suggested that the Separator component should be refactored in the future to avoid needing !important declarations for width overrides in contexts like .verseSeparator in TranslationViewCell.module.scss.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Provide proper alt text for images

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Profile and optimize render performance

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-09-25T23:23:27.647Z
Learnt from: Osama-Elshimy
Repo: quran/quran.com-frontend-next PR: 2500
File: src/components/DataFetcher/index.tsx:40-41
Timestamp: 2025-09-25T23:23:27.647Z
Learning: The DataFetcher component's showSpinnerOnRevalidate prop had a default value of true, not false. When it was renamed to shouldShowSpinnerOnRevalidate in a Next.js upgrade PR, the default value remained true, making it a behavior-neutral rename.

Applied to files:

  • src/components/Navbar/SearchDrawer/SearchDrawer.tsx
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/components/**/*.{ts,tsx} : Organize React components by feature and place DLS components under src/components/dls

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement cleanup in useEffect when needed

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use useState for local component state

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use appropriate dependency arrays in useEffect

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
🧬 Code graph analysis (4)
src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (3)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
src/utils/apiPaths.ts (1)
  • makeDonatePageUrl (301-306)
src/components/Navbar/NavbarBody/index.tsx (2)
src/redux/slices/navbar.ts (1)
  • selectIsNavigationDrawerOpen (87-88)
src/utils/auth/login.ts (1)
  • isLoggedIn (17-17)
src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (6)
src/redux/slices/defaultSettings.ts (1)
  • selectIsUsingDefaultSettings (47-48)
src/utils/cookies.ts (1)
  • setLocaleCookie (6-11)
src/utils/eventLogger.ts (1)
  • logValueChange (74-85)
src/utils/auth/login.ts (1)
  • isLoggedIn (17-17)
src/utils/auth/api.ts (1)
  • addOrUpdateUserPreference (384-394)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
src/components/Navbar/SearchDrawer/SearchDrawer.tsx (1)
src/utils/apiPaths.ts (1)
  • makeNewSearchResultsUrl (150-155)
🪛 Biome (2.1.2)
src/components/dls/Collapsible/Collapsible.tsx

[error] 101-111: Static Elements should not be interactive.

To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.

(lint/a11y/noStaticElementInteractions)


[error] 101-111: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)

🔇 Additional comments (37)
src/components/Search/SearchBodyContainer.tsx (1)

49-49: LGTM! Test ID update aligns with drawer-based search UI.

The test ID change from "search-body-container" to "search-drawer-container" is consistent with the broader refactoring to a drawer-based search interface and aligns with corresponding test updates.

tests/integration/authentification/login.spec.ts (1)

33-36: Verify the UX intent of displaying two profile avatar buttons simultaneously.

The test now asserts that two profile-avatar-button elements are visible. Based on the NavigationDrawer changes, one appears in the main navbar and another in the navigation drawer header. While this aligns with the code changes, consider whether having two identical profile avatars visible at the same time creates a confusing user experience, especially on desktop where both the navbar and drawer might be visible simultaneously.

Please confirm this is the intended UX behavior and that users won't find it confusing to see two profile avatars at once.

src/components/Navbar/SearchDrawer/Header/index.tsx (1)

75-75: LGTM! Test ID addition improves test stability.

The addition of the data-testid attribute enables stable element selection in integration tests without affecting functionality.

src/components/Navbar/SearchDrawer/SearchDrawer.tsx (2)

167-167: LGTM! ID attribute enables stable test targeting.

The addition of the id prop to the Drawer component improves test stability and aligns with the broader pattern of providing stable identifiers for drawer components.


181-188: LGTM! Cleaner structure with wrapper div removal.

The removal of the extra wrapper div around DataFetcher simplifies the component structure while preserving the isOpen gating logic. The DataFetcher still only renders when the drawer is open, maintaining the same functional behavior.

tests/integration/navigation-and-general-structure/navbar-and-header/settings-drawer.spec.ts (1)

20-20: LGTM! Test selector updates are consistent.

The test selector changes from 'settings-drawer-container' to 'settings-drawer-body' are applied consistently across all test cases and align with the updated SettingsDrawer DOM structure.

Also applies to: 24-24, 38-38, 44-44, 61-61, 67-67

src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx (3)

26-26: LGTM! ID attribute enables stable test targeting.

The addition of the id prop improves test stability and follows the same pattern applied to other drawer components in this PR.


28-28: LGTM! Drawer position change aligns with PR objectives.

The change from DrawerSide.Left to DrawerSide.Right correctly implements the requirement to move the burger menu from the left to the right side of the navigation bar.


9-9: Confirm ProfileAvatarButton isPopoverPortalled implementation is correct; aria-label differentiation recommended.

The implementation is sound. ProfileAvatarButton properly accepts and handles the isPopoverPortalled prop (default: true), correctly passing it to PopoverMenu as isPortalled at line 128. NavigationDrawer correctly renders it with isPopoverPortalled={false} to create an inline popover within the drawer, while the default usage in NavbarBody renders a portalled popover.

However:

  • Both avatar buttons use identical ariaLabel={t('profile')}, which may make screen readers less distinctive. Consider adding context-based aria-labels (e.g., "Profile menu in drawer" vs "Profile menu in navbar") to help users distinguish the two buttons.
  • Static code analysis confirms the prop handling is correct, but runtime concerns (focus management, keyboard navigation, z-index positioning with non-portalled popover in drawer context) require manual testing to verify PopoverMenu behavior in the drawer context.
tests/integration/loggedin/profile.spec.ts (1)

17-20: LGTM! Test updates are consistent with NavigationDrawer changes.

The test correctly validates that two profile avatar buttons are visible, consistent with the ProfileAvatarButton being added to the NavigationDrawer header. This matches the same pattern used in login.spec.ts.

tests/integration/search-and-navigation/search-functionality/dedicated-search-page.spec.ts (1)

59-59: LGTM! Test selector updates align with component changes.

The test selector changes from 'search-body-container' to 'search-drawer-container' are consistent with the test ID update in SearchBodyContainer.tsx and applied correctly in both test cases.

Also applies to: 76-76

tests/integration/navigation-and-general-structure/navbar-and-header/sign-in-button.spec.ts (1)

18-21: LGTM! Clear and defensive test assertions.

The test now properly validates that two "Sign in" buttons exist (likely one in the navbar and one in the navigation drawer) and explicitly clicks the first one. The count and visibility checks are good defensive practices.

tests/integration/search-and-navigation/search-functionality/search-drawer-history.spec.ts (2)

40-41: LGTM! Improved test selector targeting.

The test now correctly targets search-drawer-header for input focus interactions, which aligns with the refactored search drawer structure where the header contains the search input.

Also applies to: 54-55


64-77: LGTM! Consistent selector updates.

The updates to use search-drawer-container for result interactions are consistent with the new drawer structure.

src/components/Navbar/SettingsDrawer/SettingsDrawer.tsx (2)

69-76: LGTM! Improved structure with consolidated wrapper.

The change to wrap all drawer body views in a single conditional container with data-testid="settings-drawer-body" improves test selector consistency. The conditional rendering based on isSettingsDrawerOpen is appropriate since all views are dynamically imported and don't need to be in the DOM when the drawer is closed.


63-63: LGTM! Explicit drawer ID improves testability.

Adding id="settings-drawer" provides a stable identifier for the drawer component, which aligns with the updated Drawer component API.

tests/integration/language/language-selector.spec.ts (1)

22-31: LGTM! Test correctly reflects new language selection flow.

The test now properly opens the navigation drawer first, then the language selector, and interacts with language options within the dedicated language-container. This aligns with the PR's navigation drawer reorganization.

src/components/Navbar/Drawer/index.tsx (2)

38-38: LGTM! Flexible ID prop improves component reusability.

The addition of the optional id prop and its usage for both data-testid and element id provides better control over drawer identification for testing and DOM manipulation.

Also applies to: 90-90, 161-161


170-170: The original review suggestion is incorrect and should not be applied.

The backward compatibility fallback to 'settings-drawer-container' is actively used by the onboarding checklist. The code in src/components/Onboarding/OnboardingChecklist/hooks/useHandleOnboardingEvents.ts (line 62) explicitly queries for this ID via document.getElementById('settings-drawer-container') and scrolls the element (line 65). Removing the fallback as suggested would break onboarding functionality. The current implementation at line 170 is correct and should remain unchanged.

Likely an incorrect or invalid review comment.

tests/integration/language/language-persistance.spec.ts (1)

16-27: LGTM! Language persistence test correctly updated for new flow.

The test now properly opens the navigation drawer and interacts with the language-container, which aligns with the new burger menu structure. The persistence validation logic remains intact and correct.

tests/auth.setup.ts (1)

35-38: Verified: two profile avatar buttons are intentional.

The ProfileAvatarButton component renders with data-testid="profile-avatar-button" and appears in two locations post-authentication: the navbar header (NavbarBody/index.tsx:93) and the navigation drawer (NavigationDrawer.tsx:33). The test correctly expects both to be visible.

src/components/Navbar/NavbarBody/index.tsx (3)

47-63: LGTM! Well-structured drawer event handlers.

The openNavigationDrawer and openSearchDrawer handlers are properly separated with clear logging. The pattern of dispatching actions via type and payload is consistent.


66-71: Good use of inert + dimming for accessibility.

The combination of inert attribute and visual dimming correctly prevents interaction with navbar content when the navigation drawer is open, improving both keyboard and screen reader UX.


78-106: Clean conditional rendering with proper accessibility.

The search and menu buttons have appropriate ariaLabel, tooltip, and data-testid attributes. Conditional ProfileAvatarButton positioning based on login state follows the design requirements as clarified previously.

tests/integration/language/language-content.spec.ts (3)

19-29: LGTM! Well-structured test flow for new navigation drawer.

The step-by-step pattern (open drawer → trigger language selector → get container → select language) is consistent and readable. Using Promise.all with waitForURL properly handles the navigation race condition.


94-94: Test ID updated correctly.

The selector change from the previous settings drawer test ID to 'settings-drawer-body' aligns with the component's data-testid attribute.


105-111: Good verification of French locale UI elements.

Re-opening the navigation drawer after language change and verifying translated content ('Devenir un donateur mensuel', 'Accueil', 'À propos de nous') provides solid coverage of the localization flow.

src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (4)

25-29: Good use of centralized event name constants.

The EVENT_NAMES constant with as const assertion provides type safety and prevents typos in event logging calls.


50-54: Focus restoration correctly implemented.

The useEffect restores focus to the language trigger button when the container closes, providing proper keyboard navigation UX. Based on learnings, this pattern is confirmed correct.


58-62: Properly wired aria-controls with matching id.

The LanguageContainer now receives id="nav-lang-container" which correctly links to the trigger button's aria-controls attribute, resolving the previous accessibility gap.


80-94: Comprehensive accessibility on language trigger.

The button includes aria-expanded, aria-controls, aria-haspopup="dialog", and a fallback for the label (getLocaleName(lang) || lang). The ref is properly attached for focus restoration.

src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (3)

36-57: Good error recovery UX with Undo action.

The handleLanguagePersistError provides clear user feedback with actionable options. The Undo action properly reverts both the UI language and cookie, maintaining consistency.


59-77: Language change flow is well-orchestrated.

The sequence (reset if default → log → setLanguage → cookie → persist if logged in → close) is correct. The async addOrUpdateUserPreference call with .catch() provides non-blocking persistence with error handling.

Based on learnings, using PreferenceGroup.LANGUAGE as both key and group is the established codebase pattern.


79-94: Proper dialog accessibility attributes.

The container correctly uses role="dialog", aria-modal="true", aria-hidden={!show}, and aria-labelledby pointing to the title element. This provides good screen reader support.

tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts (1)

143-176: LGTM!

The updated drawerLinks fixture accurately reflects the new navigation drawer structure described in the PR objectives. The fixture properly accounts for:

  • Main navigation items (Read, Learn, My Quran)
  • Core features (Quran Radio, Reciters, About Us)
  • Collapsible sections (More, Our Projects)
  • Fundraising link

The empty href values for Android/iOS app links are appropriate since they're validated separately in the dedicated test (lines 102-119).

src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1)

1-142: LGTM!

This implementation successfully addresses all concerns from previous reviews:

  • ✅ PROJECTS constant at module scope avoids unnecessary recreation
  • ✅ Centralized URLs via EXTERNAL_ROUTES and QURAN_URL
  • ✅ Data-driven approach with array mapping
  • ✅ Stable key using eventName
  • ✅ Consistent early-return pattern in onOpenChange

The component is well-structured, follows i18n best practices with Trans, and properly integrates with the navigation drawer architecture.

src/components/dls/Collapsible/Collapsible.tsx (1)

54-64: LGTM!

The handleOpenChange function correctly fixes the double-toggle bug from previous reviews by centralizing state management and properly delegating to Radix's controlled component pattern. The useEffect guard against undefined values is also correctly implemented.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (1)
tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts (1)

111-117: Opening “Our Projects” before asserting links is correct; consider scoping locator

Expanding the Our Projects section via navigation-links-our-projects before checking the Android/iOS links aligns the test with the new collapsible UX. For extra isolation, you could scope the toggle to the drawer locator (e.g., drawer.getByTestId(...)) to guard against a future element with the same test id elsewhere on the page, but it’s not strictly necessary.

♻️ Duplicate comments (3)
tests/auth.setup.ts (1)

35-38: Dual profile button validation consistent with login flow.

The auth setup correctly validates two profile avatar buttons post-login, consistent with the updated UI structure.

tests/integration/authentification/login.spec.ts (1)

33-36: Login verification updated consistently.

The test correctly validates the new dual-button structure after successful login.

tests/integration/navigation-and-general-structure/navbar-and-header/sign-in-button.spec.ts (1)

18-21: Sign-in button pattern mirrors profile button behavior.

The test correctly validates two Sign in button instances (navbar + burger menu for guests) before interaction. This aligns with the PR's navigation updates.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a552946 and c933262.

📒 Files selected for processing (25)
  • src/components/Navbar/Drawer/index.tsx (4 hunks)
  • src/components/Navbar/NavbarBody/index.tsx (4 hunks)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx (2 hunks)
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (1 hunks)
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1 hunks)
  • src/components/Navbar/SearchDrawer/Header/index.tsx (1 hunks)
  • src/components/Navbar/SearchDrawer/SearchDrawer.tsx (2 hunks)
  • src/components/Navbar/SettingsDrawer/SettingsDrawer.tsx (1 hunks)
  • src/components/Search/SearchBodyContainer.tsx (1 hunks)
  • src/components/dls/Collapsible/Collapsible.tsx (3 hunks)
  • tests/auth.setup.ts (1 hunks)
  • tests/integration/authentification/login.spec.ts (1 hunks)
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts (4 hunks)
  • tests/integration/language/language-content.spec.ts (5 hunks)
  • tests/integration/language/language-persistance.spec.ts (1 hunks)
  • tests/integration/language/language-selector.spec.ts (3 hunks)
  • tests/integration/loggedin/profile.spec.ts (1 hunks)
  • tests/integration/navigation-and-general-structure/navbar-and-header/general.spec.ts (1 hunks)
  • tests/integration/navigation-and-general-structure/navbar-and-header/settings-drawer.spec.ts (3 hunks)
  • tests/integration/navigation-and-general-structure/navbar-and-header/sign-in-button.spec.ts (1 hunks)
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts (4 hunks)
  • tests/integration/quran-reader/settings-gear.spec.ts (3 hunks)
  • tests/integration/search-and-navigation/search-functionality/dedicated-search-page.spec.ts (2 hunks)
  • tests/integration/search-and-navigation/search-functionality/search-drawer-history.spec.ts (4 hunks)
🧰 Additional context used
🧠 Learnings (59)
📓 Common learnings
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx:33-45
Timestamp: 2025-11-24T12:16:47.248Z
Learning: In src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx, focus restoration on language container close is implemented using languageButtonRef with useEffect (lines 48-52), which correctly restores focus to the trigger button when showLanguageContainer becomes false.
📚 Learning: 2025-11-24T12:16:47.248Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx:33-45
Timestamp: 2025-11-24T12:16:47.248Z
Learning: In src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx, focus restoration on language container close is implemented using languageButtonRef with useEffect (lines 48-52), which correctly restores focus to the trigger button when showLanguageContainer becomes false.

Applied to files:

  • tests/integration/search-and-navigation/search-functionality/search-drawer-history.spec.ts
  • src/components/Search/SearchBodyContainer.tsx
  • tests/integration/language/language-content.spec.ts
  • src/components/Navbar/NavbarBody/index.tsx
  • tests/integration/search-and-navigation/search-functionality/dedicated-search-page.spec.ts
  • tests/integration/navigation-and-general-structure/navbar-and-header/settings-drawer.spec.ts
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • tests/integration/language/language-selector.spec.ts
  • tests/integration/language/language-persistance.spec.ts
  • src/components/Navbar/Drawer/index.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/dls/Collapsible/Collapsible.tsx
  • tests/integration/quran-reader/settings-gear.spec.ts
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/SearchDrawer/Header/index.tsx
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/SearchDrawer/SearchDrawer.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx
  • src/components/Navbar/SettingsDrawer/SettingsDrawer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Test user interactions

Applied to files:

  • tests/integration/search-and-navigation/search-functionality/search-drawer-history.spec.ts
  • tests/auth.setup.ts
  • tests/integration/authentification/login.spec.ts
  • tests/integration/loggedin/profile.spec.ts
  • src/components/Search/SearchBodyContainer.tsx
  • tests/integration/language/language-content.spec.ts
  • tests/integration/search-and-navigation/search-functionality/dedicated-search-page.spec.ts
  • tests/integration/navigation-and-general-structure/navbar-and-header/settings-drawer.spec.ts
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • tests/integration/language/language-selector.spec.ts
  • tests/integration/navigation-and-general-structure/navbar-and-header/sign-in-button.spec.ts
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • tests/integration/navigation-and-general-structure/navbar-and-header/general.spec.ts
  • src/components/dls/Collapsible/Collapsible.tsx
  • tests/integration/quran-reader/settings-gear.spec.ts
  • src/components/Navbar/SearchDrawer/Header/index.tsx
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-10-22T20:39:29.339Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: tests/integration/learning-plans/guest-access.spec.ts:3-5
Timestamp: 2025-10-22T20:39:29.339Z
Learning: Repository: quran/quran.com-frontend-next
Context: tests/integration/learning-plans/guest-access.spec.ts and similar focused integration tests
Learning: For focused integration tests that validate specific route behavior, maintainers prefer hard-coded route paths (e.g., LP_URL, FIRST_LESSON_URL) over environment-based URLs to avoid unnecessary complexity.

Applied to files:

  • tests/integration/search-and-navigation/search-functionality/search-drawer-history.spec.ts
  • tests/integration/loggedin/profile.spec.ts
  • tests/integration/language/language-content.spec.ts
  • tests/integration/language/language-selector.spec.ts
  • tests/integration/language/language-persistance.spec.ts
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • tests/integration/navigation-and-general-structure/navbar-and-header/general.spec.ts
  • tests/integration/quran-reader/settings-gear.spec.ts
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Test error scenarios

Applied to files:

  • tests/integration/loggedin/profile.spec.ts
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/integration/**/*.{test,spec}.{tsx,jsx} : Implement integration tests for complex flows

Applied to files:

  • tests/integration/loggedin/profile.spec.ts
  • tests/integration/language/language-content.spec.ts
  • tests/integration/language/language-selector.spec.ts
📚 Learning: 2025-10-28T09:59:48.894Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2557
File: src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx:88-0
Timestamp: 2025-10-28T09:59:48.894Z
Learning: In src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx, the empty `<div className={styles.separatorContainer} />` rendered when `isModal` is true is required for maintaining consistent spacing in modal view and should not be removed.

Applied to files:

  • src/components/Search/SearchBodyContainer.tsx
  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
  • src/components/Navbar/SettingsDrawer/SettingsDrawer.tsx
📚 Learning: 2025-10-20T15:16:53.776Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx:14-23
Timestamp: 2025-10-20T15:16:53.776Z
Learning: In the quran.com-frontend-next codebase, the `direction` property should be typed as `string` rather than using union types like `'ltr' | 'rtl'` to maintain consistency with the established codebase pattern (e.g., LanguageData interface in src/utils/locale.ts).

Applied to files:

  • tests/integration/language/language-content.spec.ts
  • tests/integration/navigation-and-general-structure/navbar-and-header/general.spec.ts
  • tests/integration/quran-reader/settings-gear.spec.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-10-18T11:22:53.139Z
Learnt from: jonybekov
Repo: quran/quran.com-frontend-next PR: 2537
File: src/redux/slices/session.ts:36-42
Timestamp: 2025-10-18T11:22:53.139Z
Learning: In Redux selectors, avoid calling functions that read from external state (cookies, localStorage, etc.) like `isLoggedIn()` from utils/auth/login. Instead, use reactive hooks like `useIsLoggedIn` directly in components and keep selectors focused only on Redux state to ensure proper memoization.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid unnecessary re-renders

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-08-01T08:51:05.924Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/redux-toolkit-best-practices.mdc:0-0
Timestamp: 2025-08-01T08:51:05.924Z
Learning: Applies to src/redux/**/*.ts : Use selectors for accessing state in components.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/use*.{tsx,jsx} : Keep hooks focused and simple

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper memoization (useMemo, useCallback)

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Avoid prop drilling through proper state management

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-10-26T03:27:28.728Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2545
File: src/pages/reading-goal/index.tsx:31-35
Timestamp: 2025-10-26T03:27:28.728Z
Learning: In src/pages/reading-goal/index.tsx, the initialExampleKey is intentionally computed only when isLoggedIn() is true. This is by design: guest users can interact with the page and select options manually, but the example URL parameter only pre-selects an option for logged-in users (typically after being redirected back from login). The example selection is preserved through the authentication redirect flow.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.tsx : Implement proper prop types with TypeScript

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper ARIA attributes

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/SearchDrawer/Header/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper key props in lists

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Avoid using `any`, prefer `unknown` for unknown types

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use semantic HTML elements

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Ensure keyboard navigation

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper fallback UI

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • tests/integration/language/language-selector.spec.ts
  • src/components/dls/Collapsible/Collapsible.tsx
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle edge cases gracefully

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:51:05.924Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/redux-toolkit-best-practices.mdc:0-0
Timestamp: 2025-08-01T08:51:05.924Z
Learning: Applies to src/redux/**/*.ts : Use Redux hooks (useSelector, useDispatch) in components.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use React.memo for expensive components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-08-01T08:50:15.592Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/performance-optimization-rules.mdc:0-0
Timestamp: 2025-08-01T08:50:15.592Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use dynamic loading for non-critical components using src/components/dls/Spinner/Spinner.tsx

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:03.171Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/next-js-conventions.mdc:0-0
Timestamp: 2025-08-01T08:50:03.171Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Minimize 'use client' usage: Prefer server components and Next.js SSR features.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper lazy loading

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:03.171Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/next-js-conventions.mdc:0-0
Timestamp: 2025-08-01T08:50:03.171Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Minimize 'use client' usage: Avoid using 'use client' for data fetching or state management.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Use explicit return types for public functions

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/**/*.tsx : Prefer React functional components for UI implementation

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use functional components over class components

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:22.602Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react-functional-components.mdc:0-0
Timestamp: 2025-08-01T08:50:22.602Z
Learning: Applies to src/components/**/*.tsx : Use React.FC for functional components with props.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Document complex component logic

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle focus management

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-17T07:24:45.226Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2567
File: src/components/ReadingProgressPage/ReadingProgressPage.module.scss:208-213
Timestamp: 2025-11-17T07:24:45.226Z
Learning: In the quran.com-frontend-next repository, when the Button component from `src/components/dls/Button/Button.tsx` is used, interactive states (:hover, :focus-visible, :active) are handled by the Button component's internal styles in `src/components/dls/Button/Button.module.scss`. Module-specific SCSS classes applied to Button instances should not duplicate these interactive states.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*Form*.tsx : Implement proper accessibility for forms

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-23T09:25:11.475Z
Learnt from: al-imam
Repo: quran/quran.com-frontend-next PR: 2593
File: src/components/Verse/TranslationFeedback/TranslationFeedbackModal.tsx:57-84
Timestamp: 2025-11-23T09:25:11.475Z
Learning: In src/components/Verse/TranslationFeedback/TranslationFeedbackModal.tsx, when the user has no preferred translations, the correct UX per spec is to show a single disabled option with the label "No translations in your preferences" in the Select dropdown. The form validation should remain in place to surface this state to the user, rather than silently disabling the textarea and submit button.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • tests/integration/language/language-selector.spec.ts
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Use arrow functions for callbacks and methods

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use custom hooks for reusable logic

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Extract reusable logic into custom hooks

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-09-19T13:56:15.026Z
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/auth.tsx:189-191
Timestamp: 2025-09-19T13:56:15.026Z
Learning: In the Quran.com frontend codebase, the `resolveSafeRedirect` function in `src/utils/url.ts` is intentionally designed to validate and allow external URLs, particularly for SSO (Single Sign-On) functionality where cross-domain redirects between platforms are required. This is not a security vulnerability but intended behavior for the SSO authentication flow.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-10-22T20:33:55.176Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:44-49
Timestamp: 2025-10-22T20:33:55.176Z
Learning: Preference: In quran.com-frontend-next, keep concise “why” comments for analytics/UX decision points (e.g., guest vs enrolled click handlers) but avoid verbose JSDoc that repeats params/types. Convert multi-line JSDoc to brief inline rationale comments, especially in src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx and similar analytics handlers.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • tests/integration/navigation-and-general-structure/navbar-and-header/general.spec.ts
  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
📚 Learning: 2025-11-23T10:08:59.766Z
Learnt from: al-imam
Repo: quran/quran.com-frontend-next PR: 2593
File: src/components/Verse/TranslationFeedback/TranslationPreview.tsx:62-62
Timestamp: 2025-11-23T10:08:59.766Z
Learning: In src/components/Verse/TranslationFeedback/TranslationPreview.tsx, the non-null assertion on translation.languageId is safe because the useVerseAndTranslation hook explicitly requests translationFields: 'resource_name,language_id' in its API params, guaranteeing that language_id will always be present in the returned translation data.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • tests/integration/language/language-selector.spec.ts
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Use React Testing Library

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • tests/integration/quran-reader/settings-gear.spec.ts
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.{ts,tsx,d.ts} : Avoid type assertions unless necessary

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
📚 Learning: 2025-10-22T20:42:09.214Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx:35-59
Timestamp: 2025-10-22T20:42:09.214Z
Learning: Preference for quran.com-frontend-next: keep single-use, page-specific components inline. Example: NotEnrolledMessage in src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx should remain inline; extract only if reused elsewhere.

Applied to files:

  • src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
📚 Learning: 2025-10-26T10:22:52.381Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx:60-60
Timestamp: 2025-10-26T10:22:52.381Z
Learning: In src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx, verse references displayed alongside chapter names should use English/Western numerals only, not localized numerals, as per design specifications.

Applied to files:

  • tests/integration/navigation-and-general-structure/navbar-and-header/general.spec.ts
📚 Learning: 2025-10-07T08:37:58.213Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-07T08:37:58.213Z
Learning: Applies to src/components/**/*.{ts,tsx} : Organize React components by feature and place DLS components under src/components/dls

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Split large components into smaller, focused ones

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:51:28.930Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-08-01T08:51:28.930Z
Learning: Applies to **/*.tsx : Prefix interfaces for React props with 'Props' (e.g., ButtonProps)

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement cleanup in useEffect when needed

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use useState for local component state

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use appropriate dependency arrays in useEffect

Applied to files:

  • src/components/dls/Collapsible/Collapsible.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Profile and optimize render performance

Applied to files:

  • src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx
📚 Learning: 2025-10-19T11:34:07.609Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/Verse/PlainVerseText/index.tsx:4-4
Timestamp: 2025-10-19T11:34:07.609Z
Learning: In src/components/Verse/PlainVerseText/index.tsx, the translation for verse titles should be wired directly to the component using next-translate rather than passed as props from parent components, as this ensures the wording from locales is centralized and only needs to be changed in one place.

Applied to files:

  • tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-10-28T06:07:39.429Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/LanguageContainer.tsx:68-74
Timestamp: 2025-10-28T06:07:39.429Z
Learning: In the quran.com-frontend-next codebase, when calling addOrUpdateUserPreference for language preferences, the established pattern is to pass PreferenceGroup.LANGUAGE (which resolves to the string 'language') as both the key and group parameters. This is valid because PreferenceGroup is a string enum and this pattern is used consistently across the codebase (e.g., LanguageSelector.tsx).

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-07-31T15:31:22.667Z
Learnt from: AhmedCodeGuy
Repo: quran/quran.com-frontend-next PR: 2477
File: src/components/QuranReader/TranslationView/TranslationViewCell.module.scss:204-207
Timestamp: 2025-07-31T15:31:22.667Z
Learning: AhmedCodeGuy suggested that the Separator component should be refactored in the future to avoid needing !important declarations for width overrides in contexts like .verseSeparator in TranslationViewCell.module.scss.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Provide proper alt text for images

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
🧬 Code graph analysis (4)
src/components/Navbar/NavbarBody/index.tsx (2)
src/redux/slices/navbar.ts (1)
  • selectIsNavigationDrawerOpen (87-88)
src/utils/auth/login.ts (1)
  • isLoggedIn (17-17)
src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (3)
src/utils/eventLogger.ts (2)
  • logEvent (25-37)
  • logButtonClick (44-46)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
src/utils/apiPaths.ts (1)
  • makeDonatePageUrl (301-306)
src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (7)
src/redux/slices/defaultSettings.ts (1)
  • selectIsUsingDefaultSettings (47-48)
src/components/dls/Toast/Toast.tsx (1)
  • useToast (86-96)
src/utils/cookies.ts (1)
  • setLocaleCookie (6-11)
src/utils/eventLogger.ts (1)
  • logValueChange (74-85)
src/utils/auth/login.ts (1)
  • isLoggedIn (17-17)
src/utils/auth/api.ts (1)
  • addOrUpdateUserPreference (384-394)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
src/components/Navbar/SearchDrawer/SearchDrawer.tsx (1)
src/utils/apiPaths.ts (1)
  • makeNewSearchResultsUrl (150-155)
🪛 Biome (2.1.2)
src/components/dls/Collapsible/Collapsible.tsx

[error] 101-111: Static Elements should not be interactive.

To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.

(lint/a11y/noStaticElementInteractions)

🔇 Additional comments (31)
tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts (2)

38-41: Scoped close-button locator improves robustness

Scoping the “Close Drawer” control lookup to the navigation-drawer container makes the test less brittle if another “Close Drawer” label appears elsewhere and better reflects the user interaction target.


141-176: drawerLinks fixture matches new IA and uses resilient expectations

The updated drawerLinks set (Read/Learn/My Quran main links, “More”, “Our Projects”, and the “Become A Monthly Donor” CTA) is consistent with the new drawer design. Using empty href for dynamic links (continue reading, app-store URLs) while still asserting their targets, and checking app-store domains in a dedicated test, keeps the suite robust to URL tweaks. Hard-coding the internal paths (/learning-plans, /profile, etc.) for this focused integration spec also aligns with the repo’s preference for explicit routes in such tests. Based on learnings, this looks well-aligned with existing testing conventions.

src/components/Navbar/SearchDrawer/Header/index.tsx (1)

75-75: LGTM!

The test ID addition enables proper test targeting without affecting behavior.

src/components/Search/SearchBodyContainer.tsx (1)

49-49: LGTM!

The test ID rename improves naming consistency. Related tests have been updated accordingly.

src/components/Navbar/SearchDrawer/SearchDrawer.tsx (1)

167-188: LGTM!

The id prop addition and wrapper div removal both improve the code: the id enables proper drawer identification, and removing the unnecessary wrapper simplifies the structure without affecting behavior.

src/components/dls/Collapsible/Collapsible.tsx (2)

54-81: LGTM!

The open state management correctly integrates with Radix's controlled component pattern via handleOpenChange, the useEffect properly guards against non-boolean shouldOpen, and the suffix handlers appropriately manage event propagation based on shouldSuffixTrigger. These changes address the concerns raised in previous reviews.


85-130: LGTM!

The Trigger structure correctly uses Radix's asChild pattern with proper id/test-id support, and the conditional rendering of prefix/suffix containers with rotation styles and accessibility attributes is well-implemented. The suffix's conditional role and tabIndex (lines 107-110) appropriately make it interactive only when shouldSuffixTrigger is true.

tests/integration/loggedin/profile.spec.ts (1)

17-20: Dual profile button instances are intentional and verified.

The codebase confirms two instances of ProfileAvatarButton render when logged in:

  1. Main navbar (NavbarBody, line 93: {loggedIn && <ProfileAvatarButton />})
  2. Burger menu drawer (NavigationDrawer, line 33)

The test assertion is correct and matches the intended UI behavior.

src/components/Navbar/NavigationDrawer/OurProjectsCollapsible.tsx (1)

30-135: Config-driven projects list and collapsible wiring look solid

Static PROJECTS at module scope, centralized URLs via EXTERNAL_ROUTES/QURAN_URL, stable eventName keys, and the onOpenChange/handleProjectClick logging all align with the existing collapsible + analytics pattern; nothing blocking here.
Based on learnings, this matches the earlier guidance about moving static arrays out of components and reusing shared URL helpers.

src/components/Navbar/NavigationDrawer/NavigationDrawer.tsx (1)

9-39: Drawer side change and profile button integration are consistent

Using side={DrawerSide.Right} for the navigation drawer and rendering ProfileAvatarButton in the drawer header with isPopoverPortalled={false} is consistent with the new navbar design and should avoid popover layering issues inside the Drawer.

tests/integration/navigation-and-general-structure/navbar-and-header/settings-drawer.spec.ts (1)

20-68: Selectors now correctly target the settings drawer body

Updating all expectations to use getByTestId('settings-drawer-body') aligns these tests with the new SettingsDrawer body wrapper and keeps the visibility checks scoped to the actual drawer content.

tests/integration/content-display-and-reading/translations/translation-selection-and-display.spec.ts (1)

44-45: Translation tests correctly scoped to settings-drawer-body

Using a settingsBody = page.getByTestId('settings-drawer-body') locator and querying translations through it keeps these tests aligned with the new drawer structure and avoids accidental matches outside the settings drawer.

Also applies to: 61-62, 93-94, 129-130

tests/integration/navigation-and-general-structure/navbar-and-header/general.spec.ts (1)

16-18: Navbar logo click test now self-consistent

The comment and locator both now clearly refer to the first Quran.com title element as the navbar logo, and the redirect assertion remains intact; this looks good.

tests/integration/search-and-navigation/search-functionality/search-drawer-history.spec.ts (1)

40-41: Search drawer tests correctly distinguish header and container

Targeting the input via search-drawer-header for focus and the results/history via search-drawer-container makes the tests reflect the new drawer DOM structure without changing behavior.

Also applies to: 54-55, 64-65, 77-77

src/components/Navbar/SettingsDrawer/SettingsDrawer.tsx (1)

63-77: Drawer id/body wiring and conditional body wrapper look correct

Passing id="settings-drawer" and bodyId="settings-drawer-body" to Drawer, and only rendering the inner <div data-testid="settings-drawer-body"> (with the four view bodies) when isSettingsDrawerOpen is true, lines up with the new tests and avoids mounting heavy content when the drawer is closed.

tests/integration/search-and-navigation/search-functionality/dedicated-search-page.spec.ts (1)

59-60: Dedicated search page tests aligned with new drawer container id

Switching assertions to getByTestId('search-drawer-container') for “No results found” and “2:255” makes these tests consistent with the updated search drawer container used elsewhere.

Also applies to: 75-77

tests/integration/quran-reader/settings-gear.spec.ts (1)

11-12: LGTM! Consistent test-id selectors improve test stability.

The migration from DOM id-based selectors (#settings-drawer-container, #settings-drawer-body) to test-id based queries (getByTestId('settings-drawer'), getByTestId('settings-drawer-body')) is well-executed and applied consistently across all test cases. This addresses the previous review feedback and improves test maintainability.

Also applies to: 22-23, 26-26, 35-36

tests/integration/language/language-persistance.spec.ts (1)

16-27: LGTM! Test flow correctly updated for new navigation drawer structure.

The test properly adapts to the new UI flow:

  1. Opens the navigation drawer first
  2. Accesses the language selector through the drawer
  3. Uses scoped button queries within language-container

The Promise.all pattern for click + navigation wait is appropriate and the step comments are clear.

src/components/Navbar/Drawer/index.tsx (1)

38-38: LGTM! Clean addition of the optional id prop.

The id prop addition to the interface (line 38), its destructuring (line 90), and the data-testid logic (line 161) are all correctly implemented. The data-testid expression properly uses id || \${type}-drawer-container`` as a fallback pattern.

Also applies to: 90-90, 161-161

src/components/Navbar/NavbarBody/index.tsx (3)

50-51: LGTM! Proper state management with memoized selector and single auth check.

The use of selectIsNavigationDrawerOpen avoids selecting the entire navbar slice, and isLoggedIn() is computed once at the top of the component. This addresses the previous review feedback.


79-105: LGTM! Clean conditional rendering with proper accessibility.

The conditional placement of ProfileAvatarButton based on login state implements the design requirement correctly (guest: profile before search, logged-in: profile after search). All buttons have appropriate ariaLabel, tooltip, and data-testid attributes for accessibility and testability.


66-71: No TypeScript compatibility issues with the inert attribute.

The project's TypeScript configuration ("strict": false and "skipLibCheck": true) does not enforce strict type validation on DOM attributes. The inert attribute is valid HTML and works correctly at runtime. The pattern—inert={isNavigationDrawerOpen || undefined}—properly removes the attribute when false. This usage is already established elsewhere in the codebase (NavigationDrawer, AppContent components), confirming it's an accepted pattern.

tests/integration/language/language-selector.spec.ts (2)

20-32: LGTM! Consistent scoped queries within language container.

The test correctly:

  1. Uses button role instead of menuitem to match the Button component rendering
  2. Opens the navigation drawer before accessing the language selector
  3. Scopes all language button queries to language-container

This pattern is consistently applied and aligns with the new LanguageContainer component structure.


65-76: LGTM! Language selection tests properly adapted.

Both test cases follow the established pattern for the new UI flow and correctly scope button interactions to the language-container. The HTML lang attribute verification in the third test is comprehensive.

Also applies to: 85-98

tests/integration/language/language-content.spec.ts (4)

19-32: Arabic RTL test correctly updated to use the language container

The new steps (open nav drawer, trigger language selector, select العربية from the scoped language container, then assert dir="rtl") match the updated UI and keep the test robust.


40-50: Spanish homepage content test aligns with new drawer flow

Selecting Español via the language container and waiting for navigation to /es before asserting translated Surah 108 metadata is a good fit for the new interaction model.


67-95: French UI coverage through drawer + settings checks looks solid

Opening the language container, switching to French, then validating navbar search labels, settings drawer content (using settings-drawer-body), and navigation drawer labels provides comprehensive UI verification for the fr locale.

Also applies to: 104-112


121-131: Spanish default-translation test correctly reuses the language container flow

Re-selecting Español via the language container and waiting on /es before asserting <html lang="es"> and downstream verse/translation expectations keeps this test consistent with the new language-selection UX.

src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx (2)

20-55: State, analytics logging, and focus restoration are cleanly wired

Centralizing event names in EVENT_NAMES, wrapping the handlers in useCallback, and restoring focus to the language trigger when showLanguageContainer flips to false gives stable props and good keyboard UX without extra complexity.


56-110: Language drawer body structure and accessibility look correct

Linking the trigger to LanguageContainer via aria-controls/id, combining aria-hidden with inert on the main list while the language sheet is open, and using the existing donate URL helper with isNewTab makes this drawer body both accessible and consistent with the rest of the app.

src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1)

79-123: Dialog semantics and language list accessibility are well implemented

The dialog root (role="dialog", aria-modal, aria-hidden, aria-labelledby) plus the back button–hosted title and aria-current on the active locale button provide a solid, screen-reader-friendly language picker that stays in sync with i18nConfig.locales and getLocaleName.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (2)
src/components/Navbar/Drawer/index.tsx (1)

160-171: data-testid / id fallback logic now matches the intended behavior

The updated expressions:

  • Line 161 (data-testid={isOpen ? id || \${type}-drawer-container` : undefined}) correctly prefers a provided id` and otherwise falls back to the type-based container id, only when the drawer is open.
  • Line 170 (id={id || (type === DrawerType.Settings ? 'settings-drawer-container' : undefined)}) fixes the earlier precedence issue and preserves the legacy 'settings-drawer-container' id for the Settings drawer when no custom id is passed.

This matches the described API: consumer-provided id wins; otherwise Settings keeps its historical id, and other drawers have no DOM id.

If you ever need to support an explicit empty-string id, consider switching || to ?? on both lines so only null/undefined trigger the fallback.

tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts (1)

110-117: Optionally scope the “Our Projects” trigger via the existing drawer locator

You already assign const drawer = page.getByTestId('navigation-drawer-body');. For extra robustness and consistency, you can scope the “Our Projects” trigger to that drawer instead of the whole page:

-    const drawer = page.getByTestId('navigation-drawer-body');
-    await page.getByTestId('navigation-links-our-projects').click();
+    const drawer = page.getByTestId('navigation-drawer-body');
+    await drawer.getByTestId('navigation-links-our-projects').click();

This reduces the chance of collisions if another element with the same test id is ever introduced outside the drawer.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c933262 and 87c7de4.

📒 Files selected for processing (3)
  • src/components/Navbar/Drawer/index.tsx (4 hunks)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1 hunks)
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts (4 hunks)
🧰 Additional context used
🧠 Learnings (21)
📓 Common learnings
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx:33-45
Timestamp: 2025-11-24T12:16:47.248Z
Learning: In src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx, focus restoration on language container close is implemented using languageButtonRef with useEffect (lines 48-52), which correctly restores focus to the trigger button when showLanguageContainer becomes false.
📚 Learning: 2025-11-24T12:16:47.248Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx:33-45
Timestamp: 2025-11-24T12:16:47.248Z
Learning: In src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx, focus restoration on language container close is implemented using languageButtonRef with useEffect (lines 48-52), which correctly restores focus to the trigger button when showLanguageContainer becomes false.

Applied to files:

  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/Drawer/index.tsx
📚 Learning: 2025-10-22T20:39:29.339Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: tests/integration/learning-plans/guest-access.spec.ts:3-5
Timestamp: 2025-10-22T20:39:29.339Z
Learning: Repository: quran/quran.com-frontend-next
Context: tests/integration/learning-plans/guest-access.spec.ts and similar focused integration tests
Learning: For focused integration tests that validate specific route behavior, maintainers prefer hard-coded route paths (e.g., LP_URL, FIRST_LESSON_URL) over environment-based URLs to avoid unnecessary complexity.

Applied to files:

  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Test user interactions

Applied to files:

  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/integration/**/*.{test,spec}.{tsx,jsx} : Implement integration tests for complex flows

Applied to files:

  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper fallback UI

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-10-28T06:07:39.429Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/LanguageContainer.tsx:68-74
Timestamp: 2025-10-28T06:07:39.429Z
Learning: In the quran.com-frontend-next codebase, when calling addOrUpdateUserPreference for language preferences, the established pattern is to pass PreferenceGroup.LANGUAGE (which resolves to the string 'language') as both the key and group parameters. This is valid because PreferenceGroup is a string enum and this pattern is used consistently across the codebase (e.g., LanguageSelector.tsx).

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-10-20T15:16:53.776Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx:14-23
Timestamp: 2025-10-20T15:16:53.776Z
Learning: In the quran.com-frontend-next codebase, the `direction` property should be typed as `string` rather than using union types like `'ltr' | 'rtl'` to maintain consistency with the established codebase pattern (e.g., LanguageData interface in src/utils/locale.ts).

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-23T09:25:11.475Z
Learnt from: al-imam
Repo: quran/quran.com-frontend-next PR: 2593
File: src/components/Verse/TranslationFeedback/TranslationFeedbackModal.tsx:57-84
Timestamp: 2025-11-23T09:25:11.475Z
Learning: In src/components/Verse/TranslationFeedback/TranslationFeedbackModal.tsx, when the user has no preferred translations, the correct UX per spec is to show a single disabled option with the label "No translations in your preferences" in the Select dropdown. The form validation should remain in place to surface this state to the user, rather than silently disabling the textarea and submit button.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-23T10:08:59.766Z
Learnt from: al-imam
Repo: quran/quran.com-frontend-next PR: 2593
File: src/components/Verse/TranslationFeedback/TranslationPreview.tsx:62-62
Timestamp: 2025-11-23T10:08:59.766Z
Learning: In src/components/Verse/TranslationFeedback/TranslationPreview.tsx, the non-null assertion on translation.languageId is safe because the useVerseAndTranslation hook explicitly requests translationFields: 'resource_name,language_id' in its API params, guaranteeing that language_id will always be present in the returned translation data.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper ARIA attributes

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-17T07:24:45.226Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2567
File: src/components/ReadingProgressPage/ReadingProgressPage.module.scss:208-213
Timestamp: 2025-11-17T07:24:45.226Z
Learning: In the quran.com-frontend-next repository, when the Button component from `src/components/dls/Button/Button.tsx` is used, interactive states (:hover, :focus-visible, :active) are handled by the Button component's internal styles in `src/components/dls/Button/Button.module.scss`. Module-specific SCSS classes applied to Button instances should not duplicate these interactive states.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-10-19T11:34:07.609Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/Verse/PlainVerseText/index.tsx:4-4
Timestamp: 2025-10-19T11:34:07.609Z
Learning: In src/components/Verse/PlainVerseText/index.tsx, the translation for verse titles should be wired directly to the component using next-translate rather than passed as props from parent components, as this ensures the wording from locales is centralized and only needs to be changed in one place.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-07-31T15:31:22.667Z
Learnt from: AhmedCodeGuy
Repo: quran/quran.com-frontend-next PR: 2477
File: src/components/QuranReader/TranslationView/TranslationViewCell.module.scss:204-207
Timestamp: 2025-07-31T15:31:22.667Z
Learning: AhmedCodeGuy suggested that the Separator component should be refactored in the future to avoid needing !important declarations for width overrides in contexts like .verseSeparator in TranslationViewCell.module.scss.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Ensure keyboard navigation

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*Form*.tsx : Implement proper accessibility for forms

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Provide proper alt text for images

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Use proper key props in lists

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/*.{tsx,jsx} : Handle focus management

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-08-01T08:50:54.518Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-08-01T08:50:54.518Z
Learning: Applies to **/use*.{tsx,jsx} : Keep hooks focused and simple

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-09-21T19:00:54.303Z
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/logout.tsx:11-12
Timestamp: 2025-09-21T19:00:54.303Z
Learning: In src/pages/logout.tsx, the developer mohsinayoob prefers to let decodeURIComponent exceptions bubble up to the global catch block rather than handling them locally. This ensures centralized error handling where all logout errors redirect to a safe default path, maintaining consistent fallback behavior instead of having multiple error handling points.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
🧬 Code graph analysis (1)
src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (7)
src/redux/slices/defaultSettings.ts (1)
  • selectIsUsingDefaultSettings (47-48)
src/components/dls/Toast/Toast.tsx (1)
  • useToast (86-96)
src/utils/cookies.ts (1)
  • setLocaleCookie (6-11)
src/utils/eventLogger.ts (1)
  • logValueChange (74-85)
src/utils/auth/login.ts (1)
  • isLoggedIn (17-17)
src/utils/auth/api.ts (1)
  • addOrUpdateUserPreference (384-394)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
🔇 Additional comments (7)
src/components/Navbar/Drawer/index.tsx (1)

37-47: New id prop wiring is consistent and non‑breaking

Adding id?: string to Props and destructuring it in Drawer cleanly extends the public API without affecting existing callers (since it’s optional). This gives a single source for both DOM id and test selectors and doesn’t interfere with the existing defaults.

Also applies to: 89-99

src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (4)

1-28: LGTM! Clean imports and type-safe interface.

The imports are well-organized, and the interface properly extends HTMLAttributes<HTMLDivElement> to support spreading additional props while maintaining type safety.


30-57: LGTM! Good error handling with actionable user feedback.

The persistence error handler provides excellent UX by offering an Undo action to revert the language change or Continue to proceed despite the server-side persistence failure. The Undo action correctly reverts both the in-memory state and the cookie.


59-79: LGTM! Try-finally pattern ensures dialog cleanup.

The try-finally pattern correctly ensures onBack() is called even if an error occurs, providing consistent UX. The fire-and-forget persistence with error handling via toast is appropriate for this non-blocking operation.

Based on learnings, the usage of PreferenceGroup.LANGUAGE for both the key and group parameters is correct and consistent with the codebase pattern.


81-126: LGTM! Proper ARIA attributes and accessibility.

The dialog structure includes all necessary ARIA attributes:

  • role="dialog" with aria-modal="true" for modal semantics
  • aria-hidden to hide from assistive tech when closed
  • aria-labelledby pointing to the dialog title
  • aria-current="true" on the selected language for screen readers

Based on learnings, focus restoration and keyboard handling (Escape key, focus trap) are correctly implemented in the parent components (NavigationDrawerBody and Drawer).

tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts (2)

38-41: Scoping the close-button lookup to the drawer improves selector safety

Using const navigationDrawer = page.getByTestId('navigation-drawer'); then navigationDrawer.getByLabel('Close Drawer') keeps the selector local to the drawer and avoids accidentally hitting similarly-labeled controls elsewhere. This is a solid improvement with no downsides.


142-177: drawerLinks updates align with the new IA and keep fragile URLs flexible

The updated drawerLinks structure matches the described burger menu:

  • Splitting the main section into Read, Learn, and My Quran with appropriate local hrefs.
  • Adding “More” and “Our Projects” items with correct internal/external URLs and _blank targets for external properties.
  • Including Become A Monthly Donor at the end, pointing to https://donate.quran.foundation with _blank, which pairs well with the dedicated donation test.
  • Leaving href: '' for dynamic or frequently changing destinations (e.g., Read, Quran For Android, Quran iOS) so the generic link test doesn’t over-constrain those URLs, while the focused app-link test handles store URLs explicitly.

This also follows the repository preference to use hard-coded route paths in focused integration tests rather than env-driven URLs. Based on learnings, this looks correct and maintainable.

@afifvdin
Copy link
Collaborator Author

update the approval status @coderabbitai

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 25, 2025

@afifvdin: I'll approve this pull request for you.

✅ Actions performed

Comments resolved and changes approved.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (2)
tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts (1)

142-177: Data structure correctly reflects the new drawer layout.

The updated drawerLinks array properly represents the restructured navigation drawer with Main Navigation, More section, Our Projects, and Fundraising links.

Minor observation: The Read link (line 144) has an empty href because it dynamically redirects to continue-reading. The existing comment at line 89 documents empty hrefs for app store links, but doesn't mention the Read link case. Consider adding a brief comment for clarity:

 const drawerLinks = [
   // Main Navigation Links
+  // Note: 'Read' href is empty because it dynamically redirects to continue-reading URL
   { text: 'Read', href: '', target: '' },
src/components/Navbar/NavbarBody/index.tsx (1)

124-134: Consider memoizing callback functions.

The openNavigationDrawer and openSearchDrawer functions are recreated on every render. Since this component is wrapped with memo and these callbacks are passed to child components, memoizing them with useCallback could prevent unnecessary re-renders.

Apply this diff:

+import { memo, useCallback, useEffect, useRef, useState } from 'react';

  // ... other code ...

-  const openNavigationDrawer = () => {
+  const openNavigationDrawer = useCallback(() => {
     logDrawerOpenEvent('navigation');
     dispatch(setIsNavigationDrawerOpen(true));
-  };
+  }, [dispatch]);

-  const openSearchDrawer = () => {
+  const openSearchDrawer = useCallback(() => {
     logDrawerOpenEvent('search');
     dispatch(setIsSearchDrawerOpen(true));
     // reset the disable transition state
     dispatch(setDisableSearchDrawerTransition(false));
-  };
+  }, [dispatch]);

As per coding guidelines on React memoization best practices.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c933262 and e94d121.

📒 Files selected for processing (4)
  • src/components/Navbar/Drawer/index.tsx (4 hunks)
  • src/components/Navbar/NavbarBody/index.tsx (4 hunks)
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1 hunks)
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (22)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript with strict configuration
Use path alias @/ for src/ and @/dls/* for design system components

**/*.{ts,tsx}: Flag usage of any type in TypeScript - prefer unknown or specific types
Require explicit return types for public/exported functions in TypeScript
Prefer interface over type for object definitions in TypeScript
Use type for unions, intersections, and mapped types in TypeScript
Require enums for repeated raw values of the same category in TypeScript

**/*.{ts,tsx}: Flag any usage of any type - suggest unknown or specific types instead
Require explicit return types for all exported/public functions
Flag implicit any in function parameters
Ensure strict null checks are handled properly
Prefer interface for object shape definitions
Use type only for unions, intersections, and mapped types
Flag type usage where interface is more appropriate
Require enums when the same raw values appear multiple times
Flag repeated string/number literals that should be enums
Use PascalCase for types, interfaces, enums, and components
Use camelCase for variables, functions, and methods
Use UPPER_SNAKE_CASE for constants
Prefix Props interfaces with component name: ButtonProps, ModalProps
Flag unhandled Promise rejections
Require try-catch blocks for async operations
Ensure error types are properly typed, not any
Flag unused imports
Ensure imports are alphabetized within groups
Group import order: React → External packages → Internal modules → Types

**/*.{ts,tsx}: Flag any any types - use unknown or specific types instead
Require explicit return types on exported functions
Use interfaces for object shapes, types for unions in TypeScript
Use enums for repeated categorical values in TypeScript
Functions should be under 30 lines
Flag duplicated code - extract to reusable functions (DRY principle)
Require proper error handling with meaningful fallbacks
Flag unused imports, variables, or dead code
Comments shou...

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/Drawer/index.tsx
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

src/components/**/*.{ts,tsx}: Use React 18 functional components
Organize React components by feature in src/components/
Use TypeScript interfaces for props in functional components

src/components/**/*.{ts,tsx}: Use next-translate with t() for all user-facing text
Use Radix UI primitives for UI components
Use semantic HTML and ARIA attributes for accessibility
Use functional components only (no class components)

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/Drawer/index.tsx
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use API utilities from src/utils/auth/api.ts for authenticated requests

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/Drawer/index.tsx
**/*.*

📄 CodeRabbit inference engine (.cursor/rules/bug-handling-with-todo-comments.mdc)

Add comments starting with 'TODO:' to outline problems or bugs encountered in existing code

**/*.*: Utilize Early Returns: Use early returns to avoid nested conditions and improve readability.
Prefer conditional classes over ternary operators for class attributes.

**/*.*: Use comments sparingly and make them meaningful when you do use them
Don't comment on obvious things; avoid excessive or unclear comments that clutter the codebase and become outdated
Use comments to convey the 'why' behind specific actions and explain unusual behavior and potential pitfalls
Provide meaningful information about function behavior and explain unusual behavior and potential pitfalls in function comments

Order functions with those that are composing other functions appearing earlier in the file. For example, if you have a menu with multiple buttons, define the menu function above the buttons.

**/*.*: Always add helpful comments to the code explaining what you are doing
Never delete old comments, unless they are no longer relevant because the code has been rewritten or deleted

**/*.*: Only modify sections of the code related to the task at hand
Avoid modifying unrelated pieces of code
Accomplish goals with minimal code changes

**/*.*: Choose names for variables, functions, and classes that reflect their purpose and behavior
A name should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use specific names that provide a clearer understanding of what the variables represent and how they are used

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/Drawer/index.tsx
**/*.{js,ts,jsx,tsx,java,py,cs,cpp,c,go,rb,php}

📄 CodeRabbit inference engine (.cursor/rules/clean-code.mdc)

**/*.{js,ts,jsx,tsx,java,py,cs,cpp,c,go,rb,php}: Replace hard-coded values with named constants and use descriptive constant names that explain the value's purpose
Keep constants at the top of the file or in a dedicated constants file
Variables, functions, and classes should reveal their purpose with meaningful names that explain why something exists and how it's used
Avoid abbreviations in names unless they're universally understood
Use comments to explain why something is done a certain way, not what the code does - make the code self-documenting
Document APIs, complex algorithms, and non-obvious side effects in comments
Each function should do exactly one thing and be small and focused
If a function needs a comment to explain what it does, it should be split into smaller, more focused functions
Extract repeated code into reusable functions and share common logic through proper abstraction
Keep related code together and organize code in a logical hierarchy
Hide implementation details and expose clear interfaces through encapsulation
Move nested conditionals into well-named functions for better readability

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/Drawer/index.tsx
**/*.{ts,js,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/next-js-conventions.mdc)

**/*.{ts,js,jsx,tsx}: Rely on Next.js Pages Router for state changes
Prioritize Web Vitals (LCP, CLS, FID) in performance optimization
Minimize 'use client' usage - prefer server components and Next.js SSR features
Use 'use client' only for Web API access in small components
Avoid using 'use client' for data fetching or state management

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/Drawer/index.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/performance-optimization-rules.mdc)

Optimize Web Vitals (LCP, CLS, FID) in JavaScript and TypeScript files

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/Drawer/index.tsx
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/performance-optimization-rules.mdc)

Use dynamic loading for non-critical components using @src/components/dls/Spinner/Spinner.tsx

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/Drawer/index.tsx
src/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-functional-components.mdc)

src/components/**/*.tsx: Always use React functional components with hooks in React components
Use React.FC for functional components with props in React components

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/Drawer/index.tsx
**/*.{tsx,jsx}

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

**/*.{tsx,jsx}: Use functional components over class components in React
Keep React components small and focused
Extract reusable logic into custom hooks in React
Use composition over inheritance in React components
Split large React components into smaller, focused ones
Follow the Rules of Hooks in React
Use custom hooks for reusable logic in React
Keep React hooks focused and simple
Use appropriate dependency arrays in useEffect hooks
Implement cleanup in useEffect when needed in React components
Avoid nested hooks in React
Use useState for local component state in React
Implement Redux Toolkit for efficient Redux development for medium-complex state logic
Avoid prop drilling through proper state management
Use xstate for complex state logic in React applications
Implement proper memoization (useMemo, useCallback) in React components
Use React.memo for expensive components
Avoid unnecessary re-renders in React components
Implement proper lazy loading in React applications
Use proper key props in React lists
Profile and optimize React render performance
Re-use @src/components/FormBuilder/FormBuilder.tsx to build forms in React
Implement proper form validation in React applications
Handle form submission states properly in React forms
Show appropriate loading and error states in React forms
Implement proper accessibility for React forms
Handle async errors properly in React components
Show user-friendly error messages in React applications
Implement proper fallback UI in React components
Log errors appropriately in React applications
Handle edge cases gracefully in React components
Use semantic HTML elements in React components
Implement proper ARIA attributes in React components
Ensure keyboard navigation in React applications
Handle focus management in React components
Provide proper alt text for images in React components
Use proper imports/exports in React components
Document complex React component logic

**/*.{tsx,jsx}: Require functional components only (...

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/Drawer/index.tsx
src/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/redux-toolkit-best-practices.mdc)

src/**/*.tsx: Use selectors for accessing state in components
Use Redux hooks (useSelector, useDispatch) in components

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/Drawer/index.tsx
**/*.{ts,tsx,d.ts}

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

**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions in TypeScript
Use type for unions, intersections, and mapped types in TypeScript
Avoid using any, prefer unknown for unknown types in TypeScript
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns in TypeScript
Use PascalCase for type names and interfaces in TypeScript
Use camelCase for variables and functions in TypeScript
Use UPPER_CASE for constants in TypeScript
Use descriptive names with auxiliary verbs for boolean variables (e.g., isLoading, hasError) in TypeScript
Keep type definitions close to where they're used in TypeScript
Use explicit return types for public functions in TypeScript
Use arrow functions for callbacks and methods in TypeScript
Use function overloads for complex type scenarios in TypeScript
Prefer async/await over Promises in TypeScript
Use readonly for immutable properties in TypeScript
Leverage discriminated unions for type safety in TypeScript
Use type guards for runtime type checking in TypeScript
Implement proper null checking in TypeScript
Avoid type assertions unless necessary in TypeScript
Use try-catch blocks with typed catch clauses in TypeScript
Handle Promise rejections properly in TypeScript

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/Drawer/index.tsx
**/*.tsx

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

Prefix React component prop interfaces with 'Props' (e.g., ButtonProps) in TypeScript

**/*.tsx: Use functional components only - no class components in React
Props interface must be defined for React components
Use proper memoization (useCallback, useMemo) for callbacks and expensive computations in React components
Flag unnecessary useEffect - prefer event handlers or derived state in React components
Require skeleton loaders for async data to prevent layout shifts in React components
Use useSWR for data fetching, not raw fetch in React components
Use optimistic updates for predictable actions (bookmark, like) in React components
No hardcoded strings in UI
Use semantic HTML elements in React components
Add ARIA attributes where needed for accessibility in React components
Ensure keyboard navigation works in React components

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/Drawer/index.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx}: Flag functions exceeding 30 lines - should be split
Identify duplicated code that should be extracted to reusable functions (DRY principle)
Flag unused imports, variables, or dead code
Require proper error handling with meaningful fallbacks
Flag skipped linting rules without clear justification
Ensure complex logic has inline comments explaining 'why'
Ensure environment variables are used for configuration instead of hardcoded values
Flag missing input validation or sanitization
Flag undocumented complex business logic

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/Drawer/index.tsx
**/*.{tsx,jsx,ts,js}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{tsx,jsx,ts,js}: Flag hardcoded strings that should be localized
Ensure proper authentication checks for protected routes

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/Drawer/index.tsx
**/*.{tsx,jsx,css,module.css}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Ensure RTL (right-to-left) support is maintained

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/Drawer/index.tsx
**/*.{ts,tsx,js,jsx,json,env,yml,yaml}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Flag any hardcoded credentials or secrets

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/Drawer/index.tsx
{src/components,src/pages}/**/*.tsx

📄 CodeRabbit inference engine (.github/instructions/localization.instructions.md)

{src/components,src/pages}/**/*.tsx: Flag ALL hardcoded user-facing strings - must use next-translate hook for text content
Use descriptive, hierarchical key names for translation keys and group related translations under common prefixes
Ensure interpolation is used for dynamic values in translations instead of string concatenation
Flag string concatenation with translated text - use translation interpolation instead

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/Drawer/index.tsx
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.github/instructions/security.instructions.md)

**/*.{ts,tsx,js}: Flag ANY hardcoded credentials, API keys, or secrets in TypeScript/JavaScript code
Ensure all sensitive values use environment variables instead of hardcoding
Use NEXT_PUBLIC_ prefix only for client-side variables in environment variable declarations
Flag sensitive data exposed to client-side code
Require validation for all user inputs in TypeScript/JavaScript code
Flag direct usage of user input without sanitization, particularly with dangerouslySetInnerHTML
Ensure proper encoding for dynamic content to prevent injection attacks
Flag protected routes without auth checks in Next.js applications
Ensure proper session validation for authenticated requests
Flag sensitive operations without authentication checks

Files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/Drawer/index.tsx
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Playwright for integration tests

Files:

  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
tests/integration/**/*

📄 CodeRabbit inference engine (.github/instructions/testing.instructions.md)

Place integration tests in tests/integration/ directory

Files:

  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
tests/**/*.{ts,js}

📄 CodeRabbit inference engine (AGENTS.md)

Write integration tests with Playwright

Files:

  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
🧠 Learnings (71)
📓 Common learnings
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx:33-45
Timestamp: 2025-11-24T12:16:47.282Z
Learning: In src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx, focus restoration on language container close is implemented using languageButtonRef with useEffect (lines 48-52), which correctly restores focus to the trigger button when showLanguageContainer becomes false.
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/react-components.instructions.md:0-0
Timestamp: 2025-11-28T12:30:01.385Z
Learning: Applies to src/components/**/*.tsx,src/pages/**/*.tsx : Flag custom implementations of common UI patterns - suggest Radix UI alternatives: Dialog, Dropdown, Tooltip, Popover, etc.
📚 Learning: 2025-11-24T12:16:47.282Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx:33-45
Timestamp: 2025-11-24T12:16:47.282Z
Learning: In src/components/Navbar/NavigationDrawer/NavigationDrawerBody/index.tsx, focus restoration on language container close is implemented using languageButtonRef with useEffect (lines 48-52), which correctly restores focus to the trigger button when showLanguageContainer becomes false.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
  • src/components/Navbar/Drawer/index.tsx
📚 Learning: 2025-11-28T12:30:01.385Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/react-components.instructions.md:0-0
Timestamp: 2025-11-28T12:30:01.385Z
Learning: Applies to src/components/**/*.tsx,src/pages/**/*.tsx : Flag custom implementations of common UI patterns - suggest Radix UI alternatives: Dialog, Dropdown, Tooltip, Popover, etc.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/Drawer/index.tsx
📚 Learning: 2025-10-18T11:22:53.139Z
Learnt from: jonybekov
Repo: quran/quran.com-frontend-next PR: 2537
File: src/redux/slices/session.ts:36-42
Timestamp: 2025-10-18T11:22:53.139Z
Learning: In Redux selectors, avoid calling functions that read from external state (cookies, localStorage, etc.) like `isLoggedIn()` from utils/auth/login. Instead, use reactive hooks like `useIsLoggedIn` directly in components and keep selectors focused only on Redux state to ensure proper memoization.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:30:01.385Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/react-components.instructions.md:0-0
Timestamp: 2025-11-28T12:30:01.385Z
Learning: Applies to src/components/**/*.tsx,src/pages/**/*.tsx : Ensure keyboard navigation support

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:29:33.962Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-28T12:29:33.962Z
Learning: Applies to **/*.{tsx,jsx} : Flag unnecessary API calls in React - suggest caching with `useSWR`

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Avoid unnecessary re-renders in React components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:29:33.962Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-28T12:29:33.962Z
Learning: Applies to **/*.{tsx,jsx} : Check for proper memoization to prevent unnecessary re-renders in React

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-25T13:20:58.280Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/redux-toolkit-best-practices.mdc:0-0
Timestamp: 2025-11-25T13:20:58.280Z
Learning: Applies to src/**/*.tsx : Use selectors for accessing state in components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:29:33.962Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-28T12:29:33.962Z
Learning: Applies to **/*.{tsx,jsx} : Flag redundant state in React when `useSWR` already manages cached data

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:30:01.385Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/react-components.instructions.md:0-0
Timestamp: 2025-11-28T12:30:01.385Z
Learning: Applies to src/components/**/*.tsx,src/pages/**/*.tsx : Flag unnecessary state - derive values when possible

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Keep React hooks focused and simple

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:30:01.385Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/react-components.instructions.md:0-0
Timestamp: 2025-11-28T12:30:01.385Z
Learning: Applies to src/components/**/*.tsx,src/pages/**/*.tsx : Flag over-memoization where unnecessary

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:29:33.962Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-28T12:29:33.962Z
Learning: Applies to **/*.{tsx,jsx,ts,js} : Ensure proper authentication checks for protected routes

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:30:50.691Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/pre-pr-review.mdc:0-0
Timestamp: 2025-11-28T12:30:50.691Z
Learning: Applies to **/*.{ts,tsx} : Flag duplicated code - extract to reusable functions (DRY principle)

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-10-26T03:27:28.728Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2545
File: src/pages/reading-goal/index.tsx:31-35
Timestamp: 2025-10-26T03:27:28.728Z
Learning: In src/pages/reading-goal/index.tsx, the initialExampleKey is intentionally computed only when isLoggedIn() is true. This is by design: guest users can interact with the page and select options manually, but the example URL parameter only pre-selects an option for logged-in users (typically after being redirected back from login). The example selection is preserved through the authentication redirect flow.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:29:33.962Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-28T12:29:33.962Z
Learning: Applies to **/*.{tsx,jsx} : Flag missing ARIA attributes where needed in React

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx} : Implement proper prop types with TypeScript in React components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:30:01.385Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/react-components.instructions.md:0-0
Timestamp: 2025-11-28T12:30:01.385Z
Learning: Applies to src/components/**/*.tsx,src/pages/**/*.tsx : Flag missing or incomplete prop types

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:29:33.962Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-28T12:29:33.962Z
Learning: Applies to **/*.{tsx,jsx} : Flag prop drilling in React - suggest proper state management

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper ARIA attributes in React components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:30:50.691Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/pre-pr-review.mdc:0-0
Timestamp: 2025-11-28T12:30:50.691Z
Learning: Applies to **/*.tsx : Props interface must be defined for React components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/Drawer/index.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Use proper key props in React lists

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:30:50.691Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/pre-pr-review.mdc:0-0
Timestamp: 2025-11-28T12:30:50.691Z
Learning: Applies to **/*.tsx : Add ARIA attributes where needed for accessibility in React components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:30:50.691Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/pre-pr-review.mdc:0-0
Timestamp: 2025-11-28T12:30:50.691Z
Learning: Applies to **/*.tsx : Ensure keyboard navigation works in React components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:29:33.962Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-28T12:29:33.962Z
Learning: Applies to **/*.{tsx,jsx} : Require semantic HTML elements in React

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:29:33.962Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-28T12:29:33.962Z
Learning: Applies to **/*.{tsx,jsx} : Ensure proper memoization with `useMemo` and `useCallback` where appropriate in React

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Use React.memo for expensive components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper memoization (useMemo, useCallback) in React components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:30:50.691Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/pre-pr-review.mdc:0-0
Timestamp: 2025-11-28T12:30:50.691Z
Learning: Applies to **/*.tsx : Use proper memoization (useCallback, useMemo) for callbacks and expensive computations in React components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-25T13:20:09.790Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/next-js-conventions.mdc:0-0
Timestamp: 2025-11-25T13:20:09.790Z
Learning: Applies to **/*.{ts,js,jsx,tsx} : Rely on Next.js Pages Router for state changes

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:30:01.385Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/react-components.instructions.md:0-0
Timestamp: 2025-11-28T12:30:01.385Z
Learning: Applies to src/components/**/*.tsx,src/pages/**/*.tsx : Require `useMemo` for expensive computations

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Use useState for local component state in React

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Use custom hooks for reusable logic in React

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-25T13:19:57.738Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/next-js-app-router-rule.mdc:0-0
Timestamp: 2025-11-25T13:19:57.738Z
Learning: Applies to app/**/*.tsx : Follow Next.js documentation for best practices in data fetching, rendering, and routing when working with App Router components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-25T13:20:58.280Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/redux-toolkit-best-practices.mdc:0-0
Timestamp: 2025-11-25T13:20:58.280Z
Learning: Applies to src/**/*.tsx : Use Redux hooks (useSelector, useDispatch) in components

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-10-28T09:59:48.894Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2557
File: src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx:88-0
Timestamp: 2025-10-28T09:59:48.894Z
Learning: In src/components/QuranReader/ReflectionView/ReflectionBodyContainer/ReflectionBody/index.tsx, the empty `<div className={styles.separatorContainer} />` rendered when `isModal` is true is required for maintaining consistent spacing in modal view and should not be removed.

Applied to files:

  • src/components/Navbar/NavbarBody/index.tsx
📚 Learning: 2025-11-28T12:29:49.882Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/localization.instructions.md:0-0
Timestamp: 2025-11-28T12:29:49.882Z
Learning: Applies to {src/components,src/pages}/**/*.tsx : Use descriptive, hierarchical key names for translation keys and group related translations under common prefixes

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:30:50.691Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/pre-pr-review.mdc:0-0
Timestamp: 2025-11-28T12:30:50.691Z
Learning: Applies to **/*.tsx : No hardcoded strings in UI

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:31:06.687Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T12:31:06.687Z
Learning: Applies to src/components/**/*.{ts,tsx} : Use next-translate with `t()` for all user-facing text

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:29:33.962Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-28T12:29:33.962Z
Learning: Applies to **/*.{tsx,jsx,ts,js} : Flag hardcoded strings that should be localized

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:29:49.882Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/localization.instructions.md:0-0
Timestamp: 2025-11-28T12:29:49.882Z
Learning: Applies to {src/components,src/pages}/**/*.tsx : Flag ALL hardcoded user-facing strings - must use `next-translate` hook for text content

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:29:33.962Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-28T12:29:33.962Z
Learning: Applies to **/*.{tsx,jsx} : All user-facing text must use `next-translate` localization

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:29:49.882Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/localization.instructions.md:0-0
Timestamp: 2025-11-28T12:29:49.882Z
Learning: Applies to {src/components,src/pages}/**/*.tsx : Flag string concatenation with translated text - use translation interpolation instead

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-10-28T06:07:39.429Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2556
File: src/components/Navbar/NavigationDrawer/LanguageContainer.tsx:68-74
Timestamp: 2025-10-28T06:07:39.429Z
Learning: In the quran.com-frontend-next codebase, when calling addOrUpdateUserPreference for language preferences, the established pattern is to pass PreferenceGroup.LANGUAGE (which resolves to the string 'language') as both the key and group parameters. This is valid because PreferenceGroup is a string enum and this pattern is used consistently across the codebase (e.g., LanguageSelector.tsx).

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-10-20T15:16:53.776Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2540
File: src/components/QuranReader/TranslationView/TranslationText/TranslationAndReference.tsx:14-23
Timestamp: 2025-10-20T15:16:53.776Z
Learning: In the quran.com-frontend-next codebase, the `direction` property should be typed as `string` rather than using union types like `'ltr' | 'rtl'` to maintain consistency with the established codebase pattern (e.g., LanguageData interface in src/utils/locale.ts).

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-23T09:25:11.492Z
Learnt from: al-imam
Repo: quran/quran.com-frontend-next PR: 2593
File: src/components/Verse/TranslationFeedback/TranslationFeedbackModal.tsx:57-84
Timestamp: 2025-11-23T09:25:11.492Z
Learning: In src/components/Verse/TranslationFeedback/TranslationFeedbackModal.tsx, when the user has no preferred translations, the correct UX per spec is to show a single disabled option with the label "No translations in your preferences" in the Select dropdown. The form validation should remain in place to surface this state to the user, rather than silently disabling the textarea and submit button.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:29:33.962Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-28T12:29:33.962Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Flag undocumented complex business logic

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-23T10:08:59.786Z
Learnt from: al-imam
Repo: quran/quran.com-frontend-next PR: 2593
File: src/components/Verse/TranslationFeedback/TranslationPreview.tsx:62-62
Timestamp: 2025-11-23T10:08:59.786Z
Learning: In src/components/Verse/TranslationFeedback/TranslationPreview.tsx, the non-null assertion on translation.languageId is safe because the useVerseAndTranslation hook explicitly requests translationFields: 'resource_name,language_id' in its API params, guaranteeing that language_id will always be present in the returned translation data.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:30:12.447Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/security.instructions.md:0-0
Timestamp: 2025-11-28T12:30:12.447Z
Learning: Applies to **/*.{ts,tsx,js} : Flag sensitive data exposed to client-side code

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:30:50.691Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/pre-pr-review.mdc:0-0
Timestamp: 2025-11-28T12:30:50.691Z
Learning: Applies to **/*.{ts,tsx} : All user-facing text must use `t('key')` from next-translate for localization

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:30:01.385Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/react-components.instructions.md:0-0
Timestamp: 2025-11-28T12:30:01.385Z
Learning: Applies to src/components/**/*.tsx,src/pages/**/*.tsx : Flag missing ARIA labels on interactive elements

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:31:06.687Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T12:31:06.687Z
Learning: Applies to src/components/**/*.{ts,tsx} : Use semantic HTML and ARIA attributes for accessibility

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-17T07:24:45.226Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2567
File: src/components/ReadingProgressPage/ReadingProgressPage.module.scss:208-213
Timestamp: 2025-11-17T07:24:45.226Z
Learning: In the quran.com-frontend-next repository, when the Button component from `src/components/dls/Button/Button.tsx` is used, interactive states (:hover, :focus-visible, :active) are handled by the Button component's internal styles in `src/components/dls/Button/Button.module.scss`. Module-specific SCSS classes applied to Button instances should not duplicate these interactive states.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper accessibility for React forms

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{test,spec}.{tsx,jsx} : Test React components with screen readers for accessibility

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Provide proper alt text for images in React components

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Ensure keyboard navigation in React applications

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Handle focus management in React components

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:31:06.687Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T12:31:06.687Z
Learning: Applies to **/*.{ts,tsx} : Handle errors with meaningful fallbacks for async operations

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-28T12:30:50.691Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/pre-pr-review.mdc:0-0
Timestamp: 2025-11-28T12:30:50.691Z
Learning: Applies to **/*.{ts,tsx} : Require proper error handling with meaningful fallbacks

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-09-21T19:00:54.303Z
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/logout.tsx:11-12
Timestamp: 2025-09-21T19:00:54.303Z
Learning: In src/pages/logout.tsx, the developer mohsinayoob prefers to let decodeURIComponent exceptions bubble up to the global catch block rather than handling them locally. This ensures centralized error handling where all logout errors redirect to a safe default path, maintaining consistent fallback behavior instead of having multiple error handling points.

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Implement proper fallback UI in React components

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-11-25T13:21:18.501Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-11-25T13:21:18.501Z
Learning: Co-locate React component props with their components in TypeScript

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
  • src/components/Navbar/Drawer/index.tsx
📚 Learning: 2025-11-25T13:20:48.459Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-11-25T13:20:48.459Z
Learning: Applies to **/*.{tsx,jsx} : Document complex React component logic

Applied to files:

  • src/components/Navbar/NavigationDrawer/LanguageContainer.tsx
📚 Learning: 2025-10-22T20:39:29.339Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: tests/integration/learning-plans/guest-access.spec.ts:3-5
Timestamp: 2025-10-22T20:39:29.339Z
Learning: Repository: quran/quran.com-frontend-next
Context: tests/integration/learning-plans/guest-access.spec.ts and similar focused integration tests
Learning: For focused integration tests that validate specific route behavior, maintainers prefer hard-coded route paths (e.g., LP_URL, FIRST_LESSON_URL) over environment-based URLs to avoid unnecessary complexity.

Applied to files:

  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
📚 Learning: 2025-11-28T12:30:29.165Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/testing.instructions.md:0-0
Timestamp: 2025-11-28T12:30:29.165Z
Learning: Applies to **/*.test.tsx,tests/**/* : Prefer user-centric queries in tests (getByRole, getByText)

Applied to files:

  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
📚 Learning: 2025-10-22T20:42:09.214Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx:35-59
Timestamp: 2025-10-22T20:42:09.214Z
Learning: Preference for quran.com-frontend-next: keep single-use, page-specific components inline. Example: NotEnrolledMessage in src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx should remain inline; extract only if reused elsewhere.

Applied to files:

  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
📚 Learning: 2025-10-22T20:33:55.176Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:44-49
Timestamp: 2025-10-22T20:33:55.176Z
Learning: Preference: In quran.com-frontend-next, keep concise “why” comments for analytics/UX decision points (e.g., guest vs enrolled click handlers) but avoid verbose JSDoc that repeats params/types. Convert multi-line JSDoc to brief inline rationale comments, especially in src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx and similar analytics handlers.

Applied to files:

  • tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts
📚 Learning: 2025-11-28T12:30:38.634Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-28T12:30:38.634Z
Learning: Applies to **/*.{ts,tsx} : Ensure strict null checks are handled properly

Applied to files:

  • src/components/Navbar/Drawer/index.tsx
📚 Learning: 2025-11-28T12:30:38.634Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-28T12:30:38.634Z
Learning: Applies to **/*.{ts,tsx} : Prefix Props interfaces with component name: `ButtonProps`, `ModalProps`

Applied to files:

  • src/components/Navbar/Drawer/index.tsx
🧬 Code graph analysis (2)
src/components/Navbar/NavbarBody/index.tsx (2)
src/redux/slices/navbar.ts (1)
  • selectIsNavigationDrawerOpen (87-88)
src/utils/auth/login.ts (1)
  • isLoggedIn (17-17)
src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (6)
src/redux/slices/defaultSettings.ts (1)
  • selectIsUsingDefaultSettings (47-48)
src/utils/cookies.ts (1)
  • setLocaleCookie (6-11)
src/utils/eventLogger.ts (1)
  • logValueChange (74-85)
src/utils/auth/login.ts (1)
  • isLoggedIn (17-17)
src/utils/auth/api.ts (1)
  • addOrUpdateUserPreference (384-394)
src/utils/locale.ts (1)
  • getLocaleName (284-284)
🪛 ESLint
src/components/Navbar/NavbarBody/index.tsx

[error] 28-28: @/utils/auth/login import should occur after import of @/redux/slices/QuranReader/sidebarNavigation

(import/order)

🔇 Additional comments (6)
tests/integration/navigation-and-general-structure/sidebar/navigation-drawer.spec.ts (3)

38-41: Good use of scoped selectors.

Capturing the drawer element and scoping the close button selector to it improves test reliability and follows Playwright best practices for user-centric queries.


111-118: Correctly expands the collapsible before asserting links.

The click on navigation-links-our-projects is necessary since the Our Projects section is now a collapsible. The test properly expands it before verifying the app store links.


132-138: Race condition fix correctly applied.

The pattern of creating newPagePromise before clicking and awaiting it after follows Playwright's recommended approach for handling new page events. This ensures the event listener is active before the action triggers the new tab.

src/components/Navbar/Drawer/index.tsx (1)

37-47: Drawer id prop wiring and precedence fix look correct

The new id?: string prop is correctly threaded through: a provided id now consistently takes precedence for both the DOM id and data-testid, and the previous settings-drawer default is preserved via the explicit parentheses, which also resolve the earlier operator-precedence bug. The data-testid being present only when open is a reasonable testing convention as long as consumers expect it.

Also applies to: 89-99, 160-171

src/components/Navbar/NavigationDrawer/LanguageContainer.tsx (1)

25-79: Robust language-change flow and error handling

This component is well-structured: props are typed cleanly, the language-change pipeline (Redux reset, logValueChange, setLanguage, cookie, and addOrUpdateUserPreference) follows existing patterns, and the try/finally ensures onBack() runs even if something throws. The toast-based handleLanguagePersistError gives a clear Undo/Continue path and correctly uses the previous lang value for rollback. ARIA attributes (dialog role, aria-modal, aria-hidden, aria-labelledby, aria-current) and localization via t() are all in good shape.

Also applies to: 81-125

src/components/Navbar/NavbarBody/index.tsx (1)

137-142: Excellent accessibility improvement with dimmed backdrop and inert attribute.

The addition of the dimmed styling and inert attribute when the navigation drawer is open significantly improves both UX and accessibility. This prevents interaction with navbar elements while the drawer is open and provides clear visual feedback.

setIsNavigationDrawerOpen,
setIsSearchDrawerOpen,
} from '@/redux/slices/navbar';
import { isLoggedIn } from '@/utils/auth/login';
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix import order to comply with ESLint rules.

The import from @/utils/auth/login should be placed after the import from @/redux/slices/QuranReader/sidebarNavigation to maintain the project's import ordering convention.

Apply this diff to fix the import order:

 import {
   selectIsSidebarNavigationVisible,
   setIsSidebarNavigationVisible,
 } from '@/redux/slices/QuranReader/sidebarNavigation';
+import { isLoggedIn } from '@/utils/auth/login';
 import { logEvent } from '@/utils/eventLogger';

And remove the import from line 28.

🧰 Tools
🪛 ESLint

[error] 28-28: @/utils/auth/login import should occur after import of @/redux/slices/QuranReader/sidebarNavigation

(import/order)

🤖 Prompt for AI Agents
In src/components/Navbar/NavbarBody/index.tsx around line 28, the import from
'@/utils/auth/login' is out of order per ESLint import ordering rules; remove
the import at line 28 and re-add it after the import from
'@/redux/slices/QuranReader/sidebarNavigation' so the '@/utils' import appears
below the '@/redux' import, ensuring the project's import ordering convention
and ESLint compliance.

const { t } = useTranslation('common');
const dispatch = useDispatch();
const isNavigationDrawerOpen = useSelector(selectIsNavigationDrawerOpen);
const loggedIn = isLoggedIn();
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using a reactive hook for login state.

Calling isLoggedIn() directly reads from cookies on every render and is not reactive. Based on learnings, consider creating and using a useIsLoggedIn hook that subscribes to login state changes reactively, similar to how you're using useSelector for Redux state.

This would:

  • Avoid reading cookies on every render (performance)
  • Make the component reactive to login state changes
  • Follow the same pattern as other state management in this component

Example implementation:

// In src/hooks/auth/useIsLoggedIn.ts
import { useSyncExternalStore } from 'react';
import { isLoggedIn } from '@/utils/auth/login';

export const useIsLoggedIn = () => {
  return useSyncExternalStore(
    (callback) => {
      // Subscribe to cookie changes (implementation depends on your cookie library)
      // Return unsubscribe function
    },
    isLoggedIn,
    () => false // Server snapshot
  );
};

Then use it in the component:

const loggedIn = useIsLoggedIn();

Based on learnings, this approach ensures proper reactivity and memoization.

🤖 Prompt for AI Agents
In src/components/Navbar/NavbarBody/index.tsx around line 69, replace the direct
call to isLoggedIn() with a reactive hook: create a new hook
src/hooks/auth/useIsLoggedIn.ts that uses useSyncExternalStore to subscribe to
login state (subscribe to cookie/auth changes and return an unsubscribe) with
isLoggedIn as the getSnapshot and a safe serverSnapshot fallback, then import
and call useIsLoggedIn() in this file instead of isLoggedIn(); ensure the hook
handles subscription/unsubscription correctly and export it for reuse so the
component no longer reads cookies on every render and becomes reactive to login
state changes.

Comment on lines +150 to +176
{!loggedIn && <ProfileAvatarButton />}
<Button
tooltip={t('search.title')}
variant={ButtonVariant.Ghost}
onClick={openSearchDrawer}
shape={ButtonShape.Circle}
shouldFlipOnRTL={false}
ariaLabel={t('search.title')}
data-testid="open-search-drawer"
>
<IconSearch />
</Button>
<SearchDrawer />
<SidebarNavigation />
{loggedIn && <ProfileAvatarButton />}
<Button
tooltip={t('menu')}
variant={ButtonVariant.Ghost}
shape={ButtonShape.Circle}
onClick={openNavigationDrawer}
ariaLabel={t('aria.nav-drawer-open')}
data-testid="open-navigation-drawer"
>
<IconMenu />
</Button>
<SettingsDrawer />
<NavigationDrawer />
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Complex rightCTA section could benefit from extraction.

The rightCTA section contains multiple conditional renderings and component placements. While functionally correct, extracting this into smaller, focused sub-components could improve readability and maintainability.

Consider extracting into logical groups:

const NavbarSearchSection = memo(() => (
  <>
    <Button
      tooltip={t('search.title')}
      variant={ButtonVariant.Ghost}
      onClick={openSearchDrawer}
      shape={ButtonShape.Circle}
      shouldFlipOnRTL={false}
      ariaLabel={t('search.title')}
      data-testid="open-search-drawer"
    >
      <IconSearch />
    </Button>
    <SearchDrawer />
  </>
));

const NavbarMenuSection = memo(() => (
  <>
    <Button
      tooltip={t('menu')}
      variant={ButtonVariant.Ghost}
      shape={ButtonShape.Circle}
      onClick={openNavigationDrawer}
      ariaLabel={t('aria.nav-drawer-open')}
      data-testid="open-navigation-drawer"
    >
      <IconMenu />
    </Button>
    <SettingsDrawer />
    <NavigationDrawer />
  </>
));

This would make the rightCTA render more readable while maintaining the same functionality.

🤖 Prompt for AI Agents
In src/components/Navbar/NavbarBody/index.tsx around lines 150 to 176, the
rightCTA JSX block is large and mixes conditional rendering with several buttons
and drawers; extract logical subcomponents to simplify the parent component:
create a memoized NavbarSearchSection that contains the search Button and
SearchDrawer, and a memoized NavbarMenuSection that contains the menu Button,
SettingsDrawer and NavigationDrawer; replace the inline JSX with these new
subcomponents, keep the existing props/handlers (t, openSearchDrawer,
openNavigationDrawer, ButtonVariant/Shape, aria/data-testid attributes) and
preserve the conditional rendering of ProfileAvatarButton (render before search
when !loggedIn and after navigation when loggedIn); ensure imports and memo are
added and run type checks.

Comment on lines +59 to +79
const onLanguageChange = async (newLocale: string) => {
try {
if (isUsingDefaultSettings) {
dispatch(resetSettings(newLocale));
}
logValueChange('locale', lang, newLocale);

await setLanguage(newLocale);
setLocaleCookie(newLocale);

if (isLoggedIn()) {
addOrUpdateUserPreference(
PreferenceGroup.LANGUAGE,
newLocale,
PreferenceGroup.LANGUAGE,
).catch(handleLanguagePersistError);
}
} finally {
onBack();
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Optionally short‑circuit when clicking the already‑selected language

Right now onLanguageChange runs the full flow even if newLocale === lang (logging, setLanguage, cookie write, preference call). To avoid redundant work and noisy logs, you could add an early return:

-  const onLanguageChange = async (newLocale: string) => {
+  const onLanguageChange = async (newLocale: string) => {
+    if (newLocale === lang) {
+      onBack();
+      return;
+    }
     try {
       if (isUsingDefaultSettings) {
         dispatch(resetSettings(newLocale));
       }
       logValueChange('locale', lang, newLocale);
       …

This keeps behavior the same for real changes while making “re-select current language” a cheap no-op that just closes the sheet.

Also applies to: 110-123

🤖 Prompt for AI Agents
In src/components/Navbar/NavigationDrawer/LanguageContainer.tsx around lines
59-79 (and likewise apply to lines 110-123), add an early short-circuit: if
newLocale === lang then call onBack() and return immediately before performing
logging, setLanguage, cookie write, or preference calls; this makes re-selecting
the current language a cheap no-op while preserving the sheet-close behavior.

@osamasayed osamasayed requested a review from Copilot November 30, 2025 17:12
Copilot finished reviewing on behalf of osamasayed November 30, 2025 17:17
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 52 out of 57 changed files in this pull request and generated 6 comments.

Comment on lines +100 to +114
{suffix && (
<div
className={classNames(styles.suffixContainer, {
[styles.suffixRotated]: shouldRotateSuffixOnToggle && isOpen,
})}
onClick={onSuffixClicked}
onKeyDown={onSuffixKeyDown}
{...(shouldSuffixTrigger && {
role: 'button',
tabIndex: 0,
})}
>
{suffix}
</div>
)}
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

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

The suffix element conditionally adds role="button" and tabIndex={0} when shouldSuffixTrigger is true, but it's wrapped in a <div> that always has click and keydown handlers. When shouldSuffixTrigger is false, the div still receives keyboard events and has no role, which may cause accessibility issues.

Consider either:

  1. Only attaching event handlers when shouldSuffixTrigger is true
  2. Always setting an appropriate ARIA role when the element is interactive (has event handlers)

Copilot uses AI. Check for mistakes.
);
};
},
);
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

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

The Button component now uses forwardRef but doesn't set a display name, which is a React best practice for debugging purposes. When this component appears in React DevTools or error stack traces, it will show as "Anonymous" instead of "Button".

Add a display name:

Button.displayName = 'Button';

Copilot uses AI. Check for mistakes.
Comment on lines +76 to +77
} finally {
onBack();
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

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

The onLanguageChange function always calls onBack() in the finally block, even if an error occurs during language change. This means the language container will be hidden even when the language change fails, which could confuse users since the UI will close before they know if the operation succeeded or failed.

Consider moving onBack() to the end of the try block so it only executes on success:

const onLanguageChange = async (newLocale: string) => {
  try {
    if (isUsingDefaultSettings) {
      dispatch(resetSettings(newLocale));
    }
    logValueChange('locale', lang, newLocale);

    await setLanguage(newLocale);
    setLocaleCookie(newLocale);

    if (isLoggedIn()) {
      addOrUpdateUserPreference(
        PreferenceGroup.LANGUAGE,
        newLocale,
        PreferenceGroup.LANGUAGE,
      ).catch(handleLanguagePersistError);
    }
    
    onBack(); // Only call if successful
  } catch (error) {
    // Handle error appropriately
  }
};
Suggested change
} finally {
onBack();
onBack(); // Only call if successful
} catch (error) {
toast(t('error.language-change-failed'), {
status: ToastStatus.Error,
});

Copilot uses AI. Check for mistakes.
Comment on lines +42 to 51
<div
className={classNames(styles.contentContainer, {
[styles.dimmed]: isNavigationDrawerOpen,
})}
inert={isNavigationDrawerOpen || undefined}
aria-hidden={isNavigationDrawerOpen || undefined}
>
<Component {...pageProps} />
</div>
<AudioPlayer />
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

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

The AudioPlayer component is placed inside the conditional dimming/inert wrapper. When the navigation drawer is open, the audio player becomes inert and hidden from screen readers (inert and aria-hidden), which would prevent users from controlling audio playback while the drawer is open.

The AudioPlayer should likely remain accessible even when the navigation drawer is open. Consider moving it outside the dimmed wrapper:

<Component {...pageProps} />
</div>
<AudioPlayer />

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +71
const PROJECTS: ProjectItem[] = [
{
title: 'Quran.com',
href: QURAN_URL,
eventName: 'navigation_drawer_project_quran_com',
},
{
title: 'Quran For Android',
href: EXTERNAL_ROUTES.QURAN_ANDROID,
eventName: 'navigation_drawer_project_quran_android',
},
{
title: 'Quran iOS',
href: EXTERNAL_ROUTES.QURAN_IOS,
eventName: 'navigation_drawer_project_quran_ios',
},
{
title: 'QuranReflect.com',
href: EXTERNAL_ROUTES.QURAN_REFLECT,
eventName: 'navigation_drawer_project_quran_reflect',
},
{
title: 'Sunnah.com',
href: EXTERNAL_ROUTES.SUNNAH,
eventName: 'navigation_drawer_project_sunnah',
},
{
title: 'Nuqayah.com',
href: EXTERNAL_ROUTES.NUQAYAH,
eventName: 'navigation_drawer_project_nuqayah',
},
{
title: 'Legacy.quran.com',
href: EXTERNAL_ROUTES.LEGACY_QURAN_COM,
eventName: 'navigation_drawer_project_legacy',
},
{
title: 'Corpus.quran.com',
href: EXTERNAL_ROUTES.CORPUS_QURAN_COM,
eventName: 'navigation_drawer_project_corpus',
},
];
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

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

The project titles in the PROJECTS array are hardcoded strings that should be localized. These are user-facing text elements that appear in the navigation drawer.

All project titles should use translation keys from next-translate. For example:

const PROJECTS: ProjectItem[] = [
  {
    title: t('projects.quran-com'),
    href: QURAN_URL,
    eventName: 'navigation_drawer_project_quran_com',
  },
  // ... rest of projects
];

However, since this is inside a constant declaration outside the component, you'll need to move this array inside the component function where t is available, or use the raw translation keys and translate them when rendering.

Copilot generated this review using guidance from repository custom instructions.
<IconSearch />
</Button>
<SearchDrawer />
<SidebarNavigation />
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

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

The SidebarNavigation component is now rendered unconditionally. Previously, it was conditionally rendered based on shouldRenderSidebarNavigation. This could potentially render the component even when it shouldn't be visible, which may cause unnecessary rendering or side effects.

The previous logic was:

{shouldRenderSidebarNavigation && <SidebarNavigation />}

Consider restoring the conditional rendering to avoid rendering components that shouldn't be shown.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants