Skip to content

Update dashboard tab titles to use shared suffix#262

Merged
BillChirico merged 2 commits intomainfrom
bill/update-dashboard-tab-titles
Mar 8, 2026
Merged

Update dashboard tab titles to use shared suffix#262
BillChirico merged 2 commits intomainfrom
bill/update-dashboard-tab-titles

Conversation

@BillChirico
Copy link
Collaborator

Summary:

  • Centralize dashboard document-title logic so route changes produce consistent titles like “Members - Volvox.Bot - AI Powered Discord Bot”.
  • Wire the shared helper into metadata definitions and a client-side DashboardTitleSync hook so both SSR entry points and SPA tab switches stay in sync.
  • Cover the new behavior with targeted unit tests for the title helpers and integration-level sync component.

Key Changes:

  • Added web/src/lib/page-titles.ts plus helper metadata wrappers to encapsulate the canonical app title suffix and per-route mappings.
  • Updated dashboard layout to mount DashboardTitleSync, ensuring document.title follows the new helpers on client navigation, and adjusted metadata for dashboard entry pages.
  • Expanded test surface with web/tests/lib/page-titles.test.ts and web/tests/components/layout/dashboard-title-sync.test.tsx to guard formatting and runtime sync.

Impact:

  • Dashboard UI now consistently updates the browser title during navigation; no downstream services are affected.

Testing:

  • Not run (not requested)
  1. Structure: Use the following format:
    • Title: A concise title following Conventional Commits.
    • Summary: A high-level overview (2-3 sentences) of the purpose of these changes.
    • Key Changes: A bulleted list of the most important logic or architectural changes.
    • Impact: Briefly mention if this affects any downstream services or UI components.
    • Testing: List the steps taken to verify the changes (e.g., Unit tests, manual verification).

  2. Context: If I provide a git diff, focus on the logic changes. Ignore noise like whitespace changes, dependency lockfile updates, or minor linting fixes unless they are the primary focus.

  3. Tone: Professional, objective, and technical. Avoid flowery language

  4. Emoji Usage & Professionalism:
    • Minimalist Approach: Use emojis only for functional status indicators, never for decoration.
    • Forbidden: No emojis in PR titles, commit messages, or headers. No "decorative" emojis (e.g., 🚀, ✨, 🤖, 💻).
    • Allowed: Only use emojis to denote status in lists or tables, specifically:
    • ✅ for passed tests/requirements.
    • ❌ for failures or bugs.
    ⚠️ for warnings or technical debt.
    • 💡 for optional suggestions/refactors.
    • Text-First: If an emoji is used, it must be followed by clear text. Never use an emoji to replace a word.

Copilot AI review requested due to automatic review settings March 7, 2026 23:48
@github-project-automation github-project-automation bot moved this to Backlog in Volvox.Bot Mar 7, 2026
@railway-app railway-app bot temporarily deployed to volvox-bot / volvox-bot-pr-262 March 7, 2026 23:48 Destroyed
@railway-app
Copy link

railway-app bot commented Mar 7, 2026

🚅 Deployed to the volvox-bot-pr-262 environment in volvox-bot

Service Status Web Updated (UTC)
docs ✅ Success (View Logs) Web Mar 8, 2026 at 12:43 am
bot 🚨 Crashed (View Logs) Web Mar 8, 2026 at 12:42 am
web ✅ Success (View Logs) Mar 8, 2026 at 12:41 am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 7, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e23ae182-19ef-4da7-8b52-05f203e06850

📥 Commits

Reviewing files that changed from the base of the PR and between 71d758f and 5a4c733.

📒 Files selected for processing (1)
  • web/tests/components/layout/dashboard-shell.test.tsx
📜 Recent 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). (2)
  • GitHub Check: Greptile Review
  • GitHub Check: claude-review
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,mjs,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,mjs,jsx,ts,tsx}: Use single quotes for strings in code, double quotes only allowed in JSON files
Always end statements with semicolons
Use 2-space indentation, enforced by Biome

