File size: 3,881 Bytes
ee0b401
 
 
 
 
 
 
 
 
 
 
 
4ab93a6
 
 
 
ee0b401
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4ab93a6
ee0b401
4ab93a6
ee0b401
 
4ab93a6
ee0b401
 
 
 
4ab93a6
ee0b401
 
 
4ab93a6
ee0b401
 
4ab93a6
ee0b401
 
 
 
4ab93a6
 
ee0b401
 
4ab93a6
 
ee0b401
4ab93a6
ee0b401
 
 
4ab93a6
ee0b401
 
4ab93a6
ee0b401
4ab93a6
ee0b401
4ab93a6
 
ee0b401
4ab93a6
ee0b401
 
 
 
4ab93a6
 
ee0b401
 
 
 
 
 
 
4ab93a6
ee0b401
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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>
  );
}