Import source: src/components/Navbar/Navbar
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
import { useState } from 'react';
|
||||
import { useTheme } from '../../context/ThemeContext';
|
||||
import { BatchModal } from '../BatchModal';
|
||||
|
||||
function QRIcon() {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 22 22" fill="none">
|
||||
<rect x="1" y="1" width="8" height="8" rx="1.5" stroke="#7C6FE0" strokeWidth="1.8"/>
|
||||
<rect x="3.5" y="3.5" width="3" height="3" rx="0.5" fill="#7C6FE0"/>
|
||||
<rect x="13" y="1" width="8" height="8" rx="1.5" stroke="#A78BFA" strokeWidth="1.8"/>
|
||||
<rect x="15.5" y="3.5" width="3" height="3" rx="0.5" fill="#A78BFA"/>
|
||||
<rect x="1" y="13" width="8" height="8" rx="1.5" stroke="#7C6FE0" strokeWidth="1.8"/>
|
||||
<rect x="3.5" y="15.5" width="3" height="3" rx="0.5" fill="#7C6FE0"/>
|
||||
<rect x="13" y="13" width="3" height="3" rx="0.5" fill="#A78BFA"/>
|
||||
<rect x="18" y="13" width="3" height="3" rx="0.5" fill="#A78BFA"/>
|
||||
<rect x="13" y="18" width="3" height="3" rx="0.5" fill="#7C6FE0"/>
|
||||
<rect x="18" y="18" width="3" height="3" rx="0.5" fill="#7C6FE0"/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function SunIcon() {
|
||||
return (
|
||||
<svg width="17" height="17" viewBox="0 0 18 18" fill="none">
|
||||
<circle cx="9" cy="9" r="3.5" stroke="currentColor" strokeWidth="1.6"/>
|
||||
<line x1="9" y1="1.5" x2="9" y2="3" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
|
||||
<line x1="9" y1="15" x2="9" y2="16.5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
|
||||
<line x1="1.5" y1="9" x2="3" y2="9" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
|
||||
<line x1="15" y1="9" x2="16.5" y2="9" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
|
||||
<line x1="3.4" y1="3.4" x2="4.5" y2="4.5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
|
||||
<line x1="13.5" y1="13.5" x2="14.6" y2="14.6" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
|
||||
<line x1="14.6" y1="3.4" x2="13.5" y2="4.5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
|
||||
<line x1="4.5" y1="13.5" x2="3.4" y2="14.6" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function MoonIcon() {
|
||||
return (
|
||||
<svg width="15" height="15" viewBox="0 0 17 17" fill="none">
|
||||
<path d="M14.5 10.5A7 7 0 0 1 6.5 2.5a7 7 0 0 0 8 8z"
|
||||
stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
const navBtnBase: React.CSSProperties = {
|
||||
background: 'var(--bg-elevated)',
|
||||
border: '1px solid var(--border-sub)',
|
||||
color: 'var(--text-secondary)',
|
||||
cursor: 'pointer',
|
||||
};
|
||||
|
||||
export function Navbar() {
|
||||
const { isDark, toggle } = useTheme();
|
||||
const [batchOpen, setBatchOpen] = useState(false);
|
||||
|
||||
const onHover = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
(e.currentTarget as HTMLElement).style.borderColor = 'rgba(124,111,224,0.5)';
|
||||
(e.currentTarget as HTMLElement).style.color = '#7C6FE0';
|
||||
};
|
||||
const onLeave = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
(e.currentTarget as HTMLElement).style.borderColor = 'var(--border-sub)';
|
||||
(e.currentTarget as HTMLElement).style.color = 'var(--text-secondary)';
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<nav
|
||||
className="flex-shrink-0 flex items-center relative z-10"
|
||||
style={{
|
||||
height: 'var(--nav-h)',
|
||||
background: 'var(--bg-panel)',
|
||||
borderBottom: '1px solid var(--border)',
|
||||
paddingLeft: 'max(16px, env(safe-area-inset-left))',
|
||||
paddingRight: 'max(16px, env(safe-area-inset-right))',
|
||||
}}
|
||||
>
|
||||
<div className="absolute bottom-0 left-0 right-0 h-px pointer-events-none"
|
||||
style={{ background: 'linear-gradient(90deg, transparent, var(--navbar-glow), transparent)' }} />
|
||||
|
||||
{/* Logo */}
|
||||
<div className="flex items-center gap-2 sm:gap-3 flex-shrink-0">
|
||||
<div className="w-7 h-7 sm:w-8 sm:h-8 rounded-[8px] sm:rounded-[9px] flex items-center justify-center"
|
||||
style={{ background: 'rgba(124,111,224,0.12)', border: '1px solid rgba(124,111,224,0.25)' }}>
|
||||
<QRIcon />
|
||||
</div>
|
||||
<div className="flex items-baseline gap-1.5 sm:gap-2">
|
||||
<span style={{
|
||||
fontFamily: '"Unbounded", sans-serif', fontWeight: 900,
|
||||
fontSize: 'clamp(12px, 2vw, 15px)', letterSpacing: '-0.02em',
|
||||
background: 'linear-gradient(135deg, #7C6FE0 0%, #A78BFA 55%, #C084FC 100%)',
|
||||
WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', lineHeight: 1,
|
||||
}}>CQRC</span>
|
||||
<span className="hidden sm:inline" style={{
|
||||
fontFamily: '"Unbounded", sans-serif', fontWeight: 700,
|
||||
fontSize: 'clamp(9px, 1.2vw, 11px)', letterSpacing: '0.04em',
|
||||
color: 'var(--text-secondary)', lineHeight: 1,
|
||||
}}>Platform</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex-1" />
|
||||
|
||||
<div className="flex items-center gap-1.5 sm:gap-2">
|
||||
<button onClick={() => setBatchOpen(true)}
|
||||
className="flex items-center gap-1.5 h-8 sm:h-9 px-2.5 sm:px-3 rounded-[9px] sm:rounded-[10px] text-[12px] sm:text-[13px] font-medium transition-all"
|
||||
style={navBtnBase} onMouseEnter={onHover} onMouseLeave={onLeave}>
|
||||
<svg width="14" height="14" viewBox="0 0 15 15" fill="none">
|
||||
<rect x="1" y="1" width="5" height="5" rx="1" stroke="currentColor" strokeWidth="1.4"/>
|
||||
<rect x="9" y="1" width="5" height="5" rx="1" stroke="currentColor" strokeWidth="1.4"/>
|
||||
<rect x="1" y="9" width="5" height="5" rx="1" stroke="currentColor" strokeWidth="1.4"/>
|
||||
<rect x="9" y="9" width="5" height="5" rx="1" stroke="currentColor" strokeWidth="1.4"/>
|
||||
</svg>
|
||||
<span className="hidden sm:inline">Batch</span>
|
||||
</button>
|
||||
|
||||
<button onClick={toggle} title={isDark ? 'Light mode' : 'Dark mode'}
|
||||
className="flex items-center gap-1.5 h-8 sm:h-9 px-2.5 sm:px-3 rounded-[9px] sm:rounded-[10px] text-[12px] sm:text-[13px] font-medium transition-all"
|
||||
style={navBtnBase} onMouseEnter={onHover} onMouseLeave={onLeave}>
|
||||
<span style={{ transition: 'transform 0.4s', transform: isDark ? 'rotate(0deg)' : 'rotate(180deg)', display: 'flex' }}>
|
||||
{isDark ? <SunIcon /> : <MoonIcon />}
|
||||
</span>
|
||||
<span className="hidden sm:inline">{isDark ? 'Light' : 'Dark'}</span>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<BatchModal isOpen={batchOpen} onClose={() => setBatchOpen(false)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user