This commit is contained in:
envicy
2026-06-11 22:29:16 +07:00
parent 503e9421a9
commit ce26f9fac6
15 changed files with 1933 additions and 2015 deletions
@@ -1,196 +0,0 @@
<?php
header('Content-Type: application/json; charset=UTF-8');
require_once '../auth_helper.php';
requireLogin();
include_once '../db_connect.php';
$user = getCurrentUser();
$isPengelola = $user['role'] === 'pengelola';
$ibadahId = $isPengelola ? intval($user['ibadah_id']) : null;
// ── Helper: Haversine distance in meters ──────────────────────────────────
function haversine($lat1, $lng1, $lat2, $lng2) {
$R = 6371000;
$dLat = deg2rad($lat2 - $lat1);
$dLng = deg2rad($lng2 - $lng1);
$a = sin($dLat/2)*sin($dLat/2)
+ cos(deg2rad($lat1))*cos(deg2rad($lat2))*sin($dLng/2)*sin($dLng/2);
return $R * 2 * atan2(sqrt($a), sqrt(1-$a));
}
// ── 1. Rumah Ibadah ───────────────────────────────────────────────────────
if ($isPengelola && $ibadahId) {
$riRes = $conn->query("SELECT * FROM rumah_ibadah WHERE id=$ibadahId");
} else {
$riRes = $conn->query("SELECT * FROM rumah_ibadah");
}
$ibadahList = [];
while ($row = $riRes->fetch_assoc()) $ibadahList[] = $row;
$totalIbadah = count($ibadahList);
// Distribusi per jenis
$jenisDist = [];
foreach ($ibadahList as $ib) {
$j = $ib['jenis'] ?? 'Lainnya';
$jenisDist[$j] = ($jenisDist[$j] ?? 0) + 1;
}
// ── 2. Penduduk Miskin ────────────────────────────────────────────────────
$pmRes = $conn->query("SELECT * FROM penduduk_miskin");
$allMiskin = [];
while ($row = $pmRes->fetch_assoc()) $allMiskin[] = $row;
// Filter: pengelola hanya lihat yang dalam radius ibadahnya
if ($isPengelola && $ibadahId && !empty($ibadahList)) {
$ib = $ibadahList[0];
$filteredMiskin = array_filter($allMiskin, function($m) use ($ib) {
return haversine((float)$ib['lat'], (float)$ib['lng'], (float)$m['lat'], (float)$m['lng']) <= (float)$ib['radius'];
});
$filteredMiskin = array_values($filteredMiskin);
} else {
$filteredMiskin = $allMiskin;
}
$totalMiskin = count($filteredMiskin);
$totalJiwa = array_sum(array_column($filteredMiskin, 'jumlah_jiwa'));
// Kategori bantuan
$kategoriDist = [];
foreach ($filteredMiskin as $m) {
$k = $m['kategori_bantuan'] ?? 'Lainnya';
$kategoriDist[$k] = ($kategoriDist[$k] ?? 0) + 1;
}
// Terurus vs Tidak (dalam radius salah satu ibadah)
$terurusCount = 0;
$tidakTerurusCount = 0;
foreach ($filteredMiskin as $m) {
$inAnyRadius = false;
foreach ($ibadahList as $ib) {
if (haversine((float)$ib['lat'], (float)$ib['lng'], (float)$m['lat'], (float)$m['lng']) <= (float)$ib['radius']) {
$inAnyRadius = true;
break;
}
}
if ($inAnyRadius) $terurusCount++;
else $tidakTerurusCount++;
}
// Jika admin: hitung seluruh miskin dalam radius seluruh ibadah
if (!$isPengelola) {
$allIbadahRes = $conn->query("SELECT * FROM rumah_ibadah");
$allIbadahList = [];
while ($row = $allIbadahRes->fetch_assoc()) $allIbadahList[] = $row;
$terurusCount = 0;
$tidakTerurusCount = 0;
foreach ($allMiskin as $m) {
$inAnyRadius = false;
foreach ($allIbadahList as $ib) {
if (haversine((float)$ib['lat'], (float)$ib['lng'], (float)$m['lat'], (float)$m['lng']) <= (float)$ib['radius']) {
$inAnyRadius = true;
break;
}
}
if ($inAnyRadius) $terurusCount++;
else $tidakTerurusCount++;
}
}
// ── 3. Log Bantuan ────────────────────────────────────────────────────────
if ($isPengelola && $ibadahId) {
$logRes = $conn->query("
SELECT lb.*, ri.nama as nama_ibadah, ri.jenis as jenis_ibadah, pm.nama as nama_kk
FROM log_bantuan lb
JOIN rumah_ibadah ri ON ri.id = lb.ibadah_id
JOIN penduduk_miskin pm ON pm.id = lb.miskin_id
WHERE lb.ibadah_id = $ibadahId
ORDER BY lb.tanggal DESC, lb.id DESC
LIMIT 10
");
$totalLogRes = $conn->query("SELECT COUNT(*) as cnt FROM log_bantuan WHERE ibadah_id=$ibadahId");
} else {
$logRes = $conn->query("
SELECT lb.*, ri.nama as nama_ibadah, ri.jenis as jenis_ibadah, pm.nama as nama_kk
FROM log_bantuan lb
JOIN rumah_ibadah ri ON ri.id = lb.ibadah_id
JOIN penduduk_miskin pm ON pm.id = lb.miskin_id
ORDER BY lb.tanggal DESC, lb.id DESC
LIMIT 10
");
$totalLogRes = $conn->query("SELECT COUNT(*) as cnt FROM log_bantuan");
}
$recentLogs = [];
while ($row = $logRes->fetch_assoc()) $recentLogs[] = $row;
$totalLog = 0;
if ($totalLogRes && $trow = $totalLogRes->fetch_assoc()) $totalLog = (int)$trow['cnt'];
// Distribusi tipe bantuan dari log
$tipeDist = [];
if ($isPengelola && $ibadahId) {
$tipeRes = $conn->query("SELECT tipe_bantuan, COUNT(*) as cnt FROM log_bantuan WHERE ibadah_id=$ibadahId GROUP BY tipe_bantuan");
} else {
$tipeRes = $conn->query("SELECT tipe_bantuan, COUNT(*) as cnt FROM log_bantuan GROUP BY tipe_bantuan");
}
while ($row = $tipeRes->fetch_assoc()) $tipeDist[$row['tipe_bantuan']] = (int)$row['cnt'];
// Bantuan per bulan (6 bulan terakhir)
if ($isPengelola && $ibadahId) {
$bulanRes = $conn->query("
SELECT DATE_FORMAT(tanggal, '%Y-%m') as bulan, COUNT(*) as cnt
FROM log_bantuan
WHERE ibadah_id=$ibadahId AND tanggal >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
GROUP BY bulan ORDER BY bulan ASC
");
} else {
$bulanRes = $conn->query("
SELECT DATE_FORMAT(tanggal, '%Y-%m') as bulan, COUNT(*) as cnt
FROM log_bantuan
WHERE tanggal >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
GROUP BY bulan ORDER BY bulan ASC
");
}
$bantuanPerBulan = [];
while ($row = $bulanRes->fetch_assoc()) $bantuanPerBulan[] = $row;
// ── 4. Ibadah Tipe (admin only: performa per ibadah) ─────────────────────
$ibadahPerforma = [];
if (!$isPengelola) {
$perfRes = $conn->query("
SELECT ri.id, ri.nama, ri.jenis, ri.radius,
COUNT(DISTINCT lb.id) as total_log,
COUNT(DISTINCT lb.miskin_id) as total_penerima
FROM rumah_ibadah ri
LEFT JOIN log_bantuan lb ON lb.ibadah_id = ri.id
GROUP BY ri.id
ORDER BY total_log DESC
");
while ($row = $perfRes->fetch_assoc()) $ibadahPerforma[] = $row;
}
// ── Output ────────────────────────────────────────────────────────────────
echo json_encode([
'status' => 'success',
'role' => $user['role'],
'ibadah_id' => $ibadahId,
'stats' => [
'total_ibadah' => $totalIbadah,
'total_miskin' => $totalMiskin,
'total_jiwa' => $totalJiwa,
'total_log' => $totalLog,
'terurus' => $terurusCount,
'tidak_terurus' => $tidakTerurusCount,
'pct_terurus' => $totalMiskin > 0 ? round($terurusCount / $totalMiskin * 100, 1) : 0,
],
'distribusi' => [
'jenis_ibadah' => $jenisDist,
'kategori' => $kategoriDist,
'tipe_bantuan' => $tipeDist,
'per_bulan' => $bantuanPerBulan,
],
'ibadah_list' => $ibadahList,
'ibadah_performa' => $ibadahPerforma,
'recent_logs' => $recentLogs,
]);
@@ -1,171 +0,0 @@
<?php
/**
* stats_extended.php
* Dashboard terintegrasi: webgis_poverty + jalan + spbu + penduduk choropleth
*/
header('Content-Type: application/json; charset=UTF-8');
require_once '../auth_helper.php';
requireLogin();
// ── Helper: buat koneksi terpisah ─────────────────────────────────────────
function makeConn($dbName) {
$c = new mysqli("localhost", "root", "", $dbName);
if ($c->connect_error) return null;
$c->set_charset("utf8mb4");
return $c;
}
// ── Koneksi ke masing-masing database ────────────────────────────────────
$connPoverty = makeConn("webgis_poverty"); // atau "webgis" sesuai db.sql
$connJalan = makeConn("jalan");
$connSpbu = makeConn("spbu");
// ── 1. Data dari webgis_poverty (kemiskinan) ─────────────────────────────
$poverty = [
'total_miskin' => 0,
'total_jiwa' => 0,
'total_ibadah' => 0,
'total_log' => 0,
'terurus' => 0,
'tidak_terurus' => 0,
'pct_terurus' => 0,
'distribusi' => ['kategori' => [], 'tipe_bantuan' => [], 'per_bulan' => []],
];
if ($connPoverty) {
// Total KK miskin & jiwa
$r = $connPoverty->query("SELECT COUNT(*) as c, COALESCE(SUM(jumlah_jiwa),0) as j FROM penduduk_miskin");
if ($r && $row = $r->fetch_assoc()) {
$poverty['total_miskin'] = (int)$row['c'];
$poverty['total_jiwa'] = (int)$row['j'];
}
// Total rumah ibadah
$r = $connPoverty->query("SELECT COUNT(*) as c FROM rumah_ibadah");
if ($r && $row = $r->fetch_assoc()) $poverty['total_ibadah'] = (int)$row['c'];
// Total log bantuan
$r = $connPoverty->query("SELECT COUNT(*) as c FROM log_bantuan");
if ($r && $row = $r->fetch_assoc()) $poverty['total_log'] = (int)$row['c'];
// Kategori bantuan
$r = $connPoverty->query("SELECT kategori_bantuan, COUNT(*) as c FROM penduduk_miskin GROUP BY kategori_bantuan");
if ($r) while ($row = $r->fetch_assoc()) $poverty['distribusi']['kategori'][$row['kategori_bantuan']] = (int)$row['c'];
// Tipe bantuan dari log
$r = $connPoverty->query("SELECT tipe_bantuan, COUNT(*) as c FROM log_bantuan GROUP BY tipe_bantuan");
if ($r) while ($row = $r->fetch_assoc()) $poverty['distribusi']['tipe_bantuan'][$row['tipe_bantuan']] = (int)$row['c'];
// Bantuan per bulan (6 bulan terakhir)
$r = $connPoverty->query("
SELECT DATE_FORMAT(tanggal,'%Y-%m') as bulan, COUNT(*) as cnt
FROM log_bantuan
WHERE tanggal >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
GROUP BY bulan ORDER BY bulan ASC
");
if ($r) while ($row = $r->fetch_assoc()) $poverty['distribusi']['per_bulan'][] = $row;
// Terurus vs tidak (radius sederhana: ada di radius salah satu ibadah)
$ibadahRes = $connPoverty->query("SELECT lat, lng, radius FROM rumah_ibadah");
$ibadahArr = [];
if ($ibadahRes) while ($row = $ibadahRes->fetch_assoc()) $ibadahArr[] = $row;
$miskinRes = $connPoverty->query("SELECT lat, lng FROM penduduk_miskin");
if ($miskinRes) {
while ($m = $miskinRes->fetch_assoc()) {
$inRadius = false;
foreach ($ibadahArr as $ib) {
$dlat = deg2rad($ib['lat'] - $m['lat']);
$dlng = deg2rad($ib['lng'] - $m['lng']);
$a = sin($dlat/2)**2 + cos(deg2rad($m['lat']))*cos(deg2rad($ib['lat']))*sin($dlng/2)**2;
$dist = 6371000 * 2 * atan2(sqrt($a), sqrt(1-$a));
if ($dist <= (float)$ib['radius']) { $inRadius = true; break; }
}
if ($inRadius) $poverty['terurus']++; else $poverty['tidak_terurus']++;
}
$tot = $poverty['total_miskin'];
$poverty['pct_terurus'] = $tot > 0 ? round($poverty['terurus'] / $tot * 100, 1) : 0;
}
$connPoverty->close();
}
// ── 2. Data Jalan ─────────────────────────────────────────────────────────
$jalan = [
'total_jalan' => 0,
'total_panjang_m' => 0,
'per_status' => [],
'total_parsil' => 0,
'total_luas_m2' => 0,
'per_kepemilikan' => [],
];
if ($connJalan) {
$r = $connJalan->query("SELECT COUNT(*) as c, COALESCE(SUM(panjang_meter),0) as p FROM jalan");
if ($r && $row = $r->fetch_assoc()) {
$jalan['total_jalan'] = (int)$row['c'];
$jalan['total_panjang_m'] = (float)$row['p'];
}
$r = $connJalan->query("SELECT status_jalan, COUNT(*) as c FROM jalan GROUP BY status_jalan");
if ($r) while ($row = $r->fetch_assoc()) $jalan['per_status'][$row['status_jalan']] = (int)$row['c'];
$r = $connJalan->query("SELECT COUNT(*) as c, COALESCE(SUM(luas_m2),0) as l FROM parsil_tanah");
if ($r && $row = $r->fetch_assoc()) {
$jalan['total_parsil'] = (int)$row['c'];
$jalan['total_luas_m2'] = (float)$row['l'];
}
$r = $connJalan->query("SELECT status_kepemilikan, COUNT(*) as c FROM parsil_tanah GROUP BY status_kepemilikan");
if ($r) while ($row = $r->fetch_assoc()) $jalan['per_kepemilikan'][$row['status_kepemilikan']] = (int)$row['c'];
$connJalan->close();
}
// ── 3. Data SPBU ──────────────────────────────────────────────────────────
$spbu = [
'total_spbu' => 0,
'buka_24_jam' => 0,
'tidak_24_jam' => 0,
'list' => [],
];
if ($connSpbu) {
$r = $connSpbu->query("SELECT COUNT(*) as c FROM spbu");
if ($r && $row = $r->fetch_assoc()) $spbu['total_spbu'] = (int)$row['c'];
$r = $connSpbu->query("SELECT SUM(buka_24_jam=1) as buka, SUM(buka_24_jam=0) as tidak FROM spbu");
if ($r && $row = $r->fetch_assoc()) {
$spbu['buka_24_jam'] = (int)$row['buka'];
$spbu['tidak_24_jam'] = (int)$row['tidak'];
}
$r = $connSpbu->query("SELECT nama_spbu, nomor_wa, buka_24_jam, latitude, longitude FROM spbu ORDER BY nama_spbu");
if ($r) while ($row = $r->fetch_assoc()) $spbu['list'][] = $row;
$connSpbu->close();
}
// ── 4. Data Penduduk (choropleth — static dari pontianak.json) ────────────
// Data kepadatan per kecamatan sudah ada di file JS, ringkasan di sini
$penduduk = [
'kecamatan' => [
['nama' => 'Pontianak Barat', 'density' => 9.331],
['nama' => 'Pontianak Kota', 'density' => 8.102],
['nama' => 'Pontianak Timur', 'density' => 9.196],
['nama' => 'Pontianak Selatan', 'density' => 5.673],
['nama' => 'Pontianak Utara', 'density' => 3.642],
['nama' => 'Pontianak Tenggara', 'density' => 3.103],
]
];
$penduduk['total_kecamatan'] = count($penduduk['kecamatan']);
$penduduk['rata_density'] = round(array_sum(array_column($penduduk['kecamatan'],'density')) / $penduduk['total_kecamatan'], 3);
$penduduk['terpadat'] = $penduduk['kecamatan'][array_search(max(array_column($penduduk['kecamatan'],'density')), array_column($penduduk['kecamatan'],'density'))]['nama'];
// ── Output ────────────────────────────────────────────────────────────────
echo json_encode([
'status' => 'success',
'poverty' => $poverty,
'jalan' => $jalan,
'spbu' => $spbu,
'penduduk' => $penduduk,
], JSON_UNESCAPED_UNICODE);
@@ -59,42 +59,34 @@ if ($currentUser && $currentUser['role'] === 'pengelola') {
}
}
if ($lat != 0 && $lng != 0) {
$upload_dir = "../../uploads/";
if (!file_exists($upload_dir)) {
mkdir($upload_dir, 0777, true);
}
// Handle file upload
$upload_dir = dirname(dirname(__DIR__)) . '/uploads/';
if (!file_exists($upload_dir)) {
mkdir($upload_dir, 0777, true);
}
$foto_rumah = null;
$foto_kk = null;
function uploadFile($fileKey, $upload_dir) {
if (isset($_FILES[$fileKey]) && $_FILES[$fileKey]['error'] === UPLOAD_ERR_OK) {
$fileTmpPath = $_FILES[$fileKey]['tmp_name'];
$fileName = $_FILES[$fileKey]['name'];
$fileNameCmps = explode(".", $fileName);
$fileExtension = strtolower(end($fileNameCmps));
$allowedfileExtensions = array('jpg', 'jpeg', 'png', 'gif');
if (in_array($fileExtension, $allowedfileExtensions)) {
$newFileName = uniqid() . '_' . preg_replace('/[^a-zA-Z0-9\._-]/', '_', $fileName);
$dest_path = $upload_dir . $newFileName;
if (move_uploaded_file($fileTmpPath, $dest_path)) {
return $newFileName;
}
function uploadFileCreate($fileKey, $upload_dir) {
if (isset($_FILES[$fileKey]) && $_FILES[$fileKey]['error'] === UPLOAD_ERR_OK) {
$fileTmpPath = $_FILES[$fileKey]['tmp_name'];
$fileName = $_FILES[$fileKey]['name'];
$fileExtension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'];
if (in_array($fileExtension, $allowedExtensions)) {
$newFileName = uniqid() . '_' . preg_replace('/[^a-zA-Z0-9\\._-]/', '_', $fileName);
if (move_uploaded_file($fileTmpPath, $upload_dir . $newFileName)) {
return $newFileName;
}
}
return null;
}
return null;
}
$foto_rumah = uploadFile('foto_rumah', $upload_dir);
$foto_kk = uploadFile('foto_kk', $upload_dir);
$val_foto_rumah = $foto_rumah ? "'$foto_rumah'" : "NULL";
$val_foto_kk = $foto_kk ? "'$foto_kk'" : "NULL";
$foto_rumah = uploadFileCreate('foto_rumah', $upload_dir);
$foto_kk = uploadFileCreate('foto_kk', $upload_dir);
$val_foto_rumah = $foto_rumah ? "'" . $conn->real_escape_string($foto_rumah) . "'" : "NULL";
$val_foto_kk = $foto_kk ? "'" . $conn->real_escape_string($foto_kk) . "'" : "NULL";
if ($lat != 0 && $lng != 0) {
$query = "INSERT INTO penduduk_miskin (nama, kategori_bantuan, jumlah_jiwa, lat, lng, foto_rumah, foto_kk)
VALUES ('$nama', '$kategori', $jumlah_jiwa, $lat, $lng, $val_foto_rumah, $val_foto_kk)";
@@ -81,7 +81,7 @@ if ($id > 0) {
$old_foto_kk = $row['foto_kk'];
}
$upload_dir = "../../uploads/";
$upload_dir = dirname(dirname(__DIR__)) . '/uploads/';
if (!file_exists($upload_dir)) {
mkdir($upload_dir, 0777, true);
}