From 26dc563a496a74d7edb0868e51db80480e05f7bd Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Thu, 19 Mar 2026 16:37:24 +0530 Subject: [PATCH] feat: Implement S3 avatar resolution for network connections, refine messaging initial conversation selection, and adjust profile display logic and header navigation. --- src/app/(agent)/agent/network/page.tsx | 39 ++++++++++++++++++++++-- src/app/(user)/user/profiles/page.tsx | 18 ++++++----- src/components/layout/CommonHeader.tsx | 6 ++-- src/components/message/MessagingPage.tsx | 6 ++-- 4 files changed, 52 insertions(+), 17 deletions(-) diff --git a/src/app/(agent)/agent/network/page.tsx b/src/app/(agent)/agent/network/page.tsx index 9616433..397dbfd 100644 --- a/src/app/(agent)/agent/network/page.tsx +++ b/src/app/(agent)/agent/network/page.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState, useEffect } from 'react'; +import { useState, useEffect, useCallback } from 'react'; import Image from 'next/image'; import { useRouter } from 'next/navigation'; import { NetworkSidebar } from './component/NetworkSidebar'; @@ -8,6 +8,7 @@ import { InvitationCard } from './component/InvitationCard'; import { ConnectionCard } from './component/ConnectionCard'; import { connectionRequestsService, ConnectionRequest, ConnectionRequestCounts } from '@/services/connection-requests.service'; import { messagesService } from '@/services/messages.service'; +import { uploadService } from '@/services/upload.service'; export default function NetworkPage() { const router = useRouter(); @@ -17,6 +18,31 @@ export default function NetworkPage() { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [processingIds, setProcessingIds] = useState>(new Set()); + const [avatarUrls, setAvatarUrls] = useState>({}); + + // Helper to check if a string is an S3 key (not a URL or local path) + const isS3Key = (value: string | null | undefined): boolean => { + if (!value) return false; + return !value.startsWith('http') && !value.startsWith('/') && !value.startsWith('data:'); + }; + + // Resolve S3 avatar keys to presigned URLs + const resolveAvatars = useCallback(async (requests: ConnectionRequest[]) => { + const newUrls: Record = {}; + for (const req of requests) { + const avatar = req.user?.userProfile?.avatar || req.user?.avatar; + if (avatar && isS3Key(avatar) && !avatarUrls[req.id]) { + try { + newUrls[req.id] = await uploadService.getPresignedDownloadUrl(avatar); + } catch { + // Keep empty, will show placeholder + } + } + } + if (Object.keys(newUrls).length > 0) { + setAvatarUrls(prev => ({ ...prev, ...newUrls })); + } + }, [avatarUrls]); // Fetch connection requests on mount useEffect(() => { @@ -38,6 +64,9 @@ export default function NetworkPage() { setPendingRequests(pending); setConnections(accepted); setCounts(requestCounts); + + // Resolve avatars for all requests + resolveAvatars([...pending, ...accepted]); } catch (err) { console.error('Failed to fetch connection requests:', err); setError('Failed to load connection requests'); @@ -198,12 +227,14 @@ export default function NetworkPage() { {pendingRequests.map((request) => { const profile = request.user?.userProfile; const userName = [profile?.firstName, profile?.lastName].filter(Boolean).join(' ') || request.user?.email || 'Unknown User'; + const rawAvatar = profile?.avatar || request.user?.avatar; + const resolvedAvatar = avatarUrls[request.id] || (rawAvatar && !isS3Key(rawAvatar) ? rawAvatar : null); return ( { const profile = connection.user?.userProfile; const userName = [profile?.firstName, profile?.lastName].filter(Boolean).join(' ') || connection.user?.email || 'Unknown User'; + const rawAvatar = profile?.avatar || connection.user?.avatar; + const resolvedAvatar = avatarUrls[connection.id] || (rawAvatar && !isS3Key(rawAvatar) ? rawAvatar : null); return ( 200 - ? description.slice(0, 200) + '...' + const maxDescLength = 150; + const truncatedDescription = description && description.length > maxDescLength + ? description.slice(0, maxDescLength) + '...' : description || ''; + const INITIAL_TAG_COUNT = 6; return ( -
+
{/* Profile Image & View Profile Button */}

{showFullBio ? description : truncatedDescription} - {description.length > 200 && ( + {description.length > maxDescLength && ( <> {' '} )}

diff --git a/src/components/layout/CommonHeader.tsx b/src/components/layout/CommonHeader.tsx index 068ed8c..00ff71d 100644 --- a/src/components/layout/CommonHeader.tsx +++ b/src/components/layout/CommonHeader.tsx @@ -57,7 +57,7 @@ export function CommonHeader() { return (
-
+
{/* Logo */} - {/* Navigation - Desktop only */} -