"use client"; import { signOut } from "next-auth/react"; import Head from "next/head"; import { usePathname, useRouter } from "next/navigation"; import { Suspense } from "react"; 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 { Button, StepCard, Steps } from "@calcom/ui"; import { Icon } from "@calcom/ui"; import PageWrapper from "@components/PageWrapper"; 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"; export { getServerSideProps } from "@lib/getting-started/[[...step]]/getServerSideProps"; const INITIAL_STEP = "user-settings"; const steps = [ "user-settings", "connected-calendar", "connected-video", "setup-availability", "user-profile", ] as const; const stepTransform = (step: (typeof steps)[number]) => { const stepIndex = steps.indexOf(step); if (stepIndex > -1) { return steps[stepIndex]; } return INITIAL_STEP; }; const stepRouteSchema = z.object({ step: z.array(z.enum(steps)).default([INITIAL_STEP]), from: z.string().optional(), }); // TODO: Refactor how steps work to be contained in one array/object. Currently we have steps,initalsteps,headers etc. These can all be in one place const OnboardingPage = () => { 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 : ""; const headers = [ { 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")}`], }, ]; // 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 goToIndex = (index: number) => { const newStep = steps[index]; router.push(`/getting-started/${stepTransform(newStep)}`); }; const currentStepIndex = steps.indexOf(currentStep); return (
{headers[currentStepIndex]?.title || "Undefined title"}
{headers[currentStepIndex]?.subtitle.map((subtitle, index) => ({subtitle}
))}