Skip to content

Conversation

@rasulkireev
Copy link
Owner

@rasulkireev rasulkireev commented Nov 2, 2025

This pull request contains changes generated by a Cursor Cloud Agent

Open in Cursor Open in Web

Summary by CodeRabbit

  • New Features
    • Generated blog post pages now have project information available in the page context for richer header/details.
  • New Features
    • Added a unified project base layout with sidebar navigation (Overview, Keywords, Your Pages, Settings, Publish History) and active-state highlighting.
  • Refactor
    • Reworked project templates to extend the new project base and use a shared project_content block for consistent layout.
  • Chores
    • Updated CHANGELOG with a 0.0.7 entry noting Project UI updates.

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

Note

Other AI code review bot(s) detected

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

Walkthrough

Adds a new project-focused base template (base_project.html) and migrates multiple project-related templates to extend it and use a new project_content block. Also exposes project in GeneratedBlogPostDetailView.get_context_data via context["project"] = project. No public API changes.

Changes

Cohort / File(s) Summary
Backend context update
core/views.py
Added context["project"] = project inside GeneratedBlogPostDetailView.get_context_data to make the related project available to templates.
New project base template
frontend/templates/base_project.html
Added a new base template (extends base_app.html) providing project header, responsive left sidebar navigation (Overview, Keywords, Pages, Settings, Publish History), active-state logic via request.resolver_match.url_name, and a project_content block for page content.
Templates migrated to project base
frontend/templates/blog/generated_blog_post_detail.html, frontend/templates/project/project_detail.html, frontend/templates/project/project_keywords.html, frontend/templates/project/project_pages.html, frontend/templates/project/project_publish_history.html, frontend/templates/project/project_settings.html
Switched each template to extend base_project.html (from base_app.html), renamed primary block from content to project_content, and removed local header/sidebar scaffolding in favor of base_project.html layout. Minor structural and styling adjustments to fit the new block.
Changelog
CHANGELOG.md
Added new 0.0.7 entry (2025-11-02) noting "Project UI updated to be more intuitive."

Sequence Diagram(s)

sequenceDiagram
    participant Browser
    participant DjangoView as View (GeneratedBlogPostDetailView)
    participant Template as Template Engine
    participant BaseProject as base_project.html
    participant Child as Child Template (e.g., generated_blog_post_detail)

    Browser->>DjangoView: GET /projects/{id}/posts/{slug}/
    DjangoView->>DjangoView: load project, post, flags
    DjangoView->>DjangoView: context["project"] = project
    DjangoView->>Template: render Child with context
    Template->>BaseProject: extend/includes (sidebar, header, project_content)
    BaseProject->>Child: inject `project_content` block
    Template->>Browser: HTML response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas to pay attention:
    • Ensure all templates correctly use project_content and that no content block is still expected by other includes.
    • Verify sidebar active-state logic (request.resolver_match.url_name) matches actual URL names.
    • Confirm context["project"] is available where templates assume it and no variable shadowing occurs.
    • Spot-check project_settings.html inline text/templating for stray characters or formatting issues.

Poem

🐰 I hopped through templates, neat and bright,
Built a base to guide each project site.
Context tucked in, the sidebar in place,
Pages unified with elegant grace.
A little rabbit’s refactor — gentle delight.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Create project base template with sidebar" directly and accurately describes the primary change in this PR: the creation of a new base_project.html template file that includes sidebar navigation, as evidenced by the AI-generated summary and the multiple existing project templates updated to extend from it. The title is clear, specific, and concise, avoiding vague terminology while effectively communicating the scope of changes—the creation of a new base template with a key feature (sidebar).
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cursor/create-project-base-template-with-sidebar-897c

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 00:25
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

Refactored project templates to use a new base_project.html base template with a consistent sidebar navigation, eliminating duplicate code across 7 template files.

Key Changes:

  • Created base_project.html with reusable project header, sidebar navigation, and "Back to Projects" button
  • Updated all project-related templates to extend base_project.html instead of base_app.html
  • Removed duplicate navigation elements from individual templates (headers, back buttons, inline navigation links)
  • Added project to context in GeneratedBlogPostDetailView to support the new template hierarchy
  • Sidebar navigation uses request.resolver_match.url_name to highlight the active page

Benefits:

  • Reduced code duplication significantly
  • Improved maintainability - navigation changes only need to be made in one place
  • Consistent user experience across all project pages
  • Cleaner template structure with separation of concerns

