Najjar\NajjarV02 9394b58b0e
Some checks are pending
CI/CD / test-and-build (push) Waiting to run
CI/CD / deploy (push) Blocked by required conditions
feat: initialize Lootah Robotics web application with 3D configurator and scroll-driven UI components
2026-04-20 11:36:04 +04:00

217 lines
7.4 KiB
TypeScript

'use client';
import React, { useState, useEffect } from 'react';
import Link from 'next/link';
export function Navbar() {
const [scrolled, setScrolled] = useState(false);
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
useEffect(() => {
const handleScroll = () => {
setScrolled(window.scrollY > 20);
};
window.addEventListener('scroll', handleScroll, { passive: true });
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const navLinks = [
{ label: 'Contact', href: '#contact' }
];
const handleNavClick = (e: React.MouseEvent<HTMLAnchorElement>, link: any) => {
if (link.progress !== undefined) {
e.preventDefault();
setMobileMenuOpen(false);
// We have 7 snap-sections of 100vh each. Max scroll inside the scene is 600vh.
const targetScroll = link.progress * (6 * window.innerHeight);
window.scrollTo({ top: targetScroll, behavior: 'smooth' });
}
};
return (
<>
<nav
style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
zIndex: 100,
background: scrolled ? 'rgba(255, 255, 255, 0.85)' : 'transparent',
backdropFilter: scrolled ? 'blur(16px)' : 'none',
WebkitBackdropFilter: scrolled ? 'blur(16px)' : 'none',
borderBottom: scrolled ? '1px solid rgba(0,0,0,0.05)' : '1px solid transparent',
transition: 'all 0.4s cubic-bezier(0.16, 1, 0.3, 1)',
padding: scrolled ? '1rem 2rem' : '1.5rem 2rem',
}}
>
<div style={{ maxWidth: '1280px', margin: '0 auto', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
{/* Logo */}
<Link href="/" style={{ textDecoration: 'none', display: 'flex', alignItems: 'center', gap: '0.75rem' }}>
<span style={{
fontSize: '1.1rem',
fontWeight: 700,
color: 'var(--color-gold)',
letterSpacing: '0.15em',
textTransform: 'uppercase',
textShadow: scrolled ? 'none' : '0 2px 10px rgba(0,0,0,0.1)'
}}>
YS Lootah
</span>
<span style={{
fontSize: '1.1rem',
fontWeight: 300,
color: scrolled ? '#1a1a2e' : '#1a1a2e',
letterSpacing: '0.15em',
textTransform: 'uppercase'
}}>
Robotics
</span>
</Link>
{/* Desktop Links */}
<div className="hidden md:flex" style={{ alignItems: 'center', gap: '3rem' }}>
{navLinks.map((link) => (
<Link
key={link.label}
href={link.href || '#'}
onClick={(e) => handleNavClick(e, link)}
style={{
color: scrolled ? '#64748b' : '#1a1a2e',
fontSize: '0.85rem',
fontWeight: 600,
textDecoration: 'none',
textTransform: 'uppercase',
letterSpacing: '0.1em',
transition: 'color 0.2s',
textShadow: scrolled ? 'none' : '0 2px 10px rgba(255,255,255,0.2)'
}}
onMouseOver={(e) => e.currentTarget.style.color = 'var(--color-gold)'}
onMouseOut={(e) => e.currentTarget.style.color = scrolled ? '#64748b' : '#1a1a2e'}
>
{link.label}
</Link>
))}
</div>
{/* Action Button & Hamburger */}
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
<Link
href="/configure/"
className="hidden md:flex"
style={{
alignItems: 'center',
justifyContent: 'center',
padding: '0.75rem 1.5rem',
borderRadius: '2rem',
background: scrolled ? '#1a1a2e' : 'var(--color-gold)',
color: '#ffffff',
fontSize: '0.85rem',
fontWeight: 600,
textDecoration: 'none',
textTransform: 'uppercase',
letterSpacing: '0.05em',
transition: 'all 0.3s',
boxShadow: scrolled ? 'none' : '0 4px 14px rgba(196, 162, 101, 0.3)',
}}
onMouseOver={(e) => {
e.currentTarget.style.transform = 'translateY(-1px)';
e.currentTarget.style.boxShadow = scrolled ? '0 4px 14px rgba(26, 26, 46, 0.2)' : '0 6px 20px rgba(196, 162, 101, 0.4)';
}}
onMouseOut={(e) => {
e.currentTarget.style.transform = 'translateY(0)';
e.currentTarget.style.boxShadow = scrolled ? 'none' : '0 4px 14px rgba(196, 162, 101, 0.3)';
}}
>
Configure G1
</Link>
{/* Mobile Menu Toggle */}
<button
className="md:hidden"
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
style={{
background: 'transparent',
border: 'none',
cursor: 'pointer',
color: scrolled ? '#1a1a2e' : 'var(--color-gold)',
padding: '0.5rem',
}}
>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
{mobileMenuOpen ? (
<path d="M18 6L6 18M6 6l12 12" />
) : (
<path d="M4 12h16M4 6h16M4 18h16" />
)}
</svg>
</button>
</div>
</div>
</nav>
{/* Mobile Menu Dropdown */}
<div
className="md:hidden"
style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
background: '#ffffff',
zIndex: 90,
display: mobileMenuOpen ? 'block' : 'none',
paddingTop: '6rem',
}}
>
<div style={{ display: 'flex', flexDirection: 'column', padding: '0 2rem', gap: '2rem' }}>
{navLinks.map((link) => (
<Link
key={link.label}
href={link.href || '#'}
onClick={(e) => handleNavClick(e, link)}
style={{
color: '#1a1a2e',
fontSize: '1.4rem',
fontWeight: 300,
textDecoration: 'none',
textTransform: 'uppercase',
letterSpacing: '0.1em',
borderBottom: '1px solid #f1f5f9',
paddingBottom: '1rem',
}}
>
{link.label}
</Link>
))}
<Link
href="/configure/"
onClick={() => setMobileMenuOpen(false)}
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: '1.25rem',
borderRadius: '3rem',
background: 'var(--color-gold)',
color: '#ffffff',
fontSize: '1.1rem',
fontWeight: 600,
textDecoration: 'none',
textTransform: 'uppercase',
letterSpacing: '0.1em',
marginTop: '1rem',
boxShadow: '0 4px 14px rgba(196, 162, 101, 0.3)',
}}
>
Configure Your G1
</Link>
</div>
</div>
</>
);
}