File size: 3,401 Bytes
05b4ab1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
539ec6f
05b4ab1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
// src/components/Header.jsx
import React, { useEffect, useState } from 'react'
import { healthCheck } from '../lib/api'

const NAV_LINKS = [
  { label: 'Dashboard', action: () => window.scrollTo({ top: 0, behavior: 'smooth' }) },
  { label: 'Pipeline',  action: () => document.getElementById('pipeline-section')?.scrollIntoView({ behavior: 'smooth' }) },
  { label: 'Docs',      action: () => window.open('http://localhost:8000/docs', '_blank') },
  { label: 'GitHub',    action: () => window.open('https://github.com/', '_blank') },
]

export default function Header() {
  const [apiStatus, setApiStatus] = useState('checking')
  const [activeNav, setActiveNav] = useState('Dashboard')

  useEffect(() => {
    healthCheck()
      .then(() => setApiStatus('online'))
      .catch(() => setApiStatus('offline'))
  }, [])

  const statusDot = {
    checking: 'bg-amber animate-pulse',
    online:   'bg-green',
    offline:  'bg-red',
  }[apiStatus]

  const statusLabel = {
    checking: 'Connecting…',
    online:   'API Online',
    offline:  'Demo Mode',
  }[apiStatus]

  return (
    <header className="flex items-center justify-between px-6 py-4 border-b border-[#1a3a6e40] bg-[#050d1b] sticky top-0 z-50">
      {/* Logo */}
      <div
        className="flex items-center gap-3 cursor-pointer"
        onClick={() => { setActiveNav('Dashboard'); window.scrollTo({ top: 0, behavior: 'smooth' }) }}
      >
        <div className="w-8 h-8 rounded-md bg-teal flex items-center justify-center">
          <span className="font-mono font-bold text-bg text-[11px]">EM</span>
        </div>
        <div>
          <div className="font-display font-semibold text-[15px] gradient-text">perceive_ai</div>
          <div className="font-mono text-[9px] text-muted tracking-[0.1em]">MULTIMODAL EMOTIONAL INTELLIGENCE</div>
        </div>
      </div>

      {/* Center nav */}
      <nav className="hidden md:flex items-center gap-1">
        {NAV_LINKS.map(({ label, action }) => {
          const isActive = activeNav === label
          return (
            <button
              key={label}
              onClick={() => { setActiveNav(label); action() }}
              className={`
                font-mono text-[11px] px-4 py-2 rounded-md border transition-all duration-150 cursor-pointer
                ${isActive
                  ? 'text-teal bg-[#0ec9a815] border-[#0ec9a830]'
                  : 'text-muted bg-transparent border-transparent hover:text-[#cfe2f7] hover:bg-[#0c1e38]'}
              `}
            >
              {label}
            </button>
          )
        })}
      </nav>

      {/* Status */}
      <div className="flex items-center gap-3">
        <div className="flex items-center gap-1.5 bg-[#081527] border border-[#1a3a6e40] rounded-full px-3 py-1.5">
          <span className={`w-[6px] h-[6px] rounded-full flex-shrink-0 ${statusDot}`} />
          <span className="font-mono text-[10px] text-muted">{statusLabel}</span>
        </div>
        <button
          onClick={() => window.open('http://localhost:8000/docs', '_blank')}
          className="hidden sm:flex items-center gap-1 bg-[#081527] border border-[#1a3a6e40] rounded-full px-3 py-1.5 cursor-pointer hover:border-teal transition-colors duration-150"
        >
          <span className="font-mono text-[10px] text-muted">FastAPI :8000</span>
        </button>
      </div>
    </header>
  )
}