137 lines
5.3 KiB
TypeScript
137 lines
5.3 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState, useEffect, useRef } from "react";
|
|
import { motion, AnimatePresence } from "framer-motion";
|
|
import {
|
|
Search,
|
|
Bell,
|
|
User,
|
|
Settings,
|
|
LogOut,
|
|
ChevronDown,
|
|
Menu,
|
|
} from "lucide-react";
|
|
|
|
interface ModernHeaderProps {
|
|
onMenuToggle: () => void;
|
|
sidebarOpen: boolean;
|
|
}
|
|
|
|
export const ModernHeader: React.FC<ModernHeaderProps> = ({
|
|
onMenuToggle,
|
|
sidebarOpen,
|
|
}) => {
|
|
const [showUserDropdown, setShowUserDropdown] = useState(false);
|
|
const [searchQuery, setSearchQuery] = useState("");
|
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
|
|
// Close dropdown when clicking outside
|
|
useEffect(() => {
|
|
const handleClickOutside = (event: MouseEvent) => {
|
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
|
setShowUserDropdown(false);
|
|
}
|
|
};
|
|
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
return () => {
|
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<header className="bg-gray-50 border-b border-gray-200 px-4 lg:px-6 py-4">
|
|
<div className="flex items-center justify-between">
|
|
{/* Left Section */}
|
|
<div className="flex items-center space-x-4">
|
|
{/* Mobile Menu Button */}
|
|
<button
|
|
onClick={onMenuToggle}
|
|
className="lg:hidden p-2 rounded-lg hover:bg-gray-200 transition-colors"
|
|
>
|
|
<Menu className="w-5 h-5 text-gray-600" />
|
|
</button>
|
|
|
|
{/* Search Bar */}
|
|
<div className="hidden md:flex px-6">
|
|
<div className="relative w-64 lg:w-80">
|
|
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400" />
|
|
<input
|
|
type="text"
|
|
placeholder="Search..."
|
|
value={searchQuery}
|
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
className="w-full pl-10 pr-4 py-2 bg-white border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Right Section */}
|
|
<div className="flex items-center space-x-2 lg:space-x-4">
|
|
{/* Notifications */}
|
|
<button className="relative p-2 rounded-lg hover:bg-gray-200 transition-colors">
|
|
<Bell className="w-5 h-5 text-gray-600" />
|
|
{/* Notification Badge */}
|
|
<span className="absolute -top-1 -right-1 w-3 h-3 bg-red-500 rounded-full flex items-center justify-center">
|
|
<span className="text-xs text-white font-medium">3</span>
|
|
</span>
|
|
</button>
|
|
|
|
{/* User Avatar & Dropdown */}
|
|
<div className="relative" ref={dropdownRef}>
|
|
<button
|
|
onClick={() => setShowUserDropdown(!showUserDropdown)}
|
|
className="flex items-center space-x-3 p-2 rounded-lg hover:bg-gray-200 transition-colors"
|
|
>
|
|
<div className="w-8 h-8 bg-gradient-to-br from-blue-500 to-purple-600 rounded-full flex items-center justify-center">
|
|
<User className="w-4 h-4 text-white" />
|
|
</div>
|
|
<div className="hidden md:block text-left">
|
|
<p className="text-sm font-medium text-gray-900">Admin User</p>
|
|
<p className="text-xs text-gray-500">admin@netidhub.com</p>
|
|
</div>
|
|
<ChevronDown className="w-4 h-4 text-gray-500" />
|
|
</button>
|
|
|
|
{/* Dropdown Menu */}
|
|
<AnimatePresence>
|
|
{showUserDropdown && (
|
|
<motion.div
|
|
initial={{ opacity: 0, y: -10, scale: 0.95 }}
|
|
animate={{ opacity: 1, y: 0, scale: 1 }}
|
|
exit={{ opacity: 0, y: -10, scale: 0.95 }}
|
|
transition={{ duration: 0.2 }}
|
|
className="absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg border border-gray-200 py-2 z-50"
|
|
>
|
|
<div className="px-4 py-2 border-b border-gray-100">
|
|
<p className="text-sm font-medium text-gray-900">Admin User</p>
|
|
<p className="text-xs text-gray-500">admin@netidhub.com</p>
|
|
</div>
|
|
|
|
<button className="w-full flex items-center space-x-3 px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 transition-colors">
|
|
<User className="w-4 h-4" />
|
|
<span>Profile</span>
|
|
</button>
|
|
|
|
<button className="w-full flex items-center space-x-3 px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 transition-colors">
|
|
<Settings className="w-4 h-4" />
|
|
<span>Settings</span>
|
|
</button>
|
|
|
|
<div className="border-t border-gray-100 my-1"></div>
|
|
|
|
<button className="w-full flex items-center space-x-3 px-4 py-2 text-sm text-red-600 hover:bg-red-50 transition-colors">
|
|
<LogOut className="w-4 h-4" />
|
|
<span>Logout</span>
|
|
</button>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
);
|
|
};
|