Files
afriadirahman 8c6dad2a31
tests / ci (push) Canceled after 0s
Admin Panel
2026-09-29 14:57:37 +07:00

130 lines
5.7 KiB
TypeScript

import { Link } from '@inertiajs/react';
import { useState } from 'react';
import Brand from '@/components/site/brand';
import { ButtonLink } from '@/components/site/button';
import Container from '@/components/site/container';
import Icon from '@/components/site/icon';
import LanguageToggle from '@/components/site/language-toggle';
import ThemeToggle from '@/components/site/theme-toggle';
import { common } from '@/content/common';
import { consultationUrl, navigation } from '@/data/site';
import { useCurrentUrl } from '@/hooks/use-current-url';
import { useContent } from '@/hooks/use-locale';
import { useSiteInfo } from '@/hooks/use-site-info';
import { cn } from '@/lib/utils';
export default function SiteHeader() {
const site = useSiteInfo();
const t = useContent(common);
const { isCurrentUrl } = useCurrentUrl();
const [menuOpen, setMenuOpen] = useState(false);
const closeMenu = () => setMenuOpen(false);
return (
<header className="border-outline-variant/40 bg-surface/85 fixed inset-x-0 top-0 z-50 border-b backdrop-blur-md">
<Container className="flex h-20 items-center justify-between gap-4">
<Brand />
<nav
aria-label={t.header.mainNav}
className="hidden items-center gap-8 lg:flex"
>
{navigation.map((item) => (
<Link
key={item.key}
href={item.href}
className={cn(
'hover:border-primary hover:text-on-surface border-b-2 pb-1 text-sm font-medium transition-all',
isCurrentUrl(item.href)
? 'border-primary text-on-surface font-semibold'
: 'text-on-surface-variant border-transparent',
)}
>
{t.nav[item.key]}
</Link>
))}
</nav>
<div className="flex items-center gap-2 sm:gap-3">
<div className="text-on-surface-variant hidden flex-col text-right font-mono text-[11px] 2xl:flex">
<a
href={site.phone.href}
className="text-on-surface hover:text-primary flex items-center justify-end gap-1 font-semibold"
>
<Icon
name="call"
className="text-primary text-xs"
/>
{site.phone.label}
</a>
<a
href={`mailto:${site.email.busdev}`}
className="hover:text-primary"
>
{site.email.busdev}
</a>
</div>
<LanguageToggle />
<ThemeToggle />
<ButtonLink
href={consultationUrl}
size="sm"
icon="support_agent"
className="hidden md:inline-flex"
>
{t.header.consult}
</ButtonLink>
<button
type="button"
aria-label={
menuOpen ? t.header.closeMenu : t.header.openMenu
}
aria-expanded={menuOpen}
onClick={() => setMenuOpen((open) => !open)}
className="border-outline-variant/50 bg-surface-container-low text-on-surface inline-flex h-10 w-10 cursor-pointer items-center justify-center rounded-xl border lg:hidden"
>
<Icon
name={menuOpen ? 'close' : 'menu'}
className="text-2xl"
/>
</button>
</div>
</Container>
{menuOpen && (
<nav
aria-label={t.header.mainNav}
className="border-outline-variant/40 bg-surface border-t lg:hidden"
>
<Container className="flex flex-col gap-1 py-4">
{navigation.map((item) => (
<Link
key={item.key}
href={item.href}
onClick={closeMenu}
className={cn(
'rounded-lg px-3 py-2.5 text-sm font-medium transition-colors',
isCurrentUrl(item.href)
? 'bg-surface-container-high text-on-surface'
: 'text-on-surface-variant hover:bg-surface-container hover:text-on-surface',
)}
>
{t.nav[item.key]}
</Link>
))}
<ButtonLink
href={consultationUrl}
size="sm"
icon="support_agent"
onClick={closeMenu}
className="mt-2 md:hidden"
>
{t.header.consult}
</ButtonLink>
</Container>
</nav>
)}
</header>
);
}