Skip to content

Conversation

@Innocent-Akim
Copy link
Contributor

@Innocent-Akim Innocent-Akim commented Dec 31, 2025

The Layout combobox in the header is now only visible in DEMO mode. For deployed sites (non-DEMO), layout switching remains available only through Settings.

  • Add isDemoMode() condition in NavigationControls
  • Add isDemoMode() condition in mobile header
  • Layout switcher remains accessible via Settings in all modes

Summary

Related Issues

Description

Changes Made

  • [ ]
  • [ ]
  • [ ]

Screenshots / Videos

Type of Change

  • 🐛 Bug fix (non-breaking change addressing an issue)
  • ✨ New feature (non-breaking change adding functionality)
  • 💥 Breaking change (fix or feature causing existing functionality to change)
  • 📝 Documentation update
  • 🔧 Configuration change
  • 🧪 Test addition or modification
  • 🛠️ CI/CD infrastructure improvement
  • ♻️ Refactoring (no functional changes)
  • 🎨 Code style/formatting update
  • 🚀 Performance improvement

Implementation Details

Testing Instructions

Deployment Notes

Checklist

  • I have performed a self-review of my code
  • I have added/updated tests that prove my fix is effective or my feature works
  • I have updated relevant documentation
  • My changes generate no new warnings or errors
  • I have verified my changes in multiple browsers/environments (if applicable)
  • New and existing unit tests pass locally with my changes
  • I have made corresponding changes to the documentation
  • My code follows the established code style of the project
  • I have commented my code, particularly in hard-to-understand areas

Additional Context


Summary by cubic

Show the Layout switcher in the header only in DEMO mode to reduce clutter in production. Non-DEMO sites can still change layout from Settings.

  • New Features
    • Gate header LayoutSwitcher with isDemoMode() in NavigationControls and the mobile header.

Written for commit 356b03c. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes
    • Restricted layout switcher visibility to display only when demo mode is enabled and layout switching is configured.

✏️ Tip: You can customize this high-level summary in your review settings.

The Layout combobox in the header is now only visible in DEMO mode.
For deployed sites (non-DEMO), layout switching remains available
only through Settings.

- Add isDemoMode() condition in NavigationControls
- Add isDemoMode() condition in mobile header
- Layout switcher remains accessible via Settings in all modes
@vercel
Copy link

vercel bot commented Dec 31, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
ever-works-website-template Ready Ready Preview, Comment Dec 31, 2025 7:46pm

@Innocent-Akim Innocent-Akim self-assigned this Dec 31, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 31, 2025

Walkthrough

Two header/navigation components were updated to add conditional demo mode checks. The LayoutSwitcher component now renders only when both headerSettings.layoutEnabled is true AND isDemoMode() returns true, previously requiring only the first condition.

Changes

Cohort / File(s) Summary
Header & Navigation Demo Mode Gating
components/header/index.tsx, components/navigation-controls.tsx
Added isDemoMode import from utilities. Introduced isDemo variable. Updated LayoutSwitcher conditional rendering to require both headerSettings.layoutEnabled && isDemo before display; previously only checked headerSettings.layoutEnabled.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

Possibly related PRs

Poem

🐰 A switcher once roamed wild and free,
Now whispers "demo" – "is this me?"
Conditional checks, a gentle gate,
Headers align, both locked in fate.
UI logic, neat and bright! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: conditionally showing the Layout switcher only in DEMO mode, which matches the core objective and all code changes across both modified files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/demo-only-layout-switcher-header

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.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Dec 31, 2025

Greptile Summary

This PR restricts the Layout switcher visibility in the header navigation to DEMO mode only. The implementation adds isDemoMode() checks in both NavigationControls (desktop) and the mobile header menu to conditionally render the LayoutSwitcher component based on the NEXT_PUBLIC_DEMO environment variable.

Key Changes:

  • Added isDemoMode() condition in NavigationControls component (line 15)
  • Added isDemoMode() condition in mobile header menu (line 376)
  • Layout switcher remains accessible via Settings in all deployment modes
  • Code formatting updated to single quotes in navigation-controls.tsx

The changes are straightforward and correctly implement the feature requirement. The layout switcher functionality is preserved and simply hidden from the header UI when not in DEMO mode.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are simple, focused, and implement a clear feature requirement. The implementation correctly uses an existing utility function (isDemoMode()) and applies it consistently across both desktop and mobile navigation. No logic errors, security issues, or breaking changes are present. The layout switcher functionality remains available through Settings, ensuring no features are lost.
  • No files require special attention

Important Files Changed

