Merge pull request #348 from emrysal/bugfix/available-slots-timezone
Fixes #347: timeZone is not applied to AvailableTimespull/352/head
commit
1fe0dc1dc6
|
@ -3,10 +3,25 @@ import { useRouter } from "next/router";
|
||||||
import Slots from "./Slots";
|
import Slots from "./Slots";
|
||||||
import { ExclamationIcon } from "@heroicons/react/solid";
|
import { ExclamationIcon } from "@heroicons/react/solid";
|
||||||
|
|
||||||
const AvailableTimes = ({ date, eventLength, eventTypeId, workingHours, timeFormat, user }) => {
|
const AvailableTimes = ({
|
||||||
|
date,
|
||||||
|
eventLength,
|
||||||
|
eventTypeId,
|
||||||
|
workingHours,
|
||||||
|
timeFormat,
|
||||||
|
user,
|
||||||
|
organizerTimeZone,
|
||||||
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { rescheduleUid } = router.query;
|
const { rescheduleUid } = router.query;
|
||||||
const { slots, isFullyBooked, hasErrors } = Slots({ date, eventLength, workingHours });
|
|
||||||
|
const { slots, isFullyBooked, hasErrors } = Slots({
|
||||||
|
date,
|
||||||
|
eventLength,
|
||||||
|
workingHours,
|
||||||
|
organizerTimeZone,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="sm:pl-4 mt-8 sm:mt-0 text-center sm:w-1/3 md:max-h-97 overflow-y-auto">
|
<div className="sm:pl-4 mt-8 sm:mt-0 text-center sm:w-1/3 md:max-h-97 overflow-y-auto">
|
||||||
<div className="text-gray-600 font-light text-xl mb-4 text-left">
|
<div className="text-gray-600 font-light text-xl mb-4 text-left">
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { useEffect, useState } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import getSlots from "../../lib/slots";
|
import getSlots from "../../lib/slots";
|
||||||
import dayjs, { Dayjs } from "dayjs";
|
import dayjs, { Dayjs } from "dayjs";
|
||||||
import isBetween from "dayjs/plugin/isBetween";
|
import isBetween from "dayjs/plugin/isBetween";
|
||||||
import utc from "dayjs/plugin/utc";
|
import utc from "dayjs/plugin/utc";
|
||||||
|
|
||||||
dayjs.extend(isBetween);
|
dayjs.extend(isBetween);
|
||||||
dayjs.extend(utc);
|
dayjs.extend(utc);
|
||||||
|
|
||||||
|
@ -12,9 +11,11 @@ type Props = {
|
||||||
eventLength: number;
|
eventLength: number;
|
||||||
minimumBookingNotice?: number;
|
minimumBookingNotice?: number;
|
||||||
date: Dayjs;
|
date: Dayjs;
|
||||||
|
workingHours: [];
|
||||||
|
organizerTimeZone: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Slots = ({ eventLength, minimumBookingNotice, date, workingHours, organizerUtcOffset }: Props) => {
|
const Slots = ({ eventLength, minimumBookingNotice, date, workingHours, organizerTimeZone }: Props) => {
|
||||||
minimumBookingNotice = minimumBookingNotice || 0;
|
minimumBookingNotice = minimumBookingNotice || 0;
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -48,7 +49,7 @@ const Slots = ({ eventLength, minimumBookingNotice, date, workingHours, organize
|
||||||
inviteeDate: date,
|
inviteeDate: date,
|
||||||
workingHours,
|
workingHours,
|
||||||
minimumBookingNotice,
|
minimumBookingNotice,
|
||||||
organizerUtcOffset,
|
organizerTimeZone,
|
||||||
});
|
});
|
||||||
|
|
||||||
const timesLengthBeforeConflicts: number = times.length;
|
const timesLengthBeforeConflicts: number = times.length;
|
||||||
|
|
|
@ -81,9 +81,12 @@ const organizerBoundaries = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
boundaries.push({ lowerBound, upperBound });
|
if (item.days.includes(startDay)) {
|
||||||
|
boundaries.push({ lowerBound, upperBound });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return boundaries;
|
return boundaries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,7 +119,7 @@ const getSlots = ({
|
||||||
workingHours,
|
workingHours,
|
||||||
organizerTimeZone,
|
organizerTimeZone,
|
||||||
}: GetSlots): Dayjs[] => {
|
}: GetSlots): Dayjs[] => {
|
||||||
const startTime = dayjs.utc().isSame(dayjs(inviteeDate), "day")
|
const startTime = dayjs().utcOffset(inviteeDate.utcOffset()).isSame(inviteeDate, "day")
|
||||||
? inviteeDate.hour() * 60 + inviteeDate.minute() + (minimumBookingNotice || 0)
|
? inviteeDate.hour() * 60 + inviteeDate.minute() + (minimumBookingNotice || 0)
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@ import { useEffect, useState } from "react";
|
||||||
import { GetServerSideProps } from "next";
|
import { GetServerSideProps } from "next";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { ChevronDownIcon, ClockIcon, GlobeIcon } from "@heroicons/react/solid";
|
import { ChevronDownIcon, ClockIcon, GlobeIcon } from "@heroicons/react/solid";
|
||||||
import prisma from "../../lib/prisma";
|
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { Dayjs } from "dayjs";
|
import { Dayjs } from "dayjs";
|
||||||
|
|
||||||
|
import prisma, { whereAndSelect } from "@lib/prisma";
|
||||||
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "../../lib/telemetry";
|
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "../../lib/telemetry";
|
||||||
import AvailableTimes from "../../components/booking/AvailableTimes";
|
import AvailableTimes from "../../components/booking/AvailableTimes";
|
||||||
import TimeOptions from "../../components/booking/TimeOptions";
|
import TimeOptions from "../../components/booking/TimeOptions";
|
||||||
|
@ -134,6 +134,7 @@ export default function Type(props): Type {
|
||||||
<AvailableTimes
|
<AvailableTimes
|
||||||
workingHours={props.workingHours}
|
workingHours={props.workingHours}
|
||||||
timeFormat={timeFormat}
|
timeFormat={timeFormat}
|
||||||
|
organizerTimeZone={props.eventType.timeZone || props.user.timeZone}
|
||||||
eventLength={props.eventType.length}
|
eventLength={props.eventType.length}
|
||||||
eventTypeId={props.eventType.id}
|
eventTypeId={props.eventType.id}
|
||||||
date={selectedDate}
|
date={selectedDate}
|
||||||
|
@ -149,26 +150,27 @@ export default function Type(props): Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps = async (context) => {
|
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||||
const user = await prisma.user.findFirst({
|
const user = await whereAndSelect(
|
||||||
where: {
|
prisma.user.findFirst,
|
||||||
|
{
|
||||||
username: context.query.user.toLowerCase(),
|
username: context.query.user.toLowerCase(),
|
||||||
},
|
},
|
||||||
select: {
|
[
|
||||||
id: true,
|
"id",
|
||||||
username: true,
|
"username",
|
||||||
name: true,
|
"name",
|
||||||
email: true,
|
"email",
|
||||||
bio: true,
|
"bio",
|
||||||
avatar: true,
|
"avatar",
|
||||||
eventTypes: true,
|
"eventTypes",
|
||||||
startTime: true,
|
"startTime",
|
||||||
timeZone: true,
|
"endTime",
|
||||||
endTime: true,
|
"timeZone",
|
||||||
weekStart: true,
|
"weekStart",
|
||||||
availability: true,
|
"availability",
|
||||||
hideBranding: true,
|
"hideBranding",
|
||||||
},
|
]
|
||||||
});
|
);
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return {
|
return {
|
||||||
|
@ -176,22 +178,14 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventType = await prisma.eventType.findFirst({
|
const eventType = await whereAndSelect(
|
||||||
where: {
|
prisma.eventType.findFirst,
|
||||||
|
{
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
slug: {
|
slug: context.query.type,
|
||||||
equals: context.query.type,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
select: {
|
["id", "title", "description", "length", "availability", "timeZone"]
|
||||||
id: true,
|
);
|
||||||
title: true,
|
|
||||||
description: true,
|
|
||||||
length: true,
|
|
||||||
availability: true,
|
|
||||||
timeZone: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!eventType) {
|
if (!eventType) {
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Reference in New Issue