erp-platform/ui/src/views/project/components/DocumentViewerModal.tsx

206 lines
6.7 KiB
TypeScript
Raw Normal View History

2025-09-15 09:31:47 +00:00
import React from "react";
import {
FaTimes,
FaDownload,
FaFileAlt,
FaFilePdf,
FaFileWord,
FaFileExcel,
FaFilePowerpoint,
FaFileImage,
} from "react-icons/fa";
import { PsProjectDocument } from "../../../types/ps";
import dayjs from "dayjs";
import { getPsDocumentTypeText } from "../../../utils/erp";
interface DocumentViewerModalProps {
isOpen: boolean;
onClose: () => void;
document: PsProjectDocument | null;
onDownload?: (document: PsProjectDocument) => void;
}
const DocumentViewerModal: React.FC<DocumentViewerModalProps> = ({
isOpen,
onClose,
document,
onDownload,
}) => {
const getFileIcon = (fileName: string) => {
const extension = fileName.toLowerCase().split(".").pop();
switch (extension) {
case "pdf":
return <FaFilePdf className="w-8 h-8 text-red-500" />;
case "doc":
case "docx":
return <FaFileWord className="w-8 h-8 text-blue-500" />;
case "xls":
case "xlsx":
return <FaFileExcel className="w-8 h-8 text-green-500" />;
case "ppt":
case "pptx":
return <FaFilePowerpoint className="w-8 h-8 text-orange-500" />;
case "jpg":
case "jpeg":
case "png":
case "gif":
return <FaFileImage className="w-8 h-8 text-purple-500" />;
default:
return <FaFileAlt className="w-8 h-8 text-gray-500" />;
}
};
const formatFileSize = (sizeInMB: number): string => {
if (sizeInMB < 1) {
return `${(sizeInMB * 1024).toFixed(0)} KB`;
}
return `${sizeInMB.toFixed(2)} MB`;
};
const handleDownload = () => {
if (document && onDownload) {
onDownload(document);
} else if (document) {
// Fallback: create a download link
const link = window.document.createElement("a");
link.href = document.filePath;
link.download = document.documentName;
link.click();
}
};
const isImageFile = (fileName: string): boolean => {
const extension = fileName.toLowerCase().split(".").pop();
return ["jpg", "jpeg", "png", "gif"].includes(extension || "");
};
const isPdfFile = (fileName: string): boolean => {
const extension = fileName.toLowerCase().split(".").pop();
return extension === "pdf";
};
if (!isOpen || !document) return null;
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg w-full max-w-4xl max-h-[90vh] overflow-hidden flex flex-col">
{/* Header */}
<div className="flex items-center justify-between p-3 border-b border-gray-200">
<div className="flex items-center space-x-3">
{getFileIcon(document.documentName)}
<div>
<h2 className="text-lg font-semibold text-gray-900">
{document.documentName}
</h2>
<p className="text-sm text-gray-500">
{getPsDocumentTypeText(document.documentType)} {" "}
{formatFileSize(document.fileSize)}
</p>
</div>
</div>
<div className="flex items-center space-x-2">
<button
onClick={handleDownload}
className="flex items-center space-x-2 px-3 py-1 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
>
<FaDownload className="w-4 h-4" />
<span>İndir</span>
</button>
<button
onClick={onClose}
className="text-gray-400 hover:text-gray-600 p-2"
>
<FaTimes className="w-4 h-4" />
</button>
</div>
</div>
{/* Document Info */}
<div className="px-4 py-2 bg-gray-50 border-b border-gray-200">
<div className="grid grid-cols-2 md:grid-cols-4 gap-3 text-sm">
<div>
<span className="font-medium text-gray-700">Yükleyen:</span>
<p className="text-gray-600">{document.uploadedBy}</p>
</div>
<div>
<span className="font-medium text-gray-700">
Yüklenme Tarihi:
</span>
<p className="text-gray-600">
{dayjs(document.uploadedAt).format("DD.MM.YYYY HH:mm")}
</p>
</div>
<div>
<span className="font-medium text-gray-700">Versiyon:</span>
<p className="text-gray-600">v{document.version}</p>
</div>
<div>
<span className="font-medium text-gray-700">Dosya Boyutu:</span>
<p className="text-gray-600">
{formatFileSize(document.fileSize)}
</p>
</div>
</div>
</div>
{/* Document Preview */}
<div className="flex-1 p-3 overflow-auto">
{isImageFile(document.documentName) ? (
<div className="flex items-center justify-center h-full">
<img
src={document.filePath}
alt={document.documentName}
className="max-w-full max-h-full object-contain"
onError={(e) => {
const target = e.target as HTMLImageElement;
target.style.display = "none";
}}
/>
</div>
) : isPdfFile(document.documentName) ? (
<div className="h-full">
<iframe
src={document.filePath}
className="w-full h-full border-0"
title={document.documentName}
/>
</div>
) : (
<div className="flex flex-col items-center justify-center h-full text-center">
{getFileIcon(document.documentName)}
<h3 className="mt-4 text-lg font-medium text-gray-900">
Önizleme Mevcut Değil
</h3>
<p className="mt-2 text-sm text-gray-500">
Bu dosya türü için önizleme desteklenmiyor.
</p>
<p className="text-sm text-gray-500">
Dosyayı görüntülemek için indirin.
</p>
</div>
)}
</div>
{/* Footer */}
<div className="px-4 py-2 bg-gray-50 border-t border-gray-200">
<div className="flex items-center justify-between">
<div className="text-sm text-gray-500">
Son güncelleme:{" "}
{dayjs(document.uploadedAt).format("DD.MM.YYYY HH:mm")}
</div>
<button
onClick={onClose}
className="px-3 py-1 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50"
>
Kapat
</button>
</div>
</div>
</div>
</div>
);
};
export default DocumentViewerModal;