новый лендинг

This commit is contained in:
2026-04-26 16:09:08 +04:00
parent 103e2bc4cf
commit 7701aa16c0
24 changed files with 6368 additions and 341 deletions
+118
View File
@@ -0,0 +1,118 @@
import { useEffect, useState } from 'react';
import { Icons, MoonMark, getBootstrap } from './atoms.jsx';
export default function Nav() {
const [scrolled, setScrolled] = useState(false);
const [open, setOpen] = useState(false);
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 40);
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
useEffect(() => {
document.body.style.overflow = open ? 'hidden' : '';
return () => { document.body.style.overflow = ''; };
}, [open]);
const close = () => setOpen(false);
const links = [
{ href: '#about', label: 'О сервере' },
{ href: '#features', label: 'Особенности' },
{ href: '#join', label: 'Регистрация' },
{ href: '#news', label: 'Новости' },
];
const bootstrap = getBootstrap();
const auth = bootstrap.auth || {};
const playUrl = bootstrap.play_url || '#join';
return (
<nav className={`nav ${scrolled ? 'scrolled' : ''}`}>
<div className="wrap nav-inner">
<a href="#" className="nav-logo" onClick={close}>
<span className="nav-logo-mark" style={{ color: 'var(--moon)' }}>
<MoonMark size={32} />
</span>
<span>MoonWell</span>
</a>
<div className="nav-links nav-links-desktop">
{links.map((l) => (
<a key={l.href} href={l.href}>{l.label}</a>
))}
{auth.is_admin && <a href={auth.admin_url}>Админка</a>}
<a
href={auth.authenticated ? auth.cabinet_url : (auth.login_url || '/login')}
className="nav-cta"
>
{auth.authenticated ? 'Личный кабинет' : 'Войти в кабинет'}
<span style={{ color: 'var(--moon)' }}>{Icons.arrow}</span>
</a>
<a href={playUrl} className="nav-cta">
Играть <span style={{ color: 'var(--moon)' }}>{Icons.arrow}</span>
</a>
</div>
<button
className={`nav-burger ${open ? 'is-open' : ''}`}
onClick={() => setOpen((v) => !v)}
aria-label={open ? 'Закрыть меню' : 'Открыть меню'}
aria-expanded={open}
>
<span></span>
<span></span>
<span></span>
</button>
</div>
<div
className={`nav-drawer-backdrop ${open ? 'is-open' : ''}`}
onClick={close}
aria-hidden="true"
/>
<aside className={`nav-drawer ${open ? 'is-open' : ''}`} aria-hidden={!open}>
<div className="nav-drawer-head">
<span className="eyebrow">Навигация</span>
</div>
<div className="nav-drawer-links">
{links.map((l, i) => (
<a
key={l.href}
href={l.href}
onClick={close}
style={{ transitionDelay: `${60 + i * 40}ms` }}
>
<span className="num">{String(i + 1).padStart(2, '0')}</span>
<span className="lbl">{l.label}</span>
<span className="arr">{Icons.arrow}</span>
</a>
))}
<a
href={auth.authenticated ? auth.cabinet_url : (auth.login_url || '/login')}
onClick={close}
>
<span className="num">{String(links.length + 1).padStart(2, '0')}</span>
<span className="lbl">{auth.authenticated ? 'Личный кабинет' : 'Войти в кабинет'}</span>
<span className="arr">{Icons.arrow}</span>
</a>
{auth.is_admin && (
<a href={auth.admin_url} onClick={close}>
<span className="num">{String(links.length + 2).padStart(2, '0')}</span>
<span className="lbl">Админка</span>
<span className="arr">{Icons.arrow}</span>
</a>
)}
</div>
<a href={playUrl} className="btn btn-primary nav-drawer-cta" onClick={close}>
Играть {Icons.arrow}
</a>
<div className="nav-drawer-foot">
<span className="eyebrow" style={{ color: 'var(--text-mute)' }}>moonwell · 3.3.5a</span>
</div>
</aside>
</nav>
);
}