📄 a couple updates
All checks were successful
Build and Deploy Next.js Blog to Production / 🔍 Code Quality Checks (push) Successful in 17s
Build and Deploy Next.js Blog to Production / 🏗️ Build and Push Docker Image (push) Successful in 30s
Build and Deploy Next.js Blog to Production / 🚀 Deploy to Production (push) Successful in 48s

This commit was merged in pull request #9.
This commit is contained in:
RJ
2025-12-02 17:57:31 +02:00
committed by Rares J
parent a4be3c5d93
commit 6e5d641c06
17 changed files with 335 additions and 294 deletions

View File

@@ -27,38 +27,44 @@ export function OptimizedImage({
if (hasError) {
return (
<div className="my-8 rounded-lg border border-zinc-800 bg-zinc-900/50 p-8 text-center">
<p className="text-zinc-400">Failed to load image</p>
{caption && <p className="mt-2 text-sm text-zinc-500">{caption}</p>}
</div>
<span className="block my-8 rounded-lg border border-zinc-800 bg-zinc-900/50 p-8 text-center">
<span className="block text-zinc-400">Failed to load image</span>
{caption && <span className="block mt-2 text-sm text-zinc-500">{caption}</span>}
</span>
)
}
return (
<figure className={`my-8 ${className}`}>
<div className="relative overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900/50">
<Image
src={src}
alt={alt}
width={width}
height={height}
priority={priority}
style={{ maxWidth: '100%', height: 'auto' }}
className={`transition-opacity duration-300 ${isLoading ? 'opacity-0' : 'opacity-100'}`}
onLoad={() => setIsLoading(false)}
onError={() => setHasError(true)}
placeholder="blur"
blurDataURL="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='300'%3E%3Crect width='400' height='300' fill='%2318181b'/%3E%3C/svg%3E"
/>
{isLoading && (
<div className="absolute inset-0 flex items-center justify-center">
<div className="h-8 w-8 animate-spin rounded-full border-2 border-emerald-500 border-t-transparent" />
</div>
)}
</div>
{caption && (
<figcaption className="mt-3 text-center text-sm text-zinc-400">{caption}</figcaption>
const imageElement = (
<span className="block relative overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900/50">
<Image
src={src}
alt={alt}
width={width}
height={height}
priority={priority}
style={{ maxWidth: '100%', height: 'auto' }}
className={`transition-opacity duration-300 ${isLoading ? 'opacity-0' : 'opacity-100'}`}
onLoad={() => setIsLoading(false)}
onError={() => setHasError(true)}
placeholder="blur"
blurDataURL="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='300'%3E%3Crect width='400' height='300' fill='%2318181b'/%3E%3C/svg%3E"
/>
{isLoading && (
<span className="absolute inset-0 flex items-center justify-center">
<span className="block h-8 w-8 animate-spin rounded-full border-2 border-emerald-500 border-t-transparent" />
</span>
)}
</figure>
</span>
)
// Always use <span> to avoid invalid HTML nesting in <p> tags
// This prevents hydration mismatches between server and client
return (
<span className={`block my-8 ${className}`}>
{imageElement}
{caption && (
<span className="block mt-3 text-center text-sm text-zinc-400">{caption}</span>
)}
</span>
)
}