"use client"; import { UploadCloud, X } from "lucide-react"; import Image from "next/image"; import { useCallback, useState } from "react"; import { useDropzone } from "react-dropzone"; import { toast } from "sonner"; import { Button } from "./ui/button"; import fileApi, { FileUploadResponse } from "../services/file"; const API_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000"; interface ImageUploadProps { value?: string; onChange: (value: string) => void; onRemove: () => void; description?: string; } export function ImageUpload({ value, onChange, onRemove, description, }: ImageUploadProps) { const [isUploading, setIsUploading] = useState(false); const [, setImageError] = useState(false); const onDrop = useCallback( async (acceptedFiles: File[]) => { const file = acceptedFiles[0]; if (!file) return; try { setIsUploading(true); setImageError(false); const response: FileUploadResponse = await fileApi.uploadFile( file, description ); if (!response.id) { throw new Error("No file ID received from server"); } onChange(response.id); toast.success("Gambar berhasil diunggah"); } catch (error) { console.error("Error uploading image:", error); toast.error( error instanceof Error ? error.message : "Gagal mengunggah gambar" ); } finally { setIsUploading(false); } }, [onChange, description] ); const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, accept: { "image/*": [".png", ".jpg", ".jpeg", ".gif"], }, maxFiles: 1, maxSize: 5 * 1024 * 1024, // 5MB disabled: isUploading, }); const imageUrl = value ? `${API_URL}/files/${value}/download` : undefined; return (
Gambar berhasil diunggah
Klik untuk mengubah gambar
{isUploading ? "Mengunggah..." : isDragActive ? "Drop the image here" : "Drag & drop an image here, or click to select"}
Max file size: 5MB. Supported formats: PNG, JPG, JPEG, GIF