File size: 2,893 Bytes
5da4770
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import React, { useState, useEffect } from 'react';
import { Loader2, LucideIcon } from 'lucide-react';
import { cn } from '@/lib/utils';
import { Progress } from '@/components/ui/progress';

interface LoadingStateProps {
  icon?: LucideIcon;
  iconColor?: string;
  bgColor?: string;
  title: string;
  subtitle?: string;
  filePath?: string | null;
  showProgress?: boolean;
  progressText?: string;
  autoProgress?: boolean;
  initialProgress?: number;
}

export function LoadingState({
  icon: Icon = Loader2,
  iconColor = 'text-purple-500 dark:text-purple-400',
  bgColor = 'bg-gradient-to-b from-purple-100 to-purple-50 shadow-inner dark:from-purple-800/40 dark:to-purple-900/60 dark:shadow-purple-950/20',
  title,
  subtitle,
  filePath,
  showProgress = true,
  progressText,
  autoProgress = true,
  initialProgress = 0,
}: LoadingStateProps): JSX.Element {
  const [progress, setProgress] = useState(initialProgress);

  useEffect(() => {
    if (showProgress && autoProgress) {
      setProgress(0);
      const timer = setInterval(() => {
        setProgress((prevProgress) => {
          if (prevProgress >= 95) {
            clearInterval(timer);
            return prevProgress;
          }
          return prevProgress + Math.random() * 10 + 5;
        });
      }, 500);
      return () => clearInterval(timer);
    }
  }, [showProgress, autoProgress]);
  return (
    <div className="flex flex-col items-center justify-center h-[calc(100vh-15rem)] overflow-hidden scrollbar-hide py-12 px-6">
      <div className="text-center w-full max-w-sm">
        <div className={cn("w-16 h-16 rounded-full mx-auto mb-6 flex items-center justify-center", bgColor)}>
          <Icon className={cn("h-8 w-8", iconColor, Icon === Loader2 && "animate-spin")} />
        </div>
        
        <h3 className="text-xl font-semibold mb-4 text-zinc-900 dark:text-zinc-100">
          {title}
        </h3>
        
        {filePath && (
          <div className="bg-zinc-50 dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-lg p-4 w-full text-center mb-6 shadow-sm">
            <code className="text-sm font-mono text-zinc-700 dark:text-zinc-300 break-all">
              {filePath}
            </code>
          </div>
        )}
        
        {showProgress && (
          <div className="space-y-3">
            <Progress value={Math.min(progress, 100)} className="w-full h-1" />
            <div className="flex justify-between items-center text-xs text-zinc-500 dark:text-zinc-400">
              <span>{progressText || 'Processing...'}</span>
              <span className="font-mono">{Math.round(Math.min(progress, 100))}%</span>
            </div>
          </div>
        )}
        
        {subtitle && (
          <p className="text-sm text-zinc-500 dark:text-zinc-400 mt-4">
            {subtitle}
          </p>
        )}
      </div>
    </div>
  );
}