ImageCard.tsx 3.69 KB
import React, { useState } from 'react';
import { ImageItem } from '../types';
import { Download, Heart } from 'lucide-react';

interface ImageCardProps {
  image: ImageItem;
  onClick: (image: ImageItem) => void;
  onLike: (image: ImageItem) => void;
  currentUser?: string;
}

const ImageCard: React.FC<ImageCardProps> = ({ image, onClick, onLike, currentUser }) => {
  const [isLoaded, setIsLoaded] = useState(false);
  const [isHovered, setIsHovered] = useState(false);

  const handleLike = (e: React.MouseEvent) => {
    e.stopPropagation();
    onLike(image);
  };

  return (
    <div 
      className="group relative mb-4 break-inside-avoid rounded-2xl overflow-hidden bg-gray-200 cursor-zoom-in shadow-sm hover:shadow-xl transition-all duration-300"
      onClick={() => onClick(image)}
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => setIsHovered(false)}
    >
      {/* Placeholder / Skeleton */}
      {!isLoaded && (
        <div className="absolute inset-0 bg-gray-200 animate-pulse min-h-[200px]" />
      )}

      {/* Main Image */}
      <img
        src={image.url}
        alt={image.prompt}
        className={`w-full h-auto object-cover transition-transform duration-700 ease-in-out group-hover:scale-105 ${isLoaded ? 'opacity-100' : 'opacity-0'}`}
        onLoad={() => setIsLoaded(true)}
        loading="lazy"
      />

      {/* Hover Overlay */}
      <div className="absolute inset-0 bg-gradient-to-t from-black/90 via-black/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex flex-col justify-end p-4 md:p-5">
        
        {/* Top Right: Download */}
        <div className="absolute top-4 right-4 translate-y-[-10px] opacity-0 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-300 delay-75">
          <button 
            className="p-2 bg-white/20 backdrop-blur-md hover:bg-white/40 rounded-full text-white transition-colors"
            title="Download"
            onClick={(e) => {
              e.stopPropagation();
              const link = document.createElement('a');
              link.href = image.url;
              link.download = `z-image-${image.id}.png`;
              document.body.appendChild(link);
              link.click();
              document.body.removeChild(link);
            }}
          >
            <Download size={16} />
          </button>
        </div>

        {/* Content Info */}
        <div className="text-white transform translate-y-4 group-hover:translate-y-0 transition-transform duration-300">
          <p className="font-medium text-sm line-clamp-2 mb-2 text-shadow-sm">
            {image.prompt}
          </p>
          
          <div className="flex justify-between items-end">
             {/* Author Info */}
             <div className="text-xs text-gray-300 font-mono flex flex-col gap-1">
                <span className="opacity-75">ID: {image.authorId || 'UNKNOWN'}</span>
                <span className="bg-white/10 px-1.5 py-0.5 rounded w-fit">{image.width}x{image.height}</span>
             </div>

             {/* Like Button */}
             <button 
               onClick={handleLike}
               className={`flex items-center gap-1.5 px-3 py-1.5 rounded-full backdrop-blur-md transition-all duration-200 ${image.isLikedByCurrentUser ? 'bg-red-500/80 text-white' : 'bg-white/20 text-white hover:bg-white/30'}`}
               title={currentUser ? "Like this image" : "Login to like"}
             >
               <Heart size={14} fill={image.isLikedByCurrentUser ? "currentColor" : "none"} />
               <span className="text-xs font-bold">{image.likes}</span>
             </button>
          </div>
        </div>
      </div>
    </div>
  );
};

export default ImageCard;