-
Notifications
You must be signed in to change notification settings - Fork 8
Create project base template with sidebar #98
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
Create project base template with sidebar #98
Conversation
Co-authored-by: me <me@rasulkireev.com>
|
Cursor Agent can help with this pull request. Just |
|
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. WalkthroughAdds a new project-focused base template ( Changes
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 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.
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.htmlwith reusable project header, sidebar navigation, and "Back to Projects" button - Updated all project-related templates to extend
base_project.htmlinstead ofbase_app.html - Removed duplicate navigation elements from individual templates (headers, back buttons, inline navigation links)
- Added
projectto context inGeneratedBlogPostDetailViewto support the new template hierarchy - Sidebar navigation uses
request.resolver_match.url_nameto 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.htmlline 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.htmlwhich 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
8 files reviewed, 1 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: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 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.htmlfrontend/templates/project/project_settings.htmlfrontend/templates/project/project_keywords.htmlfrontend/templates/base_project.htmlfrontend/templates/project/project_pages.htmlfrontend/templates/blog/generated_blog_post_detail.htmlfrontend/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.htmlfrontend/templates/project/project_settings.htmlfrontend/templates/project/project_keywords.htmlfrontend/templates/base_project.htmlfrontend/templates/project/project_pages.htmlfrontend/templates/blog/generated_blog_post_detail.htmlfrontend/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.htmlfrontend/templates/project/project_settings.htmlfrontend/templates/project/project_keywords.htmlfrontend/templates/base_project.htmlfrontend/templates/project/project_pages.htmlfrontend/templates/blog/generated_blog_post_detail.htmlfrontend/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.htmlfrontend/templates/project/project_settings.htmlfrontend/templates/project/project_keywords.htmlfrontend/templates/base_project.htmlfrontend/templates/project/project_pages.htmlfrontend/templates/blog/generated_blog_post_detail.htmlfrontend/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 underscoresIn 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
projectto the template context properly supports the newbase_project.htmllayout, 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_contentblock, 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.htmland uses theproject_contentblock, 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.htmland uses theproject_contentblock 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_contentblock.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_contentblockThe 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.htmland theproject_contentblock, 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.htmlwith:
- Breadcrumb navigation for better UX (lines 13-21)
- Streamlined header with title and description
- Correct dependency on
projectcontext (provided by the view change in core/views.py)All functionality is preserved within the new
project_contentblock 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> |
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.
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.
| <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.
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)
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
📒 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.htmlfrontend/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.htmlfrontend/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.htmlfrontend/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.htmlfrontend/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.htmland theproject_contentblock 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.htmlis clean, and the Stimulus controllers (title-suggestions,content-idea,archived-list,tooltip) are well-integrated with clear data bindings toproject.id. The new UI flow (content generator, form toggle, suggestion cards) is well-organized.
| <!-- 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> |
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.
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.
| <!-- 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.
This pull request contains changes generated by a Cursor Cloud Agent
Summary by CodeRabbit