// TODO: replace headlessui with radix-ui import { Menu, Transition } from "@headlessui/react"; import { BanIcon, CalendarIcon, CheckIcon, ClockIcon, XIcon } from "@heroicons/react/outline"; import { DotsHorizontalIcon } from "@heroicons/react/solid"; import { BookingStatus } from "@prisma/client"; import dayjs from "dayjs"; import { Fragment } from "react"; import { useMutation } from "react-query"; import classNames from "@lib/classNames"; import { HttpError } from "@lib/core/http/error"; import { inferQueryOutput, trpc } from "@lib/trpc"; import EmptyScreen from "@components/EmptyScreen"; import Loader from "@components/Loader"; import Shell from "@components/Shell"; import { Alert } from "@components/ui/Alert"; import { Button } from "@components/ui/Button"; type BookingItem = inferQueryOutput<"viewer.bookings">[number]; function BookingListItem(booking: BookingItem) { const utils = trpc.useContext(); const mutation = useMutation( async (confirm: boolean) => { const res = await fetch("/api/book/confirm", { method: "PATCH", body: JSON.stringify({ id: booking.id, confirmed: confirm }), headers: { "Content-Type": "application/json", }, }); if (!res.ok) { throw new HttpError({ statusCode: res.status }); } }, { async onSettled() { await utils.invalidateQuery(["viewer.bookings"]); }, } ); return ( {!booking.confirmed && !booking.rejected && ( Unconfirmed )}
{booking.eventType?.team && {booking.eventType.team.name}: } {booking.title}
{dayjs(booking.startTime).format("D MMMM YYYY")}:{" "} {dayjs(booking.startTime).format("HH:mm")} - {dayjs(booking.endTime).format("HH:mm")}
{booking.attendees.length !== 0 && (
{booking.attendees[0].email}
)}
{dayjs(booking.startTime).format("D MMMM YYYY")}
{dayjs(booking.startTime).format("HH:mm")} - {dayjs(booking.endTime).format("HH:mm")}
{!booking.confirmed && !booking.rejected && ( <>
{({ open }) => ( <>
Open options
{({ active }) => ( mutation.mutate(true)} className={classNames( active ? "bg-neutral-100 text-neutral-900" : "text-neutral-700", "group flex items-center px-4 py-2 text-sm font-medium" )}> )} {({ active }) => ( mutation.mutate(false)} className={classNames( active ? "bg-neutral-100 text-neutral-900" : "text-neutral-700", "group flex items-center px-4 py-2 text-sm w-full font-medium" )}> )}
)}
)} {booking.confirmed && !booking.rejected && ( <>
{({ open }) => ( <>
Open options
{({ active }) => ( )} {({ active }) => ( )}
)}
)} {!booking.confirmed && booking.rejected &&
Rejected
} ); } export default function Bookings() { const query = trpc.useQuery(["viewer.bookings"]); const bookings = query.data; return (
{query.status === "error" && ( )} {query.status === "loading" && } {bookings && (bookings.length === 0 ? ( ) : (
{bookings .filter((booking) => booking.status !== BookingStatus.CANCELLED) .map((booking) => ( ))}
))}
); }