nomadweb/frontend/src/components/SiteShell.tsx
eric bdf0516197 Fix dating match gate and expand seed data for usable demos.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 06:18:25 -05:00

59 lines
1.6 KiB
TypeScript

"use client";
import { useEffect } from "react";
import dynamic from "next/dynamic";
import { usePathname, useRouter } from "next/navigation";
import Navbar from "./Navbar";
import ParticleCanvas from "./ParticleCanvas";
import Footer from "./Footer";
import GlobalSearch from "./GlobalSearch";
const KeyboardShortcuts = dynamic(() => import("./KeyboardShortcuts"), { ssr: false });
export default function SiteShell({ children, showFooter = false }: { children: React.ReactNode; showFooter?: boolean }) {
const pathname = usePathname();
const router = useRouter();
useEffect(() => {
const observer = new IntersectionObserver(
(entries) =>
entries.forEach((e) => {
if (e.isIntersecting) {
e.target.classList.add("visible");
observer.unobserve(e.target);
}
}),
{ threshold: 0.08, rootMargin: "0px 0px -40px 0px" }
);
const observeAll = () => {
document.querySelectorAll(".reveal:not(.visible)").forEach((el) => observer.observe(el));
};
observeAll();
const mo = new MutationObserver(() => observeAll());
mo.observe(document.body, { childList: true, subtree: true });
return () => {
observer.disconnect();
mo.disconnect();
};
}, []);
return (
<>
<ParticleCanvas />
<Navbar />
<GlobalSearch />
<KeyboardShortcuts
onOpenMatcher={() => {
if (pathname === "/") {
window.dispatchEvent(new Event("open-matcher"));
} else {
router.push("/#matcher");
}
}}
/>
{children}
{showFooter && <Footer />}
</>
);
}