feat: integrate FullCalendar for booking management and add booking dashboard

- Added FullCalendar component to display bookings in a calendar view.
- Implemented BookingDashboardTab to show summary statistics including bookings today, revenue, checked-in guests, and outstanding payments.
- Created BookingInvoicesTab to manage and display booking payment receipts separately from membership invoices.
- Enhanced AdhocBookingTab to allow selection of existing members for guest bookings.
- Updated BookingRosterTab to include payment methods and improved UI for guest identification.
- Introduced new API endpoints for fetching booking invoices and dashboard summaries.
- Updated models to support new features including payment methods and invoice structures.
This commit is contained in:
2026-10-01 03:45:55 +05:30
parent 0ba1e6a9e6
commit 698fd4239b
13 changed files with 752 additions and 55 deletions
+8
View File
@@ -0,0 +1,8 @@
/** Mirrors BookingDashboardSummaryDto. */
export interface BookingDashboardSummary {
bookingsToday: number
revenueToday: number
checkedInNow: number
upcomingConfirmed: number
outstandingUnpaid: number
}
+23
View File
@@ -0,0 +1,23 @@
import type { PaymentMethod } from "@/lib/models/booking"
/** Mirrors BookingInvoiceDto. A booking payment receipt — deliberately separate from
* membership-based Customer Payments/invoices. */
export interface BookingInvoice {
bookingInvoiceId: string
bookingId: string
amount: number
paymentMethod: PaymentMethod
guestName: string
guestPhone?: string | null
facilityName: string
bookingStartTime: string
bookingEndTime: string
issuedAt: string
/** Public, unauthenticated link to this receipt's printable page. */
shareUrl?: string | null
}
export type GetBookingInvoicesFilters = {
fromDate?: string
toDate?: string
}
+21
View File
@@ -1,4 +1,5 @@
export type BookingStatus = "Confirmed" | "CheckedIn" | "Cancelled" | "NoShow" | "Completed"
export type PaymentMethod = "Cash" | "Bank"
/** Mirrors BookingDto. Covers both Scheduled (facilitySessionId set) and AdHoc
* (facilitySessionId null, exclusive-unit) bookings. */
@@ -30,6 +31,9 @@ export interface Booking {
paymentStatus: string
amountCharged: number
/** Set once paymentStatus becomes "Paid". */
paymentMethod?: PaymentMethod | null
paidAt?: string | null
status: BookingStatus
bookedAt: string
checkedInAt?: string | null
@@ -51,6 +55,8 @@ export interface CreateGuestBookingInput {
facilitySessionId: string
guestName: string
guestPhone: string
/** Optional link to an existing registered customer — identification/auto-fill only. */
customerId?: string
}
export interface CreateAdhocBookingInput {
@@ -69,6 +75,8 @@ export interface CreateGuestAdhocBookingInput {
partySize?: number
/** Overrides the facility's own price per hour for this booking's charge only. */
pricePerHour?: number
/** Optional link to an existing registered customer — identification/auto-fill only. */
customerId?: string
}
export interface ReassignBookingInput {
@@ -82,3 +90,16 @@ export interface RescheduleBookingInput {
durationMinutes?: number
facilitySessionId?: string
}
/** Only required when the target booking is a guest booking still Unpaid — the backend
* rejects checkout otherwise. Ignored for a member booking or a guest booking already Paid. */
export interface CompleteBookingInput {
markPaid?: boolean
amountCollected?: number
paymentMethod?: PaymentMethod
}
export interface MarkGuestBookingPaidInput {
amountCharged: number
paymentMethod?: PaymentMethod
}