Skip to content

Commit 80e2118

Browse files
authored
Revert "feat: Phone based bookings for everyone (calcom#21320)" (calcom#22018)
This reverts commit 866a0e2.
1 parent ed5086d commit 80e2118

7 files changed

Lines changed: 67 additions & 431 deletions

File tree

apps/web/public/static/locales/en/common.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,6 @@
267267
"guests": "Guests",
268268
"guest": "Guest",
269269
"web_conferencing_details_to_follow": "Web conferencing details to follow in the confirmation email.",
270-
"confirmation":"Confirmation",
271-
"what_booker_should_provide": "What your booker should provide to receive confirmations",
272270
"404_the_user": "The username",
273271
"username": "Username",
274272
"is_still_available": "is still available.",
@@ -1712,8 +1710,6 @@
17121710
"show_available_seats_count": "Show the number of available seats",
17131711
"how_booking_questions_as_variables": "How to use booking questions as variables?",
17141712
"format": "Format",
1715-
"questions": "Questions",
1716-
"all_info_your_booker_provide": "All the info your booker should provide before booking with you.",
17171713
"uppercase_for_letters": "Use uppercase for all letters",
17181714
"replace_whitespaces_underscores": "Replace whitespaces with underscores",
17191715
"platform_members": "Platform members",

packages/features/bookings/lib/getBookingFields.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -160,22 +160,7 @@ export const ensureBookingInputsHaveSystemFields = ({
160160
type: "email",
161161
name: "email",
162162
required: !isEmailFieldOptional,
163-
editable: "system-but-optional",
164-
sources: [
165-
{
166-
label: "Default",
167-
id: "default",
168-
type: "default",
169-
},
170-
],
171-
},
172-
{
173-
defaultLabel: "phone_number",
174-
type: "phone",
175-
name: "attendeePhoneNumber",
176-
required: false,
177-
hidden: true,
178-
editable: "system-but-optional",
163+
editable: isOrgTeamEvent ? "system-but-optional" : "system",
179164
sources: [
180165
{
181166
label: "Default",
@@ -184,6 +169,7 @@ export const ensureBookingInputsHaveSystemFields = ({
184169
},
185170
],
186171
},
172+
187173
{
188174
defaultLabel: "location",
189175
type: "radioInput",
@@ -218,6 +204,23 @@ export const ensureBookingInputsHaveSystemFields = ({
218204
],
219205
},
220206
];
207+
if (isOrgTeamEvent) {
208+
systemBeforeFields.splice(2, 0, {
209+
defaultLabel: "phone_number",
210+
type: "phone",
211+
name: "attendeePhoneNumber",
212+
required: false,
213+
hidden: true,
214+
editable: "system-but-optional",
215+
sources: [
216+
{
217+
label: "Default",
218+
id: "default",
219+
type: "default",
220+
},
221+
],
222+
});
223+
}
221224

222225
// These fields should be added after other user fields
223226
const systemAfterFields: typeof bookingFields = [

packages/features/eventtypes/components/tabs/advanced/EventAdvancedTab.tsx

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -577,38 +577,27 @@ export const EventAdvancedTab = ({
577577
/>
578578
)}
579579

580-
<div className="border-subtle bg-muted rounded-lg border p-1">
581-
<div className="p-5">
582-
<div className="text-default text-sm font-semibold leading-none ltr:mr-1 rtl:ml-1">
583-
{t("booking_questions_title")}
584-
</div>
585-
<p className="text-subtle mt-1 max-w-[280px] break-words text-sm sm:max-w-[500px]">
586-
{t("booking_questions_description")}
587-
</p>
588-
</div>
589-
<div className="border-subtle bg-default rounded-lg border p-5">
590-
<FormBuilder
591-
showPhoneAndEmailToggle
592-
title={t("confirmation")}
593-
description={t("what_booker_should_provide")}
594-
addFieldLabel={t("add_a_booking_question")}
595-
formProp="bookingFields"
596-
{...shouldLockDisableProps("bookingFields")}
597-
dataStore={{
598-
options: {
599-
locations: {
600-
// FormBuilder doesn't handle plural for non-english languages. So, use english(Location) only. This is similar to 'Workflow'
601-
source: { label: "Location" },
602-
value: getLocationsOptionsForSelect(formMethods.getValues("locations") ?? [], t),
603-
},
580+
<div className="border-subtle space-y-6 rounded-lg border p-6">
581+
<FormBuilder
582+
title={t("booking_questions_title")}
583+
description={t("booking_questions_description")}
584+
addFieldLabel={t("add_a_booking_question")}
585+
formProp="bookingFields"
586+
{...shouldLockDisableProps("bookingFields")}
587+
dataStore={{
588+
options: {
589+
locations: {
590+
// FormBuilder doesn't handle plural for non-english languages. So, use english(Location) only. This is similar to 'Workflow'
591+
source: { label: "Location" },
592+
value: getLocationsOptionsForSelect(formMethods.getValues("locations") ?? [], t),
604593
},
605-
}}
606-
shouldConsiderRequired={(field: BookingField) => {
607-
// Location field has a default value at backend so API can send no location but we don't allow it in UI and thus we want to show it as required to user
608-
return field.name === "location" ? true : field.required;
609-
}}
610-
/>
611-
</div>
594+
},
595+
}}
596+
shouldConsiderRequired={(field: BookingField) => {
597+
// Location field has a default value at backend so API can send no location but we don't allow it in UI and thus we want to show it as required to user
598+
return field.name === "location" ? true : field.required;
599+
}}
600+
/>
612601
</div>
613602
<RequiresConfirmationController
614603
eventType={eventType}

packages/features/form-builder/FormBuilder.tsx

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { Badge } from "@calcom/ui/components/badge";
1515
import { Button } from "@calcom/ui/components/button";
1616
import { DialogContent, DialogFooter, DialogHeader, DialogClose } from "@calcom/ui/components/dialog";
1717
import { Editor } from "@calcom/ui/components/editor";
18-
import { ToggleGroup } from "@calcom/ui/components/form";
1918
import {
2019
Switch,
2120
CheckboxField,
@@ -60,15 +59,13 @@ export const FormBuilder = function FormBuilder({
6059
LockedIcon,
6160
dataStore,
6261
shouldConsiderRequired,
63-
showPhoneAndEmailToggle = false,
6462
}: {
6563
formProp: string;
6664
title: string;
6765
description: string;
6866
addFieldLabel: string;
6967
disabled: boolean;
7068
LockedIcon: false | JSX.Element;
71-
showPhoneAndEmailToggle?: boolean;
7269
/**
7370
* A readonly dataStore that is used to lookup the options for the fields. It works in conjunction with the field.getOptionAt property which acts as the key in options
7471
*/
@@ -132,68 +129,7 @@ export const FormBuilder = function FormBuilder({
132129
{title}
133130
{LockedIcon}
134131
</div>
135-
<div className="flex items-start justify-between">
136-
<p className="text-subtle mt-1 max-w-[280px] break-words text-sm sm:max-w-[500px]">{description}</p>
137-
{showPhoneAndEmailToggle && (
138-
<ToggleGroup
139-
value={(() => {
140-
const phoneField = fields.find((field) => field.name === "attendeePhoneNumber");
141-
const emailField = fields.find((field) => field.name === "email");
142-
143-
if (phoneField && !phoneField.hidden && phoneField.required && !emailField?.required) {
144-
return "phone";
145-
}
146-
147-
return "email";
148-
})()}
149-
options={[
150-
{
151-
value: "email",
152-
label: "Email",
153-
iconLeft: <Icon name="mail" className="h-4 w-4" />,
154-
},
155-
{
156-
value: "phone",
157-
label: "Phone",
158-
iconLeft: <Icon name="phone" className="h-4 w-4" />,
159-
},
160-
]}
161-
onValueChange={(value) => {
162-
const phoneFieldIndex = fields.findIndex((field) => field.name === "attendeePhoneNumber");
163-
const emailFieldIndex = fields.findIndex((field) => field.name === "email");
164-
if (value === "email") {
165-
update(emailFieldIndex, {
166-
...fields[emailFieldIndex],
167-
hidden: false,
168-
required: true,
169-
});
170-
update(phoneFieldIndex, {
171-
...fields[phoneFieldIndex],
172-
hidden: true,
173-
required: false,
174-
});
175-
} else if (value === "phone") {
176-
update(emailFieldIndex, {
177-
...fields[emailFieldIndex],
178-
hidden: true,
179-
required: false,
180-
});
181-
update(phoneFieldIndex, {
182-
...fields[phoneFieldIndex],
183-
hidden: false,
184-
required: true,
185-
});
186-
}
187-
}}
188-
/>
189-
)}
190-
</div>
191-
<p className="text-default mt-5 text-sm font-semibold leading-none ltr:mr-1 rtl:ml-1">
192-
{t("questions")}
193-
</p>
194-
<p className="text-subtle mt-1 max-w-[280px] break-words text-sm sm:max-w-[500px]">
195-
{t("all_info_your_booker_provide")}
196-
</p>
132+
<p className="text-subtle mt-0.5 max-w-[280px] break-words text-sm sm:max-w-[500px]">{description}</p>
197133
<ul ref={parent} className="border-subtle divide-subtle mt-4 divide-y rounded-md border">
198134
{fields.map((field, index) => {
199135
let options = field.options ?? null;
@@ -544,7 +480,6 @@ function FieldEditDialog({
544480
const variantsConfig = fieldForm.watch("variantsConfig");
545481

546482
const fieldTypes = Object.values(fieldTypesConfigMap);
547-
const fieldName = fieldForm.getValues("name");
548483

549484
return (
550485
<Dialog open={dialog.isOpen} onOpenChange={onOpenChange} modal={false}>

packages/lib/server/repository/team.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -360,18 +360,4 @@ export class TeamRepository {
360360
inviteToken: inviteTokens.find((token) => token.identifier === `invite-link-for-teamId-${team.id}`),
361361
}));
362362
}
363-
364-
static async findTeamWithOrganizationSettings(teamId: number) {
365-
return await prisma.team.findUnique({
366-
where: { id: teamId },
367-
select: {
368-
parent: {
369-
select: {
370-
isOrganization: true,
371-
organizationSettings: true,
372-
},
373-
},
374-
},
375-
});
376-
}
377363
}

packages/sms/sms-manager.ts

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { sendSmsOrFallbackEmail } from "@calcom/features/ee/workflows/lib/remind
44
import { checkSMSRateLimit } from "@calcom/lib/checkRateLimitAndThrowError";
55
import { SENDER_ID } from "@calcom/lib/constants";
66
import isSmsCalEmail from "@calcom/lib/isSmsCalEmail";
7-
import { TeamRepository } from "@calcom/lib/server/repository/team";
87
import { TimeFormat } from "@calcom/lib/timeFormat";
8+
import prisma from "@calcom/prisma";
99
import type { CalendarEvent, Person } from "@calcom/types/Calendar";
1010

1111
const handleSendingSMS = async ({
@@ -14,25 +14,36 @@ const handleSendingSMS = async ({
1414
senderID,
1515
teamId,
1616
bookingUid,
17-
organizerUserId,
1817
}: {
1918
reminderPhone: string;
2019
smsMessage: string;
2120
senderID: string;
22-
teamId?: number;
21+
teamId: number;
2322
bookingUid?: string | null;
24-
organizerUserId?: number;
2523
}) => {
24+
const team = await prisma.team.findUnique({
25+
where: { id: teamId },
26+
select: {
27+
parent: {
28+
select: {
29+
isOrganization: true,
30+
organizationSettings: {
31+
select: {
32+
disablePhoneOnlySMSNotifications: true,
33+
},
34+
},
35+
},
36+
},
37+
},
38+
});
39+
40+
if (!team?.parent?.isOrganization || team?.parent?.organizationSettings?.disablePhoneOnlySMSNotifications) {
41+
return; // resolves implicitly (as undefined)
42+
}
43+
2644
try {
27-
// If teamId is provided, we check the rate limit for the team.
28-
// If organizerUserId is provided, we check the rate limit for the organizer.
29-
// If neither is provided(Just in case), we check the rate limit for the reminderPhone.
3045
await checkSMSRateLimit({
31-
identifier: teamId
32-
? `handleSendingSMS:team:${teamId}`
33-
: organizerUserId
34-
? `handleSendingSMS:user:${organizerUserId}`
35-
: `handleSendingSMS:user:${reminderPhone}`,
46+
identifier: `handleSendingSMS:team:${teamId}`,
3647
rateLimitingType: "sms",
3748
});
3849

@@ -41,7 +52,7 @@ const handleSendingSMS = async ({
4152
phoneNumber: reminderPhone,
4253
body: smsMessage,
4354
sender: senderID,
44-
...(!!teamId ? { teamId } : { userId: organizerUserId }),
55+
teamId,
4556
bookingUid,
4657
},
4758
});
@@ -57,32 +68,11 @@ export default abstract class SMSManager {
5768
calEvent: CalendarEvent;
5869
isTeamEvent = false;
5970
teamId: number | undefined = undefined;
60-
organizerUserId: number | undefined = undefined;
61-
private _isSMSNotificationEnabled: boolean | null = null;
6271

6372
constructor(calEvent: CalendarEvent) {
6473
this.calEvent = calEvent;
6574
this.teamId = this.calEvent?.team?.id;
6675
this.isTeamEvent = !!this.calEvent?.team?.id;
67-
this.organizerUserId = this.calEvent?.organizer?.id;
68-
}
69-
70-
private async isSMSNotificationEnabled(): Promise<boolean> {
71-
if (this._isSMSNotificationEnabled !== null) {
72-
return this._isSMSNotificationEnabled;
73-
}
74-
75-
const teamId = this.teamId;
76-
77-
if (teamId) {
78-
const team = await TeamRepository.findTeamWithOrganizationSettings(teamId);
79-
80-
this._isSMSNotificationEnabled = !team?.parent?.organizationSettings?.disablePhoneOnlySMSNotifications;
81-
return this._isSMSNotificationEnabled;
82-
}
83-
84-
this._isSMSNotificationEnabled = true;
85-
return true;
8676
}
8777

8878
getFormattedTime(
@@ -109,25 +99,17 @@ export default abstract class SMSManager {
10999
const attendeePhoneNumber = attendee.phoneNumber;
110100
const isPhoneOnlyBooking = attendeePhoneNumber && isSmsCalEmail(attendee.email);
111101

112-
if (!attendeePhoneNumber || !isPhoneOnlyBooking || !(await this.isSMSNotificationEnabled())) return;
102+
if (!this.isTeamEvent || !teamId || !attendeePhoneNumber || !isPhoneOnlyBooking) return;
113103

114104
const smsMessage = this.getMessage(attendee);
115105
const senderID = getSenderId(attendeePhoneNumber, SENDER_ID);
116-
return handleSendingSMS({
117-
reminderPhone: attendeePhoneNumber,
118-
smsMessage,
119-
senderID,
120-
teamId,
121-
bookingUid,
122-
organizerUserId: this.organizerUserId,
123-
});
106+
return handleSendingSMS({ reminderPhone: attendeePhoneNumber, smsMessage, senderID, teamId, bookingUid });
124107
}
125108

126109
async sendSMSToAttendees() {
110+
if (!this.isTeamEvent) return;
127111
const smsToSend: Promise<unknown>[] = [];
128112

129-
if (!(await this.isSMSNotificationEnabled())) return;
130-
131113
for (const attendee of this.calEvent.attendees) {
132114
smsToSend.push(this.sendSMSToAttendee(attendee, this.calEvent.uid));
133115
}

0 commit comments

Comments
 (0)