Add src/components/dashboard/TopBar.jsx

This commit is contained in:
Eric Lay 2026-03-11 08:41:17 -05:00
parent b1d89f1e47
commit 312ac7ab85
1 changed files with 140 additions and 0 deletions

View File

@ -0,0 +1,140 @@
import React, { useState, useRef, useEffect } from "react";
import { Search, Bell, ChevronDown, User, Mail, LogOut } from "lucide-react";
export default function TopBar({ breadcrumb, userData }) {
const [userMenuOpen, setUserMenuOpen] = useState(false);
const [notifOpen, setNotifOpen] = useState(false);
const userRef = useRef(null);
const notifRef = useRef(null);
useEffect(() => {
const handleClick = (e) => {
if (userRef.current && !userRef.current.contains(e.target)) setUserMenuOpen(false);
if (notifRef.current && !notifRef.current.contains(e.target)) setNotifOpen(false);
};
document.addEventListener("mousedown", handleClick);
return () => document.removeEventListener("mousedown", handleClick);
}, []);
return (
<header id="topbar" className="h-14 bg-white border-b border-gray-200 flex items-center justify-between px-6 sticky top-0 z-20">
{/* Left - Breadcrumb */}
<div className="flex items-center gap-2 text-sm text-gray-500">
<span className="text-[#2980b9] hover:underline cursor-pointer font-medium">Homepage</span>
<span className="text-gray-400">/</span>
<span className="font-medium text-gray-700">{breadcrumb}</span>
</div>
{/* Center - Search */}
<div className="hidden md:flex items-center max-w-md w-full mx-8">
<div className="relative w-full">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
<input
type="text"
placeholder="Search..."
className="w-full h-9 pl-10 pr-4 bg-gray-50 border border-gray-200 rounded-lg text-sm focus:outline-none focus:border-[#3498db] focus:ring-1 focus:ring-[#3498db] transition-all"
/>
</div>
</div>
{/* Right - Notifications + User */}
<div className="flex items-center gap-3">
{/* Notifications */}
<div ref={notifRef} className="relative">
<button
id="notifications-btn"
onClick={() => setNotifOpen(!notifOpen)}
className="relative w-10 h-10 rounded border border-gray-300 bg-white flex items-center justify-center hover:bg-gray-50 transition-colors shadow-sm"
>
<Bell className="w-5 h-5 text-gray-600" />
<span className="absolute -top-1.5 -right-1.5 min-w-[18px] h-[18px] bg-red-500 text-white text-[10px] font-bold rounded-full flex items-center justify-center px-1">
6
</span>
</button>
{notifOpen && (
<div className="absolute right-0 top-full mt-2 w-96 bg-white rounded-xl shadow-2xl border border-gray-200 overflow-hidden">
<div className="px-4 py-3 border-b border-gray-200 flex items-center justify-between bg-gray-50">
<div className="flex items-center gap-2">
<h3 className="font-bold text-gray-800">Alerts</h3>
<span className="text-xs bg-gray-200 text-gray-600 px-2 py-0.5 rounded-full font-medium">6 unread</span>
</div>
<div className="flex items-center gap-2">
<label className="flex items-center gap-1.5 text-xs text-gray-500 cursor-pointer">
<input type="checkbox" className="w-3 h-3" /> Select all
</label>
<button className="text-xs bg-white border border-gray-300 text-gray-600 px-2 py-1 rounded flex items-center gap-1">
Actions <ChevronDown className="w-3 h-3" />
</button>
</div>
</div>
<div className="max-h-80 overflow-y-auto">
<div className="m-3 border border-yellow-300 rounded-lg bg-yellow-50 p-3">
<div className="flex items-start justify-between">
<div className="flex items-center gap-2 mb-1">
<span className="text-[10px] font-bold text-gray-500 uppercase tracking-wider">Bulletin</span>
<span className="w-2 h-2 bg-blue-500 rounded-full" />
</div>
<button className="text-gray-400 hover:text-gray-600 text-xs"></button>
</div>
<p className="text-sm font-semibold text-gray-800">Now Available: PBC Marketing Toolbox</p>
<p className="text-xs text-gray-600 mt-1 leading-relaxed">The Marketing Toolbox is the dedicated spot to find all kinds of materials, logos and resources.</p>
<p className="text-xs text-amber-600 font-semibold mt-2">Action Required</p>
</div>
<div className="mx-3 mb-3 border border-gray-200 rounded-lg bg-white p-3">
<div className="flex items-start justify-between">
<div className="flex items-center gap-2 mb-1">
<span className="text-[10px] font-bold text-gray-500 uppercase tracking-wider">Bulletin</span>
<span className="w-2 h-2 bg-blue-500 rounded-full" />
</div>
<button className="text-gray-400 hover:text-gray-600 text-xs"></button>
</div>
<p className="text-sm font-semibold text-gray-800">Now Available: Contact Us</p>
</div>
</div>
</div>
)}
</div>
{/* User Menu */}
<div ref={userRef} className="relative">
<button
id="user-menu-btn"
onClick={() => setUserMenuOpen(!userMenuOpen)}
className="flex items-center gap-2 bg-[#2980b9] hover:bg-[#2471a3] text-white px-4 py-2 rounded-md transition-colors shadow-sm text-sm font-semibold"
>
<User className="w-4 h-4" />
<span className="text-sm font-medium max-w-[120px] truncate">
{userData?.full_name || "Demo User"}
</span>
<ChevronDown className="w-3.5 h-3.5" />
</button>
{userMenuOpen && (
<div className="absolute right-0 top-full mt-2 w-64 bg-white rounded-xl shadow-2xl border border-gray-200 overflow-hidden">
<div className="px-4 py-3 border-b border-gray-100">
<p className="text-sm font-bold text-gray-800 uppercase">{userData?.full_name || "Demo User"}</p>
<p className="text-xs text-gray-500">{userData?.email || "demo@example.com"}</p>
<div className="mt-2 space-y-1 text-xs text-gray-600">
<p><span className="text-gray-400">Store ID:</span> {userData?.store_id || "AA1112"}</p>
<p><span className="text-gray-400">Store Name:</span> {userData?.store_name || "Demo Store"}</p>
</div>
</div>
<div className="py-1">
<button id="my-profile-menu" className="flex items-center gap-2 px-4 py-2.5 text-sm text-gray-700 hover:bg-gray-50 w-full">
<User className="w-4 h-4 text-gray-400" /> My Profile
</button>
<button className="flex items-center gap-2 px-4 py-2.5 text-sm text-gray-700 hover:bg-gray-50 w-full">
<Mail className="w-4 h-4 text-gray-400" /> Contact Us
</button>
</div>
<div className="border-t border-gray-100 py-1">
<button className="flex items-center gap-2 px-4 py-2.5 text-sm text-red-600 hover:bg-red-50 w-full">
<LogOut className="w-4 h-4" /> Logout
</button>
</div>
</div>
)}
</div>
</div>
</header>
);
}