Files
d1041231044_webgis_geopoverty/index.html
T
2026-06-11 21:18:48 +07:00

1556 lines
52 KiB
HTML

<!doctype html>
<html lang="id">
<head>
<title>SosialMap Pontianak — Sistem Pemetaan Sosial</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="Sistem pemetaan sosial berbasis GIS untuk pemantauan keluarga prasejahtera dan koordinasi bantuan di Kota Pontianak."
/>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<link
rel="stylesheet"
href="https://unpkg.com/leaflet-routing-machine@latest/dist/leaflet-routing-machine.css"
/>
<link rel="stylesheet" href="css/lumina.css?v=2" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
/>
<style>
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
height: 100%;
margin: 0;
font-family: "Hanken Grotesk", system-ui, sans-serif;
overflow: hidden;
color: var(--lumina-text, #1a2138);
}
#map {
position: absolute !important;
inset: 0;
width: 100vw;
height: 100vh;
z-index: 1;
}
.modal-bg {
position: fixed;
inset: 0;
z-index: 5000;
background: rgba(17, 24, 39, 0.45);
backdrop-filter: blur(4px);
display: flex;
align-items: center;
justify-content: center;
}
.modal-card {
width: 480px;
max-width: 94vw;
max-height: 90vh;
overflow: auto;
background: #fff;
border-radius: 16px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.16);
}
.modal-top {
display: flex;
align-items: flex-start;
gap: 14px;
padding: 22px 24px 16px;
border-bottom: 1px solid #eef1f6;
position: sticky;
top: 0;
background: #fff;
z-index: 1;
}
.modal-icon-wrap {
width: 42px;
height: 42px;
border-radius: 10px;
display: grid;
place-items: center;
flex: 0 0 auto;
}
.modal-icon-blue {
background: #eaf2ff;
color: #2563eb;
}
.modal-icon-green {
background: #eafaf0;
color: #16a34a;
}
.modal-icon-red {
background: #fff0f0;
color: #ef4444;
}
.modal-icon-amber {
background: #fff7df;
color: #d97706;
}
.modal-icon-purple {
background: #eef0ff;
color: #625ff4;
}
.modal-title {
font-size: 16px;
font-weight: 800;
color: #151c32;
}
.modal-subtitle {
font-size: 12px;
color: #727b90;
margin-top: 2px;
}
.modal-close {
margin-left: auto;
border: 0;
background: #f4f6fb;
color: #727b90;
width: 30px;
height: 30px;
border-radius: 8px;
cursor: pointer;
}
.modal-body {
padding: 20px 24px 24px;
display: flex;
flex-direction: column;
gap: 14px;
}
.field,
.field-row .field {
display: flex;
flex-direction: column;
gap: 6px;
flex: 1;
}
.field-row {
display: flex;
gap: 10px;
}
.field-label {
font-size: 12px;
font-weight: 700;
color: #151c32;
}
.req {
color: #ef4444;
}
.field input,
.field select,
.field textarea,
#pesan-jenis,
#pesan-judul,
#pesan-isi {
border: 1.5px solid #e7eaf1;
border-radius: 8px;
padding: 10px 12px;
font: inherit;
font-size: 13px;
background: #f8fafc;
color: #151c32;
transition: border-color 0.18s, box-shadow 0.18s;
outline: none;
width: 100%;
box-sizing: border-box;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
border-color: #625ff4;
background: #fff;
box-shadow: 0 0 0 3px rgba(98, 95, 244, 0.10);
}
.field input::placeholder,
.field textarea::placeholder {
color: #b0b8cc;
font-size: 13px;
}
.field-hint {
font-size: 11px;
color: #9aa3b5;
}
.modal-footer {
display: flex;
justify-content: flex-end;
gap: 8px;
padding-top: 4px;
border-top: 1px solid #eef1f6;
margin-top: 4px;
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
border: 1.5px solid #e7eaf1;
border-radius: 8px;
height: 38px;
padding: 0 18px;
font: inherit;
font-size: 13px;
font-weight: 700;
cursor: pointer;
background: #fff;
color: #727b90;
transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.btn:hover {
background: #f4f6fb;
border-color: #d1d5e0;
}
.btn-primary,
.btn-send {
background: #625ff4;
border-color: #625ff4;
color: #fff;
}
.btn-primary:hover {
background: #4f4cd4;
border-color: #4f4cd4;
}
.btn-send {
background: #16a34a;
border-color: #16a34a;
}
.btn-send:hover {
background: #15803d;
border-color: #15803d;
}
.btn-add {
width: 100%;
border-style: dashed;
background: #eef0ff;
color: #625ff4;
}
.toast {
padding: 11px 14px;
border-radius: 10px;
color: #fff;
font-weight: 700;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.15);
}
.toast.success {
background: #16a34a;
}
.toast.error {
background: #ef4444;
}
.toast.info {
background: #2563eb;
}
.toast.removing {
opacity: 0;
transform: translateX(20px);
transition: 0.25s;
}
#toast-wrap {
position: fixed;
right: 20px;
bottom: 20px;
display: flex;
flex-direction: column;
gap: 8px;
z-index: 999999;
}
/* SweetAlert2 harus tampil di atas modal-login (z-index 99999) */
.swal2-container {
z-index: 200000 !important;
}
#detail-panel {
position: fixed;
top: calc(var(--navbar-h) + 16px);
bottom: 8px;
right: 12px;
width: 380px;
max-width: 94vw;
transform: translateX(calc(100% + 30px));
transition: 0.25s ease;
z-index: 2100;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(8px);
border-radius: 12px;
border: 1px solid var(--lumina-outline);
box-shadow: 0 4px 16px rgba(0,0,0,0.06);
display: flex;
flex-direction: column;
overflow: hidden;
}
#detail-panel.open {
transform: translateX(0);
}
.dp-head,
.dp-foot {
padding: 18px 20px;
border-bottom: 1px solid #e7eaf1;
}
.dp-foot {
border-top: 1px solid #e7eaf1;
border-bottom: 0;
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.dp-head-row {
display: flex;
justify-content: space-between;
gap: 12px;
}
.dp-title {
font-weight: 800;
font-size: 18px;
}
.dp-addr {
color: #727b90;
font-size: 12px;
margin-top: 4px;
}
.dp-close,
.pdf-close,
.ldf-close {
border: 0;
width: 30px;
height: 30px;
border-radius: 8px;
background: #f4f6fb;
cursor: pointer;
}
.dp-status {
margin-top: 12px;
padding: 9px 10px;
border-radius: 8px;
background: #eafaf0;
color: #16a34a;
font-weight: 800;
font-size: 12px;
}
.dp-tabs {
display: grid;
grid-template-columns: repeat(3, 1fr);
padding: 10px;
gap: 8px;
border-bottom: 1px solid #e7eaf1;
}
.dp-tab {
border: 1px solid #e7eaf1;
background: #fff;
border-radius: 8px;
height: 36px;
font-weight: 800;
color: #727b90;
cursor: pointer;
}
.dp-tab.active {
background: #625ff4;
border-color: #625ff4;
color: #fff;
}
.dp-content {
padding: 16px 20px;
overflow: auto;
flex: 1;
}
.hidden {
display: none !important;
}
.l-card,
.a-card,
.b-card,
.p-card {
border: 1px solid #e7eaf1;
border-radius: 10px;
padding: 12px;
margin-bottom: 10px;
background: #fff;
}
.lumina-panel-right {
overflow: hidden;
}
.panel-compose select,
.panel-compose input,
.panel-compose textarea {
width: 100%;
margin-bottom: 8px;
}
#pesan-detail-float,
#laporan-detail-float {
display: none;
position: fixed;
right: 440px;
top: 120px;
z-index: 3000;
width: 340px;
background: #fff;
border-radius: 16px;
box-shadow: 0 18px 48px rgba(28, 36, 62, 0.16);
overflow: hidden;
}
.pdf-head,
.ldf-head {
padding: 16px;
display: flex;
gap: 10px;
border-bottom: 1px solid #e7eaf1;
}
.pdf-body,
.ldf-body,
.ldf-footer {
padding: 16px;
}
@media (max-width: 900px) {
#detail-panel {
top: auto;
left: 10px;
right: 10px;
bottom: 10px;
width: auto;
max-height: 70vh;
}
}
</style>
</head>
<body>
<div id="map"></div>
<div id="toast-wrap"></div>
<div
id="modal-login"
style="
display: none;
position: fixed;
inset: 0;
z-index: 99999;
background: rgba(241, 245, 249, 0.45);
backdrop-filter: blur(10px);
justify-content: flex-end;
align-items: stretch;
"
>
<div
style="
width: 100%;
max-width: 420px;
background: #fff;
box-shadow: -10px 0 40px rgba(0, 0, 0, 0.08);
display: flex;
flex-direction: column;
padding: 48px 40px;
overflow: auto;
"
>
<div style="margin-bottom: 40px; text-align: right">
<div
style="
color: var(--lumina-primary);
font-weight: 800;
margin-bottom: 20px;
"
>
<i class="fa-solid fa-map-location-dot"></i> Portal Petugas
</div>
<h1 style="margin: 0 0 12px; font-size: 30px; line-height: 1.15">
Masuk ke<br />Sistem GeoPoverty
</h1>
<p
style="margin: 0; color: var(--lumina-text-muted); line-height: 1.6"
>
Masukkan kredensial Anda untuk mengakses data kemiskinan dan sosial
Kota Pontianak.
</p>
</div>
<form
id="form-login"
onsubmit="window.doLogin(event)"
style="display: flex; flex-direction: column; gap: 16px"
>
<div class="field">
<label class="field-label">Username</label>
<input
type="text"
id="login-username"
placeholder="Masukkan username"
autocomplete="username"
required
/>
</div>
<div class="field">
<label class="field-label">Password</label>
<div style="position: relative; display: flex; align-items: center;">
<input
type="password"
id="login-password"
placeholder="Masukkan password"
autocomplete="current-password"
style="width: 100%; padding-right: 40px; margin-bottom: 0;"
required
/>
<button
type="button"
onclick="togglePassword()"
style="position: absolute; right: 10px; background: none; border: none; cursor: pointer; color: var(--lumina-text-muted);"
>
<i class="fa-solid fa-eye" id="login-password-eye"></i>
</button>
</div>
</div>
<div
id="login-error"
style="
display: none;
color: #ef4444;
font-size: 13px;
text-align: right;
"
></div>
<button
type="submit"
id="btn-submit-login"
class="btn btn-primary"
style="width: 100%; height: 50px; font-size: 15px; margin-top: 8px;"
>
Masuk Sekarang <i class="fa-solid fa-arrow-right"></i>
</button>
</form>
<div style="margin-top: auto; padding-top: 42px">
<div
style="
display: flex;
align-items: center;
gap: 10px;
color: #727b90;
font-size: 12px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 16px;
"
>
<span style="height: 1px; background: #e7eaf1; flex: 1"></span>
Pelaporan Warga
<span style="height: 1px; background: #e7eaf1; flex: 1"></span>
</div>
<button
type="button"
onclick="window.openLaporanPublikModal(null, null)"
class="btn"
style="
width: 100%;
height: 54px;
background: #fff0f0;
color: #ef4444;
border-color: #fecaca;
"
>
<i class="fa-solid fa-triangle-exclamation"></i> Lapor Kondisi
Darurat
</button>
</div>
</div>
</div>
<nav class="lumina-navbar">
<!-- Brand -->
<a href="#" class="lumina-brand">
<div class="lumina-brand-icon">
<i class="fa-solid fa-map-location-dot"></i>
</div>
Admin GeoPoverty
</a>
<!-- Center Nav Buttons - always visible -->
<div id="nav-menus" style="display: flex; align-items: center; gap: 6px; margin-left: 12px;">
<button
class="nav-btn nav-btn-data"
id="nav-btn-data"
onclick="
document.getElementById('sidebar').style.display = 'flex';
if (window.filterSidebar) window.filterSidebar('semua');
"
>
<i class="fa-solid fa-folder-open"></i> Data
</button>
</div>
<!-- Right Actions -->
<div class="lumina-nav-right">
<button
class="lumina-btn-primary danger"
id="btn-lapor-kondisi-nav"
onclick="window.openLaporanPublikModal(null, null)"
>
<i class="fa-solid fa-triangle-exclamation"></i> Lapor Kondisi
</button>
<div id="auth-area" style="display: flex; align-items: center; gap: 8px;"></div>
</div>
</nav>
<aside class="lumina-sidebar">
<!-- Mode Toggle -->
<div class="lumina-sidebar-top">
<button
class="lumina-btn-primary"
id="luminaModeView"
style="flex: 1; justify-content: center;"
onclick="setMode('view')"
>
<i class="fa-solid fa-eye"></i> Lihat
</button>
<button
class="lumina-btn-primary secondary"
id="luminaModeEdit"
style="flex: 1; justify-content: center;"
onclick="setMode('edit')"
>
<i class="fa-solid fa-pen"></i> Edit
</button>
</div>
<!-- Scrollable Menu -->
<div class="lumina-menu">
<!-- Pencarian Cepat -->
<div class="lumina-menu-section-label">Pencarian Cepat</div>
<div style="padding: 4px 14px 8px; position: relative">
<i
class="fa-solid fa-magnifying-glass"
style="position: absolute; left: 28px; top: 50%; transform: translateY(-50%); color: var(--lumina-text-muted); font-size: 12px;"
></i>
<input
type="text"
id="map-search-input"
placeholder="Cari nama warga / masjid..."
style="width: 100%; padding: 10px 10px 10px 36px; border: 1px solid var(--border); border-radius: 8px; font-size: 13px; font-family: inherit; background: #f8fafc; color: var(--lumina-text);"
onkeyup="if (window.searchMapData) window.searchMapData(this.value);"
/>
</div>
<!-- Alat Peta -->
<div class="lumina-menu-section-label">Alat Peta</div>
<div
class="lumina-menu-item active"
id="menu-tambah-keluarga"
onclick="setDataType('kemiskinan'); setActiveMenu(this);"
>
<i class="fa-solid fa-location-crosshairs"></i> Tambah Keluarga
</div>
<div
class="lumina-menu-item"
id="menu-tambah-ibadah"
onclick="setDataType('masjid'); setActiveMenu(this);"
>
<i class="fa-solid fa-location-crosshairs"></i> Tambah Rumah Ibadah
</div>
<!-- Visibilitas Layer -->
<div class="lumina-menu-section-label">Visibilitas Layer</div>
<div
class="lumina-menu-item active"
onclick="setLayerVisibility('kemiskinan', !appState.layerVisibility.kemiskinan); this.classList.toggle('active');"
>
<i class="fa-solid fa-layer-group"></i> Layer Keluarga
</div>
<div
class="lumina-menu-item active"
onclick="setLayerVisibility('masjid', !appState.layerVisibility.masjid); this.classList.toggle('active');"
>
<i class="fa-solid fa-layer-group"></i> Layer Rumah Ibadah
</div>
<!-- Fitur Lanjut -->
<div class="lumina-menu-section-label">Fitur Lanjut Analisis</div>
<div
class="lumina-menu-item"
id="btn-toggle-heatmap"
onclick="if (window.toggleHeatmap) window.toggleHeatmap(this);"
>
<i class="fa-solid fa-fire"></i> Mode Peta Panas
</div>
<div
id="desc-heatmap"
style="display: none; font-size: 10px; color: var(--lumina-text-muted); padding: 0 14px 10px 42px; line-height: 1.4;"
>
Tampilkan area terpadat yang belum tersentuh bantuan.
</div>
<div
class="lumina-menu-item"
id="btn-toggle-routing"
onclick="if (window.toggleRoutingMode) window.toggleRoutingMode(this);"
>
<i class="fa-solid fa-route"></i> Simulasi Rute
</div>
<div
id="desc-routing"
style="display: none; font-size: 10px; color: var(--lumina-text-muted); padding: 0 14px 10px 42px; line-height: 1.4;"
>
Gambar rute jalan raya otomatis antara posko dan rumah tujuan.
</div>
<!-- Ekspor Data -->
<div class="lumina-menu-section-label">Ekspor Data</div>
<div class="lumina-menu-item" onclick="window.downloadMapPDF()">
<i class="fa-solid fa-print"></i> Cetak Peta (PDF)
</div>
<div
class="lumina-menu-item"
onclick="if (window.exportToCSV) window.exportToCSV();"
>
<i class="fa-solid fa-file-excel"></i> Unduh Data (CSV)
</div>
<!-- Legenda Peta -->
<div class="lumina-menu-section-label">Legenda Peta</div>
<div class="lumina-legend">
<div class="lumina-legend-item">
<span class="lumina-legend-dot" style="background: #16a34a;"></span>
Terjangkau bantuan
</div>
<div class="lumina-legend-item">
<span class="lumina-legend-dot" style="background: #dc2626;"></span>
Perlu bantuan (Luar area)
</div>
<div class="lumina-legend-item">
<span class="lumina-legend-dot" style="background: #7c3aed;"></span>
Lokasi Rumah Ibadah
</div>
</div>
</div><!-- end lumina-menu -->
</aside>
<!-- ── STATS PANEL: floating card over map ── -->
<div class="lumina-stats" id="stats-panel">
<div class="stat-title">
<div><i class="fa-solid fa-chart-pie"></i> Statistik Wilayah</div>
<button
id="btn-toggle-stats"
onclick="
var b = document.getElementById('stats-body');
b.style.display = b.style.display === 'none' ? 'block' : 'none';
"
><i class="fa-solid fa-chevron-down"></i></button>
</div>
<div id="stats-body">
<div class="stat-sub-label">
Keluarga Terjangkau <span id="stat-progress-text">0%</span>
</div>
<div class="stat-progress-bar">
<div class="stat-progress-fill" id="stat-progress-fill" style="width: 0%"></div>
</div>
<div class="stat-grid">
<div>
<div class="stat-item-val" id="stat-total-keluarga">0</div>
<div class="stat-item-lbl">Total Keluarga</div>
</div>
<div>
<div class="stat-item-val" id="stat-total-jiwa">0</div>
<div class="stat-item-lbl">Total Jiwa</div>
</div>
</div>
<div class="stat-grid">
<div>
<div class="stat-item-val error" id="stat-perlu-bantuan">0</div>
<div class="stat-item-lbl">Perlu Bantuan</div>
</div>
<div>
<div class="stat-item-val" id="stat-keluarga-mentas" style="color: #10b981">0</div>
<div class="stat-item-lbl">Sudah Mentas</div>
</div>
</div>
<hr class="stat-divider" />
<div class="stat-ibadah-label">Distribusi Rumah Ibadah</div>
<div class="stat-ibadah-row">
<div>🕌<b id="stat-masjid">0</b>Masjid</div>
<div><b id="stat-gereja">0</b>Gereja</div>
<div>🛕<b id="stat-vihara">0</b>Vihara</div>
</div>
</div>
</div>
<div id="sidebar">
<div class="sidebar-head">
<div class="sidebar-head-title" id="sidebar-title">
<i class="fa-solid fa-folder-open"></i> Manajemen Data
</div>
<button
class="lumina-icon-btn"
onclick="document.getElementById('sidebar').style.display = 'none'"
><i class="fa-solid fa-xmark"></i></button>
</div>
<div class="sidebar-filter">
<button class="lumina-btn-filter active" id="filter-btn-semua" onclick="window.filterSidebar('semua')">Semua</button>
<button class="lumina-btn-filter" id="filter-btn-kemiskinan" onclick="window.filterSidebar('kemiskinan')">Keluarga</button>
<button class="lumina-btn-filter" id="filter-btn-masjid" onclick="window.filterSidebar('masjid')">Rumah Ibadah</button>
</div>
<div class="sidebar-head-sub" id="sidebar-sub">Menampilkan semua data</div>
<div class="sidebar-scroll" id="sidebar-body">
<div class="loading">Memuat data dari server...</div>
</div>
</div>
<div id="notif-panel" style="display: none; position: fixed; top: calc(var(--navbar-h) + 10px); left: calc(var(--sidebar-left-w) + 14px); z-index: 2000; width: 300px; padding: 14px; background: #fff; border-radius: 10px; border: 1px solid var(--lumina-outline); box-shadow: var(--lumina-shadow);">
<div style="display: flex; justify-content: space-between; font-weight: 800; margin-bottom: 8px;">
<span style="color: var(--lumina-error); font-size: 13px;"><i class="fa-solid fa-bell"></i> Peringatan Darurat</span>
<button onclick="document.getElementById('notif-panel').style.display = 'none'" style="border: 0; background: none; cursor: pointer;"><i class="fa-solid fa-xmark"></i></button>
</div>
<div id="notif-body" style="font-size: 12px; margin-bottom: 10px;"></div>
<button class="lumina-btn-primary" onclick="window.openLaporanPanel(); document.getElementById('notif-panel').style.display = 'none';" style="width: 100%;">Buka Laporan</button>
</div>
<div id="routing-instruction-panel" style="display: none; position: fixed; top: calc(var(--navbar-h) + 10px); left: calc(var(--sidebar-left-w) + 14px); z-index: 1000; width: 280px; padding: 14px; background: #fff; border-radius: 10px; border-left: 4px solid var(--lumina-primary); border-top: 1px solid var(--lumina-outline); border-right: 1px solid var(--lumina-outline); border-bottom: 1px solid var(--lumina-outline); box-shadow: var(--lumina-shadow);">
<div style="font-weight: 800; color: var(--lumina-primary); margin-bottom: 10px; font-size: 13px;"><i class="fa-solid fa-route"></i> Navigasi Distribusi</div>
<div id="routing-instruction-text" style="font-size: 12px; line-height: 1.5;"></div>
<button class="lumina-btn-primary" style="background: var(--lumina-error); margin-top: 12px; width: 100%;" onclick="if (window.cancelRouting) window.cancelRouting();">Tutup Mode Rute</button>
</div>
<div id="detail-panel">
<div class="dp-head">
<div class="dp-head-row">
<div>
<div class="dp-title" id="detail-panel-nama">-</div>
<div class="dp-addr" id="detail-panel-alamat">-</div>
</div>
<button class="dp-close" onclick="window.closeDetailPanel()">
</button>
</div>
<div id="detail-status-banner" class="dp-status aktif">Aktif</div>
</div>
<div class="dp-tabs">
<button
class="dp-tab active"
id="tab-btn-anggota"
onclick="window.switchDetailTab('anggota')"
>
Anggota</button
><button
class="dp-tab"
id="tab-btn-bantuan"
onclick="window.switchDetailTab('bantuan')"
>
Bantuan</button
><button
class="dp-tab"
id="tab-btn-laporan-detail"
onclick="window.switchDetailTab('laporan-detail')"
>
Laporan
</button>
</div>
<div id="detail-tab-anggota" class="dp-content"></div>
<div id="detail-tab-bantuan" class="dp-content hidden"></div>
<div id="detail-tab-laporan-detail" class="dp-content hidden"></div>
<div class="dp-foot" id="detail-actions-bar"></div>
</div>
<div id="panel-pesan" class="lumina-panel-right" style="display: none">
<div class="sidebar-head">
<div class="sidebar-head-title">
<i class="fa-regular fa-comments" style="margin-right: 8px"></i>
Komunikasi Pengurus
</div>
<button class="modal-close" onclick="window.closePesanPanel()">
</button>
</div>
<div class="sidebar-scroll" id="pesan-list-container">
<div class="loading">Memuat pesan...</div>
</div>
<div class="panel-compose">
<div class="panel-compose-title">Kirim Pesan</div>
<form id="form-pesan" onsubmit="window.submitPesan(event)">
<select id="pesan-jenis">
<option value="koordinasi">Koordinasi</option>
<option value="permintaan_bantuan">Permintaan Bantuan</option>
<option value="pengumuman">Pengumuman</option></select
><input
type="text"
id="pesan-judul"
placeholder="Judul pesan..."
required
/><textarea
id="pesan-isi"
rows="3"
placeholder="Isi pesan..."
required
></textarea
><button
type="submit"
class="btn btn-primary"
id="btn-submit-pesan"
style="width: 100%"
>
Kirim Pesan
</button>
</form>
</div>
</div>
<div id="panel-laporan" class="lumina-panel-right" style="display: none">
<div class="sidebar-head">
<div class="sidebar-head-title">
<i
class="fa-solid fa-triangle-exclamation"
style="margin-right: 8px"
></i>
Manajemen Laporan
</div>
<button class="modal-close" onclick="window.closeLaporanPanel()">
</button>
</div>
<div style="padding: 0 24px 12px">
<select
id="laporan-filter-status"
onchange="window.loadLaporan(this.value)"
style="
width: 100%;
padding: 8px;
border-radius: 8px;
border: 1px solid var(--lumina-outline);
"
>
<option value="">Semua Status</option>
<option value="menunggu">Menunggu</option>
<option value="diproses">Diproses</option>
<option value="selesai">Selesai</option>
<option value="ditolak">Ditolak</option>
</select>
</div>
<div class="sidebar-scroll" id="laporan-list-container">
<div class="loading">Memuat laporan...</div>
</div>
</div>
<div id="pesan-detail-float">
<div class="pdf-accent-bar" id="pdf-accent-bar"></div>
<div class="pdf-head">
<div id="pdf-icon">💬</div>
<div style="flex: 1">
<div id="pdf-title" style="font-weight: 800">Detail Pesan</div>
<div id="pdf-subtitle" style="font-size: 12px; color: #727b90"></div>
</div>
<button class="pdf-close" id="pdf-close"></button>
</div>
<div class="pdf-body">
<div id="pdf-isi"></div>
<div id="pdf-pengirim"></div>
<div id="pdf-role"></div>
<div id="pdf-jenis-label"></div>
<div id="pdf-row-broadcast" style="display: none">
<span class="pdf-broadcast-badge">Broadcast ke semua</span>
</div>
<div id="pdf-waktu"></div>
<div id="pdf-row-baru" style="display: none">
<span class="pdf-badge-baru">Pesan Baru</span>
</div>
</div>
</div>
<div id="laporan-detail-float">
<div id="ldf-status-bar"></div>
<div class="ldf-head">
<div id="ldf-icon">🚨</div>
<div style="flex: 1">
<div id="ldf-title" style="font-weight: 800">Detail Laporan</div>
<div id="ldf-subtitle" style="font-size: 12px; color: #727b90"></div>
</div>
<button class="ldf-close" id="ldf-close"></button>
</div>
<div class="ldf-body">
<div id="ldf-deskripsi"></div>
<div id="ldf-section-kk" style="display: none">
<span id="ldf-kk-badge"></span>
</div>
<div id="ldf-pelapor"></div>
<div id="ldf-row-wa" style="display: none">
<span id="ldf-wa"></span>
</div>
<div id="ldf-waktu"></div>
<div id="ldf-row-ditangani" style="display: none">
<span id="ldf-ditangani"></span>
</div>
</div>
<div class="ldf-footer" id="ldf-footer" style="display: none"></div>
</div>
<div id="modal-kemiskinan" class="modal-bg" style="display: none">
<div class="modal-card">
<div class="modal-top">
<div class="modal-icon-wrap modal-icon-amber">📍</div>
<div>
<div class="modal-title">Tambah Keluarga Prasejahtera</div>
<div class="modal-subtitle">
Isi data keluarga untuk titik yang dipilih.
</div>
</div>
<button class="modal-close" onclick="window.closeModal('kemiskinan')">
</button>
</div>
<div class="modal-body">
<div class="field-row">
<div class="field">
<label class="field-label"
>Latitude <span class="req">*</span></label
><input id="kem-lat" required />
</div>
<div class="field">
<label class="field-label"
>Longitude <span class="req">*</span></label
><input id="kem-lng" required />
</div>
</div>
<div class="field">
<label class="field-label"
>Nama Kepala Keluarga <span class="req">*</span></label
><input id="kem-nama" required />
</div>
<div class="field">
<label class="field-label"
>Jumlah Anggota Keluarga <span class="req">*</span></label
><input type="number" id="kem-jumlah" min="1" required />
</div>
<div class="field">
<label class="field-label"
>Alamat Lengkap <span class="req">*</span></label
><textarea id="kem-alamat" rows="3" required></textarea>
</div>
<div class="field">
<label class="field-label">Status Keluarga</label
><select id="kem-status">
<option value="aktif">Aktif</option>
<option value="meninggal">Meninggal</option>
<option value="pindah">Pindah</option>
<option value="sudah_mampu">Sudah Mampu</option>
</select>
</div>
<div class="modal-footer">
<button class="btn" onclick="window.closeModal('kemiskinan')">
Batal</button
><button
class="btn btn-primary"
id="btn-submit-kemiskinan"
onclick="window._submitKemiskinanBtn()"
>
Simpan
</button>
</div>
</div>
</div>
</div>
<div id="modal-masjid" class="modal-bg" style="display: none">
<div class="modal-card">
<div class="modal-top">
<div class="modal-icon-wrap modal-icon-blue">🏛️</div>
<div>
<div class="modal-title">Tambah Rumah Ibadah</div>
<div class="modal-subtitle">
Masjid, Gereja, Vihara, Pura, dan lainnya.
</div>
</div>
<button class="modal-close" onclick="window.closeModal('masjid')">
</button>
</div>
<div class="modal-body">
<div class="field-row">
<div class="field">
<label class="field-label"
>Latitude <span class="req">*</span></label
><input id="msj-lat" required />
</div>
<div class="field">
<label class="field-label"
>Longitude <span class="req">*</span></label
><input id="msj-lng" required />
</div>
</div>
<div class="field">
<label class="field-label">Jenis Rumah Ibadah</label
><select id="msj-jenis">
<option value="masjid">Masjid</option>
<option value="gereja">Gereja</option>
<option value="vihara">Vihara</option>
<option value="pura">Pura</option>
<option value="klenteng">Klenteng</option>
<option value="kapel">Kapel</option>
<option value="lainnya">Lainnya</option>
</select>
</div>
<div class="field">
<label class="field-label"
>Nama Rumah Ibadah <span class="req">*</span></label
><input id="msj-nama" required />
</div>
<div class="field">
<label class="field-label"
>PIC / Pengurus <span class="req">*</span></label
><input id="msj-pic" required />
</div>
<div class="field">
<label class="field-label"
>Alamat Lengkap <span class="req">*</span></label
><textarea id="msj-alamat" rows="3" required></textarea>
</div>
<div class="field">
<label class="field-label">Radius Layanan</label
><input
type="number"
id="msj-radius"
min="100"
max="5000"
value="500"
/>
</div>
<div class="modal-footer">
<button class="btn" onclick="window.closeModal('masjid')">
Batal</button
><button
class="btn btn-primary"
id="btn-submit-masjid"
onclick="window._submitMasjidBtn()"
>
Simpan
</button>
</div>
</div>
</div>
</div>
<div id="modal-edit-kemiskinan" class="modal-bg" style="display: none">
<div class="modal-card">
<div class="modal-top">
<div class="modal-icon-wrap modal-icon-purple">✏️</div>
<div>
<div class="modal-title">Edit Data Keluarga</div>
<div class="modal-subtitle">
Perbarui informasi keluarga prasejahtera.
</div>
</div>
<button
class="modal-close"
onclick="window.closeModal('edit-kemiskinan')"
>
</button>
</div>
<div class="modal-body">
<input type="hidden" id="edit-kem-id" />
<div class="field">
<label class="field-label">Nama Kepala Keluarga</label
><input id="edit-kem-nama" required />
</div>
<div class="field">
<label class="field-label">Jumlah Anggota</label
><input type="number" id="edit-kem-jumlah" min="1" required />
</div>
<div class="field">
<label class="field-label">Alamat</label
><textarea id="edit-kem-alamat" rows="3" required></textarea>
</div>
<div class="field">
<label class="field-label">Status</label
><select id="edit-kem-status">
<option value="aktif">Aktif</option>
<option value="meninggal">Meninggal</option>
<option value="pindah">Pindah</option>
<option value="sudah_mampu">Sudah Mampu</option>
</select>
</div>
<div class="modal-footer">
<button class="btn" onclick="window.closeModal('edit-kemiskinan')">
Batal</button
><button
class="btn btn-primary"
id="btn-submit-edit-kemiskinan"
onclick="window._submitEditKemiskinanBtn()"
>
Simpan Perubahan
</button>
</div>
</div>
</div>
</div>
<div id="modal-edit-masjid" class="modal-bg" style="display: none">
<div class="modal-card">
<div class="modal-top">
<div class="modal-icon-wrap modal-icon-purple">✏️</div>
<div>
<div class="modal-title">Edit Rumah Ibadah</div>
<div class="modal-subtitle">Perbarui informasi rumah ibadah.</div>
</div>
<button
class="modal-close"
onclick="window.closeModal('edit-masjid')"
>
</button>
</div>
<div class="modal-body">
<input type="hidden" id="edit-msj-id" />
<div class="field">
<label class="field-label">Jenis Rumah Ibadah</label
><select id="edit-msj-jenis">
<option value="masjid">Masjid</option>
<option value="gereja">Gereja</option>
<option value="vihara">Vihara</option>
<option value="pura">Pura</option>
<option value="klenteng">Klenteng</option>
<option value="kapel">Kapel</option>
<option value="lainnya">Lainnya</option>
</select>
</div>
<div class="field">
<label class="field-label">Nama Rumah Ibadah</label
><input id="edit-msj-nama" required />
</div>
<div class="field">
<label class="field-label">PIC / Pengurus</label
><input id="edit-msj-pic" required />
</div>
<div class="field">
<label class="field-label">Alamat</label
><textarea id="edit-msj-alamat" rows="3" required></textarea>
</div>
<div class="modal-footer">
<button class="btn" onclick="window.closeModal('edit-masjid')">
Batal</button
><button
class="btn btn-primary"
id="btn-submit-edit-masjid"
onclick="window._submitEditMasjidBtn()"
>
Simpan Perubahan
</button>
</div>
</div>
</div>
</div>
<div id="modal-anggota" class="modal-bg" style="display: none">
<div class="modal-card">
<div class="modal-top">
<div class="modal-icon-wrap modal-icon-blue">👤</div>
<div>
<div class="modal-title" id="modal-anggota-title">
Tambah Anggota
</div>
<div class="modal-subtitle">Data individu anggota keluarga.</div>
</div>
<button
class="modal-close"
onclick="
document.getElementById('modal-anggota').style.display = 'none'
"
>
</button>
</div>
<div class="modal-body">
<input type="hidden" id="anggota-kem-id" /><input
type="hidden"
id="anggota-edit-id"
/>
<div class="field">
<label class="field-label">Nama Lengkap</label
><input id="anggota-nama" required />
</div>
<div class="field-row">
<div class="field">
<label class="field-label">Hubungan</label
><select id="anggota-hubungan">
<option value="kepala_keluarga">Kepala Keluarga</option>
<option value="istri">Istri</option>
<option value="anak">Anak</option>
<option value="orang_tua">Orang Tua</option>
<option value="saudara">Saudara</option>
<option value="lainnya">Lainnya</option>
</select>
</div>
<div class="field">
<label class="field-label">Jenis Kelamin</label
><select id="anggota-jk">
<option value="laki_laki">Laki-laki</option>
<option value="perempuan">Perempuan</option>
</select>
</div>
</div>
<div class="field">
<label class="field-label">Tanggal Lahir</label
><input type="date" id="anggota-tgl-lahir" />
</div>
<div id="anggota-saran" class="saran-box" style="display: none"></div>
<div class="field-row">
<div class="field">
<label class="field-label">Pendidikan</label
><select id="anggota-pendidikan">
<option value="belum_sekolah">Belum Sekolah</option>
<option value="paud">PAUD</option>
<option value="sd">SD</option>
<option value="smp">SMP</option>
<option value="sma">SMA</option>
<option value="kuliah">Kuliah</option>
<option value="pesantren">Pesantren</option>
<option value="pelatihan">Pelatihan</option>
<option value="bekerja">Bekerja</option>
<option value="tidak_sekolah">Tidak Sekolah</option>
</select>
</div>
<div class="field">
<label class="field-label">Status Hidup</label
><select id="anggota-status">
<option value="hidup">Hidup</option>
<option value="meninggal">Meninggal</option>
<option value="pindah">Pindah</option>
<option value="menikah_keluar">Menikah Keluar</option>
</select>
</div>
</div>
<div class="field">
<label class="field-label">Catatan Kondisi</label
><textarea id="anggota-catatan" rows="2"></textarea>
</div>
<div class="modal-footer">
<button
class="btn"
onclick="
document.getElementById('modal-anggota').style.display = 'none'
"
>
Batal</button
><button class="btn btn-primary" id="btn-submit-anggota">
Simpan
</button>
</div>
</div>
</div>
</div>
<div id="modal-bantuan" class="modal-bg" style="display: none">
<div class="modal-card">
<div class="modal-top">
<div class="modal-icon-wrap modal-icon-green">📦</div>
<div>
<div class="modal-title" id="modal-bantuan-title">
Catat Bantuan
</div>
<div class="modal-subtitle">
Rekam bantuan yang diberikan ke keluarga ini.
</div>
</div>
<button
class="modal-close"
onclick="
document.getElementById('modal-bantuan').style.display = 'none'
"
>
</button>
</div>
<div class="modal-body">
<input type="hidden" id="bantuan-kem-id" />
<div class="field-row">
<div class="field">
<label class="field-label">Jenis Bantuan</label
><select id="bantuan-jenis">
<option value="sembako">Sembako</option>
<option value="uang">Uang</option>
<option value="pendidikan">Pendidikan</option>
<option value="kesehatan">Kesehatan</option>
<option value="pakaian">Pakaian</option>
<option value="pelatihan">Pelatihan</option>
<option value="lainnya">Lainnya</option>
</select>
</div>
<div class="field">
<label class="field-label">Status</label
><select id="bantuan-status">
<option value="belum">Belum</option>
<option value="tersalur">Tersalur</option>
<option value="batal">Batal</option>
</select>
</div>
</div>
<div class="field">
<label class="field-label">Deskripsi</label
><textarea id="bantuan-deskripsi" rows="2" required></textarea>
</div>
<div class="field-row">
<div class="field">
<label class="field-label">Jumlah</label
><input type="number" id="bantuan-jumlah" step="0.01" />
</div>
<div class="field">
<label class="field-label">Satuan</label
><input id="bantuan-satuan" />
</div>
</div>
<div class="field-row">
<div class="field">
<label class="field-label">Tanggal Bantuan</label
><input type="date" id="bantuan-tanggal" />
</div>
<div class="field">
<label class="field-label">Periode Berikutnya</label
><input type="date" id="bantuan-periode" />
</div>
</div>
<div class="field">
<label class="field-label">Dicatat oleh</label
><input id="bantuan-dicatat" />
</div>
<div class="modal-footer">
<button
class="btn"
onclick="
document.getElementById('modal-bantuan').style.display = 'none'
"
>
Batal</button
><button class="btn btn-primary" id="btn-submit-bantuan">
Simpan Bantuan
</button>
</div>
</div>
</div>
</div>
<div
id="modal-laporan-publik"
class="modal-bg"
style="display: none; z-index: 100000"
>
<div class="modal-card">
<div class="modal-top">
<div class="modal-icon-wrap modal-icon-red">🚨</div>
<div>
<div class="modal-title" id="laporan-judul-kkname">
Laporkan Kondisi Warga
</div>
<div class="modal-subtitle">
Siapa saja dapat melapor · Tidak perlu login
</div>
</div>
<button
class="modal-close"
onclick="
document.getElementById('modal-laporan-publik').style.display =
'none'
"
>
</button>
</div>
<div class="modal-body">
<input type="hidden" id="laporan-kem-id" />
<div class="field-row">
<div class="field">
<label class="field-label">Nama Pelapor <span class="req">*</span></label>
<input
id="laporan-nama-pelapor"
required
placeholder="Nama lengkap pelapor"
/>
</div>
<div class="field">
<label class="field-label">No. WhatsApp</label>
<input
type="tel"
id="laporan-nomor-wa"
placeholder="08xxxxxxxxxx"
/>
</div>
</div>
<div class="field">
<label class="field-label">Kategori <span class="req">*</span></label>
<select id="laporan-kategori">
<option value="sakit">🏥 Sakit / Butuh Bantuan Medis</option>
<option value="kematian">🕊️ Kematian</option>
<option value="kelahiran">👶 Kelahiran Bayi Baru</option>
<option value="pernikahan">💍 Pernikahan</option>
<option value="pindah">🏠 Pindah Tempat</option>
<option value="darurat_ekonomi">💸 Darurat Ekonomi</option>
<option value="lainnya" selected>📋 Lainnya</option>
</select>
</div>
<div class="field">
<label class="field-label">Deskripsi Kondisi <span class="req">*</span></label>
<textarea
id="laporan-deskripsi"
rows="4"
required
placeholder="Jelaskan kondisi yang perlu dilaporkan secara singkat dan jelas..."
></textarea>
</div>
<div class="modal-footer">
<button
class="btn"
onclick="document.getElementById('modal-laporan-publik').style.display = 'none'"
>Batal</button>
<button
class="btn btn-send"
id="btn-submit-laporan"
onclick="window._submitLaporanBtn()"
>✉️ Kirim Laporan</button>
</div>
</div>
</div>
</div>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet.heat/dist/leaflet-heat.js"></script>
<script src="https://unpkg.com/leaflet-routing-machine@latest/dist/leaflet-routing-machine.js"></script>
<script src="https://unpkg.com/sweetalert2@11"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="js/map.js"></script>
<script src="js/auth.js"></script>
<script src="js/anggota.js"></script>
<script src="js/bantuan.js"></script>
<script src="js/laporan.js"></script>
<script src="js/pesan.js"></script>
<script src="js/loadData.js"></script>
<script>
window._submitKemiskinanBtn = function () {
if (window._submitKemiskinan) window._submitKemiskinan();
};
window._submitMasjidBtn = function () {
if (window._submitMasjid) window._submitMasjid();
};
window._submitEditKemiskinanBtn = function () {
if (window._submitEditKemiskinan) window._submitEditKemiskinan();
};
window._submitEditMasjidBtn = function () {
if (window._submitEditMasjid) window._submitEditMasjid();
};
if (!window._submitLaporanBtn && window.submitLaporanPublik) {
window._submitLaporanBtn = function () {
window.submitLaporanPublik();
};
}
document.addEventListener("click", function (e) {
if (e.target && e.target.id === "pdf-close")
document.getElementById("pesan-detail-float").style.display = "none";
if (e.target && e.target.id === "ldf-close")
document.getElementById("laporan-detail-float").style.display =
"none";
});
</script>
</body>
</html>