feat: (Overlay) Persist toggle option (#11961)

This commit is contained in:
sean-brydon 2023-10-18 11:16:02 +01:00 committed by GitHub
parent 0c92fbe11d
commit 0b46f61a23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 105 additions and 75 deletions

View File

@ -19,7 +19,8 @@ export const LargeCalendar = ({ extraDays }: { extraDays: number }) => {
const schedule = useScheduleForEvent({
prefetchNextMonth: !!extraDays && dayjs(date).month() !== dayjs(date).add(extraDays, "day").month(),
});
const displayOverlay = getQueryParam("overlayCalendar") === "true";
const displayOverlay =
getQueryParam("overlayCalendar") === "true" || localStorage.getItem("overlayCalendarSwitchDefault");
const event = useEvent();
const eventDuration = selectedEventDuration || event?.data?.length || 30;

View File

@ -1,5 +1,5 @@
import { useSession } from "next-auth/react";
import { useRouter, useSearchParams, usePathname } from "next/navigation";
import { useSearchParams, useRouter, usePathname } from "next/navigation";
import { useState, useCallback, useEffect } from "react";
import dayjs from "@calcom/dayjs";
@ -17,19 +17,108 @@ import { OverlayCalendarSettingsModal } from "../OverlayCalendar/OverlayCalendar
import { useLocalSet } from "../hooks/useLocalSet";
import { useOverlayCalendarStore } from "./store";
export function OverlayCalendarContainer() {
interface OverlayCalendarSwitchProps {
setContinueWithProvider: (val: boolean) => void;
setCalendarSettingsOverlay: (val: boolean) => void;
enabled?: boolean;
}
function OverlayCalendarSwitch({
setCalendarSettingsOverlay,
setContinueWithProvider,
enabled,
}: OverlayCalendarSwitchProps) {
const { t } = useLocale();
const layout = useBookerStore((state) => state.layout);
const searchParams = useSearchParams();
const { data: session } = useSession();
const router = useRouter();
const pathname = usePathname();
const switchEnabled = enabled;
// Toggle query param for overlay calendar
const toggleOverlayCalendarQueryParam = useCallback(
(state: boolean) => {
const current = new URLSearchParams(Array.from(searchParams.entries()));
if (state) {
current.set("overlayCalendar", "true");
localStorage.setItem("overlayCalendarSwitchDefault", "true");
} else {
current.delete("overlayCalendar");
localStorage.removeItem("overlayCalendarSwitchDefault");
}
// cast to string
const value = current.toString();
const query = value ? `?${value}` : "";
router.push(`${pathname}${query}`);
},
[searchParams, pathname, router]
);
/**
* If a user is not logged in and the overlay calendar query param is true,
* show the continue modal so they can login / create an account
*/
useEffect(() => {
if (!session && switchEnabled) {
toggleOverlayCalendarQueryParam(false);
setContinueWithProvider(true);
}
}, [session, switchEnabled, setContinueWithProvider, toggleOverlayCalendarQueryParam]);
return (
<div
className={classNames(
"hidden gap-2",
layout === "week_view" || layout === "column_view" ? "xl:flex" : "md:flex"
)}>
<div className="flex items-center gap-2 pr-2">
<Switch
data-testid="overlay-calendar-switch"
checked={switchEnabled}
id="overlayCalendar"
onCheckedChange={(state) => {
if (!session) {
setContinueWithProvider(state);
} else {
toggleOverlayCalendarQueryParam(state);
}
}}
/>
<label
htmlFor="overlayCalendar"
className="text-emphasis text-sm font-medium leading-none hover:cursor-pointer">
{t("overlay_my_calendar")}
</label>
</div>
{session && (
<Button
size="base"
data-testid="overlay-calendar-settings-button"
variant="icon"
color="secondary"
StartIcon={Settings}
onClick={() => {
setCalendarSettingsOverlay(true);
}}
/>
)}
</div>
);
}
export function OverlayCalendarContainer() {
const isEmbed = useIsEmbed();
const searchParams = useSearchParams();
const [continueWithProvider, setContinueWithProvider] = useState(false);
const [calendarSettingsOverlay, setCalendarSettingsOverlay] = useState(false);
const { data: session } = useSession();
const setOverlayBusyDates = useOverlayCalendarStore((state) => state.setOverlayBusyDates);
const switchEnabled =
searchParams.get("overlayCalendar") === "true" ||
localStorage.getItem("overlayCalendarSwitchDefault") === "true";
const layout = useBookerStore((state) => state.layout);
const selectedDate = useBookerStore((state) => state.selectedDate);
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
const { timezone } = useTimePreferences();
// Move this to a hook
@ -37,7 +126,6 @@ export function OverlayCalendarContainer() {
credentialId: number;
externalId: string;
}>("toggledConnectedCalendars", []);
const overlayCalendarQueryParam = searchParams.get("overlayCalendar");
const { data: overlayBusyDates } = trpc.viewer.availability.calendarOverlay.useQuery(
{
@ -50,7 +138,7 @@ export function OverlayCalendarContainer() {
})),
},
{
enabled: !!session && set.size > 0 && overlayCalendarQueryParam === "true",
enabled: !!session && set.size > 0 && switchEnabled,
onError: () => {
clearSet();
},
@ -76,77 +164,17 @@ export function OverlayCalendarContainer() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [overlayBusyDates]);
// Toggle query param for overlay calendar
const toggleOverlayCalendarQueryParam = useCallback(
(state: boolean) => {
const current = new URLSearchParams(Array.from(searchParams.entries()));
if (state) {
current.set("overlayCalendar", "true");
} else {
current.delete("overlayCalendar");
}
// cast to string
const value = current.toString();
const query = value ? `?${value}` : "";
router.push(`${pathname}${query}`);
},
[searchParams, pathname, router]
);
/**
* If a user is not logged in and the overlay calendar query param is true,
* show the continue modal so they can login / create an account
*/
useEffect(() => {
if (!session && overlayCalendarQueryParam === "true") {
toggleOverlayCalendarQueryParam(false);
setContinueWithProvider(true);
}
}, [session, overlayCalendarQueryParam, toggleOverlayCalendarQueryParam]);
if (isEmbed) {
return null;
}
return (
<>
<div
className={classNames(
"hidden gap-2",
layout === "week_view" || layout === "column_view" ? "xl:flex" : "md:flex"
)}>
<div className="flex items-center gap-2 pr-2">
<Switch
data-testid="overlay-calendar-switch"
checked={overlayCalendarQueryParam === "true"}
id="overlayCalendar"
onCheckedChange={(state) => {
if (!session) {
setContinueWithProvider(state);
} else {
toggleOverlayCalendarQueryParam(state);
}
}}
/>
<label
htmlFor="overlayCalendar"
className="text-emphasis text-sm font-medium leading-none hover:cursor-pointer">
{t("overlay_my_calendar")}
</label>
</div>
{session && (
<Button
size="base"
data-testid="overlay-calendar-settings-button"
variant="icon"
color="secondary"
StartIcon={Settings}
onClick={() => {
setCalendarSettingsOverlay(true);
}}
/>
)}
</div>
<OverlayCalendarSwitch
setCalendarSettingsOverlay={setCalendarSettingsOverlay}
setContinueWithProvider={setContinueWithProvider}
enabled={switchEnabled}
/>
<OverlayCalendarContinueModal
open={continueWithProvider}
onClose={(val) => {

View File

@ -48,7 +48,8 @@ const SlotItem = ({
}) => {
const { t } = useLocale();
const overlayCalendarToggled = getQueryParam("overlayCalendar") === "true";
const overlayCalendarToggled =
getQueryParam("overlayCalendar") === "true" || localStorage.getItem("overlayCalendarSwitchDefault");
const [timeFormat, timezone] = useTimePreferences((state) => [state.timeFormat, state.timezone]);
const selectedDuration = useBookerStore((state) => state.selectedDuration);
const bookingData = useBookerStore((state) => state.bookingData);