init commit
This commit is contained in:
152
src/components/ui/UserDropdown.tsx
Normal file
152
src/components/ui/UserDropdown.tsx
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* User Dropdown Component
|
||||
* Reusable header dropdown with user information and navigation
|
||||
*
|
||||
* @author David Valera Melendez <david@valera-melendez.de>
|
||||
* @created 2025-08-07
|
||||
* @location Made in Germany 🇩🇪
|
||||
*/
|
||||
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { User, FileText, ChevronDown, Settings, LogOut } from 'lucide-react';
|
||||
|
||||
interface UserDropdownProps {
|
||||
/** Current page identifier to highlight in dropdown */
|
||||
currentPage?: 'dashboard' | 'settings';
|
||||
/** Whether to show the logo icon */
|
||||
showLogo?: boolean;
|
||||
/** Custom CSS classes */
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* UserDropdown Component - Reusable header dropdown
|
||||
*
|
||||
* Professional user dropdown component with user information display
|
||||
* and navigation options. Can be customized for different pages.
|
||||
*
|
||||
* Features:
|
||||
* - User information display (name + email)
|
||||
* - Navigation menu with current page highlighting
|
||||
* - Settings and logout functionality
|
||||
* - Optional logo display
|
||||
* - Responsive design
|
||||
*
|
||||
* @param currentPage - Current page to highlight in dropdown
|
||||
* @param showLogo - Whether to display the logo icon
|
||||
* @param className - Additional CSS classes
|
||||
* @returns Reusable user dropdown component
|
||||
*/
|
||||
export function UserDropdown({
|
||||
currentPage,
|
||||
showLogo = false,
|
||||
className = '',
|
||||
}: UserDropdownProps) {
|
||||
const router = useRouter();
|
||||
const [isUserMenuOpen, setIsUserMenuOpen] = useState(false);
|
||||
|
||||
/**
|
||||
* Handles navigation to settings page
|
||||
*/
|
||||
const handleAccountSettings = () => {
|
||||
setIsUserMenuOpen(false);
|
||||
router.push('/settings');
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles logout functionality
|
||||
*/
|
||||
const handleLogout = () => {
|
||||
setIsUserMenuOpen(false);
|
||||
// Here you would typically clear user session/tokens
|
||||
console.log('Logging out...');
|
||||
// Redirect to login or home page
|
||||
router.push('/');
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes dropdown when clicking outside
|
||||
*/
|
||||
const handleDropdownToggle = () => {
|
||||
setIsUserMenuOpen(!isUserMenuOpen);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`flex items-center gap-3 ${className}`}>
|
||||
{/* Optional Logo */}
|
||||
{showLogo && (
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-primary-600 to-primary-700 shadow-sm">
|
||||
<FileText className="h-6 w-6 text-white" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* User Info Display */}
|
||||
<div className="text-right">
|
||||
<h1 className="text-lg font-bold text-primary-700">
|
||||
David Valera Melendez
|
||||
</h1>
|
||||
<p className="text-xs text-gray-500">david@valera-melendez.de</p>
|
||||
</div>
|
||||
|
||||
{/* User Dropdown */}
|
||||
<div className="relative">
|
||||
<button
|
||||
onClick={handleDropdownToggle}
|
||||
className="flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-100"
|
||||
aria-label="User menu"
|
||||
aria-expanded={isUserMenuOpen}
|
||||
>
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-gradient-to-br from-primary-100 to-primary-200">
|
||||
<User className="h-4 w-4 text-primary-600" />
|
||||
</div>
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
</button>
|
||||
|
||||
{/* Dropdown Menu */}
|
||||
{isUserMenuOpen && (
|
||||
<>
|
||||
{/* Backdrop for mobile */}
|
||||
<div
|
||||
className="fixed inset-0 z-40 lg:hidden"
|
||||
onClick={() => setIsUserMenuOpen(false)}
|
||||
/>
|
||||
|
||||
<div className="absolute right-0 top-full z-50 mt-2 w-56 rounded-lg border border-gray-200 bg-white shadow-lg">
|
||||
<div className="py-1">
|
||||
{/* Settings Option */}
|
||||
<button
|
||||
onClick={handleAccountSettings}
|
||||
className={`flex w-full items-center gap-2 px-4 py-2 text-left text-sm transition-colors ${
|
||||
currentPage === 'settings'
|
||||
? 'bg-primary-50 text-primary-600'
|
||||
: 'text-gray-700 hover:bg-gray-50'
|
||||
}`}
|
||||
>
|
||||
<Settings className="h-4 w-4" />
|
||||
Konto-Einstellungen
|
||||
</button>
|
||||
|
||||
{/* Divider */}
|
||||
<div className="mx-1 my-1 border-t border-gray-100" />
|
||||
|
||||
{/* Logout Option */}
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
className="flex w-full items-center gap-2 px-4 py-2 text-left text-sm text-red-600 transition-colors hover:bg-red-50"
|
||||
>
|
||||
<LogOut className="h-4 w-4" />
|
||||
Abmelden
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default UserDropdown;
|
||||
Reference in New Issue
Block a user