Files:

  • web/tests/components/layout/dashboard-shell.test.tsx
web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Next.js 16 web dashboard uses App Router with Discord OAuth2 authentication, dark/light theme support, and mobile-responsive design

Files:

  • web/tests/components/layout/dashboard-shell.test.tsx
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-05T18:07:15.752Z
Learning: Applies to web/**/*.{ts,tsx} : Next.js 16 web dashboard uses App Router with Discord OAuth2 authentication, dark/light theme support, and mobile-responsive design
📚 Learning: 2026-03-07T15:34:56.495Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-07T15:34:56.495Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.test.{js,jsx,ts,tsx} : Config editor tests must cover manual-save workspace behavior (not autosave assumptions), category switching, search functionality, and dirty badges

Applied to files:

  • web/tests/components/layout/dashboard-shell.test.tsx
📚 Learning: 2026-03-07T15:34:56.495Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-07T15:34:56.495Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{js,jsx,ts,tsx} : Refactor config feature presentation to use reusable `SettingsFeatureCard` pattern with structure: header + master toggle + Basic/Advanced blocks

Applied to files:

  • web/tests/components/layout/dashboard-shell.test.tsx
📚 Learning: 2026-03-05T18:07:15.752Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-05T18:07:15.752Z
Learning: Applies to **/*.{js,mjs,jsx,ts,tsx} : Use single quotes for strings in code, double quotes only allowed in JSON files

Applied to files:

  • web/tests/components/layout/dashboard-shell.test.tsx
🔇 Additional comments (2)
web/tests/components/layout/dashboard-shell.test.tsx (2)

9-11: JSX attribute still uses double quotes.

The past review requested changing data-testid="dashboard-title-sync" to single quotes per coding guidelines. The module path was updated to single quotes, but the JSX attribute remains with double quotes.

🔧 Proposed fix
 vi.mock('@/components/layout/dashboard-title-sync', () => ({
-  DashboardTitleSync: () => <div data-testid="dashboard-title-sync" />,
+  DashboardTitleSync: () => <div data-testid='dashboard-title-sync' />,
 }));

21-34: Mock and assertion correctly verify DashboardTitleSync integration.

The mock appropriately returns a DOM element with a test ID (rather than null like the real component) to enable verification via getByTestId. The assertion at line 31 correctly validates that DashboardShell renders the DashboardTitleSync component as shown in the relevant context snippet from dashboard-shell.tsx.


📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Enhanced dashboard page titles with contextual names shown in browser tabs.
    • Dynamic document title syncing so the tab updates as you navigate dashboard sections.
    • Consistent metadata generation across dashboard pages and a root title template for unified titles.
  • Documentation

    • Added Session Notes documenting the dashboard title synchronization changes.
  • Tests

    • New and updated tests covering title utilities and the title-sync behavior.

Walkthrough

This change centralizes dashboard page title handling via a new page-titles utility, adds server-rendered metadata for dashboard routes, and introduces a client-side DashboardTitleSync component to keep the browser document title in sync with the current dashboard route. Layout and dashboard pages are updated to use the shared helpers; tests and docs added.

Changes

Cohort / File(s) Summary
Page Title Management System
web/src/lib/page-titles.ts, web/src/app/dashboard/page.tsx, web/src/app/dashboard/config/page.tsx, web/src/app/dashboard/performance/page.tsx, web/tests/lib/page-titles.test.ts
Adds web/src/lib/page-titles.ts exporting APP_TITLE, title formatting and route→title mapping helpers, and createPageMetadata(). Dashboard pages now export metadata via the helper. Tests added for utilities and metadata creation.
Dashboard Title Synchronization
web/src/components/layout/dashboard-title-sync.tsx, web/tests/components/layout/dashboard-title-sync.test.tsx
New client component DashboardTitleSync uses Next.js usePathname to update document.title from route-derived titles. Tests simulate pathname changes and assert correct title formatting and fallback behavior.
Layout Components and Root Configuration
web/src/app/layout.tsx, web/src/components/layout/dashboard-shell.tsx, web/tests/components/layout/dashboard-shell.test.tsx
Root metadata title changed to use APP_TITLE and a title template. DashboardTitleSync is mounted in the dashboard shell above the Header. Shell tests mock and assert presence of the new component.
Documentation
CLAUDE.md
Adds Session Notes describing the dashboard title synchronization design, helpers, server-rendered metadata usage, and test coverage locations.

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main objective: centralizing and synchronizing dashboard tab titles with a shared suffix across server and client rendering.
Description check ✅ Passed The description is directly related to the changeset, providing a structured summary of the changes, key modifications, impact, and testing approach that aligns with the actual file modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bill/update-dashboard-tab-titles
  • 🛠️ Publish Changes: Commit on current branch
  • 🛠️ Publish Changes: Create PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link

claude bot commented Mar 7, 2026

Claude finished @BillChirico's task in 3m 58s —— View job


Code Review PR #262

  • Gather context
  • Read changed files
  • Analyze for issues
  • Post review findings

Issues

1. AGENTS.md not updated for new files and patterns

File: AGENTS.md

Two new files introduce a pattern that future developers need to be aware of when adding dashboard routes:

  • web/src/lib/page-titles.ts — route-to-title matcher table; every new route requires a new entry here
  • web/src/components/layout/dashboard-title-sync.tsx — client component mounted in the shell to drive document.title

Per project rules, AGENTS.md must be updated when new files or patterns are added. The "Adding a New Feature" section (step 7) and the Web Dashboard section should document that new routes require a matcher entry in dashboardTitleMatchers.

Fix this →


2. Leaf-route matchers missing trailing path boundary

File: web/src/lib/page-titles.ts:28-70

The detail-route matchers correctly use a trailing slash to bound the match:

matches: (pathname) => pathname.startsWith('/dashboard/members/'),  // correct

The leaf-route (section) matchers do not:

matches: (pathname) => pathname.startsWith('/dashboard/ai'),         // line 36
matches: (pathname) => pathname.startsWith('/dashboard/moderation'), // line 28
matches: (pathname) => pathname.startsWith('/dashboard/logs'),       // line 64
matches: (pathname) => pathname.startsWith('/dashboard/settings'),   // line 68
matches: (pathname) => pathname.startsWith('/dashboard/temp-roles'), // line 32
matches: (pathname) => pathname.startsWith('/dashboard/audit-log'),  // line 56
matches: (pathname) => pathname.startsWith('/dashboard/performance'),// line 60

/dashboard/ai matches any future /dashboard/airline or /dashboard/ai-studio route, producing a silent wrong title. These matchers should either use pathname === '/dashboard/ai' for exact matches or pathname.startsWith('/dashboard/ai/') to bound to the subtree.

Fix this →


3. DashboardTitleSync unconditionally overwrites page-level metadata titles

File: web/src/components/layout/dashboard-title-sync.tsx:10-12

useEffect(() => {
  document.title = getDashboardDocumentTitle(pathname);
}, [pathname]);

This fires on every navigation and overwrites whatever title Next.js already applied from a page's metadata export. For the three current pages the values are identical so there is no visible conflict. However any future sub-route that exports a more specific metadata.title (e.g. /dashboard/config/advanced → "Advanced Config - …") would have its title silently replaced by the broader prefix match (Bot Config - …). The useEffect should guard against overwriting when Next.js has already set a more specific title, or the client-side title sync should be abandoned entirely in favour of relying solely on metadata exports per page.

Fix this →


| Branch

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coveralls
Copy link

coveralls commented Mar 7, 2026

Coverage Status

coverage: 87.566%. remained the same
when pulling 5a4c733 on bill/update-dashboard-tab-titles
into a6e76d0 on main.

@greptile-apps
Copy link

greptile-apps bot commented Mar 7, 2026

Greptile Summary

This PR centralizes dashboard browser-title logic behind a shared APP_TITLE constant and a dashboardTitleMatchers lookup table in web/src/lib/page-titles.ts. SSR entry points (/dashboard, /dashboard/config, /dashboard/performance) gain explicit metadata exports that compose with the new root-layout title template, while client-side navigation is handled by a new DashboardTitleSync hook mounted in DashboardShell that imperative-sets document.title on each pathname change.

Key changes:

  • web/src/lib/page-titles.ts: new module exporting APP_TITLE, formatDocumentTitle, getDashboardPageTitle, getDashboardDocumentTitle, and createPageMetadata
  • web/src/app/layout.tsx: root metadata switches from a static string to a Next.js title template object, enabling per-route suffix composition
  • web/src/components/layout/dashboard-title-sync.tsx: new 'use client' component that calls getDashboardDocumentTitle(pathname) inside a useEffect to keep the tab title in sync during SPA navigation
  • Three dashboard page files (/dashboard, /dashboard/config, /dashboard/performance) add or update their metadata exports using createPageMetadata
  • New test files cover page-titles.ts helpers and the DashboardTitleSync component

⚠️ The dashboardTitleMatchers section-level entries use startsWith without a trailing-slash boundary (e.g. startsWith('/dashboard/logs') would match a future /dashboard/logout route). The detail-page matchers at the top already use the safer startsWith('/dashboard/members/') pattern — the section matchers should follow suit.

💡 The normalizePathname trailing-slash stripping logic has no direct test coverage; adding a few cases for paths like /dashboard/ and /dashboard/members/ would guard that branch.

Confidence Score: 4/5

  • Safe to merge — all issues are non-breaking style concerns with no impact on existing functionality.
  • The approach is architecturally sound: SSR and client navigation produce consistent titles, the 'use client' boundary is correctly placed, and the title template in the root layout composes properly with per-route metadata. The two concerns (open-ended startsWith matchers and missing trailing-slash test coverage) are forward-looking and do not cause any current breakage. Score is 4 rather than 5 only because the matcher design could silently mismatch if new routes with similar prefixes are added.
  • web/src/lib/page-titles.ts — the section-level matchers should add a path-segment boundary check (trailing slash or exact match) to prevent future false positives.

Important Files Changed

Filename Overview
web/src/lib/page-titles.ts New helper module for dashboard title logic. Core logic is sound but section-level startsWith matchers lack a path-segment boundary (no trailing slash), making them susceptible to false positives as the route table grows.
web/src/components/layout/dashboard-title-sync.tsx Minimal client component that syncs document.title on pathname change via useEffect. Correct implementation of the 'use client' boundary and dependency array.
web/src/app/layout.tsx Root layout correctly switches from a static title string to a Next.js title template object, enabling per-route suffix composition for SSR entry points.
web/tests/lib/page-titles.test.ts Happy-path coverage is solid, but the normalizePathname trailing-slash branch is never exercised, and null/undefined edge cases for formatDocumentTitle are absent.
web/tests/components/layout/dashboard-title-sync.test.tsx Good coverage for initial mount, route change, and unknown-route fallback. The module-level mutable mockPathname pattern is a reasonable workaround for mocking usePathname in Vitest.
web/src/components/layout/dashboard-shell.tsx Correctly mounts DashboardTitleSync as the first child; importing a client component into a server component is valid in the Next.js App Router model.
web/src/app/dashboard/config/page.tsx Switches to createPageMetadata helper; relies on root layout template for the full suffix, which is consistent with the new approach.
web/src/app/dashboard/page.tsx Adds previously absent metadata export for the dashboard overview route via createPageMetadata.
web/src/app/dashboard/performance/page.tsx Adds previously absent metadata export for the performance route via createPageMetadata.
web/tests/components/layout/dashboard-shell.test.tsx Adds a mock for DashboardTitleSync and verifies it renders. Also normalizes quotes to single quotes throughout the file.

Sequence Diagram

sequenceDiagram
    participant Browser
    participant Next.js SSR
    participant RootLayout
    participant DashboardShell
    participant DashboardTitleSync
    participant page-titles.ts

    Note over Browser,page-titles.ts: Direct page load (SSR path)
    Browser->>Next.js SSR: GET /dashboard/members
    Next.js SSR->>RootLayout: Apply title template "%s - Volvox.Bot - AI Powered Discord Bot"
    RootLayout->>Next.js SSR: metadata.title = { default: APP_TITLE, template }
    Next.js SSR->>Browser: <title>Members - Volvox.Bot - AI Powered Discord Bot</title>

    Note over Browser,page-titles.ts: Client-side navigation (SPA path)
    Browser->>DashboardShell: Route change to /dashboard/config
    DashboardShell->>DashboardTitleSync: renders (pathname changes)
    DashboardTitleSync->>page-titles.ts: getDashboardDocumentTitle('/dashboard/config')
    page-titles.ts->>page-titles.ts: normalizePathname → match dashboardTitleMatchers
    page-titles.ts-->>DashboardTitleSync: "Bot Config - Volvox.Bot - AI Powered Discord Bot"
    DashboardTitleSync->>Browser: document.title = "Bot Config - Volvox.Bot - AI Powered Discord Bot"
Loading

Last reviewed commit: 5a4c733

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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/tests/components/layout/dashboard-shell.test.tsx`:
- Around line 9-11: The test mock uses double-quoted string literals; change
them to single quotes to follow the project's quoting style. Update the vi.mock
call for '@/components/layout/dashboard-title-sync', the exported property name
'DashboardTitleSync', and the JSX data-testid value 'dashboard-title-sync' to
use single quotes (locate the vi.mock invocation and the DashboardTitleSync
stub).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 963a9183-248d-463b-97bd-67a7162f14c2

📥 Commits

Reviewing files that changed from the base of the PR and between a6e76d0 and 71d758f.

📒 Files selected for processing (11)
  • CLAUDE.md
  • web/src/app/dashboard/config/page.tsx
  • web/src/app/dashboard/page.tsx
  • web/src/app/dashboard/performance/page.tsx
  • web/src/app/layout.tsx
  • web/src/components/layout/dashboard-shell.tsx
  • web/src/components/layout/dashboard-title-sync.tsx
  • web/src/lib/page-titles.ts
  • web/tests/components/layout/dashboard-shell.test.tsx
  • web/tests/components/layout/dashboard-title-sync.test.tsx
  • web/tests/lib/page-titles.test.ts
📜 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). (3)
  • GitHub Check: Greptile Review
  • GitHub Check: claude-review
  • GitHub Check: Docker Build Validation
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,mjs,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,mjs,jsx,ts,tsx}: Use single quotes for strings in code, double quotes only allowed in JSON files
Always end statements with semicolons
Use 2-space indentation, enforced by Biome

Files:

  • web/src/app/layout.tsx
  • web/src/components/layout/dashboard-title-sync.tsx
  • web/src/app/dashboard/page.tsx
  • web/tests/components/layout/dashboard-title-sync.test.tsx
  • web/tests/components/layout/dashboard-shell.test.tsx
  • web/src/app/dashboard/performance/page.tsx
  • web/tests/lib/page-titles.test.ts
  • web/src/lib/page-titles.ts
  • web/src/components/layout/dashboard-shell.tsx
  • web/src/app/dashboard/config/page.tsx
web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Next.js 16 web dashboard uses App Router with Discord OAuth2 authentication, dark/light theme support, and mobile-responsive design

Files:

  • web/src/app/layout.tsx
  • web/src/components/layout/dashboard-title-sync.tsx
  • web/src/app/dashboard/page.tsx
  • web/tests/components/layout/dashboard-title-sync.test.tsx
  • web/tests/components/layout/dashboard-shell.test.tsx
  • web/src/app/dashboard/performance/page.tsx
  • web/tests/lib/page-titles.test.ts
  • web/src/lib/page-titles.ts
  • web/src/components/layout/dashboard-shell.tsx
  • web/src/app/dashboard/config/page.tsx
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-05T18:07:15.752Z
Learning: Applies to web/**/*.{ts,tsx} : Next.js 16 web dashboard uses App Router with Discord OAuth2 authentication, dark/light theme support, and mobile-responsive design
📚 Learning: 2026-03-05T18:07:15.752Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-05T18:07:15.752Z
Learning: Applies to web/**/*.{ts,tsx} : Next.js 16 web dashboard uses App Router with Discord OAuth2 authentication, dark/light theme support, and mobile-responsive design

