Spesifikasi UI · pegangan Peran D

Halaman dan komponen WebGIS

Semua layar dirancang mobile-first untuk petugas di lapangan. Bahasa default Indonesia, dengan tombol ganti ke Inggris untuk juri. Data diambil dari API, bukan langsung dari Firestore.

01 · Peta halaman

Tujuh rute, empat untuk publik

Rute publik tidak perlu login. Rute operator dilindungi Firebase Auth dan hanya terbuka untuk akun dengan peran operator.

RuteHalamanPenggunaIsi utamaData dari
/Peta publiksemuaGrid risiko hari ini, insiden 24 jam, daftar insiden, legendaGET /meta, /risk, /incidents
/insiden/:idDetail insidensemuaLevel, alasan, tindakan, bukti citra, riwayat deteksi, peta miniGET /incidents/{id}
/laporanSitrep hariansemuaRingkasan satu halaman, pilih tanggal, tabel insiden per levelGET /sitreps/{date}
/tentangTentang & metodesemua, juriCara kerja, ToPeCAl, sumber data, batasan sistemstatis
/masukLogin operatoroperatorTombol "Masuk dengan Google"Firebase Auth
/operatorAntrean drafoperatorDraf dari agen, tab Draf / Disetujui / Ditolak, urut levelGET /operator/queue
/operator/alert/:idTinjau drafoperatorEdit pesan, ubah level dengan alasan, setujui atau tolakGET / PATCH / POST /operator/alerts/{id}
Semua path API diawali /api/v1. Contoh: /api/v1/incidents.
02 · Alur pengguna

Dua alur yang harus mulus di demo

Publik
Buka peta→Lihat sel risiko merah→Tap titik insiden→Baca kartu→Buka detail

Target: dari membuka situs sampai membaca alasan insiden dalam tiga tap.

Operator
Masuk→Antrean→Buka draf teratas→Cek alasan & bukti→Edit bila perlu→Setujui→Muncul di peta publik

Target: satu draf bisa disetujui dalam kurang dari satu menit.

03 · Wireframe

Lima layar utama, ukuran HP

Di layar selebar 1024 px ke atas, daftar insiden pindah ke panel kiri selebar 360 px dan peta mengisi sisanya. Data dalam sketsa adalah contoh fiktif.

ASAPifyID | EN
Layer
3 insiden · 24 jamurut level
AwasKT-042 · 3,2 km dari desa
SiagaKT-051 · 2 deteksi

Peta publik /

  • Peta layar penuh, bottom sheet daftar insiden yang bisa ditarik
  • Tombol Layer: Risiko, Insiden, Batas gambut, Desa
  • Banner kesegaran data selalu tampil
  • Tap titik: sheet membuka kartu insiden ringkas
← Insiden KT-042Siaga
Titik api berulang di lahan gambut
Alasan
  • 3 deteksi VIIRS dalam 18 jam
  • 11 hari tanpa hujan
  • Desa terdekat 3,2 km
Tindakan
  • BPBD: kirim tim cek
  • MPA: siagakan pompa
  • Warga: jangan membakar
Verifikasi citraBelum ada lintasan Landsat

Detail insiden /insiden/:id

  • Urutan: bukti citra, judul, alasan, tindakan, verifikasi
  • Riwayat deteksi sebagai garis waktu di bawah
  • Tombol Bagikan menyalin tautan
  • Hanya alert berstatus approved yang tampil
Laporan harian12 Sep 2026 ▾
RingkasanKalimantan Tengah: 3 insiden aktif di lahan gambut, 1 berstatus Awas. Risiko Sangat tinggi di 14 sel, terpusat di selatan.
Per level
Awas1
Siaga1
Waspada1
Prakiraan 3 hariBelum ada hujan. Risiko tetap tinggi.
Disusun oleh agen Gemini, disetujui operator 06.20 WIB

Sitrep /laporan

  • Pemilih tanggal, default hari ini
  • Teks ringkasan maksimal 120 kata
  • Tabel jumlah insiden per level
  • Tautan ke setiap insiden
Antrean operatorKeluar
Draf 3DisetujuiDitolak
Awas10.12
KT-042 · ToPeCAl: menyala
Tinjau
Siaga09.48
KT-051 · 2 deteksi
Tinjau
Waspada09.05
KT-060 · 1 deteksi⚠ perlu dicek: validator gagal

Antrean /operator

  • Urut level tertinggi, lalu waktu terbaru
  • Penanda "perlu dicek" bila validator gagal dua kali
  • Muat ulang otomatis tiap 60 detik
← Tinjau KT-042Siaga
Validator✓ skema · ✓ level · ✓ angka
Pesan (ID) · 212/400
Titik api berulang terdeteksi di lahan gambut 3,2 km dari Desa …
Pesan (EN) · 198/400
Repeated hotspots detected on peatland 3.2 km from …
Ubah levelSiaga ▾ · alasan wajib diisi bila diubah
SetujuiSimpanTolak

Tinjau draf /operator/alert/:id

  • Tampilkan jejak pemanggilan tools (bisa dilipat)
  • Tolak wajib dengan alasan
  • Ubah level wajib dengan alasan, tercatat di audit
  • Tombol "Buat ulang" memanggil agen lagi
04 · Layer peta

Lima layer MapLibre

Urutan dari bawah ke atas sesuai tabel. Basemap raster OpenStreetMap atau basemap vektor gratis. Cantumkan atribusinya.

