File size: 3,622 Bytes
a4bdc89
 
3993320
 
 
 
a4bdc89
 
 
 
 
 
 
 
 
 
 
3993320
 
 
d87c1fb
 
 
3993320
 
d87c1fb
 
3acde0a
3993320
 
 
3acde0a
 
a4bdc89
d87c1fb
a4bdc89
3993320
a4bdc89
d87c1fb
a4bdc89
3993320
 
 
a4bdc89
3993320
d87c1fb
a4bdc89
3993320
 
a4bdc89
3acde0a
a4bdc89
 
 
 
 
3acde0a
a4bdc89
 
 
3993320
a4bdc89
3acde0a
a4bdc89
3acde0a
a4bdc89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3993320
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import { useEffect, useState } from 'react';
import { BookOpen, Database, Download, Menu, X } from 'lucide-react';
import { Link, useLocation } from 'react-router-dom';

export function Header() {
  const location = useLocation();
  const [menuOpen, setMenuOpen] = useState(false);

  // Close the mobile menu whenever the route changes
  useEffect(() => {
    setMenuOpen(false);
  }, [location.pathname]);

  const navItemClass = (active: boolean) =>
    `flex items-center gap-1.5 px-3 py-2 text-sm rounded-lg transition-colors ${
      active ? 'bg-slate-100 text-slate-900 font-semibold' : 'text-slate-600 hover:bg-slate-50'
    }`;

  return (
    <header className="border-b border-gray-200 bg-white sticky top-0 z-50 shadow-sm">
      <div className="max-w-7xl mx-auto px-4 sm:px-6 py-4 flex items-center justify-between gap-3 sm:gap-6">
        <Link to="/" className="flex items-center gap-3 hover:opacity-80 transition-opacity min-w-0">
          <div className="w-9 h-9 bg-slate-900 rounded-lg flex items-center justify-center shrink-0">
            <Database className="w-5 h-5 text-white" />
          </div>
          <div className="min-w-0">
            <div className="text-xl font-semibold text-slate-900 truncate">MuSProt</div>
            <div className="header-nav-subtitle text-xs text-slate-500 truncate">Multistate Protein Structure Database</div>
          </div>
        </Link>

        {/* Full nav — shown in landscape (W >= H) */}
        <nav className="header-nav-full items-center gap-2">
          <Link to="/" className={navItemClass(location.pathname === '/')}>
            <Database className="w-4 h-4 shrink-0" />
            Explorer
          </Link>
          <Link to="/docs" className={navItemClass(location.pathname === '/docs')}>
            <BookOpen className="w-4 h-4 shrink-0" />
            Docs
          </Link>
          <a
            href="/api/protein/download/db"
            className="flex items-center gap-1.5 px-4 py-2 text-sm font-medium text-white bg-slate-900 rounded-lg hover:bg-slate-700 transition-colors"
          >
            <Download className="w-4 h-4 shrink-0" />
            Download DB
          </a>
        </nav>

        {/* Menu toggle — shown only in portrait (W < H) */}
        <button
          type="button"
          aria-label="Toggle navigation menu"
          aria-expanded={menuOpen}
          onClick={() => setMenuOpen((open) => !open)}
          className="header-nav-toggle items-center justify-center p-2 rounded-lg text-slate-700 hover:bg-slate-100 transition-colors shrink-0"
        >
          {menuOpen ? <X className="w-6 h-6" /> : <Menu className="w-6 h-6" />}
        </button>
      </div>

      {/* Dropdown menu — portrait only */}
      {menuOpen && (
        <nav className="header-nav-dropdown border-t border-gray-200 bg-white px-4 py-3 flex-col gap-1">
          <Link to="/" className={navItemClass(location.pathname === '/')}>
            <Database className="w-4 h-4 shrink-0" />
            Explorer
          </Link>
          <Link to="/docs" className={navItemClass(location.pathname === '/docs')}>
            <BookOpen className="w-4 h-4 shrink-0" />
            Docs
          </Link>
          <a
            href="/api/protein/download/db"
            onClick={() => setMenuOpen(false)}
            className="flex items-center gap-1.5 px-3 py-2 text-sm font-medium text-white bg-slate-900 rounded-lg hover:bg-slate-700 transition-colors"
          >
            <Download className="w-4 h-4 shrink-0" />
            Download DB
          </a>
        </nav>
      )}
    </header>
  );
}