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