Applied to files:

  • web/src/app/layout.tsx
  • web/src/components/layout/dashboard-title-sync.tsx
  • web/src/app/dashboard/page.tsx
  • web/tests/components/layout/dashboard-title-sync.test.tsx
  • web/src/app/dashboard/performance/page.tsx
  • CLAUDE.md
  • web/src/lib/page-titles.ts
📚 Learning: 2026-03-07T15:34:56.495Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-07T15:34:56.495Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{js,jsx,ts,tsx} : Config editor must implement metadata-driven config search with cross-category quick jump, focus/scroll targeting, and auto-open advanced sections when search hits advanced controls

Applied to files:

  • web/src/app/dashboard/page.tsx
  • CLAUDE.md
  • web/src/app/dashboard/config/page.tsx
📚 Learning: 2026-03-07T15:34:56.495Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-07T15:34:56.495Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{js,jsx,ts,tsx} : Web dashboard config editor must use category workspace navigation with categories: `AI & Automation`, `Onboarding & Growth`, `Moderation & Safety`, `Community Tools`, `Support & Integrations` located in `web/src/components/dashboard/config-workspace/`

Applied to files:

  • web/src/app/dashboard/page.tsx
  • web/tests/components/layout/dashboard-title-sync.test.tsx
  • CLAUDE.md
  • web/src/app/dashboard/config/page.tsx
