satupeta-main/shared/components/layout/menu-header.tsx
2026-01-27 09:31:12 +07:00

137 lines
4.2 KiB
TypeScript

"use client";
import React from "react";
import { usePathname, useRouter } from "next/navigation";
import { appConfig, isActiveFeature } from "@/shared/config/app-config";
import { useAuthSession } from "@/shared/hooks/use-session";
import Image from "next/image";
import Link from "next/link";
import { handleLogout } from "@/shared/hooks/use-auth-api";
import { cn } from "@/shared/utils/utils";
import { Button } from "../button/button";
const navigation = [
{ name: "Katalog", href: "#catalog" },
{ name: "OPD", href: "#organization" },
// { name: "Statistik", href: "#statistic" },
isActiveFeature.news && { name: "Berita", href: "#news" },
];
export function MenuHeader() {
const [isScrolled, setIsScrolled] = React.useState(false);
const pathname = usePathname();
const router = useRouter();
const { session, isAuthenticated } = useAuthSession();
React.useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 10);
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
const handleNavigation = (
e: React.MouseEvent<HTMLAnchorElement>,
href: string,
) => {
e.preventDefault();
const fixedHeaderHeight = 85;
if (pathname === "/") {
const targetElement = document.querySelector(href);
if (targetElement) {
const elementTop =
targetElement.getBoundingClientRect().top + window.pageYOffset;
const offsetTop = elementTop - fixedHeaderHeight;
window.scrollTo({
top: offsetTop,
behavior: "smooth",
});
}
} else {
router.push(`/${href}`);
}
};
const handleLogin = () => {
router.push("/auth/admin/login?callbackUrl=/admin");
};
return (
<header
className={cn(
"font-onest fixed top-0 right-0 left-0 z-[1005] h-20 border-b border-zinc-200 bg-white text-white transition-all duration-300",
isScrolled ?? "shadow-sm",
)}
>
<div className="container h-full">
<div className="flex h-full items-center justify-between">
<div className="flex items-center">
<Link href="/" className="h-auto w-40">
<Image
src={appConfig.logo}
alt="Satu Peta"
width={120}
height={120}
className="w-auto"
/>
</Link>
</div>
{/* list menu */}
<nav className="hidden md:flex md:items-center md:gap-x-12">
{navigation.map(
(item) =>
item && (
<a
key={item.name}
href={item.href}
onClick={(e) => handleNavigation(e, item.href)}
className="hover:text-primary text-md text-biru-500 transition-colors"
>
{item.name}
</a>
),
)}
{isAuthenticated ? (
<div className="flex items-center gap-4">
<span className="text-dark-300 font-onest text-sm">
Hi, {session?.user?.name}
</span>
<Button variant="outlined" size="sm" onClick={handleLogout}>
Logout
</Button>
</div>
) : (
<Button variant="primary" onClick={handleLogin}>
MASUK
</Button>
)}
<Button variant="outlined" size="icon" className="ml-2 md:hidden">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</Button>
</nav>
</div>
</div>
</header>
);
}