feat: add customer email functionality for booking confirmations

- Implemented email confirmation for admin and public bookings.
- Added customerEmail field to booking schemas and services.
- Created email templates for booking confirmation, cancellation, and no-show notifications.
- Updated booking handlers to send emails upon booking creation and status updates.
- Enhanced frontend forms to capture customer email during booking creation.
This commit is contained in:
Jose Selesan
2026-06-02 19:21:04 -03:00
parent 50fa4ed9a5
commit 85f234b05e
22 changed files with 610 additions and 1536 deletions

View File

@@ -33,6 +33,7 @@ export type CourtBookingMinAggregateOutputType = {
endTime: string | null
customerName: string | null
customerPhone: string | null
customerEmail: string | null
status: $Enums.CourtBookingStatus | null
createdAt: Date | null
updatedAt: Date | null
@@ -47,6 +48,7 @@ export type CourtBookingMaxAggregateOutputType = {
endTime: string | null
customerName: string | null
customerPhone: string | null
customerEmail: string | null
status: $Enums.CourtBookingStatus | null
createdAt: Date | null
updatedAt: Date | null
@@ -61,6 +63,7 @@ export type CourtBookingCountAggregateOutputType = {
endTime: number
customerName: number
customerPhone: number
customerEmail: number
status: number
createdAt: number
updatedAt: number
@@ -77,6 +80,7 @@ export type CourtBookingMinAggregateInputType = {
endTime?: true
customerName?: true
customerPhone?: true
customerEmail?: true
status?: true
createdAt?: true
updatedAt?: true
@@ -91,6 +95,7 @@ export type CourtBookingMaxAggregateInputType = {
endTime?: true
customerName?: true
customerPhone?: true
customerEmail?: true
status?: true
createdAt?: true
updatedAt?: true
@@ -105,6 +110,7 @@ export type CourtBookingCountAggregateInputType = {
endTime?: true
customerName?: true
customerPhone?: true
customerEmail?: true
status?: true
createdAt?: true
updatedAt?: true
@@ -192,6 +198,7 @@ export type CourtBookingGroupByOutputType = {
endTime: string
customerName: string
customerPhone: string
customerEmail: string | null
status: $Enums.CourtBookingStatus
createdAt: Date
updatedAt: Date
@@ -227,6 +234,7 @@ export type CourtBookingWhereInput = {
endTime?: Prisma.StringFilter<"CourtBooking"> | string
customerName?: Prisma.StringFilter<"CourtBooking"> | string
customerPhone?: Prisma.StringFilter<"CourtBooking"> | string
customerEmail?: Prisma.StringNullableFilter<"CourtBooking"> | string | null
status?: Prisma.EnumCourtBookingStatusFilter<"CourtBooking"> | $Enums.CourtBookingStatus
createdAt?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string
updatedAt?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string
@@ -242,6 +250,7 @@ export type CourtBookingOrderByWithRelationInput = {
endTime?: Prisma.SortOrder
customerName?: Prisma.SortOrder
customerPhone?: Prisma.SortOrder
customerEmail?: Prisma.SortOrderInput | Prisma.SortOrder
status?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
updatedAt?: Prisma.SortOrder
@@ -261,6 +270,7 @@ export type CourtBookingWhereUniqueInput = Prisma.AtLeast<{
endTime?: Prisma.StringFilter<"CourtBooking"> | string
customerName?: Prisma.StringFilter<"CourtBooking"> | string
customerPhone?: Prisma.StringFilter<"CourtBooking"> | string
customerEmail?: Prisma.StringNullableFilter<"CourtBooking"> | string | null
status?: Prisma.EnumCourtBookingStatusFilter<"CourtBooking"> | $Enums.CourtBookingStatus
createdAt?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string
updatedAt?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string
@@ -276,6 +286,7 @@ export type CourtBookingOrderByWithAggregationInput = {
endTime?: Prisma.SortOrder
customerName?: Prisma.SortOrder
customerPhone?: Prisma.SortOrder
customerEmail?: Prisma.SortOrderInput | Prisma.SortOrder
status?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
updatedAt?: Prisma.SortOrder
@@ -296,6 +307,7 @@ export type CourtBookingScalarWhereWithAggregatesInput = {
endTime?: Prisma.StringWithAggregatesFilter<"CourtBooking"> | string
customerName?: Prisma.StringWithAggregatesFilter<"CourtBooking"> | string
customerPhone?: Prisma.StringWithAggregatesFilter<"CourtBooking"> | string
customerEmail?: Prisma.StringNullableWithAggregatesFilter<"CourtBooking"> | string | null
status?: Prisma.EnumCourtBookingStatusWithAggregatesFilter<"CourtBooking"> | $Enums.CourtBookingStatus
createdAt?: Prisma.DateTimeWithAggregatesFilter<"CourtBooking"> | Date | string
updatedAt?: Prisma.DateTimeWithAggregatesFilter<"CourtBooking"> | Date | string
@@ -309,6 +321,7 @@ export type CourtBookingCreateInput = {
endTime: string
customerName: string
customerPhone: string
customerEmail?: string | null
status?: $Enums.CourtBookingStatus
createdAt?: Date | string
updatedAt?: Date | string
@@ -324,6 +337,7 @@ export type CourtBookingUncheckedCreateInput = {
endTime: string
customerName: string
customerPhone: string
customerEmail?: string | null
status?: $Enums.CourtBookingStatus
createdAt?: Date | string
updatedAt?: Date | string
@@ -337,6 +351,7 @@ export type CourtBookingUpdateInput = {
endTime?: Prisma.StringFieldUpdateOperationsInput | string
customerName?: Prisma.StringFieldUpdateOperationsInput | string
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
customerEmail?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
@@ -352,6 +367,7 @@ export type CourtBookingUncheckedUpdateInput = {
endTime?: Prisma.StringFieldUpdateOperationsInput | string
customerName?: Prisma.StringFieldUpdateOperationsInput | string
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
customerEmail?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
@@ -366,6 +382,7 @@ export type CourtBookingCreateManyInput = {
endTime: string
customerName: string
customerPhone: string
customerEmail?: string | null
status?: $Enums.CourtBookingStatus
createdAt?: Date | string
updatedAt?: Date | string
@@ -379,6 +396,7 @@ export type CourtBookingUpdateManyMutationInput = {
endTime?: Prisma.StringFieldUpdateOperationsInput | string
customerName?: Prisma.StringFieldUpdateOperationsInput | string
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
customerEmail?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
@@ -393,6 +411,7 @@ export type CourtBookingUncheckedUpdateManyInput = {
endTime?: Prisma.StringFieldUpdateOperationsInput | string
customerName?: Prisma.StringFieldUpdateOperationsInput | string
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
customerEmail?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
@@ -423,6 +442,7 @@ export type CourtBookingCountOrderByAggregateInput = {
endTime?: Prisma.SortOrder
customerName?: Prisma.SortOrder
customerPhone?: Prisma.SortOrder
customerEmail?: Prisma.SortOrder
status?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
updatedAt?: Prisma.SortOrder
@@ -437,6 +457,7 @@ export type CourtBookingMaxOrderByAggregateInput = {
endTime?: Prisma.SortOrder
customerName?: Prisma.SortOrder
customerPhone?: Prisma.SortOrder
customerEmail?: Prisma.SortOrder
status?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
updatedAt?: Prisma.SortOrder
@@ -451,6 +472,7 @@ export type CourtBookingMinOrderByAggregateInput = {
endTime?: Prisma.SortOrder
customerName?: Prisma.SortOrder
customerPhone?: Prisma.SortOrder
customerEmail?: Prisma.SortOrder
status?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
updatedAt?: Prisma.SortOrder
@@ -510,6 +532,7 @@ export type CourtBookingCreateWithoutCourtInput = {
endTime: string
customerName: string
customerPhone: string
customerEmail?: string | null
status?: $Enums.CourtBookingStatus
createdAt?: Date | string
updatedAt?: Date | string
@@ -523,6 +546,7 @@ export type CourtBookingUncheckedCreateWithoutCourtInput = {
endTime: string
customerName: string
customerPhone: string
customerEmail?: string | null
status?: $Enums.CourtBookingStatus
createdAt?: Date | string
updatedAt?: Date | string
@@ -566,6 +590,7 @@ export type CourtBookingScalarWhereInput = {
endTime?: Prisma.StringFilter<"CourtBooking"> | string
customerName?: Prisma.StringFilter<"CourtBooking"> | string
customerPhone?: Prisma.StringFilter<"CourtBooking"> | string
customerEmail?: Prisma.StringNullableFilter<"CourtBooking"> | string | null
status?: Prisma.EnumCourtBookingStatusFilter<"CourtBooking"> | $Enums.CourtBookingStatus
createdAt?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string
updatedAt?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string
@@ -579,6 +604,7 @@ export type CourtBookingCreateManyCourtInput = {
endTime: string
customerName: string
customerPhone: string
customerEmail?: string | null
status?: $Enums.CourtBookingStatus
createdAt?: Date | string
updatedAt?: Date | string
@@ -592,6 +618,7 @@ export type CourtBookingUpdateWithoutCourtInput = {
endTime?: Prisma.StringFieldUpdateOperationsInput | string
customerName?: Prisma.StringFieldUpdateOperationsInput | string
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
customerEmail?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
@@ -605,6 +632,7 @@ export type CourtBookingUncheckedUpdateWithoutCourtInput = {
endTime?: Prisma.StringFieldUpdateOperationsInput | string
customerName?: Prisma.StringFieldUpdateOperationsInput | string
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
customerEmail?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
@@ -618,6 +646,7 @@ export type CourtBookingUncheckedUpdateManyWithoutCourtInput = {
endTime?: Prisma.StringFieldUpdateOperationsInput | string
customerName?: Prisma.StringFieldUpdateOperationsInput | string
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
customerEmail?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
@@ -634,6 +663,7 @@ export type CourtBookingSelect<ExtArgs extends runtime.Types.Extensions.Internal
endTime?: boolean
customerName?: boolean
customerPhone?: boolean
customerEmail?: boolean
status?: boolean
createdAt?: boolean
updatedAt?: boolean
@@ -649,6 +679,7 @@ export type CourtBookingSelectCreateManyAndReturn<ExtArgs extends runtime.Types.
endTime?: boolean
customerName?: boolean
customerPhone?: boolean
customerEmail?: boolean
status?: boolean
createdAt?: boolean
updatedAt?: boolean
@@ -664,6 +695,7 @@ export type CourtBookingSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.
endTime?: boolean
customerName?: boolean
customerPhone?: boolean
customerEmail?: boolean
status?: boolean
createdAt?: boolean
updatedAt?: boolean
@@ -679,12 +711,13 @@ export type CourtBookingSelectScalar = {
endTime?: boolean
customerName?: boolean
customerPhone?: boolean
customerEmail?: boolean
status?: boolean
createdAt?: boolean
updatedAt?: boolean
}
export type CourtBookingOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "bookingCode" | "courtId" | "bookingDate" | "startTime" | "endTime" | "customerName" | "customerPhone" | "status" | "createdAt" | "updatedAt", ExtArgs["result"]["courtBooking"]>
export type CourtBookingOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "bookingCode" | "courtId" | "bookingDate" | "startTime" | "endTime" | "customerName" | "customerPhone" | "customerEmail" | "status" | "createdAt" | "updatedAt", ExtArgs["result"]["courtBooking"]>
export type CourtBookingInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
court?: boolean | Prisma.CourtDefaultArgs<ExtArgs>
}
@@ -709,6 +742,7 @@ export type $CourtBookingPayload<ExtArgs extends runtime.Types.Extensions.Intern
endTime: string
customerName: string
customerPhone: string
customerEmail: string | null
status: $Enums.CourtBookingStatus
createdAt: Date
updatedAt: Date
@@ -1144,6 +1178,7 @@ export interface CourtBookingFieldRefs {
readonly endTime: Prisma.FieldRef<"CourtBooking", 'String'>
readonly customerName: Prisma.FieldRef<"CourtBooking", 'String'>
readonly customerPhone: Prisma.FieldRef<"CourtBooking", 'String'>
readonly customerEmail: Prisma.FieldRef<"CourtBooking", 'String'>
readonly status: Prisma.FieldRef<"CourtBooking", 'CourtBookingStatus'>
readonly createdAt: Prisma.FieldRef<"CourtBooking", 'DateTime'>
readonly updatedAt: Prisma.FieldRef<"CourtBooking", 'DateTime'>