📚 Learning: 2026-03-07T15:34:56.495Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-07T15:34:56.495Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.test.{js,jsx,ts,tsx} : Config editor tests must cover manual-save workspace behavior (not autosave assumptions), category switching, search functionality, and dirty badges

Applied to files:

  • web/tests/components/layout/dashboard-title-sync.test.tsx
  • web/tests/components/layout/dashboard-shell.test.tsx
  • CLAUDE.md
  • web/tests/lib/page-titles.test.ts
📚 Learning: 2026-03-05T18:07:15.752Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-05T18:07:15.752Z
Learning: Before starting any coding session, read `CLAUDE.md` for coding standards and persona; after infrastructure work, update `CLAUDE.md` with technical decisions and session notes

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-07T15:34:56.495Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-07T15:34:56.495Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{js,jsx,ts,tsx} : Refactor config feature presentation to use reusable `SettingsFeatureCard` pattern with structure: header + master toggle + Basic/Advanced blocks

Applied to files:

  • CLAUDE.md
  • web/src/components/layout/dashboard-shell.tsx
  • web/src/app/dashboard/config/page.tsx
📚 Learning: 2026-03-07T15:34:56.495Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-07T15:34:56.495Z
Learning: Applies to web/src/components/dashboard/config-workspace/**/*.{js,jsx,ts,tsx} : Config editor save contract must maintain: global save/discard, diff-modal confirmation, per-section PATCH batching, and partial-failure behavior

