import { Menu, Transition } from "@headlessui/react"; import { SelectorIcon } from "@heroicons/react/outline"; import { CalendarIcon, ClockIcon, CogIcon, ExternalLinkIcon, LinkIcon, LogoutIcon, PuzzleIcon, } from "@heroicons/react/solid"; import { signOut, useSession } from "next-auth/client"; import Link from "next/link"; import { useRouter } from "next/router"; import React, { Fragment, ReactNode, useEffect } from "react"; import { Toaster } from "react-hot-toast"; import HelpMenuItemDynamic from "@ee/lib/intercom/HelpMenuItemDynamic"; import classNames from "@lib/classNames"; import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry"; import { trpc } from "@lib/trpc"; import { HeadSeo } from "@components/seo/head-seo"; import Avatar from "@components/ui/Avatar"; import Logo from "./Logo"; function useMeQuery() { const [session] = useSession(); const meQuery = trpc.useQuery(["viewer.me"], { // refetch max once per 5s staleTime: 5000, }); useEffect(() => { // refetch if sesion changes meQuery.refetch(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [session]); return meQuery; } function useRedirectToLoginIfUnauthenticated() { const [session, loading] = useSession(); const router = useRouter(); useEffect(() => { if (!loading && !session) { router.replace({ pathname: "/auth/login", query: { callbackUrl: `${location.pathname}${location.search}`, }, }); } }, [loading, session, router]); } export default function Shell(props: { title?: string; heading: ReactNode; subtitle: string; children: ReactNode; CTA?: ReactNode; }) { const router = useRouter(); // eslint-disable-next-line @typescript-eslint/no-unused-vars useRedirectToLoginIfUnauthenticated(); const telemetry = useTelemetry(); const query = useMeQuery(); const navigation = [ { name: "Event Types", href: "/event-types", icon: LinkIcon, current: router.asPath.startsWith("/event-types"), }, { name: "Bookings", href: "/bookings/upcoming", icon: ClockIcon, current: router.asPath.startsWith("/bookings"), }, { name: "Availability", href: "/availability", icon: CalendarIcon, current: router.asPath.startsWith("/availability"), }, { name: "Integrations", href: "/integrations", icon: PuzzleIcon, current: router.asPath.startsWith("/integrations"), }, { name: "Settings", href: "/settings/profile", icon: CogIcon, current: router.asPath.startsWith("/settings"), }, ]; useEffect(() => { telemetry.withJitsu((jitsu) => { return jitsu.track(telemetryEventTypes.pageView, collectPageParameters(router.asPath)); }); }, [telemetry]); if (query.status !== "loading" && !query.data) { router.replace("/auth/login"); } const pageTitle = typeof props.heading === "string" ? props.heading : props.title; return ( <>
{/* Static sidebar for desktop */}
{/* Sidebar component, swap this element with another sidebar if you like */}
{/* show top navigation for md and smaller (tablet and phones) */}

{props.heading}

{props.subtitle}

{props.CTA}
{props.children}
{/* show bottom navigation for md and smaller (tablet and phones) */} {/* add padding to content for mobile navigation*/}
); } function UserDropdown({ small, bottom }: { small?: boolean; bottom?: boolean }) { const query = useMeQuery(); const user = query.data; return ( {({ open }) => ( <>
{user && ( {!small && ( {user.name} /{user.username} )} {!small && ( )}
View public page
{({ active }) => ( Join our Slack )}
{({ active }) => ( signOut({ callbackUrl: "/auth/logout" })} className={classNames( active ? "bg-gray-100 text-gray-900" : "text-gray-700", "flex px-4 py-2 text-sm font-medium" )}> )}
)}
); }