fix: Booker atom modal not rendering for mobile devices (#14278)

* make sure modal always appears

* separate event form wrappers into two components

* platform hook to fetch event type by id

* testing useGetEventTypeById hook

* add useGetEventTypeById to monorepo exports

* use platform hook for event type by id
This commit is contained in:
Rajiv Sahal
2024-04-02 20:41:28 +03:00
committed by GitHub
parent b202c4e79f
commit aca552c9f7
5 changed files with 78 additions and 15 deletions
+5 -9
View File
@@ -447,15 +447,11 @@ const BookerComponent = ({
)}
</div>
{!isPlatform ? (
<BookFormAsModal
onCancel={() => setSelectedTimeslot(null)}
visible={bookerState === "booking" && shouldShowFormInDialog}>
{EventBooker}
</BookFormAsModal>
) : (
<></>
)}
<BookFormAsModal
onCancel={() => setSelectedTimeslot(null)}
visible={bookerState === "booking" && shouldShowFormInDialog}>
{EventBooker}
</BookFormAsModal>
</>
);
};
@@ -1,6 +1,7 @@
import { Calendar, Clock } from "lucide-react";
import type { ReactNode } from "react";
import { useIsPlatform, useGetEventTypeById } from "@calcom/atoms/monorepo";
import dayjs from "@calcom/dayjs";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Badge, Dialog, DialogContent } from "@calcom/ui";
@@ -9,11 +10,42 @@ import { useTimePreferences } from "../../../lib";
import { useBookerStore } from "../../store";
import { useEvent } from "../../utils/event";
const BookEventFormWrapper = ({ children }: { onCancel: () => void; children: ReactNode }) => {
const BookEventFormWrapper = ({ children, onCancel }: { onCancel: () => void; children: ReactNode }) => {
const { data } = useEvent();
return <BookEventFormWrapperComponent child={children} eventLength={data?.length} onCancel={onCancel} />;
};
const PlatformBookEventFormWrapper = ({
children,
onCancel,
}: {
onCancel: () => void;
children: ReactNode;
}) => {
const eventId = useBookerStore((state) => state.eventId);
const { data } = useGetEventTypeById(eventId);
return (
<BookEventFormWrapperComponent
child={children}
eventLength={data?.eventType.length}
onCancel={onCancel}
/>
);
};
export const BookEventFormWrapperComponent = ({
child,
eventLength,
}: {
onCancel: () => void;
child: ReactNode;
eventLength?: number;
}) => {
const { t } = useLocale();
const selectedTimeslot = useBookerStore((state) => state.selectedTimeslot);
const selectedDuration = useBookerStore((state) => state.selectedDuration);
const { data } = useEvent();
const parsedSelectedTimeslot = dayjs(selectedTimeslot);
const { timeFormat, timezone } = useTimePreferences();
if (!selectedTimeslot) {
@@ -28,13 +60,13 @@ const BookEventFormWrapper = ({ children }: { onCancel: () => void; children: Re
{parsedSelectedTimeslot.format("LL")} {parsedSelectedTimeslot.tz(timezone).format(timeFormat)}
</span>
</Badge>
{(selectedDuration || data?.length) && (
{(selectedDuration || eventLength) && (
<Badge variant="grayWithoutHover" startIcon={Clock} size="lg">
<span>{selectedDuration || data?.length}</span>
<span>{selectedDuration || eventLength}</span>
</Badge>
)}
</div>
{children}
{child}
</>
);
};
@@ -48,13 +80,19 @@ export const BookFormAsModal = ({
onCancel: () => void;
children: ReactNode;
}) => {
const isPlatform = useIsPlatform();
return (
<Dialog open={visible} onOpenChange={onCancel}>
<DialogContent
type={undefined}
enableOverflow
className="[&_.modalsticky]:border-t-subtle [&_.modalsticky]:bg-default max-h-[80vh] pb-0 [&_.modalsticky]:sticky [&_.modalsticky]:bottom-0 [&_.modalsticky]:left-0 [&_.modalsticky]:right-0 [&_.modalsticky]:-mx-8 [&_.modalsticky]:border-t [&_.modalsticky]:px-8 [&_.modalsticky]:py-4">
<BookEventFormWrapper onCancel={onCancel}>{children}</BookEventFormWrapper>
{!isPlatform ? (
<BookEventFormWrapper onCancel={onCancel}>{children}</BookEventFormWrapper>
) : (
<PlatformBookEventFormWrapper onCancel={onCancel}>{children}</PlatformBookEventFormWrapper>
)}
</DialogContent>
</Dialog>
);
@@ -0,0 +1,27 @@
import { useQuery } from "@tanstack/react-query";
import { BASE_URL, API_VERSION, V2_ENDPOINTS, SUCCESS_STATUS } from "@calcom/platform-constants";
import type { EventType as AtomEventType } from "@calcom/platform-libraries";
import type { ApiResponse, ApiSuccessResponse } from "@calcom/platform-types";
import http from "../../lib/http";
export const QUERY_KEY = "get-event-by-id";
export const useGetEventTypeById = (id: number | null) => {
const endpoint = new URL(BASE_URL);
endpoint.pathname = `api/${API_VERSION}/${V2_ENDPOINTS.eventTypes}/${id}`;
endpoint.searchParams.set("for", "atom");
return useQuery({
queryKey: [QUERY_KEY, id],
queryFn: () => {
return http?.get<ApiResponse<AtomEventType>>(endpoint.toString()).then((res) => {
if (res.data.status === SUCCESS_STATUS) {
return (res.data as ApiSuccessResponse<AtomEventType>).data;
}
throw new Error(res.data.error.message);
});
},
});
};
+1
View File
@@ -6,6 +6,7 @@ export { useIsPlatform } from "./hooks/useIsPlatform";
export { useAtomsContext } from "./hooks/useAtomsContext";
export { useConnectedCalendars } from "./hooks/useConnectedCalendars";
export { useEventTypesPublic } from "./hooks/event-types/useEventTypesPublic";
export { useGetEventTypeById } from "./hooks/event-types/useGetEventTypeById";
export { useCancelBooking } from "./hooks/useCancelBooking";
export { useGetBooking } from "./hooks/useGetBooking";
export { useGetBookings } from "./hooks/useGetBookings";
+1
View File
@@ -3,6 +3,7 @@ export { WebAvailabilitySettingsWrapper as AvailabilitySettings } from "./availa
export { CalProvider } from "./cal-provider/CalProvider";
export { useIsPlatform } from "./hooks/useIsPlatform";
export { useAtomsContext } from "./hooks/useAtomsContext";
export { useGetEventTypeById } from "./hooks/event-types/useGetEventTypeById";
export { useHandleBookEvent } from "./hooks/useHandleBookEvent";
export * as Dialog from "./src/components/ui/dialog";
export { Timezone } from "./timezone";