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:
arsam
2026-09-18 23:17:06 +03:30
parent 8565b4ef39
commit 8f7490beb4
+132
View File
@@ -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)} />
</>
);
}