mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-07 23:29:36 -06:00
167 lines
7.1 KiB
TypeScript
167 lines
7.1 KiB
TypeScript
import { useCallback, useEffect, useState } from "react";
|
|
import Link from "next/link";
|
|
import { useRouter } from "next/router";
|
|
import clsx from "clsx";
|
|
|
|
import { Hero } from "@/components/shared/Hero";
|
|
import { FooterLogo, Logomark } from "@/components/shared/Logo";
|
|
import { MobileNavigation } from "@/components/shared/MobileNavigation";
|
|
import { Navigation } from "@/components/shared/Navigation";
|
|
import { Prose } from "@/components/shared/Prose";
|
|
import { Search } from "@/components/shared/Search";
|
|
import { ThemeSelector } from "@/components/shared/ThemeSelector";
|
|
import navigation from "@/lib/docsNavigation";
|
|
import Button from "../shared/Button";
|
|
import MetaInformation from "../shared/MetaInformation";
|
|
|
|
function GitHubIcon(props: any) {
|
|
return (
|
|
<svg aria-hidden="true" viewBox="0 0 16 16" {...props}>
|
|
<path d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
function Header({ navigation }: any) {
|
|
const router = useRouter();
|
|
let [isScrolled, setIsScrolled] = useState(false);
|
|
|
|
useEffect(() => {
|
|
function onScroll() {
|
|
setIsScrolled(window.scrollY > 0);
|
|
}
|
|
onScroll();
|
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
return () => {
|
|
window.removeEventListener("scroll", onScroll);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<header
|
|
className={clsx(
|
|
"sticky top-0 z-50 flex flex-wrap items-center justify-between bg-white px-4 py-5 shadow-md shadow-slate-900/5 transition duration-500 dark:shadow-none sm:px-6 lg:px-8",
|
|
isScrolled
|
|
? "dark:bg-slate-900/95 dark:backdrop-blur dark:[@supports(backdrop-filter:blur(0))]:bg-slate-900/75"
|
|
: "dark:bg-transparent"
|
|
)}>
|
|
<div className="mr-6 flex lg:hidden">
|
|
<MobileNavigation navigation={navigation} />
|
|
</div>
|
|
<div className="relative flex flex-grow basis-0 items-center">
|
|
<Link href="/" aria-label="Home page">
|
|
<Logomark className="h-9 w-9 lg:hidden" />
|
|
<FooterLogo className="hidden h-9 w-auto fill-slate-700 dark:fill-slate-100 lg:block" />
|
|
</Link>
|
|
<div>
|
|
<Button
|
|
variant="secondary"
|
|
onClick={() => router.push("/")}
|
|
size="sm"
|
|
className="ml-10 hidden justify-center opacity-60 sm:flex">
|
|
← Back to Mainpage
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
<div className="-my-5 mr-6 sm:mr-8 md:mr-0">
|
|
<Search />
|
|
</div>
|
|
<div className="relative flex basis-0 justify-end gap-6 sm:gap-8 md:flex-grow">
|
|
<ThemeSelector className="relative z-10" />
|
|
<Link href="https://github.com" className="group" aria-label="GitHub">
|
|
<GitHubIcon className="h-6 w-6 fill-slate-400 group-hover:fill-slate-500 dark:group-hover:fill-slate-300" />
|
|
</Link>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|
|
|
|
interface LayoutProps {
|
|
children: React.ReactNode;
|
|
meta: {
|
|
title: string;
|
|
};
|
|
}
|
|
|
|
export function Layout({ children, meta }: LayoutProps) {
|
|
let router = useRouter();
|
|
let isHomePage = router.pathname === "/";
|
|
let allLinks = navigation.flatMap((section) => section.links);
|
|
let linkIndex = allLinks.findIndex((link) => link.href === router.pathname);
|
|
let previousPage = allLinks[linkIndex - 1];
|
|
let nextPage = allLinks[linkIndex + 1];
|
|
let section = navigation.find((section) => section.links.find((link) => link.href === router.pathname));
|
|
|
|
return (
|
|
<>
|
|
<MetaInformation
|
|
title="Formbricks Documentation"
|
|
description="Modular, customizable, extendable. Take what you like, build on top what you need. Build your next big thing faster."
|
|
/>
|
|
<Header navigation={navigation} />
|
|
|
|
{isHomePage && <Hero />}
|
|
|
|
<div className="max-w-8xl relative mx-auto flex justify-center sm:px-2 lg:px-8 xl:px-12">
|
|
<div className="hidden lg:relative lg:block lg:flex-none">
|
|
<div className="absolute inset-y-0 right-0 w-[50vw] bg-slate-50 dark:hidden" />
|
|
<div className="absolute top-16 bottom-0 right-0 hidden h-12 w-px bg-gradient-to-t from-slate-800 dark:block" />
|
|
<div className="absolute top-28 bottom-0 right-0 hidden w-px bg-slate-800 dark:block" />
|
|
<div className="sticky top-[4.5rem] -ml-0.5 h-[calc(100vh-4.5rem)] overflow-y-auto overflow-x-hidden py-16 pl-0.5">
|
|
<Navigation navigation={navigation} className="w-64 pr-8 xl:w-72 xl:pr-16" />
|
|
</div>
|
|
</div>
|
|
<div className="min-w-0 max-w-2xl flex-auto px-4 py-16 lg:max-w-none lg:pr-0 lg:pl-8 xl:px-16">
|
|
<article>
|
|
{(meta.title || section) && (
|
|
<header className="mb-9 space-y-1">
|
|
{section && (
|
|
<p className="font-display text-brand-light dark:text-brand-dark text-sm font-medium">
|
|
{section.title}
|
|
</p>
|
|
)}
|
|
{meta.title && (
|
|
<h1 className="font-display text-3xl tracking-tight text-slate-800 dark:text-slate-100">
|
|
{meta.title}
|
|
</h1>
|
|
)}
|
|
</header>
|
|
)}
|
|
<Prose className="">{children}</Prose>
|
|
</article>
|
|
<dl className="mt-12 flex border-t border-slate-200 pt-6 dark:border-slate-800">
|
|
{previousPage && (
|
|
<div>
|
|
<dt className="font-display text-brand-dark dark:text-brand-light text-sm font-medium">
|
|
Previous
|
|
</dt>
|
|
<dd className="mt-1">
|
|
<Link
|
|
href={previousPage.href}
|
|
className="text-base font-semibold text-slate-500 hover:text-slate-600 dark:text-slate-400 dark:hover:text-slate-300">
|
|
<span aria-hidden="true">←</span> {previousPage.title}
|
|
</Link>
|
|
</dd>
|
|
</div>
|
|
)}
|
|
{nextPage && (
|
|
<div className="ml-auto text-right">
|
|
<dt className="font-display text-brand-dark dark:text-brand-light text-sm font-medium">
|
|
Next
|
|
</dt>
|
|
<dd className="mt-1">
|
|
<Link
|
|
href={nextPage.href}
|
|
className="text-base font-semibold text-slate-500 hover:text-slate-600 dark:text-slate-400 dark:hover:text-slate-300">
|
|
{nextPage.title} <span aria-hidden="true">→</span>
|
|
</Link>
|
|
</dd>
|
|
</div>
|
|
)}
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|