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, { ReactNode, useEffect } from "react"; import { Toaster } from "react-hot-toast"; import LicenseBanner from "@ee/components/LicenseBanner"; import HelpMenuItemDynamic from "@ee/lib/intercom/HelpMenuItemDynamic"; import classNames from "@lib/classNames"; import { shouldShowOnboarding } from "@lib/getting-started"; import { useLocale } from "@lib/hooks/useLocale"; import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry"; import { trpc } from "@lib/trpc"; import Loader from "@components/Loader"; import { HeadSeo } from "@components/seo/head-seo"; import Avatar from "@components/ui/Avatar"; import Dropdown, { DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@components/ui/Dropdown"; import { useViewerI18n } from "./I18nLanguageHandler"; import Logo from "./Logo"; function useMeQuery() { const meQuery = trpc.useQuery(["viewer.me"]); return meQuery; } function useRedirectToLoginIfUnauthenticated() { const [session, loading] = useSession(); const router = useRouter(); const query = useMeQuery(); useEffect(() => { if (!loading && !session) { router.replace({ pathname: "/auth/login", query: { callbackUrl: `${location.pathname}${location.search}`, }, }); } }, [loading, session, router]); if (query.status !== "loading" && !query.data) { router.replace("/auth/login"); } } function useRedirectToOnboardingIfNeeded() { const [session, loading] = useSession(); const router = useRouter(); const query = useMeQuery(); const user = query.data; useEffect(() => { if (!loading && user) { if (shouldShowOnboarding(user)) { router.replace({ pathname: "/getting-started", }); } } }, [loading, session, router, user]); } export function ShellSubHeading(props: { title: ReactNode; subtitle?: ReactNode; actions?: ReactNode; className?: string; }) { return (

{props.title}

{props.subtitle &&

{props.subtitle}

}
{props.actions &&
{props.actions}
}
); } export default function Shell(props: { centered?: boolean; title?: string; heading: ReactNode; subtitle?: ReactNode; children: ReactNode; CTA?: ReactNode; }) { const { t } = useLocale(); const router = useRouter(); useRedirectToLoginIfUnauthenticated(); useRedirectToOnboardingIfNeeded(); const telemetry = useTelemetry(); const navigation = [ { name: t("event_types_page_title"), href: "/event-types", icon: LinkIcon, current: router.asPath.startsWith("/event-types"), }, { name: t("bookings"), href: "/bookings/upcoming", icon: ClockIcon, current: router.asPath.startsWith("/bookings"), }, { name: t("availability"), href: "/availability", icon: CalendarIcon, current: router.asPath.startsWith("/availability"), }, { name: t("integrations"), href: "/integrations", icon: PuzzleIcon, current: router.asPath.startsWith("/integrations"), }, { name: t("settings"), href: "/settings/profile", icon: CogIcon, current: router.asPath.startsWith("/settings"), }, ]; useEffect(() => { telemetry.withJitsu((jitsu) => { return jitsu.track(telemetryEventTypes.pageView, collectPageParameters(router.asPath)); }); }, [telemetry, router.asPath]); const pageTitle = typeof props.heading === "string" ? props.heading : props.title; const i18n = useViewerI18n(); if (i18n.status === "loading") { // show spinner whilst i18n is loading to avoid language flicker return (
); } return ( <>
{/* 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 }: { small?: boolean }) { const { t } = useLocale(); const query = useMeQuery(); const user = query.data; return user ? (
{!small && ( <> {user.name} cal.com/{user.username}
{t("view_public_page")} {t("join_our_slack")} signOut({ callbackUrl: "/auth/logout" })} className="flex px-4 py-2 text-sm cursor-pointer hover:bg-gray-100 hover:text-gray-900">
) : null; }