All files / web/src/app/create/worksheets/components/config-sidebar LayoutPreview.tsx

0% Statements 0/139
0% Branches 0/1
0% Functions 0/1
0% Lines 0/139

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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140                                                                                                                                                                                                                                                                                       
'use client'

import { css } from '@styled/css'
import { useTheme } from '@/contexts/ThemeContext'

interface LayoutPreviewProps {
  orientation: 'portrait' | 'landscape'
  cols: number
  rows: number
  className?: string
  onClick?: () => void
  isSelected?: boolean
  maxSize?: number
}

/**
 * Visual preview of worksheet layout showing page orientation and problem grid
 * Can act as a button when onClick is provided
 */
export function LayoutPreview({
  orientation,
  cols,
  rows,
  className,
  onClick,
  isSelected = false,
  maxSize = 48,
}: LayoutPreviewProps) {
  const { resolvedTheme } = useTheme()
  const isDark = resolvedTheme === 'dark'

  // Page dimensions (aspect ratios)
  const pageAspect = orientation === 'portrait' ? 8.5 / 11 : 11 / 8.5

  // Scale to fit in button (max dimensions)
  let pageWidth: number
  let pageHeight: number

  if (orientation === 'portrait') {
    pageHeight = maxSize
    pageWidth = pageHeight * pageAspect
  } else {
    pageWidth = maxSize
    pageHeight = pageWidth / pageAspect
  }

  // Problem cell dimensions with padding
  const padding = 3
  const cellWidth = (pageWidth - padding * 2) / cols
  const cellHeight = (pageHeight - padding * 2) / rows
  const cellPadding = 1

  const svgContent = (
    <svg
      viewBox={`0 0 ${pageWidth} ${pageHeight}`}
      className={css({
        rounded: 'sm',
        width: '100%',
        height: '100%',
      })}
      style={{
        backgroundColor: isDark ? '#1f2937' : 'white',
      }}
      preserveAspectRatio="xMidYMid meet"
    >
      {/* Problem grid */}
      {Array.from({ length: rows }).map((_, rowIdx) =>
        Array.from({ length: cols }).map((_, colIdx) => (
          <rect
            key={`${rowIdx}-${colIdx}`}
            x={padding + colIdx * cellWidth + cellPadding}
            y={padding + rowIdx * cellHeight + cellPadding}
            width={cellWidth - cellPadding * 2}
            height={cellHeight - cellPadding * 2}
            fill={isDark ? '#6b7280' : '#d1d5db'}
            rx={0.5}
          />
        ))
      )}
    </svg>
  )

  // If used as a button, wrap in button element with styling
  if (onClick) {
    const aspectRatio = orientation === 'portrait' ? 8.5 / 11 : 11 / 8.5

    return (
      <button
        type="button"
        onClick={onClick}
        className={css({
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          border: '2px solid',
          borderColor: isSelected ? 'brand.500' : isDark ? 'gray.600' : 'gray.300',
          bg: isSelected ? (isDark ? 'brand.900' : 'brand.50') : isDark ? 'gray.700' : 'white',
          rounded: 'lg',
          cursor: 'pointer',
          transition: 'all 0.15s',
          p: '2',
          width: '100%',
          maxWidth: '32',
          _hover: {
            borderColor: 'brand.400',
          },
        })}
        style={{
          aspectRatio: aspectRatio.toString(),
        }}
      >
        {svgContent}
      </button>
    )
  }

  // Otherwise just return the SVG with border
  const aspectRatio = orientation === 'portrait' ? 8.5 / 11 : 11 / 8.5

  return (
    <div
      className={css({
        border: '1px solid',
        borderColor: isDark ? 'gray.600' : 'gray.300',
        rounded: 'sm',
        display: 'inline-flex',
        alignItems: 'center',
        justifyContent: 'center',
        p: '1',
      })}
      style={{
        width: `${maxSize}px`,
        aspectRatio: aspectRatio.toString(),
      }}
    >
      {svgContent}
    </div>
  )
}