AIEXTRACT1 / frontend /src /components /ocr /DocumentPreview.jsx
Seth0330's picture
Create frontend/src/components/ocr/DocumentPreview.jsx
525e60d verified
raw
history blame
5.99 kB
import React from "react";
import { motion } from "framer-motion";
import { FileText, ZoomIn, ZoomOut, RotateCw, Maximize2 } from "lucide-react";
import { Button } from "@/components/ui/button";
export default function DocumentPreview({ file, isProcessing }) {
// Mock preview - in real app would show actual document
const mockPages = [1, 2, 3];
return (
<div className="h-full flex flex-col bg-white rounded-2xl border border-slate-200 overflow-hidden">
{/* Header */}
<div className="flex items-center justify-between px-5 py-4 border-b border-slate-100">
<div className="flex items-center gap-3">
<div className="h-8 w-8 rounded-lg bg-indigo-50 flex items-center justify-center">
<FileText className="h-4 w-4 text-indigo-600" />
</div>
<div>
<h3 className="font-semibold text-slate-800 text-sm">Document Preview</h3>
<p className="text-xs text-slate-400">{file?.name || "No file selected"}</p>
</div>
</div>
{file && (
<div className="flex items-center gap-1">
<Button
variant="ghost"
size="icon"
className="h-8 w-8 text-slate-400 hover:text-slate-600"
>
<ZoomOut className="h-4 w-4" />
</Button>
<span className="text-xs text-slate-500 w-12 text-center">100%</span>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 text-slate-400 hover:text-slate-600"
>
<ZoomIn className="h-4 w-4" />
</Button>
<div className="w-px h-4 bg-slate-200 mx-2" />
<Button
variant="ghost"
size="icon"
className="h-8 w-8 text-slate-400 hover:text-slate-600"
>
<RotateCw className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 text-slate-400 hover:text-slate-600"
>
<Maximize2 className="h-4 w-4" />
</Button>
</div>
)}
</div>
{/* Preview Area */}
<div className="flex-1 p-6 bg-slate-50/50 overflow-auto">
{!file ? (
<div className="h-full flex items-center justify-center">
<div className="text-center">
<div className="h-20 w-20 mx-auto rounded-2xl bg-slate-100 flex items-center justify-center mb-4">
<FileText className="h-10 w-10 text-slate-300" />
</div>
<p className="text-slate-400 text-sm">Upload a document to preview</p>
</div>
</div>
) : (
<div className="space-y-4">
{mockPages.map((page, index) => (
<motion.div
key={page}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.1 }}
className="relative bg-white rounded-xl shadow-sm border border-slate-200 aspect-[8.5/11] overflow-hidden"
>
{/* Mock document content */}
<div className="absolute inset-0 p-8">
{/* Header simulation */}
<div className="flex items-center gap-4 mb-8">
<div className="h-12 w-12 rounded-lg bg-slate-100" />
<div className="space-y-2">
<div className="h-3 w-32 bg-slate-100 rounded" />
<div className="h-2 w-24 bg-slate-50 rounded" />
</div>
</div>
{/* Text lines simulation */}
<div className="space-y-3">
{[...Array(12)].map((_, i) => (
<div
key={i}
className="h-2 bg-slate-100 rounded"
style={{ width: `${Math.random() * 40 + 60}%` }}
/>
))}
</div>
{/* Table simulation */}
<div className="mt-6 border border-slate-100 rounded-lg overflow-hidden">
{[...Array(4)].map((_, i) => (
<div key={i} className="flex border-b border-slate-50 last:border-0">
{[...Array(3)].map((_, j) => (
<div
key={j}
className="flex-1 p-3 border-r border-slate-50 last:border-0"
>
<div className="h-2 bg-slate-100 rounded w-3/4" />
</div>
))}
</div>
))}
</div>
</div>
{/* Processing overlay */}
{isProcessing && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
className="absolute inset-0 bg-indigo-600/5 backdrop-blur-[1px]"
>
<motion.div
initial={{ top: 0 }}
animate={{ top: "100%" }}
transition={{
duration: 2,
repeat: Infinity,
ease: "linear",
}}
className="absolute left-0 right-0 h-1 bg-gradient-to-r from-transparent via-indigo-500 to-transparent"
/>
</motion.div>
)}
{/* Page number */}
<div className="absolute bottom-3 right-3 text-xs text-slate-400 bg-white/90 px-2 py-1 rounded">
Page {page}
</div>
</motion.div>
))}
</div>
)}
</div>
</div>
);
}