Confidence Score: 4/5

  • This PR is safe to merge with minimal risk after fixing the character encoding issue
  • Score reflects a well-executed refactoring with good architectural improvements. The only issue is a minor character encoding problem (? instead of —) in project_settings.html line 287. All other changes follow Django best practices, maintain existing functionality, and improve code maintainability through DRY principles.
  • Pay attention to frontend/templates/project/project_settings.html which has a character encoding issue that should be fixed before merging

Important Files Changed

File Analysis

Filename Score Overview
frontend/templates/base_project.html 5/5 Created new base template with sidebar navigation for project pages, includes project header and consistent navigation structure
core/views.py 5/5 Added project to context in GeneratedBlogPostDetailView to support new base template structure
frontend/templates/project/project_settings.html 4/5 Refactored to extend base_project.html, removed duplicate header; contains a character encoding issue on line 287

Sequence Diagram

sequenceDiagram
    participant User
    participant Browser
    participant Django
    participant BaseProject as base_project.html
    participant ChildTemplate as Child Template

    User->>Browser: Navigate to project page
    Browser->>Django: HTTP Request
    Django->>Django: Route to view (e.g., ProjectDetailView)
    Django->>Django: Load project from database
    Django->>Django: Build context with project object
    Django->>ChildTemplate: Render child template
    ChildTemplate->>BaseProject: Extend base_project.html
    BaseProject->>BaseProject: Render sidebar navigation
    BaseProject->>BaseProject: Render project header
    BaseProject->>ChildTemplate: Insert project_content block
    ChildTemplate->>BaseProject: Return rendered content
    BaseProject->>Django: Return complete HTML
    Django->>Browser: HTTP Response
    Browser->>User: Display page with sidebar
Loading

8 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1317210 and a9a8657.

