import React, { useState, useEffect } from 'react'; import { getAuthToken } from '../../config/api'; import { buildResourceUrl } from '../../utils/url'; interface AuthenticatedImageProps extends React.ImgHTMLAttributes { src: string; fallbackSrc?: string; useWatermark?: boolean; isGallery?: boolean; } export const AuthenticatedImage: React.FC = ({ src, fallbackSrc, alt, useWatermark = false, isGallery = false, ...props }) => { const [imageSrc, setImageSrc] = useState(''); const [error, setError] = useState(false); const [isLoading, setIsLoading] = useState(true); useEffect(() => { let objectUrl: string | null = null; // Determine which token to use based on context let token: string | undefined; if (isGallery) { // For gallery images, get the gallery-specific token const pathParts = window.location.pathname.split('/'); if (pathParts[1] === 'gallery' && pathParts[2]) { const gallerySlug = pathParts[2]; token = localStorage.getItem(`gallery_token_${gallerySlug}`) || undefined; } } else { // For admin images, use the admin token token = getAuthToken(true); } if (!src) { setImageSrc(fallbackSrc || ''); setIsLoading(false); return; } if (!token) { console.warn('No auth token found for image:', src); setImageSrc(fallbackSrc || ''); setIsLoading(false); return; } setIsLoading(true); setError(false); // Create a new URL with auth header const fetchImage = async () => { try { // Use the src as-is since it should already be the correct endpoint let imageUrl = src; // Build full URL for the image const fullImageUrl = imageUrl.startsWith('/') ? buildResourceUrl(imageUrl) : imageUrl; console.log('Fetching authenticated image:', fullImageUrl); const response = await fetch(fullImageUrl, { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error(`Failed to fetch image: ${response.status} ${response.statusText}`); } const blob = await response.blob(); objectUrl = URL.createObjectURL(blob); setImageSrc(objectUrl); setIsLoading(false); } catch (err) { console.error('Failed to load image:', src, err); setError(true); setImageSrc(fallbackSrc || ''); setIsLoading(false); } }; fetchImage(); // Cleanup function return () => { if (objectUrl) { URL.revokeObjectURL(objectUrl); } }; }, [src, fallbackSrc, useWatermark, isGallery]); if (isLoading) { return (
{/* Show a placeholder while loading */}
); } if (error && fallbackSrc) { return {alt}; } if (!imageSrc) { return null; } return {alt}; };