feat: Implement S3 avatar resolution for network connections, refine messaging initial conversation selection, and adjust profile display logic and header navigation.

This commit is contained in:
pradeepkumar
2026-03-19 16:37:24 +05:30
parent 94b7577234
commit 26dc563a49
4 changed files with 52 additions and 17 deletions

View File

@@ -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<string | null>(null);
const [processingIds, setProcessingIds] = useState<Set<string>>(new Set());
const [avatarUrls, setAvatarUrls] = useState<Record<string, string>>({});
// 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<string, string> = {};
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 (
<InvitationCard
key={request.id}
id={request.id}
name={userName}
avatar={profile?.avatar || request.user?.avatar || '/assets/icons/user-placeholder-icon.svg'}
avatar={resolvedAvatar || '/assets/icons/user-placeholder-icon.svg'}
description={request.message || 'No message provided'}
createdAt={request.createdAt}
isProcessing={processingIds.has(request.id)}
@@ -252,12 +283,14 @@ export default function NetworkPage() {
{connections.map((connection) => {
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 (
<ConnectionCard
key={connection.id}
id={connection.userId}
name={userName}
avatar={profile?.avatar || connection.user?.avatar || '/assets/icons/user-placeholder-icon.svg'}
avatar={resolvedAvatar || '/assets/icons/user-placeholder-icon.svg'}
email={connection.user?.email || ''}
connectedAt={connection.respondedAt || connection.updatedAt}
onMessage={handleMessage}