From d99f1715979c6e64e74afac437495d46f209da07 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Tue, 8 Oct 2024 10:41:53 +0100 Subject: [PATCH] perf: Only render the TimezoneChangeDialog when needed (#16986) * perf: Only render the TimezoneChangeDialog when needed * fix: Import error * Minor style fixes --- .../settings/TimezoneChangeDialog.tsx | 116 ++++++++++-------- 1 file changed, 64 insertions(+), 52 deletions(-) diff --git a/packages/features/settings/TimezoneChangeDialog.tsx b/packages/features/settings/TimezoneChangeDialog.tsx index 853f85b9a1..2b2d849340 100644 --- a/packages/features/settings/TimezoneChangeDialog.tsx +++ b/packages/features/settings/TimezoneChangeDialog.tsx @@ -1,112 +1,124 @@ "use client"; +import type { ManipulateType as DayjsManipulateType } from "dayjs"; import { useSession } from "next-auth/react"; import { useEffect, useState } from "react"; import dayjs from "@calcom/dayjs"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; -import { Dialog, DialogClose, DialogContent, DialogFooter, showToast } from "@calcom/ui"; +import { showToast, Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader } from "@calcom/ui"; + +function hideDialogFor(hideFor: [number, DayjsManipulateType], toastContent: string) { + document.cookie = `calcom-timezone-dialog=1;max-age=${ + dayjs().add(hideFor[0], hideFor[1]).unix() - dayjs().unix() + }`; + if (toastContent) showToast(toastContent, "success"); +} + +const TimezoneChangeDialogContent = () => { + const { t, isLocaleReady } = useLocale(); + if (!isLocaleReady) return null; -const TimezoneChangeDialogContent = ({ - onAction, - browserTimezone, -}: { - browserTimezone: string; - onAction: (action?: "update" | "cancel") => void; -}) => { - const { t } = useLocale(); const utils = trpc.useUtils(); + + const browserTimezone = dayjs.tz.guess() || "Europe/London"; 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"); - } - - const onSuccessMutation = async () => { + const onMutationSuccess = async () => { showToast(t("updated_timezone_to", { formattedCurrentTz }), "success"); await utils.viewer.me.invalidate(); }; - const onErrorMutation = () => { + const onMutationError = () => { showToast(t("couldnt_update_timezone"), "error"); }; // update timezone in db const mutation = trpc.viewer.updateProfile.useMutation({ - onSuccess: onSuccessMutation, - onError: onErrorMutation, + onSuccess: onMutationSuccess, + onError: onMutationError, }); - function updateTimezone() { - onAction("update"); + const updateTimezone = () => { mutation.mutate({ timeZone: browserTimezone, }); - } + }; return ( - 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([3, "months"], true)} color="secondary"> + hideDialogFor([3, "months"], t("we_wont_show_again"))} 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 - ) { + if (!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() - ) { + const browserTimezone = dayjs.tz.guess() || "Europe/London"; + if (dayjs.tz(undefined, browserTimezone).utcOffset() !== dayjs.tz(undefined, user.timeZone).utcOffset()) { setShowDialog(true); } - }, [user, isLocaleReady, status, browserTimezone, userSession?.user?.impersonatedBy]); + }, [user?.timeZone, status, userSession?.user?.impersonatedBy]); - return { open: showDialog, setOpen: setShowDialog, browserTimezone }; + return { open: showDialog, setOpen: setShowDialog }; } -export default function TimezoneChangeDialog() { - const { open, setOpen, browserTimezone } = useOpenTimezoneDialog(); +function TimezoneChangeDialogContainer() { + const { open, setOpen } = useOpenTimezoneDialog(); + const { t } = useLocale(); + + const handleInteractOutside = () => { + hideDialogFor([1, "day"], t("we_wont_show_again")); + }; + return ( - setOpen(false)} /> + {/* Dismiss dialog for a day on outside interaction */} + + + ); } + +export default function TimezoneChangeDialog() { + const [renderDialog, setRenderDialog] = useState(false); + useEffect(() => { + if (typeof window !== "undefined" && document) { + const cookie = document.cookie + .split(";") + .find((cookie) => cookie.trim().startsWith("calcom-timezone-dialog")); + if (!cookie) { + setRenderDialog(true); + } + } + }, []); + // bail if the cookie exists or window/document is not available + if (!renderDialog) { + return null; + } + return ; +}