{"version":3,"sources":["../src/components/Whiteboard/Whiteboard.tsx"],"sourcesContent":["import { HTMLAttributes, useCallback, useState } from 'react';\nimport { ArrowsOutIcon } from '@phosphor-icons/react/dist/csr/ArrowsOut';\nimport { cn } from '../../utils/utils';\n\n// Design constants for critical layout dimensions\nconst IMAGE_WIDTH = 225;\nconst IMAGE_HEIGHT = 90;\n\n/**\n * Whiteboard image item interface\n */\nexport interface WhiteboardImage {\n  id: string;\n  imageUrl: string;\n  title?: string;\n}\n\n/**\n * Whiteboard component props interface\n */\nexport interface WhiteboardProps extends HTMLAttributes<HTMLDivElement> {\n  /** Array of images to display in the whiteboard */\n  images: WhiteboardImage[];\n  /** Whether to show download button on images */\n  showDownload?: boolean;\n  /** Custom className for the container */\n  className?: string;\n  /** Callback when download button is clicked */\n  onDownload?: (image: WhiteboardImage) => void;\n  /** Maximum number of images to display per row on desktop */\n  imagesPerRow?: 2 | 3 | 4;\n}\n\n/**\n * Whiteboard component for displaying classroom board images\n * @param props Component properties\n * @returns Whiteboard component\n */\nconst Whiteboard = ({\n  images,\n  showDownload = true,\n  className,\n  onDownload,\n  imagesPerRow = 2,\n  ...rest\n}: WhiteboardProps) => {\n  // State to track images that failed to load\n  const [imageErrors, setImageErrors] = useState<Set<string>>(new Set());\n\n  /**\n   * Handle image download\n   */\n  const handleDownload = useCallback(\n    (image: WhiteboardImage) => {\n      if (onDownload) {\n        onDownload(image);\n      } else {\n        const link = document.createElement('a');\n        link.href = image.imageUrl;\n        link.download = image.title || `whiteboard-${image.id}`;\n        link.target = '_blank';\n        link.rel = 'noopener noreferrer';\n        document.body.appendChild(link);\n        link.click();\n        document.body.removeChild(link);\n      }\n    },\n    [onDownload]\n  );\n\n  /**\n   * Handle image loading error\n   */\n  const handleImageError = useCallback((imageId: string) => {\n    setImageErrors((prev) => new Set(prev).add(imageId));\n  }, []);\n\n  const gridColsClass =\n    images?.length === 1\n      ? 'grid-cols-1'\n      : {\n          2: 'grid-cols-1 sm:grid-cols-2',\n          3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',\n          4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',\n        }[imagesPerRow];\n\n  // Let CSS handle sizing responsively\n\n  if (!images || images.length === 0) {\n    return (\n      <div\n        className={cn(\n          'flex items-center justify-center p-8 bg-background border border-border-50 rounded-xl',\n          className\n        )}\n        {...rest}\n      >\n        <p className=\"text-gray-400 text-sm\">Nenhuma imagem disponível</p>\n      </div>\n    );\n  }\n\n  return (\n    <div\n      className={cn(\n        'flex flex-col bg-background border border-border-50 p-4 gap-2 rounded-xl w-fit mx-auto',\n        className\n      )}\n      {...rest}\n    >\n      <div className={cn('grid gap-4', gridColsClass)}>\n        {images.map((image) => (\n          <div\n            key={image.id}\n            className=\"relative group overflow-hidden bg-gray-100 rounded-lg\"\n            style={{\n              width: `${IMAGE_WIDTH}px`,\n            }}\n          >\n            <div\n              className=\"relative\"\n              style={{\n                width: `${IMAGE_WIDTH}px`,\n                height: `${IMAGE_HEIGHT}px`,\n              }}\n            >\n              {imageErrors.has(image.id) ? (\n                <div className=\"absolute inset-0 flex items-center justify-center bg-gray-200\">\n                  <p className=\"text-gray-500 text-sm text-center px-2\">\n                    Imagem indisponível\n                  </p>\n                </div>\n              ) : (\n                <button\n                  type=\"button\"\n                  onClick={() => handleDownload(image)}\n                  className=\"absolute inset-0 w-full h-full cursor-pointer border-none p-0 bg-transparent\"\n                  aria-label={`Ampliar ${image.title || 'imagem'}`}\n                >\n                  <img\n                    src={image.imageUrl}\n                    alt={image.title || `Whiteboard ${image.id}`}\n                    className=\"w-full h-full object-cover\"\n                    loading=\"lazy\"\n                    onError={() => handleImageError(image.id)}\n                  />\n                  <div className=\"absolute inset-0 bg-gradient-to-t from-black/20 to-transparent pointer-events-none\" />\n                </button>\n              )}\n            </div>\n            {showDownload && (\n              <button\n                type=\"button\"\n                onClick={() => handleDownload(image)}\n                className=\"cursor-pointer absolute bottom-3 right-3 flex items-center justify-center bg-black/20 backdrop-blur-sm rounded hover:bg-black/30 transition-colors duration-200 group/button w-6 h-6\"\n                aria-label={`Download ${image.title || 'imagem'}`}\n              >\n                <ArrowsOutIcon\n                  size={24}\n                  weight=\"regular\"\n                  className=\"text-white group-hover/button:scale-110 transition-transform duration-200\"\n                />\n              </button>\n            )}\n          </div>\n        ))}\n      </div>\n    </div>\n  );\n};\n\nexport default Whiteboard;\n"],"mappings":"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","names":[]}