2026-04-23 20:52:43 +03:00
|
|
|
'use client';
|
2026-04-19 08:40:08 +03:00
|
|
|
|
2026-04-23 20:52:43 +03:00
|
|
|
import { useState } from 'react';
|
|
|
|
|
import { cn } from '$shared/lib';
|
|
|
|
|
import type { NavItem } from '../model/types';
|
2026-04-19 08:40:08 +03:00
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
/**
|
|
|
|
|
* Navigation items to render
|
|
|
|
|
*/
|
2026-04-23 20:52:43 +03:00
|
|
|
items: NavItem[];
|
2026-04-19 08:40:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Mobile navigation overlay, hidden on lg+ screens.
|
|
|
|
|
*/
|
|
|
|
|
export function MobileNav({ items }: Props) {
|
2026-04-23 20:52:43 +03:00
|
|
|
const [isOpen, setIsOpen] = useState(false);
|
2026-04-19 08:40:08 +03:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Scrolls to the section by id with a 100px offset, then closes the menu.
|
|
|
|
|
*/
|
|
|
|
|
function scrollToSection(id: string) {
|
2026-04-23 20:52:43 +03:00
|
|
|
const el = document.getElementById(id);
|
2026-04-19 08:40:08 +03:00
|
|
|
if (el) {
|
2026-04-23 20:52:43 +03:00
|
|
|
const top = el.getBoundingClientRect().top + window.scrollY - 100;
|
|
|
|
|
window.scrollTo({ top, behavior: 'smooth' });
|
2026-04-19 08:40:08 +03:00
|
|
|
}
|
2026-04-23 20:52:43 +03:00
|
|
|
setIsOpen(false);
|
2026-04-19 08:40:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="lg:hidden fixed top-0 left-0 right-0 bg-ochre-clay brutal-border-bottom z-50">
|
|
|
|
|
<div className="px-6 py-4 flex items-center justify-between">
|
|
|
|
|
<h4>allmy.work</h4>
|
|
|
|
|
<button
|
2026-04-24 08:38:00 +03:00
|
|
|
type="button"
|
2026-04-23 20:52:43 +03:00
|
|
|
onClick={() => setIsOpen((prev) => !prev)}
|
2026-04-19 08:40:08 +03:00
|
|
|
className="brutal-border px-4 py-2 bg-carbon-black text-ochre-clay"
|
|
|
|
|
>
|
|
|
|
|
{isOpen ? 'Close' : 'Menu'}
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
{isOpen && (
|
|
|
|
|
<div className="px-6 py-6 brutal-border-top space-y-2 max-h-[80vh] overflow-y-auto">
|
2026-04-23 20:52:43 +03:00
|
|
|
{items.map((item) => (
|
2026-04-19 08:40:08 +03:00
|
|
|
<button
|
2026-04-24 08:38:00 +03:00
|
|
|
type="button"
|
2026-04-19 08:40:08 +03:00
|
|
|
key={item.id}
|
|
|
|
|
onClick={() => scrollToSection(item.id)}
|
|
|
|
|
className="w-full text-left brutal-border bg-ochre-clay px-4 py-3"
|
|
|
|
|
>
|
|
|
|
|
<div className={cn('flex items-baseline gap-3')}>
|
|
|
|
|
<span className="text-sm opacity-60 font-body">{item.number}</span>
|
|
|
|
|
<span
|
|
|
|
|
className="font-heading text-lg font-black"
|
|
|
|
|
style={{ fontVariationSettings: '"WONK" 1, "SOFT" 0' }}
|
|
|
|
|
>
|
|
|
|
|
{item.label}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</button>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
2026-04-23 20:52:43 +03:00
|
|
|
);
|
2026-04-19 08:40:08 +03:00
|
|
|
}
|