feat: add Vue Simulator section to Releases page - #175
Conversation
✅ Deploy Preview for cv-community-dashboard ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
WalkthroughReplaces per-release map rendering in app/releases/page.tsx with a new client component ReleasesClient; updates components/Releases/ReleaseCard.tsx to a responsive, break-word layout and adjusted spacing; and adds a new client-side component components/Releases/ReleasesClient.tsx that provides a tabbed filter for releases by repository and renders ReleaseCard entries. No exported/public API signatures were removed. Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
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.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @components/Releases/ReleasesClient.tsx:
- Around line 22-44: The tab container div and the two buttons need ARIA roles
and keyboard navigation: add role="tablist" to the div that wraps the buttons,
give each button role="tab", set aria-selected based on the activeRepo state
(e.g., aria-selected={activeRepo === "Mobile App"}), add aria-controls values
that reference the corresponding panel IDs (create matching id attributes on the
release panels), and ensure each button has an id used by the panel's
aria-labelledby; also implement Left/Right arrow key handlers on the buttons (or
a shared keyboard handler) to move focus between tabs and call setActiveRepo to
update the active tab accordingly.
🧹 Nitpick comments (1)
components/Releases/ReleasesClient.tsx (1)
12-13: Consider deriving available repositories dynamically from data.The repository names are hard-coded, requiring manual code changes when new repos are added. Since the PR objectives mention supporting multiple repositories, consider making this extensible:
💡 Dynamic repo tabs approach
export default function ReleasesClient({ releases, }: { releases: Release[]; }) { + // Derive unique repos from data + const availableRepos = Array.from(new Set(releases.map(r => r.repo))); + const [activeRepo, setActiveRepo] = useState(availableRepos[0] || ""); - const [activeRepo, setActiveRepo] = - useState<"Mobile App" | "Vue Simulator">("Mobile App"); const filtered = releases.filter( (r) => r.repo === activeRepo ); return ( <div className="mt-6 space-y-6"> {/* Tabs */} <div className="flex gap-6 border-b pb-2"> - <button - onClick={() => setActiveRepo("Mobile App")} - className={ - activeRepo === "Mobile App" - ? "font-semibold text-[#50B78B]" - : "text-zinc-500" - } - > - Mobile App - </button> - - <button - onClick={() => setActiveRepo("Vue Simulator")} - className={ - activeRepo === "Vue Simulator" - ? "font-semibold text-[#50B78B]" - : "text-zinc-500" - } - > - Vue Simulator - </button> + {availableRepos.map((repo) => ( + <button + key={repo} + onClick={() => setActiveRepo(repo)} + className={ + activeRepo === repo + ? "font-semibold text-[#50B78B]" + : "text-zinc-500" + } + > + {repo} + </button> + ))} </div>This approach automatically adapts to new repos in the data without code changes.
Also applies to: 22-44
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
.gitignoreapp/releases/page.tsxcomponents/Releases/ReleaseCard.tsxcomponents/Releases/ReleasesClient.tsx
🧰 Additional context used
🧬 Code graph analysis (2)
app/releases/page.tsx (2)
lib/releases.ts (1)
getReleases(18-31)components/Releases/ReleasesClient.tsx (1)
ReleasesClient(7-61)
components/Releases/ReleasesClient.tsx (2)
lib/releases.ts (1)
Release(4-15)components/Releases/ReleaseCard.tsx (1)
ReleaseCard(7-76)
🔇 Additional comments (4)
.gitignore (1)
66-66: LGTM! Appropriate ignore rule for generated releases data.The ignore rule correctly excludes the dynamically generated releases JSON file from version control.
components/Releases/ReleaseCard.tsx (1)
12-26: LGTM! Well-implemented responsive layout improvements.The responsive header layout correctly stacks on mobile and flows horizontally on larger screens. The
break-wordsutility prevents overflow issues, and themin-w-0wrapper allows proper flex shrinking. The date positioning adjusts appropriately across breakpoints.components/Releases/ReleasesClient.tsx (1)
1-61: Core implementation is solid with good client/server separation.The client component correctly uses the
"use client"directive, implements stateful tab filtering, and provides a good user experience with the placeholder state for empty repositories. The filtering logic is correct, and the key generation ensures unique identifiers.app/releases/page.tsx (1)
1-17: LGTM! Clean implementation following Next.js 15 best practices.The page correctly implements the server component pattern: it fetches data server-side with
getReleases()and passes it to the client component for stateful rendering. The simplified structure improves maintainability while preserving functionality.
| <div className="flex gap-6 border-b pb-2"> | ||
| <button | ||
| onClick={() => setActiveRepo("Mobile App")} | ||
| className={ | ||
| activeRepo === "Mobile App" | ||
| ? "font-semibold text-[#50B78B]" | ||
| : "text-zinc-500" | ||
| } | ||
| > | ||
| Mobile App | ||
| </button> | ||
|
|
||
| <button | ||
| onClick={() => setActiveRepo("Vue Simulator")} | ||
| className={ | ||
| activeRepo === "Vue Simulator" | ||
| ? "font-semibold text-[#50B78B]" | ||
| : "text-zinc-500" | ||
| } | ||
| > | ||
| Vue Simulator | ||
| </button> | ||
| </div> |
There was a problem hiding this comment.
Missing ARIA attributes for accessible tab navigation.
The tab buttons lack proper ARIA attributes needed for screen reader users and assistive technology. Tab interfaces should implement the ARIA tabs pattern with:
role="tablist"on the containerrole="tab"on each buttonaria-selected="true|false"to indicate the active tabaria-controlslinking each tab to its panel- Keyboard navigation (Left/Right arrow keys to navigate between tabs)
♿ Proposed accessibility improvements
{/* Tabs */}
- <div className="flex gap-6 border-b pb-2">
+ <div role="tablist" className="flex gap-6 border-b pb-2">
<button
+ role="tab"
+ aria-selected={activeRepo === "Mobile App"}
+ aria-controls="releases-panel"
onClick={() => setActiveRepo("Mobile App")}
className={
activeRepo === "Mobile App"
? "font-semibold text-[#50B78B]"
: "text-zinc-500"
}
>
Mobile App
</button>
<button
+ role="tab"
+ aria-selected={activeRepo === "Vue Simulator"}
+ aria-controls="releases-panel"
onClick={() => setActiveRepo("Vue Simulator")}
className={
activeRepo === "Vue Simulator"
? "font-semibold text-[#50B78B]"
: "text-zinc-500"
}
>
Vue Simulator
</button>
</div>
{/* Content */}
- {filtered.length === 0 ? (
+ <div id="releases-panel" role="tabpanel">
+ {filtered.length === 0 ? (
<p className="text-sm text-zinc-500">
No releases yet for {activeRepo}.
</p>
) : (
filtered.map((release) => (
<ReleaseCard
key={`${release.repoSlug}-${release.version}`}
release={release}
/>
))
)}
+ </div>For full keyboard support, also add arrow key handlers to move focus between tabs.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In @components/Releases/ReleasesClient.tsx around lines 22 - 44, The tab
container div and the two buttons need ARIA roles and keyboard navigation: add
role="tablist" to the div that wraps the buttons, give each button role="tab",
set aria-selected based on the activeRepo state (e.g., aria-selected={activeRepo
=== "Mobile App"}), add aria-controls values that reference the corresponding
panel IDs (create matching id attributes on the release panels), and ensure each
button has an id used by the panel's aria-labelledby; also implement Left/Right
arrow key handlers on the buttons (or a shared keyboard handler) to move focus
between tabs and call setActiveRepo to update the active tab accordingly.
|
Never add json data in .gitignore file |
This reverts commit a43be06.
Description
This PR adds a dedicated Vue Simulator section to the Releases page.
The Releases page now supports multiple repositories via tabs:
For Vue Simulator, a placeholder state is shown when no releases are available, ensuring the UI is future-ready and consistent.
Once Vue Simulator releases are created on GitHub, they will automatically appear without requiring further frontend changes.
Related Issue
Fixes #104
Type of change
Checklist
Summary by CodeRabbit
New Features
Style
✏️ Tip: You can customize this high-level summary in your review settings.