fix: display phone numbers and localized timezone in BookingDetailsSheet (#27909)
* fix: display phone numbers and localized timezone in BookingDetailsSheet Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: replace selectAll with explicit column selects for Attendee query Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * Update apps/web/modules/bookings/components/BookingDetailsSheet.tsx Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> * Add tests: packages/lib/dayjs/formatToLocalizedTimezone.test.ts Generated by Paragon from proposal for PR #27909 * Revert "refactor: replace selectAll with explicit column selects for Attendee query" This reverts commit f810ba801c900c8f065e5e1ce1d02a1700322257. --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
cubic-dev-ai[bot]
Devin AI
parent
50c7210d6b
commit
1b6b91b0ad
@@ -4,6 +4,7 @@ import dayjs from "@calcom/dayjs";
|
||||
import { useBookingLocation } from "@calcom/features/bookings/hooks";
|
||||
import { shouldShowFieldInCustomResponses } from "@calcom/lib/bookings/SystemField";
|
||||
import { formatPrice } from "@calcom/lib/currencyConversions";
|
||||
import { formatToLocalizedTimezone } from "@calcom/lib/dayjs";
|
||||
import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage";
|
||||
import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
@@ -445,14 +446,20 @@ function DisplayTimestamp({
|
||||
endTime: Date | dayjs.Dayjs;
|
||||
timeZone?: string;
|
||||
}) {
|
||||
const {
|
||||
i18n: { language },
|
||||
} = useLocale();
|
||||
const start = startTime instanceof Date ? dayjs(startTime).tz(timeZone) : startTime;
|
||||
const end = endTime instanceof Date ? dayjs(endTime).tz(timeZone) : endTime;
|
||||
const localizedTimezone = timeZone
|
||||
? formatToLocalizedTimezone(start, language, timeZone) ?? timeZone
|
||||
: start.format("Z");
|
||||
|
||||
return (
|
||||
<>
|
||||
<span>{start.format("dddd, MMMM D, YYYY")}</span>
|
||||
<span>
|
||||
{start.format("h:mma")} - {end.format("h:mma")} ({timeZone || start.format("Z")})
|
||||
{start.format("h:mma")} - {end.format("h:mma")} ({localizedTimezone})
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
@@ -507,6 +514,9 @@ function WhoSection({ booking }: { booking: BookingOutput }) {
|
||||
/>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="text-emphasis truncate text-sm leading-[1.2]">{name}</p>
|
||||
{attendee.phoneNumber && (
|
||||
<p className="text-default truncate text-sm leading-[1.2]">{attendee.phoneNumber}</p>
|
||||
)}
|
||||
<p className="text-default truncate text-sm leading-[1.2]">{attendee.email}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
import { describe, expect, it, beforeAll, vi } from "vitest";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
|
||||
import { formatToLocalizedTimezone } from "./index";
|
||||
|
||||
beforeAll(() => {
|
||||
vi.setSystemTime(dayjs.utc("2024-06-15T12:00:00Z").toDate());
|
||||
});
|
||||
|
||||
describe("formatToLocalizedTimezone", () => {
|
||||
it("returns a localized timezone string for a Date object with explicit timezone", () => {
|
||||
const date = new Date("2024-06-15T12:00:00Z");
|
||||
const result = formatToLocalizedTimezone(date, "en", "America/New_York");
|
||||
expect(result).toBeDefined();
|
||||
expect(typeof result).toBe("string");
|
||||
// Should contain recognizable timezone name like "Eastern Daylight Time"
|
||||
expect(result!.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("returns a localized timezone string for a Dayjs object with explicit timezone", () => {
|
||||
const date = dayjs.utc("2024-06-15T12:00:00Z");
|
||||
const result = formatToLocalizedTimezone(date, "en", "America/New_York");
|
||||
expect(result).toBeDefined();
|
||||
expect(typeof result).toBe("string");
|
||||
expect(result!.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("returns consistent results for Date and Dayjs objects with same timezone", () => {
|
||||
const jsDate = new Date("2024-06-15T12:00:00Z");
|
||||
const djsDate = dayjs.utc("2024-06-15T12:00:00Z");
|
||||
const resultDate = formatToLocalizedTimezone(jsDate, "en", "America/New_York");
|
||||
const resultDayjs = formatToLocalizedTimezone(djsDate, "en", "America/New_York");
|
||||
expect(resultDate).toBe(resultDayjs);
|
||||
});
|
||||
|
||||
it("returns different results for different timezones", () => {
|
||||
const date = new Date("2024-06-15T12:00:00Z");
|
||||
const nyResult = formatToLocalizedTimezone(date, "en", "America/New_York");
|
||||
const tokyoResult = formatToLocalizedTimezone(date, "en", "Asia/Tokyo");
|
||||
expect(nyResult).not.toBe(tokyoResult);
|
||||
});
|
||||
|
||||
it("returns a short timezone name when timeZoneName is 'short'", () => {
|
||||
const date = new Date("2024-06-15T12:00:00Z");
|
||||
const longResult = formatToLocalizedTimezone(date, "en", "America/New_York", "long");
|
||||
const shortResult = formatToLocalizedTimezone(date, "en", "America/New_York", "short");
|
||||
expect(shortResult).toBeDefined();
|
||||
expect(longResult).toBeDefined();
|
||||
// Short name should be shorter than or equal to long name
|
||||
expect(shortResult!.length).toBeLessThanOrEqual(longResult!.length);
|
||||
});
|
||||
|
||||
it("defaults to long timezone name when timeZoneName is not provided", () => {
|
||||
const date = new Date("2024-06-15T12:00:00Z");
|
||||
const defaultResult = formatToLocalizedTimezone(date, "en", "America/New_York");
|
||||
const longResult = formatToLocalizedTimezone(date, "en", "America/New_York", "long");
|
||||
expect(defaultResult).toBe(longResult);
|
||||
});
|
||||
|
||||
it("works with undefined locale (falls back to environment default)", () => {
|
||||
const date = new Date("2024-06-15T12:00:00Z");
|
||||
const result = formatToLocalizedTimezone(date, undefined, "America/New_York");
|
||||
expect(result).toBeDefined();
|
||||
expect(typeof result).toBe("string");
|
||||
expect(result!.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("handles UTC timezone", () => {
|
||||
const date = new Date("2024-06-15T12:00:00Z");
|
||||
const result = formatToLocalizedTimezone(date, "en", "UTC");
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toContain("Coordinated Universal Time");
|
||||
});
|
||||
|
||||
it("handles Europe/London timezone", () => {
|
||||
const date = new Date("2024-06-15T12:00:00Z");
|
||||
const result = formatToLocalizedTimezone(date, "en", "Europe/London");
|
||||
expect(result).toBeDefined();
|
||||
expect(typeof result).toBe("string");
|
||||
expect(result!.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("handles Pacific/Auckland timezone", () => {
|
||||
const date = new Date("2024-06-15T12:00:00Z");
|
||||
const result = formatToLocalizedTimezone(date, "en", "Pacific/Auckland");
|
||||
expect(result).toBeDefined();
|
||||
expect(typeof result).toBe("string");
|
||||
expect(result!.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user