import React, { useState, useEffect, useRef } from "react"; import ReactDOM from "react-dom"; import { motion } from "framer-motion"; import { X, ZoomIn, ZoomOut, RotateCcw, Download, Printer, ShieldCheck, AlertTriangle, CheckCircle, ChevronLeft, ChevronRight, FileText, Maximize, Minimize, } from "lucide-react"; import { Button } from "./Button"; interface Acceptance { id: string; signatureHash: string | null; documentUrl: string | null; signatureBase64: string | null; ipAddress: string; acceptedAt: string; document: { id: string; type: string; version: string; content: string; }; } interface DocumentPreviewModalProps { isOpen: boolean; onClose: () => void; partnerId: string; partnerEmail: string; partnerCreatedAt: string; acceptances: Acceptance[]; verifiedDocs: { nda: boolean; msa: boolean }; onVerify: (docType: "NDA" | "MSA") => void; onApprovePartner: () => void; isApproving: boolean; } export const DocumentPreviewModal: React.FC = ({ isOpen, onClose, partnerId: _partnerId, partnerEmail, partnerCreatedAt: _partnerCreatedAt, acceptances, verifiedDocs, onVerify, onApprovePartner, isApproving, }) => { const [currentTab, setCurrentTab] = useState<"NDA" | "MSA">("NDA"); const [zoom, setZoom] = useState(100); const [fitWidth, setFitWidth] = useState(false); const [currentPage, setCurrentPage] = useState(1); const [isFullScreen, setIsFullScreen] = useState(false); const modalRef = useRef(null); const containerRef = useRef(null); const ndaAcceptance = acceptances.find((a) => a.document.type === "NDA"); const msaAcceptance = acceptances.find((a) => a.document.type === "MSA"); const activeAcceptance = currentTab === "NDA" ? ndaAcceptance : msaAcceptance; const totalPages = activeAcceptance?.documentUrl ? 1 : 2; // Prevent background page scrolling when modal is open useEffect(() => { if (isOpen) { document.body.style.overflow = "hidden"; } else { document.body.style.overflow = ""; } return () => { document.body.style.overflow = ""; }; }, [isOpen]); // Handle auto-opening on the signature page (Page 2) for digitally signed documents useEffect(() => { if (isOpen && activeAcceptance) { if (!activeAcceptance.documentUrl && activeAcceptance.signatureHash) { setCurrentPage(2); } else { setCurrentPage(1); } } }, [currentTab, isOpen, activeAcceptance]); // Full Screen logic const toggleFullScreen = () => { if (!modalRef.current) return; if (!isFullScreen) { if (modalRef.current.requestFullscreen) { modalRef.current.requestFullscreen().catch(() => { setIsFullScreen(true); }); } else { setIsFullScreen(true); } } else { if (document.exitFullscreen) { document.exitFullscreen().catch(() => {}); } setIsFullScreen(false); } }; useEffect(() => { const handleFullscreenChange = () => { setIsFullScreen(!!document.fullscreenElement); }; document.addEventListener("fullscreenchange", handleFullscreenChange); return () => document.removeEventListener("fullscreenchange", handleFullscreenChange); }, []); if (!isOpen) return null; const handleZoomIn = () => { setFitWidth(false); setZoom((prev) => Math.min(200, prev + 25)); }; const handleZoomOut = () => { setFitWidth(false); setZoom((prev) => Math.max(50, prev - 25)); }; const handleZoomReset = () => { setFitWidth(false); setZoom(100); }; const toggleFitWidth = () => { setFitWidth(!fitWidth); }; const handlePrint = () => { const printContent = document.getElementById("printable-doc-content"); if (!printContent) return; const windowUrl = "about:blank"; const uniqueName = new Date().getTime(); const printWindow = window.open( windowUrl, uniqueName.toString(), "left=50000,top=50000,width=0,height=0", ); if (!printWindow) return; printWindow.document.write(` Print Document - ${currentTab}

${currentTab === "NDA" ? "Non-Disclosure Agreement (NDA)" : "Master Services Agreement (MSA)"}

${activeAcceptance?.document.content || ""}

Digitally Signed & Verified
Signed By: ${partnerEmail}
Verification Hash: ${activeAcceptance?.signatureHash || "N/A"}
IP Address: ${activeAcceptance?.ipAddress || "N/A"}
Date Signed: ${activeAcceptance ? new Date(activeAcceptance.acceptedAt).toLocaleString() : ""}
`); printWindow.document.close(); printWindow.focus(); printWindow.print(); printWindow.close(); }; const handleDownloadText = () => { if (!activeAcceptance) return; const element = document.createElement("a"); const file = new Blob( [ `${currentTab === "NDA" ? "Non-Disclosure Agreement (NDA)" : "Master Services Agreement (MSA)"}\n\n`, activeAcceptance.document.content, `\n\n=== DIGITAL SIGNATURE ===\n`, `Signed By: ${partnerEmail}\n`, `Verification Hash: ${activeAcceptance.signatureHash || "N/A"}\n`, `IP Address: ${activeAcceptance.ipAddress}\n`, `Signed On: ${new Date(activeAcceptance.acceptedAt).toLocaleString()}\n`, ], { type: "text/plain" }, ); element.href = URL.createObjectURL(file); element.download = `${currentTab}_Agreement_${partnerEmail.split("@")[0]}.txt`; document.body.appendChild(element); element.click(); document.body.removeChild(element); }; const fileHost = ( import.meta.env.VITE_API_URL || "http://localhost:5000/api/v1" ).replace("/api/v1", ""); const isBothVerified = verifiedDocs.nda && verifiedDocs.msa; const isCurrentVerified = currentTab === "NDA" ? verifiedDocs.nda : verifiedDocs.msa; // Responsive classes based on screen size const modalContainerClasses = isFullScreen ? "fixed inset-0 w-screen h-screen bg-ink-0 z-[9999] flex flex-col overflow-hidden" : "relative w-full h-full sm:w-[90vw] sm:h-[88vh] lg:w-[78vw] lg:h-[86vh] bg-ink-0 border border-ink-200 sm:rounded-2xl shadow-2xl flex flex-col overflow-hidden z-[9999]"; return ReactDOM.createPortal(
{/* Full-screen Backdrop overlay */} {/* Modal Box */} {/* Sticky Header */}

{currentTab === "NDA" ? "Mutual Non-Disclosure Agreement (NDA)" : "Master Services Agreement (MSA)"}

Partner: {partnerEmail}

{/* Switcher tabs */}
{/* Warning Banner if Unsigned */} {!activeAcceptance && (

Attention: This document has not been submitted or signed by the partner.

)} {/* Professional Document Viewer Toolbar */}
{/* Page navigation controls */}
Page {activeAcceptance ? currentPage : 0} of{" "} {activeAcceptance ? totalPages : 0}
{/* Zoom controls */}
{zoom}%
{/* Download & Print Actions */}
{/* Modal Main Body (Split Pane) */}
{/* Left Pane: Centered Document Viewer */}
{activeAcceptance ? ( activeAcceptance.documentUrl ? ( // PDF / Uploaded Document Viewer centered
{activeAcceptance.documentUrl .toLowerCase() .endsWith(".pdf") ? (