"use client"; import { useCallback, useEffect, useRef, useState } from "react"; export type ImageLoadStatus = "loading" | "loaded" | "error"; export function useImageLoadStatus(src: string | undefined) { let [status, setStatus] = useState("loading"); let [attempt, setAttempt] = useState(0); let ref = useRef(null); useEffect(() => { if (!src) return; let img = ref.current; // A cached image can settle before the handlers attach if (img?.complete) setStatus(img.naturalWidth > 0 ? "loaded" : "error"); else setStatus("loading"); }, [src, attempt]); return { status, imgProps: { ref, onLoad: useCallback(() => setStatus("loaded"), []), onError: useCallback(() => setStatus("error"), []), }, reset: useCallback(() => { setStatus("loading"); setAttempt((a) => a + 1); }, []), }; } // `compact` drops the message for small surfaces like gallery thumbnails. export function ImageErrorState(props: { message: string; actionLabel: string; onAction: () => void; compact?: boolean; className?: string; }) { return (
{!props.compact && {props.message}}
); }