Skip to content

Make review popup#1227

Draft
jackrhoa wants to merge 2 commits intodevfrom
make_review_popup
Draft

Make review popup#1227
jackrhoa wants to merge 2 commits intodevfrom
make_review_popup

Conversation

@jackrhoa
Copy link
Collaborator

@jackrhoa jackrhoa commented Feb 13, 2026

What I did

  • Add a popup recommending the user create a review that appears after every 5 courses once the user has viewed at least 10 courses

Screenshots

  • After
Screenshot 2026-02-13 at 4 09 58 PM

Summary by CodeRabbit

  • New Features

    • Added a notification modal that displays on course pages when you've viewed multiple courses, informing you of your browsing activity.
  • Improvements

    • Extended the recently viewed items history storage capacity from 10 to 20 items for better retention of your browsing history.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 13, 2026

📝 Walkthrough

Walkthrough

The pull request adds a view-limiting modal feature to the recently viewed items tracking system. It increases the storage cap from 10 to 20 items, introduces a conditional modal trigger based on item count and course URL pattern matching, and includes a new modal template for display to users.

Changes

Cohort / File(s) Summary
Recently Viewed Tracking
tcf_website/static/common/recently_viewed.js
Updated storage logic to enforce a 20-item cap instead of 10. Added conditional modal trigger that activates when stored items count reaches a multiple of 5 (minimum 10) and current URL matches a course detail page pattern. Includes regex-based URL validation.
Modal Template & Base Integration
tcf_website/templates/base/index.html, tcf_website/templates/common/view_limit_modal.html
Added new modal template file with Bootstrap styling, logo, heading, and close button to inform users about viewing limits. Integrated modal into base template by adding include statement in body section.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 We track your course views, oh seekers so keen,
Twenty items stored in our recently-seen,
When five times you've browsed (or more, we confess),
A modal appears—a gentle caress! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Make review popup' is vague and generic, using non-descriptive phrasing that doesn't clearly convey what the popup does or its specific purpose in the changeset. Revise the title to be more specific and descriptive, such as 'Add review prompt modal that appears after viewing 5+ courses' to clearly communicate the feature's purpose.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description is mostly complete with the 'What I did' section properly filled out and includes a relevant screenshot, though it's missing sections for 'GitHub Issues addressed', 'Testing', and 'Questions/Discussions/Notes' from the template.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into dev

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch make_review_popup

