Umum
Arsitektur Widget System
flowchart LR subgraph Frontend Page["dashboard page.tsx"] --> Hook[useDashboardLayout] Hook --> API1["GET /api/dashboard/layouts/:role"] API1 -->|null| Preset["presets.ts
hardcoded fallback"] API1 -->|dto| LayoutDB[("DashboardLayout")] Hook --> Grid[DashboardGrid] Page --> Data["DashboardData
fetched once, shared"] Grid --> Reg["registry.ts
20+ widgets"] Reg --> Widget1[KpiRevenue] Reg --> Widget2[ArAging] Reg --> Widget3[TrendChart] Reg --> WidgetN["..."] Widget1 --> Data Widget2 --> Data Widget3 --> Data end subgraph Editor SettingsPage["/settings/dashboard"] --> APIEdit["PUT /dashboard/layouts/:role"] APIEdit --> LayoutDB end style LayoutDB fill:#dbeafe,stroke:#3b82f6 style Reg fill:#fef3c7,stroke:#d97706 style Data fill:#f0fdf4,stroke:#16a34a
UI โ€” Dashboard Manager & Layout Editor
bengkelpintar.app/dashboard
Dashboard
Work Order
Inventory
Dashboard โ€” Manager
๐ŸŸข Live
MG
๐Ÿ’ฐ
Rp 482jt
Revenue MTD โ†‘12%
๐Ÿ“ˆ
Rp 96jt
Net Profit ยท 19.9%
๐Ÿ”ง
42
SPK Aktif
โš ๏ธ
7
Stok Kritis
Tren Revenue (12 Bln) ยท Target โ”„ ยท โ—‹ Forecast EOM
AR Aging โ€” Umur Piutang
๐ŸŸข Lancar (0-30)Rp 28jt ยท 14 invoice
๐ŸŸก Perhatian (31-60)Rp 12jt ยท 6 invoice
๐ŸŸ  Risiko (61-90)Rp 5jt ยท 3 invoice
๐Ÿ”ด Macet (>90)Rp 2jt ยท 1 invoice
bengkelpintar.app/settings/dashboard
Pengaturan
Layout Dashboard
Layout Dashboard โ€” Editor
๐Ÿ”ด Admin Only
Admin Manager SA Kasir +4
Palet
KPI
Revenue MTD SM
SPK Aktif SM
CHART
Tren 12 Bln LG
FINANCE
AR Aging $ MD
Layout Admin (drag-drop)
1. Header & Quick ActionsFULL
2. Role Decision PanelFULL
3. KPI Revenue MTD $SM
4. TrendChart 12 BlnLG
5. AR AgingMD
Katalog Widget (20+ widget)

๐Ÿ“‹ Header

  • header โ€” sambutan, tanggal, quick action sesuai role
  • alert-bar โ€” notifikasi stok habis, PO transit, AR pending
  • role-panel โ€” panel keputusan harian per role
  • Category: header / alert / action โ€” selalu full-width

๐Ÿ“Š KPI Cards (sm)

  • kpi-revenue ๐Ÿ’ฒ ยท kpi-profit ๐Ÿ’ฒ ยท kpi-spk ยท kpi-gross ๐Ÿ’ฒ
  • kpi-customer ยท kpi-ar ๐Ÿ’ฒ ยท kpi-ap ๐Ÿ’ฒ ยท kpi-stock
  • $ icon = sensitive (default disembunyikan untuk non-finance role)
  • Sparkline 6 bulan + delta vs bulan lalu

๐Ÿ“ˆ Charts

  • chart-trend โ€” Revenue + Profit 12 bln, target line, forecast EOM
  • spk-pipeline โ€” donut status SPK + masuk/selesai hari ini
  • Forecast = MTD / dayOfMonth ร— daysInMonth
  • Target = avg 6 bln ร— 1.10 (heuristik growth 10%)

๐Ÿ’ฐ Finance Widgets

  • ar-aging ๐Ÿ’ฒ โ€” bucket 0-30 / 31-60 / 61-90 / >90 hari
  • supplier-due ๐Ÿ’ฒ โ€” hutang outstanding
  • summary-12mo ๐Ÿ’ฒ โ€” tabel revenue/profit per bulan
  • Highlight risiko: AR > 60 hari โ†’ "prioritas penagihan minggu ini"

๐Ÿ“ƒ List / Tabel

  • recent-spk โ€” 8 SPK terbaru dengan status & total
  • mekanik-performance โ€” utilisasi & rating per mekanik
  • top-jasa โ€” top 5 layanan + ringkasan kas
  • po-transit ยท low-stock ยท summary-spk

๐Ÿ“ Size System

  • Grid 4-kolom; sm=1, md=2, lg=3, full=4
  • Default size dari widget meta โ€” admin bisa override per layout
  • Layout (header/alert/action) selalu full-width otomatis
  • Saved size override di kolom widgetSizes (JSON)
Role Presets (Default Layout)

๐Ÿ›ก๏ธ Admin / Manager

  • Semua KPI + finance + chart + list = ~20 widget
  • TrendChart, AR Aging, Summary 12 bulan, mekanik performance
  • Sensitive widgets ($) terlihat semua

๐Ÿ›Ž๏ธ Service Advisor (SA)

  • SPK aktif, customer, AR, stok
  • SPK pipeline donut, summary SPK, recent SPK
  • Tanpa widget profit / cogs / chart trend

๐Ÿ’ณ Kasir

  • Revenue, AR, AP, AR Aging
  • Pipeline + summary SPK + supplier due
  • Fokus collection & cash position

๐Ÿ”ง Mekanik / Karu / Gudang / Operator

  • Mekanik: SPK saya, stok kritis, pipeline
  • Karu: SPK + KPI tim + mekanik performance
  • Gudang: stok, PO transit, supplier due, AP
  • Operator: SPK aktif, customer, summary
Layout Editor (Admin Only) ยท /settings/dashboard

๐ŸŽฏ Tab Per Role

  • 8 role: admin, manager, sa, kasir, mekanik, gudang, operator, karu
  • Tab horizontal di top untuk switch antar role
  • Loading: fetch dari API โ†’ fallback ke preset jika belum di-customize

๐Ÿ“‹ Palet Widget (Sticky Left)

  • Dikelompokkan per kategori dengan warna khas
  • Drag widget atau click untuk tambah
  • Widget yang sudah dipilih โ†’ opacity 0.55
  • Badge $ untuk sensitive (finance) widget

๐ŸŽจ List Layout (Right)

  • Drag handle โ‹ฎโ‹ฎ untuk reorder
  • Drop-zone biru di antara item saat drag
  • Size selector inline: S / M / L / Full
  • Badge "custom" muncul jika size override aktif
  • ร— untuk hapus widget dari layout

๐Ÿ’พ Save / Reset

  • Indicator dirty state โ€” "Ada perubahan belum disimpan"
  • Save โ†’ PUT /api/dashboard/layouts/:role
  • Reset to Default โ†’ DELETE /api/dashboard/layouts/:role (kembali ke preset hardcoded)
  • Status: "Custom layout" (hijau) atau "Default preset" (kuning)
API Endpoints
MethodPathPermissionDeskripsi
GET/dashboard/layoutssettings.dashboard:viewList semua layout terkonfigurasi (admin/manager)
GET/dashboard/layouts/:roleany authGet layout role (non-admin hanya boleh role-nya sendiri)
PUT/dashboard/layouts/:rolesettings.dashboard:editUpsert layout role
DELETE/dashboard/layouts/:rolesettings.dashboard:deleteReset ke default preset (admin only)
GET/dashboardrbac admin/manager/sa/karuAggregate KPI + alerts (legacy endpoint)
GET/dashboard/summaryrbacToday summary (revenue, bay, queue)
GET/dashboard/chart/revenuerbacRevenue trend 30 hari
GET/dashboard/chart/wo-statusrbacDistribusi status WO
GET/dashboard/alertsrbacLow stock, expiring STNK, budget
Tabel & Event

Tabel: DashboardLayout (role unique, widgetKeys[], widgetSizes JSON, audit fields)

Resource permission baru: settings.dashboard (view/create/edit/delete)

WS Events (real-time): wo:status_changed, wo:created, bay:occupied, bay:free, payment:closed, followup:created

Throttle: hook useSpkRealtime 300ms agar event burst tidak spam re-render

Performance: shared DashboardData dihitung sekali, semua widget tinggal pakai (mengurangi N+1 fetch)