feat: enable user profile avatar upload and display across header and settings.
This commit is contained in:
@@ -4,6 +4,8 @@ import { useState, useEffect, useRef } from 'react';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { useSession, signOut } from 'next-auth/react';
|
||||
import { agentsService } from '@/services/agents.service';
|
||||
import { uploadService } from '@/services/upload.service';
|
||||
|
||||
const navLinks = [
|
||||
{ label: 'Education', href: '/education' },
|
||||
@@ -15,6 +17,7 @@ export function CommonHeader() {
|
||||
const { data: session } = useSession();
|
||||
const [showProfileMenu, setShowProfileMenu] = useState(false);
|
||||
const profileMenuRef = useRef<HTMLDivElement>(null);
|
||||
const [profileImage, setProfileImage] = useState<string | null>(null);
|
||||
|
||||
// Close dropdown when clicking outside
|
||||
useEffect(() => {
|
||||
@@ -33,9 +36,34 @@ export function CommonHeader() {
|
||||
};
|
||||
}, [showProfileMenu]);
|
||||
|
||||
// Fetch profile image from backend
|
||||
useEffect(() => {
|
||||
const fetchProfileImage = async () => {
|
||||
try {
|
||||
const profile = await agentsService.getMyProfile();
|
||||
if (profile.avatar) {
|
||||
try {
|
||||
const avatarUrl = await uploadService.getPresignedDownloadUrl(profile.avatar);
|
||||
setProfileImage(avatarUrl);
|
||||
} catch {
|
||||
setProfileImage(profile.avatar);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to fetch profile image:', err);
|
||||
}
|
||||
};
|
||||
|
||||
if (session) {
|
||||
fetchProfileImage();
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
const userName = session?.user?.name;
|
||||
const userEmail = session?.user?.email;
|
||||
const userRole = (session?.user as any)?.role;
|
||||
// Use fetched profile image, fallback to session image
|
||||
const userImage = profileImage || session?.user?.image;
|
||||
|
||||
// Determine dashboard link based on user role
|
||||
const dashboardLink = userRole === 'AGENT' ? '/agent/dashboard' : '/user/dashboard';
|
||||
@@ -90,14 +118,22 @@ export function CommonHeader() {
|
||||
className="flex items-center gap-3 hover:opacity-80 transition-opacity cursor-pointer"
|
||||
>
|
||||
{/* Avatar */}
|
||||
<div className="w-[35px] h-[35px] rounded-full overflow-hidden border-2 border-[#e58625]">
|
||||
<Image
|
||||
src="/assets/icons/user-placeholder-icon.svg"
|
||||
alt="Profile"
|
||||
width={35}
|
||||
height={35}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
<div className="w-[35px] h-[35px] rounded-full overflow-hidden border-2 border-[#e58625] bg-gray-100">
|
||||
{userImage ? (
|
||||
<img
|
||||
src={userImage}
|
||||
alt="Profile"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<Image
|
||||
src="/assets/icons/user-placeholder-icon.svg"
|
||||
alt="Profile"
|
||||
width={35}
|
||||
height={35}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{/* Greeting Text */}
|
||||
<div className="flex flex-col text-left">
|
||||
@@ -118,14 +154,22 @@ export function CommonHeader() {
|
||||
|
||||
{/* User Profile Section */}
|
||||
<div className="flex items-center gap-3 px-4 py-4 border-b border-black/10">
|
||||
<div className="w-[42px] h-[42px] rounded-full overflow-hidden flex-shrink-0">
|
||||
<Image
|
||||
src="/assets/icons/user-placeholder-icon.svg"
|
||||
alt="Profile"
|
||||
width={42}
|
||||
height={42}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
<div className="w-[42px] h-[42px] rounded-full overflow-hidden flex-shrink-0 bg-gray-100">
|
||||
{userImage ? (
|
||||
<img
|
||||
src={userImage}
|
||||
alt="Profile"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<Image
|
||||
src="/assets/icons/user-placeholder-icon.svg"
|
||||
alt="Profile"
|
||||
width={42}
|
||||
height={42}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<p className="font-fractul font-medium text-[16px] leading-[20px] text-black">
|
||||
|
||||
Reference in New Issue
Block a user