"use client" import React, { useState, useRef, useEffect } from 'react' import Link from 'next/link' import { House, Link as LinkIcon, User, Phone, BookOpen, X, Menu, Globe, ChevronDown, ChevronRight, Brain, Smartphone } from 'lucide-react' import { SiClaude, SiGoogle } from 'react-icons/si' import { useTranslation } from 'react-i18next' interface NavItemProps { href: string; icon: React.ElementType; children: React.ReactNode; } const NavItem = ({ href, icon, children }: NavItemProps) => (
{React.createElement(icon, { className: "text-md mr-2", strokeWidth: 2.5, size: 20 })} {children}
); interface DropdownNavItemProps { id: string; href: string; icon: React.ElementType; children: React.ReactNode; dropdownContent: React.ReactNode; isMobile?: boolean; isOpen?: boolean; onOpenChange?: (id: string | null) => void; } const DropdownNavItem = ({ id, href, icon, children, dropdownContent, isMobile = false, isOpen = false, onOpenChange }: DropdownNavItemProps) => { const dropdownRef = useRef(null); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { onOpenChange?.(null); } }; if (isMobile && isOpen) { document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); } }, [isMobile, isOpen, onOpenChange]); const handleMouseEnter = () => { if (!isMobile) { onOpenChange?.(id); } }; const handleMouseLeave = (e: React.MouseEvent) => { if (!isMobile) { const relatedTarget = e.relatedTarget as HTMLElement; if (relatedTarget && dropdownRef.current?.contains(relatedTarget)) { return; } onOpenChange?.(null); } }; const handleClick = (e: React.MouseEvent) => { if (isMobile) { e.preventDefault(); onOpenChange?.(isOpen ? null : id); } }; return (
{React.createElement(icon, { className: "text-md mr-2", strokeWidth: 2.5, size: 20 })} {children} {isOpen && ( <> {/* Invisible bridge to handle gap */} {!isMobile && (
)}
{dropdownContent}
)}
); }; interface NestedDropdownItemProps { children: React.ReactNode; nestedContent: React.ReactNode; isMobile?: boolean; } const NestedDropdownItem = ({ children, nestedContent, isMobile = false }: NestedDropdownItemProps) => { const [isOpen, setIsOpen] = useState(false); const itemRef = useRef(null); const handleMouseEnter = () => { if (!isMobile) { setIsOpen(true); } }; const handleMouseLeave = (e: React.MouseEvent) => { if (!isMobile) { const relatedTarget = e.relatedTarget as HTMLElement; if (relatedTarget && itemRef.current?.contains(relatedTarget)) { return; } setIsOpen(false); } }; const handleClick = (e: React.MouseEvent) => { if (isMobile) { e.preventDefault(); setIsOpen(!isOpen); } }; if (isMobile) { return (
{isOpen && (
{nestedContent}
)}
); } return (
{isOpen && ( <> {/* Invisible bridge to handle gap */}
{nestedContent}
)}
); }; const LanguageSelector = () => { const { i18n } = useTranslation(); const [isOpen, setIsOpen] = useState(false); const [isMobile, setIsMobile] = useState(false); const dropdownRef = useRef(null); const languages = [ { code: 'en-US', name: 'English' }, ]; useEffect(() => { const checkMobile = () => { setIsMobile(window.innerWidth < 1024); }; checkMobile(); window.addEventListener('resize', checkMobile); return () => window.removeEventListener('resize', checkMobile); }, []); const changeLanguage = (lng: string) => { i18n.changeLanguage(lng); setIsOpen(false); }; useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { setIsOpen(false); } }; if (isMobile) { document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); } }, [isMobile]); const handleMouseEnter = () => { if (!isMobile) { setIsOpen(true); } }; const handleMouseLeave = (e: React.MouseEvent) => { if (!isMobile) { const relatedTarget = e.relatedTarget as HTMLElement; if (relatedTarget && dropdownRef.current?.contains(relatedTarget)) { return; } setIsOpen(false); } }; const handleClick = () => { if (isMobile) { setIsOpen(!isOpen); } }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Escape') { setIsOpen(false); } if (e.key === 'Enter' || e.key === ' ') { setIsOpen(!isOpen); } }; return (
{isOpen && ( <> {/* Invisible bridge to handle gap */} {!isMobile && (
)}
{languages.map((lang) => ( ))}
)}
); }; export default function Header() { const [isOpen, setIsOpen] = useState(false); const [isMobile, setIsMobile] = useState(false); const [activeDropdown, setActiveDropdown] = useState(null); const toggleMenu = () => setIsOpen(!isOpen); useEffect(() => { const checkMobile = () => { setIsMobile(window.innerWidth < 1024); }; checkMobile(); window.addEventListener('resize', checkMobile); return () => window.removeEventListener('resize', checkMobile); }, []); const aboutDropdownContent = ( <>
About Me Pixel 3a XL (bonito) Pixel 7 Pro (cheetah) Pixel 9 Pro (komodo) } > Devices
); const aiDropdownContent = (
AI Claude Usage
); return ( <>
{isOpen && (
)}
); }