refactor: Reimplement header functionality within CommonHeader and add new profile menu icons.

This commit is contained in:
pradeepkumar
2026-02-01 00:06:52 +05:30
parent db331e5a2b
commit 465551fea5
5 changed files with 133 additions and 214 deletions

View File

@@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.90002 7.56C9.21002 3.96 11.06 2.49 15.11 2.49H15.24C19.71 2.49 21.5 4.28 21.5 8.75V15.27C21.5 19.74 19.71 21.53 15.24 21.53H15.11C11.09 21.53 9.24002 20.08 8.91002 16.54" stroke="#E58625" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15 12H3.62" stroke="#E58625" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M5.85 8.65L2.5 12L5.85 15.35" stroke="#E58625" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 608 B

View File

@@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 6.44V9.77" stroke="#00293D" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M12.02 2C8.34 2 5.36 4.98 5.36 8.66V10.76C5.36 11.44 5.08 12.46 4.73 13.04L3.46 15.16C2.68 16.47 3.22 17.93 4.66 18.41C9.44 20 14.61 20 19.39 18.41C20.74 17.96 21.32 16.38 20.59 15.16L19.32 13.04C18.97 12.46 18.69 11.43 18.69 10.76V8.66C18.68 5 15.68 2 12.02 2Z" stroke="#00293D" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M15.33 18.82C15.33 20.65 13.83 22.15 12 22.15C11.09 22.15 10.25 21.77 9.65 21.17C9.05 20.57 8.67 19.73 8.67 18.82" stroke="#00293D" stroke-width="1.5" stroke-miterlimit="10"/>
</svg>

After

Width:  |  Height:  |  Size: 758 B

View File

