"use client" import { useRef, useState } from "react" import Image from "next/image" import { UploadIcon, XIcon } from "lucide-react" import { toast } from "sonner" import { uploadAsset } from "@/lib/api/admin" import { useI18n } from "@/i18n/provider" import { cn } from "@/lib/utils" export type ImageInputProps = { value?: string onChange?: (value: string) => void disabled?: boolean accept?: string maxSize?: number prefix?: string placeholder?: string className?: string } export function ImageInput({ value, onChange, disabled, accept = "image/*", maxSize = 5 * 1024 * 1024, prefix, placeholder, className, }: ImageInputProps) { const t = useI18n() const [uploading, setUploading] = useState(false) const fileInputRef = useRef(null) const resolvedPlaceholder = placeholder ?? t("upload.imagePlaceholder") function handleClick() { if (disabled || uploading) { return } fileInputRef.current?.click() } function handleClear(event: React.MouseEvent) { event.stopPropagation() onChange?.("") } async function handleFileChange(event: React.ChangeEvent) { const file = event.target.files?.[0] if (!file) { return } if (!file.type.startsWith("image/")) { toast.error(t("upload.chooseImage")) return } if (file.size > maxSize) { const maxSizeMB = (maxSize / 1024 / 1024).toFixed(0) toast.error(t("upload.imageTooLarge", { maxSize: maxSizeMB })) return } setUploading(true) try { const result = await uploadAsset(file, prefix) onChange?.(result.url) toast.success(t("upload.imageUploaded")) } catch (error) { toast.error(error instanceof Error ? error.message : t("upload.imageUploadFailed")) } finally { setUploading(false) if (fileInputRef.current) { fileInputRef.current.value = "" } } } const isDisabled = disabled || uploading return (
{ if (e.key === "Enter" || e.key === " ") { e.preventDefault() handleClick() } }} role="button" aria-label={value ? t("upload.replaceImage") : resolvedPlaceholder} > {value ? ( <> {t("upload.uploadedImage")}
{t("upload.replaceImage")}
) : (
{uploading ? t("upload.uploading") : resolvedPlaceholder}
)} {uploading && (
)}
{value && !isDisabled && ( )}
) }