import { useState, useRef, useEffect } from "react"; import { cn } from "@/lib/utils"; interface LazyImageProps { src: string; alt: string; className?: string; placeholder?: string; onLoad?: () => void; onError?: () => void; } export default function LazyImage({ src, alt, className, placeholder = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjQwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2YzZjRmNiIvPgo8dGV4dCB4PSI1MCUiIHk9IjUwJSIgZm9udC1zaXplPSIxOCIgZmlsbD0iIzlDQTNCRiIgZHk9Ii4zZW0iIHRleHQtYW5jaG9yPSJtaWRkbGUiPkxvYWRpbmcuLi48L3RleHQ+Cjwvc3ZnPg==", onLoad, onError }: LazyImageProps) { const [isLoaded, setIsLoaded] = useState(false); const [isInView, setIsInView] = useState(false); const [hasError, setHasError] = useState(false); const imgRef = useRef(null); useEffect(() => { const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { setIsInView(true); observer.disconnect(); } }, { threshold: 0.1, rootMargin: '50px' } ); if (imgRef.current) { observer.observe(imgRef.current); } return () => observer.disconnect(); }, []); const handleLoad = () => { setIsLoaded(true); onLoad?.(); }; const handleError = () => { setHasError(true); onError?.(); }; return (
{alt}
); }