Skip to content

Commit e9f3248

Browse files
emrysalPeerRichkodiakhq[bot]zomars
authored
Feature/booking page refactor (#3035)
* Extracted UI related logic on the DatePicker, stripped out all logic * wip * fixed small regression due to merge * Fix alignment of the chevrons * Added isToday dot, added onMonthChange so we can fetch this month slots * Added includedDates to inverse excludedDates * removed trpcState * Improvements to the state * All params are now dynamic * This builds the flat map so not all paths block on every new build * Added requiresConfirmation * Correctly take into account getFilteredTimes to make the calendar function * Rewritten team availability, seems to work * Circumvent i18n flicker by showing the loader instead * 'You can remove this code. Its not being used now' - Hariom * Nailed a persistent little bug, new Date() caused the current day to flicker on and off * TS fixes * Fix some eventType details in AvailableTimes * '5 / 6 Seats Available' instead of '6 / Seats Available' * More type fixes * Removed unrelated merge artifact * Use WEBAPP_URL instead of hardcoded * Next round of TS fixes * I believe this was mistyped * Temporarily disabled rescheduling 'this is when you originally scheduled', so removed dep * Sorting some dead code * This page has a lot of red, not all related to this PR * A PR to your PR (#3067) * Cleanup * Cleanup * Uses zod to parse params * Type fixes * Fixes ISR * E2E fixes * Disabled dynamic bookings until post v1.7 * More test fixes * Fixed border position (transparent border) to prevent dot from jumping - and possibly fix spacing * Disabled style nitpicks * Delete useSlots.ts Removed early design artifact * Unlock DatePicker locale * Adds mini spinner to DatePicker Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
1 parent 6959eb2 commit e9f3248

File tree

21 files changed

+1044
-565
lines changed

21 files changed

+1044
-565
lines changed

apps/web/components/booking/AvailableTimes.tsx

+11-49
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,44 @@
1-
import { ExclamationIcon } from "@heroicons/react/solid";
21
import { SchedulingType } from "@prisma/client";
32
import dayjs, { Dayjs } from "dayjs";
43
import Link from "next/link";
54
import { useRouter } from "next/router";
6-
import React, { FC, useEffect, useState } from "react";
5+
import { FC, useEffect, useState } from "react";
76

7+
import { useLocale } from "@calcom/lib/hooks/useLocale";
88
import { nameOfDay } from "@calcom/lib/weekday";
99

1010
import classNames from "@lib/classNames";
1111
import { timeZone } from "@lib/clock";
12-
import { useLocale } from "@lib/hooks/useLocale";
13-
import { useSlots } from "@lib/hooks/useSlots";
1412

15-
import Loader from "@components/Loader";
13+
import type { Slot } from "@server/routers/viewer/slots";
1614

1715
type AvailableTimesProps = {
1816
timeFormat: string;
19-
minimumBookingNotice: number;
20-
beforeBufferTime: number;
21-
afterBufferTime: number;
2217
eventTypeId: number;
23-
eventLength: number;
2418
recurringCount: number | undefined;
2519
eventTypeSlug: string;
26-
slotInterval: number | null;
2720
date: Dayjs;
2821
users: {
2922
username: string | null;
3023
}[];
3124
schedulingType: SchedulingType | null;
3225
seatsPerTimeSlot?: number | null;
26+
slots?: Slot[];
3327
};
3428

3529
const AvailableTimes: FC<AvailableTimesProps> = ({
30+
slots = [],
3631
date,
37-
eventLength,
3832
eventTypeId,
3933
eventTypeSlug,
40-
slotInterval,
41-
minimumBookingNotice,
4234
recurringCount,
4335
timeFormat,
44-
users,
4536
schedulingType,
46-
beforeBufferTime,
47-
afterBufferTime,
4837
seatsPerTimeSlot,
4938
}) => {
5039
const { t, i18n } = useLocale();
5140
const router = useRouter();
5241
const { rescheduleUid } = router.query;
53-
const { slots, loading, error } = useSlots({
54-
date,
55-
slotInterval,
56-
eventLength,
57-
schedulingType,
58-
users,
59-
minimumBookingNotice,
60-
beforeBufferTime,
61-
afterBufferTime,
62-
eventTypeId,
63-
});
6442

6543
const [brand, setBrand] = useState("#292929");
6644

@@ -80,8 +58,7 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
8058
</span>
8159
</div>
8260
<div className="flex-grow overflow-y-auto md:h-[364px]">
83-
{!loading &&
84-
slots?.length > 0 &&
61+
{slots?.length > 0 &&
8562
slots.map((slot) => {
8663
type BookingURL = {
8764
pathname: string;
@@ -91,7 +68,7 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
9168
pathname: "book",
9269
query: {
9370
...router.query,
94-
date: slot.time.format(),
71+
date: dayjs(slot.time).format(),
9572
type: eventTypeId,
9673
slug: eventTypeSlug,
9774
/** Treat as recurring only when a count exist and it's not a rescheduling workflow */
@@ -113,15 +90,15 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
11390
}
11491

11592
return (
116-
<div key={slot.time.format()}>
93+
<div key={dayjs(slot.time).format()}>
11794
{/* Current there is no way to disable Next.js Links */}
11895
{seatsPerTimeSlot && slot.attendees && slot.attendees >= seatsPerTimeSlot ? (
11996
<div
12097
className={classNames(
12198
"text-primary-500 mb-2 block rounded-sm border bg-white py-4 font-medium opacity-25 dark:border-transparent dark:bg-gray-600 dark:text-neutral-200 ",
12299
brand === "#fff" || brand === "#ffffff" ? "border-brandcontrast" : "border-brand"
123100
)}>
124-
{slot.time.format(timeFormat)}
101+
{dayjs(slot.time).tz(timeZone()).format(timeFormat)}
125102
{!!seatsPerTimeSlot && <p className={`text-sm`}>{t("booking_full")}</p>}
126103
</div>
127104
) : (
@@ -132,7 +109,7 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
132109
brand === "#fff" || brand === "#ffffff" ? "border-brandcontrast" : "border-brand"
133110
)}
134111
data-testid="time">
135-
{dayjs.tz(slot.time, timeZone()).format(timeFormat)}
112+
{dayjs(slot.time).tz(timeZone()).format(timeFormat)}
136113
{!!seatsPerTimeSlot && (
137114
<p
138115
className={`${
@@ -152,26 +129,11 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
152129
</div>
153130
);
154131
})}
155-
{!loading && !error && !slots.length && (
132+
{!slots.length && (
156133
<div className="-mt-4 flex h-full w-full flex-col content-center items-center justify-center">
157134
<h1 className="my-6 text-xl text-black dark:text-white">{t("all_booked_today")}</h1>
158135
</div>
159136
)}
160-
161-
{loading && <Loader />}
162-
163-
{error && (
164-
<div className="border-l-4 border-yellow-400 bg-yellow-50 p-4">
165-
<div className="flex">
166-
<div className="flex-shrink-0">
167-
<ExclamationIcon className="h-5 w-5 text-yellow-400" aria-hidden="true" />
168-
</div>
169-
<div className="ltr:ml-3 rtl:mr-3">
170-
<p className="text-sm text-yellow-700">{t("slots_load_fail")}</p>
171-
</div>
172-
</div>
173-
</div>
174-
)}
175137
</div>
176138
</div>
177139
);

apps/web/components/booking/DatePicker.tsx

+2-8
Original file line numberDiff line numberDiff line change
@@ -249,15 +249,9 @@ function DatePicker({
249249
day.disabled ? { ...disabledDateButtonEmbedStyles } : { ...enabledDateButtonEmbedStyles }
250250
}
251251
className={classNames(
252-
"absolute top-0 left-0 right-0 bottom-0 mx-auto w-full rounded-sm text-center",
253-
"hover:border-brand hover:border dark:hover:border-white",
254-
day.disabled
255-
? "text-bookinglighter cursor-default font-light hover:border-0"
256-
: "font-medium",
252+
"hover:border-brand disabled:text-bookinglighter absolute top-0 left-0 right-0 bottom-0 mx-auto w-full rounded-sm text-center font-medium hover:border disabled:cursor-default disabled:font-light disabled:hover:border-0 dark:hover:border-white",
257253
date && date.isSame(browsingDate.date(day.date), "day")
258-
? "bg-brand text-brandcontrast dark:bg-darkmodebrand dark:text-darkmodebrandcontrast"
259-
: !day.disabled
260-
? " bg-gray-100 dark:bg-gray-600 dark:text-white"
254+
? "bg-brand text-brandcontrast dark:bg-darkmodebrand dark:text-darkmodebrandcontrast disabled:bg-gray-100 disabled:dark:bg-gray-600 disabled:dark:text-white"
261255
: ""
262256
)}
263257
data-testid="day"

0 commit comments

Comments
 (0)