# Modul Dashboard

File terkait:
- Page: [Dashboard.jsx](../../src/pages/dashboard/Dashboard.jsx)
- Service: [dashboardService.js](../../src/services/dashboardService.js)

> **Catatan koreksi:** dashboard ini **bukan dummy** — ia menyusun statistik dengan
> menggabungkan beberapa endpoint report yang sudah ada, bukan endpoint summary
> tunggal. Tidak ada input/form di modul ini, murni read-only.

## Flow

1. Saat halaman mount, `useQuery(['dashboard-summary', branch.id], () => dashboardService.summary(branch.id))` jalan otomatis. `staleTime: 5 menit` — data tidak di-refetch ulang kalau pindah halaman dan balik lagi dalam 5 menit.
2. `branch` diambil dari `authStore` (cabang aktif yang dipilih user di topbar) — kalau ganti cabang, `queryKey` berubah → query baru otomatis jalan.
3. Selama loading → tampil skeleton (card, chart, list placeholder berkedip).

## Bagaimana `dashboardService.summary()` menyusun data

Memanggil **5 endpoint report sekaligus secara paralel** (`Promise.all`), masing-masing dengan filter tanggal & `branch_id` (kalau ada cabang aktif):

| Tujuan | Endpoint | Params |
|---|---|---|
| Statistik hari ini | `GET /v1/reports/sales` | `from=today, to=today` |
| Statistik kemarin (untuk hitung trend %) | `GET /v1/reports/sales` | `from=yesterday, to=yesterday` |
| Chart 7 hari terakhir | `GET /v1/reports/sales` | `from=6 hari lalu, to=today` |
| Top 5 produk terlaris hari ini | `GET /v1/reports/products` | `from=today, to=today, limit=5` |
| Transaksi terbaru hari ini | `GET /v1/reports/orders` | `from=today, to=today` |

Semua params juga menambahkan `branch_id` kalau ada cabang aktif dipilih (kalau tidak ada → data semua cabang/tenant).

**Expected response `/v1/reports/sales`:**
```json
{ "data": { "summary": { "total_revenue": "...", "total_orders": 0, "by_payment_method": [{ "name": "Cash", "total": "..." }] }, "daily_rows": [{ "date": "YYYY-MM-DD", "revenue": "..." }] } }
```

**Expected response `/v1/reports/products`:** array `[{ product_name, total_qty }]`

**Expected response `/v1/reports/orders`:** array order, tiap item minimal punya `id, order_number, order_type, status, table, branch, total`

## Transformasi data di FE (tidak ada di backend)

- **Trend %** (`revenue_trend`, `transaction_trend`): `((hari_ini - kemarin) / kemarin) * 100`, dibulatkan 1 desimal. Kalau kemarin = 0, trend dianggap 0 (hindari divide by zero).
- **Rata-rata transaksi:** `total_revenue / total_orders` (0 kalau tidak ada transaksi).
- **Weekly chart:** hari yang tidak ada datanya di `daily_rows` diisi `amount: 0` supaya chart tetap 7 batang penuh.
- **Payment summary %:** persentase tiap metode pembayaran relatif terhadap total semua metode hari ini.
- **Top products %:** persentase qty tiap produk relatif terhadap qty produk #1 (bukan persentase dari total penjualan).
- **Recent orders:** ambil 5 teratas dari hasil `/v1/reports/orders` (backend tidak punya parameter `limit` khusus untuk ini, slice di FE).

## UI yang ditampilkan

- 3 stat card: Pendapatan Hari Ini, Total Transaksi, Rata-rata Transaksi (dengan badge trend naik/turun vs kemarin)
- Bar chart penjualan 7 hari (Recharts)
- List metode pembayaran dengan progress bar persentase
- List 5 transaksi terbaru (status badge, no order, meja/takeaway, cabang, total)
- List top 5 produk terlaris dengan progress bar

**Catatan UX:** Tidak ada error state eksplisit di UI — kalau salah satu dari 5 request gagal, `Promise.all` reject semuanya dan TanStack Query akan masuk state error, tapi halaman ini **tidak merender pesan error**, jadi gagal total = dashboard tampak loading terus/blank tergantung implementasi `isLoading` (perlu dicek manual kalau ada laporan "dashboard kosong").