Filename Overview
components/navigation-controls.tsx Added isDemoMode() check to conditionally render Layout switcher in desktop navigation; formatting standardized to use single quotes
components/header/index.tsx Added isDemoMode() import and check to conditionally render Layout switcher in mobile menu navigation

Sequence Diagram

sequenceDiagram
    participant User
    participant Header
    participant NavigationControls
    participant isDemoMode
    participant LayoutSwitcher
    
    User->>Header: Load page
    Header->>isDemoMode: Check if DEMO mode
    isDemoMode-->>Header: Returns boolean (NEXT_PUBLIC_DEMO === "true")
    
    alt DEMO mode enabled
        Header->>NavigationControls: Render navigation controls
        NavigationControls->>isDemoMode: Check if DEMO mode
        isDemoMode-->>NavigationControls: true
        NavigationControls->>LayoutSwitcher: Render layout switcher (desktop)
        LayoutSwitcher-->>User: Display layout switcher button
        
        Header->>LayoutSwitcher: Render layout switcher (mobile menu)
        LayoutSwitcher-->>User: Display layout switcher in mobile menu
    else DEMO mode disabled
        Header->>NavigationControls: Render navigation controls
        NavigationControls->>isDemoMode: Check if DEMO mode
        isDemoMode-->>NavigationControls: false
        NavigationControls-->>User: Skip layout switcher rendering
        
        Header->>isDemoMode: Check if DEMO mode
        isDemoMode-->>Header: false
        Header-->>User: Skip layout switcher in mobile menu
    end
    
    Note over User,LayoutSwitcher: Layout switcher remains available in Settings for all modes
Loading

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 2 files

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: 0

🧹 Nitpick comments (2)
components/header/index.tsx (1)

32-32: Consider memoizing the demo mode check.

The implementation is correct, but since process.env.NEXT_PUBLIC_DEMO is a build-time constant in Next.js, calling isDemoMode() on every render is unnecessary. Consider wrapping it in useMemo to avoid redundant function calls.

