import React, { useRef, useState, useEffect, ChangeEvent } from "react"; import { ArrowDownTrayIcon, ArrowUpTrayIcon, CheckCircleIcon, } from "@heroicons/react/24/outline"; import api from "../../utils/axios"; import { useBackdropStore } from "../../context/zustand-store/appStore"; import { useToast } from "../../hooks/useToast"; import { useUserProfileStore } from "../../context/zustand-store/userStore"; import { RolesContextMenu } from "../Button/RolesContextMenu"; interface DocumentOperationProps { downloadLink: string; uploadLink: string; validFiles?: string[]; payloadKey: string; onUploadSuccess?: () => void; page?: string; access?: string; limitSize?: number; } const buildAcceptString = (extensions: string[]): string => { const mimeTypes: string[] = []; extensions.forEach((ext) => { const lower = ext.toLowerCase().replace(".", ""); if (lower === "img" || lower === "image") { mimeTypes.push("image/*"); } else { mimeTypes.push(`.${lower}`); } }); return mimeTypes.join(","); }; export const DocumentOperation = ({ downloadLink, uploadLink, validFiles = [], payloadKey, onUploadSuccess, page = "", access = "", limitSize, }: DocumentOperationProps) => { const { openBackdrop, closeBackdrop } = useBackdropStore(); const showToast = useToast(); const fileInputRef = useRef(null); const [uploadedFileName, setUploadedFileName] = useState(""); const { profile } = useUserProfileStore(); const [contextMenu, setContextMenu] = useState<{ x: number; y: number; } | null>(null); const isAdmin = profile?.role?.type?.key === "ADM"; const ableToSee = () => { if (!access || !page) { return true; } const found = profile?.permissions?.find( (item: any) => item.page_name === page, ); if (found && found.page_access.includes(access)) { return true; } return false; }; const handleContextMenu = (e: React.MouseEvent) => { if (isAdmin && page && access) { e.preventDefault(); e.stopPropagation(); setContextMenu({ x: e.clientX, y: e.clientY, }); } }; useEffect(() => { const handleClick = () => { if (contextMenu) { setContextMenu(null); } }; if (contextMenu) { document.addEventListener("click", handleClick); } return () => { document.removeEventListener("click", handleClick); }; }, [contextMenu]); const handleDownload = async () => { if (!downloadLink) return; openBackdrop(); try { const response = await api.get(downloadLink, { responseType: "blob", }); const contentDisposition = response.headers["content-disposition"]; let fileName = "document"; if (contentDisposition) { const match = contentDisposition.match( /filename\*?=(?:UTF-8''|"?)([^";]+)/i, ); if (match?.[1]) { fileName = decodeURIComponent(match[1].replace(/"/g, "")); } } else { const urlParts = downloadLink.split("/").filter(Boolean); const lastPart = urlParts[urlParts.length - 1]; if (lastPart && lastPart.includes(".")) { fileName = lastPart; } } const url = window.URL.createObjectURL(new Blob([response.data])); const link = document.createElement("a"); link.href = url; link.setAttribute("download", fileName); document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(url); showToast("فایل با موفقیت دانلود شد", "success"); } catch { showToast("خطا در دانلود فایل", "error"); } finally { closeBackdrop(); } }; const handleUploadClick = () => { fileInputRef.current?.click(); }; const handleFileChange = async (e: ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; if (fileInputRef.current) { fileInputRef.current.value = ""; } if (limitSize && file.size > limitSize * 1024 * 1024) { showToast(`حداکثر حجم فایل ${limitSize} مگابایت است`, "error"); return; } openBackdrop(); try { const formData = new FormData(); formData.append(payloadKey, file); await api.post(uploadLink, formData, { headers: { "Content-Type": "multipart/form-data", }, }); setUploadedFileName(file.name); showToast("فایل با موفقیت آپلود شد", "success"); onUploadSuccess?.(); } catch { showToast("خطا در آپلود فایل", "error"); } finally { closeBackdrop(); } }; const acceptString = validFiles.length > 0 ? buildAcceptString(validFiles) : undefined; return ( <>
{contextMenu && page && access && ( setContextMenu(null)} /> )} ); };