Dashboard
The dashboard is the landing page after login. It provides a real-time overview of your property's performance through six analytics widgets, each pulling data from dedicated API endpoints.
Overview
graph TD
subgraph Dashboard
KPI[KPI Cards]
REV[Revenue Chart]
OUT[Outstanding Payments]
OCC[Occupancy Heatmap]
EVR[Expense vs Revenue]
CAL[Room Calendar]
end
subgraph APIs
A1["GET /analytics/kpi"]
A2["GET /analytics/revenue"]
A3["GET /analytics/outstanding"]
A4["GET /analytics/occupancy"]
A5["GET /analytics/expense-vs-revenue"]
A6["GET /analytics/room-calendar"]
end
KPI --> A1
REV --> A2
OUT --> A3
OCC --> A4
EVR --> A5
CAL --> A6All dashboard data is organization-scoped — you only see metrics for the currently selected organization. Data refreshes automatically when a real-time dashboard:refresh event is received via Socket.IO.
Widget 1: KPI Cards
What It Shows
A row of summary cards at the top of the dashboard displaying key performance indicators at a glance:
| Card | Metric | Description |
|---|---|---|
| Today's Revenue | ₹ amount | Total payments received today |
| Active Bookings | Count | Bookings currently in checked-in status |
| Occupancy Rate | Percentage | Occupied rooms / total available rooms |
| Pending Checkouts | Count | Bookings due for checkout today |
| This Month's Revenue | ₹ amount | Revenue for the current calendar month |
| Outstanding Balance | ₹ amount | Total unpaid invoice amounts |
API Endpoint
GET /api/analytics/kpi?period=today
Authorization: Bearer <access_token>Response:
{
"success": true,
"data": {
"todayRevenue": 45200,
"activeBookings": 12,
"occupancyRate": 78.5,
"pendingCheckouts": 3,
"monthRevenue": 892400,
"outstandingBalance": 134500
}
}Interaction
- Click any card to navigate to the relevant detail page (e.g., clicking "Active Bookings" opens the bookings list filtered by
checked-instatus). - Cards update in real-time when booking or payment changes occur.
Screenshot
KPI Cards appear as a horizontal row of 6 colored cards spanning the full dashboard width. Each card shows an icon, the metric label, the value in large font, and a trend indicator (↑/↓) comparing to the previous period.
Widget 2: Revenue Chart
What It Shows
A line/bar chart displaying revenue over time. Supports daily, weekly, and monthly granularity with a date range picker.
- X-axis: Time periods (days, weeks, or months)
- Y-axis: Revenue amount (₹)
- Data series: Payments received, grouped by period
API Endpoint
GET /api/analytics/revenue?from=2026-02-01&to=2026-02-23&granularity=daily
Authorization: Bearer <access_token>Response:
{
"success": true,
"data": {
"labels": ["Feb 1", "Feb 2", "Feb 3"],
"datasets": [
{
"label": "Revenue",
"data": [32000, 28500, 41200]
}
],
"total": 892400,
"average": 38800
}
}Interaction
- Date range selector — Pick custom start/end dates or use presets (Last 7 days, This month, Last month, This quarter).
- Granularity toggle — Switch between daily, weekly, and monthly views.
- Hover tooltips — Hovering a data point shows the exact amount and date.
- Export — Download chart data as CSV.
Screenshot
A responsive bar chart with blue bars for each day's revenue. A floating date range picker sits in the top-right corner of the card. Total and average values display below the chart.
Widget 3: Outstanding Payments
What It Shows
A table listing all invoices with unpaid balances, sorted by amount descending. Helps front-desk and accounting staff follow up on pending payments.
| Column | Description |
|---|---|
| Invoice # | Auto-generated invoice number |
| Guest | Guest name linked to the booking |
| Booking # | Associated booking reference |
| Total | Invoice total amount |
| Paid | Amount already paid |
| Outstanding | Remaining balance |
| Due Date | Payment due date |
| Status | partial, unpaid, overdue |
API Endpoint
GET /api/analytics/outstanding?page=1&limit=10&sort=outstanding:desc
Authorization: Bearer <access_token>Response:
{
"success": true,
"data": {
"invoices": [
{
"invoiceId": "inv_001",
"invoiceNumber": "INV-2026-0042",
"guestName": "Rajesh Kumar",
"bookingNumber": "BK-2026-0105",
"total": 24500,
"paid": 10000,
"outstanding": 14500,
"dueDate": "2026-02-25",
"status": "partial"
}
],
"pagination": { "page": 1, "limit": 10, "total": 23 },
"totalOutstanding": 134500
}
}Interaction
- Click a row to open the invoice detail page.
- Filter by status (
partial,unpaid,overdue). - Sort by any column.
- The total outstanding amount displays prominently above the table.
Screenshot
A data table with alternating row colors. Overdue invoices are highlighted with a red left border. A summary bar above the table shows "Total Outstanding: ₹1,34,500" in bold.
Widget 4: Occupancy Heatmap
What It Shows
A calendar-style heatmap showing daily occupancy rates over the past 30 days (or selected range). Color intensity represents occupancy percentage:
| Color | Occupancy Range |
|---|---|
| Light green | 0–25% |
| Green | 25–50% |
| Dark green | 50–75% |
| Deep green / Blue | 75–100% |
API Endpoint
GET /api/analytics/occupancy?from=2026-01-24&to=2026-02-23
Authorization: Bearer <access_token>Response:
{
"success": true,
"data": {
"days": [
{ "date": "2026-02-01", "occupancy": 65.0, "occupied": 13, "total": 20 },
{ "date": "2026-02-02", "occupancy": 80.0, "occupied": 16, "total": 20 },
{ "date": "2026-02-03", "occupancy": 45.0, "occupied": 9, "total": 20 }
],
"averageOccupancy": 63.5
}
}Interaction
- Hover a cell to see the date, exact percentage, and room count (e.g., "Feb 2 — 80%, 16 of 20 rooms").
- Click a cell to navigate to the room calendar for that specific date.
- Average occupancy for the selected period displays below the heatmap.
Screenshot
A grid of colored squares arranged in a calendar layout (7 columns for days of the week). Darker squares indicate higher occupancy. A color-scale legend runs along the bottom.
Widget 5: Expense vs Revenue
What It Shows
A dual-axis chart comparing monthly expenses against revenue, helping managers understand profitability trends.
- Bar series: Monthly revenue (blue)
- Bar series: Monthly expenses (red/orange)
- Line series: Net profit/loss (green/red dashed line)
API Endpoint
GET /api/analytics/expense-vs-revenue?year=2026
Authorization: Bearer <access_token>Response:
{
"success": true,
"data": {
"labels": ["Jan", "Feb"],
"revenue": [920000, 892400],
"expenses": [680000, 542000],
"netProfit": [240000, 350400]
}
}Interaction
- Year selector — Switch between financial years.
- Hover tooltips — Shows revenue, expenses, and net profit for the hovered month.
- Click a month — Drills down into a detailed breakdown of expense categories for that month.
Screenshot
A grouped bar chart with blue (revenue) and orange (expenses) bars side by side for each month. A green dashed line traces the net profit across the top. The current month is subtly highlighted.
Widget 6: Room Calendar
What It Shows
A Gantt-style calendar view showing all rooms on the Y-axis and dates on the X-axis. Booking blocks span across dates, color-coded by status:
| Color | Booking Status |
|---|---|
| Blue | Confirmed (upcoming) |
| Green | Checked-in (active) |
| Gray | Checked-out (completed) |
| Red | Cancelled |
| White / Empty | Available |
API Endpoint
GET /api/analytics/room-calendar?from=2026-02-20&to=2026-02-27
Authorization: Bearer <access_token>Response:
{
"success": true,
"data": {
"rooms": [
{
"roomId": "room_101",
"roomNumber": "101",
"category": "Deluxe",
"bookings": [
{
"bookingId": "bk_001",
"guestName": "Anita Sharma",
"checkIn": "2026-02-20",
"checkOut": "2026-02-24",
"status": "checked-in"
}
]
},
{
"roomId": "room_102",
"roomNumber": "102",
"category": "Deluxe",
"bookings": []
}
]
}
}Interaction
- Scroll horizontally to navigate through dates.
- Click a booking block to open the booking detail page.
- Click an empty cell to start creating a new booking for that room and date.
- Drag a booking block's edge to extend or shorten the stay (triggers an update API call).
- Rooms are grouped by category with collapsible sections.
Screenshot
A horizontal timeline with room numbers listed vertically on the left. Colored bars span across date columns representing bookings. Room categories act as section headers (e.g., "Deluxe — 5 rooms"). Empty slots are clickable with a subtle "+" icon on hover.
Real-Time Updates
All dashboard widgets subscribe to Socket.IO events. When any user in the organization creates a booking, records a payment, or changes a room status, the server emits a dashboard:refresh event:
// Frontend listens for refresh signal
socket.on('dashboard:refresh', () => {
// Re-fetch all widget data
queryClient.invalidateQueries({ queryKey: ['dashboard'] });
});This ensures every team member always sees the latest data without manually refreshing the page.
Permissions
Dashboard access is controlled by the dashboard:read permission. Users without this permission see a restricted view with only basic KPI cards. Full analytics (charts, heatmap, calendar) require analytics:read.