refactor: Reimplement header functionality within CommonHeader and add new profile menu icons.
This commit is contained in:
5
public/assets/icons/logout-icon.svg
Normal file
5
public/assets/icons/logout-icon.svg
Normal 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 |
5
public/assets/icons/notification-settings-icon.svg
Normal file
5
public/assets/icons/notification-settings-icon.svg
Normal 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 |
4
public/assets/icons/settings-icon.svg
Normal file
4
public/assets/icons/settings-icon.svg
Normal 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 |
@@ -1,6 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useState, useEffect, useRef } from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { useSession, signOut } from 'next-auth/react';
|
import { useSession, signOut } from 'next-auth/react';
|
||||||
@@ -14,6 +14,24 @@ const navLinks = [
|
|||||||
export function CommonHeader() {
|
export function CommonHeader() {
|
||||||
const { data: session } = useSession();
|
const { data: session } = useSession();
|
||||||
const [showProfileMenu, setShowProfileMenu] = useState(false);
|
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 userName = session?.user?.name;
|
||||||
const userEmail = session?.user?.email;
|
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>
|
<span className="absolute -top-0.5 -right-0.5 w-2 h-2 bg-red-500 rounded-full"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* Profile Icon with Dropdown */}
|
{/* Profile Section with Greeting - Entire area clickable */}
|
||||||
<div className="relative">
|
<div className="relative" ref={profileMenuRef}>
|
||||||
<button
|
<button
|
||||||
onClick={() => setShowProfileMenu(!showProfileMenu)}
|
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
|
{/* Avatar */}
|
||||||
src="/assets/profile-icon.svg"
|
<div className="w-[35px] h-[35px] rounded-full overflow-hidden border-2 border-[#e58625]">
|
||||||
alt="Profile"
|
<Image
|
||||||
width={24}
|
src="/assets/icons/user-placeholder-icon.svg"
|
||||||
height={24}
|
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>
|
</button>
|
||||||
|
|
||||||
{/* Profile Dropdown Menu */}
|
{/* Profile Dropdown Menu */}
|
||||||
{showProfileMenu && (
|
{showProfileMenu && (
|
||||||
<div className="absolute right-0 mt-2 w-56 bg-white rounded-[15px] border border-[#00293d]/10 py-3 z-50">
|
<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)]">
|
||||||
<div className="px-4 py-2 border-b border-[#00293d]/10">
|
{/* Arrow/Triangle at top */}
|
||||||
<p className="font-fractul font-bold text-[14px] leading-[17px] text-[#00293D]">
|
<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>
|
||||||
{userName || 'User'}
|
|
||||||
|
{/* 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>
|
||||||
<p className="font-serif text-[12px] leading-[16px] text-[#00293D]/50">{userEmail}</p>
|
</Link>
|
||||||
</div>
|
|
||||||
<div className="py-2">
|
{/* Log Out */}
|
||||||
<Link
|
<button
|
||||||
href={dashboardLink}
|
onClick={() => signOut({ callbackUrl: '/login' })}
|
||||||
className="block px-4 py-2 font-serif text-[14px] leading-[19px] text-[#00293D] hover:bg-[#00293d]/5 transition-colors"
|
className="w-full flex items-center gap-3 px-4 py-3 hover:bg-black/5 transition-colors"
|
||||||
onClick={() => setShowProfileMenu(false)}
|
>
|
||||||
>
|
<Image
|
||||||
Dashboard
|
src="/assets/icons/logout-icon.svg"
|
||||||
</Link>
|
alt="Log Out"
|
||||||
<Link
|
width={24}
|
||||||
href={userRole === 'AGENT' ? '/agent/settings' : '/user/settings'}
|
height={24}
|
||||||
className="block px-4 py-2 font-serif text-[14px] leading-[19px] text-[#00293D] hover:bg-[#00293d]/5 transition-colors"
|
/>
|
||||||
onClick={() => setShowProfileMenu(false)}
|
<p className="font-fractul font-bold text-[16px] leading-[18px] text-[#e58625]">
|
||||||
>
|
Log Out
|
||||||
Settings
|
</p>
|
||||||
</Link>
|
</button>
|
||||||
</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>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -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'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's
|
|
||||||
</Link>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user