Files
buzz-sheet/components/public/media-image.tsx
T

56 lines
1.3 KiB
TypeScript

"use client";
import Image from "next/image";
import { ImageOffIcon } from "lucide-react";
import { useState } from "react";
import { cn } from "@/lib/utils";
interface MediaImageProps {
mediaId: string | null | undefined;
alt: string;
className?: string;
fit?: "cover" | "contain";
priority?: boolean;
}
export function MediaImage({
mediaId,
alt,
className,
fit = "cover",
priority = false,
}: MediaImageProps) {
const [failedId, setFailedId] = useState<string | null>(null);
const failed = !mediaId || failedId === mediaId;
return (
<div
className={cn(
"relative grid min-h-32 overflow-hidden bg-muted text-muted-foreground",
className,
)}
>
{failed ? (
<div className="grid place-items-center gap-2 p-6 text-center">
<ImageOffIcon aria-hidden="true" className="size-8 opacity-60" />
<span className="text-xs">ไม่มีภาพ</span>
</div>
) : (
<Image
src={`/media/${mediaId}`}
alt={alt}
fill
priority={priority}
unoptimized
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
className={cn(
fit === "cover" ? "object-cover" : "object-contain",
)}
onError={() => setFailedId(mediaId)}
/>
)}
</div>
);
}