File size: 4,207 Bytes
84820a1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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

import React, { useState, useEffect } from "react";
import { Loader2, CheckCircle2, Circle, Activity, Cpu, Scan, ShieldCheck, Binary, RefreshCw } from "lucide-react";
import GlassCard from "./GlassCard";

interface Step {
  label: string;
  icon: React.ReactNode;
}

interface ProcessingOverlayProps {
  isOpen: boolean;
  type: "diagnosis" | "segmentation";
}

const DIAGNOSIS_STEPS: Step[] = [
  { label: "Resizing Image", icon: <Scan className="w-5 h-5" /> },
  { label: "Input to Diagnosis mode", icon: <Cpu className="w-5 h-5" /> },
  { label: "Region identified", icon: <Activity className="w-5 h-5" /> },
  { label: "Status determined", icon: <ShieldCheck className="w-5 h-5" /> },
  { label: "Stage diagnosed", icon: <Binary className="w-5 h-5" /> },
];

const SEGMENTATION_STEPS: Step[] = [
  { label: "Image resizing", icon: <Scan className="w-5 h-5" /> },
  { label: "Input to model", icon: <Cpu className="w-5 h-5" /> },
  { label: "Reconstructing image and then segmenting cells", icon: <Activity className="w-5 h-5" /> },
  { label: "Lastly cleaning the mask", icon: <Binary className="w-5 h-5" /> },
];

const ProcessingOverlay: React.FC<ProcessingOverlayProps> = ({ isOpen, type }) => {
  const [currentStep, setCurrentStep] = useState(0);
  const steps = type === "diagnosis" ? DIAGNOSIS_STEPS : SEGMENTATION_STEPS;

  useEffect(() => {
    if (!isOpen) {
      setCurrentStep(0);
      return;
    }

    const interval = setInterval(() => {
      setCurrentStep((prev) => {
        if (prev < steps.length - 1) return prev + 1;
        return prev;
      });
    }, 2000); // Change step every 2 seconds

    return () => clearInterval(interval);
  }, [isOpen, steps.length]);

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-md animate-in fade-in duration-300">
      <GlassCard variant="bordered" className="w-full max-w-md p-8 flex flex-col items-center gap-8 shadow-2xl border-primary/20 bg-card/50">
        {/* Main Loader Icon */}
        <div className="relative">
          <div className="absolute inset-0 rounded-full bg-primary/20 animate-ping" />
          <div className="relative w-20 h-20 rounded-full bg-primary/10 flex items-center justify-center border border-primary/30">
            <Loader2 className="w-10 h-10 text-primary animate-spin" />
          </div>
        </div>

        <div className="text-center">
          <h2 className="text-2xl font-bold text-foreground mb-2">
            {type === "diagnosis" ? "Running Diagnosis" : "Generating Segmentation"}
          </h2>
          <p className="text-muted-foreground text-sm">
            Please wait while our AI models process your sample...
          </p>
        </div>

        {/* Steps List */}
        <div className="w-full flex flex-col gap-4">
          {steps.map((step, index) => {
            const isCompleted = index < currentStep;
            const isCurrent = index === currentStep;
            
            return (
              <div 
                key={index}
                className={`flex items-center gap-4 p-3 rounded-lg transition-all duration-500 ${
                  isCurrent ? "bg-primary/10 border border-primary/20 scale-105" : "opacity-50"
                } ${isCompleted ? "opacity-80" : ""}`}
              >
                <div className={`flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center ${
                  isCompleted ? "bg-success/20 text-success" : 
                  isCurrent ? "bg-primary/20 text-primary" : "bg-muted text-muted-foreground"
                }`}>
                  {isCompleted ? <CheckCircle2 className="w-5 h-5" /> : step.icon}
                </div>
                
                <div className="flex-1 text-left">
                  <p className={`font-medium ${isCurrent ? "text-primary" : "text-foreground"}`}>
                    {step.label}
                  </p>
                </div>

                {isCurrent && <Loader2 className="w-4 h-4 text-primary animate-spin" />}
              </div>
            );
          })}
        </div>
      </GlassCard>
    </div>
  );
};

export default ProcessingOverlay;