-
-
Notifications
You must be signed in to change notification settings - Fork 529
[QF-3518] open learning plans for guest users #2589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: testing
Are you sure you want to change the base?
Conversation
…updating enrollUser function to accept enrollment method as a parameter.
…, updating components to utilize it, and simplifying the enrollment process for logged-in users. Adjusted StartOrContinueLearning and StatusHeader components to streamline user experience and removed unnecessary checks for enrollment status.
…the NotEnrolledNotice component along with its associated styles, streamlining the course enrollment experience.
…ation process and reduce code complexity.
…module.scss to streamline the codebase.
|
Note Other AI code review bot(s) detectedCodeRabbit 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. WalkthroughReplaces guest-enrollment flow with a unified enroll-user approach (new hook and EnrollmentMethod), removes guest enrollment Redux slice and NotEnrolledNotice, updates components/pages to use manual/automatic enrollment or redirect unauthenticated users, adds "start-here" localization and updates a CTA label. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Browser as "Client (Lesson Page)"
participant Hook as "useEnrollUser"
participant Auth as "AuthService"
participant API as "enrollUser API"
User->>Browser: Open lesson URL
Browser->>Browser: DataFetcher fetches lesson
Browser->>Hook: onFetchSuccess -> enroll(courseId, AUTOMATIC)
activate Hook
Hook->>Auth: isLoggedIn()
alt logged in
Auth-->>Hook: true
Hook->>API: POST /enroll { courseId, enrollmentMethod: AUTOMATIC }
API-->>Hook: { success: true }
Hook-->>Browser: success
else not logged in
Auth-->>Hook: false
Hook-->>Browser: { success: false }
Browser->>User: redirect to login (or navigate to first lesson if guest access allowed)
end
deactivate Hook
Browser->>User: Render lesson content (NextSeoWrapper / LessonView)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this 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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (16)
locales/en/learn.json(1 hunks)src/components/Course/Buttons/StartOrContinueLearning/index.tsx(2 hunks)src/components/Course/CourseDetails/StatusHeader/index.tsx(5 hunks)src/components/Course/CourseDetails/Tabs/Syllabus/Syllabus.module.scss(0 hunks)src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx(2 hunks)src/components/Course/LessonContent/index.tsx(2 hunks)src/components/Course/NotEnrolledNotice/NotEnrolledNotice.module.scss(0 hunks)src/components/Course/NotEnrolledNotice/index.tsx(0 hunks)src/hooks/auth/useEnrollUser.ts(1 hunks)src/hooks/auth/useGuestEnrollment.ts(0 hunks)src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx(0 hunks)src/redux/slices/guestEnrollment.ts(0 hunks)src/redux/store.ts(0 hunks)src/redux/types/SliceName.ts(0 hunks)src/utils/auth/api.ts(2 hunks)types/auth/EnrollmentMethod.ts(1 hunks)
💤 Files with no reviewable changes (8)
- src/components/Course/CourseDetails/Tabs/Syllabus/Syllabus.module.scss
- src/components/Course/NotEnrolledNotice/index.tsx
- src/redux/slices/guestEnrollment.ts
- src/redux/store.ts
- src/redux/types/SliceName.ts
- src/components/Course/NotEnrolledNotice/NotEnrolledNotice.module.scss
- src/hooks/auth/useGuestEnrollment.ts
- src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
🧰 Additional context used
📓 Path-based instructions (14)
**/*.*
📄 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:
locales/en/learn.jsontypes/auth/EnrollmentMethod.tssrc/components/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.tsxsrc/utils/auth/api.ts
locales/**
📄 CodeRabbit inference engine (CLAUDE.md)
Keep translation files under locales/[lang]/ using next-translate conventions
Files:
locales/en/learn.json
**/*.{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:
types/auth/EnrollmentMethod.tssrc/components/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.tsxsrc/utils/auth/api.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/react.mdc)
Use xstate for complex state logic
Files:
types/auth/EnrollmentMethod.tssrc/components/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.tsxsrc/utils/auth/api.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 usingany, preferunknownfor 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:
types/auth/EnrollmentMethod.tssrc/components/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.tsxsrc/utils/auth/api.ts
**/types/**/*.{ts,d.ts}
📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)
**/types/**/*.{ts,d.ts}: Export types and interfaces from dedicated type files when shared
Place shared types in atypesdirectory
Files:
types/auth/EnrollmentMethod.ts
{src,types}/**/*.ts?(x)
📄 CodeRabbit inference engine (CLAUDE.md)
Use TypeScript throughout the codebase with strict configuration
Files:
types/auth/EnrollmentMethod.tssrc/components/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.tsxsrc/utils/auth/api.ts
{src,types}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use path aliases @/ for src and @/dls/* for design system imports
Files:
types/auth/EnrollmentMethod.tssrc/components/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.tsxsrc/utils/auth/api.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/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/components/Course/CourseDetails/StatusHeader/index.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/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/components/Course/CourseDetails/StatusHeader/index.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/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/components/Course/CourseDetails/StatusHeader/index.tsx
src/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Prefer React functional components for UI implementation
Files:
src/components/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/components/Course/CourseDetails/StatusHeader/index.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/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/components/Course/CourseDetails/StatusHeader/index.tsx
src/utils/auth/api.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Place authentication API utilities in src/utils/auth/api.ts
Files:
src/utils/auth/api.ts
🧠 Learnings (17)
📓 Common learnings
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:26-27
Timestamp: 2025-10-22T20:51:18.747Z
Learning: Analytics naming convention in quran.com-frontend-next: For syllabus day clicks, retain the legacy event name 'course_syllabus_day' for logged-in users to preserve existing dashboards; only guest flows introduce the 'guest_' prefix (e.g., 'guest_course_syllabus_day'). Apply concise inline "why" comments near such analytics decisions to prevent accidental renaming.
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.
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: 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.
📚 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/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/Course/LessonContent/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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 : Always use React functional components with hooks.
Applied to files:
src/components/Course/LessonContent/index.tsxsrc/hooks/auth/useEnrollUser.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} : Use custom hooks for reusable logic
Applied to files:
src/components/Course/LessonContent/index.tsxsrc/hooks/auth/useEnrollUser.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 **/use*.{tsx,jsx} : Keep hooks focused and simple
Applied to files:
src/components/Course/LessonContent/index.tsxsrc/hooks/auth/useEnrollUser.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} : Extract reusable logic into custom hooks
Applied to files:
src/components/Course/LessonContent/index.tsxsrc/hooks/auth/useEnrollUser.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} : Use appropriate dependency arrays in useEffect
Applied to files:
src/components/Course/LessonContent/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 useState for local component state
Applied to files:
src/components/Course/LessonContent/index.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/Course/LessonContent/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/Course/LessonContent/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/Course/LessonContent/index.tsx
📚 Learning: 2025-10-22T20:51:18.747Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:26-27
Timestamp: 2025-10-22T20:51:18.747Z
Learning: Analytics naming convention in quran.com-frontend-next: For syllabus day clicks, retain the legacy event name 'course_syllabus_day' for logged-in users to preserve existing dashboards; only guest flows introduce the 'guest_' prefix (e.g., 'guest_course_syllabus_day'). Apply concise inline "why" comments near such analytics decisions to prevent accidental renaming.
Applied to files:
src/components/Course/CourseDetails/Tabs/Syllabus/index.tsxsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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:
src/components/Course/Buttons/StartOrContinueLearning/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/Course/Buttons/StartOrContinueLearning/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/hooks/auth/useEnrollUser.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/utils/auth/api.ts : Place authentication API utilities in src/utils/auth/api.ts
Applied to files:
src/hooks/auth/useEnrollUser.tssrc/utils/auth/api.ts
🔇 Additional comments (3)
locales/en/learn.json (1)
41-41: Newstart-herecopy and key look consistentKey naming and casing match existing learn namespace entries; no issues from i18n or UX perspective.
src/components/Course/Buttons/StartOrContinueLearning/index.tsx (1)
23-25: Guard against missing redirect lesson slugThe simplified redirect logic is clear, but if a course ever has neither
continueFromLessonnor any lessons,redirectToLessonSlugbecomesundefined, andgetLessonNavigationUrl(slug, redirectToLessonSlug)will build an invalid route.TODO: Either assert the invariant or guard the edge case. For example:
- const redirectToLessonSlug = continueFromLesson || lessons?.[0]?.slug; + const redirectToLessonSlug = continueFromLesson || lessons?.[0]?.slug; + + if (!redirectToLessonSlug) { + // TODO: No lesson to continue from; consider disabling the button or rendering nothing. + return null; + }If the domain model guarantees at least one lesson for any course that renders this component, just document that assumption in a brief comment.
Also applies to: 26-33, 35-35
src/components/Course/CourseDetails/StatusHeader/index.tsx (1)
14-19: Unified “Start here” flow looks correct; tidy up EnrollmentMethod import and error handling detailsThe overall flow matches the new design well: guests are either taken straight to the first lesson (when
allowGuestAccess) or to login, and logged‑in users enroll withEnrollmentMethod.Manual, update cached course state, and then navigate to the first lesson. CTA vs non‑CTA behavior is also clear.A few refinements:
Avoid potential double Sentry logging
useEnrollUseralready logs errors to Sentry before rethrowing. The catch block here logs again:} catch (error) { logErrorToSentry(error, { metadata: { context: `${userType}_course_enrollment`, courseId: id, courseSlug: slug, }, }); toast(t('common:error.general'), { status: ToastStatus.Error }); }TODO: Decide where you want the single source of error logging. Options:
- Remove logging from
useEnrollUserand keep this richer context here, or- Keep logging in
useEnrollUserand drop the extralogErrorToSentryhere, retaining just the toast.Defensive mutate callback (optional)
If
useMutateWithoutRevalidationcan ever invoke the updater withundefined(e.g., cache not primed), spreadingcurrentCoursewould throw. To be safe:
mutate(makeGetCourseUrl(slug), (currentCourse: Course) => ({...currentCourse,isUserEnrolled: true,}));
mutate(makeGetCourseUrl(slug), (currentCourse?: Course) =>currentCourse? { ...currentCourse, isUserEnrolled: true }: currentCourse,);If the cache is guaranteed to be populated here, this is purely defensive.
Align EnrollmentMethod import path
As with the other files, standardize on the canonical
EnrollmentMethodmodule path:
- import EnrollmentMethod from '@/types/auth/EnrollmentMethod';
- import EnrollmentMethod from 'types/auth/EnrollmentMethod';
TODO: Address the logging duplication and import path consistency; consider the mutate guard if there’s any chance the cache entry is missing.
Also applies to: 34-42, 43-89, 91-101, 103-125
…o return success status, simplifying error handling, and removing unnecessary code from StatusHeader and LessonContent components. Implement automatic enrollment in LessonPage upon successful data fetch.
There was a problem hiding this 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
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/Course/CourseDetails/StatusHeader/index.tsx (1)
42-81: HardenonStartHereClickedloading state and navigation flowThe enrollment flow looks correct, but
setIsLoading(false)only runs if nothing betweenenrollUserInCourse,mutate, androuter.pushthrows. Also, awaitingrouter.pushisn’t necessary here and can cause a state update after unmount.You can make this more robust:
const onStartHereClicked = async (): Promise<void> => { @@ - // Logged-in user - enroll with MANUAL method - setIsLoading(true); - const { success } = await enrollUserInCourse(id, EnrollmentMethod.Manual); - - if (success) { - mutate(makeGetCourseUrl(slug), (currentCourse: Course) => ({ - ...currentCourse, - isUserEnrolled: true, - })); - - if (lessons?.length > 0) { - await router.push(getLessonNavigationUrl(slug, lessons[0].slug)); - } - } else { - toast(t('common:error.general'), { - status: ToastStatus.Error, - }); - } - - setIsLoading(false); + // Logged-in user - enroll with MANUAL method + setIsLoading(true); + try { + const { success } = await enrollUserInCourse(id, EnrollmentMethod.Manual); + + if (!success) { + toast(t('common:error.general'), { + status: ToastStatus.Error, + }); + return; + } + + mutate(makeGetCourseUrl(slug), (currentCourse: Course) => ({ + ...currentCourse, + isUserEnrolled: true, + })); + + if (lessons?.length > 0) { + void router.push(getLessonNavigationUrl(slug, lessons[0].slug)); + } + } finally { + setIsLoading(false); + } };This keeps the UX the same while ensuring loading state is always reset and avoiding unnecessary coupling to the navigation promise.
Also applies to: 83-88, 112-116
♻️ Duplicate comments (1)
src/hooks/auth/useEnrollUser.ts (1)
36-41: Align SentrytransactionNamewith shared “enroll_user” conventionPrevious feedback suggested using a shared transaction name for enrollment operations. To keep Sentry traces coherent with other enrollment paths, consider switching to the agreed name:
- logErrorToSentry(error, { - transactionName: 'useEnrollUser', + logErrorToSentry(error, { + transactionName: 'enroll_user', metadata: { courseId, enrollmentMethod }, });This makes it easier to aggregate all enrollment failures under a single transaction in Sentry.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (4)
src/components/Course/CourseDetails/StatusHeader/index.tsx(4 hunks)src/components/Course/LessonContent/index.tsx(0 hunks)src/hooks/auth/useEnrollUser.ts(1 hunks)src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx(3 hunks)
💤 Files with no reviewable changes (1)
- src/components/Course/LessonContent/index.tsx
🧰 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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/index.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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/index.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/react.mdc)
Use xstate for complex state logic
Files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.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 usingany, preferunknownfor 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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.tsx
src/pages/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use Next.js Pages Router; place all route files under src/pages
Files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
{src,types}/**/*.ts?(x)
📄 CodeRabbit inference engine (CLAUDE.md)
Use TypeScript throughout the codebase with strict configuration
Files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.tsx
src/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Prefer React functional components for UI implementation
Files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/index.tsx
{src,types}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use path aliases @/ for src and @/dls/* for design system imports
Files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.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/Course/CourseDetails/StatusHeader/index.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/Course/CourseDetails/StatusHeader/index.tsx
🧠 Learnings (17)
📓 Common learnings
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:26-27
Timestamp: 2025-10-22T20:51:18.747Z
Learning: Analytics naming convention in quran.com-frontend-next: For syllabus day clicks, retain the legacy event name 'course_syllabus_day' for logged-in users to preserve existing dashboards; only guest flows introduce the 'guest_' prefix (e.g., 'guest_course_syllabus_day'). Apply concise inline "why" comments near such analytics decisions to prevent accidental renaming.
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.
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: 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.
📚 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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/hooks/auth/useEnrollUser.tssrc/components/Course/CourseDetails/StatusHeader/index.tsx
📚 Learning: 2025-10-22T20:51:18.747Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:26-27
Timestamp: 2025-10-22T20:51:18.747Z
Learning: Analytics naming convention in quran.com-frontend-next: For syllabus day clicks, retain the legacy event name 'course_syllabus_day' for logged-in users to preserve existing dashboards; only guest flows introduce the 'guest_' prefix (e.g., 'guest_course_syllabus_day'). Apply concise inline "why" comments near such analytics decisions to prevent accidental renaming.
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/index.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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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: Refer to Next.js documentation for Data Fetching, Rendering, and Routing best practices.
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/hooks/auth/useEnrollUser.ts
📚 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} : Rely on Next.js Pages Router for state changes.
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/**/*.{ts,tsx} : Use Next.js Pages Router; place all route files under src/pages
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
📚 Learning: 2025-09-21T18:32:41.811Z
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/logout.tsx:12-17
Timestamp: 2025-09-21T18:32:41.811Z
Learning: In the Next.js codebase, redirect-only pages like src/pages/logout.tsx intentionally use GetServerSidePropsResult<any> in JSDoc comments because they only perform server-side redirects without passing meaningful data to client-side rendering.
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/hooks/auth/useEnrollUser.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} : Extract reusable logic into custom hooks
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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/hooks/auth/useEnrollUser.ts
📚 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/hooks/auth/useEnrollUser.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/utils/auth/api.ts : Place authentication API utilities in src/utils/auth/api.ts
Applied to files:
src/hooks/auth/useEnrollUser.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 memoization (useMemo, useCallback)
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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/Course/CourseDetails/StatusHeader/index.tsx
🧬 Code graph analysis (3)
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx (1)
types/auth/Course.ts (1)
Lesson(3-16)
src/hooks/auth/useEnrollUser.ts (3)
src/utils/auth/login.ts (1)
isLoggedIn(17-17)src/utils/auth/api.ts (1)
enrollUser(457-464)src/lib/sentry.ts (1)
logErrorToSentry(123-152)
src/components/Course/CourseDetails/StatusHeader/index.tsx (5)
src/components/dls/Toast/Toast.tsx (1)
useToast(86-96)src/utils/auth/login.ts (1)
isLoggedIn(17-17)src/utils/navigation.ts (3)
getLessonNavigationUrl(355-356)getLoginNavigationUrl(405-406)getCourseNavigationUrl(346-347)src/utils/auth/apiPaths.ts (1)
makeGetCourseUrl(145-145)types/auth/Course.ts (1)
Course(29-48)
…llUser function, enhancing clarity and simplifying the enrollment process.
There was a problem hiding this 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/hooks/auth/useEnrollUser.ts (1)
43-43: Add dependencies to satisfy exhaustive-deps rule.Previous review feedback requested adding
[enrollUser, isLoggedIn, logErrorToSentry]to the dependency array. While these imported functions are stable in practice, including them satisfies thereact-hooks/exhaustive-depslinting rule and follows React best practices.Apply this diff:
}, - [], + [enrollUser, isLoggedIn, logErrorToSentry], );As per coding guidelines and learnings: "Use appropriate dependency arrays in useEffect" and similar hooks.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
src/hooks/auth/useEnrollUser.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.*
📄 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/hooks/auth/useEnrollUser.ts
**/*.{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/hooks/auth/useEnrollUser.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/react.mdc)
Use xstate for complex state logic
Files:
src/hooks/auth/useEnrollUser.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 usingany, preferunknownfor 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/hooks/auth/useEnrollUser.ts
{src,types}/**/*.ts?(x)
📄 CodeRabbit inference engine (CLAUDE.md)
Use TypeScript throughout the codebase with strict configuration
Files:
src/hooks/auth/useEnrollUser.ts
{src,types}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use path aliases @/ for src and @/dls/* for design system imports
Files:
src/hooks/auth/useEnrollUser.ts
🧠 Learnings (10)
📓 Common learnings
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.
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:26-27
Timestamp: 2025-10-22T20:51:18.747Z
Learning: Analytics naming convention in quran.com-frontend-next: For syllabus day clicks, retain the legacy event name 'course_syllabus_day' for logged-in users to preserve existing dashboards; only guest flows introduce the 'guest_' prefix (e.g., 'guest_course_syllabus_day'). Apply concise inline "why" comments near such analytics decisions to prevent accidental renaming.
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.
📚 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/hooks/auth/useEnrollUser.ts
📚 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/hooks/auth/useEnrollUser.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} : Extract reusable logic into custom hooks
Applied to files:
src/hooks/auth/useEnrollUser.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} : Use custom hooks for reusable logic
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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/hooks/auth/useEnrollUser.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/utils/auth/api.ts : Place authentication API utilities in src/utils/auth/api.ts
Applied to files:
src/hooks/auth/useEnrollUser.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 memoization (useMemo, useCallback)
Applied to files:
src/hooks/auth/useEnrollUser.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/hooks/auth/useEnrollUser.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} : Use appropriate dependency arrays in useEffect
Applied to files:
src/hooks/auth/useEnrollUser.ts
🧬 Code graph analysis (1)
src/hooks/auth/useEnrollUser.ts (3)
src/utils/auth/login.ts (1)
isLoggedIn(17-17)src/utils/auth/api.ts (1)
enrollUser(457-464)src/lib/sentry.ts (1)
logErrorToSentry(123-152)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
🔇 Additional comments (5)
src/hooks/auth/useEnrollUser.ts (5)
8-18: Excellent documentation of error handling contract.The JSDoc clearly communicates that this hook doesn't throw (safe for fire-and-forget usage in automatic enrollment flows) and returns a result object instead. This addresses previous concerns and helps prevent unhandled promise rejections.
19-27: Good use of early return pattern.The early return for non-logged-in users prevents unnecessary API calls and improves readability, following coding guidelines effectively.
29-34: Success propagation correctly implemented.The hook now properly destructures and returns the
successflag from the backend response. This addresses previous feedback and allows callers to distinguish between backend success and failure cases.
36-38: Clarify transactionName feedback from previous review.A previous reviewer (osamasayed) commented: "
transactionName: 'enroll_user',1 level higher". The current implementation uses'useEnrollUser'as the transaction name. Please clarify:
- Should the transaction name be
'enroll_user'instead of'useEnrollUser'?- What does "1 level higher" mean in this context?
Based on learnings, analytics naming conventions matter for dashboard consistency. If
'enroll_user'is the established convention for enrollment events, the transaction name should match.
4-4: Import path is correct.The file properly uses
@/types/auth/EnrollmentMethod, which aligns with the coding guidelines ("Use path aliases @/ for src imports") and the modern convention across the codebase. While older code insrc/api.tsand somesrc/components/files use baretypes/paths, newer utilities and hooks consistently use the@/prefix. The original review comment suggesting a bare path was based on an outdated pattern.
There was a problem hiding this 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 removes guest enrollment functionality and implements enrollment method tracking to align with backend API changes. The changes enable automatic enrollment for logged-in users when they view lessons and track whether enrollment was manual (via "Start here" button) or automatic (when accessing lessons directly).
Key Changes:
- Removed guest enrollment infrastructure (Redux slice, hooks, and related components)
- Added
EnrollmentMethodenum to track manual vs automatic enrollment - Implemented automatic enrollment when logged-in users access lesson pages
- Updated enrollment API to accept
enrollmentMethodparameter
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
types/auth/EnrollmentMethod.ts |
New enum defining MANUAL and AUTOMATIC enrollment methods |
src/utils/auth/api.ts |
Updated enrollUser function to accept enrollment method parameter |
src/redux/types/SliceName.ts |
Removed GUEST_ENROLLMENT enum value |
src/redux/store.ts |
Removed guest enrollment from Redux store and persist config |
src/redux/slices/guestEnrollment.ts |
Deleted guest enrollment Redux slice |
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx |
Added automatic enrollment logic via onFetchSuccess callback |
src/hooks/auth/useGuestEnrollment.ts |
Deleted guest enrollment hooks |
src/hooks/auth/useEnrollUser.ts |
New hook for enrolling logged-in users with error handling |
src/components/Course/NotEnrolledNotice/index.tsx |
Deleted component no longer needed without guest enrollment checks |
src/components/Course/NotEnrolledNotice/NotEnrolledNotice.module.scss |
Deleted associated styles |
src/components/Course/LessonContent/index.tsx |
Removed enrollment checks and NotEnrolledNotice component usage |
src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx |
Removed enrollment checks - all lessons now clickable |
src/components/Course/CourseDetails/Tabs/Syllabus/Syllabus.module.scss |
Removed .notEnrolledLink styles |
src/components/Course/CourseDetails/StatusHeader/index.tsx |
Updated to use useEnrollUser hook with manual enrollment method, renamed "Enroll" to "Start here" |
src/components/Course/Buttons/StartOrContinueLearning/index.tsx |
Simplified to always show "Continue Learning" button |
locales/en/learn.json |
Added "start-here" translation key |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const handleFetchSuccess: (data: any) => void = useCallback( | ||
| (lesson: Lesson) => { | ||
| if (lesson?.course && !lesson.course.isUserEnrolled) { | ||
| enrollUserInCourse(lesson.course.id, EnrollmentMethod.Automatic); | ||
| } | ||
| }, | ||
| [enrollUserInCourse], | ||
| ); |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The automatic enrollment may trigger on every revalidation of the lesson data. Since onFetchSuccess is called in the DataFetcher's promise chain (line 48 of DataFetcher), it will execute every time SWR revalidates the data, not just on the initial fetch. This could result in redundant API calls to enroll the user even after they're already enrolled.
Consider adding a check to prevent re-enrollment or using a ref to track if enrollment has been attempted for this course.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The worry isn’t accurate.
We already gate on lesson.course.isUserEnrolled, so once the backend marks the user as enrolled, enrollUserInCourse stops running.
Plus DataFetcher uses useSWRImmutable, so it only fires on the initial fetch unless we manually revalidate.
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
Outdated
Show resolved
Hide resolved
…an reader from "Begin Now" to "Start Now" to enhance user engagement.
…finition by removing explicit type annotation, improving code readability.
There was a problem hiding this 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 17 out of 17 changed files in this pull request and generated 8 comments.
| "reflection-description-1": "Clicking \"Add Reflection\" will take you to QuranReflect, a platform for sharing personal reflections on the Quran. Unlike Tafsir (scholarly interpretation), reflections are personal insights and experiences related to the verses.", | ||
| "reflection-description-2": "If you post publicly, your reflection will be reviewed by the moderation team and become visible to the QuranReflect community.", | ||
| "start-here": "Start here", | ||
| "start-learning": "Start Learning", |
Copilot
AI
Nov 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The translation key 'start-learning' is still defined in the locale file but is no longer used anywhere in the code after the simplification of the StartOrContinueLearning component. This is dead code that should be removed from locales/en/learn.json.
| "start-learning": "Start Learning", |
…uppercase naming convention for consistency. Update related function calls in CourseDetails and LessonPage components to match the new naming, enhancing code clarity.
…returning the success status from enrollUser, improving error handling and reducing code complexity. Update LessonPage to handle specific enrollment errors and navigate accordingly.
There was a problem hiding this 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 (2)
src/hooks/auth/useEnrollUser.ts (2)
32-32: Fix theuseCallbackdependency array to satisfy React hooks rules.The empty dependency array violates
react-hooks/exhaustive-deps. WhileenrollUser,isLoggedIn, andlogErrorToSentryare module-level imports that won't change between renders, including them prevents linter warnings and documents the hook's dependencies explicitly.As per coding guidelines: "Use appropriate dependency arrays in useEffect hooks" and "Follow the Rules of Hooks in React."
Apply this diff:
- }, []); + }, [enrollUser, isLoggedIn, logErrorToSentry]);
25-30: Use safer type narrowing for the caught error.The caught
errorcould be any type (string, number, object, etc.), not just anErrorinstance. Checking withinstanceof Errorprevents runtime issues when logging or accessing error properties.As per coding guidelines: "Avoid type assertions unless necessary in TypeScript" and "Ensure error types are properly typed, not
any."Apply this diff:
} catch (error) { logErrorToSentry(error, { transactionName: 'useEnrollUser', metadata: { courseId, enrollmentMethod }, }); - return { success: false }; + return { + success: false, + error: error instanceof Error ? error : new Error(String(error)) + }; }Note: This assumes the return type should include an optional
errorproperty. If the current{ success: boolean }contract is sufficient, you can keep the existing return but still pass a normalized error to Sentry.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
src/hooks/auth/useEnrollUser.ts(1 hunks)src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx(3 hunks)
🧰 Additional context used
📓 Path-based instructions (19)
**/*.{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 ofanytype in TypeScript - preferunknownor specific types
Require explicit return types for public/exported functions in TypeScript
Preferinterfaceovertypefor object definitions in TypeScript
Usetypefor unions, intersections, and mapped types in TypeScript
Require enums for repeated raw values of the same category in TypeScript
**/*.{ts,tsx}: Flag any usage ofanytype - suggestunknownor specific types instead
Require explicit return types for all exported/public functions
Flag implicitanyin function parameters
Ensure strict null checks are handled properly
Preferinterfacefor object shape definitions
Usetypeonly for unions, intersections, and mapped types
Flagtypeusage whereinterfaceis more appropriate
Require enums when the same raw values appear multiple times
Flag repeated string/number literals that should be enums
UsePascalCasefor types, interfaces, enums, and components
UsecamelCasefor variables, functions, and methods
UseUPPER_SNAKE_CASEfor 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, notany
Flag unused imports
Ensure imports are alphabetized within groups
Group import order: React → External packages → Internal modules → Types
**/*.{ts,tsx}: Flag anyanytypes - useunknownor 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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
src/hooks/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Place custom React hooks in src/hooks/
Use useSWR for data fetching with caching
Files:
src/hooks/auth/useEnrollUser.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use API utilities from src/utils/auth/api.ts for authenticated requests
Files:
src/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 commentsOrder 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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 usingany, preferunknownfor 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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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
UseNEXT_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 withdangerouslySetInnerHTML
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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
src/pages/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
src/pages/**/*.{ts,tsx}: Use Next.js 14 with Pages Router (not App Router)
Protect routes using withAuth HOCUse Next.js 14 with Pages Router (NOT App Router) as the framework
Files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
**/*.{tsx,jsx,css,module.css}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Ensure RTL (right-to-left) support is maintained
Files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 usenext-translatehook 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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
🧠 Learnings (55)
📓 Common learnings
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.
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:26-27
Timestamp: 2025-10-22T20:51:18.747Z
Learning: Analytics naming convention in quran.com-frontend-next: For syllabus day clicks, retain the legacy event name 'course_syllabus_day' for logged-in users to preserve existing dashboards; only guest flows introduce the 'guest_' prefix (e.g., 'guest_course_syllabus_day'). Apply concise inline "why" comments near such analytics decisions to prevent accidental renaming.
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.
📚 Learning: 2025-11-25T13:18:33.501Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:18:33.501Z
Learning: Applies to src/hooks/**/*.{ts,tsx} : Place custom React hooks in src/hooks/
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.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/hooks/**/*.{ts,tsx} : Use useSWR for data fetching with caching
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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} : Extract reusable logic into custom hooks in React
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 Learning: 2025-11-25T13:20:26.998Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .cursor/rules/react-functional-components.mdc:0-0
Timestamp: 2025-11-25T13:20:26.998Z
Learning: Applies to src/components/**/*.tsx : Always use React functional components with hooks in React components
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
📚 Learning: 2025-11-25T13:18:33.501Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:18:33.501Z
Learning: Applies to src/**/*.{ts,tsx} : Use API utilities from src/utils/auth/api.ts for authenticated requests
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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/hooks/auth/useEnrollUser.ts
📚 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/hooks/auth/useEnrollUser.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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 appropriate dependency arrays in useEffect hooks
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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/hooks/auth/useEnrollUser.ts
📚 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/hooks/auth/useEnrollUser.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 error types are properly typed, not `any`
Applied to files:
src/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 **/*.{ts,tsx,js,jsx} : Require proper error handling with meaningful fallbacks
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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} : Handle error states with user-friendly messages in API and data handling
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 Learning: 2025-11-28T12:29:41.178Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/api-data.instructions.md:0-0
Timestamp: 2025-11-28T12:29:41.178Z
Learning: Applies to src/api.ts,src/hooks/**/*.ts,src/services/**/*.ts,src/utils/api/**/*.ts : Ensure meaningful error messages for users in API error handling
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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: Implement proper error handling with custom error types in TypeScript
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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: Applies to **/*.{ts,tsx,d.ts} : Use try-catch blocks with typed catch clauses in TypeScript
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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: Applies to **/*.{ts,tsx,d.ts} : Avoid type assertions unless necessary in TypeScript
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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/hooks/auth/useEnrollUser.ts
📚 Learning: 2025-11-28T12:29:41.178Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/api-data.instructions.md:0-0
Timestamp: 2025-11-28T12:29:41.178Z
Learning: Applies to src/api.ts,src/hooks/**/*.ts,src/services/**/*.ts,src/utils/api/**/*.ts : Require error states for all API-dependent components - flag blind trust in API responses
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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/hooks/auth/useEnrollUser.tssrc/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.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: Add tests for new functionality
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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} : Implement integration tests for complex React flows
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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 **/*.test.{ts,tsx} : New functionality needs tests
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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 **/*.test.{ts,tsx,js,jsx} : Ensure test coverage for edge cases and error scenarios
Applied to files:
src/hooks/auth/useEnrollUser.ts
📚 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 **/*.test.{ts,tsx} : Cover edge cases and error scenarios in tests
Applied to files:
src/hooks/auth/useEnrollUser.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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
📚 Learning: 2025-10-22T20:51:18.747Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:26-27
Timestamp: 2025-10-22T20:51:18.747Z
Learning: Analytics naming convention in quran.com-frontend-next: For syllabus day clicks, retain the legacy event name 'course_syllabus_day' for logged-in users to preserve existing dashboards; only guest flows introduce the 'guest_' prefix (e.g., 'guest_course_syllabus_day'). Apply concise inline "why" comments near such analytics decisions to prevent accidental renaming.
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
📚 Learning: 2025-11-24T11:52:10.333Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2589
File: src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx:24-33
Timestamp: 2025-11-24T11:52:10.333Z
Learning: In quran.com-frontend-next, DataFetcher's onFetchSuccess prop is typed as (data: BaseResponse) => void, but privateFetcher can return unwrapped types (e.g., Lesson) at runtime. Components using privateFetcher with onFetchSuccess may annotate callbacks as (data: any) => void to bridge this type mismatch, then treat the parameter as the actual returned type inside the callback body.
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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} : Flag any usage of `any` type - suggest `unknown` or specific types instead
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.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: Applies to **/*.{ts,tsx,d.ts} : Avoid using `any`, prefer `unknown` for unknown types in TypeScript
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 **/*.{ts,tsx} : Flag usage of `any` type in TypeScript - prefer `unknown` or specific types
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.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} : Use explicit types instead of `any` type without justification
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 any `any` types - use `unknown` or specific types instead
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 useSWR for data fetching, not raw fetch in React components
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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} : Avoid using 'use client' for data fetching or state management
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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} : Provide fallbacks for API responses - don't blindly trust data
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 **/*.{ts,tsx,js,jsx} : Ensure complex logic has inline comments explaining 'why'
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.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: Applies to **/*.{ts,tsx,d.ts} : Use arrow functions for callbacks and methods in TypeScript
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 `useCallback` for functions passed to child components
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 unnecessary `useEffect` usage in React
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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: Refer to Next.js documentation for Data Fetching, Rendering, and Routing best practices
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
📚 Learning: 2025-11-25T13:18:33.501Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:18:33.501Z
Learning: Applies to src/pages/**/*.{ts,tsx} : Use Next.js 14 with Pages Router (not App Router)
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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: Be an expert in Next.js Pages Router best practices
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.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/pages/**/*.{ts,tsx} : Use Next.js 14 with Pages Router (NOT App Router) as the framework
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
📚 Learning: 2025-11-25T13:18:33.501Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:18:33.501Z
Learning: Applies to src/pages/**/*.{ts,tsx} : Protect routes using withAuth HOC
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
📚 Learning: 2025-09-21T18:32:41.811Z
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/logout.tsx:12-17
Timestamp: 2025-09-21T18:32:41.811Z
Learning: In the Next.js codebase, redirect-only pages like src/pages/logout.tsx intentionally use GetServerSidePropsResult<any> in JSDoc comments because they only perform server-side redirects without passing meaningful data to client-side rendering.
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
📚 Learning: 2025-09-19T13:59:31.762Z
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/auth.tsx:143-149
Timestamp: 2025-09-19T13:59:31.762Z
Learning: In this Next.js codebase, the pattern of returning both `props: {}` and `redirect` together from getServerSideProps works correctly and is used consistently throughout multiple files including src/pages/auth.tsx and src/pages/logout.tsx. The Next.js runtime appears to ignore empty props when redirect is present.
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
🧬 Code graph analysis (1)
src/hooks/auth/useEnrollUser.ts (3)
src/utils/auth/login.ts (1)
isLoggedIn(17-17)src/utils/auth/api.ts (1)
enrollUser(457-464)src/lib/sentry.ts (1)
logErrorToSentry(123-152)
…nents. Consolidate enrollment handling into a single function, improve user navigation for guest users, and enhance error handling. Update button rendering logic for better clarity and user experience.
There was a problem hiding this 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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
src/components/Course/CourseDetails/StatusHeader/index.tsx(3 hunks)src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx(3 hunks)
🧰 Additional context used
📓 Path-based instructions (20)
src/pages/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
src/pages/**/*.{ts,tsx}: Use Next.js 14 with Pages Router (not App Router)
Protect routes using withAuth HOCUse Next.js 14 with Pages Router (NOT App Router) as the framework
Files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
**/*.{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 ofanytype in TypeScript - preferunknownor specific types
Require explicit return types for public/exported functions in TypeScript
Preferinterfaceovertypefor object definitions in TypeScript
Usetypefor unions, intersections, and mapped types in TypeScript
Require enums for repeated raw values of the same category in TypeScript
**/*.{ts,tsx}: Flag any usage ofanytype - suggestunknownor specific types instead
Require explicit return types for all exported/public functions
Flag implicitanyin function parameters
Ensure strict null checks are handled properly
Preferinterfacefor object shape definitions
Usetypeonly for unions, intersections, and mapped types
Flagtypeusage whereinterfaceis more appropriate
Require enums when the same raw values appear multiple times
Flag repeated string/number literals that should be enums
UsePascalCasefor types, interfaces, enums, and components
UsecamelCasefor variables, functions, and methods
UseUPPER_SNAKE_CASEfor 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, notany
Flag unused imports
Ensure imports are alphabetized within groups
Group import order: React → External packages → Internal modules → Types
**/*.{ts,tsx}: Flag anyanytypes - useunknownor 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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/index.tsx
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use API utilities from src/utils/auth/api.ts for authenticated requests
Files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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 commentsOrder 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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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 usingany, preferunknownfor 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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/index.tsx
**/*.{tsx,jsx,css,module.css}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Ensure RTL (right-to-left) support is maintained
Files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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 usenext-translatehook 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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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
UseNEXT_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 withdangerouslySetInnerHTML
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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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 witht()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/Course/CourseDetails/StatusHeader/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/Course/CourseDetails/StatusHeader/index.tsx
🧠 Learnings (40)
📓 Common learnings
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.
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:26-27
Timestamp: 2025-10-22T20:51:18.747Z
Learning: Analytics naming convention in quran.com-frontend-next: For syllabus day clicks, retain the legacy event name 'course_syllabus_day' for logged-in users to preserve existing dashboards; only guest flows introduce the 'guest_' prefix (e.g., 'guest_course_syllabus_day'). Apply concise inline "why" comments near such analytics decisions to prevent accidental renaming.
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.
📚 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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/index.tsx
📚 Learning: 2025-11-24T11:52:10.333Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2589
File: src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx:24-33
Timestamp: 2025-11-24T11:52:10.333Z
Learning: In quran.com-frontend-next, DataFetcher's onFetchSuccess prop is typed as (data: BaseResponse) => void, but privateFetcher can return unwrapped types (e.g., Lesson) at runtime. Components using privateFetcher with onFetchSuccess may annotate callbacks as (data: any) => void to bridge this type mismatch, then treat the parameter as the actual returned type inside the callback body.
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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} : Flag any usage of `any` type - suggest `unknown` or specific types instead
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.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: Applies to **/*.{ts,tsx,d.ts} : Avoid using `any`, prefer `unknown` for unknown types in TypeScript
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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} : Ensure error types are properly typed, not `any`
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 **/*.{ts,tsx} : Flag usage of `any` type in TypeScript - prefer `unknown` or specific types
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 useSWR for data fetching, not raw fetch in React components
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.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} : Use explicit types instead of `any` type without justification
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 any `any` types - use `unknown` or specific types instead
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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} : Avoid using 'use client' for data fetching or state management
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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} : Provide fallbacks for API responses - don't blindly trust data
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
📚 Learning: 2025-10-22T20:51:18.747Z
Learnt from: yousefdergham
Repo: quran/quran.com-frontend-next PR: 2547
File: src/components/Course/CourseDetails/Tabs/Syllabus/index.tsx:26-27
Timestamp: 2025-10-22T20:51:18.747Z
Learning: Analytics naming convention in quran.com-frontend-next: For syllabus day clicks, retain the legacy event name 'course_syllabus_day' for logged-in users to preserve existing dashboards; only guest flows introduce the 'guest_' prefix (e.g., 'guest_course_syllabus_day'). Apply concise inline "why" comments near such analytics decisions to prevent accidental renaming.
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsxsrc/components/Course/CourseDetails/StatusHeader/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 **/*.{ts,tsx,js,jsx} : Ensure complex logic has inline comments explaining 'why'
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.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: Applies to **/*.{ts,tsx,d.ts} : Use arrow functions for callbacks and methods in TypeScript
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 `useCallback` for functions passed to child components
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 unnecessary `useEffect` usage in React
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.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: Applies to **/*.{ts,tsx,d.ts} : Handle Promise rejections properly in TypeScript
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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} : Flag unhandled Promise rejections
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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} : Require proper error handling with meaningful fallbacks
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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 **/*.{ts,tsx,js,jsx} : Require proper error handling with meaningful fallbacks
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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} : Require try-catch blocks for async operations
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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} : Handle async errors properly in React components
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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: Refer to Next.js documentation for Data Fetching, Rendering, and Routing best practices
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
📚 Learning: 2025-11-25T13:18:33.501Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:18:33.501Z
Learning: Applies to src/pages/**/*.{ts,tsx} : Use Next.js 14 with Pages Router (not App Router)
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.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/pages/**/*.{ts,tsx} : Use Next.js 14 with Pages Router (NOT App Router) as the framework
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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: Be an expert in Next.js Pages Router best practices
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
📚 Learning: 2025-11-25T13:18:33.501Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:18:33.501Z
Learning: Applies to src/pages/**/*.{ts,tsx} : Protect routes using withAuth HOC
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx
📚 Learning: 2025-09-21T18:32:41.811Z
Learnt from: mohsinayoob
Repo: quran/quran.com-frontend-next PR: 2495
File: src/pages/logout.tsx:12-17
Timestamp: 2025-09-21T18:32:41.811Z
Learning: In the Next.js codebase, redirect-only pages like src/pages/logout.tsx intentionally use GetServerSidePropsResult<any> in JSDoc comments because they only perform server-side redirects without passing meaningful data to client-side rendering.
Applied to files:
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/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/Course/CourseDetails/StatusHeader/index.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/Course/CourseDetails/StatusHeader/index.tsx
📚 Learning: 2025-11-28T12:29:41.178Z
Learnt from: CR
Repo: quran/quran.com-frontend-next PR: 0
File: .github/instructions/api-data.instructions.md:0-0
Timestamp: 2025-11-28T12:29:41.178Z
Learning: Applies to src/api.ts,src/hooks/**/*.ts,src/services/**/*.ts,src/utils/api/**/*.ts : Require optimistic updates for predictable actions (like, bookmark, etc.) using mutate with optimisticData
Applied to files:
src/components/Course/CourseDetails/StatusHeader/index.tsx
📚 Learning: 2025-12-01T07:32:06.462Z
Learnt from: afifvdin
Repo: quran/quran.com-frontend-next PR: 2608
File: src/components/HeaderNavigation/index.tsx:18-18
Timestamp: 2025-12-01T07:32:06.462Z
Learning: In src/components/HeaderNavigation/index.tsx, the team prefers using JavaScript-based responsive logic (useIsMobile() hook) for button sizing over CSS media queries, despite potential SSR hydration considerations.
Applied to files:
src/components/Course/CourseDetails/StatusHeader/index.tsx
🧬 Code graph analysis (2)
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx (3)
src/utils/navigation.ts (2)
getLoginNavigationUrl(405-406)getLessonNavigationUrl(355-356)types/auth/Course.ts (2)
Lesson(3-16)Course(29-48)src/utils/auth/apiPaths.ts (1)
makeGetCourseUrl(145-145)
src/components/Course/CourseDetails/StatusHeader/index.tsx (6)
src/components/dls/Toast/Toast.tsx (1)
useToast(86-96)src/utils/auth/login.ts (2)
isLoggedIn(17-17)getUserType(24-27)src/utils/auth/apiPaths.ts (1)
makeGetCourseUrl(145-145)types/auth/Course.ts (1)
Course(29-48)src/utils/navigation.ts (2)
getLessonNavigationUrl(355-356)getCourseNavigationUrl(346-347)src/utils/eventLogger.ts (1)
logButtonClick(44-46)
🔇 Additional comments (8)
src/pages/learning-plans/[slug]/lessons/[lessonSlugOrId]/index.tsx (4)
1-1: LGTM! Imports correctly support the auto-enrollment flow.All added imports are used and necessary for the enrollment feature implementation.
Also applies to: 9-10, 13-14, 16-17
27-28: LGTM! Hooks are correctly initialized.Using
useMutateWithoutRevalidationis appropriate for optimistic cache updates after enrollment.
30-37: LGTM! Error handling correctly redirects unauthenticated users.The updated navigation flow properly uses utility functions to redirect to login with the current lesson URL as the redirect target.
82-82: LGTM! DataFetcher prop correctly wires auto-enrollment.The
onFetchSuccesscallback properly triggers enrollment when lesson data is successfully fetched.src/components/Course/CourseDetails/StatusHeader/index.tsx (4)
14-17: LGTM - Import changes align with new enrollment flow.The new imports for
useEnrollUserandEnrollmentMethodproperly support the unified enrollment approach, replacing the previous guest enrollment mechanism.
32-40: LGTM - Component setup is clean and addresses past feedback.The removal of
titlefrom destructuring resolves the previously flagged dead code issue. The hook setup properly initializes the newenrollUserInCoursefunction.
63-80: LGTM - Clear branching logic for enrollment flow.The function correctly handles all user states:
- Guest with
allowGuestAccess: navigates directly to first lesson- Guest without access: redirects to login with return URL
- Logged-in user: proceeds with enrollment
The early return pattern and analytics logging follow project conventions.
82-108: LGTM - Well-structured render logic with DRY principle.Extracting
startButtonas a reusable element eliminates duplication. The conditional rendering uses clean early returns, and returningnullfor enrolled users in CTA mode is appropriate.
Summary
Fixes QF-3520
This PR removes guest enrollment functionality and implements enrollment method tracking to align with backend changes in quran/quran.com-users-backend#798.
Key Changes:
EnrollmentMethodenum withMANUALandAUTOMATICvaluesuseEnrollUserhook for consistent enrollment handlingType of change
Changes Made
1. Guest Enrollment Removal
Deleted Files:
src/hooks/auth/useGuestEnrollment.ts- Removed guest enrollment hooks (useIsEnrolled,useEnrollGuest)src/redux/slices/guestEnrollment.ts- Removed guest enrollment Redux slicetests/integration/learning-plans/guest-access.spec.ts- Removed guest access integration testsModified Files:
src/redux/store.ts- RemovedguestEnrollmentfrom store configuration and persist whitelistsrc/redux/types/SliceName.ts- RemovedGUEST_ENROLLMENTenum valuesrc/components/Course/CourseDetails/Tabs/Syllabus/Syllabus.module.scss- Removed.notEnrolledLinkCSS styles2. Enrollment Method Tracking
New Files:
types/auth/EnrollmentMethod.ts- Enum for enrollment method trackingsrc/hooks/auth/useEnrollUser.ts- New hook for enrolling logged-in users with enrollment methodUpdated Components:
src/components/Course/LessonContent/index.tsxEnrollmentMethod.Automaticfor auto-enrollmentNotEnrolledNoticecomponent (no longer needed)src/components/Course/CourseDetails/StatusHeader/index.tsxuseEnrollUserhook withEnrollmentMethod.ManualallowGuestAccesscan now directly access lessons without enrollmentsrc/components/Course/Buttons/StartOrContinueLearning/index.tsxsrc/components/Course/CourseDetails/Tabs/Syllabus/index.tsx3. API Integration
src/utils/auth/api.tsenrollUserfunction signature to acceptenrollmentMethodparameterenrollmentMethodto backend APIBefore:
After:
4. Localization
locales/en/learn.json"start-here": "Start here"translation keyTest plan
Manual Testing
allowGuestAccess)Checklist
Dependencies
The backend must be deployed first, as it adds the required
enrollmentMethodfield to the/courses/enrollAPI endpoint.Breaking Changes
Guest Enrollment Removed:
allowGuestAccessflag allow guests to view content without enrollmentAPI Changes:
enrollmentMethodfield with enrollment requestsMigration Notes
Redux Persist:
guestEnrollmentslice has been removed from Redux storeUser Experience Changes
allowGuestAccessis enabled)Summary by CodeRabbit
New Features
Refactor
Localization
Style
Tests
✏️ Tip: You can customize this high-level summary in your review settings.