AIEXTRACT1 / frontend /src /components /ocr /ProcessingStatus.jsx
Seth0330's picture
Update frontend/src/components/ocr/ProcessingStatus.jsx
4ab93a6 verified
import React from "react";
import { motion } from "framer-motion";
import {
FileSearch,
Cpu,
TableProperties,
CheckCircle2,
Loader2,
} from "lucide-react";
import { cn } from "@/lib/utils";
const steps = [
{ id: "upload", label: "Received", icon: FileSearch },
{ id: "analyze", label: "Analysis", icon: Cpu },
{ id: "extract", label: "Extraction", icon: TableProperties },
{ id: "complete", label: "Done", icon: CheckCircle2 },
];
export default function ProcessingStatus({ isProcessing, isComplete }) {
const getCurrentStep = () => {
if (isComplete) return 4;
if (isProcessing) return 2;
return 0;
};
const currentStep = getCurrentStep();
if (!isProcessing && !isComplete) return null;
return (
<motion.div
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
className="bg-white rounded-xl border border-slate-200 px-4 py-3"
>
<div className="flex items-center justify-between gap-2">
{steps.map((step, index) => {
const isActive = index + 1 === currentStep;
const isCompleted = index + 1 < currentStep || isComplete;
const Icon = step.icon;
return (
<React.Fragment key={step.id}>
<div className="flex items-center gap-2">
<motion.div
initial={false}
animate={{
scale: (isActive && !isComplete) ? 1.05 : 1,
backgroundColor: isCompleted
? "rgb(16 185 129)"
: (isActive && !isComplete)
? "rgb(99 102 241)"
: "rgb(241 245 249)",
}}
className={cn(
"h-8 w-8 rounded-lg flex items-center justify-center transition-colors",
(isCompleted || isActive) && "shadow-md"
)}
style={{
boxShadow: (isActive && !isComplete)
? "0 4px 8px -2px rgba(99, 102, 241, 0.3)"
: isCompleted
? "0 4px 8px -2px rgba(16, 185, 129, 0.3)"
: "none",
}}
>
{(isActive && !isComplete) ? (
<motion.div
animate={{ rotate: 360 }}
transition={{ duration: 1.5, repeat: Infinity, ease: "linear" }}
>
<Loader2 className="h-4 w-4 text-white" />
</motion.div>
) : isCompleted ? (
<CheckCircle2 className="h-4 w-4 text-white" />
) : (
<Icon className={cn("h-4 w-4 text-slate-400")} />
)}
</motion.div>
<span
className={cn(
"text-xs font-medium hidden sm:inline",
isActive ? "text-indigo-600" : isCompleted ? "text-emerald-600" : "text-slate-400"
)}
>
{step.label}
</span>
</div>
{index < steps.length - 1 && (
<div className="flex-1 h-0.5 mx-1 relative overflow-hidden rounded-full bg-slate-100">
<motion.div
initial={{ width: 0 }}
animate={{
width: isCompleted ? "100%" : isActive ? "50%" : "0%",
}}
transition={{ duration: 0.5 }}
className={cn(
"absolute inset-y-0 left-0",
isCompleted ? "bg-emerald-500" : "bg-indigo-500"
)}
/>
</div>
)}
</React.Fragment>
);
})}
</div>
</motion.div>
);
}