diff --git a/media_commons_booking_app/src/client/routes/admin/components/BookingActions.tsx b/media_commons_booking_app/src/client/routes/admin/components/BookingActions.tsx index bd9acaf9..b1e682f0 100644 --- a/media_commons_booking_app/src/client/routes/admin/components/BookingActions.tsx +++ b/media_commons_booking_app/src/client/routes/admin/components/BookingActions.tsx @@ -1,10 +1,10 @@ -import { Booking, BookingStatusLabel } from '../../../../types'; import React, { useContext, useMemo, useState } from 'react'; +import { BookingStatusLabel } from '../../../../types'; import { DatabaseContext } from '../../components/Provider'; import Loading from '../../../utils/Loading'; import { serverFunctions } from '../../../utils/serverFunctions'; -import useBookingStatus from '../hooks/getBookingStatus'; +import { useLocation } from 'react-router'; interface Props { calendarEventId: string; @@ -15,6 +15,9 @@ export default function BookingActions({ status, calendarEventId }: Props) { const [loading, setLoading] = useState(false); const { reloadBookings, reloadBookingStatuses } = useContext(DatabaseContext); + const location = useLocation(); + const isAdminPage = useMemo(() => location.pathname === '/admin', [location]); + const reload = async () => { await Promise.all([reloadBookings(), reloadBookingStatuses()]); }; @@ -33,9 +36,6 @@ export default function BookingActions({ status, calendarEventId }: Props) { } finally { setLoading(false); } - // await action(); - // await reload(); - // setLoading(false); }} > {text} @@ -43,25 +43,47 @@ export default function BookingActions({ status, calendarEventId }: Props) { ); if (loading) { - return ; + return ( + + + + ); } - return ( + const paBtns = ( <> - {status === BookingStatusLabel.PRE_APPROVED && - ActionButton('Second Approve', () => - serverFunctions.approveBooking(calendarEventId) - )} - {status === BookingStatusLabel.REQUESTED && - ActionButton('First Approve', () => - serverFunctions.approveBooking(calendarEventId) - )} - {ActionButton('Reject', () => serverFunctions.reject(calendarEventId))} - {ActionButton('Cancel', () => serverFunctions.cancel(calendarEventId))} {status !== BookingStatusLabel.CHECKED_IN && ActionButton('Check In', () => serverFunctions.checkin(calendarEventId) )} + {status !== BookingStatusLabel.NO_SHOW && + ActionButton('No Show', () => serverFunctions.noShow(calendarEventId))} ); + + if (!isAdminPage) { + return ( + +
{paBtns}
+ + ); + } + + return ( + +
+ {status === BookingStatusLabel.PRE_APPROVED && + ActionButton('2nd Approve', () => + serverFunctions.approveBooking(calendarEventId) + )} + {status === BookingStatusLabel.REQUESTED && + ActionButton('1st Approve', () => + serverFunctions.approveBooking(calendarEventId) + )} + {ActionButton('Reject', () => serverFunctions.reject(calendarEventId))} + {ActionButton('Cancel', () => serverFunctions.cancel(calendarEventId))} + {paBtns} +
+ + ); } diff --git a/media_commons_booking_app/src/client/routes/admin/components/Bookings.tsx b/media_commons_booking_app/src/client/routes/admin/components/Bookings.tsx index c06799fb..e7e3e8e9 100644 --- a/media_commons_booking_app/src/client/routes/admin/components/Bookings.tsx +++ b/media_commons_booking_app/src/client/routes/admin/components/Bookings.tsx @@ -66,17 +66,12 @@ export const Bookings: React.FC = ({ {filteredBookings.map((booking, index) => { const status = getBookingStatus(booking, bookingStatuses); return ( - + {!isUserView && ( - - - + )} {status} {booking.roomId} diff --git a/media_commons_booking_app/src/client/routes/admin/hooks/getBookingStatus.ts b/media_commons_booking_app/src/client/routes/admin/hooks/getBookingStatus.ts index 69a9e24c..02c53adf 100644 --- a/media_commons_booking_app/src/client/routes/admin/hooks/getBookingStatus.ts +++ b/media_commons_booking_app/src/client/routes/admin/hooks/getBookingStatus.ts @@ -11,6 +11,8 @@ export default function getBookingStatus( if (bookingStatusMatch === undefined) return BookingStatusLabel.UNKNOWN; if (bookingStatusMatch.checkedInAt !== '') { return BookingStatusLabel.CHECKED_IN; + } else if (bookingStatusMatch.noShowedAt !== '') { + return BookingStatusLabel.NO_SHOW; } else if (bookingStatusMatch.canceledAt !== '') { return BookingStatusLabel.CANCELED; } else if (bookingStatusMatch.rejectedAt !== '') { diff --git a/media_commons_booking_app/src/policy.ts b/media_commons_booking_app/src/policy.ts index 73cb41a2..e00c26e3 100644 --- a/media_commons_booking_app/src/policy.ts +++ b/media_commons_booking_app/src/policy.ts @@ -39,7 +39,7 @@ export enum ActiveSheetBookingStatusColumns { REJECTED_DATE = 5, CANCELLED_DATE = 6, CHECKED_IN_DATE = 7, - STATUS = 8, + NO_SHOWED_DATE = 8, } export enum ActiveSheetRoomsColumns { diff --git a/media_commons_booking_app/src/server/admin.ts b/media_commons_booking_app/src/server/admin.ts index d16eb5ce..26780b94 100644 --- a/media_commons_booking_app/src/server/admin.ts +++ b/media_commons_booking_app/src/server/admin.ts @@ -168,6 +168,29 @@ export const checkin = (id: string) => { updateEventPrefix(id, BookingStatusLabel.CHECKED_IN); }; +export const noShow = (id: string) => { + updateActiveSheetValueById( + TableNames.BOOKING_STATUS, + id, + ActiveSheetBookingStatusColumns.NO_SHOWED_DATE, + new Date() + ); + const guestEmail = getActiveSheetValueById( + TableNames.BOOKING_STATUS, + id, + ActiveSheetBookingStatusColumns.EMAIL + ); + const eventTitle = getActiveSheetValueById(TableNames.BOOKING, id, 16); + + sendTextEmail( + guestEmail, + BookingStatusLabel.NO_SHOW, + eventTitle, + 'You did not check-in for your Media Commons Reservation and have been marked as a no-show.' + ); + updateEventPrefix(id, BookingStatusLabel.NO_SHOW); +}; + // assumes the email is in column 0 but that can be overridden export const removeFromListByEmail = ( sheetName: TableNames, diff --git a/media_commons_booking_app/src/server/index.ts b/media_commons_booking_app/src/server/index.ts index 73f6a413..9ca89610 100644 --- a/media_commons_booking_app/src/server/index.ts +++ b/media_commons_booking_app/src/server/index.ts @@ -22,6 +22,7 @@ import { approveInstantBooking, cancel, checkin, + noShow, reject, removeFromListByEmail, } from './admin'; @@ -58,6 +59,7 @@ export { reject, cancel, checkin, + noShow, approveInstantBooking, removeFromListByEmail, }; diff --git a/media_commons_booking_app/src/types.ts b/media_commons_booking_app/src/types.ts index 8c1f8a16..2b4c7589 100644 --- a/media_commons_booking_app/src/types.ts +++ b/media_commons_booking_app/src/types.ts @@ -26,6 +26,7 @@ export type BookingStatus = { rejectedAt: string; canceledAt: string; checkedInAt: string; + noShowedAt: string; }; export enum BookingStatusLabel {