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:
@@ -0,0 +1,76 @@
|
||||
"use client"
|
||||
|
||||
import dynamic from "next/dynamic"
|
||||
import {
|
||||
CalendarClockIcon,
|
||||
CheckCheckIcon,
|
||||
ClipboardListIcon,
|
||||
DollarSignIcon,
|
||||
TriangleAlertIcon,
|
||||
} from "lucide-react"
|
||||
|
||||
import { getBookingDashboardSummary } from "@/lib/api/bookings"
|
||||
import { useFetch } from "@/lib/use-fetch"
|
||||
import { Spinner } from "@/components/ui/spinner"
|
||||
import { StatCard } from "@/components/hexa/stat-card"
|
||||
|
||||
// FullCalendar touches the DOM at import time -- must not run during server-side rendering.
|
||||
const BookingCalendar = dynamic(
|
||||
() => import("@/components/hexa/views/booking-calendar").then((m) => m.BookingCalendar),
|
||||
{
|
||||
ssr: false,
|
||||
loading: () => (
|
||||
<div className="flex h-[500px] items-center justify-center rounded-lg border">
|
||||
<Spinner className="size-6" />
|
||||
</div>
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
function BookingDashboardTab() {
|
||||
const summaryFetch = useFetch(() => getBookingDashboardSummary())
|
||||
const summary = summaryFetch.data
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="grid grid-cols-2 gap-3 lg:grid-cols-5">
|
||||
<StatCard
|
||||
icon={ClipboardListIcon}
|
||||
tone="blue"
|
||||
label="Bookings Today"
|
||||
value={summaryFetch.loading ? "…" : (summary?.bookingsToday ?? 0)}
|
||||
/>
|
||||
<StatCard
|
||||
icon={DollarSignIcon}
|
||||
tone="green"
|
||||
label="Revenue Today"
|
||||
value={summaryFetch.loading ? "…" : `Rs. ${(summary?.revenueToday ?? 0).toLocaleString()}`}
|
||||
/>
|
||||
<StatCard
|
||||
icon={CheckCheckIcon}
|
||||
tone="purple"
|
||||
label="Checked In Now"
|
||||
value={summaryFetch.loading ? "…" : (summary?.checkedInNow ?? 0)}
|
||||
/>
|
||||
<StatCard
|
||||
icon={CalendarClockIcon}
|
||||
tone="amber"
|
||||
label="Upcoming"
|
||||
value={summaryFetch.loading ? "…" : (summary?.upcomingConfirmed ?? 0)}
|
||||
hint="Confirmed, not yet checked in"
|
||||
/>
|
||||
<StatCard
|
||||
icon={TriangleAlertIcon}
|
||||
tone="amber"
|
||||
label="Outstanding"
|
||||
value={summaryFetch.loading ? "…" : `Rs. ${(summary?.outstandingUnpaid ?? 0).toLocaleString()}`}
|
||||
hint="Unpaid guest bookings"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<BookingCalendar />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export { BookingDashboardTab }
|
||||
Reference in New Issue
Block a user