imagine / components /Gallery /ImageCard.tsx
github-actions[bot]
GitHub deploy: 8ac466cec7cb18a3cdc40223ab11ee9b5f5f569b
e6ce630
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>
);
}