From cbf528c33e256e8e6f4d8beca5fb98ddb6ed2e51 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Sun, 19 Dec 2021 13:11:31 +0100 Subject: [PATCH] Allows setting the event frequency to other than event length (#1349) --- components/booking/AvailableTimes.tsx | 3 ++ components/booking/pages/AvailabilityPage.tsx | 1 + lib/hooks/useSlots.ts | 5 +- lib/types/event-type.ts | 1 + pages/[user]/[type].tsx | 1 + pages/api/availability/eventtype.ts | 1 + pages/event-types/[type].tsx | 50 +++++++++++++++++++ pages/team/[slug]/[type].tsx | 1 + .../migration.sql | 2 + prisma/schema.prisma | 1 + public/static/locales/en/common.json | 4 +- public/static/locales/nl/common.json | 4 +- 12 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 prisma/migrations/20211217215952_added_slot_interval_to_event_type/migration.sql diff --git a/components/booking/AvailableTimes.tsx b/components/booking/AvailableTimes.tsx index 99c7e7c3..e1e5ae91 100644 --- a/components/booking/AvailableTimes.tsx +++ b/components/booking/AvailableTimes.tsx @@ -16,6 +16,7 @@ type AvailableTimesProps = { minimumBookingNotice: number; eventTypeId: number; eventLength: number; + slotInterval: number | null; date: Dayjs; users: { username: string | null; @@ -27,6 +28,7 @@ const AvailableTimes: FC = ({ date, eventLength, eventTypeId, + slotInterval, minimumBookingNotice, timeFormat, users, @@ -38,6 +40,7 @@ const AvailableTimes: FC = ({ const { slots, loading, error } = useSlots({ date, + slotInterval, eventLength, schedulingType, users, diff --git a/components/booking/pages/AvailabilityPage.tsx b/components/booking/pages/AvailabilityPage.tsx index 5500710f..21041c22 100644 --- a/components/booking/pages/AvailabilityPage.tsx +++ b/components/booking/pages/AvailabilityPage.tsx @@ -220,6 +220,7 @@ const AvailabilityPage = ({ profile, eventType, workingHours }: Props) => { timeFormat={timeFormat} minimumBookingNotice={eventType.minimumBookingNotice} eventTypeId={eventType.id} + slotInterval={eventType.slotInterval} eventLength={eventType.length} date={selectedDate} users={eventType.users} diff --git a/lib/hooks/useSlots.ts b/lib/hooks/useSlots.ts index 1f173900..196651f5 100644 --- a/lib/hooks/useSlots.ts +++ b/lib/hooks/useSlots.ts @@ -23,6 +23,7 @@ type Slot = { }; type UseSlotsProps = { + slotInterval: number | null; eventLength: number; eventTypeId: number; minimumBookingNotice?: number; @@ -32,7 +33,7 @@ type UseSlotsProps = { }; export const useSlots = (props: UseSlotsProps) => { - const { eventLength, minimumBookingNotice = 0, date, users, eventTypeId } = props; + const { slotInterval, eventLength, minimumBookingNotice = 0, date, users, eventTypeId } = props; const [slots, setSlots] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); @@ -102,7 +103,7 @@ export const useSlots = (props: UseSlotsProps) => { const handleAvailableSlots = async (res: Response) => { const responseBody: AvailabilityUserResponse = await res.json(); const times = getSlots({ - frequency: eventLength, + frequency: slotInterval || eventLength, inviteeDate: date, workingHours: responseBody.workingHours, minimumBookingNotice, diff --git a/lib/types/event-type.ts b/lib/types/event-type.ts index b352a1e3..69f9dd86 100644 --- a/lib/types/event-type.ts +++ b/lib/types/event-type.ts @@ -12,6 +12,7 @@ export type AdvancedOptions = { requiresConfirmation?: boolean; disableGuests?: boolean; minimumBookingNotice?: number; + slotInterval?: number | null; price?: number; currency?: string; schedulingType?: SchedulingType; diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index a5d65b6b..6702d1e2 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -44,6 +44,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) => schedulingType: true, minimumBookingNotice: true, timeZone: true, + slotInterval: true, users: { select: { avatar: true, diff --git a/pages/api/availability/eventtype.ts b/pages/api/availability/eventtype.ts index a17e8319..c01dbb63 100644 --- a/pages/api/availability/eventtype.ts +++ b/pages/api/availability/eventtype.ts @@ -132,6 +132,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) req.body.minimumBookingNotice || req.body.minimumBookingNotice === 0 ? parseInt(req.body.minimumBookingNotice, 10) : undefined, + slotInterval: req.body.slotInterval, price: req.body.price, currency: req.body.currency, }; diff --git a/pages/event-types/[type].tsx b/pages/event-types/[type].tsx index cd7c8344..8c435391 100644 --- a/pages/event-types/[type].tsx +++ b/pages/event-types/[type].tsx @@ -275,6 +275,7 @@ const EventTypePage = (props: inferSSRProps) => { periodDaysType: string; periodDates: { startDate: Date; endDate: Date }; minimumBookingNotice: number; + slotInterval: number | null; }>({ defaultValues: { locations: eventType.locations || [], @@ -512,6 +513,7 @@ const EventTypePage = (props: inferSSRProps) => { advancedPayload.periodStartDate = values.periodDates.startDate || undefined; advancedPayload.periodEndDate = values.periodDates.endDate || undefined; advancedPayload.minimumBookingNotice = values.minimumBookingNotice; + advancedPayload.slotInterval = values.slotInterval; // prettier-ignore advancedPayload.price = !requirePayment ? undefined : @@ -849,6 +851,53 @@ const EventTypePage = (props: inferSSRProps) => { )} /> +
+
+ +
+
+
+ { + const slotIntervalOptions = [ + { + label: t("slot_interval_default"), + value: -1, + }, + ...[5, 10, 15, 20, 30, 45, 60].map((minutes) => ({ + label: minutes + " " + t("minutes"), + value: minutes, + })), + ]; + return ( +