# Sprint — Dashboard Web Profesional (Pengembangan & Rekomendasi)

**Aplikasi:** LPK TIP v2 (Web Laravel 13 + Livewire 4 + Tailwind 4 + ApexCharts)
**Modul:** Dashboard (`/` — `App\Livewire\Dashboard`)
**Tanggal:** 2026-08-26 · **Status:** Rencana (draft D1–D4)

---

## 1. Ringkasan & Tujuan

Menjadikan dashboard web **lebih profesional, informatif, dan sesuai peran** — dari dashboard admin-generik saat ini menjadi **pusat kendali operasional** yang menampilkan KPI bermakna, grafik multi-modul, peringatan proaktif, dan aksi cepat, dengan **tampilan berbeda sesuai peran** (admin vs user dengan scope proyek).

**Prinsip:** maksimalkan data yang sudah ada (tanpa skema baru besar) → tambah KPI/grafik/widget yang menjawab kebutuhan operasional harian → role-aware → performa & UX profesional.

---

## 2. Kondisi Saat Ini (Audit)

| Komponen | Ada? | Detail |
|---|---|---|
| KPI cards (6) | ✅ | Material Aktif, Proyek Aktif, SPB Open (+qty), Transfer Open, BKK Periode (Rp + delta), Absensi Hari Ini — icon + warna, link, delta vs periode sebelumnya |
| Filter periode | ✅ | bulan ini / 30 hari / semua / custom (`date_from`–`date_to`) |
| Grafik #1 | ✅ | Tren 7 hari: SPB, Transfer, BKK (ApexCharts bar) |
| Grafik #2 | ✅ | BKK per proyek top-6 (bar horizontal) |
| Widget transaksi terbaru | ✅ | SPB/Transfer/BKK 5 terbaru + status + link |
| Widget stok menipis | ✅ | stok aktual ≤ minimum (limit 6) |
| Widget dokumen open | ✅ | SPB/Transfer/BKK status open (limit 8) |
| Aksi cepat | ✅ | tombol pintasan |
| **Role-based view** | ❌ | Satu dashboard sama utk semua user login web |
| **Scope proyek** | ❌ | Belum memakai `user_projects` (user non-admin melihat data semua proyek) |
| **KPI nilai stok (Rp)** | ❌ | Hanya jumlah item, belum nilai persediaan |
| **Grafik stok/solar/absensi** | ❌ | Belum ada arus stok, saldo solar, kehadiran per hari |
| **Agenda/libur mendatang** | ❌ | Tidak ada |
| **Refresh otomatis** | ❌ | Hanya saat reload/halaman dibuka |
| **Export/unduh ringkasan** | ❌ | Tidak ada |
| **Empty/loading state** | ⚠️ | Parsial |

---

## 3. Rekomendasi Desain Target

### 3.1 Dashboard per peran (paling penting)

| Peran | Fokus |
|---|---|
| **Admin (full akses)** | Semua KPI operasional + grafik lintas modul + peringatan |
| **User non-admin + scope proyek** (`user_projects`) | Hanya KPI/grafik/widgeet proyek yang diotorisasi — KPI: SPB/Transfer/BKK proyeknya, stok gudang terkait, absensi proyek |

Implementasi: `Dashboard` memeriksa `$user->isAdmin()` + daftar `user_projects` → query diberi `->whereIn('project_id', $ids)` (atau tanpa filter utk admin). **Wajib** agar RBAC konsisten dgn menu.

### 3.2 KPI (susunan rekomendasi — 6–8 kartu dinamis)

| KPI | Sumber | Nilai | Delta? |
|---|---|---|---|
| Nilai Persediaan (Rp) | `stock_balances` × `unit_price` | Total nilai stok | ✅ |
| Stok Menipis | item stok ≤ min | jumlah item | ✅ |
| SPB Open | `transfer_requests status=1` | jumlah + sub total qty | — |
| Transfer Open | `transfers status=1` | jumlah | — |
| BKK Periode (Rp) | `cash_payments` | total + sub jumlah dok | ✅ |
| Absensi Hari Ini | `attendances is_present today` | hadir | — |
| Solar (Rp / liter) | `solar_receipts`−`solar_usages` periode | saldo/nilai | ✅ |
| PR/PO Open | `purchase_requests/orders status` | jumlah | — |

