# Case Context Management - CareBridge ## Overview CareBridge is a multi-case management system where users can manage multiple care recipients. The `caseId` is the primary context identifier that must be preserved across ALL navigation. ## Critical Rule **NEVER navigate to a page without preserving the current `caseId`.** ## How Case Context Works ### URL Structure All protected routes must support the `caseId` query parameter: ``` /dashboard?caseId=uuid-here /calendar?caseId=uuid-here /subscriptions?caseId=uuid-here /case-settings?caseId=uuid-here ``` ### Reading Case Context Use the helper function to safely extract `caseId`: ```typescript // In Server Components (pages) import { getCaseIdFromParams } from '@/lib/case-context' type SearchParams = Promise<{ caseId?: string }> export default async function MyPage({ searchParams, }: { searchParams: SearchParams }) { const params = await searchParams // Next.js 15 requirement const caseId = getCaseIdFromParams(params) if (!caseId) { // Show "No case selected" empty state return } // Use caseId for data fetching const data = await getData(caseId) // ... } ``` ```typescript // In Client Components 'use client' import { useSearchParams } from 'next/navigation' import { useState, useEffect } from 'react' export function MyClientComponent() { const searchParams = useSearchParams() const [caseId, setCaseId] = useState(null) // Prevent hydration mismatch useEffect(() => { setCaseId(searchParams.get('caseId')) }, [searchParams]) if (!caseId) return null // Use caseId } ``` ### Preserving Case Context in Navigation **All navigation links MUST preserve caseId:** ```typescript // ✅ CORRECT - Preserves caseId import { useSearchParams } from 'next/navigation' import Link from 'next/link' const searchParams = useSearchParams() const caseId = searchParams.get('caseId') Dashboard // ❌ WRONG - Loses case context Dashboard ``` ### Navigation Component Pattern See `src/components/nav-main.tsx` for the correct pattern: ```typescript 'use client' export function NavMain({ items }) { const searchParams = useSearchParams() const [caseId, setCaseId] = useState(null) useEffect(() => { setCaseId(searchParams.get('caseId')) }, [searchParams]) return items.map((item) => { // Preserve caseId in ALL navigation const url = caseId ? `${item.url}?caseId=${caseId}` : item.url return {item.title} }) } ``` ## Case Switching Case switching happens in the sidebar via `CaseSwitcher` component. When a user selects a different case: 1. The URL updates with the new `caseId` 2. All navigation automatically preserves the new `caseId` 3. The page re-renders with new case data ## Empty States When `caseId` is missing, show a helpful empty state: ```typescript if (!caseId) { return ( ) } ``` ## Common Mistakes ### ❌ Mistake #1: Forgetting to preserve caseId in links ```typescript // WRONG - Will break case context Subscribe ``` ### ❌ Mistake #2: Not handling Next.js 15 async params ```typescript // WRONG - In Next.js 15, params are async export default function Page({ searchParams }) { const caseId = searchParams.caseId // ERROR! } // CORRECT export default async function Page({ searchParams }) { const params = await searchParams const caseId = getCaseIdFromParams(params) } ``` ### ❌ Mistake #3: Using router.push without caseId ```typescript // WRONG router.push('/dashboard') // CORRECT const caseId = searchParams.get('caseId') router.push(caseId ? `/dashboard?caseId=${caseId}` : '/dashboard') ``` ## Testing Case Context When testing a feature: 1. Navigate to a page with a caseId 2. Click any link/button that navigates 3. Verify the URL still has `?caseId=...` 4. Repeat for all navigation paths If caseId is lost, you'll see the "No Case Selected" empty state - this indicates broken context preservation.