Update
This commit is contained in:
48
resources/js/components/ui/media-item.jsx
Normal file
48
resources/js/components/ui/media-item.jsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import { useState } from 'react';
|
||||
import { MediaItemSkeleton } from './media-item-skeleton';
|
||||
|
||||
const MediaItem = ({ src, alt, onClick, isSelected, className = "" }) => {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [hasError, setHasError] = useState(false);
|
||||
|
||||
const handleImageLoad = () => {
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
const handleImageError = () => {
|
||||
setIsLoading(false);
|
||||
setHasError(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`relative aspect-[9/16] w-full overflow-hidden rounded-lg bg-muted ${className}`}>
|
||||
{isLoading && (
|
||||
<div className="absolute inset-0 z-10">
|
||||
<MediaItemSkeleton />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{hasError ? (
|
||||
<div className="flex h-full w-full items-center justify-center bg-muted text-muted-foreground text-xs p-2 text-center">
|
||||
Failed to load
|
||||
</div>
|
||||
) : (
|
||||
<img
|
||||
src={src}
|
||||
alt={alt}
|
||||
className={`h-full w-full object-cover cursor-pointer transition-opacity duration-300 ${isLoading ? 'opacity-0' : 'opacity-100'}`}
|
||||
onLoad={handleImageLoad}
|
||||
onError={handleImageError}
|
||||
onClick={onClick}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Selection border overlay */}
|
||||
{isSelected && !isLoading && (
|
||||
<div className="absolute inset-0 rounded-lg ring-2 ring-blue-500 pointer-events-none" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { MediaItem };
|
||||
Reference in New Issue
Block a user