Setiap kartu: icon + warna konsisten (sprite `menu-icons`), link, delta dengan panah ▲▼, sub-info, tooltip.

### 3.3 Grafik (ApexCharts — naik dari 2 jadi 4)

| Grafik | Data | Catatan |
|---|---|---|
| Tren 7 hari (ada) | SPB / Transfer / BKK per hari | pertahankan |
| BKK per proyek (ada) | top 6 periode | pertahankan |
| **Arus stok 14 hari** | `stock_movements` masuk (GR/TRANSFER_IN) vs keluar (USE/OUT) | bar stacked |
| **Absensi minggu ini** | hadir / terlambat / alpha per hari | bar stacked |
| **Solar periode** (opsional) | penerimaan vs pemakaian per minggu | bar |

### 3.4 Widget tambahan

| Widget | Isi |
|---|---|
| **Agenda** | Hari libur mendatang (7 hari) dari `holidays` + periode payroll aktif |
| **Peringatan** | gabungan: stok menipis + SPB lama (>3 hari open) + transfer tanpa konfirmasi + absen anomali (mock/tanpa wajah) hari ini |
| **Mini kalender absensi** | grid hari ini per proyek (hadir/terlambat/alpha) |
| **Aktivitas terbaru** | `audit_logs` / notifikasi terbaru (bukan hanya transaksi) |
| **Quick actions** | per peran: Tambah SPB, BKK Baru, Input Absensi, Upload Material |

### 3.5 Interaksi & UX profesional

- **Refresh otomatis**: polling ringan 60 dtk utk badge/angka kecil (`wire:poll.60s` hanya pada widget tertentu) — bukan seluruh halaman.
- **Export ringkasan**: tombol "Unduh Ringkasan" → CSV (KPI + grafik data) via route GET.
- **Klik KPI** → buka modul dgn filter terkait (mis. stok menipis → `/material?low=1`).
- **Empty/loading state**: skeleton saat load; kartu kosong beri pesan ramah.
- **Waktu relatif** widget ("2 jam lalu") konsisten dgn helper.
- **Konsistensi visual**: gradient kartu, hover lift, badge status, tooltip.

### 3.6 Performa

- Hindari N+1: eager load + agregasi SQL (`selectRaw`/`withSum`) — pola sudah ada.
- **Cache KPI** (opsional): `Cache::remember(60s)` utk query berat (nilai stok, delta).
- Widget dibatasi limit (5–10) + "lihat semua" → modul.

---

## 4. Rencana Fase Implementasi

### Fase D1 — Fondasi & Role-based KPI (P0) — ✅ SELESAI (2026-08-26)
- [x] `Dashboard` role-aware: admin = semua; non-admin = scope `user_projects` (`projectScope()` terpusat + `scoped()` helper)
- [x] KPI baru: **Nilai Persediaan (Rp)**, **Stok Menipis**, **PR/PO Open**, **Solar Periode** → admin 8 kartu; non-admin 5 kartu (Proyek Saya, BKK, Absensi, PR, Solar — semua ter-scope)
- [x] Delta ▲▼ konsisten (helper `deltaPct`/`deltaCount`)
- [x] Grafik & widget ikut ter-scope: BKK (semua peran), SPB/Transfer khusus admin, stok menipis disembunyikan utk non-admin
- [x] Test: `DashboardEnterpriseTest` (render KPI baru, chart 3 seri admin, role-aware scope — BKK hanya proyek user, seri grafik, stockLow kosong) · full suite 164/166 (2 pre-existing: PeriodeBadge, UploadFoto)

