Spaces:
Sleeping
Sleeping
| import React, { useState } from 'react' | |
| import { useData } from '../DataContext.jsx' | |
| import UploadModal from './UploadModal.jsx' | |
| const LS_KEY = 'genesis_active_file' | |
| export default function Header({ user, onLogout }) { | |
| const { stats, reload } = useData() | |
| const s = stats || {} | |
| const [uploadOpen, setUploadOpen] = useState(false) | |
| const [activeFile, setActiveFile] = useState( | |
| () => localStorage.getItem(LS_KEY) || '' | |
| ) | |
| function handleSuccess(filename) { | |
| if (filename) { | |
| setActiveFile(filename) | |
| localStorage.setItem(LS_KEY, filename) | |
| } | |
| reload() | |
| } | |
| return ( | |
| <> | |
| <header className="hdr"> | |
| <div className="hdr-left"> | |
| <img src="/dabur_logo.jpg" alt="Dabur" className="logo-d" /> | |
| <div className="hdr-brand-txt"> | |
| <div className="brand">{s.brand || 'Genesis AI'}</div> | |
| <div className="sub">Price Elasticity Intelligence Ā· Genesis AI</div> | |
| </div> | |
| <img src="/genesis_logo.jpg" alt="Genesis AI" className="logo-g" /> | |
| </div> | |
| <div className="hdr-right"> | |
| {/* Active file display */} | |
| <div style={{ | |
| display: 'flex', alignItems: 'center', gap: 7, | |
| background: activeFile ? 'rgba(26,107,47,.07)' : 'var(--sf)', | |
| border: `1px solid ${activeFile ? 'rgba(26,107,47,.25)' : 'var(--bd)'}`, | |
| borderRadius: 8, padding: '5px 11px', | |
| minWidth: 160, maxWidth: 280, | |
| }}> | |
| <span style={{ fontSize: 14, flexShrink: 0 }}> | |
| {activeFile ? 'š' : 'š'} | |
| </span> | |
| <div style={{ minWidth: 0 }}> | |
| <div style={{ | |
| fontSize: 9, fontWeight: 600, letterSpacing: .5, | |
| color: activeFile ? 'var(--gn)' : 'var(--mt)', | |
| textTransform: 'uppercase', lineHeight: 1, | |
| }}> | |
| {activeFile ? 'Simulating' : 'No file loaded'} | |
| </div> | |
| {activeFile ? ( | |
| <div style={{ | |
| fontSize: 10, color: 'var(--tx)', fontFamily: 'var(--mono)', | |
| whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', | |
| maxWidth: 200, marginTop: 2, lineHeight: 1.2, | |
| }}> | |
| {activeFile} | |
| </div> | |
| ) : ( | |
| <div style={{ fontSize: 10, color: 'var(--mt)', marginTop: 2, lineHeight: 1.2 }}> | |
| Upload an Excel file to begin | |
| </div> | |
| )} | |
| </div> | |
| </div> | |
| {/* Upload button ā always visible */} | |
| <button | |
| onClick={() => setUploadOpen(true)} | |
| title={activeFile ? 'Replace current file' : 'Upload Excel file'} | |
| style={{ | |
| display: 'flex', alignItems: 'center', gap: 5, | |
| background: activeFile ? 'var(--sf)' : 'var(--gn)', | |
| color: activeFile ? 'var(--gn)' : '#fff', | |
| border: activeFile ? '1px solid rgba(26,107,47,.4)' : 'none', | |
| borderRadius: 8, | |
| padding: '6px 13px', cursor: 'pointer', | |
| fontSize: 11, fontWeight: 600, | |
| boxShadow: activeFile ? 'none' : '0 1px 4px rgba(26,107,47,.25)', | |
| flexShrink: 0, | |
| }}> | |
| {activeFile ? 'ā Replace' : 'ā Upload'} | |
| </button> | |
| <div className="bdg">30 grains</div> | |
| {s.dab_cr_25 && ( | |
| <div className="hdr-stat"> | |
| <span className="val">ā¹{s.dab_cr_25?.toFixed(1)}Cr</span> | |
| <span className="lbl">2025 Value</span> | |
| </div> | |
| )} | |
| {s.vol_growth != null && ( | |
| <div className="hdr-stat"> | |
| <span className="val" style={{ color: s.vol_growth >= 0 ? 'var(--gn)' : 'var(--rd)' }}> | |
| {s.vol_growth >= 0 ? '+' : ''}{s.vol_growth?.toFixed(1)}% | |
| </span> | |
| <span className="lbl">Vol Growth</span> | |
| </div> | |
| )} | |
| {s.avg_own_e != null && ( | |
| <div className="hdr-stat"> | |
| <span className="val" style={{ color: 'var(--saf)' }}>{s.avg_own_e?.toFixed(2)}</span> | |
| <span className="lbl">Avg Own ε</span> | |
| </div> | |
| )} | |
| {/* Logged-in user + logout */} | |
| {user && ( | |
| <div style={{ | |
| display: 'flex', alignItems: 'center', gap: 8, | |
| borderLeft: '1px solid var(--bd)', paddingLeft: 12, marginLeft: 4, | |
| }}> | |
| <div style={{ textAlign: 'right' }}> | |
| <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--tx)', lineHeight: 1.2 }}> | |
| {user.name} | |
| </div> | |
| <div style={{ fontSize: 9, color: 'var(--mt)', lineHeight: 1.2 }}> | |
| {user.email} | |
| </div> | |
| </div> | |
| <button | |
| onClick={onLogout} | |
| title="Sign out" | |
| style={{ | |
| background: 'var(--sf)', border: '1px solid var(--bd)', | |
| borderRadius: 7, padding: '5px 10px', | |
| fontSize: 11, fontWeight: 600, color: 'var(--mt)', | |
| cursor: 'pointer', flexShrink: 0, | |
| }}> | |
| Sign out | |
| </button> | |
| </div> | |
| )} | |
| </div> | |
| </header> | |
| <UploadModal | |
| open={uploadOpen} | |
| onClose={() => setUploadOpen(false)} | |
| onSuccess={handleSuccess} | |
| /> | |
| </> | |
| ) | |
| } | |