{"version":3,"sources":["../src/logo-upload/logo-upload.tsx"],"names":["cva","React","isImageFile","formatBytes","jsxs","cn","jsx","Fragment","Upload","ImageIcon","Loader2","X"],"mappings":"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","file":"chunk-YWWYNH5T.cjs","sourcesContent":["\"use client\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { ImageIcon, Loader2, Upload, X } from \"lucide-react\";\nimport * as React from \"react\";\nimport type { UploadHandler } from \"../lib/types\";\nimport { cn, formatBytes, isImageFile } from \"../lib/utils\";\n\nconst containerVariants = cva(\n  \"relative rounded-lg overflow-hidden bg-muted border-2 border-dashed border-muted-foreground/25 flex items-center justify-center cursor-pointer transition-all group hover:border-muted-foreground/50\",\n  {\n    variants: {\n      size: {\n        sm: \"h-16\",\n        default: \"h-24\",\n        lg: \"h-32\",\n        xl: \"h-40\",\n      },\n      aspect: {\n        square: \"aspect-square\",\n        wide: \"aspect-video\",\n        banner: \"aspect-[3/1]\",\n        auto: \"\",\n      },\n    },\n    defaultVariants: {\n      size: \"default\",\n      aspect: \"wide\",\n    },\n  },\n);\n\nexport interface LogoUploadProps\n  extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\">,\n    VariantProps<typeof containerVariants> {\n  /**\n   * Upload handler configuration\n   */\n  handler: UploadHandler;\n  /**\n   * Current logo URL\n   */\n  value?: string | null;\n  /**\n   * Called when logo changes\n   */\n  onChange?: (url: string | null) => void;\n  /**\n   * Called when upload completes\n   */\n  onUploadComplete?: (url: string) => void;\n  /**\n   * Maximum file size in bytes\n   * @default 5 * 1024 * 1024 (5MB)\n   */\n  maxSize?: number;\n  /**\n   * Accepted image types\n   * @default [\"image/jpeg\", \"image/png\", \"image/gif\", \"image/webp\", \"image/svg+xml\"]\n   */\n  accept?: string[];\n  /**\n   * Whether to allow removing the logo\n   * @default true\n   */\n  allowRemove?: boolean;\n  /**\n   * Disabled state\n   */\n  disabled?: boolean;\n  /**\n   * Placeholder text\n   * @default \"Upload logo\"\n   */\n  placeholder?: string;\n  /**\n   * Object fit for the image\n   * @default \"contain\"\n   */\n  objectFit?: \"contain\" | \"cover\" | \"fill\";\n}\n\ntype UploadState = \"idle\" | \"uploading\" | \"processing\" | \"error\";\n\nexport function LogoUpload({\n  handler,\n  value,\n  onChange,\n  onUploadComplete,\n  maxSize = 5 * 1024 * 1024,\n  accept = [\"image/jpeg\", \"image/png\", \"image/gif\", \"image/webp\", \"image/svg+xml\"],\n  allowRemove = true,\n  disabled = false,\n  placeholder = \"Upload logo\",\n  objectFit = \"contain\",\n  size,\n  aspect,\n  className,\n  ...props\n}: LogoUploadProps) {\n  const [uploadState, setUploadState] = React.useState<UploadState>(\"idle\");\n  const [error, setError] = React.useState<string | null>(null);\n  const [previewUrl, setPreviewUrl] = React.useState<string | null>(null);\n  const inputRef = React.useRef<HTMLInputElement>(null);\n\n  // Clean up preview URL on unmount\n  React.useEffect(() => {\n    return () => {\n      if (previewUrl) {\n        URL.revokeObjectURL(previewUrl);\n      }\n    };\n  }, [previewUrl]);\n\n  const handleClick = React.useCallback(() => {\n    if (!disabled && uploadState === \"idle\") {\n      inputRef.current?.click();\n    }\n  }, [disabled, uploadState]);\n\n  const handleRemove = React.useCallback(\n    (e: React.MouseEvent) => {\n      e.stopPropagation();\n      if (previewUrl) {\n        URL.revokeObjectURL(previewUrl);\n        setPreviewUrl(null);\n      }\n      onChange?.(null);\n    },\n    [onChange, previewUrl],\n  );\n\n  const handleFileSelect = React.useCallback(\n    async (e: React.ChangeEvent<HTMLInputElement>) => {\n      const file = e.target.files?.[0];\n      e.target.value = \"\";\n\n      if (!file) return;\n\n      // Validate file type\n      const isValidType = isImageFile(file.type) || file.type === \"image/svg+xml\" || accept.includes(file.type);\n\n      if (!isValidType) {\n        setError(\"Please select a valid image file\");\n        return;\n      }\n\n      // Validate file size\n      if (file.size > maxSize) {\n        setError(`Image must be less than ${formatBytes(maxSize)}`);\n        return;\n      }\n\n      setError(null);\n\n      // Create preview\n      const objectUrl = URL.createObjectURL(file);\n      if (previewUrl) {\n        URL.revokeObjectURL(previewUrl);\n      }\n      setPreviewUrl(objectUrl);\n\n      try {\n        setUploadState(\"uploading\");\n\n        // Get upload URL\n        const { uploadUrl, assetId } = await handler.getUploadUrl(file);\n\n        // Upload file\n        const response = await fetch(uploadUrl, {\n          method: \"PUT\",\n          body: file,\n          headers: {\n            \"Content-Type\": file.type,\n          },\n        });\n\n        if (!response.ok) {\n          throw new Error(\"Upload failed\");\n        }\n\n        setUploadState(\"processing\");\n\n        // Confirm upload\n        let finalUrl = objectUrl;\n        if (handler.onUploadComplete && assetId) {\n          const result = await handler.onUploadComplete(assetId, file);\n          if (result.url) {\n            finalUrl = result.url;\n            URL.revokeObjectURL(objectUrl);\n            setPreviewUrl(null);\n          }\n        }\n\n        setUploadState(\"idle\");\n        onChange?.(finalUrl);\n        onUploadComplete?.(finalUrl);\n      } catch (err) {\n        setUploadState(\"error\");\n        setError(err instanceof Error ? err.message : \"Upload failed\");\n        handler.onError?.(err instanceof Error ? err : new Error(\"Upload failed\"), file);\n      }\n    },\n    [accept, handler, maxSize, onChange, onUploadComplete, previewUrl],\n  );\n\n  const displayUrl = previewUrl || value;\n  const isLoading = uploadState === \"uploading\" || uploadState === \"processing\";\n\n  return (\n    <div className={cn(\"w-full\", className)} {...props}>\n      <div\n        role=\"button\"\n        tabIndex={disabled ? -1 : 0}\n        onClick={handleClick}\n        onKeyDown={(e) => {\n          if (e.key === \"Enter\" || e.key === \" \") {\n            handleClick();\n          }\n        }}\n        className={cn(\n          containerVariants({ size, aspect }),\n          displayUrl && \"border-solid border-muted-foreground/15\",\n          disabled && \"opacity-50 cursor-not-allowed\",\n          \"focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2\",\n        )}\n      >\n        <input\n          ref={inputRef}\n          type=\"file\"\n          accept={accept.join(\",\")}\n          onChange={handleFileSelect}\n          className=\"hidden\"\n          disabled={disabled || isLoading}\n        />\n\n        {/* Logo image or placeholder */}\n        {displayUrl ? (\n          <>\n            <img\n              src={displayUrl}\n              alt=\"Logo\"\n              className={cn(\n                \"h-full w-full p-2\",\n                objectFit === \"contain\" && \"object-contain\",\n                objectFit === \"cover\" && \"object-cover\",\n                objectFit === \"fill\" && \"object-fill\",\n              )}\n            />\n            {/* Hover overlay */}\n            {!disabled && !isLoading && (\n              <div className=\"absolute inset-0 bg-black/60 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity\">\n                <Upload className=\"h-6 w-6 text-white\" />\n              </div>\n            )}\n          </>\n        ) : (\n          <div className=\"flex flex-col items-center justify-center gap-2 p-4\">\n            <ImageIcon className=\"h-8 w-8 text-muted-foreground\" />\n            <span className=\"text-sm text-muted-foreground\">{placeholder}</span>\n          </div>\n        )}\n\n        {/* Loading overlay */}\n        {isLoading && (\n          <div className=\"absolute inset-0 bg-black/60 flex items-center justify-center\">\n            <Loader2 className=\"h-6 w-6 text-white animate-spin\" />\n          </div>\n        )}\n\n        {/* Remove button */}\n        {allowRemove && displayUrl && !disabled && !isLoading && (\n          <button\n            type=\"button\"\n            onClick={handleRemove}\n            className=\"absolute top-2 right-2 h-6 w-6 rounded-full bg-destructive text-destructive-foreground flex items-center justify-center hover:bg-destructive/90 transition-colors opacity-0 group-hover:opacity-100\"\n          >\n            <X className=\"h-3 w-3\" />\n          </button>\n        )}\n      </div>\n\n      {/* Error message */}\n      {error && <p className=\"text-xs text-destructive mt-2\">{error}</p>}\n\n      {/* Status message */}\n      {isLoading && (\n        <p className=\"text-xs text-muted-foreground mt-2\">\n          {uploadState === \"uploading\" ? \"Uploading...\" : \"Processing...\"}\n        </p>\n      )}\n    </div>\n  );\n}\n\nLogoUpload.displayName = \"LogoUpload\";\n"]}