feat: Improve avatar loading experience by displaying placeholders until images are fully loaded across various components.

This commit is contained in:
pradeepkumar
2026-03-13 22:45:11 +05:30
parent b339dd865c
commit 7b5c670159
11 changed files with 225 additions and 80 deletions

View File

@@ -50,6 +50,14 @@ export function ProfileCard({
const router = useRouter();
const pathname = usePathname();
const [isUnlinking, setIsUnlinking] = useState(false);
const [showLocationModal, setShowLocationModal] = useState(false);
// Split location into parts and limit display
const locationParts = location.split(',').map(s => s.trim()).filter(Boolean);
const maxVisibleLocations = 4;
const visibleLocations = locationParts.slice(0, maxVisibleLocations).join(', ');
const hasMoreLocations = locationParts.length > maxVisibleLocations;
const remainingCount = locationParts.length - maxVisibleLocations;
// Handle unlink click
const handleUnlinkClick = async () => {
@@ -113,26 +121,35 @@ export function ProfileCard({
)}
</div>
<p className="text-[#00293d] text-sm mb-2 font-fractul">{title}</p>
<div className="flex items-center justify-center lg:justify-start gap-4 text-sm text-[#00293d] font-fractul">
<div className="flex flex-wrap items-center justify-center lg:justify-start gap-x-4 gap-y-1 text-sm text-[#00293d] font-fractul">
<span className="flex items-center gap-1">
<Image
src="/assets/icons/location-pin-icon.svg"
alt="Location"
width={21}
height={19}
className="flex-shrink-0"
/>
<span className="text-[14px] font-bold text-[#00293D] font-serif leading-[19px]">
{location}
{visibleLocations}
{hasMoreLocations && (
<button
onClick={() => setShowLocationModal(true)}
className="ml-1 text-[#e58625] hover:underline cursor-pointer"
>
+{remainingCount} more
</button>
)}
</span>
</span>
<span className="flex items-center gap-1">
<span className="flex items-center gap-1 flex-shrink-0">
<Image
src="/assets/icons/calendar-icon.svg"
alt="Calendar"
width={23}
height={21}
/>
<span className="text-[13px] font-medium text-[#00293D] font-serif leading-[18px]">
<span className="text-[13px] font-medium text-[#00293D] font-serif leading-[18px] whitespace-nowrap">
Member Since {memberSince}
</span>
</span>
@@ -260,6 +277,33 @@ export function ProfileCard({
))}
</div>
</div>
{/* Location Modal */}
{showLocationModal && (
<div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4" onClick={() => setShowLocationModal(false)}>
<div className="bg-white rounded-[20px] p-6 max-w-[400px] w-full max-h-[80vh] overflow-y-auto" onClick={e => e.stopPropagation()}>
<div className="flex items-center justify-between mb-4">
<h3 className="font-fractul font-bold text-[18px] text-[#00293D]">Service Areas</h3>
<button
onClick={() => setShowLocationModal(false)}
className="text-[#00293D]/50 hover:text-[#00293D] text-[20px] leading-none cursor-pointer"
>
&times;
</button>
</div>
<div className="flex flex-wrap gap-2">
{locationParts.map((loc, idx) => (
<span
key={idx}
className="px-3 py-1.5 bg-[#e8e8e8] rounded-[10px] text-[13px] font-serif text-[#00293D]"
>
{loc}
</span>
))}
</div>
</div>
</div>
)}
</div>
);
}