feat: Improve avatar loading experience by displaying placeholders until images are fully loaded across various components.
This commit is contained in:
@@ -46,12 +46,18 @@ export function ProfileSettingsForm({
|
||||
});
|
||||
|
||||
const [avatarUrl, setAvatarUrl] = useState<string | null>(null);
|
||||
const [avatarLoaded, setAvatarLoaded] = useState(false);
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
const [uploadProgress, setUploadProgress] = useState(0);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
||||
// Reset avatar loaded state when URL changes (e.g., after upload)
|
||||
useEffect(() => {
|
||||
setAvatarLoaded(false);
|
||||
}, [avatarUrl]);
|
||||
|
||||
// Store original data for cancel/reset functionality
|
||||
const [originalData, setOriginalData] = useState<typeof formData | null>(null);
|
||||
// Track if initial profile fetch is done to avoid re-showing loading spinner
|
||||
@@ -382,20 +388,22 @@ export function ProfileSettingsForm({
|
||||
{/* Profile Photo Section */}
|
||||
<div className="mb-8">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-[60px] h-[60px] rounded-full overflow-hidden border border-[#00293D]/20 flex-shrink-0 bg-gray-100">
|
||||
{avatarUrl ? (
|
||||
<img
|
||||
src={avatarUrl}
|
||||
alt="Profile"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<div className="w-[60px] h-[60px] rounded-full overflow-hidden border border-[#00293D]/20 flex-shrink-0 bg-gray-100 relative">
|
||||
{(!avatarUrl || !avatarLoaded) && (
|
||||
<Image
|
||||
src="/assets/icons/user-placeholder-icon.svg"
|
||||
alt="Profile"
|
||||
width={60}
|
||||
height={60}
|
||||
className="w-full h-full object-cover"
|
||||
className="absolute inset-0 w-full h-full object-cover"
|
||||
/>
|
||||
)}
|
||||
{avatarUrl && (
|
||||
<img
|
||||
src={avatarUrl}
|
||||
alt="Profile"
|
||||
className={`absolute inset-0 w-full h-full object-cover transition-opacity duration-200 ${avatarLoaded ? 'opacity-100' : 'opacity-0'}`}
|
||||
onLoad={() => setAvatarLoaded(true)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user