"use client" import { useCallback, useRef, useState, useEffect } from "react" import { ImagePlus, X } from "lucide-react" import type { BaseFieldControlProps } from "../types" import { cn } from "@/shared/lib/utils" export type ImageInputFieldProps = BaseFieldControlProps & { accept?: string } export function ImageInputField({ value, onChange, onBlur, name, disabled, invalid, accept = "image/*", }: ImageInputFieldProps) { const inputRef = useRef(null) const [preview, setPreview] = useState(null) const [isDragging, setIsDragging] = useState(false) useEffect(() => { if (!value) { setPreview(null) return } const url = URL.createObjectURL(value) setPreview(url) return () => URL.revokeObjectURL(url) }, [value]) const handleFile = useCallback( (file: File | null) => { if (file && !file.type.startsWith("image/")) return onChange(file) }, [onChange], ) const handleDrop = useCallback( (e: React.DragEvent) => { e.preventDefault() setIsDragging(false) if (disabled) return const file = e.dataTransfer.files?.[0] ?? null handleFile(file) }, [disabled, handleFile], ) const handleDragOver = useCallback( (e: React.DragEvent) => { e.preventDefault() if (!disabled) setIsDragging(true) }, [disabled], ) const handleDragLeave = useCallback(() => setIsDragging(false), []) const handleClear = useCallback( (e: React.MouseEvent) => { e.stopPropagation() onChange(null) if (inputRef.current) inputRef.current.value = "" }, [onChange], ) return (
!disabled && inputRef.current?.click()} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault() inputRef.current?.click() } }} onDrop={handleDrop} onDragOver={handleDragOver} onDragLeave={handleDragLeave} onBlur={onBlur} aria-invalid={invalid || undefined} className={cn( "relative flex min-h-35 cursor-pointer flex-col items-center justify-center gap-2 rounded-md border border-dashed border-input bg-background p-4 text-sm transition-colors", isDragging && "border-primary bg-primary/5", invalid && "border-destructive", disabled && "pointer-events-none opacity-50", )} > handleFile(e.target.files?.[0] ?? null)} /> {preview ? ( <> Preview {!disabled && ( )} ) : ( <> Click or drag & drop an image )}
) }