File size: 2,658 Bytes
e6ce630
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { useEffect } from 'react';
import { Fancybox } from "@fancyapps/ui";
import "@fancyapps/ui/dist/fancybox/fancybox.css";

interface Image {
  url: string;
}

interface ImageCardProps {
  image: Image;
  batchImages: Image[];
  batchId: number;
  status?: 'pending' | 'error' | 'completed';
  width: number;
  height: number;
  elapsedTime: number;
}

export default function ImageCard({ image, batchImages, batchId, status, width, height, elapsedTime }: ImageCardProps) {
  useEffect(() => {
    Fancybox.bind(`[data-fancybox="gallery-${batchId}"]`, {
      contentClick: "iterateZoom",
      Images: {
        Panzoom: {
          maxScale: 8,
        },
      },
      Toolbar: {
        display: {
          left: ["infobar"],
          middle: [],
          right: ["iterateZoom", "fullscreen", "download", "thumbs", "close"],
        }
      },
      Thumbs: {
        type: "classic",
      },
    });

    return () => {
      Fancybox.destroy();
    };
  }, [batchId]);

  const aspectRatio = `${width} / ${height}`;

  return (
    <a
      href={image.url}
      data-fancybox={`gallery-${batchId}`}
      data-src={image.url}
      className="block relative"
      style={{ aspectRatio }}
    >
      <div
        className={`w-full h-full bg-center bg-no-repeat bg-cover rounded-xl cursor-pointer overflow-hidden ${
          status === 'pending' ? 'animate-pulse bg-gray-300 dark:bg-gray-700' : ''
        }`}
        style={status !== 'pending' ? {backgroundImage: `url("${image.url}")`} : {}}
      >
        {status === 'pending' && (
          <div className="absolute inset-0 flex items-center justify-center">
            <div className="relative w-16 h-16">
              <svg className="animate-spin h-16 w-16 text-primary" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
              </svg>
              <div className="absolute inset-0 flex items-center justify-center">
                <span className="text-primary font-bold">{elapsedTime.toFixed(1)}s</span>
              </div>
            </div>
          </div>
        )}
        {status === 'error' && (
          <div className="flex items-center justify-center h-full bg-red-200 dark:bg-red-900 rounded-xl">
            <span className="text-red-500 dark:text-red-300">Error</span>
          </div>
        )}
      </div>
    </a>
  );
}