Booking confirm endpoint refactoring (#2949)
* Adds new default handler and responder * Moved confirm endpoint * Fixes availability for unconfirmed bookings * Cleanup * Update _patch.ts * Prevent too much diffs * Adds missing BookingStatus * Migrates confirmed & rejected to status * Adds requiresConfirmation icon to listing * Adds booking status migration * Adds migrations to remove confirmed/rejected * Undo refactor * Sets the organizer as "accepted" in gCal * Update getBusyTimes.ts Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
parent
3b321e5d3c
commit
12d66cb9df
@@ -87,6 +87,9 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
);
|
||||
const isUpcoming = new Date(booking.endTime) >= new Date();
|
||||
const isCancelled = booking.status === BookingStatus.CANCELLED;
|
||||
const isConfirmed = booking.status === BookingStatus.ACCEPTED;
|
||||
const isRejected = booking.status === BookingStatus.REJECTED;
|
||||
const isPending = booking.status === BookingStatus.PENDING;
|
||||
|
||||
const pendingActions: ActionType[] = [
|
||||
{
|
||||
@@ -205,7 +208,7 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
if (location.includes("integration")) {
|
||||
if (booking.status === BookingStatus.CANCELLED || booking.status === BookingStatus.REJECTED) {
|
||||
location = t("web_conference");
|
||||
} else if (booking.confirmed) {
|
||||
} else if (isConfirmed) {
|
||||
location = linkValueToString(booking.location, t);
|
||||
} else {
|
||||
location = t("web_conferencing_details_to_follow");
|
||||
@@ -227,7 +230,7 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
eventName: booking.eventType.eventName || "",
|
||||
bookingId: booking.id,
|
||||
recur: booking.recurringEventId,
|
||||
reschedule: booking.confirmed,
|
||||
reschedule: isConfirmed,
|
||||
listingStatus: booking.listingStatus,
|
||||
status: booking.status,
|
||||
},
|
||||
@@ -322,14 +325,10 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
className={"flex-1 ltr:pl-4 rtl:pr-4" + (booking.rejected ? " line-through" : "")}
|
||||
onClick={onClick}>
|
||||
<td className={"flex-1 ltr:pl-4 rtl:pr-4" + (isRejected ? " line-through" : "")} onClick={onClick}>
|
||||
<div className="cursor-pointer py-4">
|
||||
<div className="sm:hidden">
|
||||
{!booking.confirmed && !booking.rejected && (
|
||||
<Tag className="mb-2 ltr:mr-2 rtl:ml-2">{t("unconfirmed")}</Tag>
|
||||
)}
|
||||
{isPending && <Tag className="mb-2 ltr:mr-2 rtl:ml-2">{t("unconfirmed")}</Tag>}
|
||||
{!!booking?.eventType?.price && !booking.paid && (
|
||||
<Tag className="mb-2 ltr:mr-2 rtl:ml-2">Pending payment</Tag>
|
||||
)}
|
||||
@@ -351,9 +350,7 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
{!!booking?.eventType?.price && !booking.paid && (
|
||||
<Tag className="hidden ltr:ml-2 rtl:mr-2 sm:inline-flex">Pending payment</Tag>
|
||||
)}
|
||||
{!booking.confirmed && !booking.rejected && (
|
||||
<Tag className="hidden ltr:ml-2 rtl:mr-2 sm:inline-flex">{t("unconfirmed")}</Tag>
|
||||
)}
|
||||
{isPending && <Tag className="hidden ltr:ml-2 rtl:mr-2 sm:inline-flex">{t("unconfirmed")}</Tag>}
|
||||
</div>
|
||||
{booking.description && (
|
||||
<div
|
||||
@@ -382,13 +379,9 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
<td className="whitespace-nowrap py-4 text-right text-sm font-medium ltr:pr-4 rtl:pl-4">
|
||||
{isUpcoming && !isCancelled ? (
|
||||
<>
|
||||
{!booking.confirmed && !booking.rejected && user!.id === booking.user!.id && (
|
||||
<TableActions actions={pendingActions} />
|
||||
)}
|
||||
{booking.confirmed && !booking.rejected && <TableActions actions={bookedActions} />}
|
||||
{!booking.confirmed && booking.rejected && (
|
||||
<div className="text-sm text-gray-500">{t("rejected")}</div>
|
||||
)}
|
||||
{isPending && user?.id === booking.user?.id && <TableActions actions={pendingActions} />}
|
||||
{isConfirmed && <TableActions actions={bookedActions} />}
|
||||
{isRejected && <div className="text-sm text-gray-500">{t("rejected")}</div>}
|
||||
</>
|
||||
) : null}
|
||||
{isCancelled && booking.rescheduled && (
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
import { ClockIcon, CreditCardIcon, RefreshIcon, UserIcon, UsersIcon } from "@heroicons/react/solid";
|
||||
import { SchedulingType } from "@prisma/client";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import React, { useMemo } from "react";
|
||||
import {
|
||||
ClipboardCheckIcon,
|
||||
ClockIcon,
|
||||
CreditCardIcon,
|
||||
RefreshIcon,
|
||||
UserIcon,
|
||||
UsersIcon,
|
||||
} from "@heroicons/react/solid";
|
||||
import { Prisma, SchedulingType } from "@prisma/client";
|
||||
import { useMemo } from "react";
|
||||
import { FormattedNumber, IntlProvider } from "react-intl";
|
||||
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { baseEventTypeSelect } from "@calcom/prisma/selects";
|
||||
import { RecurringEvent } from "@calcom/types/Calendar";
|
||||
|
||||
import classNames from "@lib/classNames";
|
||||
|
||||
const eventTypeData = Prisma.validator<Prisma.EventTypeArgs>()({
|
||||
select: {
|
||||
id: true,
|
||||
length: true,
|
||||
price: true,
|
||||
currency: true,
|
||||
schedulingType: true,
|
||||
recurringEvent: true,
|
||||
description: true,
|
||||
},
|
||||
select: baseEventTypeSelect,
|
||||
});
|
||||
|
||||
type EventType = Prisma.EventTypeGetPayload<typeof eventTypeData>;
|
||||
@@ -83,6 +82,12 @@ export const EventTypeDescription = ({ eventType, className }: EventTypeDescript
|
||||
</IntlProvider>
|
||||
</li>
|
||||
)}
|
||||
{eventType.requiresConfirmation && (
|
||||
<li className="mr-4 flex items-center whitespace-nowrap">
|
||||
<ClipboardCheckIcon className="mr-1.5 inline h-4 w-4 text-neutral-400" aria-hidden="true" />
|
||||
Opt-in
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user