### Fase D2 — Grafik & Widget lanjutan (P1) — ✅ SELESAI (2026-08-26)
- [x] Grafik **Arus stok 14 hari** (stacked Masuk/Keluar dari `stock_movements`, admin-only) + **Absensi minggu ini** (stacked Hadir/Terlambat/Alpha, di-scope proyek)
- [x] Widget **Agenda** (libur 3 mendatang + periode payroll aktif), **Peringatan** (anomali absen mock/tanpa wajah [scoped], stok menipis, SPB >3 hari, BKK open >7 hari [admin]), **Absensi Hari Ini per Proyek** (top 6, scoped)
- [x] `app.js`: renderer stacked generik `renderStackedDashChart` + chart3/chart4 di init & morphed; asset Vite dibuild
- [x] Test: `DashboardEnterpriseTest` + D2 (arus 14 hari, absensi 7 hari, agenda, limit peringatan/absensi; non-admin stockFlow kosong) · full suite 165/167 (2 pre-existing)

### Fase D3 — Interaksi & polish (P1) — ✅ SELESAI (2026-08-26)
- [x] **Export Ringkasan CSV** (`GET /dashboard/export`) — KPI + BKK per proyek hasil filter periode, BOM UTF-8 utk Excel, tombol **Unduh** di header
- [x] **Polling 60 detik** (`wire:poll.60s`) + indikator "Memperbarui…" saat loading/polling
- [x] **Quick actions per peran**: admin 6 aksi; non-admin 3 aksi relevan (BKK, Absensi, Laporan Stok)
- [x] Tooltip pada tombol export; subjudul dashboard menjelaskan auto-refresh
- [x] Test: export CSV berisi KPI/BKK, view punya polling, quickActions admin 6 / non-admin 3 · full suite 166/168 (2 pre-existing)

### Fase D4 — Opsional / lanjutan (P2)
- [ ] Dark mode dashboard; personalisasi (menu favorit, greeting)
- [ ] Insight otomatis ("BKK naik 20% minggu ini — cek proyek X"); PWA offline-cache
- [ ] Dashboard real-time via pusat notifikasi (FCM/web-push) — sinergi fitur notifikasi

---

## 5. Test Plan

| Area | Skenario |
|---|---|
| RBAC | Admin lihat semua; user scope proyek HANYA data proyeknya (SPB/Transfer/BKK/stok/absensi) |
| KPI | Angka cocok dgn query manual; delta benar utk periode sama panjang |
| Grafik | Data 7/14 hari lengkap; BKK per proyek top-N benar; sumbu/tooltip OK |
| Widget | Limit benar; empty state muncul; link navigasi benar |
| Interaksi | Polling 60s tidak memuat ulang halaman; export CSV valid; klik KPI membuka modul terfilter |
| Regresi | Semua route tetap 200 (`AllRoutesSmokeTest`); dashboard karyawan mobile tidak terpengaruh |

---

## 6. Risiko & Keputusan

| Risiko | Mitigasi |
|---|---|
| Query berat (nilai stok, delta, 14 hari) | Agregasi SQL + limit + `Cache::remember` opsional; hindari loop query |
| Scope proyek salah diterapkan | Helper terpusat `projectScope()` + test RBAC per modul data |
| Polling membebani | `wire:poll` hanya widget angka ringan (60s), bukan seluruh halaman |
| Dashboard jadi ramai | Prioritas widget; setiap blok bisa "lihat semua" → modul |
| Konsistensi desain | Pakai token warna/icon yang sudah ada (`menu-icons`, `AppColors`) |

---

## 7. Ringkasan

| Item | Nilai |
|---|---|
| Fondasi | Livewire `Dashboard` + ApexCharts sudah ada — fokus: role-aware, KPI nilai/operasional, grafik stok/absensi, widget agenda/peringatan, interaksi |
| Fase | D1 (role & KPI) → D2 (grafik & widget) → D3 (interaksi & polish) → D4 (opsional) |
| Estimasi | 3–4 + 3–4 + 2–3 hari kerja |
| Risiko utama | Performa query & konsistensi scope proyek |
