feat(web): improve dashboard ux structure and reduce clutter#305
feat(web): improve dashboard ux structure and reduce clutter#305BillChirico merged 2 commits intoVolvoxLLC:mainfrom
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (25)
📝 WalkthroughSummary by CodeRabbit
WalkthroughReworks dashboard UI: adds PageHeader and EmptyState components, dashboard CSS utilities, and visual refinements across pages and layout. Several page modules were slimmed to render new client components (ConversationsClient, MembersClient, ModerationClient, TicketsClient), while tables, filters, and panels received consistent styling updates. Changes
Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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 |
|
| Filename | Overview |
|---|---|
| web/src/app/dashboard/conversations/conversations-client.tsx | New client component split from page.tsx; contains two issues: hardcoded 'en-US' locale in formatDate (violates project rule) and missing keyboard/ARIA accessibility on clickable table rows (regression from original). |
| web/src/components/dashboard/page-header.tsx | New shared PageHeader component with icon, title, description, and actions slot. Clean implementation using dashboard-panel and dashboard-chip utility classes with good responsive layout. |
| web/src/components/dashboard/empty-state.tsx | New shared EmptyState component with configurable icon, title, description, and className. Simple and well-structured with sensible defaults. |
| web/src/components/layout/dashboard-shell.tsx | Shell updated with dashboard-canvas/grid background treatment, wider sidebar (w-80), improved overflow handling, and max-width content container — clean layout improvements. |
| web/src/components/layout/sidebar.tsx | Sidebar refactored with primary/secondary nav split, collapsible Extensions section using HTML details, active indicator pill, and a hardcoded "Workflow" tip card. Well-structured, no logic issues. |
| web/src/app/globals.css | Adds dashboard-specific CSS utilities (dashboard-canvas, dashboard-grid, dashboard-panel, dashboard-chip, dashboard-fade-in) using CSS custom properties for both light and dark themes. |
| web/src/app/dashboard/tickets/tickets-client.tsx | New tickets client component split from page.tsx; correctly preserves tabIndex and onKeyDown keyboard accessibility on table rows, and uses undefined locale in formatDate — good reference for how conversations-client should be fixed. |
| web/src/components/dashboard/analytics-dashboard.tsx | Charts upgraded with themed tooltips, EmptyState for zero-data conditions, and grid layout refined. New hexToRgba helper improves the heatmap to respect the theme's primary color rather than a hardcoded Discord blue. |
| web/src/app/dashboard/audit-log/page.tsx | Adopts PageHeader and EmptyState components, adds three stat cards, and applies dashboard-panel styling to filters and table. No logic changes. |
| web/tsconfig.json | Adds explicit baseUrl: "." which is a safe and common Next.js tsconfig pattern, complementing the existing @/* path alias. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
subgraph "Before (monolithic page.tsx)"
A["page.tsx\n'use client'\nAll state + UI"]
end
subgraph "After (server/client split)"
B["page.tsx\nServer Component\nMetadata only"]
C["*-client.tsx\n'use client'\nState + UI"]
B --> C
end
subgraph "New Shared Components"
D["PageHeader\nicon · title · description · actions"]
E["EmptyState\nicon · title · description"]
end
subgraph "New CSS Utilities"
F["dashboard-panel\ndashboard-chip\ndashboard-canvas\ndashboard-grid\ndashboard-fade-in"]
end
C --> D
C --> E
D --> F
E --> F
style A fill:#f4a261,color:#000
style B fill:#52b788,color:#000
style C fill:#52b788,color:#000
style D fill:#4895ef,color:#fff
style E fill:#4895ef,color:#fff
style F fill:#6c757d,color:#fff
Comments Outside Diff (2)
-
web/src/app/dashboard/conversations/conversations-client.tsx, line 334-340 (link)Hardcoded locale violates project rule
formatDatepasses the hardcoded locale'en-US'totoLocaleDateString. The project rule requires usingundefinedso the user's runtime locale is respected. Note thattickets-client.tsx(introduced in the same PR) already usesundefinedcorrectly, so this is an inconsistency within the PR itself.Rule Used: Do not hardcode locale strings like 'en-US' in Int... (source)
-
web/src/app/dashboard/conversations/conversations-client.tsx, line 645-649 (link)Keyboard accessibility regression
The refactored
conversations-client.tsxremoved keyboard navigation and ARIA attributes that existed on clickable table rows in the originalconversations/page.tsx. Specifically these props are now missing from<TableRow>:tabIndex={0}role="button"- an
aria-labeldescribing the conversation - an
onKeyDownhandler forEnter/Space
The
tickets-client.tsxintroduced in this same PR correctly retains all of these on its table rows. Conversations should be consistent — keyboard-only users cannot currently activate these rows. The fix is to restore the same pattern used intickets-client.tsx.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: web/src/app/dashboard/conversations/conversations-client.tsx
Line: 334-340
Comment:
**Hardcoded locale violates project rule**
`formatDate` passes the hardcoded locale `'en-US'` to `toLocaleDateString`. The project rule requires using `undefined` so the user's runtime locale is respected. Note that `tickets-client.tsx` (introduced in the same PR) already uses `undefined` correctly, so this is an inconsistency within the PR itself.
```suggestion
function formatDate(iso: string): string {
return new Date(iso).toLocaleDateString(undefined, {
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
});
}
```
**Rule Used:** Do not hardcode locale strings like 'en-US' in Int... ([source](https://app.greptile.com/review/custom-context?memory=no-hardcoded-locale))
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: web/src/app/dashboard/conversations/conversations-client.tsx
Line: 645-649
Comment:
**Keyboard accessibility regression**
The refactored `conversations-client.tsx` removed keyboard navigation and ARIA attributes that existed on clickable table rows in the original `conversations/page.tsx`. Specifically these props are now missing from `<TableRow>`:
- `tabIndex={0}`
- `role="button"`
- an `aria-label` describing the conversation
- an `onKeyDown` handler for `Enter`/`Space`
The `tickets-client.tsx` introduced in this same PR correctly retains all of these on its table rows. Conversations should be consistent — keyboard-only users cannot currently activate these rows. The fix is to restore the same pattern used in `tickets-client.tsx`.
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: "chore: trigger merge..."
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/dashboard/member-table.tsx`:
- Around line 285-293: Replace the duplicated empty-state markup inside the
TableCell with the shared EmptyState component: import EmptyState and use it
where the current div/span/p block is, passing the Users icon as the icon prop
(e.g., icon={<Users />}), title="No members found", description="Try adjusting
your search or filters.", and propagate the existing TableCell className (or
pass className to EmptyState) so the table context can strip borders/background;
remove the span/div/p markup and ensure TableCell still uses colSpan={8}.
In `@web/src/components/layout/dashboard-shell.tsx`:
- Around line 21-35: The flex container and its children need explicit min-size
resets so the nested overflow-y-auto on the Sidebar body and the main pane can
scroll internally: add the Tailwind min-size utility (e.g. min-h-0 and where
appropriate min-w-0) to the outer flex container (the div with class "flex
flex-1") and to the immediate flex children (the aside element containing
ServerSelector/Sidebar and the main element wrapping {children}) so those panes
can shrink and let their internal overflow-y-auto handle scrolling.
In `@web/src/components/layout/sidebar.tsx`:
- Around line 181-190: The external support Link in the sidebar doesn't close
the mobile drawer because it bypasses the MobileSidebar's onNavClick handler;
update the footer link in the Sidebar/MobileSidebar component to invoke the same
onNavClick (or a wrapper that calls onNavClick and then navigates) when
clicked—i.e., attach an onClick that calls onNavClick (and preserves opening the
external URL via target="_blank"/rel) so the sheet collapses when the support
link is tapped.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4f52645c-f853-43ba-b791-755273dbb87e
📒 Files selected for processing (13)
web/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/components/dashboard/empty-state.tsxweb/src/components/dashboard/member-table.tsxweb/src/components/dashboard/page-header.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/header.tsxweb/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/server-selector.tsxweb/src/components/layout/sidebar.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{js,ts,tsx}: Use single quotes for strings (except in JSON files); no double quotes
Always include semicolons at the end of statements
Use 2-space indentation (spaces, not tabs)
Always include trailing commas in multi-line arrays, objects, and function parameters
Maintain a maximum line width of 100 characters
Files:
web/src/components/layout/mobile-sidebar.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/layout/header.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/layout/server-selector.tsxweb/src/components/dashboard/empty-state.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/components/layout/sidebar.tsxweb/src/components/dashboard/member-table.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Never use
console.*methods in web dashboard code; use appropriate logging mechanisms for React applications
Files:
web/src/components/layout/mobile-sidebar.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/layout/header.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/layout/server-selector.tsxweb/src/components/dashboard/empty-state.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/components/layout/sidebar.tsxweb/src/components/dashboard/member-table.tsx
**/*.{js,ts,tsx,mjs}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,tsx,mjs}: Use ESM syntax (import/export) — CommonJS is not allowed
Use single quotes for strings — double quotes only allowed in JSON files
Always include semicolons at end of statements
Use 2-space indentation for all code
Use Winston logger fromsrc/logger.js— never useconsole.*methods
Files:
web/src/components/layout/mobile-sidebar.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/layout/header.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/layout/server-selector.tsxweb/src/components/dashboard/empty-state.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/components/layout/sidebar.tsxweb/src/components/dashboard/member-table.tsx
web/src/app/dashboard/**/*.tsx
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
For dashboard routes, add a matcher entry to
dashboardTitleMatchersinweb/src/lib/page-titles.ts: use exact equality for leaf routes (pathname === '/dashboard/my-route') and subtree checks (pathname.startsWith('/dashboard/my-route/')); exportmetadatausingcreatePageMetadata(title)for SSR entry points
Files:
web/src/app/dashboard/moderation/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/audit-log/page.tsx
web/src/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
web/src/app/**/*.{ts,tsx}: ExportmetadatausingcreatePageMetadata()fromweb/src/lib/page-titles.tsin SSR entry points for dashboard pages
UseDashboardTitleSynccomponent andgetDashboardDocumentTitle()for client-side navigation title updates in the dashboard
Files:
web/src/app/dashboard/moderation/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/audit-log/page.tsx
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{ts,tsx} : Web dashboard config editor should use category workspace navigation with reusable SettingsFeatureCard pattern (header + master toggle + Basic/Advanced blocks)
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T20:36:29.483Z
Learning: Applies to web/src/pages/dashboard/**/*.{ts,tsx} : Use shared title helpers from web/src/lib/page-titles.ts for setting browser titles in dashboard pages
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Use `DashboardTitleSync` component and `getDashboardDocumentTitle()` for client-side navigation title updates in the dashboard
📚 Learning: 2026-03-12T02:03:52.689Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Use `DashboardTitleSync` component and `getDashboardDocumentTitle()` for client-side navigation title updates in the dashboard
Applied to files:
web/src/components/layout/mobile-sidebar.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/layout/header.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/empty-state.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/components/layout/sidebar.tsxweb/src/components/dashboard/member-table.tsx
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'
Applied to files:
web/src/components/layout/mobile-sidebar.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/layout/header.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/empty-state.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/components/layout/sidebar.tsx
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{ts,tsx} : Web dashboard config editor should use category workspace navigation with reusable SettingsFeatureCard pattern (header + master toggle + Basic/Advanced blocks)
Applied to files:
web/src/components/layout/mobile-sidebar.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/layout/header.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/components/layout/sidebar.tsxweb/src/components/dashboard/member-table.tsx
📚 Learning: 2026-03-10T20:36:29.483Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T20:36:29.483Z
Learning: Applies to web/src/pages/dashboard/**/*.{ts,tsx} : Use shared title helpers from web/src/lib/page-titles.ts for setting browser titles in dashboard pages
Applied to files:
web/src/components/layout/mobile-sidebar.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/layout/header.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/audit-log/page.tsx
📚 Learning: 2026-03-10T20:36:29.483Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T20:36:29.483Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Apply static metadata to server-rendered dashboard entry pages and use title template format for root app metadata
Applied to files:
web/src/components/layout/mobile-sidebar.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/layout/header.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/components/dashboard/member-table.tsx
📚 Learning: 2026-03-12T02:03:52.689Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Verify responsive layout behavior when making dashboard layout changes
Applied to files:
web/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/dashboard-shell.tsx
📚 Learning: 2026-03-12T02:03:36.476Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.476Z
Learning: Applies to web/src/app/dashboard/**/*.tsx : For dashboard routes, add a matcher entry to `dashboardTitleMatchers` in `web/src/lib/page-titles.ts`: use exact equality for leaf routes (`pathname === '/dashboard/my-route'`) and subtree checks (`pathname.startsWith('/dashboard/my-route/')`); export `metadata` using `createPageMetadata(title)` for SSR entry points
Applied to files:
web/src/components/layout/mobile-sidebar.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/layout/header.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/audit-log/page.tsx
📚 Learning: 2026-03-12T02:03:52.689Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Export `metadata` using `createPageMetadata()` from `web/src/lib/page-titles.ts` in SSR entry points for dashboard pages
Applied to files:
web/src/app/dashboard/moderation/page.tsxweb/src/components/layout/header.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/audit-log/page.tsx
📚 Learning: 2026-03-12T02:03:52.689Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Add a matcher entry to `dashboardTitleMatchers` in `web/src/lib/page-titles.ts` for every new dashboard route
Applied to files:
web/src/components/layout/header.tsxweb/src/components/dashboard/page-header.tsx
📚 Learning: 2026-03-10T20:36:29.483Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T20:36:29.483Z
Learning: Applies to web/src/app/api/**/route.ts : Include guildId in signed WebSocket ticket payload when issuing tickets from dashboard endpoints
Applied to files:
web/src/app/dashboard/tickets/page.tsx
🪛 GitHub Check: SonarCloud Code Analysis
web/src/components/dashboard/empty-state.tsx
[warning] 14-14: Mark the props of the component as read-only.
web/src/components/dashboard/page-header.tsx
[warning] 14-20: Mark the props of the component as read-only.
🔇 Additional comments (11)
web/src/components/dashboard/empty-state.tsx (1)
14-30: Reusable empty-state primitive looks good.Small prop surface plus the
classNameescape hatch should make it easy to standardize
placeholder views without duplicating markup.web/src/components/dashboard/page-header.tsx (1)
14-40: CleanPageHeaderAPI.Optional icon, description, and actions cover the dashboard variants in this PR without
pushing route-specific markup back into each page.web/src/components/layout/header.tsx (1)
31-61: Nice reuse of the shared route-title helper.Deriving the subtitle from
getDashboardPageTitle()keeps the header copy aligned with the
existing dashboard title map instead of introducing a second route switch.web/src/components/layout/sidebar.tsx (1)
97-178: The split between primary and secondary nav is well-factored.Centralizing active-state checks in
isNavItemActive()keeps both sections consistent and
makes future nav additions much less error-prone.web/src/components/layout/server-selector.tsx (1)
139-267: The selector states are much clearer after this pass.Using the same bordered-card treatment for loading, error, and empty cases keeps the shell
stable, and the Manage / Member Only split makes the dropdown easier to scan.web/src/components/layout/mobile-sidebar.tsx (1)
29-39: Good reuse of the shared navigation stack on mobile.Keeping
ServerSelectorandSidebarinside the sheet avoids a separate mobile-only nav
tree.web/src/app/dashboard/conversations/page.tsx (1)
6-7: Shared header/empty-state refactor is clean and preserves behavior.The updated
PageHeader/EmptyStateintegration keeps existing fetch/filter/pagination flows intact while improving consistency.Also applies to: 45-46, 279-295, 299-303, 373-373, 436-448
web/src/app/dashboard/moderation/page.tsx (1)
7-7: Header/empty-state migration looks correct and non-breaking.The new shared components are wired correctly with existing refresh/disabled behavior and guild gating.
Also applies to: 9-9, 107-125, 129-133
web/src/app/dashboard/members/page.tsx (1)
6-6: Members page UX restructuring is solid and behavior-preserving.The new header, empty state, and stats/search containers are consistent with the dashboard pattern and keep current logic intact.
Also applies to: 13-13, 236-252, 256-260, 266-289
web/src/app/dashboard/tickets/page.tsx (1)
6-7: Tickets page refactor is cohesive and safely scoped.Shared header/empty-state adoption and card styling changes are consistent, and the functional data path remains unchanged.
Also applies to: 45-46, 276-292, 297-319, 326-330, 337-337, 397-397, 447-455
web/src/app/dashboard/audit-log/page.tsx (1)
6-7: Audit Log UI standardization is implemented correctly.The shared component migration and visual refinements are consistent and do not introduce behavior changes.
Also applies to: 272-288, 292-296, 388-388, 441-443, 455-467
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
web/src/components/layout/dashboard-shell.tsx (1)
33-35:⚠️ Potential issue | 🟠 MajorAdd
min-w-0to the main flex pane to prevent horizontal overflow regressions.Line 33 still misses
min-w-0; wide content can force page-level overflow instead of keeping overflow behavior scoped to the pane.Suggested fix
- <main className="min-h-0 flex-1 overflow-y-auto"> + <main className="min-h-0 min-w-0 flex-1 overflow-y-auto"> <div className="mx-auto w-full max-w-[1460px] p-5 md:p-8">{children}</div> </main>Based on learnings: Verify responsive layout behavior when making dashboard layout changes.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/layout/dashboard-shell.tsx` around lines 33 - 35, The main flex pane in DashboardShell currently uses className "min-h-0 flex-1 overflow-y-auto" which can allow wide children to cause page-level horizontal overflow; update the main element's className to include "min-w-0" (e.g., add min-w-0 alongside min-h-0) so the overflow is constrained to the pane and responsive layout regressions are prevented.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/layout/sidebar.tsx`:
- Around line 112-139: Extract the duplicated link/icon/class rendering into a
single shared renderer (e.g., a NavItem component or renderNavItem function) and
use it for both primaryNav and secondaryNav maps: accept the nav item object,
call isNavItemActive(item.href) inside the renderer, apply the same Link,
onClick (onNavClick), cn class logic and the item.icon rendering so both
sections reuse the identical logic; update the primaryNav.map and
secondaryNav.map to call this shared renderer passing item and avoid repeating
the JSX and className calculations.
- Line 183: In Sidebar component (web/src/components/layout/sidebar.tsx) change
the JSX href attribute value from double quotes to single quotes: replace
href="https://joinvolvox.com/" with href='https://joinvolvox.com/' so the
external URL string follows the repository rule for single-quoted strings in
JS/TS/TSX files (locate the anchor/Link element in the Sidebar component).
---
Duplicate comments:
In `@web/src/components/layout/dashboard-shell.tsx`:
- Around line 33-35: The main flex pane in DashboardShell currently uses
className "min-h-0 flex-1 overflow-y-auto" which can allow wide children to
cause page-level horizontal overflow; update the main element's className to
include "min-w-0" (e.g., add min-w-0 alongside min-h-0) so the overflow is
constrained to the pane and responsive layout regressions are prevented.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: c9f793c0-ffa4-47f2-89c4-681a9b7b82dc
📒 Files selected for processing (3)
web/src/components/dashboard/member-table.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/sidebar.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{js,ts,tsx}: Use single quotes for strings (except in JSON files); no double quotes
Always include semicolons at the end of statements
Use 2-space indentation (spaces, not tabs)
Always include trailing commas in multi-line arrays, objects, and function parameters
Maintain a maximum line width of 100 characters
Files:
web/src/components/layout/sidebar.tsxweb/src/components/dashboard/member-table.tsxweb/src/components/layout/dashboard-shell.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Never use
console.*methods in web dashboard code; use appropriate logging mechanisms for React applications
Files:
web/src/components/layout/sidebar.tsxweb/src/components/dashboard/member-table.tsxweb/src/components/layout/dashboard-shell.tsx
**/*.{js,ts,tsx,mjs}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,tsx,mjs}: Use ESM syntax (import/export) — CommonJS is not allowed
Use single quotes for strings — double quotes only allowed in JSON files
Always include semicolons at end of statements
Use 2-space indentation for all code
Use Winston logger fromsrc/logger.js— never useconsole.*methods
Files:
web/src/components/layout/sidebar.tsxweb/src/components/dashboard/member-table.tsxweb/src/components/layout/dashboard-shell.tsx
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{ts,tsx} : Web dashboard config editor should use category workspace navigation with reusable SettingsFeatureCard pattern (header + master toggle + Basic/Advanced blocks)
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T20:36:29.483Z
Learning: Applies to web/src/pages/dashboard/**/*.{ts,tsx} : Use shared title helpers from web/src/lib/page-titles.ts for setting browser titles in dashboard pages
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Use `DashboardTitleSync` component and `getDashboardDocumentTitle()` for client-side navigation title updates in the dashboard
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'
Applied to files:
web/src/components/layout/sidebar.tsxweb/src/components/layout/dashboard-shell.tsx
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{ts,tsx} : Web dashboard config editor should use category workspace navigation with reusable SettingsFeatureCard pattern (header + master toggle + Basic/Advanced blocks)
Applied to files:
web/src/components/layout/sidebar.tsxweb/src/components/layout/dashboard-shell.tsx
📚 Learning: 2026-03-12T02:03:52.689Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Use `DashboardTitleSync` component and `getDashboardDocumentTitle()` for client-side navigation title updates in the dashboard
Applied to files:
web/src/components/layout/sidebar.tsxweb/src/components/layout/dashboard-shell.tsx
📚 Learning: 2026-03-10T20:36:29.483Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T20:36:29.483Z
Learning: Applies to web/src/pages/dashboard/**/*.{ts,tsx} : Use shared title helpers from web/src/lib/page-titles.ts for setting browser titles in dashboard pages
Applied to files:
web/src/components/layout/dashboard-shell.tsx
📚 Learning: 2026-03-10T20:36:29.483Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T20:36:29.483Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Apply static metadata to server-rendered dashboard entry pages and use title template format for root app metadata
Applied to files:
web/src/components/layout/dashboard-shell.tsx
📚 Learning: 2026-03-12T02:03:36.476Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.476Z
Learning: Applies to web/src/app/dashboard/**/*.tsx : For dashboard routes, add a matcher entry to `dashboardTitleMatchers` in `web/src/lib/page-titles.ts`: use exact equality for leaf routes (`pathname === '/dashboard/my-route'`) and subtree checks (`pathname.startsWith('/dashboard/my-route/')`); export `metadata` using `createPageMetadata(title)` for SSR entry points
Applied to files:
web/src/components/layout/dashboard-shell.tsx
📚 Learning: 2026-03-12T02:03:52.689Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Verify responsive layout behavior when making dashboard layout changes
Applied to files:
web/src/components/layout/dashboard-shell.tsx
🔇 Additional comments (4)
web/src/components/dashboard/member-table.tsx (3)
17-17: SharedEmptyStateimport is the right abstraction move.This keeps the table aligned with the dashboard’s reusable empty-state pattern and reduces UI drift.
239-239: Container surface update improves structure without changing behavior.The card-like styling is consistent with the UX pass and keeps table overflow handling intact.
286-292: Empty-state integration is correctly adapted for table context.
colSpan={8}is preserved, and the class overrides cleanly remove card chrome so the shared component fits inside the table cell.web/src/components/layout/dashboard-shell.tsx (1)
18-18: Good placement of dashboard title synchronization.Keeping
DashboardTitleSyncmounted in the shell is the right pattern for route-driven title updates across dashboard pages.Based on learnings: Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'.
There was a problem hiding this comment.
Actionable comments posted: 14
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/app/dashboard/conversations/page.tsx`:
- Around line 318-324: The "Active Channels" count is using the full channels
array (all text channels filtered by type === 0), which mislabels idle channels
as active; update the UI in page.tsx to either (A) relabel the card to "Text
Channels" or (B) compute active channels from the conversations dataset
instead—for example derive a Set of unique channel IDs from the conversations
(e.g. conversations.map(c => c.channelId) then new Set(...) and use its size)
and use that value for the displayed count; locate the channels variable and the
effect that filters by type === 0 and replace the displayed channels.length with
the chosen derived value or change the label accordingly.
- Around line 279-295: This route is marked as a client component which prevents
exporting SSR metadata; refactor by turning this file into a server component
that exports metadata via createPageMetadata('Conversations') and move all
interactive UI and hooks into a new client child component (e.g.,
ConversationsClient) that contains PageHeader, the Button with
onClick={handleRefresh}, RefreshCw usage, guildId/loading logic, and any
hooks/state. In this file export const metadata =
createPageMetadata('Conversations') and render the server wrapper that imports
and renders <ConversationsClient />; ensure handlers like handleRefresh, and
symbols PageHeader, RefreshCw remain only in the client child and the route
entry has no 'use client' directive.
In `@web/src/app/dashboard/members/page.tsx`:
- Around line 236-252: Refactor the interactive UI in this page so the top-level
route exports metadata via createPageMetadata('Members'): move the interactive
portions (PageHeader, Button using handleRefresh, loading, guildId state) into a
child component (e.g., MembersClient or MembersPanel) and have the page file
export createPageMetadata('Members') at the module level while rendering the
child component server-side entry; ensure you keep the existing symbols
(PageHeader, handleRefresh, RefreshCw, loading, guildId) inside the new client
component and import/inline it from the page so metadata is available before
client hydration.
In `@web/src/app/dashboard/moderation/page.tsx`:
- Around line 171-177: Run the repository formatter (e.g. prettier/nextjs
format) on the updated JSX block that renders the "User History Lookup" panel so
the whitespace/line breaks match the project's style; specifically reformat the
section containing className="dashboard-panel space-y-3 rounded-2xl p-4 md:p-5"
and its child h3 ("User History Lookup") and p elements, then stage the
resulting changes so CI no longer reports "Formatter would have printed content
differently."
- Around line 202-212: The icon-only clear-history Button (rendered when
lookupUserId is truthy) uses title for accessibility which is not reliable;
update the Button element that calls handleClearUserHistory (the Button wrapping
the X icon) to include an explicit accessible name like aria-label="Clear user
history" so screen readers can identify the action (keep existing title if
desired but add aria-label to the Button component).
- Around line 107-125: Refactor the current moderation/page.tsx into a server
entry that exports metadata = createPageMetadata('Moderation', 'Review cases,
track activity, and audit your moderation team.') and renders a new client child
component (e.g., ModerationClient); move all interactive logic — React hooks,
state, effects, handlers like handleRefresh, statsLoading, casesLoading, and the
JSX that includes PageHeader, Button, RefreshCw, and list rendering — into that
client component, mark it with "use client" at the top, export it as default
from the client file, and update the server page to only import and render
<ModerationClient /> so the server file contains no client-side hooks or state.
In `@web/src/app/dashboard/tickets/page.tsx`:
- Around line 295-322: The summary cards are stale because they use the local
stats state but handleRefresh only refetches tickets; extract the logic that
fetches stats into a reusable async function (e.g., fetchStats or loadStats)
that sets the stats state and call that function both on initial mount and from
handleRefresh; ensure you update the same stats state used by the
dashboard-panel cards (referencing stats and formatDuration) so Refresh triggers
a stats refetch as well as the ticket list.
- Around line 276-292: Remove the top-level "use client" from page.tsx and move
all interactive/client-side logic (hooks, state, event handlers like
handleRefresh, and reactive variables loading and guildId) plus UI that depends
on them (the Button, RefreshCw spinner, and any other interactivity around
PageHeader) into a new client component (e.g., TicketsClient or
TicketsPageClient); leave the page.tsx as a server component that imports and
renders this client child, and add export const metadata =
createPageMetadata('Tickets') at the top-level page export so SSR metadata
works. Ensure the server page still renders PageHeader and the new client
component in the same structure, and keep prop names and handlers consistent
when passing data into the client component.
In `@web/src/components/dashboard/analytics-dashboard.tsx`:
- Around line 672-714: The empty-state branches render before the first
analytics payload arrives because analytics is null while loading is true;
update the conditional that uses hasMessageVolumeData (and the similar checks
around lines referenced) to also require that loading is false or that analytics
!== null (or that analytics.messageVolume is defined/has length) before showing
the EmptyState component (MessageSquare) — while loading is true show the
existing loading skeleton/spinner instead; apply the same guard to the other
empty-state checks for "No model usage", "No token metrics", and "No channel
activity" so they only render after the payload has finished loading.
In `@web/src/components/dashboard/page-header.tsx`:
- Line 36: The decorative Icon rendered in the header ({Icon && <Icon
className="h-5 w-5 text-primary" />}) should be hidden from assistive tech;
update the JSX that renders Icon to include aria-hidden="true" and (optionally)
focusable="false" on the Icon element so it isn’t announced or tabbable while
keeping the existing className and conditional rendering.
In `@web/src/components/layout/dashboard-shell.tsx`:
- Around line 35-38: The root dashboard-shell currently forces a
"dashboard-panel" wrapper (the divs with classNames "dashboard-fade-in" and
"dashboard-panel") around every route which causes nested borders/padding;
update the DashboardShell component in
web/src/components/layout/dashboard-shell.tsx to accept a boolean prop (e.g.,
wrapWithPanel or disablePanel) and render the inner "dashboard-panel" wrapper
conditionally based on that prop so routes that already render their own panel
can pass false, and update calls/pages that need the wrapper to either pass the
new prop or rely on the default.
In `@web/src/components/layout/mobile-sidebar.tsx`:
- Around line 30-33: The SheetContent in mobile-sidebar.tsx uses a fixed class
w-[21.5rem] which can overflow narrow phones; update the SheetContent className
to use a fluid width with a capped max (e.g., replace the fixed width with
w-full and a max width such as max-w-[21.5rem] or max-w-[90vw]) so the sheet
fills available space but never exceeds the viewport; locate the SheetContent
element and modify its className accordingly to prevent clipping on small
viewports.
In `@web/src/components/layout/server-selector.tsx`:
- Around line 188-221: The long Tailwind class string passed into cn for the
Button component (the string starting with "h-[3.2rem] w-full justify-between
rounded-xl border-border/70 bg-gradient-to-r from-background to-muted/40 px-3
shadow-sm") should be broken across lines for readability; refactor by pulling
that class list into a named constant (e.g., buttonClasses) or pass the classes
as a multi-line array into cn([...]) and keep the existing cn(..., className)
call so the styling and className prop behavior remain unchanged; update the
Button JSX to use the new variable/array while leaving the surrounding structure
(Button, cn, and className) intact.
In `@web/src/components/layout/sidebar.tsx`:
- Around line 100-107: The effect that reopens the secondary nav only depends on
hasActiveSecondaryItem so navigating between secondary routes can leave the
section collapsed; update the useEffect that currently references
hasActiveSecondaryItem to also depend on the current pathname (or use pathname
instead of hasActiveSecondaryItem) and call setIsSecondaryOpen(true) when the
pathname changes and hasActiveSecondaryItem is true—adjust the dependency array
for the useEffect (or key the effect to pathname) so back/forward and deep-link
navigation reopen the section; reference the existing hasActiveSecondaryItem,
isSecondaryOpen, setIsSecondaryOpen and the useEffect block when making the
change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 588e0665-7565-4bce-9950-94565a4ba83f
📒 Files selected for processing (20)
web/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/app/dashboard/logs/page.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/globals.cssweb/src/components/dashboard/analytics-dashboard.tsxweb/src/components/dashboard/config-editor.tsxweb/src/components/dashboard/config-workspace/category-navigation.tsxweb/src/components/dashboard/config-workspace/config-search.tsxweb/src/components/dashboard/config-workspace/settings-feature-card.tsxweb/src/components/dashboard/log-filters.tsxweb/src/components/dashboard/log-viewer.tsxweb/src/components/dashboard/page-header.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/header.tsxweb/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/server-selector.tsxweb/src/components/layout/sidebar.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{js,ts,tsx}: Use single quotes for strings (except in JSON files); no double quotes
Always include semicolons at the end of statements
Use 2-space indentation (spaces, not tabs)
Always include trailing commas in multi-line arrays, objects, and function parameters
Maintain a maximum line width of 100 characters
Files:
web/src/components/layout/header.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/analytics-dashboard.tsxweb/src/components/dashboard/config-workspace/category-navigation.tsxweb/src/components/layout/server-selector.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/dashboard/log-viewer.tsxweb/src/components/dashboard/config-workspace/settings-feature-card.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/components/dashboard/log-filters.tsxweb/src/components/layout/sidebar.tsxweb/src/app/dashboard/logs/page.tsxweb/src/components/dashboard/config-workspace/config-search.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/mobile-sidebar.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Never use
console.*methods in web dashboard code; use appropriate logging mechanisms for React applications
Files:
web/src/components/layout/header.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/analytics-dashboard.tsxweb/src/components/dashboard/config-workspace/category-navigation.tsxweb/src/components/layout/server-selector.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/dashboard/log-viewer.tsxweb/src/components/dashboard/config-workspace/settings-feature-card.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/components/dashboard/log-filters.tsxweb/src/components/layout/sidebar.tsxweb/src/app/dashboard/logs/page.tsxweb/src/components/dashboard/config-workspace/config-search.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/mobile-sidebar.tsx
**/*.{js,ts,tsx,mjs}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,tsx,mjs}: Use ESM syntax (import/export) — CommonJS is not allowed
Use single quotes for strings — double quotes only allowed in JSON files
Always include semicolons at end of statements
Use 2-space indentation for all code
Use Winston logger fromsrc/logger.js— never useconsole.*methods
Files:
web/src/components/layout/header.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/analytics-dashboard.tsxweb/src/components/dashboard/config-workspace/category-navigation.tsxweb/src/components/layout/server-selector.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/dashboard/log-viewer.tsxweb/src/components/dashboard/config-workspace/settings-feature-card.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/components/dashboard/log-filters.tsxweb/src/components/layout/sidebar.tsxweb/src/app/dashboard/logs/page.tsxweb/src/components/dashboard/config-workspace/config-search.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/mobile-sidebar.tsx
web/src/app/dashboard/**/*.tsx
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
For dashboard routes, add a matcher entry to
dashboardTitleMatchersinweb/src/lib/page-titles.ts: use exact equality for leaf routes (pathname === '/dashboard/my-route') and subtree checks (pathname.startsWith('/dashboard/my-route/')); exportmetadatausingcreatePageMetadata(title)for SSR entry points
Files:
web/src/app/dashboard/members/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/logs/page.tsx
web/src/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
web/src/app/**/*.{ts,tsx}: ExportmetadatausingcreatePageMetadata()fromweb/src/lib/page-titles.tsin SSR entry points for dashboard pages
UseDashboardTitleSynccomponent andgetDashboardDocumentTitle()for client-side navigation title updates in the dashboard
Files:
web/src/app/dashboard/members/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/logs/page.tsx
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{ts,tsx} : Web dashboard config editor should use category workspace navigation with reusable SettingsFeatureCard pattern (header + master toggle + Basic/Advanced blocks)
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T20:36:29.483Z
Learning: Applies to web/src/pages/dashboard/**/*.{ts,tsx} : Use shared title helpers from web/src/lib/page-titles.ts for setting browser titles in dashboard pages
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Use `DashboardTitleSync` component and `getDashboardDocumentTitle()` for client-side navigation title updates in the dashboard
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'
Applied to files:
web/src/components/layout/header.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/analytics-dashboard.tsxweb/src/components/dashboard/config-workspace/category-navigation.tsxweb/src/components/layout/server-selector.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/dashboard/log-viewer.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/components/dashboard/log-filters.tsxweb/src/components/layout/sidebar.tsxweb/src/app/dashboard/logs/page.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/mobile-sidebar.tsx
📚 Learning: 2026-03-12T02:03:52.689Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Use `DashboardTitleSync` component and `getDashboardDocumentTitle()` for client-side navigation title updates in the dashboard
Applied to files:
web/src/components/layout/header.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/analytics-dashboard.tsxweb/src/components/dashboard/config-workspace/category-navigation.tsxweb/src/components/layout/server-selector.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/dashboard/log-viewer.tsxweb/src/components/dashboard/config-workspace/settings-feature-card.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/globals.cssweb/src/components/layout/sidebar.tsxweb/src/app/dashboard/logs/page.tsxweb/src/components/dashboard/config-workspace/config-search.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/mobile-sidebar.tsx
📚 Learning: 2026-03-10T20:36:29.483Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T20:36:29.483Z
Learning: Applies to web/src/pages/dashboard/**/*.{ts,tsx} : Use shared title helpers from web/src/lib/page-titles.ts for setting browser titles in dashboard pages
Applied to files:
web/src/components/layout/header.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/analytics-dashboard.tsxweb/src/components/dashboard/config-workspace/category-navigation.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/dashboard/log-viewer.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/globals.cssweb/src/app/dashboard/logs/page.tsxweb/src/components/dashboard/config-workspace/config-search.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/mobile-sidebar.tsx
📚 Learning: 2026-03-12T02:03:36.476Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.476Z
Learning: Applies to web/src/app/dashboard/**/*.tsx : For dashboard routes, add a matcher entry to `dashboardTitleMatchers` in `web/src/lib/page-titles.ts`: use exact equality for leaf routes (`pathname === '/dashboard/my-route'`) and subtree checks (`pathname.startsWith('/dashboard/my-route/')`); export `metadata` using `createPageMetadata(title)` for SSR entry points
Applied to files:
web/src/components/layout/header.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/logs/page.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/mobile-sidebar.tsx
📚 Learning: 2026-03-10T20:36:29.483Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T20:36:29.483Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Apply static metadata to server-rendered dashboard entry pages and use title template format for root app metadata
Applied to files:
web/src/components/layout/header.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/components/dashboard/analytics-dashboard.tsxweb/src/components/layout/server-selector.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/dashboard/log-viewer.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/logs/page.tsxweb/src/components/dashboard/config-workspace/config-search.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/mobile-sidebar.tsx
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{ts,tsx} : Web dashboard config editor should use category workspace navigation with reusable SettingsFeatureCard pattern (header + master toggle + Basic/Advanced blocks)
Applied to files:
web/src/components/layout/header.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/config-workspace/category-navigation.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/components/dashboard/log-viewer.tsxweb/src/components/dashboard/config-workspace/settings-feature-card.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/globals.cssweb/src/components/layout/sidebar.tsxweb/src/app/dashboard/logs/page.tsxweb/src/components/dashboard/config-workspace/config-search.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/mobile-sidebar.tsx
📚 Learning: 2026-03-12T02:03:52.689Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Export `metadata` using `createPageMetadata()` from `web/src/lib/page-titles.ts` in SSR entry points for dashboard pages
Applied to files:
web/src/components/layout/header.tsxweb/src/components/dashboard/page-header.tsxweb/src/app/dashboard/members/page.tsxweb/src/app/dashboard/moderation/page.tsxweb/src/app/dashboard/audit-log/page.tsxweb/src/app/dashboard/tickets/page.tsxweb/src/app/dashboard/logs/page.tsx
📚 Learning: 2026-03-12T02:03:52.689Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Add a matcher entry to `dashboardTitleMatchers` in `web/src/lib/page-titles.ts` for every new dashboard route
Applied to files:
web/src/components/layout/header.tsxweb/src/components/dashboard/page-header.tsx
📚 Learning: 2026-03-12T02:03:36.476Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.476Z
Learning: Applies to web/src/**/*.{ts,tsx} : Never use `console.*` methods in web dashboard code; use appropriate logging mechanisms for React applications
Applied to files:
web/src/components/dashboard/log-viewer.tsxweb/src/components/dashboard/log-filters.tsxweb/src/app/dashboard/logs/page.tsx
📚 Learning: 2026-03-10T20:36:29.483Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T20:36:29.483Z
Learning: Applies to web/src/app/api/**/route.ts : Include guildId in signed WebSocket ticket payload when issuing tickets from dashboard endpoints
Applied to files:
web/src/app/dashboard/tickets/page.tsx
📚 Learning: 2026-03-12T02:03:36.476Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.476Z
Learning: Applies to **/*.{js,ts,tsx} : Use single quotes for strings (except in JSON files); no double quotes
Applied to files:
web/src/components/layout/sidebar.tsx
📚 Learning: 2026-03-12T02:03:52.689Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Applies to **/*.{js,ts,tsx,mjs} : Use single quotes for strings — double quotes only allowed in JSON files
Applied to files:
web/src/components/layout/sidebar.tsx
📚 Learning: 2026-03-12T02:03:52.689Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.689Z
Learning: Verify responsive layout behavior when making dashboard layout changes
Applied to files:
web/src/components/layout/dashboard-shell.tsxweb/src/components/layout/mobile-sidebar.tsx
🪛 GitHub Actions: CI
web/src/app/dashboard/moderation/page.tsx
[error] 177-177: Formatter would have printed content differently (prettier formatting issue detected).
🪛 GitHub Check: SonarCloud Code Analysis
web/src/components/layout/header.tsx
[warning] 56-56: Ambiguous spacing after previous element span
web/src/components/dashboard/page-header.tsx
[warning] 14-20: Mark the props of the component as read-only.
🔇 Additional comments (20)
web/src/components/layout/mobile-sidebar.tsx (1)
41-42: Good mobile UX: closes sheet after nav click.
onNavClick={() => setOpen(false)}prevents stale open state after navigation.web/src/components/dashboard/config-workspace/config-search.tsx (1)
40-40: LGTM: visual refresh keeps behavior intact.These class updates are purely presentational and preserve existing search/filter/select behavior.
Also applies to: 59-59, 69-69
web/src/app/globals.css (1)
183-264: LGTM: foundational dashboard style primitives are cleanly defined.The new canvas/grid/panel/chip/animation classes are consistent and reusable for the dashboard UI pass.
web/src/components/dashboard/config-workspace/settings-feature-card.tsx (1)
10-10: Good extensibility improvement.Passing
classNamethroughcn(...)is the right change and keeps default layout behavior while enabling per-feature overrides.Also applies to: 23-23, 50-50, 66-69
web/src/components/dashboard/page-header.tsx (1)
22-49: Nice shared abstraction for dashboard headers.The props surface is lean and the layout supports icon/title/description/actions cleanly.
web/src/components/dashboard/config-workspace/category-navigation.tsx (1)
45-45: LGTM: navigation restructure preserves interaction semantics.This keeps category switching/dirty badges intact while improving layout responsiveness.
Also applies to: 62-88
web/src/components/dashboard/log-filters.tsx (1)
107-107: LGTM: style updates are safe and non-functional.The filter UX is visually improved without altering existing debounce and emit logic.
Also applies to: 110-110, 134-134, 145-145, 154-154
web/src/components/layout/dashboard-shell.tsx (1)
21-23: Good fix on flex min-size/scroll containment.
min-h-0placement on the row and scroll panes is correct and prevents outer-page overflow regression.Also applies to: 33-34
web/src/components/layout/header.tsx (1)
31-35: LGTM: header refactor improves context without breaking auth/session behavior.The route-aware subtitle integration and menu restructuring look solid.
Also applies to: 50-51, 75-127
web/src/app/dashboard/logs/page.tsx (1)
27-31: No refactor needed — this page correctly uses the established client component pattern.The
logsroute usesuseLogStream()anduseGuildSelection(), both client hooks. The'use client'directive is required and correct. The title is managed viaDashboardTitleSync(mounted indashboard-shell.tsx) which looks up the route indashboardTitleMatchers— the entry for/dashboard/logsalready exists there. This matches the pattern used inaudit-logandmoderationpages. No server wrapper or refactor needed.> Likely an incorrect or invalid review comment.web/src/components/layout/server-selector.tsx (3)
41-41: LGTM!Adding
text-smfor consistent typography in dropdown rows aligns with the design system.
139-157: LGTM!The loading and error states now use the
dashboard-chipstyling consistently with the new design system. Adding the explicit Retry button improves usability over the previous refresh icon-only approach.
223-271: LGTM!The dropdown content and item styling updates are well-implemented:
- Increased width (w-80) provides better visual hierarchy
- Consistent label typography with
text-[11px] uppercase tracking-[0.14em]- Rounded corners and padding on items improve touch targets
web/src/app/dashboard/audit-log/page.tsx (7)
6-7: LGTM!Clean imports for the new shared dashboard components.
272-296: LGTM!The adoption of
PageHeaderandEmptyStatecomponents provides consistent structure across dashboard pages. The refresh button is appropriately disabled when no guild is selected or loading.
302-327: LGTM!The metrics row provides useful at-a-glance information. The gradient styling and consistent typography (
text-[11px] uppercase tracking-[0.14em]) align with the design system. Usingtabular-numsfor numeric values ensures alignment.
330-399: LGTM!Filter controls are well-organized within the dashboard-panel container. Consistent input heights (
h-10) and border radius (rounded-xl) improve visual coherence.
482-494: LGTM!The dynamic
EmptyStatethat varies based on active filters is a nice UX touch—users get relevant messaging whether they're seeing no results due to filters or simply have no entries yet.
498-521: LGTM!Pagination container styling is consistent with the
dashboard-chippattern. The disabled states and page calculation logic are correct.
120-120: Matcher entry for/dashboard/audit-logis present indashboardTitleMatchers.The route has the required matcher entry with both exact equality and subtree checks.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
web/src/components/layout/sidebar.tsx (2)
121-154: 🧹 Nitpick | 🔵 TrivialDuplicated nav-item rendering logic across primary and secondary sections.
Both
primaryNav.map()(lines 122-153) andsecondaryNav.map()(lines 168-201) contain identical Link/icon/className rendering logic. This increases maintenance burden and drift risk during future UI updates.♻️ Suggested extraction
function NavItem({ item, isActive, onNavClick, }: { item: { name: string; href: string; icon: React.ComponentType<{ className?: string }> }; isActive: boolean; onNavClick?: () => void; }) { return ( <Link key={item.name} href={item.href} onClick={onNavClick} className={cn( 'group relative flex items-center gap-3 rounded-xl px-3 py-2.5 text-sm font-medium transition-all duration-200', 'hover:bg-muted/75 hover:text-foreground', isActive ? 'bg-primary/12 text-foreground ring-1 ring-primary/25' : 'text-muted-foreground', )} > <span className={cn( 'absolute left-1.5 top-1/2 h-5 w-1 -translate-y-1/2 rounded-full transition-colors', isActive ? 'bg-primary/90' : 'bg-transparent group-hover:bg-border', )} /> <item.icon className={cn( 'h-4 w-4 transition-colors', isActive ? 'text-primary' : 'text-muted-foreground group-hover:text-foreground', )} /> <span>{item.name}</span> </Link> ); }Then both maps become:
{primaryNav.map((item) => ( <NavItem key={item.name} item={item} isActive={isNavItemActive(item.href)} onNavClick={onNavClick} /> ))}Also applies to: 167-201
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/layout/sidebar.tsx` around lines 121 - 154, The primary and secondary nav maps duplicate the same Link rendering logic; extract a reusable NavItem component (e.g., function NavItem({ item, isActive, onNavClick }) that renders the Link, span indicator, icon and label) and replace both primaryNav.map(...) and secondaryNav.map(...) usages with <NavItem key={item.name} item={item} isActive={isNavItemActive(item.href)} onNavClick={onNavClick} /> so all className/click/icon logic lives in one place (keep the same props shape for item with name, href, icon and preserve isNavItemActive and onNavClick usage).
219-220: 🛠️ Refactor suggestion | 🟠 MajorUse single quotes for the external URL string.
The
hrefattribute uses double quotes, which violates the repository's string-quote rule.✏️ Proposed fix
<Link - href="https://joinvolvox.com/" + href='https://joinvolvox.com/' target="_blank"As per coding guidelines, "
**/*.{js,ts,tsx}: Use single quotes for strings (except in JSON files); no double quotes".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/layout/sidebar.tsx` around lines 219 - 220, Change the double-quoted URL in the Link JSX to use single quotes to follow the repo string-quote rule; locate the Link element inside the Sidebar component (in web/src/components/layout/sidebar.tsx) where href="https://joinvolvox.com/" is used and replace the attribute value with a single-quoted string for the external URL.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/layout/sidebar.tsx`:
- Around line 84-88: The Settings nav item currently uses the Bot icon while the
Bot Config item uses the Cog icon; swap the icons so Settings uses a
settings-themed icon and Bot Config uses the bot-themed icon (locate the
navigation objects where name: 'Settings' references icon: Bot and name: 'Bot
Config' references icon: Cog and update accordingly), or replace the Settings
icon with a settings-specific icon such as Settings2 or SlidersHorizontal from
lucide-react to resolve the semantic mismatch.
---
Duplicate comments:
In `@web/src/components/layout/sidebar.tsx`:
- Around line 121-154: The primary and secondary nav maps duplicate the same
Link rendering logic; extract a reusable NavItem component (e.g., function
NavItem({ item, isActive, onNavClick }) that renders the Link, span indicator,
icon and label) and replace both primaryNav.map(...) and secondaryNav.map(...)
usages with <NavItem key={item.name} item={item}
isActive={isNavItemActive(item.href)} onNavClick={onNavClick} /> so all
className/click/icon logic lives in one place (keep the same props shape for
item with name, href, icon and preserve isNavItemActive and onNavClick usage).
- Around line 219-220: Change the double-quoted URL in the Link JSX to use
single quotes to follow the repo string-quote rule; locate the Link element
inside the Sidebar component (in web/src/components/layout/sidebar.tsx) where
href="https://joinvolvox.com/" is used and replace the attribute value with a
single-quoted string for the external URL.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: b751de15-9574-481d-93f2-9a17ea0682c3
📒 Files selected for processing (2)
web/src/components/layout/sidebar.tsxweb/tsconfig.json
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (4)
**/*.json
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use double quotes in JSON files (standard JSON format); this exception applies only to JSON files, not JavaScript/TypeScript
Files:
web/tsconfig.json
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{js,ts,tsx}: Use single quotes for strings (except in JSON files); no double quotes
Always include semicolons at the end of statements
Use 2-space indentation (spaces, not tabs)
Always include trailing commas in multi-line arrays, objects, and function parameters
Maintain a maximum line width of 100 characters
Files:
web/src/components/layout/sidebar.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Never use
console.*methods in web dashboard code; use appropriate logging mechanisms for React applications
Files:
web/src/components/layout/sidebar.tsx
**/*.{js,ts,tsx,mjs}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,tsx,mjs}: Use ESM syntax (import/export) — CommonJS is not allowed
Use single quotes for strings — double quotes only allowed in JSON files
Always include semicolons at end of statements
Use 2-space indentation for all code
Use Winston logger fromsrc/logger.js— never useconsole.*methods
Files:
web/src/components/layout/sidebar.tsx
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{ts,tsx} : Web dashboard config editor should use category workspace navigation with reusable SettingsFeatureCard pattern (header + master toggle + Basic/Advanced blocks)
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.709Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Use `DashboardTitleSync` component and `getDashboardDocumentTitle()` for client-side navigation title updates in the dashboard
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T06:42:38.728Z
Learning: Applies to web/src/pages/dashboard/**/*.{ts,tsx} : Use shared title helpers from web/src/lib/page-titles.ts for setting browser titles in dashboard pages
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T05:32:46.325Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Apply static metadata to server-rendered dashboard entry pages and use title template format for root app metadata
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.709Z
Learning: Verify responsive layout behavior when making dashboard layout changes
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to web/src/app/dashboard/**/*.tsx : For dashboard routes, add a matcher entry to `dashboardTitleMatchers` in `web/src/lib/page-titles.ts`: use exact equality for leaf routes (`pathname === '/dashboard/my-route'`) and subtree checks (`pathname.startsWith('/dashboard/my-route/')`); export `metadata` using `createPageMetadata(title)` for SSR entry points
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{ts,tsx} : Web dashboard config editor should use category workspace navigation with reusable SettingsFeatureCard pattern (header + master toggle + Basic/Advanced blocks)
Applied to files:
web/src/components/layout/sidebar.tsx
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'
Applied to files:
web/src/components/layout/sidebar.tsx
📚 Learning: 2026-03-12T02:03:52.709Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.709Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Use `DashboardTitleSync` component and `getDashboardDocumentTitle()` for client-side navigation title updates in the dashboard
Applied to files:
web/src/components/layout/sidebar.tsx
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to web/src/app/dashboard/**/*.tsx : For dashboard routes, add a matcher entry to `dashboardTitleMatchers` in `web/src/lib/page-titles.ts`: use exact equality for leaf routes (`pathname === '/dashboard/my-route'`) and subtree checks (`pathname.startsWith('/dashboard/my-route/')`); export `metadata` using `createPageMetadata(title)` for SSR entry points
Applied to files:
web/src/components/layout/sidebar.tsx
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to **/*.{js,ts,tsx} : Use single quotes for strings (except in JSON files); no double quotes
Applied to files:
web/src/components/layout/sidebar.tsx
📚 Learning: 2026-03-12T02:03:52.709Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.709Z
Learning: Applies to **/*.{js,ts,tsx,mjs} : Use single quotes for strings — double quotes only allowed in JSON files
Applied to files:
web/src/components/layout/sidebar.tsx
🔇 Additional comments (4)
web/tsconfig.json (1)
24-24:baseUrladdition looks correct for alias resolution.Setting
"baseUrl": "."is consistent with the existing"paths"mapping and supports stable@/import resolution.web/src/components/layout/sidebar.tsx (3)
96-110: Active state logic and effect implementation look correct.The
isNavItemActivehelper properly handles exact matches for/dashboardand prefix matches for nested routes. TheuseEffectnow correctly includespathnamein the dependency array, ensuring the Extensions section reopens on navigation changes when a secondary item becomes active.
158-166: Collapsible Extensions section is well-implemented.Using native
<details>/<summary>with controlled state viaopenandonToggleis a good approach—it provides accessibility benefits (keyboard navigation, screen reader support) while maintaining React state synchronization.
218-229: Support link now correctly invokesonNavClick.The external support link properly calls
onNavClickon click, which will close the mobile drawer when navigating. This addresses the previous concern about the drawer remaining open.
|
@BillChirico could you review this |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (3)
web/src/components/layout/sidebar.tsx (1)
220-222:⚠️ Potential issue | 🟡 MinorUse single quotes for the external
hrefliteral.Line 221 still uses double quotes for the URL string, which violates the repository string rule.
As per coding guidelines, "`**/*.{js,ts,tsx}`: Use single quotes for strings (except in JSON files); no double quotes".✏️ Proposed fix
- href="https://joinvolvox.com/" + href='https://joinvolvox.com/'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/layout/sidebar.tsx` around lines 220 - 222, The external Link component's href prop currently uses double quotes; update the string literal to use single quotes to comply with the repository rule (change the href on the Link element to use single-quoted string so Link href='https://joinvolvox.com/' uses single quotes).web/src/components/layout/dashboard-shell.tsx (1)
33-37:⚠️ Potential issue | 🟠 MajorAdd
min-w-0on the main flex child to prevent horizontal overflow.Line 33 still allows default flex min-width behavior, so wide content can push layout width instead of staying constrained in the scroll pane.
Based on learnings: "Verify responsive layout behavior when making dashboard layout changes".💡 Proposed fix
- <main className="min-h-0 flex-1 overflow-y-auto"> + <main className="min-h-0 min-w-0 flex-1 overflow-y-auto">🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/layout/dashboard-shell.tsx` around lines 33 - 37, The main flex child allows default min-width behavior which can cause horizontal overflow; update the main element's className (the <main className="min-h-0 flex-1 overflow-y-auto">) to include min-w-0 so it becomes constrained in the flex container and content scrolls vertically instead of expanding the layout.web/src/app/dashboard/conversations/page.tsx (1)
1-8:⚠️ Potential issue | 🟠 MajorThis dashboard route entry still needs SSR metadata export.
Because this file is a client component route entry, it cannot export
metadataviacreatePageMetadata(...). Please move interactive logic to a client child component and keeppage.tsxas a server wrapper that exports metadata.As per coding guidelines, "`web/src/app/dashboard/**/*.tsx`: ... export `metadata` using `createPageMetadata(title)` for SSR entry points".🧩 Suggested shape
-'use client'; +import { createPageMetadata } from '@/lib/page-titles'; +import { ConversationsClientPage } from './conversations-client-page'; + +export const metadata = createPageMetadata('Conversations'); + +export default function ConversationsPage() { + return <ConversationsClientPage />; +}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/app/dashboard/conversations/page.tsx` around lines 1 - 8, This client-only route currently contains interactive logic ('use client') and therefore cannot export SSR metadata; to fix, remove the interactive logic from the page-level entry and turn page.tsx into a server wrapper that exports metadata via createPageMetadata(...) (e.g., export const metadata = createPageMetadata('Conversations')), then create a separate client child component (e.g., ConversationsClient or ConversationsView) that contains the current client imports and hooks (useRouter, useEffect, useState, useRef, etc.) and is imported/used by the server wrapper; ensure the server wrapper does not include "use client" and simply renders the client child component.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/dashboard/config-workspace/settings-feature-card.tsx`:
- Around line 23-24: Update the JSDoc for the SettingsFeatureCard component to
document the new optional className prop: add a `@param` (or `@prop`) entry
describing className as an optional string used to pass additional CSS classes
to the root element, and include its type and optional status in the existing
doc block above the SettingsFeatureCard (or the Props/interface) so the
runtime/API contract matches the code.
---
Duplicate comments:
In `@web/src/app/dashboard/conversations/page.tsx`:
- Around line 1-8: This client-only route currently contains interactive logic
('use client') and therefore cannot export SSR metadata; to fix, remove the
interactive logic from the page-level entry and turn page.tsx into a server
wrapper that exports metadata via createPageMetadata(...) (e.g., export const
metadata = createPageMetadata('Conversations')), then create a separate client
child component (e.g., ConversationsClient or ConversationsView) that contains
the current client imports and hooks (useRouter, useEffect, useState, useRef,
etc.) and is imported/used by the server wrapper; ensure the server wrapper does
not include "use client" and simply renders the client child component.
In `@web/src/components/layout/dashboard-shell.tsx`:
- Around line 33-37: The main flex child allows default min-width behavior which
can cause horizontal overflow; update the main element's className (the <main
className="min-h-0 flex-1 overflow-y-auto">) to include min-w-0 so it becomes
constrained in the flex container and content scrolls vertically instead of
expanding the layout.
In `@web/src/components/layout/sidebar.tsx`:
- Around line 220-222: The external Link component's href prop currently uses
double quotes; update the string literal to use single quotes to comply with the
repository rule (change the href on the Link element to use single-quoted string
so Link href='https://joinvolvox.com/' uses single quotes).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: a7ec9cf2-bd43-4ecc-ae76-1ba44f0dbee8
📒 Files selected for processing (6)
web/src/app/dashboard/conversations/page.tsxweb/src/components/dashboard/config-workspace/settings-feature-card.tsxweb/src/components/dashboard/page-header.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/sidebar.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{js,ts,tsx}: Use single quotes for strings (except in JSON files); no double quotes
Always include semicolons at the end of statements
Use 2-space indentation (spaces, not tabs)
Always include trailing commas in multi-line arrays, objects, and function parameters
Maintain a maximum line width of 100 characters
Files:
web/src/components/dashboard/page-header.tsxweb/src/components/dashboard/config-workspace/settings-feature-card.tsxweb/src/components/layout/sidebar.tsxweb/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/conversations/page.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Never use
console.*methods in web dashboard code; use appropriate logging mechanisms for React applications
Files:
web/src/components/dashboard/page-header.tsxweb/src/components/dashboard/config-workspace/settings-feature-card.tsxweb/src/components/layout/sidebar.tsxweb/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/conversations/page.tsx
**/*.{js,ts,tsx,mjs}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,tsx,mjs}: Use ESM syntax (import/export) — CommonJS is not allowed
Use single quotes for strings — double quotes only allowed in JSON files
Always include semicolons at end of statements
Use 2-space indentation for all code
Use Winston logger fromsrc/logger.js— never useconsole.*methods
Files:
web/src/components/dashboard/page-header.tsxweb/src/components/dashboard/config-workspace/settings-feature-card.tsxweb/src/components/layout/sidebar.tsxweb/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/conversations/page.tsx
web/src/app/dashboard/**/*.tsx
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
For dashboard routes, add a matcher entry to
dashboardTitleMatchersinweb/src/lib/page-titles.ts: use exact equality for leaf routes (pathname === '/dashboard/my-route') and subtree checks (pathname.startsWith('/dashboard/my-route/')); exportmetadatausingcreatePageMetadata(title)for SSR entry points
Files:
web/src/app/dashboard/conversations/page.tsx
web/src/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
web/src/app/**/*.{ts,tsx}: ExportmetadatausingcreatePageMetadata()fromweb/src/lib/page-titles.tsin SSR entry points for dashboard pages
UseDashboardTitleSynccomponent andgetDashboardDocumentTitle()for client-side navigation title updates in the dashboard
Files:
web/src/app/dashboard/conversations/page.tsx
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.709Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Use `DashboardTitleSync` component and `getDashboardDocumentTitle()` for client-side navigation title updates in the dashboard
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{ts,tsx} : Web dashboard config editor should use category workspace navigation with reusable SettingsFeatureCard pattern (header + master toggle + Basic/Advanced blocks)
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T06:42:38.728Z
Learning: Applies to web/src/pages/dashboard/**/*.{ts,tsx} : Use shared title helpers from web/src/lib/page-titles.ts for setting browser titles in dashboard pages
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to web/src/app/dashboard/**/*.tsx : For dashboard routes, add a matcher entry to `dashboardTitleMatchers` in `web/src/lib/page-titles.ts`: use exact equality for leaf routes (`pathname === '/dashboard/my-route'`) and subtree checks (`pathname.startsWith('/dashboard/my-route/')`); export `metadata` using `createPageMetadata(title)` for SSR entry points
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T05:32:46.325Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Apply static metadata to server-rendered dashboard entry pages and use title template format for root app metadata
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.709Z
Learning: Verify responsive layout behavior when making dashboard layout changes
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.709Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Export `metadata` using `createPageMetadata()` from `web/src/lib/page-titles.ts` in SSR entry points for dashboard pages
📚 Learning: 2026-03-12T02:03:52.709Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.709Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Use `DashboardTitleSync` component and `getDashboardDocumentTitle()` for client-side navigation title updates in the dashboard
Applied to files:
web/src/components/dashboard/page-header.tsxweb/src/components/dashboard/config-workspace/settings-feature-card.tsxweb/src/components/layout/sidebar.tsxweb/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/conversations/page.tsx
📚 Learning: 2026-03-11T06:42:38.728Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T06:42:38.728Z
Learning: Applies to web/src/pages/dashboard/**/*.{ts,tsx} : Use shared title helpers from web/src/lib/page-titles.ts for setting browser titles in dashboard pages
Applied to files:
web/src/components/dashboard/page-header.tsxweb/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/conversations/page.tsx
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'
Applied to files:
web/src/components/dashboard/page-header.tsxweb/src/components/layout/sidebar.tsxweb/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/conversations/page.tsx
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to web/src/app/dashboard/**/*.tsx : For dashboard routes, add a matcher entry to `dashboardTitleMatchers` in `web/src/lib/page-titles.ts`: use exact equality for leaf routes (`pathname === '/dashboard/my-route'`) and subtree checks (`pathname.startsWith('/dashboard/my-route/')`); export `metadata` using `createPageMetadata(title)` for SSR entry points
Applied to files:
web/src/components/dashboard/page-header.tsxweb/src/components/layout/sidebar.tsxweb/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/conversations/page.tsx
📚 Learning: 2026-03-11T05:32:46.325Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T05:32:46.325Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Apply static metadata to server-rendered dashboard entry pages and use title template format for root app metadata
Applied to files:
web/src/components/dashboard/page-header.tsxweb/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/conversations/page.tsx
📚 Learning: 2026-03-12T02:03:52.709Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.709Z
Learning: Applies to web/src/app/**/*.{ts,tsx} : Export `metadata` using `createPageMetadata()` from `web/src/lib/page-titles.ts` in SSR entry points for dashboard pages
Applied to files:
web/src/components/dashboard/page-header.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/conversations/page.tsx
📚 Learning: 2026-03-12T02:03:52.709Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.709Z
Learning: Add a matcher entry to `dashboardTitleMatchers` in `web/src/lib/page-titles.ts` for every new dashboard route
Applied to files:
web/src/components/dashboard/page-header.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/conversations/page.tsx
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{ts,tsx} : Web dashboard config editor should use category workspace navigation with reusable SettingsFeatureCard pattern (header + master toggle + Basic/Advanced blocks)
Applied to files:
web/src/components/dashboard/page-header.tsxweb/src/components/dashboard/config-workspace/settings-feature-card.tsxweb/src/components/layout/sidebar.tsxweb/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/conversations/page.tsx
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to **/*.{js,ts,tsx} : Use single quotes for strings (except in JSON files); no double quotes
Applied to files:
web/src/components/layout/sidebar.tsx
📚 Learning: 2026-03-12T02:03:52.709Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.709Z
Learning: Applies to **/*.{js,ts,tsx,mjs} : Use single quotes for strings — double quotes only allowed in JSON files
Applied to files:
web/src/components/layout/sidebar.tsx
📚 Learning: 2026-03-12T02:03:52.709Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T02:03:52.709Z
Learning: Verify responsive layout behavior when making dashboard layout changes
Applied to files:
web/src/components/layout/mobile-sidebar.tsxweb/src/components/layout/dashboard-shell.tsx
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to **/*.{js,ts,tsx} : Maintain a maximum line width of 100 characters
Applied to files:
web/src/components/layout/mobile-sidebar.tsx
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to web/src/**/*.{ts,tsx} : Never use `console.*` methods in web dashboard code; use appropriate logging mechanisms for React applications
Applied to files:
web/src/components/layout/dashboard-shell.tsxweb/src/app/dashboard/conversations/page.tsx
🪛 GitHub Check: SonarCloud Code Analysis
web/src/components/dashboard/page-header.tsx
[warning] 14-20: Mark the props of the component as read-only.
🔇 Additional comments (5)
web/src/components/dashboard/config-workspace/settings-feature-card.tsx (2)
10-10:cnimport is correctly introduced and used.Clean, scoped utility import with no side effects or style-rule regressions.
23-24: GoodclassNamepassthrough design onSettingsFeatureCard.This adds flexible styling control while keeping the base card classes intact via
cn(...).Based on learnings: Web dashboard config editor should use category workspace navigation with reusable SettingsFeatureCard pattern (header + master toggle + Basic/Advanced blocks).
Also applies to: 50-51, 66-69
web/src/components/layout/mobile-sidebar.tsx (1)
30-42: Responsive drawer update looks good.The sheet now uses viewport-capped width and improved section spacing, which avoids the narrow-screen clipping issue while preserving hierarchy.
web/src/components/dashboard/page-header.tsx (1)
14-49: Solid reusable header abstraction.The component cleanly standardizes title/description/action layout and keeps optional icon rendering accessible.
web/src/app/dashboard/conversations/page.tsx (1)
279-503: The new conversations UI structure is cohesive and clearer.The PageHeader/EmptyState adoption plus the dashboard-panel metric/filter/table grouping improves scanability without changing fetch/filter/pagination behavior.
- sidebar.tsx: extract NavItem interface + renderNavItem helper (comment 1) - sidebar.tsx: single quotes for joinvolvox.com URL (comment 2) - conversations: split into server page (+ metadata) + ConversationsClient (comment 3) - conversations: relabel channels count to 'Text Channels' (comment 3b) - members: split into server page (+ metadata) + MembersClient (comment 4) - moderation: split into server page (+ metadata) + ModerationClient (comment 5) - moderation: aria-label already present on clear-history button (comment 7) - tickets: split into server page (+ metadata) + TicketsClient (comment 8) - tickets: fetchStats extracted as reusable callback, called from handleRefresh (comment 9) - analytics-dashboard: gate empty-state fallbacks on !loading && analytics !== null (comment 10) - server-selector: break long DropdownMenuLabel class string (comment 12) - settings-feature-card: document className prop in JSDoc (comment 13)
- sidebar.tsx: extract NavItem interface + renderNavItem helper (comment 1) - sidebar.tsx: single quotes for joinvolvox.com URL (comment 2) - conversations: split into server page (+ metadata) + ConversationsClient (comment 3) - conversations: relabel channels count to 'Text Channels' (comment 3b) - members: split into server page (+ metadata) + MembersClient (comment 4) - moderation: split into server page (+ metadata) + ModerationClient (comment 5) - moderation: aria-label already present on clear-history button (comment 7) - tickets: split into server page (+ metadata) + TicketsClient (comment 8) - tickets: fetchStats extracted as reusable callback, called from handleRefresh (comment 9) - analytics-dashboard: gate empty-state fallbacks on !loading && analytics !== null (comment 10) - server-selector: break long DropdownMenuLabel class string (comment 12) - settings-feature-card: document className prop in JSDoc (comment 13)
- Extract client components from server pages (conversations, members, moderation, tickets) - Add shared PageHeader and EmptyState components - Improve sidebar nav with shared NavItem renderer - Fix single quote consistency and class readability - Gate analytics empty states on loading status - Remove nested dashboard-panel wrapper from shell - Document className prop on settings-feature-card Addresses all 13 review comments from PR VolvoxLLC#305.
75b52f4 to
187c569
Compare
|



Summary
This PR improves the dashboard UI/UX with a more structured layout.
What changed
Notes
This is a first pass dashboard UX overhaul focused on structure, consistency, and reducing clutter.
More polish and deeper visual work can follow in a later PR.
Validation