feat: Implement useImageStatus hook and enhance image loading status handling across various components to address cached images and loading timeouts.

This commit is contained in:
pradeepkumar
2026-03-18 11:54:40 +05:30
parent f3c4e31924
commit 772e1024cc
17 changed files with 211 additions and 93 deletions

View File

@@ -41,6 +41,7 @@ export function ConnectionCard({
)}
{avatar && !isPlaceholder && (
<img
ref={(el) => { if (el?.complete && el.naturalWidth > 0) setAvatarLoaded(true); }}
src={avatar}
alt={name}
className={`absolute inset-0 w-full h-full object-cover rounded-full transition-opacity duration-300 ${avatarLoaded ? 'opacity-100' : 'opacity-0'}`}

View File

@@ -55,6 +55,7 @@ export function InvitationCard({
)}
{avatar && !isPlaceholder && (
<img
ref={(el) => { if (el?.complete && el.naturalWidth > 0) setAvatarLoaded(true); }}
src={avatar}
alt={name}
className={`absolute inset-0 w-full h-full object-cover rounded-full transition-opacity duration-300 ${avatarLoaded ? 'opacity-100' : 'opacity-0'}`}

View File

@@ -1,6 +1,6 @@
'use client';
import { useState } from 'react';
import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { signIn } from 'next-auth/react';
import Link from 'next/link';
@@ -15,6 +15,12 @@ export default function LoginPage() {
const [loading, setLoading] = useState(false);
const [userType, setUserType] = useState<'USER' | 'ADMIN'>('USER');
// Clear logout flags on mount so API calls aren't blocked after redirect from logout
useEffect(() => {
localStorage.removeItem('isLoggingOut');
resetLogoutState();
}, []);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);

View File

@@ -291,6 +291,7 @@ export default function AgentProfileView() {
)}
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
ref={(el) => { if (el?.complete) { if (el.naturalWidth > 0) setImageLoaded(true); else setImageError(true); } }}
src={getProfileImageUrl()!}
alt="Profile"
className={`w-full h-full object-cover transition-opacity duration-300 ${imageLoaded ? 'opacity-100' : 'opacity-0'}`}

View File

@@ -77,6 +77,7 @@ function ProfileImage({ src, alt, className }: { src: string | null; alt: string
{src && status !== 'error' ? (
/* eslint-disable-next-line @next/next/no-img-element */
<img
ref={(el) => { if (el?.complete) setStatus(el.naturalWidth > 0 ? 'loaded' : 'error'); }}
src={src}
alt={alt}
className={`w-full h-full object-cover transition-opacity duration-300 ${status === 'loaded' ? 'opacity-100' : 'opacity-0'}`}

View File

@@ -360,6 +360,7 @@ function SmartImage({
)}
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
ref={(el) => { if (el?.complete) setStatus(el.naturalWidth > 0 ? 'loaded' : 'error'); }}
src={src}
alt={alt}
className={`${className || ''} transition-opacity duration-300 ${status === 'loaded' ? 'opacity-100' : 'opacity-0'}`}
@@ -393,6 +394,7 @@ function FeatureCard({ feature }: { feature: AboutFeaturesContent['features'][nu
{feature.iconPath && iconStatus !== 'error' && (
/* eslint-disable-next-line @next/next/no-img-element */
<img
ref={(el) => { if (el?.complete) setIconStatus(el.naturalWidth > 0 ? 'loaded' : 'error'); }}
src={feature.iconPath}
alt=""
className={`w-[35px] h-[35px] object-contain transition-opacity duration-300 ${iconStatus === 'loaded' ? 'opacity-100' : 'opacity-0'}`}
@@ -434,6 +436,7 @@ function TeamCard({ member }: { member: AboutTeamContent['members'][number] }) {
{member.imageUrl && imgStatus !== 'error' && (
/* eslint-disable-next-line @next/next/no-img-element */
<img
ref={(el) => { if (el?.complete) setImgStatus(el.naturalWidth > 0 ? 'loaded' : 'error'); }}
src={member.imageUrl}
alt={member.name}
className={`w-full h-full object-cover transition-opacity duration-300 ${imgStatus === 'loaded' ? 'opacity-100' : 'opacity-0'}`}

View File

@@ -35,6 +35,9 @@ export default function LogoutPage() {
// Delete cookies again after signOut in case signOut recreated any
await clearAuthCookies();
// Clear the logout flag before redirecting so it doesn't block API calls on public pages
localStorage.removeItem('isLoggingOut');
// Redirect to login immediately
window.location.href = '/login';
};