ID layerSumberTipeGayaZoomInteraksi
risk-gridURL dari GET /risk (GeoJSON di Cloud Storage)fillwarna per kelas risiko, opacity 0,55semuatap: skor dan komponennya
peat-boundarypeat.geojson di bucket publik, dimuat sekalilinegaris putus-putus 1 px, warna mosssemuatidak ada
villagesvillages.geojson di bucket publiksymbolnama desa, 11 px≥ 10tidak ada
detectionsproperti detections dari detail insidencircleabu-abu 3 px≥ 9tidak ada
incidentsGET /incidents?since=24hcirclewarna per level, radius 6–14 px sesuai jumlah deteksisemuatap: kartu insiden
Gaya layer insidenmap.ts
map.addLayer({
  id: 'incidents', type: 'circle', source: 'incidents',
  paint: {
    'circle-color': ['match', ['get', 'level'],
      'AWAS', '#c2410c', 'SIAGA', '#e8743b', 'WASPADA', '#a86f00', /* PANTAU */ '#8a958e'],
    'circle-radius': ['interpolate', ['linear'], ['get', 'n_detections'], 1, 6, 5, 14],
    'circle-stroke-color': '#ffffff', 'circle-stroke-width': 2,
  },
});
05 · Token desain

Warna level selalu berpasangan dengan teks

Jangan pernah membedakan level hanya dengan warna. Setiap penanda level wajib menampilkan labelnya.

LevelLabel IDLabel ENWarna
PANTAUPantauMonitor#8A958E
WASPADAWaspadaAdvisory#A86F00
SIAGASiagaWatch#E8743B
AWASAwasWarning#C2410C
Kelas risikoSkorWarna
Rendah< 30#E3ECD9
Sedang30–54#F3E2A6
Tinggi55–74#EFB57A
Sangat tinggi≥ 75#D9714A
Huruf
Plus Jakarta Sans untuk teks dan judul (dirancang di Indonesia), IBM Plex Mono untuk angka dan kode. Keduanya dari Google Fonts.
Ukuran dasar
16 px teks, 14 px keterangan, minimal 12 px untuk label kecil
Target sentuh
minimal 44 × 44 px untuk tombol dan titik insiden
Mode gelap
ikut pengaturan sistem, basemap ganti ke versi gelap
Kontras
teks minimal WCAG AA (4,5 : 1)
06 · Komponen

Sepuluh komponen yang dipakai ulang

KomponenPropsDipakai diCatatan
LevelBadgelevel, langsemuawarna + label, tidak pernah warna saja
RiskLegendlangpetaempat kelas, bisa dilipat di HP
IncidentCardincident, compactpeta, daftar, sitrepmode ringkas untuk bottom sheet
EvidenceImagethumbUrl, sensor, date, topecalClassdetail, tinjautampilkan "belum ada citra" bila kosong
ReasonListreasons[]detail, tinjau2–5 butir
ActionListactions{agency, community, residents}detail, tinjauikon per audiens
ValidatorStatuspassed, checks[]tinjau, antreanhijau semua lolos, kuning bila perlu dicek
ToolTracecalls[]tinjaudaftar tools yang dipanggil agen, bisa dilipat. Tampilkan di video demo
DataBannerasOf, lastIngestAt, replaysemua halaman publikbiru untuk replay, kuning bila data > 2 jam
LangTogglelangheadersimpan pilihan di localStorage
07 · Status layar

Setiap layar punya lima keadaan

KeadaanKapanTampilanTeks (ID)
Memuatrequest berjalankerangka abu-abu, peta tetap tampiltanpa teks
Kosongtidak ada insiden di gambutpesan tenang, legenda risiko tetap tampil"Tidak ada insiden di lahan gambut dalam 24 jam terakhir."
GalatAPI gagalkotak pesan + tombol Coba lagi"Data belum bisa dimuat. Periksa koneksi lalu coba lagi."
Data lamalastIngestAt > 2 jambanner kuning"Data terakhir diperbarui {jam}. Pembaruan sedang terlambat."
Replayreplay = truebanner biru"Mode replay: data per {tanggal jam}."
08 · Teks antarmuka

Kunci i18n dan terjemahannya

Simpan di src/i18n/id.json dan en.json. Jangan menulis teks langsung di komponen.

KunciIDEN
level.pantauPantauMonitor
level.waspadaWaspadaAdvisory
level.siagaSiagaWatch
level.awasAwasWarning
verify.noneBelum ada citra satelitNo satellite image yet
verify.flamingCitra menunjukkan api menyalaImagery shows flaming fire
verify.smoulderingCitra menunjukkan api membaraImagery shows smouldering fire
btn.approveSetujuiApprove
btn.saveSimpanSave
btn.rejectTolakReject
btn.regenerateBuat ulangRegenerate
toast.approvedAlert disetujui dan tampil di peta publik.Alert approved and now on the public map.
banner.replayMode replay: data per {date}.Replay mode: data as of {date}.
09 · Stack & folder

Frontend ringan, satu bundle statis

Build
Vite + TypeScript
Peta
MapLibre GL JS
UI
React + React Router, atau vanilla TS bila tim lebih nyaman
Auth
Firebase JS SDK, modul Auth saja
Hosting
Firebase Hosting, /api/** diarahkan ke Cloud Run
Target
peta tampil < 3 detik di 4G, tidak ada scroll horizontal di lebar 360 px
Struktur folderweb/
web/
├─ index.html
├─ src/
│  ├─ main.ts
│  ├─ api.ts            # fetch ke /api/v1, sisipkan token operator
│  ├─ auth.ts           # Firebase Auth, cek klaim role
│  ├─ map/
│  │  ├─ map.ts         # inisialisasi + 5 layer
│  │  └─ styles.ts
│  ├─ pages/            # Peta, Insiden, Laporan, Tentang, Masuk, Operator, Tinjau
│  ├─ components/       # 10 komponen di bagian 06
│  └─ i18n/ id.json, en.json
└─ firebase.json