import { NextApiRequest, NextApiResponse } from 'next' import { Booking } from '../../../../db/booking' import { BOOKING_STATUS } from '../../../../db/enums' import { patchBooking } from '../../../../db/index' import { sendBookingConfirmed, sendBookingRejected, sendBookingCanceled, } from '../../../../helpers/mail' import { log } from '../../../../helpers/log' function changedStatus( previous: Booking, current: Partial, status: BOOKING_STATUS ): boolean { return ( [BOOKING_STATUS.REQUESTED].includes(previous.status) && current.status === status ) } function wasRejected(previous: Booking, current: Partial): boolean { return changedStatus(previous, current, BOOKING_STATUS.REJECTED) } function wasConfirmed(previous: Booking, current: Partial): boolean { return changedStatus(previous, current, BOOKING_STATUS.CONFIRMED) } function wasCanceled(previous: Booking, current: Partial): boolean { return ( [BOOKING_STATUS.REQUESTED, BOOKING_STATUS.CONFIRMED].includes( previous.status ) && current.status === BOOKING_STATUS.CANCELED ) } export default async function userHandler( req: NextApiRequest, res: NextApiResponse ): Promise { const { method, query: { uuid: uuids }, } = req const uuid = Array.isArray(uuids) ? uuids[0] : uuids switch (method) { case 'PATCH': if (!Object.values(BOOKING_STATUS).includes(req.body.status)) { res .status(400) .end( `The attribute status can only be: ${Object.values( BOOKING_STATUS ).join(', ')}` ) break } try { const { current, previous } = await patchBooking(uuid, req.body) // TODO: this should really go into the schema if (wasRejected(previous, current)) { sendBookingRejected(current) } else if (wasConfirmed(previous, current)) { sendBookingConfirmed(current) } else if (wasCanceled(previous, current)) { sendBookingCanceled(current) } res.status(200).json(current) } catch (error) { log.error('failed patch booking', error) res.status(400).end(`Failed to save booking: ${error.message}`) } break default: res.setHeader('Allow', ['PATCH']) res.status(405).end(`Method ${method} Not Allowed`) } }