📒 Files selected for processing (8)
  • core/views.py (1 hunks)
  • frontend/templates/base_project.html (1 hunks)
  • frontend/templates/blog/generated_blog_post_detail.html (2 hunks)
  • frontend/templates/project/project_detail.html (3 hunks)
  • frontend/templates/project/project_keywords.html (3 hunks)
  • frontend/templates/project/project_pages.html (3 hunks)
  • frontend/templates/project/project_publish_history.html (2 hunks)
  • frontend/templates/project/project_settings.html (3 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.html

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

**/*.html: Prefer Stimulus JS for adding interactivity to Django templates instead of raw script elements
Leverage Stimulus data attributes to connect HTML elements with JavaScript functionality
Utilize Stimulus targets to reference specific elements within a controller
Employ Stimulus actions to handle user interactions and events

Files:

  • frontend/templates/project/project_detail.html
  • frontend/templates/project/project_settings.html
  • frontend/templates/project/project_keywords.html
  • frontend/templates/base_project.html
  • frontend/templates/project/project_pages.html
  • frontend/templates/blog/generated_blog_post_detail.html
  • frontend/templates/project/project_publish_history.html
**/*.{html,htm}

📄 CodeRabbit inference engine (.cursor/rules/ui-ux-design-guidelines.mdc)

Always generate semantic HTML

Files:

  • frontend/templates/project/project_detail.html
  • frontend/templates/project/project_settings.html
  • frontend/templates/project/project_keywords.html
  • frontend/templates/base_project.html
  • frontend/templates/project/project_pages.html
  • frontend/templates/blog/generated_blog_post_detail.html
  • frontend/templates/project/project_publish_history.html
{**/*.{html,htm,css,scss},**/*_controller.@(js|ts)}

📄 CodeRabbit inference engine (.cursor/rules/ui-ux-design-guidelines.mdc)

Always favor the utility-first Tailwind approach; avoid creating reusable style classes and prefer reuse via template components

Files:

  • frontend/templates/project/project_detail.html
  • frontend/templates/project/project_settings.html
  • frontend/templates/project/project_keywords.html
  • frontend/templates/base_project.html
  • frontend/templates/project/project_pages.html
  • frontend/templates/blog/generated_blog_post_detail.html
  • frontend/templates/project/project_publish_history.html
frontend/templates/**/*.html

📄 CodeRabbit inference engine (.cursor/rules/stimulus-events.mdc)

Avoid data-*-outlet links for sibling controller communication when using the event-based approach; keep controllers self-contained

Use semantic HTML elements (e.g., dialog, details/summary) in templates

Files:

  • frontend/templates/project/project_detail.html
  • frontend/templates/project/project_settings.html
  • frontend/templates/project/project_keywords.html
  • frontend/templates/base_project.html
  • frontend/templates/project/project_pages.html
  • frontend/templates/blog/generated_blog_post_detail.html
  • frontend/templates/project/project_publish_history.html
**/*.py

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

**/*.py: Prioritize readability and maintainability; follow PEP 8
Use descriptive variable/function names with underscores

In Python, use try-except blocks that catch specific exception types; do not catch broad Exception.

**/*.py: Follow PEP 8 for Python code style
Use descriptive variable names with underscores (snake_case) in Python
Prefer Django's built-in features over external libraries

**/*.py: Use structlog for logging in Python code (avoid print and the standard logging module)
Include contextual key-value fields in log messages (e.g., error=str(e), exc_info=True, profile_id=profile.id)

**/*.py: Use descriptive, full-word variable names; avoid abbreviations and single-letter variables in Python
Provide context in variable names when format or type matters (e.g., include _iso_format, date)
Extract unchanging values into UPPER_CASE constants
Use intermediary variables to name parsed groups instead of using index access directly
Naming conventions: use is_/has_/can_ for booleans; include 'date' for dates; snake_case for variables/functions; PascalCase for classes
Define variables close to where they are used to keep lifespan short
Name things after what they do, not how they're used; ensure names make sense without extra context
Avoid generic names like data, info, manager; use specific, intention-revealing names
Function names should include necessary context without being verbose
If naming is hard, split functions into smaller focused parts
Maintain consistency: reuse the same verbs and nouns for the same concepts; name variables after the functions that create them
Use more descriptive names for longer-lived variables
Avoid else statements by using guard clauses for early returns
Replace simple conditionals with direct assignment when both branches call the same function with different values
Use dictionaries as dispatch tables instead of multiple equal-probability elif chains
Validate input before processing to prevent errors propagating in...

Files:

  • core/views.py
core/**/*.py

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

Leverage Django's ORM; avoid raw SQL when possible

Files:

  • core/views.py
core/views.py

📄 CodeRabbit inference engine (CLAUDE.md)

Keep Django views skinny: handle request/response only

Files:

  • core/views.py
🧠 Learnings (1)
📚 Learning: 2025-10-04T08:52:37.437Z
Learnt from: CR
Repo: rasulkireev/TuxSEO PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-04T08:52:37.437Z
Learning: Applies to frontend/templates/**/*.html : Use semantic HTML elements (e.g., dialog, details/summary) in templates

Applied to files:

  • frontend/templates/base_project.html
🔇 Additional comments (8)
core/views.py (1)

796-796: LGTM! Context enhancement aligns with template refactor.

The addition of project to the template context properly supports the new base_project.html layout, which requires project information for the sidebar navigation and header.

frontend/templates/project/project_pages.html (1)

1-16: LGTM! Clean migration to base_project.html.

The template correctly adopts the new base template and project_content block, removing redundant navigation that's now provided by the base. The simplified header maintains clarity while reducing duplication.

Also applies to: 290-290

frontend/templates/project/project_publish_history.html (1)

1-13: LGTM! Consistent migration to unified project layout.

The template properly extends base_project.html and uses the project_content block, maintaining consistency with other project-related templates.

Also applies to: 129-129

frontend/templates/project/project_settings.html (1)

1-9: LGTM! Template structure correctly updated.

The template properly migrates to base_project.html and uses the project_content block consistently with other project templates.

Also applies to: 372-372

frontend/templates/project/project_detail.html (1)

1-126: LGTM! Project detail page properly refactored.

The template correctly migrates to the new base layout while preserving all functionality. The content generator interface and blog post ideas sections remain intact within the new project_content block.

Also applies to: 222-222

frontend/templates/base_project.html (1)

1-146: LGTM! Well-structured base template consolidates project navigation.

This new base template successfully centralizes the project layout with:

  • Consistent navigation across all project pages
  • Clean sidebar with active state highlighting based on request.resolver_match.url_name
  • Project header with name, type badge, and optional site link
  • Proper extensibility via the project_content block

The approach reduces duplication and improves maintainability.

frontend/templates/project/project_keywords.html (1)

1-16: LGTM! Keywords page aligned with unified project layout.

The template correctly adopts base_project.html and the project_content block, maintaining all keyword management functionality while benefiting from the shared navigation structure.

Also applies to: 436-436

frontend/templates/blog/generated_blog_post_detail.html (1)

1-32: LGTM! Generated post detail page successfully integrated into project layout.

The template properly migrates to base_project.html with:

  • Breadcrumb navigation for better UX (lines 13-21)
  • Streamlined header with title and description
  • Correct dependency on project context (provided by the view change in core/views.py)

All functionality is preserved within the new project_content block structure.

Also applies to: 216-216

>
<label class="block mb-1 text-sm font-medium text-gray-700">Request Body</label>
<p class="mb-1 text-xs text-gray-500">Add key-value pairs for the request body. <span class="font-semibold">Values entered without <code>{% templatetag openvariable %} {% templatetag closevariable %}</code> will be used as-is.</span> To use dynamic values (like <code>title</code> or <code>content</code>), wrap them in <code>{% templatetag openvariable %} {% templatetag closevariable %}</code>these will be replaced dynamically. When entering a value, available dynamic options will appear in a dropdown list for your convenience.</p>
<p class="mb-1 text-xs text-gray-500">Add key-value pairs for the request body. <span class="font-semibold">Values entered without <code>{% templatetag openvariable %} {% templatetag closevariable %}</code> will be used as-is.</span> To use dynamic values (like <code>title</code> or <code>content</code>), wrap them in <code>{% templatetag openvariable %} {% templatetag closevariable %}</code>?these will be replaced dynamically. When entering a value, available dynamic options will appear in a dropdown list for your convenience.</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

Fix typo in help text.

There's an extraneous "?" character after the closing </code> tag in the help text. This should be a space instead.

Apply this diff:

-                    <p class="mb-1 text-xs text-gray-500">Add key-value pairs for the request body. <span class="font-semibold">Values entered without <code>{% templatetag openvariable %} {% templatetag closevariable %}</code> will be used as-is.</span> To use dynamic values (like <code>title</code> or <code>content</code>), wrap them in <code>{% templatetag openvariable %} {% templatetag closevariable %}</code>?these will be replaced dynamically. When entering a value, available dynamic options will appear in a dropdown list for your convenience.</p>
+                    <p class="mb-1 text-xs text-gray-500">Add key-value pairs for the request body. <span class="font-semibold">Values entered without <code>{% templatetag openvariable %} {% templatetag closevariable %}</code> will be used as-is.</span> To use dynamic values (like <code>title</code> or <code>content</code>), wrap them in <code>{% templatetag openvariable %} {% templatetag closevariable %}</code> — these will be replaced dynamically. When entering a value, available dynamic options will appear in a dropdown list for your convenience.</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-1 text-xs text-gray-500">Add key-value pairs for the request body. <span class="font-semibold">Values entered without <code>{% templatetag openvariable %} {% templatetag closevariable %}</code> will be used as-is.</span> To use dynamic values (like <code>title</code> or <code>content</code>), wrap them in <code>{% templatetag openvariable %} {% templatetag closevariable %}</code>?these will be replaced dynamically. When entering a value, available dynamic options will appear in a dropdown list for your convenience.</p>
<p class="mb-1 text-xs text-gray-500">Add key-value pairs for the request body. <span class="font-semibold">Values entered without <code>{% templatetag openvariable %} {% templatetag closevariable %}</code> will be used as-is.</span> To use dynamic values (like <code>title</code> or <code>content</code>), wrap them in <code>{% templatetag openvariable %} {% templatetag closevariable %}</code>these will be replaced dynamically. When entering a value, available dynamic options will appear in a dropdown list for your convenience.</p>
🤖 Prompt for AI Agents
In frontend/templates/project/project_settings.html around line 287, the help
text contains an extraneous "?" character immediately after the closing </code>
tag; replace that "?" with a space so the sentence reads correctly and spacing
is preserved.

@rasulkireev rasulkireev merged commit 3544964 into main Nov 2, 2025
1 of 2 checks passed
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
frontend/templates/project/project_settings.html (1)

287-287: Fix character encoding in help text.

Replace the hyphen with an em dash and proper spacing: -these — these.

-                    <p class="mb-1 text-xs text-gray-500">Add key-value pairs for the request body. <span class="font-semibold">Values entered without <code>{% templatetag openvariable %} {% templatetag closevariable %}</code> will be used as-is.</span> To use dynamic values (like <code>title</code> or <code>content</code>), wrap them in <code>{% templatetag openvariable %} {% templatetag closevariable %}</code>-these will be replaced dynamically. When entering a value, available dynamic options will appear in a dropdown list for your convenience.</p>
+                    <p class="mb-1 text-xs text-gray-500">Add key-value pairs for the request body. <span class="font-semibold">Values entered without <code>{% templatetag openvariable %} {% templatetag closevariable %}</code> will be used as-is.</span> To use dynamic values (like <code>title</code> or <code>content</code>), wrap them in <code>{% templatetag openvariable %} {% templatetag closevariable %}</code> — these will be replaced dynamically. When entering a value, available dynamic options will appear in a dropdown list for your convenience.</p>
🧹 Nitpick comments (1)
frontend/templates/project/project_detail.html (1)

165-223: Consider using semantic <details>/<summary> for collapsible sections.

The collapsible suggestions lists (Active, Published, Archived) currently use button + Stimulus to toggle visibility. Consider refactoring to use semantic HTML's <details> and <summary> elements to improve accessibility and reduce JavaScript dependency for the toggle behavior.

Example:

<details data-controller="archived-list" data-archived-list-name-value="active">
  <summary class="flex justify-between items-center px-6 py-4 w-full text-left rounded-lg cursor-pointer hover:bg-gray-100">
    <h4 class="text-base font-medium text-gray-900">Active Ideas</h4>
    <svg class="w-5 h-5 text-gray-400" ...></svg>
  </summary>
  <div data-archived-list-target="list" class="p-4 border-t border-gray-200" data-title-suggestions-target="activeSuggestionsList">
    <!-- content -->
  </div>
</details>

This aligns with the coding guideline to "use semantic HTML elements (e.g., dialog, details/summary) in templates."

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a9a8657 and 3d67bef.

📒 Files selected for processing (4)
  • CHANGELOG.md (1 hunks)
  • frontend/templates/base_project.html (1 hunks)
  • frontend/templates/project/project_detail.html (2 hunks)
  • frontend/templates/project/project_settings.html (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/templates/base_project.html
🧰 Additional context used
📓 Path-based instructions (4)
**/*.html

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

**/*.html: Prefer Stimulus JS for adding interactivity to Django templates instead of raw script elements
Leverage Stimulus data attributes to connect HTML elements with JavaScript functionality
Utilize Stimulus targets to reference specific elements within a controller
Employ Stimulus actions to handle user interactions and events

Files:

  • frontend/templates/project/project_detail.html
  • frontend/templates/project/project_settings.html
**/*.{html,htm}

📄 CodeRabbit inference engine (.cursor/rules/ui-ux-design-guidelines.mdc)

Always generate semantic HTML

Files:

  • frontend/templates/project/project_detail.html
  • frontend/templates/project/project_settings.html
{**/*.{html,htm,css,scss},**/*_controller.@(js|ts)}

📄 CodeRabbit inference engine (.cursor/rules/ui-ux-design-guidelines.mdc)

Always favor the utility-first Tailwind approach; avoid creating reusable style classes and prefer reuse via template components

Files:

  • frontend/templates/project/project_detail.html
  • frontend/templates/project/project_settings.html
frontend/templates/**/*.html

📄 CodeRabbit inference engine (.cursor/rules/stimulus-events.mdc)

Avoid data-*-outlet links for sibling controller communication when using the event-based approach; keep controllers self-contained

Use semantic HTML elements (e.g., dialog, details/summary) in templates

Files:

  • frontend/templates/project/project_detail.html
  • frontend/templates/project/project_settings.html
🔇 Additional comments (3)
CHANGELOG.md (1)

17-21: LGTM!

The changelog entry is well-formatted and accurately reflects the PR changes (template restructuring with new project-focused base layout and sidebar).

frontend/templates/project/project_settings.html (1)

1-372: Template structure and Stimulus wiring look good.

The migration to base_project.html and the project_content block aligns well with the PR's goal of a project-centric layout. Stimulus controllers (archived-list, project-details, auto-submission-toggle, etc.) are appropriately scoped with data attributes and targets.

frontend/templates/project/project_detail.html (1)

1-228: Overall structure and Stimulus patterns are solid.

The migration to base_project.html is clean, and the Stimulus controllers (title-suggestions, content-idea, archived-list, tooltip) are well-integrated with clear data bindings to project.id. The new UI flow (content generator, form toggle, suggestion cards) is well-organized.

Comment on lines +140 to +159
<!-- Content Type Tabs -->
<div class="border-b border-gray-200">
<nav class="flex -mb-px space-x-8">
<button
data-action="title-suggestions#switchTab"
data-tab="SHARING"
class="px-1 py-2 text-sm font-medium text-gray-900 border-b-2 border-gray-900 focus:outline-none"
aria-current="page"
>
Eye Catching
</button>
<button
data-action="title-suggestions#switchTab"
data-tab="SEO"
class="px-1 py-2 text-sm font-medium text-gray-500 border-b-2 border-transparent hover:text-gray-700 hover:border-gray-300 focus:outline-none"
>
SEO Optimized
</button>
</nav>
</div>
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 | 🟠 Major

Add ARIA attributes to tab buttons for accessibility.

The tab buttons need proper semantics for screen readers and keyboard navigation. Lines 146 and 154+ are missing role="tab", aria-selected, and aria-controls attributes.

          <nav class="flex -mb-px space-x-8">
            <button
              data-action="title-suggestions#switchTab"
              data-tab="SHARING"
              class="px-1 py-2 text-sm font-medium text-gray-900 border-b-2 border-gray-900 focus:outline-none"
-             aria-current="page"
+             role="tab"
+             aria-selected="true"
+             aria-controls="sharing-content"
            >
              Eye Catching
            </button>
            <button
              data-action="title-suggestions#switchTab"
              data-tab="SEO"
              class="px-1 py-2 text-sm font-medium text-gray-500 border-b-2 border-transparent hover:text-gray-700 hover:border-gray-300 focus:outline-none"
+             role="tab"
+             aria-selected="false"
+             aria-controls="seo-content"
            >
              SEO Optimized
            </button>
          </nav>

Additionally, update the tab panels (data-title-suggestions-target="suggestionsList") to use role="tabpanel" and corresponding id attributes that match the aria-controls references above.

📝 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
<!-- Content Type Tabs -->
<div class="border-b border-gray-200">
<nav class="flex -mb-px space-x-8">
<button
data-action="title-suggestions#switchTab"
data-tab="SHARING"
class="px-1 py-2 text-sm font-medium text-gray-900 border-b-2 border-gray-900 focus:outline-none"
aria-current="page"
>
Eye Catching
</button>
<button
data-action="title-suggestions#switchTab"
data-tab="SEO"
class="px-1 py-2 text-sm font-medium text-gray-500 border-b-2 border-transparent hover:text-gray-700 hover:border-gray-300 focus:outline-none"
>
SEO Optimized
</button>
</nav>
</div>
<!-- Content Type Tabs -->
<div class="border-b border-gray-200">
<nav class="flex -mb-px space-x-8">
<button
data-action="title-suggestions#switchTab"
data-tab="SHARING"
class="px-1 py-2 text-sm font-medium text-gray-900 border-b-2 border-gray-900 focus:outline-none"
role="tab"
aria-selected="true"
aria-controls="sharing-content"
>
Eye Catching
</button>
<button
data-action="title-suggestions#switchTab"
data-tab="SEO"
class="px-1 py-2 text-sm font-medium text-gray-500 border-b-2 border-transparent hover:text-gray-700 hover:border-gray-300 focus:outline-none"
role="tab"
aria-selected="false"
aria-controls="seo-content"
>
SEO Optimized
</button>
</nav>
</div>
🤖 Prompt for AI Agents
In frontend/templates/project/project_detail.html around lines 140 to 159, the
tab buttons lack ARIA semantics and the corresponding panels lack matching
identifiers; add role="tab", aria-selected="true" on the active tab and
aria-selected="false" on inactive tabs, and add aria-controls on each button
pointing to the id of its panel (e.g., aria-controls="suggestions-sharing" and
"suggestions-seo"); also update the tab panel elements (the elements with
data-title-suggestions-target="suggestionsList") to include role="tabpanel" and
matching id attributes referenced by the buttons so screen readers and assistive
tech can associate tabs with their panels.

@coderabbitai coderabbitai bot mentioned this pull request Nov 7, 2025
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