Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 3x 10x 10x 10x 10x 5x 5x 5x 5x 5x 5x 10x 10x 5x 5x 5x | import { useEffect, useState } from "react";
import { roomToIllustrationMap } from "~/utils/constants";
import { getFigure } from "~/utils/getFigure";
export const RoomIllustration = ({ roomName }: { roomName?: string }) => {
const [src, setSrc] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [hasError, setHasError] = useState(false);
useEffect(() => {
setIsLoading(true);
setHasError(false);
const loader = getFigure(roomToIllustrationMap, roomName);
loader()
.then((mod) => {
setSrc(mod.default);
setIsLoading(false);
})
.catch(() => {
setHasError(true);
setIsLoading(false);
});
}, [roomName]);
const roomDisplayName = roomName || "Room";
if (isLoading) {
return (
<div
className="w-full md:h-44 h-30 bg-gray-100 rounded-full animate-pulse"
role="img"
aria-label={`Loading illustration for ${roomDisplayName}`}
aria-live="polite"
/>
);
}
if I(hasError || !src) {
return (
<div
className="w-full md:h-44 h-30 bg-gray-100 rounded-lg flex items-center justify-center"
role="img"
aria-label={`Illustration not available for ${roomDisplayName}`}
>
<span className="text-gray-500 text-sm sr-only">
Image could not be loaded
</span>
</div>
);
}
return (
<figure className="flex justify-center" role="img">
<img
className="md:w-full w-44 md:h-52 h-full object-cover rounded-lg select-none"
src={src}
alt={`Illustration of ${roomDisplayName}`}
draggable={false}
data-cy={`room-illustration-${roomName}`}
onError={() => setHasError(true)}
loading="lazy"
/>
<figcaption
id={`room-illustration-caption-${roomName}`}
className="sr-only"
>
Visual representation of {roomDisplayName}
</figcaption>
</figure>
);
};
|