# All files / src/app PageLayout.tsx

100% Statements 94/94
50% Branches 1/2
100% Functions 1/1
100% Lines 94/94

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
    90
    91
    92
    93
    94
    951x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
    16x
     'use client';

    import { motion } from 'framer-motion';
    import { Code } from '@phosphor-icons/react';
    import { Navigation } from '@/components/layout/navigation/Navigation';
    import { NavigationSidebar } from '@/components/layout/navigation/NavigationSidebar';
    import { useNavigation } from '@/components/layout/navigation/useNavigation';
    import { BackendIndicator } from '@/components/layout/BackendIndicator';
    import { AppStatusAlerts } from '@/components/layout/AppStatusAlerts';
    import { ReactNode } from 'react';

    export function PageLayout({ children }: { children: ReactNode }) {
      const { menuOpen } = useNavigation();
      const safePad = '0.5rem';
      const safeAreaPadding = {
        paddingLeft: `max(${safePad}, env(safe-area-inset-left, 0px))`,
        paddingRight: `max(${safePad}, env(safe-area-inset-right, 0px))`,
      };

      return (
        <div className="min-h-screen bg-background" data-testid="page-layout">
          <div className="grid-pattern" aria-hidden="true" />

          <NavigationSidebar />

          <motion.div
            initial={false}
            animate={{ marginLeft: menuOpen ? 320 : 0 }}
            transition={{ type: 'spring', damping: 30, stiffness: 300 }}
            className="relative z-10 flex flex-col min-h-screen"
          >
            <header className="border-b border-border bg-background/95 backdrop-blur-md sticky top-0 z-20 overflow-hidden" data-testid="page-header">
              <div
                className="container mx-auto px-2 py-3 sm:px-6 sm:py-6 w-full min-w-0"
                style={{
                  ...safeAreaPadding,
                  paddingTop: `max(${safePad}, env(safe-area-inset-top, 0px))`,
                }}
              >
                <div className="flex flex-wrap items-center justify-between gap-2 sm:flex-nowrap min-w-0">
                  <motion.div
                    initial={{ opacity: 0 }}
                    animate={{ opacity: 1 }}
                    transition={{ duration: 0.35 }}
                    className="logo-container"
                  >
                    <Navigation />
                    <div className="logo-icon-box">
                      <Code weight="bold" />
                    </div>
                    <span className="logo-text" aria-label="CodeSnippet" data-testid="logo-text">
                      CodeSnippet
                    </span>
                  </motion.div>
                  <motion.div
                    initial={{ opacity: 0 }}
                    animate={{ opacity: 1 }}
                    transition={{ duration: 0.35, delay: 0.05 }}
                  >
                    <BackendIndicator />
                  </motion.div>
                </div>
              </div>
            </header>

            <main
              className="container mx-auto px-3 py-4 sm:px-6 sm:py-8 flex-1"
              style={safeAreaPadding}
              data-testid="main-content"
            >
              <div className="mb-4">
                <AppStatusAlerts />
              </div>
              {children}
            </main>

            <footer className="border-t border-border">
              <div
                className="container mx-auto px-3 py-4 sm:px-6 sm:py-8"
                style={{
                  ...safeAreaPadding,
                  paddingBottom: `max(1rem, env(safe-area-inset-bottom, 0px))`,
                }}
              >
                <div className="text-center text-xs sm:text-sm text-muted-foreground">
                  <p>Save, organize, and share your code snippets with beautiful syntax highlighting and live execution</p>
                  <p className="mt-2 text-xs">Supports React preview and Python execution via Pyodide</p>
                </div>
              </div>
            </footer>
          </motion.div>
        </div>
      );
    }