diff --git a/packages/emails/templates/_base-email.ts b/packages/emails/templates/_base-email.ts index 53dadcbb24..0aef1b46bc 100644 --- a/packages/emails/templates/_base-email.ts +++ b/packages/emails/templates/_base-email.ts @@ -2,7 +2,6 @@ import { decodeHTML } from "entities"; import { createTransport } from "nodemailer"; import { z } from "zod"; -import type { Dayjs } from "@calcom/dayjs"; import dayjs from "@calcom/dayjs"; import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; import { getErrorFromUnknown } from "@calcom/lib/errors"; @@ -20,12 +19,12 @@ export default class BaseEmail { return ""; } - protected getRecipientTime(time: string): Dayjs; - protected getRecipientTime(time: string, format: string): string; - protected getRecipientTime(time: string, format?: string) { - const date = dayjs(time).tz(this.getTimezone()); - if (typeof format === "string") return date.format(format); - return date; + protected getLocale(): string { + return ""; + } + + protected getFormattedRecipientTime({ time, format }: { time: string; format: string }) { + return dayjs(time).tz(this.getTimezone()).locale(this.getLocale()).format(format); } protected getNodeMailerPayload(): Record { diff --git a/packages/emails/templates/attendee-daily-video-download-recording-email.ts b/packages/emails/templates/attendee-daily-video-download-recording-email.ts index 4a7d679a53..7fc0a74d52 100644 --- a/packages/emails/templates/attendee-daily-video-download-recording-email.ts +++ b/packages/emails/templates/attendee-daily-video-download-recording-email.ts @@ -1,6 +1,7 @@ // TODO: We should find a way to keep App specific email templates within the App itself import type { TFunction } from "next-i18next"; +import { TimeFormat } from "@calcom/lib/timeFormat"; import type { CalendarEvent, Person } from "@calcom/types/Calendar"; import { renderEmail } from "../"; @@ -43,16 +44,28 @@ export default class AttendeeDailyVideoDownloadRecordingEmail extends BaseEmail return this.attendee.timeZone; } + protected getLocale(): string { + return this.attendee.language.locale; + } + protected getInviteeStart(format: string) { - return this.getRecipientTime(this.calEvent.startTime, format); + return this.getFormattedRecipientTime({ + time: this.calEvent.startTime, + format, + }); } protected getInviteeEnd(format: string) { - return this.getRecipientTime(this.calEvent.endTime, format); + return this.getFormattedRecipientTime({ + time: this.calEvent.endTime, + format, + }); } protected getFormattedDate() { - return `${this.getInviteeStart("h:mma")} - ${this.getInviteeEnd("h:mma")}, ${this.t( + const inviteeTimeFormat = this.attendee.timeFormat || TimeFormat.TWELVE_HOUR; + + return `${this.getInviteeStart(inviteeTimeFormat)} - ${this.getInviteeEnd(inviteeTimeFormat)}, ${this.t( this.getInviteeStart("dddd").toLowerCase() )}, ${this.t(this.getInviteeStart("MMMM").toLowerCase())} ${this.getInviteeStart("D, YYYY")}`; } diff --git a/packages/emails/templates/attendee-scheduled-email.ts b/packages/emails/templates/attendee-scheduled-email.ts index bf8bd9f26d..b483677267 100644 --- a/packages/emails/templates/attendee-scheduled-email.ts +++ b/packages/emails/templates/attendee-scheduled-email.ts @@ -6,6 +6,7 @@ import { RRule } from "rrule"; import dayjs from "@calcom/dayjs"; import { getRichDescription } from "@calcom/lib/CalEventParser"; +import { TimeFormat } from "@calcom/lib/timeFormat"; import type { CalendarEvent, Person } from "@calcom/types/Calendar"; import { renderEmail } from "../"; @@ -122,16 +123,28 @@ ${getRichDescription(this.calEvent, this.t)} return this.calEvent.attendees[0].timeZone; } + protected getLocale(): string { + return this.calEvent.attendees[0].language.locale; + } + protected getInviteeStart(format: string) { - return this.getRecipientTime(this.calEvent.startTime, format); + return this.getFormattedRecipientTime({ + time: this.calEvent.startTime, + format, + }); } protected getInviteeEnd(format: string) { - return this.getRecipientTime(this.calEvent.endTime, format); + return this.getFormattedRecipientTime({ + time: this.calEvent.endTime, + format, + }); } public getFormattedDate() { - return `${this.getInviteeStart("h:mma")} - ${this.getInviteeEnd("h:mma")}, ${this.t( + const inviteeTimeFormat = this.calEvent.organizer.timeFormat || TimeFormat.TWELVE_HOUR; + + return `${this.getInviteeStart(inviteeTimeFormat)} - ${this.getInviteeEnd(inviteeTimeFormat)}, ${this.t( this.getInviteeStart("dddd").toLowerCase() )}, ${this.t(this.getInviteeStart("MMMM").toLowerCase())} ${this.getInviteeStart("D, YYYY")}`; } diff --git a/packages/emails/templates/broken-integration-email.ts b/packages/emails/templates/broken-integration-email.ts index 89258fe16b..12d7800a89 100644 --- a/packages/emails/templates/broken-integration-email.ts +++ b/packages/emails/templates/broken-integration-email.ts @@ -2,6 +2,7 @@ import type { TFunction } from "next-i18next"; import { getRichDescription } from "@calcom/lib/CalEventParser"; import { APP_NAME } from "@calcom/lib/constants"; +import { TimeFormat } from "@calcom/lib/timeFormat"; import type { CalendarEvent } from "@calcom/types/Calendar"; import { renderEmail } from ".."; @@ -61,17 +62,30 @@ ${callToAction} return this.calEvent.organizer.timeZone; } + protected getLocale(): string { + return this.calEvent.organizer.language.locale; + } + protected getOrganizerStart(format: string) { - return this.getRecipientTime(this.calEvent.startTime, format); + return this.getFormattedRecipientTime({ + time: this.calEvent.startTime, + format, + }); } protected getOrganizerEnd(format: string) { - return this.getRecipientTime(this.calEvent.endTime, format); + return this.getFormattedRecipientTime({ + time: this.calEvent.endTime, + format, + }); } protected getFormattedDate() { - return `${this.getOrganizerStart("h:mma")} - ${this.getOrganizerEnd("h:mma")}, ${this.t( - this.getOrganizerStart("dddd").toLowerCase() - )}, ${this.t(this.getOrganizerStart("MMMM").toLowerCase())} ${this.getOrganizerStart("D, YYYY")}`; + const organizerTimeFormat = this.calEvent.organizer.timeFormat || TimeFormat.TWELVE_HOUR; + return `${this.getOrganizerStart(organizerTimeFormat)} - ${this.getOrganizerEnd( + organizerTimeFormat + )}, ${this.t(this.getOrganizerStart("dddd").toLowerCase())}, ${this.t( + this.getOrganizerStart("MMMM").toLowerCase() + )} ${this.getOrganizerStart("D, YYYY")}`; } } diff --git a/packages/emails/templates/organizer-daily-video-download-recording-email.ts b/packages/emails/templates/organizer-daily-video-download-recording-email.ts index 923a1f9251..60c673ef5c 100644 --- a/packages/emails/templates/organizer-daily-video-download-recording-email.ts +++ b/packages/emails/templates/organizer-daily-video-download-recording-email.ts @@ -1,6 +1,7 @@ import type { TFunction } from "next-i18next"; import { APP_NAME } from "@calcom/lib/constants"; +import { TimeFormat } from "@calcom/lib/timeFormat"; import type { CalendarEvent } from "@calcom/types/Calendar"; import { renderEmail } from "../"; @@ -42,16 +43,19 @@ export default class OrganizerDailyVideoDownloadRecordingEmail extends BaseEmail } protected getOrganizerStart(format: string) { - return this.getRecipientTime(this.calEvent.startTime, format); + return this.getFormattedRecipientTime({ time: this.calEvent.startTime, format }); } protected getOrganizerEnd(format: string) { - return this.getRecipientTime(this.calEvent.endTime, format); + return this.getFormattedRecipientTime({ time: this.calEvent.endTime, format }); } protected getFormattedDate() { - return `${this.getOrganizerStart("h:mma")} - ${this.getOrganizerEnd("h:mma")}, ${this.t( - this.getOrganizerStart("dddd").toLowerCase() - )}, ${this.t(this.getOrganizerStart("MMMM").toLowerCase())} ${this.getOrganizerStart("D, YYYY")}`; + const organizerTimeFormat = this.calEvent.organizer.timeFormat || TimeFormat.TWELVE_HOUR; + return `${this.getOrganizerStart(organizerTimeFormat)} - ${this.getOrganizerEnd( + organizerTimeFormat + )}, ${this.t(this.getOrganizerStart("dddd").toLowerCase())}, ${this.t( + this.getOrganizerStart("MMMM").toLowerCase() + )} ${this.getOrganizerStart("D, YYYY")}`; } } diff --git a/packages/emails/templates/organizer-rescheduled-email.ts b/packages/emails/templates/organizer-rescheduled-email.ts index fe8fcc154e..fc78a72034 100644 --- a/packages/emails/templates/organizer-rescheduled-email.ts +++ b/packages/emails/templates/organizer-rescheduled-email.ts @@ -16,13 +16,7 @@ export default class OrganizerRescheduledEmail extends OrganizerScheduledEmail { to: toAddresses.join(","), subject: `${this.calEvent.organizer.language.translate("event_type_has_been_rescheduled_on_time_date", { title: this.calEvent.title, - date: `${this.getOrganizerStart("h:mma")} - ${this.getOrganizerEnd( - "h:mma" - )}, ${this.calEvent.organizer.language.translate( - this.getOrganizerStart("dddd").toLowerCase() - )}, ${this.calEvent.organizer.language.translate( - this.getOrganizerStart("MMMM").toLowerCase() - )} ${this.getOrganizerStart("D")}, ${this.getOrganizerStart("YYYY")}`, + date: this.getFormattedDate(), })}`, html: renderEmail("OrganizerRescheduledEmail", { calEvent: { ...this.calEvent, attendeeSeatId: undefined }, diff --git a/packages/emails/templates/organizer-scheduled-email.ts b/packages/emails/templates/organizer-scheduled-email.ts index 8087a4fa30..ff71072d15 100644 --- a/packages/emails/templates/organizer-scheduled-email.ts +++ b/packages/emails/templates/organizer-scheduled-email.ts @@ -7,6 +7,7 @@ import { RRule } from "rrule"; import dayjs from "@calcom/dayjs"; import { getRichDescription } from "@calcom/lib/CalEventParser"; import { APP_NAME } from "@calcom/lib/constants"; +import { TimeFormat } from "@calcom/lib/timeFormat"; import type { CalendarEvent, Person } from "@calcom/types/Calendar"; import { renderEmail } from "../"; @@ -111,17 +112,30 @@ ${callToAction} return this.calEvent.organizer.timeZone; } + protected getLocale(): string { + return this.calEvent.organizer.language.locale; + } + protected getOrganizerStart(format: string) { - return this.getRecipientTime(this.calEvent.startTime, format); + return this.getFormattedRecipientTime({ + time: this.calEvent.startTime, + format, + }); } protected getOrganizerEnd(format: string) { - return this.getRecipientTime(this.calEvent.endTime, format); + return this.getFormattedRecipientTime({ + time: this.calEvent.endTime, + format, + }); } protected getFormattedDate() { - return `${this.getOrganizerStart("h:mma")} - ${this.getOrganizerEnd("h:mma")}, ${this.t( - this.getOrganizerStart("dddd").toLowerCase() - )}, ${this.t(this.getOrganizerStart("MMMM").toLowerCase())} ${this.getOrganizerStart("D, YYYY")}`; + const organizerTimeFormat = this.calEvent.organizer.timeFormat || TimeFormat.TWELVE_HOUR; + return `${this.getOrganizerStart(organizerTimeFormat)} - ${this.getOrganizerEnd( + organizerTimeFormat + )}, ${this.t(this.getOrganizerStart("dddd").toLowerCase())}, ${this.t( + this.getOrganizerStart("MMMM").toLowerCase() + )} ${this.getOrganizerStart("D, YYYY")}`; } }