"use client"; import { signOut } from "next-auth/react"; import type { TFunction } from "next-i18next"; import { usePathname, useRouter } from "next/navigation"; import { Suspense } from "react"; import { Toaster } from "sonner"; import { z } from "zod"; import { classNames } from "@calcom/lib"; import { APP_NAME } from "@calcom/lib/constants"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useParamsWithFallback } from "@calcom/lib/hooks/useParamsWithFallback"; import { trpc } from "@calcom/trpc"; import type { inferSSRProps } from "@calcom/types/inferSSRProps"; import { Button, StepCard, Steps } from "@calcom/ui"; import { Icon } from "@calcom/ui"; import type { getServerSideProps } from "@lib/getting-started/[[...step]]/getServerSideProps"; import { ConnectedCalendars } from "@components/getting-started/steps-views/ConnectCalendars"; import { ConnectedVideoStep } from "@components/getting-started/steps-views/ConnectedVideoStep"; import { SetupAvailability } from "@components/getting-started/steps-views/SetupAvailability"; import UserProfile from "@components/getting-started/steps-views/UserProfile"; import { UserSettings } from "@components/getting-started/steps-views/UserSettings"; const INITIAL_STEP = "user-settings"; const BASE_STEPS = [ "user-settings", "connected-calendar", "connected-video", "setup-availability", "user-profile", ] as const; type StepType = (typeof BASE_STEPS)[number]; const getStepsAndHeadersForUser = (t: TFunction) => { const baseHeaders: { title: string; subtitle: string[]; skipText?: string; }[] = [ { title: t("welcome_to_cal_header", { appName: APP_NAME }), subtitle: [t("we_just_need_basic_info"), t("edit_form_later_subtitle")], }, { title: t("connect_your_calendar"), subtitle: [t("connect_your_calendar_instructions")], skipText: t("connect_calendar_later"), }, { title: t("connect_your_video_app"), subtitle: [t("connect_your_video_app_instructions")], skipText: t("set_up_later"), }, { title: t("set_availability"), subtitle: [ t("set_availability_getting_started_subtitle_1"), t("set_availability_getting_started_subtitle_2"), ], }, { title: t("nearly_there"), subtitle: [t("nearly_there_instructions")], }, ]; return { steps: [...BASE_STEPS], headers: [...baseHeaders], }; }; const stepRouteSchema = z.object({ step: z .array( z.enum(["user-settings", "setup-availability", "user-profile", "connected-calendar", "connected-video"]) ) .default([INITIAL_STEP]), from: z.string().optional(), }); export type PageProps = inferSSRProps; const OnboardingPage = (props: PageProps) => { const pathname = usePathname(); const params = useParamsWithFallback(); const router = useRouter(); const [user] = trpc.viewer.me.useSuspenseQuery(); const { t } = useLocale(); const result = stepRouteSchema.safeParse({ ...params, step: Array.isArray(params.step) ? params.step : [params.step], }); const currentStep = result.success ? result.data.step[0] : INITIAL_STEP; const from = result.success ? result.data.from : ""; // TODO: Add this in when we have solved the ability to move to tokens accept invite and note invitedto // Ability to accept other pending invites if any (low priority) // if (props.hasPendingInvites) { // headers.unshift( // props.hasPendingInvites && { // title: `${t("email_no_user_invite_heading", { appName: APP_NAME })}`, // subtitle: [], // TODO: come up with some subtitle text here // } // ); // } const { steps, headers } = getStepsAndHeadersForUser(t); const stepTransform = (step: StepType) => { const stepIndex = steps.indexOf(step as (typeof steps)[number]); if (stepIndex > -1) { return steps[stepIndex]; } return INITIAL_STEP; }; const currentStepIndex = steps.indexOf(currentStep); const goToNextStep = () => { const nextIndex = currentStepIndex + 1; const newStep = steps[nextIndex]; router.push(`/getting-started/${stepTransform(newStep)}`); }; return (

{headers[currentStepIndex]?.title || "Undefined title"}

{headers[currentStepIndex]?.subtitle.map((subtitle, index) => (

{subtitle}

))}
}> {currentStep === "user-settings" && ( )} {currentStep === "connected-calendar" && } {currentStep === "connected-video" && } {currentStep === "setup-availability" && ( )} {currentStep === "user-profile" && } {headers[currentStepIndex]?.skipText && (
)}
); }; export default OnboardingPage;