Spaces:
Sleeping
Sleeping
File size: 8,016 Bytes
0f8617c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | import { Link } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
import { useSocket } from '../context/SocketContext';
import { Camera, LogOut, User, Bell, MessageSquare } from 'lucide-react';
import { useState } from 'react';
const Header = () => {
const { user, activeRole, switchRole, logout } = useAuth();
const { notifications, setNotifications } = useSocket() || { notifications: [] };
const [isNotifOpen, setIsNotifOpen] = useState(false);
const unreadCount = notifications.filter(n => !n.isRead).length;
return (
<header className="bg-white/80 backdrop-blur-md border-b sticky top-0 z-50">
<div className="container mx-auto px-4 py-4 flex justify-between items-center">
<Link to="/" className="flex items-center space-x-2 text-blue-600 font-bold text-2xl group">
<div className="bg-blue-600 text-white p-1.5 rounded-xl group-hover:rotate-12 transition-transform">
<Camera size={24} />
</div>
<span>SnapLocal<span className="text-gray-900 ml-1">Pro</span></span>
</Link>
<nav className="flex items-center space-x-6">
<Link to="/search" className="text-gray-600 hover:text-blue-600 font-bold text-sm uppercase tracking-wider">Explore</Link>
{user ? (
<div className="flex items-center space-x-5">
{/* Role Switcher — only shown when user has multiple roles */}
{user?.roles?.length > 1 && (
<div className="flex items-center bg-gray-100 rounded-xl p-1 gap-1">
<button
onClick={() => { switchRole('customer'); window.location.href = '/dashboard'; }}
className={`px-3 py-1.5 rounded-lg text-xs font-black transition ${activeRole === 'customer' ? 'bg-white text-blue-600 shadow-sm' : 'text-gray-500 hover:text-gray-700'
}`}
title="Switch to Customer view"
>
👤 Customer
</button>
<button
onClick={() => { switchRole('photographer'); window.location.href = '/dashboard'; }}
className={`px-3 py-1.5 rounded-lg text-xs font-black transition ${activeRole === 'photographer' ? 'bg-white text-blue-600 shadow-sm' : 'text-gray-500 hover:text-gray-700'
}`}
title="Switch to Photographer view"
>
📷 Photographer
</button>
</div>
)}
<Link to="/chat" className="relative p-2 text-gray-400 hover:text-blue-600 transition">
<MessageSquare size={22} />
<span className="absolute top-1 right-1 w-2 h-2 bg-blue-600 rounded-full border-2 border-white"></span>
</Link>
<div className="relative">
<button
onClick={() => setIsNotifOpen(!isNotifOpen)}
className="relative p-2 text-gray-400 hover:text-blue-600 transition"
>
<Bell size={22} />
{unreadCount > 0 && (
<span className="absolute top-0 right-0 bg-red-500 text-white text-[10px] font-black px-1.5 py-0.5 rounded-full min-w-[18px] border-2 border-white">
{unreadCount}
</span>
)}
</button>
{isNotifOpen && (
<div className="absolute right-0 mt-4 w-80 bg-white rounded-3xl shadow-2xl border border-gray-100 overflow-hidden animate-in fade-in zoom-in-95 duration-200">
<div className="p-5 border-b border-gray-50 flex justify-between items-center">
<h3 className="font-black text-gray-900">Notifications</h3>
{unreadCount > 0 && (
<button className="text-xs text-blue-600 font-bold hover:underline">Mark all read</button>
)}
</div>
<div className="max-h-96 overflow-y-auto">
{notifications.length > 0 ? notifications.map((n, i) => (
<div key={i} className="p-4 border-b border-gray-50 hover:bg-gray-50 transition cursor-pointer">
<p className="text-sm font-medium text-gray-800">{n.content}</p>
<p className="text-[10px] text-gray-400 font-bold uppercase mt-1">{new Date(n.createdAt || Date.now()).toLocaleDateString()}</p>
</div>
)) : (
<div className="p-8 text-center text-gray-400 italic text-sm">No notifications yet.</div>
)}
</div>
<Link to="/dashboard" onClick={() => setIsNotifOpen(false)} className="block p-4 text-center text-xs font-black text-blue-600 bg-gray-50 hover:bg-gray-100 transition">
View All Bookings
</Link>
</div>
)}
</div>
<Link to="/dashboard" className="flex items-center space-x-2 text-gray-700 font-black p-1 pr-4 bg-gray-50 rounded-2xl hover:ring-2 hover:ring-blue-100 transition">
<div className="w-9 h-9 bg-blue-600 text-white rounded-xl flex items-center justify-center shadow-lg shadow-blue-100">
<User size={18} />
</div>
<span className="hidden sm:inline text-xs uppercase tracking-wider">{user?.firstName || user?.email?.split('@')[0]}</span>
</Link>
<button
onClick={logout}
className="p-2 text-gray-400 hover:text-red-600 transition"
title="Logout"
>
<LogOut size={20} />
</button>
</div>
) : (
<div className="flex items-center space-x-4">
<Link to="/login" className="text-gray-600 hover:text-blue-600 font-black text-xs uppercase tracking-widest">Login</Link>
<Link to="/register" className="bg-gray-900 text-white px-6 py-3 rounded-2xl font-black text-xs uppercase tracking-widest hover:bg-gray-800 transition shadow-xl active:scale-95">Get Started</Link>
</div>
)}
</nav>
</div>
</header>
);
};
export default Header;
|