58 lines
1.4 KiB
TypeScript
58 lines
1.4 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { apiClient } from "@/lib/api/client";
|
|
import { ImageLightbox } from "./ImageLightbox";
|
|
|
|
interface AuthImageProps {
|
|
src: string;
|
|
alt?: string;
|
|
className?: string;
|
|
}
|
|
|
|
export function AuthImage({ src, alt, className }: AuthImageProps) {
|
|
const [blobUrl, setBlobUrl] = useState<string | null>(null);
|
|
const [lightboxOpen, setLightboxOpen] = useState(false);
|
|
|
|
useEffect(() => {
|
|
let objectUrl: string | null = null;
|
|
const path = src.replace(apiClient.defaults.baseURL ?? "", "");
|
|
apiClient
|
|
.get(path, { responseType: "blob" })
|
|
.then((res) => {
|
|
objectUrl = URL.createObjectURL(res.data);
|
|
setBlobUrl(objectUrl);
|
|
})
|
|
.catch(() => setBlobUrl(null));
|
|
|
|
return () => {
|
|
if (objectUrl) URL.revokeObjectURL(objectUrl);
|
|
};
|
|
}, [src]);
|
|
|
|
if (!blobUrl) {
|
|
return (
|
|
<div className={`bg-muted animate-pulse rounded ${className ?? "w-40 h-40"}`} />
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<img
|
|
src={blobUrl}
|
|
alt={alt || "이미지"}
|
|
className={`${className ?? ""} cursor-pointer`}
|
|
onClick={() => setLightboxOpen(true)}
|
|
/>
|
|
{lightboxOpen && (
|
|
<ImageLightbox
|
|
src={blobUrl}
|
|
alt={alt}
|
|
downloadHref={blobUrl}
|
|
onClose={() => setLightboxOpen(false)}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
}
|