diff --git a/packages/features/settings/TimezoneChangeDialog.tsx b/packages/features/settings/TimezoneChangeDialog.tsx index a1a9b73dcd..853f85b9a1 100644 --- a/packages/features/settings/TimezoneChangeDialog.tsx +++ b/packages/features/settings/TimezoneChangeDialog.tsx @@ -1,21 +1,33 @@ +"use client"; + import { useSession } from "next-auth/react"; import { useEffect, useState } from "react"; import dayjs from "@calcom/dayjs"; -import { IS_VISUAL_REGRESSION_TESTING } from "@calcom/lib/constants"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import { Dialog, DialogClose, DialogContent, DialogFooter, showToast } from "@calcom/ui"; -export default function TimezoneChangeDialog() { +const TimezoneChangeDialogContent = ({ + onAction, + browserTimezone, +}: { + browserTimezone: string; + onAction: (action?: "update" | "cancel") => void; +}) => { const { t } = useLocale(); - const { data: user, isPending } = trpc.viewer.me.useQuery(); const utils = trpc.useUtils(); - const userTz = user?.timeZone; - const currentTz = dayjs.tz.guess() || "Europe/London"; - const formattedCurrentTz = currentTz?.replace("_", " "); + const formattedCurrentTz = browserTimezone.replace("_", " "); + + // save cookie to not show again + function onCancel(hideFor: [number, dayjs.ManipulateType], toast: boolean) { + onAction("cancel"); + document.cookie = `calcom-timezone-dialog=1;max-age=${ + dayjs().add(hideFor[0], hideFor[1]).unix() - dayjs().unix() + }`; + toast && showToast(t("we_wont_show_again"), "success"); + } - // update user settings const onSuccessMutation = async () => { showToast(t("updated_timezone_to", { formattedCurrentTz }), "success"); await utils.viewer.me.invalidate(); @@ -32,55 +44,69 @@ export default function TimezoneChangeDialog() { }); function updateTimezone() { - setOpen(false); + onAction("update"); mutation.mutate({ - timeZone: currentTz, + timeZone: browserTimezone, }); } - // check for difference in user timezone and current browser timezone - const [open, setOpen] = useState(false); - useEffect(() => { - const tzDifferent = - !isPending && dayjs.tz(undefined, currentTz).utcOffset() !== dayjs.tz(undefined, userTz).utcOffset(); - const showDialog = tzDifferent && !document.cookie.includes("calcom-timezone-dialog=1"); - setOpen(!IS_VISUAL_REGRESSION_TESTING && showDialog); - }, [currentTz, isPending, userTz]); - - // save cookie to not show again - function onCancel(maxAge: number, toast: boolean) { - setOpen(false); - document.cookie = `calcom-timezone-dialog=1;max-age=${maxAge}`; - toast && showToast(t("we_wont_show_again"), "success"); - } - - const { data } = useSession(); - - if (data?.user.impersonatedBy) return null; - - const ONE_DAY = 60 * 60 * 24; // 1 day in seconds (60 seconds * 60 minutes * 24 hours) - const THREE_MONTHS = ONE_DAY * 90; // 90 days in seconds (90 days * 1 day in seconds) - return ( - - onCancel(ONE_DAY, false) /* 1 day expire */}> - {/* todo: save this in db and auto-update when timezone changes (be able to disable??? if yes, /settings) + onCancel([1, "day"], false) /* 1 day expire */}> + {/* todo: save this in db and auto-update when timezone changes (be able to disable??? if yes, /settings) */} -
- - onCancel(THREE_MONTHS, true)} color="secondary"> - {t("dont_update")} - - updateTimezone()} color="primary"> - {t("update_timezone")} - - - +
+ + onCancel([3, "months"], true)} color="secondary"> + {t("dont_update")} + + updateTimezone()} color="primary"> + {t("update_timezone")} + + + + ); +}; + +export function useOpenTimezoneDialog() { + const { data: user } = trpc.viewer.me.useQuery(); + const [showDialog, setShowDialog] = useState(false); + const browserTimezone = dayjs.tz.guess() || "Europe/London"; + const { isLocaleReady } = useLocale(); + const { data: userSession, status } = useSession(); + + useEffect(() => { + if ( + !isLocaleReady || + !user?.timeZone || + status !== "authenticated" || + userSession?.user?.impersonatedBy + ) { + return; + } + const cookie = document.cookie + .split(";") + .find((cookie) => cookie.trim().startsWith("calcom-timezone-dialog")); + if ( + !cookie && + dayjs.tz(undefined, browserTimezone).utcOffset() !== dayjs.tz(undefined, user.timeZone).utcOffset() + ) { + setShowDialog(true); + } + }, [user, isLocaleReady, status, browserTimezone, userSession?.user?.impersonatedBy]); + + return { open: showDialog, setOpen: setShowDialog, browserTimezone }; +} + +export default function TimezoneChangeDialog() { + const { open, setOpen, browserTimezone } = useOpenTimezoneDialog(); + return ( + + setOpen(false)} /> ); } diff --git a/packages/features/shell/Shell.tsx b/packages/features/shell/Shell.tsx index 2c1b601701..7fcb767b8b 100644 --- a/packages/features/shell/Shell.tsx +++ b/packages/features/shell/Shell.tsx @@ -251,7 +251,6 @@ const Layout = (props: LayoutProps) => {
- {/* todo: only run this if timezone is different */}
diff --git a/playwright.config.ts b/playwright.config.ts index f243442469..1f77dfef43 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -4,6 +4,8 @@ import dotEnv from "dotenv"; import * as os from "os"; import * as path from "path"; +import { WEBAPP_URL } from "@calcom/lib/constants"; + dotEnv.config({ path: ".env" }); const outputDir = path.join(__dirname, "test-results"); @@ -58,6 +60,16 @@ if (IS_EMBED_REACT_TEST) { const DEFAULT_CHROMIUM = { ...devices["Desktop Chrome"], timezoneId: "Europe/London", + storageState: { + cookies: [ + { + url: WEBAPP_URL, + name: "calcom-timezone-dialog", + expires: -1, + value: "1", + }, + ], + }, locale: "en-US", /** If navigation takes more than this, then something's wrong, let's fail fast. */ navigationTimeout: DEFAULT_NAVIGATION_TIMEOUT, @@ -98,6 +110,8 @@ const config: PlaywrightTestConfig = { expect: { timeout: DEFAULT_EXPECT_TIMEOUT, }, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore TS definitions for USE are wrong. use: DEFAULT_CHROMIUM, }, { @@ -107,6 +121,8 @@ const config: PlaywrightTestConfig = { expect: { timeout: DEFAULT_EXPECT_TIMEOUT, }, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore TS definitions for USE are wrong. use: DEFAULT_CHROMIUM, }, { @@ -129,6 +145,8 @@ const config: PlaywrightTestConfig = { timeout: DEFAULT_EXPECT_TIMEOUT, }, testMatch: /.*\.e2e\.tsx?/, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore TS definitions for USE are wrong. use: { ...DEFAULT_CHROMIUM, baseURL: "http://localhost:3101/",