Files
Portfolio/src/components-vite/ImageWithFallback.tsx
T
damjan_savicandClaude Opus 4.5 b1ec7b4d61 Migrate from Vite to Next.js 15 with SSR
- Replace Vite + React Router with Next.js 15 App Router
- Implement i18n with next-intl (URL-based: /de, /en, /sr)
- Add SSR/SSG for all pages (48 static pages generated)
- Setup Supabase SSR client for auth
- Migrate all pages: Home, About, Portfolio, Blog, Contact, Login, Dashboard, Imprint, Privacy, Terms
- Add Docker support with standalone output
- Replace i18next with next-intl JSON translations
- Use next/image for optimized images

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 01:00:33 +01:00

62 lines
2.0 KiB
TypeScript

import { useState } from 'react';
import { ImageOff } from 'lucide-react';
declare module 'react' {
interface ImgHTMLAttributes<T> extends React.HTMLAttributes<T> {
fetchpriority?: 'high' | 'low' | 'auto';
}
}
interface ImageWithFallbackProps {
src: string;
alt: string;
className?: string;
sizes?: string;
loading?: 'lazy' | 'eager';
fetchpriority?: 'high' | 'low' | 'auto';
}
const ImageWithFallback: React.FC<ImageWithFallbackProps> = ({
src,
alt,
className = '',
sizes = '100vw',
loading = 'lazy',
fetchpriority = 'auto'
}) => {
const [error, setError] = useState(false);
const [isLoading, setIsLoading] = useState(true);
if (error) {
return (
<div className={`flex items-center justify-center bg-gray-900 ${className}`}>
<div className="text-center p-4">
<ImageOff className="h-8 w-8 mx-auto mb-2 text-gray-500" />
<span className="text-sm text-gray-500">{alt}</span>
</div>
</div>
);
}
return (
<div className="relative">
{isLoading && (
<div className={`absolute inset-0 bg-gray-900/50 animate-pulse ${className}`} />
)}
<img
src={src}
alt={alt}
className={`${className} ${isLoading ? 'opacity-0' : 'opacity-100'} transition-opacity duration-300`}
loading={loading}
fetchpriority={fetchpriority}
sizes={sizes}
onLoad={() => setIsLoading(false)}
onError={() => setError(true)}
decoding="async"
/>
</div>
);
};
export default ImageWithFallback;