Applied to files:

  • CLAUDE.md
  • web/src/app/dashboard/config/page.tsx
🔇 Additional comments (15)
CLAUDE.md (1)

27-34: LGTM!

The session notes accurately document the dashboard title synchronization changes, including the shared title helpers, client-side sync component, server metadata additions, and test coverage locations. This provides valuable context for future maintenance.

web/src/components/layout/dashboard-title-sync.tsx (1)

1-15: LGTM!

Clean implementation of a side-effect-only component. The useEffect correctly depends on pathname, ensuring document.title updates on every route change. Returning null is the appropriate pattern for components that only produce side effects.

web/tests/components/layout/dashboard-shell.test.tsx (1)

30-31: LGTM on the assertion logic.

The test correctly verifies that DashboardTitleSync is rendered as part of the DashboardShell composition.

web/src/components/layout/dashboard-shell.tsx (2)

1-1: LGTM!

Import is correctly placed and uses relative path for the sibling component.


15-19: LGTM!

Rendering DashboardTitleSync as the first child is appropriate since it returns null and only produces side effects. Server components can safely render client components as children in Next.js App Router.

web/tests/lib/page-titles.test.ts (1)

1-38: LGTM!

Comprehensive test coverage for the page title utilities:

  • Tests the title formatting with suffix.
  • Covers known routes, dynamic routes with IDs (/dashboard/members/123), and unknown route fallback.
  • Validates metadata creation with optional descriptions.