Tip

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


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

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@tcf_website/static/common/recently_viewed.js`:
- Around line 81-88: Remove the stray blank line/whitespace above the if-block
and change single quotes to double quotes per ESLint: ensure the block using
previousPaths, courseRegex, currentUrl and the modal call uses
$("#viewLimitModal").modal("show"); (i.e., use double quotes for the selector
and the "show" argument) while keeping the courseRegex and logic unchanged.
- Around line 70-79: previousPaths and previousPathsTitles are getting out of
sync because only titles are sliced to 10; remove the premature 10-item slice
and keep storage logic limited to 20 items (slice both previousPaths and
previousPathsTitles to 20) and instead derive the 10-item display list at render
time; specifically, revert or remove the block that does previousPathsTitles =
previousPathsTitles.slice(0, 10) and ensure any rendering code uses
previousPaths.slice(0, 10) and previousPathsTitles.slice(0, 10) together so
indexes remain aligned.

In `@tcf_website/templates/common/view_limit_modal.html`:
- Line 10: Fix the typo in the modal paragraph text: locate the paragraph
element with class "mb-4" in view_limit_modal.html (the line containing '<p
class="mb-4">Consider making a review to help others students like you.</p>')
and change the copy from "others students" to "other students" so the sentence
reads "Consider making a review to help other students like you."
- Around line 3-4: The modal has aria-labelledby="viewLimitModalLabel" but no
element with id "viewLimitModalLabel" and it unnaturally prevents dismissal via
data-backdrop="static" and data-keyboard="false"; fix by either adding
id="viewLimitModalLabel" to the modal title element (the <h5> used for the modal
heading) so the aria-labelledby points to a real element, and remove the
heavy-handed attributes data-backdrop and data-keyboard from the <div
id="viewLimitModal"> so users can dismiss the non-critical prompt with outside
click or Escape, or alternatively remove the aria-labelledby attribute if you
prefer not to add the id—ensure the change keeps accessibility intact by having
a valid label reference or using aria-label.
🧹 Nitpick comments (1)
tcf_website/static/common/recently_viewed.js (1)

82-88: Modal re-shows every time the count hits 10, 15, or 20 — consider a cooldown or session flag.

Because previousPaths.length is checked on every page load, a user who has exactly 10 stored paths will see the modal each time they revisit a qualifying course page without adding a new unique course (the count stays at 10 after dedup). More importantly, there's no mechanism to avoid annoying repeat prompts across sessions. Consider setting a localStorage flag (e.g., lastModalShownCount) to only trigger once per threshold crossing.

Comment on lines +70 to +79
// Only display last 10 items
if (previousPaths.length > 10) {
previousPaths = previousPaths.slice(0, 10);
// previousPaths = previousPaths.slice(0, 10);
previousPathsTitles = previousPathsTitles.slice(0, 10);
}
// Prevent too many courses from being stored, max 20
if (previousPaths.length > 20) {
previousPaths = previousPaths.slice(0, 20);
previousPathsTitles = previousPathsTitles.slice(0, 20);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Bug: previousPaths and previousPathsTitles go out of sync.

Line 72 comments out the slice for previousPaths while Line 73 still slices previousPathsTitles to 10. These two arrays are parallel (same index = same item). Once previousPaths has more than 10 entries, titles will have fewer entries than paths, breaking the index correspondence. Any code that iterates both arrays together (e.g., the history/recently-viewed display) will pair wrong titles with wrong URLs or have missing titles.

If the intent is to keep 20 paths for the modal counter but only display 10 in the UI, derive the display list at read time rather than corrupting the stored data.

Proposed fix — keep both arrays in sync, derive display count at read time
-  // Only display last 10 items
-  if (previousPaths.length > 10) {
-    // previousPaths = previousPaths.slice(0, 10);
-    previousPathsTitles = previousPathsTitles.slice(0, 10);
-  }
-  // Prevent too many courses from being stored, max 20
-  if (previousPaths.length > 20) {
-    previousPaths = previousPaths.slice(0, 20);
-    previousPathsTitles = previousPathsTitles.slice(0, 20);
-  }
+  // Prevent too many courses from being stored, max 20
+  if (previousPaths.length > 20) {
+    previousPaths = previousPaths.slice(0, 20);
+    previousPathsTitles = previousPathsTitles.slice(0, 20);
+  }

Then wherever the recently-viewed list is displayed, limit to the first 10 entries at read time.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Only display last 10 items
if (previousPaths.length > 10) {
previousPaths = previousPaths.slice(0, 10);
// previousPaths = previousPaths.slice(0, 10);
previousPathsTitles = previousPathsTitles.slice(0, 10);
}
// Prevent too many courses from being stored, max 20
if (previousPaths.length > 20) {
previousPaths = previousPaths.slice(0, 20);
previousPathsTitles = previousPathsTitles.slice(0, 20);
}
// Prevent too many courses from being stored, max 20
if (previousPaths.length > 20) {
previousPaths = previousPaths.slice(0, 20);
previousPathsTitles = previousPathsTitles.slice(0, 20);
}
🤖 Prompt for AI Agents
In `@tcf_website/static/common/recently_viewed.js` around lines 70 - 79,
previousPaths and previousPathsTitles are getting out of sync because only
titles are sliced to 10; remove the premature 10-item slice and keep storage
logic limited to 20 items (slice both previousPaths and previousPathsTitles to
20) and instead derive the 10-item display list at render time; specifically,
revert or remove the block that does previousPathsTitles =
previousPathsTitles.slice(0, 10) and ensure any rendering code uses
previousPaths.slice(0, 10) and previousPathsTitles.slice(0, 10) together so
indexes remain aligned.

Comment on lines +81 to +88

if (previousPaths.length % 5 === 0 && previousPaths.length >= 10) {
// Check if URL matches .../course/[letters]/[numbers] and ends there
const courseRegex = /course\/[a-zA-Z]+\/\d+\/?$/;
if (courseRegex.test(currentUrl)) {
$('#viewLimitModal').modal('show');
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix lint/formatting failures flagged by CI.

Line 81 has an extra blank line with whitespace (prettier failure), and Line 86 should use double quotes per ESLint config.

Proposed fix
-
-  
-  if (previousPaths.length % 5 === 0 && previousPaths.length >= 10) {
+  if (previousPaths.length % 5 === 0 && previousPaths.length >= 10) {
     // Check if URL matches .../course/[letters]/[numbers] and ends there
     const courseRegex = /course\/[a-zA-Z]+\/\d+\/?$/;
     if (courseRegex.test(currentUrl)) {
-      $('#viewLimitModal').modal('show');
+      $("#viewLimitModal").modal("show");
     }
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (previousPaths.length % 5 === 0 && previousPaths.length >= 10) {
// Check if URL matches .../course/[letters]/[numbers] and ends there
const courseRegex = /course\/[a-zA-Z]+\/\d+\/?$/;
if (courseRegex.test(currentUrl)) {
$('#viewLimitModal').modal('show');
}
}
if (previousPaths.length % 5 === 0 && previousPaths.length >= 10) {
// Check if URL matches .../course/[letters]/[numbers] and ends there
const courseRegex = /course\/[a-zA-Z]+\/\d+\/?$/;
if (courseRegex.test(currentUrl)) {
$("#viewLimitModal").modal("show");
}
}
🧰 Tools
🪛 GitHub Actions: Continuous Integration

[error] 81-81: prettier/prettier: Delete ⏎·· (formatting issue).

🪛 GitHub Check: eslint

[failure] 86-86:
Replace '#viewLimitModal').modal('show' with "#viewLimitModal").modal("show"


[failure] 81-81:
Delete ⏎··

🤖 Prompt for AI Agents
In `@tcf_website/static/common/recently_viewed.js` around lines 81 - 88, Remove
the stray blank line/whitespace above the if-block and change single quotes to
double quotes per ESLint: ensure the block using previousPaths, courseRegex,
currentUrl and the modal call uses $("#viewLimitModal").modal("show"); (i.e.,
use double quotes for the selector and the "show" argument) while keeping the
courseRegex and logic unchanged.

Comment on lines +3 to +4
<div class="modal fade" id="viewLimitModal" tabindex="-1" role="dialog" aria-labelledby="viewLimitModalLabel"
aria-hidden="true" data-backdrop="static" data-keyboard="false">
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

aria-labelledby="viewLimitModalLabel" references a nonexistent element.

No element in this template has id="viewLimitModalLabel". Either add the id to the <h5> on Line 9 or remove the attribute.

Also, data-backdrop="static" and data-keyboard="false" feel heavy-handed for a non-critical promotional prompt — users can't dismiss by clicking outside or pressing Escape. Consider removing these attributes for a friendlier UX.

Proposed fix
-<div class="modal fade" id="viewLimitModal" tabindex="-1" role="dialog" aria-labelledby="viewLimitModalLabel"
-     aria-hidden="true" data-backdrop="static" data-keyboard="false">
+<div class="modal fade" id="viewLimitModal" tabindex="-1" role="dialog" aria-labelledby="viewLimitModalLabel"
+     aria-hidden="true">
     <div class="modal-dialog modal-dialog-centered" role="document">
         <div class="modal-content">
             <div class="modal-body text-center pt-4 pb-4">
                 <img src="{% static 'base/img/new_logo.svg' %}" alt="theCourseForum" class="img-fluid mb-3" style="max-height: 60px;">
-                <h5 class="mb-3">You've viewed a lot of courses!</h5>
+                <h5 id="viewLimitModalLabel" class="mb-3">You've viewed a lot of courses!</h5>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div class="modal fade" id="viewLimitModal" tabindex="-1" role="dialog" aria-labelledby="viewLimitModalLabel"
aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal fade" id="viewLimitModal" tabindex="-1" role="dialog" aria-labelledby="viewLimitModalLabel"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-body text-center pt-4 pb-4">
<img src="{% static 'base/img/new_logo.svg' %}" alt="theCourseForum" class="img-fluid mb-3" style="max-height: 60px;">
<h5 id="viewLimitModalLabel" class="mb-3">You've viewed a lot of courses!</h5>
🤖 Prompt for AI Agents
In `@tcf_website/templates/common/view_limit_modal.html` around lines 3 - 4, The
modal has aria-labelledby="viewLimitModalLabel" but no element with id
"viewLimitModalLabel" and it unnaturally prevents dismissal via
data-backdrop="static" and data-keyboard="false"; fix by either adding
id="viewLimitModalLabel" to the modal title element (the <h5> used for the modal
heading) so the aria-labelledby points to a real element, and remove the
heavy-handed attributes data-backdrop and data-keyboard from the <div
id="viewLimitModal"> so users can dismiss the non-critical prompt with outside
click or Escape, or alternatively remove the aria-labelledby attribute if you
prefer not to add the id—ensure the change keeps accessibility intact by having
a valid label reference or using aria-label.

<div class="modal-body text-center pt-4 pb-4">
<img src="{% static 'base/img/new_logo.svg' %}" alt="theCourseForum" class="img-fluid mb-3" style="max-height: 60px;">
<h5 class="mb-3">You've viewed a lot of courses!</h5>
<p class="mb-4">Consider making a review to help others students like you.</p>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Typo: "others students" → "other students".

Proposed fix
-                <p class="mb-4">Consider making a review to help others students like you.</p>
+                <p class="mb-4">Consider making a review to help other students like you.</p>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<p class="mb-4">Consider making a review to help others students like you.</p>
<p class="mb-4">Consider making a review to help other students like you.</p>
🤖 Prompt for AI Agents
In `@tcf_website/templates/common/view_limit_modal.html` at line 10, Fix the typo
in the modal paragraph text: locate the paragraph element with class "mb-4" in
view_limit_modal.html (the line containing '<p class="mb-4">Consider making a
review to help others students like you.</p>') and change the copy from "others
students" to "other students" so the sentence reads "Consider making a review to
help other students like you."

@jackrhoa jackrhoa marked this pull request as draft February 15, 2026 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants