205 lines
6.7 KiB
TypeScript
205 lines
6.7 KiB
TypeScript
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;
|