The test cases align well with the implementation patterns documented in the context snippets.

web/src/app/layout.tsx (2)

4-4: LGTM!

Centralizing APP_TITLE import ensures consistency across metadata and client-side title updates.


17-21: LGTM!

The title template pattern is correctly configured for Next.js App Router metadata. The %s placeholder will be replaced with child page titles, ensuring consistent formatting like "Performance - Volvox.Bot - AI Powered Discord Bot" across all pages.

web/src/app/dashboard/performance/page.tsx (1)

1-8: LGTM!

Correctly uses createPageMetadata helper for consistent metadata generation. The title "Performance" will be combined with the root layout template, and the description provides useful SEO context.

web/tests/components/layout/dashboard-title-sync.test.tsx (1)

1-53: LGTM!

Well-structured test suite covering the key behaviors:

  • Setting title from current route on mount.
  • Updating title when pathname changes (via rerender with updated mock).
  • Falling back to APP_TITLE for unknown routes.

The mock pattern using a module-level mockPathname variable that's reset in beforeEach provides good test isolation while allowing route change simulation through mutation + rerender.

web/src/app/dashboard/config/page.tsx (1)

3-8: LGTM!

The metadata is correctly centralized using createPageMetadata. The title 'Bot Config' aligns with the route matcher defined in page-titles.ts, ensuring consistent title handling across SSR and client-side navigation.

