import React, { useState } from 'react'; import { Upload, Modal, Button, Typography, Space, Image } from 'antd'; import { UploadOutlined, EyeOutlined, DeleteOutlined, FileOutlined } from '@ant-design/icons'; import { NotifOk, NotifAlert } from '../../../../components/Global/ToastNotif'; import { uploadFile, getFolderFromFileType, getFileUrl, getFileType } from '../../../../api/file-uploads'; const { Text } = Typography; const FileUploadHandler = ({ type = 'solution', maxCount = 1, accept = '.pdf,.jpg,.jpeg,.png,.gif', disabled = false, fileList = [], onFileUpload, onFileRemove, existingFile = null, clearSignal = null, debugProps = {}, uploadText = 'Click or drag file to this area to upload', uploadHint = 'Support for PDF and image files only', buttonText = 'Upload File', buttonType = 'default', containerStyle = {}, buttonStyle = {}, showPreview = true }) => { const [previewOpen, setPreviewOpen] = useState(false); const [previewImage, setPreviewImage] = useState(''); const [previewTitle, setPreviewTitle] = useState(''); const [isUploading, setIsUploading] = useState(false); const [uploadedFile, setUploadedFile] = useState(null); React.useEffect(() => { if (clearSignal !== null && clearSignal > 0) { setUploadedFile(null); } }, [clearSignal, debugProps]); const getBase64 = (file) => new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => resolve(reader.result); reader.onerror = (error) => reject(error); }); const handlePreview = async (file) => { if (!file.url && !file.preview) { file.preview = await getBase64(file.originFileObj); } setPreviewImage(file.url || file.preview); setPreviewOpen(true); setPreviewTitle(file.name || file.url.substring(file.url.lastIndexOf('/') + 1)); }; const validateFile = (file) => { const isAllowedType = [ 'application/pdf', 'image/jpeg', 'image/png', 'image/gif', ].includes(file.type); if (!isAllowedType) { NotifAlert({ icon: 'error', title: 'Error', message: `${file.name} bukan file PDF atau gambar yang diizinkan.`, }); return false; } return true; }; const handleFileUpload = async (file) => { if (isUploading) { return false; } if (!validateFile(file)) { return false; } try { setIsUploading(true); const fileExtension = file.name.split('.').pop().toLowerCase(); const isImage = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'].includes(fileExtension); const fileType = isImage ? 'image' : 'pdf'; const folder = getFolderFromFileType(fileType); const uploadResponse = await uploadFile(file, folder); const isSuccess = uploadResponse && ( uploadResponse.statusCode === 200 || uploadResponse.statusCode === 201 ); if (!isSuccess) { NotifAlert({ icon: 'error', title: 'Gagal', message: uploadResponse?.message || `Gagal mengupload ${file.name}`, }); setIsUploading(false); return false; } let actualPath = ''; if (uploadResponse && typeof uploadResponse === 'object') { if (uploadResponse.data && uploadResponse.data.path_document) { actualPath = uploadResponse.data.path_document; } else if (uploadResponse.path_document) { actualPath = uploadResponse.path_document; } else if (uploadResponse.data && uploadResponse.data.path_solution) { actualPath = uploadResponse.data.path_solution; } else if (uploadResponse.data && typeof uploadResponse.data === 'object') { if (uploadResponse.data.file_url) { actualPath = uploadResponse.data.file_url; } else if (uploadResponse.data.url) { actualPath = uploadResponse.data.url; } else if (uploadResponse.data.path) { actualPath = uploadResponse.data.path; } else if (uploadResponse.data.location) { actualPath = uploadResponse.data.location; } else if (uploadResponse.data.filePath) { actualPath = uploadResponse.data.filePath; } else if (uploadResponse.data.file_path) { actualPath = uploadResponse.data.file_path; } else if (uploadResponse.data.publicUrl) { actualPath = uploadResponse.data.publicUrl; } else if (uploadResponse.data.public_url) { actualPath = uploadResponse.data.public_url; } } else if (uploadResponse && typeof uploadResponse === 'string') { actualPath = uploadResponse; } } if (actualPath) { let fileObject; if (type === 'error_code') { fileObject = { name: file.name, path_icon: actualPath, uploadPath: actualPath, url: actualPath, size: file.size, type: file.type, fileExtension }; } else { fileObject = { name: file.name, path_solution: actualPath, uploadPath: actualPath, type_solution: fileType, size: file.size, type: file.type }; } onFileUpload(fileObject); setUploadedFile(fileObject); NotifOk({ icon: 'success', title: 'Berhasil', message: `${file.name} berhasil diupload!` }); setIsUploading(false); return false; } else { NotifAlert({ icon: 'error', title: 'Gagal', message: `Gagal mengupload ${file.name}. Tidak dapat menemukan path file dalam response.`, }); setIsUploading(false); return false; } } catch (error) { NotifAlert({ icon: 'error', title: 'Error', message: `Gagal mengupload ${file.name}. Silakan coba lagi.`, }); setIsUploading(false); return false; } }; const handleFileChange = ({ fileList }) => { if (fileList && fileList.length > 0 && fileList[0] && fileList[0].originFileObj) { handleFileUpload(fileList[0].originFileObj); } }; const handleRemove = () => { if (existingFile && onFileRemove) { onFileRemove(existingFile); } else if (onFileRemove) { onFileRemove(null); } }; const renderExistingFile = () => { const fileToShow = existingFile || uploadedFile; if (!fileToShow) { return null; } const filePath = fileToShow.uploadPath || fileToShow.url || fileToShow.path_icon || fileToShow.path_solution; const fileName = fileToShow.name || filePath?.split('/').pop() || 'Unknown file'; const fileType = getFileType(fileName); const isImage = fileType === 'image'; const handlePreview = () => { if (!showPreview || !filePath) return; if (isImage) { const folder = fileToShow.type_solution === 'pdf' ? 'pdf' : 'images'; const filename = filePath.split('/').pop(); const imageUrl = getFileUrl(folder, filename); if (imageUrl) { setPreviewImage(imageUrl); setPreviewOpen(true); setPreviewTitle(fileName); } else { NotifAlert({ icon: 'error', title: 'Error', message: 'Cannot generate image preview URL', }); } } else { const folder = fileToShow.type_solution === 'pdf' ? 'pdf' : 'images'; const filename = filePath.split('/').pop(); const fileUrl = getFileUrl(folder, filename); if (fileUrl) { window.open(fileUrl, '_blank', 'noopener,noreferrer'); } else { NotifAlert({ icon: 'error', title: 'Error', message: 'Cannot generate file preview URL', }); } } }; const getThumbnailUrl = () => { if (!isImage || !filePath) return null; const folder = fileToShow.type_solution === 'pdf' ? 'pdf' : 'images'; const filename = filePath.split('/').pop(); return getFileUrl(folder, filename); }; const thumbnailUrl = getThumbnailUrl(); return (
{uploadText}
{uploadHint}