All files / src/app/layout AppMain.tsx

95.5% Statements 85/89
66.66% Branches 4/6
100% Functions 3/3
95.5% Lines 85/89

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 901x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 9x 9x 9x 9x 9x 9x 9x     9x     9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 9x 9x 9x 9x 9x 9x 9x 9x 9x  
/**
 * @file AppMain.tsx
 * @module app/layout/AppMain
 *
 * @summary
 * Main content area component rendering page content with demo notice banner.
 * Extracted from AppShell to isolate main content layout and demo mode messaging.
 *
 * @enterprise
 * - Responsive flexbox layout optimized for content scrolling
 * - Demo mode non-blocking information banner
 * - Suspense fallback for lazy-loaded page components
 * - Full TypeDoc coverage for content area and demo mode integration
 */
 
import { Outlet, useLocation } from 'react-router-dom';
import {
  Box,
  Toolbar,
  Alert,
} from '@mui/material';
import { useTranslation } from 'react-i18next';
 
interface AppMainProps {
  /** Whether user is on demo account */
  isDemo: boolean;
}
 
/**
 * Main content area component.
 *
 * Renders the primary application content with optional demo mode banner.
 *
 * @param props - Component props
 * @returns JSX element rendering main content area
 */
export default function AppMain({ isDemo }: AppMainProps) {
  const { t } = useTranslation(['auth']);
  const location = useLocation();
 
  // Render-phase log to confirm this component is rendering
  try {
    if (localStorage.getItem('debugRouting') === '1') {
      console.debug('[AppMain] render', location.pathname + location.search);
    }
  } catch {
    // ignore
  }
 
  return (
    <Box
      component="main"
      sx={{
        flex: 1,
        minHeight: 'auto',
        px: 0,
        pt: 0,
        pb: 0.5,
        overflowY: 'auto',
        display: 'flex',
        flexDirection: 'column',
        gap: 0,
      }}
    >
      {/* Spacer to account for fixed AppBar height */}
      <Toolbar />
 
      {/* Demo Mode Notice Banner (non-blocking, informational) */}
      {isDemo && (
        <Alert
          severity="info"
          icon={false}
          sx={{
            mb: 0.5,
            borderLeft: (theme) => `4px solid ${theme.palette.info.main}`,
            bgcolor: (theme) => theme.palette.info.light,
          }}
        >
          {t('auth:demoNotice', 'You are browsing in demo mode. Changes are disabled.')}
        </Alert>
      )}
 
      {/* Page Content Area */}
      <Box sx={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
        <Outlet />
      </Box>
    </Box>
  );
}