Spaces:
Sleeping
Sleeping
File size: 5,989 Bytes
525e60d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
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>
);
}
|