Fixing unconfirmed/recurring bookings#4881
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
| type BookingItemProps = BookingItem & { | ||
| listingStatus: BookingListingStatus; | ||
| recurringBookings?: BookingItem[]; | ||
| recurringBookings: inferQueryOutput<"viewer.bookings">["recurringInfo"]; |
There was a problem hiding this comment.
Now relying on the returned information from tRPC viewer.bookings
| const isPending = booking.status === BookingStatus.PENDING; | ||
| const isRecurring = booking.recurringEventId !== null; | ||
| const isTabRecurring = booking.listingStatus === "recurring"; | ||
| const isTabUnconfirmed = booking.listingStatus === "unconfirmed"; |
There was a problem hiding this comment.
Simplifying a bunch of conditions throughout this file
| <Tooltip | ||
| content={recurringStrings.map((aDate, key) => ( | ||
| <p key={key}>{aDate}</p> | ||
| <p key={key} className={classNames(recurringDates[key] < now && "line-through")}> |
| recurringCount: booking.recurringBookings.length, | ||
| recurringCount: recurringDates.filter((date) => { | ||
| return date >= now; | ||
| }).length, |
| }).all(); | ||
| const dateStrings = allDates.map((r) => { | ||
| return processDate(dayjs(r).tz(timeZone), i18n); | ||
| }); |
There was a problem hiding this comment.
This implementation does not require the list of bookings anymore, which was flickering along the infinite scroll loaded more results. It calculates all the instances based on the new introduced recurring information coming from tRPC viewer.bookings which comes with actual count of recurring events selected by user (a.k.a. recurring count) and the date of the first instance of the recurring booking
| key={booking.id} | ||
| listingStatus={status} | ||
| {...defineRecurrentBookings(booking, shownBookings)} | ||
| recurringBookings={page.recurringInfo} |
There was a problem hiding this comment.
Repeating last comment: Not relying on a list of bookings anymore, which was flickering along the infinite scroll loaded more results. It calculates all the instances based on the new introduced recurring information coming from tRPC viewer.bookings which comes with actual count of recurring events selected by user (a.k.a. recurring count) and the date of the first instance of the recurring booking
| const shownBookings: Record<string, BookingOutput[]> = {}; | ||
| const filterBookings = (booking: BookingOutput) => { | ||
| if (status === "recurring" || status === "cancelled") { | ||
| if (status === "recurring" || status == "unconfirmed" || status === "cancelled") { |
There was a problem hiding this comment.
Unconfirmed tab needs to behave the same as recurring and cancelled when it comes to grouping recurring instances
| startTime: dayjs().add(1, "day").toDate(), | ||
| endTime: dayjs().add(1, "day").add(30, "minutes").toDate(), | ||
| status: BookingStatus.PENDING, | ||
| status: BookingStatus.ACCEPTED, |
There was a problem hiding this comment.
Yoga class does not require confirmation, so changing its status to ACCEPTED to be aligned to that.
| { | ||
| status: { equals: BookingStatus.PENDING }, | ||
| }, | ||
| ], |
There was a problem hiding this comment.
Behavior similar to the upcoming status but taking into consideration just PENDING bookings.
| notIn: [BookingStatus.CANCELLED], | ||
| }, | ||
| }, | ||
| }); |
There was a problem hiding this comment.
This new prisma query comes up with the following useful information to populate recurring bookings explained in other related files.
[
{
"_min": {
"startTime": "2022-09-30T18:48:22.495Z"
},
"_count": {
"recurringEventId": 5
},
"recurringEventId": "dGVubmlzLWNsYXNz"
},
{
"_min": {
"startTime": "2022-09-29T18:48:22.491Z"
},
"_count": {
"recurringEventId": 6
},
"recurringEventId": "eW9nYS1jbGFzcw=="
},
{
"_min": {
"startTime": "2022-10-31T13:00:00.000Z"
},
"_count": {
"recurringEventId": 12
},
"recurringEventId": "341f50b8-7d71-4817-96b2-fe2144487d25"
}
]| seenBookings[booking.recurringEventId] = true; | ||
| return true; | ||
| }); | ||
| } |
There was a problem hiding this comment.
This code was grouping recurring events before grouping them in the UI, which was causing problems showing not-correlated recurring bookings.
| }); | ||
| } | ||
|
|
||
| const bookingsFetched = bookings.length; |
There was a problem hiding this comment.
Moved from above, not new
| (booking.listingStatus === "recurring" || | ||
| booking.listingStatus === "unconfirmed" || | ||
| booking.listingStatus === "cancelled") && ( |
There was a problem hiding this comment.
Should we use the conditions constants here?
There was a problem hiding this comment.
Different context as you surely noticed, and it was just used once there, so I found no need to create new constants.
| ): [string[], Date[]] => { | ||
| const dateStrings = bookings.map((booking) => processDate(dayjs(booking.startTime).tz(timeZone), i18n)); | ||
| const allDates = dateStrings.map((dateString) => dayjs(dateString).tz(timeZone).toDate()); | ||
| const { count = 0, ...rest } = |
There was a problem hiding this comment.
Is unused variable intentional?
There was a problem hiding this comment.
Yes, removing the count as we are not interested in it, I could have left it there and then let the redefinition overwrite it.
|
Suggested edit: diff --git a/packages/trpc/server/routers/viewer.tsx b/packages/trpc/server/routers/viewer.tsx
index 2eaf991fa..70f0bee39 100644
--- a/packages/trpc/server/routers/viewer.tsx
+++ b/packages/trpc/server/routers/viewer.tsx
@@ -495,12 +495,8 @@ const loggedInViewerRouter = createProtectedRouter()
endTime: { gte: new Date() },
OR: [
{
- AND: [
- { NOT: { recurringEventId: { equals: null } } },
- {
- status: { equals: BookingStatus.PENDING },
- },
- ],
+ recurringEventId: { not: null },
+ status: { equals: BookingStatus.PENDING },
},
{
status: { equals: BookingStatus.PENDING },
|
| { | ||
| AND: [ | ||
| { NOT: { recurringEventId: { equals: null } } }, | ||
| { | ||
| status: { equals: BookingStatus.PENDING }, | ||
| }, | ||
| ], | ||
| }, |
There was a problem hiding this comment.
| { | |
| AND: [ | |
| { NOT: { recurringEventId: { equals: null } } }, | |
| { | |
| status: { equals: BookingStatus.PENDING }, | |
| }, | |
| ], | |
| }, | |
| { | |
| recurringEventId: { not: null }, | |
| status: { equals: BookingStatus.PENDING }, | |
| }, |
We can simplify this



What does this PR do?
When looking at "Unconfirmed" tab in Bookings, and you have recurring events to be accepted, they were not grouped correctly. Also, the number of instances in the tooltip info section for recurring events was dependant on loaded bookings, hence infinite scrolling was affecting its content, flickering the number.
See the number flickering:
Screen.Recording.2022-10-06.at.10.42.10.mov
Also as part of the fix, a new little feature is shown, the number of recurring events is adjusted to show actually dates in the future in case any instance already passed, and the tooltip shows passed instances as striked:

And the ungrouped unconfirmed recurring events:

Fixed ungrouped unconfirmed recurring events with better tooltip content:

Environment: Staging(main branch) / Production
Type of change
How should this be tested?
Have at least 3 x12 unconfirmed recurring events and go to Unconfirmed tab or Recurring tab in Bookings page.