# Code coverage report for src/components/features/snippet-viewer/SnippetViewer.tsx

# All files / src/components/features/snippet-viewer SnippetViewer.tsx

96.1% Statements 74/77
100% Branches 9/9
50% Functions 2/4
96.1% Lines 74/77

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
    781x
    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
    45x
    45x
    45x
    45x
    44x
    44x
    2x
    2x
    2x
    2x
    44x
    44x

    44x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
    45x
     "use client"

    import {
      Dialog,
      DialogContent,
      DialogHeader,
    } from '@/components/ui/dialog'
    import { Snippet } from '@/lib/types'
    import { useState } from 'react'
    import dynamic from 'next/dynamic'
    import { appConfig } from '@/lib/config'
    import { SnippetViewerHeader } from './SnippetViewerHeader'

    // Dynamically import SnippetViewerContent to avoid SSR issues with Pyodide
    const SnippetViewerContent = dynamic(
      () => import('./SnippetViewerContent').then(mod => ({ default: mod.SnippetViewerContent })),
      { ssr: false }
    )

    interface SnippetViewerProps {
      snippet: Snippet | null
      open: boolean
      onOpenChange: (open: boolean) => void
      onEdit: (snippet: Snippet) => void
      onCopy: (code: string) => void
    }

    export function SnippetViewer({ snippet, open, onOpenChange, onEdit, onCopy }: SnippetViewerProps) {
      const [isCopied, setIsCopied] = useState(false)
      const [showPreview, setShowPreview] = useState(true)

      if (!snippet) return null

      const handleCopy = () => {
        onCopy(snippet.code)
        setIsCopied(true)
        setTimeout(() => setIsCopied(false), appConfig.copiedTimeout)
      }

      const handleEdit = () => {
        onOpenChange(false)
        onEdit(snippet)
      }

      const canPreview = !!(snippet.hasPreview && appConfig.previewEnabledLanguages.includes(snippet.language))
      const isPython = snippet.language === 'Python'

      return (
        <Dialog open={open} onOpenChange={onOpenChange}>
          <DialogContent
            className="sm:max-w-[95vw] sm:max-h-[95vh] h-[95vh] overflow-hidden flex flex-col p-0"
            data-testid="snippet-viewer-dialog"
          >
            <DialogHeader className="px-6 pt-6 pb-4 pr-14 border-b border-border">
              <SnippetViewerHeader
                snippet={snippet}
                isCopied={isCopied}
                canPreview={canPreview}
                showPreview={showPreview}
                onCopy={handleCopy}
                onEdit={handleEdit}
                onTogglePreview={() => setShowPreview(!showPreview)}
              />
            </DialogHeader>

            <div className="flex-1 overflow-hidden flex">
              <SnippetViewerContent
                snippet={snippet}
                canPreview={canPreview}
                showPreview={showPreview}
                isPython={isPython}
              />
            </div>
          </DialogContent>
        </Dialog>
      )
    }