diff --git a/packages/features/bookings/Booker/components/Header.tsx b/packages/features/bookings/Booker/components/Header.tsx
index 9ac23eff02..4220c43060 100644
--- a/packages/features/bookings/Booker/components/Header.tsx
+++ b/packages/features/bookings/Booker/components/Header.tsx
@@ -57,7 +57,7 @@ export function Header({
return ;
}
- const endDate = selectedDate.add(extraDays, "days");
+ const endDate = selectedDate.add(extraDays - 1, "days");
const isSameMonth = () => {
return selectedDate.format("MMM") === endDate.format("MMM");
diff --git a/packages/features/bookings/Booker/components/LargeCalendar.tsx b/packages/features/bookings/Booker/components/LargeCalendar.tsx
index b312f22821..021f53180c 100644
--- a/packages/features/bookings/Booker/components/LargeCalendar.tsx
+++ b/packages/features/bookings/Booker/components/LargeCalendar.tsx
@@ -4,7 +4,6 @@ import dayjs from "@calcom/dayjs";
import { Calendar } from "@calcom/features/calendars/weeklyview";
import type { CalendarAvailableTimeslots } from "@calcom/features/calendars/weeklyview/types/state";
-import { useTimePreferences } from "../../lib/timePreferences";
import { useBookerStore } from "../store";
import { useEvent, useScheduleForEvent } from "../utils/event";
@@ -16,7 +15,6 @@ export const LargeCalendar = ({ extraDays }: { extraDays: number }) => {
const schedule = useScheduleForEvent({
prefetchNextMonth: !!extraDays && dayjs(date).month() !== dayjs(date).add(extraDays, "day").month(),
});
- const { timezone } = useTimePreferences();
const event = useEvent();
const eventDuration = selectedEventDuration || event?.data?.length || 30;
@@ -28,15 +26,18 @@ export const LargeCalendar = ({ extraDays }: { extraDays: number }) => {
for (const day in schedule.data.slots) {
availableTimeslots[day] = schedule.data.slots[day].map((slot) => ({
- // First formatting to LLL and then passing it to date prevents toDate()
- // from changing the timezone to users local machine (instead of itmezone selected in UI dropdown)
- start: new Date(dayjs(slot.time).utc().tz(timezone).format("LLL")),
- end: new Date(dayjs(slot.time).utc().tz(timezone).add(eventDuration, "minutes").format("LLL")),
+ start: dayjs(slot.time).toDate(),
+ end: dayjs(slot.time).add(eventDuration, "minutes").toDate(),
}));
}
return availableTimeslots;
- }, [schedule, timezone, eventDuration]);
+ }, [schedule, eventDuration]);
+
+ const startDate = selectedDate ? dayjs(selectedDate).toDate() : dayjs().toDate();
+ const endDate = dayjs(startDate)
+ .add(extraDays - 1, "day")
+ .toDate();
return (
@@ -46,9 +47,9 @@ export const LargeCalendar = ({ extraDays }: { extraDays: number }) => {
startHour={0}
endHour={23}
events={[]}
- startDate={selectedDate ? new Date(selectedDate) : new Date()}
- endDate={dayjs(selectedDate).add(extraDays, "day").toDate()}
- onEmptyCellClick={(date) => setSelectedTimeslot(date.toString())}
+ startDate={startDate}
+ endDate={endDate}
+ onEmptyCellClick={(date) => setSelectedTimeslot(date.toISOString())}
gridCellsPerHour={60 / eventDuration}
hoverEventDuration={eventDuration}
hideHeader
diff --git a/packages/features/calendars/weeklyview/components/Calendar.tsx b/packages/features/calendars/weeklyview/components/Calendar.tsx
index 72ee40d20f..ba33adc2a6 100644
--- a/packages/features/calendars/weeklyview/components/Calendar.tsx
+++ b/packages/features/calendars/weeklyview/components/Calendar.tsx
@@ -1,5 +1,6 @@
import React, { useEffect, useMemo, useRef } from "react";
+import { useTimePreferences } from "@calcom/features/bookings/lib/timePreferences";
import { classNames } from "@calcom/lib";
import { useCalendarStore } from "../state/store";
@@ -22,6 +23,7 @@ export function Calendar(props: CalendarComponentProps) {
const containerOffset = useRef
(null);
const schedulerGrid = useRef(null);
const initalState = useCalendarStore((state) => state.initState);
+ const { timezone } = useTimePreferences();
const startDate = useCalendarStore((state) => state.startDate);
const endDate = useCalendarStore((state) => state.endDate);
@@ -32,7 +34,11 @@ export function Calendar(props: CalendarComponentProps) {
const hideHeader = useCalendarStore((state) => state.hideHeader);
const days = useMemo(() => getDaysBetweenDates(startDate, endDate), [startDate, endDate]);
- const hours = useMemo(() => getHoursToDisplay(startHour || 0, endHour || 23), [startHour, endHour]);
+
+ const hours = useMemo(
+ () => getHoursToDisplay(startHour || 0, endHour || 23, timezone),
+ [startHour, endHour, timezone]
+ );
const numberOfGridStopsPerDay = hours.length * usersCellsStopsPerHour;
const hourSize = 58;
@@ -108,7 +114,7 @@ export function Calendar(props: CalendarComponentProps) {
{availableTimeslots ? (
@@ -119,11 +125,12 @@ export function Calendar(props: CalendarComponentProps) {
return (
);
})}
diff --git a/packages/features/calendars/weeklyview/components/currentTime/index.tsx b/packages/features/calendars/weeklyview/components/currentTime/index.tsx
index e47a531be0..2840031461 100644
--- a/packages/features/calendars/weeklyview/components/currentTime/index.tsx
+++ b/packages/features/calendars/weeklyview/components/currentTime/index.tsx
@@ -5,6 +5,12 @@ import { useTimePreferences } from "@calcom/features/bookings/lib";
import { useCalendarStore } from "../../state/store";
+function calculateMinutesFromStart(startHour: number, currentHour: number, currentMinute: number) {
+ const startMinute = startHour * 60;
+ const currentMinuteOfDay = currentHour * 60 + currentMinute;
+ return currentMinuteOfDay - startMinute;
+}
+
export function CurrentTime() {
const currentTimeRef = useRef(null);
const [scrolledIntoView, setScrolledIntoView] = useState(false);
@@ -13,19 +19,21 @@ export function CurrentTime() {
startHour: state.startHour || 0,
endHour: state.endHour || 23,
}));
- const { timeFormat } = useTimePreferences();
+ const { timeFormat, timezone } = useTimePreferences();
useEffect(() => {
// Set the container scroll position based on the current time.
- const currentHour = new Date().getHours();
- let currentMinute = new Date().getHours() * 60;
- currentMinute = currentMinute + new Date().getMinutes();
+
+ const currentDateTime = dayjs().tz(timezone); // Get current date and time in the specified timezone
+
+ const currentHour = currentDateTime.hour();
+ const currentMinute = currentDateTime.minute();
if (currentHour > endHour || currentHour < startHour) {
setCurrentTimePos(null);
}
- const minutesFromStart = currentMinute - startHour * 60;
+ const minutesFromStart = calculateMinutesFromStart(startHour, currentHour, currentMinute);
setCurrentTimePos(minutesFromStart);
if (!currentTimeRef.current || scrolledIntoView) return;
@@ -35,7 +43,7 @@ export function CurrentTime() {
setScrolledIntoView(true);
}, 100);
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [startHour, endHour, scrolledIntoView]);
+ }, [startHour, endHour, scrolledIntoView, timezone]);
return (
-
{dayjs().format(timeFormat)}
+
{dayjs().tz(timezone).format(timeFormat)}
diff --git a/packages/features/calendars/weeklyview/components/event/Empty.tsx b/packages/features/calendars/weeklyview/components/event/Empty.tsx
index bdf4d4ee76..c80341e0ea 100644
--- a/packages/features/calendars/weeklyview/components/event/Empty.tsx
+++ b/packages/features/calendars/weeklyview/components/event/Empty.tsx
@@ -23,12 +23,12 @@ export function EmptyCell(props: EmptyCellProps) {
totalGridCells: props.totalGridCells,
selectionLength: props.selectionLength,
startHour: props.startHour,
+ timezone: props.timezone,
});
- const minuesFromStart =
- (cellToDate.toDate().getHours() - props.startHour) * 60 + cellToDate.toDate().getMinutes();
+ const minuesFromStart = (cellToDate.hour() - props.startHour) * 60 + cellToDate.minute();
- return | ;
+ return | ;
}
type AvailableCellProps = {
@@ -38,26 +38,29 @@ type AvailableCellProps = {
};
export function AvailableCellsForDay({ availableSlots, day, startHour }: AvailableCellProps) {
+ const { timezone } = useTimePreferences();
+
const slotsForToday = availableSlots && availableSlots[dayjs(day).format("YYYY-MM-DD")];
const slots = useMemo(
() =>
slotsForToday?.map((slot) => ({
slot,
- topOffsetMinutes: (slot.start.getHours() - startHour) * 60 + slot.start.getMinutes(),
+ topOffsetMinutes:
+ (dayjs(slot.start).tz(timezone).hour() - startHour) * 60 + dayjs(slot.start).tz(timezone).minute(),
})),
- [slotsForToday, startHour]
+ [slotsForToday, startHour, timezone]
);
if (!availableSlots) return null;
return (
<>
- {slots?.map((slot) => {
+ {slots?.map((slot, index) => {
return (
|
);
@@ -73,7 +76,8 @@ type CellProps = {
};
function Cell({ isDisabled, topOffsetMinutes, timeSlot }: CellProps) {
- const timeFormat = useTimePreferences((state) => state.timeFormat);
+ const { timeFormat } = useTimePreferences();
+
const { onEmptyCellClick, hoverEventDuration } = useCalendarStore(
(state) => ({
onEmptyCellClick: state.onEmptyCellClick,
@@ -97,7 +101,9 @@ function Cell({ isDisabled, topOffsetMinutes, timeSlot }: CellProps) {
overflow: "visible",
top: topOffsetMinutes ? `calc(${topOffsetMinutes}*var(--one-minute-height))` : undefined,
}}
- onClick={() => onEmptyCellClick && onEmptyCellClick(timeSlot.toDate())}>
+ onClick={() => {
+ onEmptyCellClick && onEmptyCellClick(timeSlot.toDate());
+ }}>
{!isDisabled && hoverEventDuration !== 0 && (