🔎 Optional optimization using useMemo
 import { useMemo, useCallback, useState } from 'react';
 import { useSession } from 'next-auth/react';
 import { LayoutSwitcher } from '../layout-switcher';
 import { NavigationControls } from '../navigation-controls';
 import { ProfileButton } from './profile-button';
 import { MoreMenu } from './more-menu';
 import { SettingsButton } from '../settings-button';
 import { Container } from '../ui/container';
 import { SiteLogo } from '../shared/site-logo';
 import { useFeatureFlagsWithSimulation } from '@/hooks/use-feature-flags-with-simulation';
 import { useHasGlobalSurveys } from '@/hooks/use-has-global-surveys';
 import { useCategoriesEnabled } from '@/hooks/use-categories-enabled';
 import { useSurveysEnabled } from '@/hooks/use-surveys-enabled';
 import { useTagsEnabled } from '@/hooks/use-tags-enabled';
 import { useHeaderSettings } from '@/hooks/use-header-settings';
 import { useCategoriesExists } from '@/hooks/use-categories-exists';
 import { isDemoMode } from '@/lib/utils';

 export default function Header() {
 	const [isMenuOpen, setIsMenuOpen] = useState(false);
 	const { data: session } = useSession();
 	const { features } = useFeatureFlagsWithSimulation();
 	const { hasGlobalSurveys, isPending: surveysPending } = useHasGlobalSurveys();
 	const { categoriesEnabled } = useCategoriesEnabled();
 	const { surveysEnabled } = useSurveysEnabled();
 	const { tagsEnabled } = useTagsEnabled();
 	const { settings: headerSettings } = useHeaderSettings();
 	const { data: categoriesData, isLoading: categoriesLoading } = useCategoriesExists();
-	const isDemo = isDemoMode();
+	const isDemo = useMemo(() => isDemoMode(), []);

Alternatively, define it as a module-level constant outside the component:

+const IS_DEMO_MODE = isDemoMode();
+
 export default function Header() {
 	const [isMenuOpen, setIsMenuOpen] = useState(false);
 	const { data: session } = useSession();
 	const { features } = useFeatureFlagsWithSimulation();
 	const { hasGlobalSurveys, isPending: surveysPending } = useHasGlobalSurveys();
 	const { categoriesEnabled } = useCategoriesEnabled();
 	const { surveysEnabled } = useSurveysEnabled();
 	const { tagsEnabled } = useTagsEnabled();
 	const { settings: headerSettings } = useHeaderSettings();
 	const { data: categoriesData, isLoading: categoriesLoading } = useCategoriesExists();
-	const isDemo = isDemoMode();

Also applies to: 175-175

components/navigation-controls.tsx (1)

7-7: Consider memoizing the demo mode check (consistent with header component).

Similar to the header component, isDemoMode() is called on every render. Since process.env.NEXT_PUBLIC_DEMO is a build-time constant, consider using useMemo or a module-level constant for consistency and minor performance optimization.

🔎 Optional optimization using useMemo
 export function NavigationControls() {
 	const { settings } = useHeaderSettings();
-	const isDemo = isDemoMode();
+	const isDemo = useMemo(() => isDemoMode(), []);

 	return (

Or define as a module-level constant:

+const IS_DEMO_MODE = isDemoMode();
+
 export function NavigationControls() {
 	const { settings } = useHeaderSettings();
-	const isDemo = isDemoMode();
+	const isDemo = IS_DEMO_MODE;

Also applies to: 11-11

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3f4d9d8 and 356b03c.

📒 Files selected for processing (2)
  • components/header/index.tsx
  • components/navigation-controls.tsx
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Node.js >= 20.19.0

Files:

  • components/header/index.tsx
  • components/navigation-controls.tsx
components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

components/**/*.{ts,tsx}: UI components should be placed in the components/** directory
Keep React components mostly presentational and lean, avoiding complex business logic

Files:

  • components/header/index.tsx
  • components/navigation-controls.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Prefer TypeScript files over JavaScript

Run pnpm tsc --noEmit for TypeScript type-checking

Files:

  • components/header/index.tsx
  • components/navigation-controls.tsx
components/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Place UI and layout components in components/**

Files:

  • components/header/index.tsx
  • components/navigation-controls.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer TypeScript for all code

Files:

  • components/header/index.tsx
  • components/navigation-controls.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{js,jsx,ts,tsx}: Follow Prettier config with tabs, 4-space tabWidth, and 120-char printWidth
Prefer async/await over raw Promise chains in TypeScript/JavaScript code
Validate input with Zod where appropriate; follow existing schemas in lib/validations
Keep i18n-friendly: avoid hard-coded English strings in logic; use next-intl messages where relevant

Files:

  • components/header/index.tsx
  • components/navigation-controls.tsx
**/components/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/components/**/*.{jsx,tsx}: For forms, prefer react-hook-form + Zod; follow patterns in existing auth/profile forms
Place business logic in lib/services or lib/repositories, not in components; keep components mostly presentational and data-fetching

Files:

  • components/header/index.tsx
  • components/navigation-controls.tsx
🧠 Learnings (2)
📚 Learning: 2025-11-30T21:22:22.296Z
Learnt from: CR
Repo: ever-works/ever-works-website-template PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-30T21:22:22.296Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Keep i18n-friendly: avoid hard-coded English strings in logic; use next-intl messages where relevant

Applied to files:

  • components/navigation-controls.tsx
📚 Learning: 2025-11-24T18:34:28.233Z
Learnt from: CR
Repo: ever-works/ever-works-website-template PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T18:34:28.233Z
Learning: Applies to components/**/*.{ts,tsx} : Keep React components mostly presentational and lean, avoiding complex business logic

Applied to files:

  • components/navigation-controls.tsx
🧬 Code graph analysis (2)
components/header/index.tsx (1)
lib/utils.ts (1)
  • isDemoMode (13-15)
components/navigation-controls.tsx (3)
hooks/use-header-settings.ts (1)
  • useHeaderSettings (9-22)
lib/utils.ts (1)
  • isDemoMode (13-15)
components/layout-switcher.tsx (1)
  • LayoutSwitcher (98-364)
⏰ 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: cubic · AI code reviewer
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Lint and Build
🔇 Additional comments (2)
components/header/index.tsx (1)

376-382: LGTM: Conditional rendering correctly gates LayoutSwitcher in mobile menu.

The conditional logic properly restricts the LayoutSwitcher to demo mode while respecting the layoutEnabled setting. This aligns with the PR objective and maintains consistency with the desktop implementation in NavigationControls.

components/navigation-controls.tsx (1)

13-23: LGTM: Conditional rendering correctly implements demo-mode gating.

The refactored structure is clean and the conditional logic properly restricts the LayoutSwitcher to demo mode while respecting the layoutEnabled setting. The implementation is consistent with the changes in components/header/index.tsx and maintains appropriate responsive behavior.

@Innocent-Akim Innocent-Akim requested a review from evereq December 31, 2025 19:50
@evereq evereq merged commit 944f44e into develop Jan 1, 2026
11 checks passed
@evereq evereq deleted the feat/demo-only-layout-switcher-header branch January 1, 2026 10:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants