Files
sitemente/app/mission-control/pdf-viewer/page.tsx
T
horus 6c605a5391 fix(pdf-viewer): fix Cloudflare blocking iframe content
- For uploaded PDFs: Show download/open buttons instead of iframe
- For URL PDFs: Use Google Docs viewer
- Works around Cloudflare's content blocking
2026-03-23 20:42:53 +01:00

204 lines
7.0 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import BackToMC from "@/components/mission-control/BackToMC";
import { useState } from "react";
export default function PdfViewerPage() {
const [pdfData, setPdfData] = useState<string | null>(null);
const [pdfName, setPdfName] = useState<string>("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [viewMode, setViewMode] = useState<"embed" | "download">("embed");
const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file) return;
if (file.type !== "application/pdf") {
setError("Please select a PDF file");
return;
}
setLoading(true);
setError(null);
setPdfName(file.name);
const reader = new FileReader();
reader.onload = (event) => {
const base64 = event.target?.result as string;
setPdfData(base64);
setLoading(false);
};
reader.onerror = () => {
setError("Failed to read file");
setLoading(false);
};
reader.readAsDataURL(file);
};
const handleUrlSubmit = async () => {
const input = prompt("Enter PDF URL:");
if (!input) return;
setLoading(true);
setError(null);
try {
new URL(input);
// Use Google Docs viewer for external URLs
const googleViewerUrl = `https://docs.google.com/gview?url=${encodeURIComponent(input)}&embedded=true`;
setPdfData(googleViewerUrl);
setPdfName(input.split("/").pop() || "document.pdf");
setLoading(false);
} catch {
setError("Invalid URL");
setLoading(false);
}
};
const handleDownload = () => {
if (!pdfData) return;
const link = document.createElement("a");
link.href = pdfData;
link.download = pdfName || "document.pdf";
link.click();
};
return (
<div className="min-h-screen bg-slate-950 text-white flex flex-col">
{/* Header */}
<div className="bg-slate-900 border-b border-slate-800 px-6 py-4 flex-shrink-0">
<h1 className="text-2xl font-bold text-white">📄 PDF Viewer</h1>
<p className="text-slate-400 text-sm">View and analyze PDF documents</p>
</div>
{/* Toolbar */}
<div className="bg-slate-900/50 border-b border-slate-800 px-6 py-3 flex-shrink-0">
<div className="flex items-center gap-4 flex-wrap">
<label className="cursor-pointer bg-blue-600 hover:bg-blue-500 text-white px-4 py-2 rounded-lg text-sm font-medium transition-colors">
📁 Upload PDF
<input
type="file"
accept="application/pdf"
onChange={handleFileUpload}
className="hidden"
/>
</label>
<button
onClick={handleUrlSubmit}
className="bg-slate-700 hover:bg-slate-600 text-white px-4 py-2 rounded-lg text-sm font-medium transition-colors"
>
🔗 Load from URL
</button>
{pdfData && (
<>
<button
onClick={handleDownload}
className="bg-green-700 hover:bg-green-600 text-white px-4 py-2 rounded-lg text-sm font-medium transition-colors"
>
Download
</button>
{pdfData.startsWith("data:") && (
<a
href={pdfData}
target="_blank"
rel="noopener noreferrer"
className="bg-slate-700 hover:bg-slate-600 text-white px-4 py-2 rounded-lg text-sm font-medium transition-colors"
>
Open in New Tab
</a>
)}
</>
)}
</div>
</div>
{/* Content */}
<div className="flex-1 overflow-hidden flex flex-col">
{error && (
<div className="bg-red-900/50 border border-red-700 rounded-lg p-4 m-4 max-w-md">
<h3 className="text-red-400 font-bold mb-2">Error</h3>
<p className="text-red-300">{error}</p>
<button
onClick={() => setError(null)}
className="mt-2 bg-red-700 hover:bg-red-600 text-white px-4 py-1 rounded text-sm"
>
Dismiss
</button>
</div>
)}
{!pdfData && !loading && (
<div className="flex-1 flex items-center justify-center">
<div className="text-center">
<div className="text-8xl mb-6 opacity-50">📄</div>
<h2 className="text-xl font-bold text-white mb-2">No PDF Loaded</h2>
<p className="text-slate-400 mb-6">Upload a PDF or enter a URL to view it</p>
<div className="text-slate-500 text-sm space-y-1">
<p> Upload your resume to let Horus analyze it</p>
<p> Supports PDF files up to 50MB</p>
<p> Or load from any public PDF URL</p>
</div>
</div>
</div>
)}
{loading && (
<div className="flex-1 flex items-center justify-center">
<div className="text-center">
<div className="animate-spin text-6xl mb-4"></div>
<p className="text-slate-400">Loading PDF...</p>
</div>
</div>
)}
{pdfData && !loading && (
<div className="flex-1 overflow-auto bg-slate-800 p-4">
{pdfData.startsWith("data:") ? (
// For uploaded files, show download prompt since browser PDF rendering in iframe is blocked
<div className="flex flex-col items-center justify-center h-full">
<div className="text-8xl mb-6">📄</div>
<h2 className="text-xl font-bold text-white mb-2">{pdfName}</h2>
<p className="text-slate-400 mb-6">PDF loaded successfully</p>
<div className="flex gap-4">
<button
onClick={handleDownload}
className="bg-blue-600 hover:bg-blue-500 text-white px-6 py-3 rounded-lg font-medium"
>
Download PDF
</button>
<a
href={pdfData}
target="_blank"
rel="noopener noreferrer"
className="bg-slate-700 hover:bg-slate-600 text-white px-6 py-3 rounded-lg font-medium"
>
Open in New Tab
</a>
</div>
</div>
) : (
// For external URLs, use Google Docs viewer
<iframe
src={pdfData}
className="w-full h-full min-h-[700px] bg-white shadow-2xl rounded"
title="PDF Viewer"
/>
)}
</div>
)}
</div>
{/* Instructions */}
<div className="bg-slate-900/50 border-t border-slate-800 px-6 py-2 flex-shrink-0">
<p className="text-slate-500 text-xs">
💡 Tip: Upload your resume PDF and Horus can analyze the design to recreate it
</p>
</div>
</div>
);
}