77 lines
1.8 KiB
TypeScript
77 lines
1.8 KiB
TypeScript
import { cn } from "../lib/utils";
|
|
import placeholderImage from "../assets/icons/sellerPlaceholder.svg";
|
|
import placeholderImageDark from "../assets/icons/sellerPlaceholder-dark.svg";
|
|
import { useState, memo, useMemo, useCallback } from "react";
|
|
import { useRootData } from "~/hooks/use-root-data";
|
|
|
|
interface SellerLogoProps {
|
|
src?: string | null;
|
|
alt?: string;
|
|
className?: string;
|
|
size?: "sm" | "md" | "lg" | "xl";
|
|
}
|
|
|
|
const sizeClasses = {
|
|
sm: "w-8 h-8",
|
|
md: "w-12 h-12",
|
|
lg: "w-16 h-16",
|
|
xl: "w-20 h-20",
|
|
} as const;
|
|
|
|
const imageSizeClasses = {
|
|
sm: "w-6 h-6",
|
|
md: "w-8 h-8",
|
|
lg: "w-12 h-12",
|
|
xl: "w-16 h-16",
|
|
} as const;
|
|
|
|
const SellerLogo = memo(function SellerLogo({
|
|
src,
|
|
alt = "Seller Logo",
|
|
className,
|
|
size = "md",
|
|
}: SellerLogoProps) {
|
|
const { theme } = useRootData();
|
|
const [errorInDownload, setErrorInDownload] = useState(false);
|
|
|
|
const placeholder = useMemo(
|
|
() => (theme === "dark" ? placeholderImageDark : placeholderImage),
|
|
[theme]
|
|
);
|
|
|
|
const imageSrc = useMemo(
|
|
() => src || placeholder,
|
|
[src, placeholder]
|
|
);
|
|
|
|
const handleError = useCallback(
|
|
(e: React.SyntheticEvent<HTMLImageElement>) => {
|
|
e.currentTarget.src = placeholder;
|
|
setErrorInDownload(true);
|
|
},
|
|
[placeholder]
|
|
);
|
|
return (
|
|
<div
|
|
className={cn(
|
|
`rounded-full items-center justify-center flex ${!src || errorInDownload ? "border-GRAY2 border" : ""} object-cover shrink-0`,
|
|
sizeClasses[size]
|
|
)}
|
|
>
|
|
<img
|
|
src={imageSrc}
|
|
alt={alt}
|
|
loading="lazy"
|
|
className={cn(
|
|
"rounded-full object-cover shrink-0",
|
|
src && !errorInDownload ? sizeClasses[size] : imageSizeClasses[size],
|
|
className
|
|
)}
|
|
onError={handleError}
|
|
/>
|
|
</div>
|
|
);
|
|
});
|
|
|
|
export default SellerLogo;
|