Skip to content

Conversation

@rasulkireev
Copy link
Owner

This pull request contains changes generated by a Cursor Cloud Agent

Open in Cursor Open in Web

Co-authored-by: me <me@rasulkireev.com>
@cursor
Copy link

cursor bot commented Nov 2, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 2, 2025

Warning

Rate limit exceeded

@rasulkireev has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 21 minutes and 9 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 4ebe04a and 5316be2.

📒 Files selected for processing (15)
  • CHANGELOG.md (1 hunks)
  • core/admin.py (1 hunks)
  • core/context_processors.py (1 hunks)
  • core/migrations/0035_referrerbanner.py (1 hunks)
  • core/migrations/0036_referrerbanner_background_color_and_more.py (1 hunks)
  • core/models.py (1 hunks)
  • frontend/src/controllers/referrer_banner_controller.js (1 hunks)
  • frontend/templates/base_app.html (2 hunks)
  • frontend/templates/base_landing.html (1 hunks)
  • frontend/templates/base_project.html (1 hunks)
  • frontend/templates/components/referrer_banner.html (1 hunks)
  • frontend/templates/pages/admin_panel.html (1 hunks)
  • frontend/templates/pages/publish_history.html (1 hunks)
  • frontend/templates/pages/user-settings.html (1 hunks)
  • tuxseo/settings.py (1 hunks)

Note

Other AI code review bot(s) detected

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

✨ 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 cursor/add-banner-creation-via-admin-panel-54c9

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.

@rasulkireev rasulkireev marked this pull request as ready for review November 2, 2025 13:09
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

This PR implements a referrer banner system that displays promotional messages to users coming from specific referral sources (e.g., Product Hunt). The implementation includes:

  • Backend: New ReferrerBanner Django model with fields for referrer code, display name, discount details, and expiry date. The model includes properties for checking expiry status and display eligibility.
  • Admin Interface: Comprehensive Django admin configuration with list views, filters, and organized fieldsets for managing banners.
  • View Logic: Updated LandingView to check for ?ref= URL parameters and pass matching active banners to the template context.
  • Frontend Controller: Stimulus.js controller that manages banner dismissal state using localStorage to prevent showing dismissed banners on subsequent visits.
  • UI Component: Responsive banner template with conditional discount display, accessibility attributes, and smooth dismiss functionality.

The feature integrates cleanly with the existing codebase and follows the project's patterns (Django fat models, Stimulus.js for interactivity, server-side rendering). Minor improvements needed for production readiness.

Confidence Score: 4/5

  • This PR is safe to merge after creating the database migration, with only minor style improvements recommended.
  • The implementation is well-structured and follows Django and Stimulus.js best practices. However, the missing database migration is a critical blocker that must be addressed before deployment. The code has good separation of concerns and proper error handling in the backend (using try-except for DoesNotExist). Minor style improvements include moving imports to module level and adding localStorage error handling. The logic is sound and there are no security vulnerabilities.
  • Pay close attention to core/models.py - ensure migrations are generated and run before deploying to prevent database errors.

Important Files Changed

File Analysis

Filename Score Overview
core/models.py 3/5 Added ReferrerBanner model with properties for expiry checking and display logic, but missing database migration and potential validation constraints
core/views.py 4/5 Added context data method to fetch and validate referrer banner based on URL parameter, logic is sound but has minor performance consideration
frontend/src/controllers/referrer_banner_controller.js 4/5 Stimulus controller for banner dismissal using localStorage, follows project patterns but missing error handling for localStorage operations

Sequence Diagram

sequenceDiagram
    participant User
    participant Browser
    participant LandingView
    participant Database
    participant Template
    participant StimulusController
    participant LocalStorage

    User->>Browser: Visit landing page with ?ref=producthunt
    Browser->>LandingView: GET request with ref parameter
    LandingView->>Database: Query ReferrerBanner.objects.get(referrer='producthunt')
    
    alt Banner exists
        Database-->>LandingView: Return banner object
        LandingView->>LandingView: Check banner.should_display (is_active && !is_expired)
        
        alt Should display
            LandingView-->>Template: Pass banner in context
            Template->>Browser: Render banner HTML with Stimulus controller
            Browser->>StimulusController: Initialize referrer-banner controller
            StimulusController->>LocalStorage: Check dismissed banners
            
            alt Not dismissed
                StimulusController-->>Browser: Display banner
                Browser-->>User: Show referrer banner
                
                User->>Browser: Click dismiss button
                Browser->>StimulusController: Trigger dismiss action
                StimulusController->>LocalStorage: Save referrer to dismissedReferrerBanners
                StimulusController->>Browser: Remove banner element
            else Already dismissed
                StimulusController->>Browser: Remove banner element immediately
            end
        else Should not display
            LandingView-->>Template: No banner in context
        end
    else Banner does not exist
        Database-->>LandingView: ReferrerBanner.DoesNotExist
        LandingView-->>Template: No banner in context
    end
    
    Template-->>User: Render landing page
Loading

6 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

core/views.py Outdated
template_name = "pages/landing.html"

def get_context_data(self, **kwargs):
from core.models import ReferrerBanner
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Move import to top of file per PEP 8 style guidelines (imports should be at the module level).

Prompt To Fix With AI
This is a comment left during a code review.
Path: core/views.py
Line: 51:51

Comment:
**style:** Move import to top of file per PEP 8 style guidelines (imports should be at the module level).

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +20 to +30
getDismissedBanners() {
const dismissed = localStorage.getItem("dismissedReferrerBanners");
return dismissed ? JSON.parse(dismissed) : [];
}

saveDismissedBanner(referrer) {
const dismissed_banners = this.getDismissedBanners();
if (!dismissed_banners.includes(referrer)) {
dismissed_banners.push(referrer);
localStorage.setItem("dismissedReferrerBanners", JSON.stringify(dismissed_banners));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Wrap localStorage operations in try-catch blocks to handle QuotaExceededError or when localStorage is disabled (e.g., in private browsing mode).

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/controllers/referrer_banner_controller.js
Line: 20:30

Comment:
**style:** Wrap localStorage operations in try-catch blocks to handle `QuotaExceededError` or when localStorage is disabled (e.g., in private browsing mode).

How can I resolve this? If you propose a fix, please make it concise.

@rasulkireev rasulkireev merged commit 8688821 into main Nov 2, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants