Skip to content

Commit

Permalink
feat: Add dry run mode functionality and message display in booking p…
Browse files Browse the repository at this point in the history
…rocess

- Introduced a new `DryRunMessage` component to inform users when in dry run mode.
- Implemented utility function `isBookingDryRun` to check for dry run status based on URL search parameters.
- Updated the `Booker` component to conditionally render the dry run message.
- Adjusted booking mutation input mapping to reuse the utility
  • Loading branch information
hariombalhara committed Dec 31, 2024
1 parent 557bd8b commit fbab72c
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 11 deletions.
7 changes: 6 additions & 1 deletion apps/web/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,11 @@ const nextConfig = {
value: "cross-origin",
};

const ACCESS_CONTROL_ALLOW_ORIGIN_HEADER = {
key: "Access-Control-Allow-Origin",
value: "*",
};

return [
{
source: "/auth/:path*",
Expand Down Expand Up @@ -464,7 +469,7 @@ const nextConfig = {
},
{
source: "/icons/sprite.svg",
headers: [CORP_CROSS_ORIGIN_HEADER],
headers: [CORP_CROSS_ORIGIN_HEADER, ACCESS_CONTROL_ALLOW_ORIGIN_HEADER],
},
],
...(isOrganizationsEnabled
Expand Down
1 change: 1 addition & 0 deletions apps/web/public/static/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -2905,5 +2905,6 @@
"routing_form": "Routing Form",
"something_unexpected_occurred": "Something unexpected occurred",
"500_error_message": "It's not you, it's us.",
"dry_run_mode_active": "You are doing a test booking.",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
}
23 changes: 15 additions & 8 deletions packages/features/bookings/Booker/Booker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import dayjs from "@calcom/dayjs";
import { getQueryParam } from "@calcom/features/bookings/Booker/utils/query-param";
import { useNonEmptyScheduleDays } from "@calcom/features/schedules";
import classNames from "@calcom/lib/classNames";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { BookerLayouts } from "@calcom/prisma/zod-utils";

import { VerifyCodeDialog } from "../components/VerifyCodeDialog";
import { AvailableTimeSlots } from "./components/AvailableTimeSlots";
import { BookEventForm } from "./components/BookEventForm";
import { BookFormAsModal } from "./components/BookEventForm/BookFormAsModal";
import { DryRunMessage } from "./components/DryRunMessage";
import { EventMeta } from "./components/EventMeta";
import { HavingTroubleFindingTime } from "./components/HavingTroubleFindingTime";
import { Header } from "./components/Header";
Expand All @@ -30,6 +31,7 @@ import { NotFound } from "./components/Unavailable";
import { fadeInLeft, getBookerSizeClassNames, useBookerResizeAnimation } from "./config";
import { useBookerStore } from "./store";
import type { BookerProps, WrappedBookerProps } from "./types";
import { isBookingDryRun } from "./utils/isBookingDryRun";

const loadFramerFeatures = () => import("./framer-features").then((res) => res.default);
const PoweredBy = dynamic(() => import("@calcom/ee/components/PoweredBy").then((mod) => mod.default));
Expand Down Expand Up @@ -71,7 +73,7 @@ const BookerComponent = ({
userLocale,
hasValidLicense,
}: BookerProps & WrappedBookerProps) => {
const { t } = useLocale();
const searchParams = useCompatSearchParams();
const isPlatformBookerEmbed = useIsPlatformBookerEmbed();
const [bookerState, setBookerState] = useBookerStore((state) => [state.state, state.setState], shallow);
const selectedDate = useBookerStore((state) => state.selectedDate);
Expand Down Expand Up @@ -269,6 +271,8 @@ const BookerComponent = ({
<>
{event.data && !isPlatform ? <BookingPageTagManager eventType={event.data} /> : <></>}

{isBookingDryRun(searchParams) && <DryRunMessage isEmbed={isEmbed} />}

<div
className={classNames(
// In a popup embed, if someone clicks outside the main(having main class or main tag), it closes the embed
Expand Down Expand Up @@ -456,14 +460,17 @@ const BookerComponent = ({
layout === BookerLayouts.MONTH_VIEW && isEmbed ? "" : "fixed bottom-2"
)}
style={{ animationDelay: "1s" }}>
<InstantBooking
event={event.data}
onConnectNow={() => {
onConnectNowInstantMeeting();
}}
/>
<div className="flex">
<InstantBooking
event={event.data}
onConnectNow={() => {
onConnectNowInstantMeeting();
}}
/>
</div>
</div>
)}

{!hideBranding && (!isPlatform || isPlatformBookerEmbed) && (
<m.span
key="logo"
Expand Down
26 changes: 26 additions & 0 deletions packages/features/bookings/Booker/components/DryRunMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useState } from "react";

import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Icon } from "@calcom/ui";

export const DryRunMessage = ({ isEmbed }: { isEmbed?: boolean }) => {
const { t } = useLocale();
const [isVisible, setIsVisible] = useState(true);

if (!isVisible) return null;

return (
<div
onClick={() => setIsVisible(false)}
className={`bg-default border-subtle fixed left-1/2 ${
!isEmbed ? "top-4" : "top-0"
} z-50 -translate-x-1/2 transform cursor-pointer items-center gap-3 rounded-xl border p-3 text-sm shadow-md`}>
<div className="flex items-center gap-3">
<div className="relative">
<Icon name="info" className="h-5 w-5 text-orange-500" />
</div>
<div className="text-emphasis font-medium">{t("dry_run_mode_active")}</div>
</div>
</div>
);
};
3 changes: 3 additions & 0 deletions packages/features/bookings/Booker/utils/isBookingDryRun.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const isBookingDryRun = (searchParams: URLSearchParams) => {
return searchParams.get("cal.isBookingDryRun") === "true";
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { v4 as uuidv4 } from "uuid";

import dayjs from "@calcom/dayjs";
import { isBookingDryRun } from "@calcom/features/bookings/Booker/utils/isBookingDryRun";
import { getRoutedTeamMemberIdsFromSearchParams } from "@calcom/lib/bookings/getRoutedTeamMemberIdsFromSearchParams";
import { parseRecurringDates } from "@calcom/lib/parse-dates";

Expand Down Expand Up @@ -52,7 +53,7 @@ export const mapBookingToMutationInput = ({
const routingFormResponseId = routingFormResponseIdParam ? Number(routingFormResponseIdParam) : undefined;
const skipContactOwner = searchParams.get("cal.skipContactOwner") === "true";
const reroutingFormResponses = searchParams.get("cal.reroutingFormResponses");
const isBookingDryRun = searchParams.get("cal.isBookingDryRun") === "true";
const _isBookingDryRun = isBookingDryRun(searchParams);
const _cacheParam = searchParams?.get("cal.cache");
const _shouldServeCache = _cacheParam ? _cacheParam === "true" : undefined;

Expand Down Expand Up @@ -84,7 +85,7 @@ export const mapBookingToMutationInput = ({
skipContactOwner,
// In case of rerouting, the form responses are actually the responses that we need to update.
reroutingFormResponses: reroutingFormResponses ? JSON.parse(reroutingFormResponses) : undefined,
_isDryRun: isBookingDryRun,
_isDryRun: _isBookingDryRun,
_shouldServeCache,
};
};
Expand Down

0 comments on commit fbab72c

Please sign in to comment.