web/src/app/dashboard/page.tsx (1)

1-9: LGTM!

The metadata is correctly centralized using createPageMetadata. The 'Overview' title properly corresponds to the /dashboard route matcher, maintaining consistency with the title synchronization system.

web/src/lib/page-titles.ts (3)

10-71: LGTM!

The matcher array is correctly ordered with specific routes (e.g., /dashboard/members/ for detail pages) listed before their parent routes (e.g., /dashboard/members for the list view). Combined with normalizePathname stripping trailing slashes, this ensures accurate title resolution.


73-81: LGTM!

The normalizePathname function correctly handles edge cases: null/undefined inputs return null, trailing slashes are stripped (except for root '/'), and the fallback ensures a valid path is always returned when input is truthy.


83-110: LGTM!

The utility functions are well-composed with clear single responsibilities. createPageMetadata produces minimal metadata objects, and the title formatting functions properly chain together for consistent document title generation.

@github-project-automation github-project-automation bot moved this from Backlog to In Review in Volvox.Bot Mar 7, 2026
@railway-app railway-app bot temporarily deployed to volvox-bot / volvox-bot-pr-262 March 8, 2026 00:41 Destroyed
@BillChirico BillChirico merged commit febddc7 into main Mar 8, 2026
16 of 21 checks passed
@BillChirico BillChirico deleted the bill/update-dashboard-tab-titles branch March 8, 2026 02:15
@github-project-automation github-project-automation bot moved this from In Review to Done in Volvox.Bot Mar 8, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

🧹 Preview Environment Cleaned Up

The Railway preview environment for this PR has been removed.

Environment: pr-262

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants