Add more variables to event names and a dynamic field (#2898)

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: Alan <alannnc@gmail.com>
Co-authored-by: Bailey Pumfleet <pumfleet@hey.com>
This commit is contained in:
authored and GitHub committed 2022-06-06 08:48:13 -04:00
1 parent 3189f8b77a
commit 983c970069
27 files changed
+117 -46

No files matched your search

+51 -8
View File
@@ -5,15 +5,58 @@ type EventNameObjectType = {
eventType: string;
eventName?: string | null;
host: string;
location?: string;
t: TFunction;
};
export function getEventName(eventNameObj: EventNameObjectType) {
return eventNameObj.eventName
? eventNameObj.eventName.replace("{USER}", eventNameObj.attendeeName)
: eventNameObj.t("event_between_users", {
eventName: eventNameObj.eventType,
host: eventNameObj.host,
attendeeName: eventNameObj.attendeeName,
});
export function getEventName(eventNameObj: EventNameObjectType, forAttendeeView = false) {
if (!eventNameObj.eventName)
return eventNameObj.t("event_between_users", {
eventName: eventNameObj.eventType,
host: eventNameObj.host,
attendeeName: eventNameObj.attendeeName,
});
let eventName = eventNameObj.eventName;
let locationString = "";
if (eventNameObj.eventName.includes("{LOCATION}")) {
switch (eventNameObj.location) {
case "inPerson":
locationString = "In Person";
break;
case "userPhone":
case "phone":
locationString = "Phone";
break;
case "integrations:daily":
locationString = "Cal Video";
break;
case "integrations:zoom":
locationString = "Zoom";
break;
case "integrations:huddle01":
locationString = "Huddle01";
break;
case "integrations:tandem":
locationString = "Tandem";
break;
case "integrations:office365_video":
locationString = "MS Teams";
break;
case "integrations:jitsi":
locationString = "Jitsi";
break;
}
eventName = eventName.replace("{LOCATION}", locationString);
}
return (
eventName
// Need this for compatibility with older event names
.replace("{USER}", eventNameObj.attendeeName)
.replace("{ATTENDEE}", eventNameObj.attendeeName)
.replace("{HOST}", eventNameObj.host)
.replace("{HOST/ATTENDEE}", forAttendeeView ? eventNameObj.host : eventNameObj.attendeeName)
);
}
+15 -11
View File
@@ -190,6 +190,7 @@ const getEventTypesFromDB = async (eventTypeId: number) => {
hideCalendarNotes: true,
seatsPerTimeSlot: true,
recurringEvent: true,
locations: true,
},
});
@@ -260,10 +261,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
if (!eventTypeUser) return res.status(404).json({ message: "eventTypeUser.notFound" });
users.push(eventTypeUser);
}
const [organizerUser] = users;
const organizer = await prisma.user.findUnique({
where: {
id: users[0].id,
id: organizerUser.id,
},
select: {
locale: true,
@@ -357,14 +358,17 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const attendeesList = [...invitee, ...guests, ...teamMembers];
const seed = `${users[0].username}:${dayjs(req.body.start).utc().format()}:${new Date().getTime()}`;
const seed = `${organizerUser.username}:${dayjs(req.body.start).utc().format()}:${new Date().getTime()}`;
const uid = translator.fromUUID(uuidv5(seed, uuidv5.URL));
const location = !!eventType.locations ? (eventType.locations as Array<{ type: string }>)[0] : "";
const locationType = !!location && location.type ? location.type : "";
const eventNameObject = {
attendeeName: reqBody.name || "Nameless",
eventType: eventType.title,
eventName: eventType.eventName,
host: users[0].name || "Nameless",
host: organizerUser.name || "Nameless",
location: locationType,
t: tOrganizer,
};
@@ -387,15 +391,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
startTime: reqBody.start,
endTime: reqBody.end,
organizer: {
name: users[0].name || "Nameless",
email: users[0].email || "Email-less",
timeZone: users[0].timeZone,
name: organizerUser.name || "Nameless",
email: organizerUser.email || "Email-less",
timeZone: organizerUser.timeZone,
language: { translate: tOrganizer, locale: organizer?.locale ?? "en" },
},
attendees: attendeesList,
location: reqBody.location, // Will be processed by the EventManager later.
/** For team events & dynamic collective events, we will need to handle each member destinationCalendar eventually */
destinationCalendar: eventType.destinationCalendar || users[0].destinationCalendar,
destinationCalendar: eventType.destinationCalendar || organizerUser.destinationCalendar,
hideCalendarNotes: eventType.hideCalendarNotes,
};
@@ -503,7 +507,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
dynamicGroupSlugRef,
user: {
connect: {
id: users[0].id,
id: organizerUser.id,
},
},
destinationCalendar: evt.destinationCalendar
@@ -547,7 +551,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const stripePaymentCredential = await prisma.credential.findFirst({
where: {
type: "stripe_payment",
userId: users[0].id,
userId: organizerUser.id,
},
select: {
id: true,
@@ -831,7 +835,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
await Promise.all(promises);
// Avoid passing referencesToCreate with id unique constrain values
// refresh hashed link if used
const urlSeed = `${users[0].username}:${dayjs(req.body.start).utc().format()}`;
const urlSeed = `${organizerUser.username}:${dayjs(req.body.start).utc().format()}`;
const hashedUid = translator.fromUUID(uuidv5(urlSeed, uuidv5.URL));
if (hasHashedBookingLink) {
+13 -1
View File
@@ -328,6 +328,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
const minSeats = 2;
const [enableSeats, setEnableSeats] = useState(!!eventType.seatsPerTimeSlot);
const [displayNameTips, setDisplayNameTips] = useState(false);
const periodType =
PERIOD_TYPES.find((s) => s.type === eventType.periodType) ||
PERIOD_TYPES.find((s) => s.type === "UNLIMITED");
@@ -863,7 +864,6 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
const membership = team?.members.find((membership) => membership.user.id === props.session.user.id);
const isAdmin = membership?.role === MembershipRole.OWNER || membership?.role === MembershipRole.ADMIN;
return (
<div>
<Shell
@@ -1188,8 +1188,20 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
className="block w-full rounded-sm border-gray-300 text-sm "
placeholder={t("meeting_with_user")}
defaultValue={eventType.eventName || ""}
onFocus={() => setDisplayNameTips(true)}
{...formMethods.register("eventName")}
onBlur={() => setDisplayNameTips(false)}
/>
{displayNameTips && (
<div className="mt-1 text-gray-500">
<p>{`{HOST} = ${t("your_name")}`}</p>
<p>{`{ATTENDEE} = ${t("attendee_name")}`}</p>
<p>{`{HOST/ATTENDEE} = ${t(
"dynamically_display_attendee_or_organizer"
)}`}</p>
<p>{`{LOCATION} = ${t("event_location")}`}</p>
</div>
)}
</div>
</div>
</div>
+7 -1
View File
@@ -165,17 +165,22 @@ export default function Success(props: SuccessProps) {
const attendeeName = typeof name === "string" ? name : "Nameless";
const locationFromEventType = !!eventType.locations
? (eventType.locations as Array<{ type: string }>)[0]
: "";
const locationType = !!locationFromEventType ? locationFromEventType.type : "";
const eventNameObject = {
attendeeName,
eventType: props.eventType.title,
eventName: (props.dynamicEventName as string) || props.eventType.eventName,
host: props.profile.name || "Nameless",
location: locationType,
t,
};
const metadata = props.eventType?.metadata as { giphyThankYouPage: string };
const giphyImage = metadata?.giphyThankYouPage;
const eventName = getEventName(eventNameObject);
const eventName = getEventName(eventNameObject, true);
const needsConfirmation = eventType.requiresConfirmation && reschedule != "true";
const isCancelled = status === "CANCELLED" || status === "REJECTED";
const telemetry = useTelemetry();
@@ -680,6 +685,7 @@ const getEventTypesFromDB = async (id: number) => {
requiresConfirmation: true,
userId: true,
successRedirectUrl: true,
locations: true,
users: {
select: {
id: true,
@@ -605,7 +605,7 @@
"show_advanced_settings": "عرض الإعدادات المتقدمة",
"event_name": "اسم الحدث",
"event_name_tooltip": "الاسم الذي سيظهر في التقاويم",
"meeting_with_user": "الاجتماع مع {USER}",
"meeting_with_user": "الاجتماع مع {ATTENDEE}",
"additional_inputs": "مدخلات إضافية",
"label": "العلامة",
"placeholder": "العنصر النائب",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Zobrazit pokročilá nastavení",
"event_name": "Název události",
"event_name_tooltip": "Název, který se zobrazí v kalendářích",
"meeting_with_user": "Schůzka s {USER}",
"meeting_with_user": "Schůzka s {ATTENDEE}",
"additional_inputs": "Další pole",
"label": "Popisek",
"placeholder": "Placeholder",
@@ -605,7 +605,7 @@
"show_advanced_settings": "Erweiterte Einstellungen anzeigen",
"event_name": "Ereignisname",
"event_name_tooltip": "Der Name, der in Kalendern angezeigt wird",
"meeting_with_user": "Meeting mit {USER}",
"meeting_with_user": "Meeting mit {ATTENDEE}",
"additional_inputs": "Zusätzliche Notizen",
"label": "Bezeichnung",
"placeholder": "Placeholder",
@@ -607,7 +607,7 @@
"show_advanced_settings": "Show advanced settings",
"event_name": "Event Name",
"event_name_tooltip": "The name that will appear in calendars",
"meeting_with_user": "Meeting with {USER}",
"meeting_with_user": "Meeting with {ATTENDEE}",
"additional_inputs": "Additional Inputs",
"label": "Label",
"placeholder": "Placeholder",
@@ -822,8 +822,8 @@
"confirmation_page_gif": "Gif for confirmation page",
"search": "Search",
"impersonate": "Impersonate",
"user_impersonation_heading":"User Impersonation",
"user_impersonation_description":"Allows our support team to temporarily sign in as you to help us quickly resolve any issues you report to us.",
"user_impersonation_heading": "User Impersonation",
"user_impersonation_description": "Allows our support team to temporarily sign in as you to help us quickly resolve any issues you report to us.",
"impersonate_user_tip": "All uses of this feature is audited.",
"impersonating_user_warning": "Impersonating username \"{{user}}\".",
"impersonating_stop_instructions": "<0>Click Here to stop</0>.",
@@ -852,6 +852,8 @@
"calendar_error": "Something went wrong, try reconnecting your calendar with all necessary permissions",
"set_your_phone_number": "Set a phone number for the meeting",
"calendar_no_busy_slots": "There are no busy slots",
"display_location_label": "Display on booking page",
"display_location_info_badge": "Location will be visible before the booking is confirmed",
"add_gif": "Add GIF",
"search_giphy": "Search Giphy",
"add_link_from_giphy": "Add link from Giphy",
@@ -874,6 +876,10 @@
"nevermind": "Nevermind",
"go_to": "Go to: ",
"zapier_invite_link": "Zapier Invite Link",
"meeting_url_provided_after_confirmed": "A Meeting URL will be created once the event is confirmed.",
"attendees_name": "Attendee's name",
"dynamically_display_attendee_or_organizer": "Dynamically display the name of your attendee for you, or your name if it's viewed by your attendee",
"event_location": "Event's location",
"meeting_url_provided_after_confirmed":"A Meeting URL will be created once the event is confirmed.",
"reschedule_optional": "Reason for rescheduling (optional)",
"reschedule_placeholder": "Let others know why you need to reschedule",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Mostrar Opciones Avanzadas",
"event_name": "Nombre del Evento",
"event_name_tooltip": "Nombre que aparecerá en los calendarios",
"meeting_with_user": "Reunión con {USER}",
"meeting_with_user": "Reunión con {ATTENDEE}",
"additional_inputs": "Campos Adicionales",
"label": "Etiqueta",
"placeholder": "Marcador de posición",
@@ -605,7 +605,7 @@
"show_advanced_settings": "Afficher les paramètres avancés",
"event_name": "Nom de l'événement",
"event_name_tooltip": "Le nom qui apparaîtra dans les calendriers",
"meeting_with_user": "Rendez-vous avec {USER}",
"meeting_with_user": "Rendez-vous avec {ATTENDEE}",
"additional_inputs": "Entrées additionnelles",
"label": "Libellé",
"placeholder": "Placeholder",
@@ -604,7 +604,7 @@
"show_advanced_settings": "הצגת הגדרות מתקדמות",
"event_name": "שם האירוע",
"event_name_tooltip": "השם שיופיע בלוחות השנה",
"meeting_with_user": "פגישה עם {USER}",
"meeting_with_user": "פגישה עם {ATTENDEE}",
"additional_inputs": "אפשרויות קלט נוספות",
"label": "תווית",
"placeholder": "מציין מיקום",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Mostra impostazioni avanzate",
"event_name": "Nome Dell'Evento",
"event_name_tooltip": "Il nome che apparirà nei calendari",
"meeting_with_user": "Riunione con {USER}",
"meeting_with_user": "Riunione con {ATTENDEE}",
"additional_inputs": "Input Aggiuntivi",
"label": "Etichetta",
"placeholder": "Segnaposto",
@@ -604,7 +604,7 @@
"show_advanced_settings": "詳細設定を表示",
"event_name": "イベント名",
"event_name_tooltip": "カレンダーに表示される名前",
"meeting_with_user": "{USER} とのミーティング",
"meeting_with_user": "{ATTENDEE} とのミーティング",
"additional_inputs": "追加入力",
"label": "ラベル",
"placeholder": "プレースホルダー",
@@ -604,7 +604,7 @@
"show_advanced_settings": "고급 설정 표시",
"event_name": "이벤트 이름",
"event_name_tooltip": "캘린더에 표시될 이름",
"meeting_with_user": "{USER} 님과의 회의",
"meeting_with_user": "{ATTENDEE} 님과의 회의",
"additional_inputs": "추가 입력",
"label": "레이블",
"placeholder": "자리 표시자",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Toon geavanceerde instellingen",
"event_name": "Naam van evenement",
"event_name_tooltip": "De naam die in kalenders wordt weergegeven",
"meeting_with_user": "Afspraak met {USER}",
"meeting_with_user": "Afspraak met {ATTENDEE}",
"additional_inputs": "Extra invoer",
"label": "Omschrijving",
"placeholder": "Plaatsaanduiding",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Pokaż ustawienia zaawansowane",
"event_name": "Nazwa wydarzenia",
"event_name_tooltip": "Nazwa, która pojawi się w kalendarzach",
"meeting_with_user": "Spotkanie z {USER}",
"meeting_with_user": "Spotkanie z {ATTENDEE}",
"additional_inputs": "Dodatkowe Wejścia",
"label": "Etykieta",
"placeholder": "Tekst zastępczy",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Mostrar Configurações Avançadas",
"event_name": "Nome do Evento",
"event_name_tooltip": "O nome que aparecerá nos calendários",
"meeting_with_user": "Reunião com {USER}",
"meeting_with_user": "Reunião com {ATTENDEE}",
"additional_inputs": "Campos adicionais",
"label": "Etiqueta",
"placeholder": "Preenchimento",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Mostrar Configurações Avançadas",
"event_name": "Nome do Evento",
"event_name_tooltip": "O nome que será mostrado nos calendários",
"meeting_with_user": "Reunião com {USER}",
"meeting_with_user": "Reunião com {ATTENDEE}",
"additional_inputs": "Campos adicionais",
"label": "Etiqueta",
"placeholder": "Preenchimento",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Afișează setările avansate",
"event_name": "Denumirea evenimentului",
"event_name_tooltip": "Numele care va apărea în calendare",
"meeting_with_user": "Întâlnire cu {USER}",
"meeting_with_user": "Întâlnire cu {ATTENDEE}",
"additional_inputs": "Date suplimentare",
"label": "Eticheta",
"placeholder": "Placeholder",
@@ -605,7 +605,7 @@
"show_advanced_settings": "Показать дополнительные параметры",
"event_name": "Название события",
"event_name_tooltip": "Название, которое будет отображаться в календарях",
"meeting_with_user": "Встреча с {USER}",
"meeting_with_user": "Встреча с {ATTENDEE}",
"additional_inputs": "Дополнительные вопросы",
"label": "Название",
"placeholder": "Placeholder",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Pokaži napredna podešavanja",
"event_name": "Ime Događaja",
"event_name_tooltip": "Ime koje će se pojaviti u kalendarima",
"meeting_with_user": "Sastanak sa {USER}",
"meeting_with_user": "Sastanak sa {ATTENDEE}",
"additional_inputs": "Dodatni unosi",
"label": "Oznaka",
"placeholder": "Placeholder",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Visa avancerade inställningar",
"event_name": "Händelsenamn",
"event_name_tooltip": "Namnet som kommer visas i kalendrar",
"meeting_with_user": "Möte med {USER}",
"meeting_with_user": "Möte med {ATTENDEE}",
"additional_inputs": "Ytterligare inmatningar",
"label": "Etikett",
"placeholder": "Platshållare",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Gelişmiş ayarları göster",
"event_name": "Etkinlik Adı",
"event_name_tooltip": "Takvimlerde görünecek isim",
"meeting_with_user": "{USER} ile toplantı",
"meeting_with_user": "{ATTENDEE} ile toplantı",
"additional_inputs": "Ek Girişler",
"label": "Etiket",
"placeholder": "Yer tutucu",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Показати додаткові параметри",
"event_name": "Тип заходу",
"event_name_tooltip": "Ім’я, яке показуватиметься в календарях",
"meeting_with_user": "Нарада з користувачем {USER}",
"meeting_with_user": "Нарада з користувачем {ATTENDEE}",
"additional_inputs": "Додаткові поля введення",
"label": "Мітка",
"placeholder": "Заповнювач",
@@ -604,7 +604,7 @@
"show_advanced_settings": "Hiển thị cài đặt nâng cao",
"event_name": "Tên sự kiện",
"event_name_tooltip": "Tên sẽ xuất hiện trong lịch",
"meeting_with_user": "Gặp gỡ với {USER}",
"meeting_with_user": "Gặp gỡ với {ATTENDEE}",
"additional_inputs": "Trường bổ sung",
"label": "Label",
"placeholder": "Placeholder",
@@ -605,7 +605,7 @@
"show_advanced_settings": "显示高级设置",
"event_name": "活动名称",
"event_name_tooltip": "在日历中显示的名称",
"meeting_with_user": "与 {USER} 的会议",
"meeting_with_user": "与 {ATTENDEE} 的会议",
"additional_inputs": "更多输入框",
"label": "标签",
"placeholder": "占位符",
@@ -604,7 +604,7 @@
"show_advanced_settings": "顯示進階設定",
"event_name": "活動名稱",
"event_name_tooltip": "會顯示在行事曆上的名字",
"meeting_with_user": "與 {USER} 的會議",
"meeting_with_user": "與 {ATTENDEE} 的會議",
"additional_inputs": "額外輸入欄",
"label": "標籤",
"placeholder": "提示",