Header.jsx 4.29 KB
Newer Older
fisherdaddy's avatar
fisherdaddy committed
1
// src/components/Header.jsx
fisherdaddy's avatar
fisherdaddy committed
2
import React, { useState, useEffect, useRef } from 'react';
fisherdaddy's avatar
fisherdaddy committed
3
import { NavLink, useNavigate } from 'react-router-dom';
fisherdaddy's avatar
fisherdaddy committed
4 5
import LanguageSelector from './LanguageSelector';
import { useTranslation } from '../js/i18n';
fisherdaddy's avatar
fisherdaddy committed
6 7
import '../styles/Header.css';
import logo from '/assets/logo.png';
fisherdaddy's avatar
fisherdaddy committed
8 9 10

function Header() {
  const { t } = useTranslation();
fisherdaddy's avatar
fisherdaddy committed
11 12
  const navigate = useNavigate();
  const user = JSON.parse(localStorage.getItem('user'));
fisherdaddy's avatar
fisherdaddy committed
13
  const [menuOpen, setMenuOpen] = useState(false);
14
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
fisherdaddy's avatar
fisherdaddy committed
15
  const menuRef = useRef(null);
fisherdaddy's avatar
fisherdaddy committed
16

fisherdaddy's avatar
fisherdaddy committed
17
  const toggleMenu = () => {
18
    setMenuOpen(!menuOpen);
fisherdaddy's avatar
fisherdaddy committed
19 20 21 22 23 24 25 26
  };

  useEffect(() => {
    const handleClickOutside = (event) => {
      if (menuRef.current && !menuRef.current.contains(event.target)) {
        setMenuOpen(false);
      }
    };
27

fisherdaddy's avatar
fisherdaddy committed
28 29 30 31
    document.addEventListener('mousedown', handleClickOutside);
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
  }, [menuRef]);

  const handleLogout = () => {
    localStorage.removeItem('user');
    navigate('/login');
    setMobileMenuOpen(false);
  };

  const toggleMobileMenu = () => {
    setMobileMenuOpen(!mobileMenuOpen);
  };

  const handleNavClick = () => {
    setMobileMenuOpen(false);
  };
fisherdaddy's avatar
fisherdaddy committed
47

fisherdaddy's avatar
fisherdaddy committed
48 49 50
  return (
    <header>
      <nav>
fisherdaddy's avatar
fisherdaddy committed
51
        <div className="logo-title-container">
52
          <NavLink to="/" className="title no-underline" onClick={handleNavClick}>
fisherdaddy's avatar
fisherdaddy committed
53
            <img src={logo} alt="Logo" className="logo" />
fisherdaddy's avatar
fisherdaddy committed
54
            {t('title')}
fisherdaddy's avatar
fisherdaddy committed
55 56
          </NavLink>
        </div>
57 58 59 60 61

        <button className="mobile-menu-button" onClick={toggleMobileMenu}>
          <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            {mobileMenuOpen ? (
              <path d="M6 18L18 6M6 6l12 12" />
fisherdaddy's avatar
fisherdaddy committed
62
            ) : (
63
              <path d="M4 6h16M4 12h16M4 18h16" />
fisherdaddy's avatar
fisherdaddy committed
64
            )}
65 66 67 68 69 70
          </svg>
        </button>

        <div className={`menu-container ${mobileMenuOpen ? 'mobile-menu-open' : ''}`}>
          <div className="menu-items">
            <NavLink to="/dev-tools" onClick={handleNavClick}>
fisherdaddy's avatar
fisherdaddy committed
71
              {t('dev-tools.title')}
72 73
            </NavLink>
            <NavLink to="/image-tools" onClick={handleNavClick}>
fisherdaddy's avatar
fisherdaddy committed
74
              {t('image-tools.title')}
75 76
            </NavLink>
            <NavLink to="/ai-products" onClick={handleNavClick}>
fisherdaddy's avatar
fisherdaddy committed
77
              {t('ai-products.title')}
78
            </NavLink>
fisherdaddy's avatar
fisherdaddy committed
79
            <NavLink to="/blog" onClick={handleNavClick}>
fisherdaddy's avatar
fisherdaddy committed
80
              {t('blog.title')}
fisherdaddy's avatar
fisherdaddy committed
81
            </NavLink>
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
          </div>
          <div className="right-container">
            <LanguageSelector />
            <div className="auth-container">
              {user ? (
                <div className="user-info">
                  <div className="avatar-container" ref={menuRef}>
                    <img
                      src={user.picture}
                      alt="User Avatar"
                      className="avatar"
                      onClick={toggleMenu}
                    />
                    <div className={`dropdown-menu ${menuOpen ? 'active' : ''}`}>
                      <button onClick={handleLogout}>
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                          <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
                          <polyline points="16 17 21 12 16 7" />
                          <line x1="21" y1="12" x2="9" y2="12" />
                        </svg>
                        {t('logout')}
                      </button>
                    </div>
                  </div>
                </div>
              ) : (
                <NavLink to="/login" className="login-button">
                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                    <path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" />
                    <polyline points="10 17 15 12 10 7" />
                    <line x1="15" y1="12" x2="3" y2="12" />
                  </svg>
                  {t('login')}
                </NavLink>
              )}
            </div>
fisherdaddy's avatar
fisherdaddy committed
118 119
          </div>
        </div>
fisherdaddy's avatar
fisherdaddy committed
120 121 122 123 124
      </nav>
    </header>
  );
}

fisherdaddy's avatar
fisherdaddy committed
125
export default Header;