43 lines
999 B
TypeScript
43 lines
999 B
TypeScript
'use client';
|
|
|
|
import { useEffect, useRef } from 'react';
|
|
|
|
const PLACEHOLDER = '/images/product-placeholder.svg';
|
|
|
|
interface ProductImageProps {
|
|
src?: string | null;
|
|
alt: string;
|
|
className?: string;
|
|
width?: number;
|
|
height?: number;
|
|
loading?: 'lazy' | 'eager';
|
|
}
|
|
|
|
export function ProductImage({ src, alt, className, width, height, loading }: ProductImageProps) {
|
|
const hasErrored = useRef(false);
|
|
|
|
// Reset the loop guard whenever src changes (e.g. navigating between products)
|
|
useEffect(() => {
|
|
hasErrored.current = false;
|
|
}, [src]);
|
|
|
|
function handleError(e: React.SyntheticEvent<HTMLImageElement>) {
|
|
if (hasErrored.current) return;
|
|
hasErrored.current = true;
|
|
e.currentTarget.src = PLACEHOLDER;
|
|
}
|
|
|
|
return (
|
|
// eslint-disable-next-line @next/next/no-img-element
|
|
<img
|
|
src={src ?? PLACEHOLDER}
|
|
alt={alt}
|
|
className={className}
|
|
width={width}
|
|
height={height}
|
|
loading={loading}
|
|
onError={handleError}
|
|
/>
|
|
);
|
|
}
|