From 181074fbfb35678f274eeac9aa4e53c44f2d4778 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 13 Aug 2025 02:42:00 +0100 Subject: [PATCH] fix: Crash of onboarding connected-video page --- .../steps-views/ConnectedVideoStep.tsx | 94 ++++++++++++------- 1 file changed, 60 insertions(+), 34 deletions(-) diff --git a/apps/web/components/getting-started/steps-views/ConnectedVideoStep.tsx b/apps/web/components/getting-started/steps-views/ConnectedVideoStep.tsx index 873a4dacd3cd65..ccf9cf91dabdc0 100644 --- a/apps/web/components/getting-started/steps-views/ConnectedVideoStep.tsx +++ b/apps/web/components/getting-started/steps-views/ConnectedVideoStep.tsx @@ -1,3 +1,7 @@ +import { type TFunction } from "i18next"; +import { useState } from "react"; +import type { Dispatch, SetStateAction } from "react"; + import { useLocale } from "@calcom/lib/hooks/useLocale"; import { userMetadata } from "@calcom/prisma/zod-utils"; import { trpc } from "@calcom/trpc/react"; @@ -14,8 +18,13 @@ interface ConnectedAppStepProps { isPageLoading: boolean; } -const ConnectedVideoStep = (props: ConnectedAppStepProps) => { - const { nextStep, isPageLoading } = props; +const ConnectedVideoStepInner = ({ + t, + setAnyInstalledVideoApps, +}: { + t: TFunction; + setAnyInstalledVideoApps: Dispatch>; +}) => { const { data: queryConnectedVideoApps, isPending } = trpc.viewer.apps.integrations.useQuery({ variant: "conferencing", onlyInstalled: false, @@ -30,47 +39,64 @@ const ConnectedVideoStep = (props: ConnectedAppStepProps) => { sortByMostPopular: true, sortByInstalledFirst: true, }); - const { data } = useMeQuery(); - const { t } = useLocale(); + // we want to start loading immediately, after all this is a hook. + const { data, status } = useMeQuery(); - const metadata = userMetadata.parse(data?.metadata); + if (isPending) { + return ; + } const hasAnyInstalledVideoApps = queryConnectedVideoApps?.items.some( (item) => item.userCredentialIds.length > 0 ); + if (hasAnyInstalledVideoApps) { + setAnyInstalledVideoApps(true); + } + if (status !== "success") { + return ; + } + + const result = userMetadata.safeParse(data?.metadata); + if (!result.success) { + return ; + } + const { data: metadata } = result; const defaultConferencingApp = metadata?.defaultConferencingApp?.appSlug; return ( - <> - {!isPending && ( - - {queryConnectedVideoApps?.items && - queryConnectedVideoApps?.items.map((item) => { - if (item.slug === "daily-video") return null; // we dont want to show daily here as it is installed by default - return ( -
  • - {item.name && item.logo && ( - 0} - defaultInstall={ - !defaultConferencingApp && item.appData?.location?.linkType === "dynamic" - } - /> - )} -
  • - ); - })} -
    - )} + + {queryConnectedVideoApps?.items && + queryConnectedVideoApps?.items.map((item) => { + if (item.slug === "daily-video") return null; // we dont want to show daily here as it is installed by default + return ( +
  • + {item.name && item.logo && ( + 0} + defaultInstall={!defaultConferencingApp && item.appData?.location?.linkType === "dynamic"} + /> + )} +
  • + ); + })} +
    + ); +}; - {isPending && } +const ConnectedVideoStep = (props: ConnectedAppStepProps) => { + const { nextStep, isPageLoading } = props; + const { t } = useLocale(); + const [hasAnyInstalledVideoApps, setAnyInstalledVideoApps] = useState(false); + return ( + <> +