@@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 15C13.6569 15 15 13.6569 15 12C15 10.3431 13.6569 9 12 9C10.3431 9 9 10.3431 9 12C9 13.6569 10.3431 15 12 15Z" stroke="#00293D" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2 12.88V11.12C2 10.08 2.85 9.22 3.9 9.22C5.71 9.22 6.45 7.94 5.54 6.37C5.02 5.47 5.33 4.3 6.24 3.78L7.97 2.79C8.76 2.32 9.78 2.6 10.25 3.39L10.36 3.58C11.26 5.15 12.74 5.15 13.65 3.58L13.76 3.39C14.23 2.6 15.25 2.32 16.04 2.79L17.77 3.78C18.68 4.3 18.99 5.47 18.47 6.37C17.56 7.94 18.3 9.22 20.11 9.22C21.15 9.22 22.01 10.07 22.01 11.12V12.88C22.01 13.92 21.16 14.78 20.11 14.78C18.3 14.78 17.56 16.06 18.47 17.63C18.99 18.54 18.68 19.7 17.77 20.22L16.04 21.21C15.25 21.68 14.23 21.4 13.76 20.61L13.65 20.42C12.75 18.85 11.27 18.85 10.36 20.42L10.25 20.61C9.78 21.4 8.76 21.68 7.97 21.21L6.24 20.22C5.33 19.7 5.02 18.53 5.54 17.63C6.45 16.06 5.71 14.78 3.9 14.78C2.85 14.78 2 13.92 2 12.88Z" stroke="#00293D" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,6 +1,6 @@
'use client';
import { useState } from 'react';
import { useState, useEffect, useRef } from 'react';
import Link from 'next/link';
import Image from 'next/image';
import { useSession, signOut } from 'next-auth/react';
@@ -14,6 +14,24 @@ const navLinks = [
export function CommonHeader() {
const { data: session } = useSession();
const [showProfileMenu, setShowProfileMenu] = useState(false);
const profileMenuRef = useRef<HTMLDivElement>(null);
// Close dropdown when clicking outside
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (profileMenuRef.current && !profileMenuRef.current.contains(event.target as Node)) {
setShowProfileMenu(false);
}
}
if (showProfileMenu) {
document.addEventListener('mousedown', handleClickOutside);
}
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [showProfileMenu]);
const userName = session?.user?.name;
const userEmail = session?.user?.email;
@@ -65,53 +83,114 @@ export function CommonHeader() {
<span className="absolute -top-0.5 -right-0.5 w-2 h-2 bg-red-500 rounded-full"></span>
</button>
{/* Profile Icon with Dropdown */}
<div className="relative">
{/* Profile Section with Greeting - Entire area clickable */}
<div className="relative" ref={profileMenuRef}>
<button
onClick={() => setShowProfileMenu(!showProfileMenu)}
className="w-6 h-6 flex items-center justify-center hover:opacity-80 transition-opacity"
className="flex items-center gap-3 hover:opacity-80 transition-opacity cursor-pointer"
>
<Image
src="/assets/profile-icon.svg"
alt="Profile"
width={24}
height={24}
/>
{/* 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>
{/* Greeting Text */}
<div className="flex flex-col text-left">
<span className="font-bold text-[14px] text-[#e58625] leading-tight">
Hi {userName?.split(' ')[0] || 'User'} !
</span>
<span className="font-bold text-[9px] text-[#00293d] leading-tight">
Welcome back !
</span>
</div>
</button>
{/* Profile Dropdown Menu */}
{showProfileMenu && (
<div className="absolute right-0 mt-2 w-56 bg-white rounded-[15px] border border-[#00293d]/10 py-3 z-50">
<div className="px-4 py-2 border-b border-[#00293d]/10">
<p className="font-fractul font-bold text-[14px] leading-[17px] text-[#00293D]">
{userName || 'User'}
<div className="absolute right-0 top-full mt-3 w-[271px] bg-white rounded-[15px] border border-black/20 z-50 shadow-[0px_4px_4px_0px_rgba(0,0,0,0.25)]">
{/* Arrow/Triangle at top */}
<div className="absolute -top-2 right-6 w-0 h-0 border-l-[8px] border-l-transparent border-r-[8px] border-r-transparent border-b-[8px] border-b-white"></div>
{/* 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>
<div className="flex flex-col">
<p className="font-fractul font-medium text-[16px] leading-[20px] text-black">
{userName?.split(' ')[0] || 'User'}
</p>
<p className="font-serif text-[14px] leading-[18px] text-black/50">
{userEmail}
</p>
</div>
</div>
{/* Account Settings */}
<Link
href={userRole === 'AGENT' ? '/agent/settings' : '/user/settings'}
className="flex items-center gap-3 px-4 py-3 border-b border-black/10 hover:bg-black/5 transition-colors"
onClick={() => setShowProfileMenu(false)}
>
<Image
src="/assets/icons/settings-icon.svg"
alt="Settings"
width={24}
height={24}
/>
<div className="flex flex-col">
<p className="font-fractul text-[16px] leading-[18px] text-black">
Account Settings
</p>
<p className="font-serif text-[14px] leading-[18px] text-black/50">
Profile, Security
</p>
</div>
</Link>
{/* Notification Settings */}
<Link
href={userRole === 'AGENT' ? '/agent/settings/notifications' : '/user/settings/notifications'}
className="flex items-center gap-3 px-4 py-3 border-b border-black/10 hover:bg-black/5 transition-colors"
onClick={() => setShowProfileMenu(false)}
>
<Image
src="/assets/icons/notification-settings-icon.svg"
alt="Notifications"
width={24}
height={24}
/>
<p className="font-fractul text-[16px] leading-[18px] text-black">
Notification Settings
</p>
<p className="font-serif text-[12px] leading-[16px] text-[#00293D]/50">{userEmail}</p>
</div>
<div className="py-2">
<Link
href={dashboardLink}
className="block px-4 py-2 font-serif text-[14px] leading-[19px] text-[#00293D] hover:bg-[#00293d]/5 transition-colors"
onClick={() => setShowProfileMenu(false)}
>
Dashboard
</Link>
<Link
href={userRole === 'AGENT' ? '/agent/settings' : '/user/settings'}
className="block px-4 py-2 font-serif text-[14px] leading-[19px] text-[#00293D] hover:bg-[#00293d]/5 transition-colors"
onClick={() => setShowProfileMenu(false)}
>
Settings
</Link>
</div>
<div className="border-t border-[#00293d]/10 pt-2">
<button
onClick={() => signOut({ callbackUrl: '/login' })}
className="w-full text-left px-4 py-2 font-serif text-[14px] leading-[19px] text-[#e58625] hover:bg-[#00293d]/5 transition-colors"
>
Sign Out
</button>
</div>
</Link>
{/* Log Out */}
<button
onClick={() => signOut({ callbackUrl: '/login' })}
className="w-full flex items-center gap-3 px-4 py-3 hover:bg-black/5 transition-colors"
>
<Image
src="/assets/icons/logout-icon.svg"
alt="Log Out"
width={24}
height={24}
/>
<p className="font-fractul font-bold text-[16px] leading-[18px] text-[#e58625]">
Log Out
</p>
</button>
</div>
)}
</div>

View File

@@ -1,174 +0,0 @@
'use client';
import Link from 'next/link';
import Image from 'next/image';
import { useSession } from 'next-auth/react';
import { useState } from 'react';
export function Header() {
const { data: session } = useSession();
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
// Get first name from session
const firstName = session?.user?.name?.split(' ')[0] || 'User';
return (
<header className="bg-[#5d7a87]">
<div className="max-w-[1440px] mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-20">
{/* Logo */}
<Link href="/" className="flex items-center">
<Image
src="/assets/logo-white.svg"
alt="RE-Quest"
width={184}
height={44}
className="h-11 w-auto"
/>
</Link>
{session ? (
/* ============ AUTHENTICATED HEADER ============ */
<>
{/* Navigation - Desktop */}
<nav className="hidden md:flex items-center gap-10">
<Link
href="/education"
className="font-bold text-[15px] text-[#00293d] hover:text-[#e58625] transition-colors"
>
Education
</Link>
<Link
href="/about"
className="font-bold text-[15px] text-[#00293d] hover:text-[#e58625] transition-colors"
>
About Us
</Link>
<Link
href="/faq"
className="font-bold text-[15px] text-[#00293d] hover:text-[#e58625] transition-colors"
>
FAQ&apos;s
</Link>
</nav>
{/* Right Side - Authenticated */}
<div className="flex items-center gap-5">
{/* Notification Bell */}
<Link
href="/notifications"
className="relative hover:opacity-80 transition-opacity"
>
<Image
src="/assets/icons/notification-bell-icon.svg"
alt="Notifications"
width={20}
height={22}
/>
{/* Red notification dot */}
<span className="absolute -top-0.5 -right-0.5 w-2 h-2 bg-red-500 rounded-full border border-[#5d7a87]"></span>
</Link>
{/* Profile Section */}
<Link href="/user/dashboard" className="flex items-center gap-3">
{/* Profile Avatar */}
<div className="w-[35px] h-[35px] rounded-full overflow-hidden bg-gray-300 flex-shrink-0">
{session.user?.image ? (
<Image
src={session.user.image}
alt="Profile"
width={35}
height={35}
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="hidden sm:flex flex-col">
<span className="font-bold text-[14px] text-[#e58625] leading-tight">
Hi {firstName} !
</span>
<span className="font-bold text-[9px] text-[#00293d] leading-tight">
Welcome back !
</span>
</div>
</Link>
{/* Mobile Menu Button */}
<button
className="md:hidden p-2 hover:bg-white/10 rounded-lg transition-colors"
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
aria-label="Toggle menu"
>
{mobileMenuOpen ? (
<Image
src="/assets/icons/close-icon.svg"
alt="Close menu"
width={24}
height={24}
/>
) : (
<Image
src="/assets/icons/menu-icon.svg"
alt="Open menu"
width={24}
height={24}
/>
)}
</button>
</div>
</>
) : (
/* ============ NON-AUTHENTICATED HEADER ============ */
/* Simple: Just logo + Get Started button */
<div className="flex items-center">
<Link
href="/login"
className="bg-[#e58625] hover:bg-[#d4780f] text-white font-bold text-[14px] px-6 py-2.5 rounded-[15px] transition-colors"
>
Get Started
</Link>
</div>
)}
</div>
{/* Mobile Menu Dropdown - Authenticated Only */}
{session && mobileMenuOpen && (
<div className="md:hidden pb-4 border-t border-white/20 mt-2 pt-4">
<nav className="flex flex-col gap-3">
<Link
href="/education"
className="font-bold text-[15px] text-[#00293d] hover:text-[#e58625] transition-colors py-2"
onClick={() => setMobileMenuOpen(false)}
>
Education
</Link>
<Link
href="/about"
className="font-bold text-[15px] text-[#00293d] hover:text-[#e58625] transition-colors py-2"
onClick={() => setMobileMenuOpen(false)}
>
About Us
</Link>
<Link
href="/faq"
className="font-bold text-[15px] text-[#00293d] hover:text-[#e58625] transition-colors py-2"
onClick={() => setMobileMenuOpen(false)}
>
FAQ&apos;s
</Link>
</nav>
</div>
)}
</div>
</header>
);
}