Compare commits
2 Commits
main
..
8e136944bb
| Author | SHA1 | Date | |
|---|---|---|---|
| 8e136944bb | |||
| af2ad35c8c |
@@ -0,0 +1,14 @@
|
||||
.git
|
||||
.gitignore
|
||||
.codex
|
||||
.agents
|
||||
.env
|
||||
*.rar
|
||||
*.zip
|
||||
*.7z
|
||||
*.tar
|
||||
*.gz
|
||||
node_modules
|
||||
vendor
|
||||
*.log
|
||||
Thumbs.db
|
||||
+4
-1
@@ -1,7 +1,8 @@
|
||||
FROM php:8.2-apache
|
||||
|
||||
RUN docker-php-ext-install mysqli pdo pdo_mysql \
|
||||
&& a2enmod rewrite
|
||||
&& a2enmod rewrite \
|
||||
&& echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||
|
||||
COPY . /var/www/html/
|
||||
|
||||
@@ -12,3 +13,5 @@ RUN mkdir -p \
|
||||
/var/www/html/webgis-v3/uploads/bukti_bantuan \
|
||||
/var/www/html/webgis-v3/uploads/foto_laporan \
|
||||
&& chown -R www-data:www-data /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
+2
-2
@@ -9,10 +9,10 @@ services:
|
||||
DB_HOST: database
|
||||
DB_USER: root
|
||||
DB_PASSWORD: ${DB_ROOT_PASSWORD:-rootpassword}
|
||||
DB_CHAR: utf8mb4
|
||||
DB_NAME: webgis_kemiskinan
|
||||
SPBU_DB_NAME: db_spbu
|
||||
WEBGIS02_DB_NAME: webgis_db
|
||||
WEBGIS_V3_DB_NAME: webgis_kemiskinan
|
||||
DB_CHAR: utf8mb4
|
||||
expose:
|
||||
- "80"
|
||||
restart: unless-stopped
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
FROM php:8.2-apache
|
||||
|
||||
RUN docker-php-ext-install mysqli pdo pdo_mysql \
|
||||
&& a2enmod rewrite \
|
||||
&& echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||
|
||||
COPY . /var/www/html/
|
||||
|
||||
RUN mkdir -p \
|
||||
/var/www/html/uploads/bukti_bantuan \
|
||||
/var/www/html/uploads/foto_laporan \
|
||||
&& chown -R www-data:www-data /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
@@ -94,12 +94,10 @@ switch ($method) {
|
||||
default: jsonError('Method tidak diizinkan',405);
|
||||
}
|
||||
|
||||
if (!function_exists('jsonError')) {
|
||||
function jsonError($msg,$code=400){
|
||||
http_response_code($code);
|
||||
echo json_encode(['success'=>false,'message'=>$msg]);
|
||||
exit;
|
||||
}
|
||||
function jsonError($msg,$code=400){
|
||||
http_response_code($code);
|
||||
echo json_encode(['success'=>false,'message'=>$msg]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
define('DB_HOST', getenv('DB_HOST') ?: '127.0.0.1');
|
||||
define('DB_NAME', getenv('WEBGIS_V3_DB_NAME') ?: 'webgis_kemiskinan');
|
||||
define('DB_USER', getenv('DB_USER') ?: 'root');
|
||||
define('DB_PASS', getenv('DB_PASSWORD') !== false ? getenv('DB_PASSWORD') : '');
|
||||
define('DB_HOST', getenv('DB_HOST'));
|
||||
define('DB_NAME', getenv('DB_NAME'));
|
||||
define('DB_USER', getenv('DB_USER'));
|
||||
define('DB_PASS', getenv('DB_PASSWORD'));
|
||||
define('DB_CHAR', getenv('DB_CHAR') ?: 'utf8mb4');
|
||||
|
||||
function getDB(): PDO {
|
||||
@@ -14,43 +14,6 @@ function getDB(): PDO {
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]);
|
||||
ensureDefaultUsers($pdo);
|
||||
}
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
function ensureDefaultUsers(PDO $pdo): void {
|
||||
$stmt = $pdo->query("SHOW TABLES LIKE 'user'");
|
||||
if (!$stmt->fetch()) return;
|
||||
|
||||
$users = [
|
||||
['admin', 1, 'Administrator Sistem', 'admin@webgis-ptk.id'],
|
||||
['pengurus_jami', 2, 'Ahmad Fauzi (Masjid Jami)', 'fauzi@webgis-ptk.id'],
|
||||
['pengurus_ktdr', 2, 'Romo Benediktus (Katedral)', 'romo@webgis-ptk.id'],
|
||||
['pimpinan', 3, 'Camat Pontianak Kota', 'camat@webgis-ptk.id'],
|
||||
['warga1', 4, 'Budi Santoso', 'budi@gmail.com'],
|
||||
];
|
||||
|
||||
$select = $pdo->prepare("SELECT password_hash FROM user WHERE username = ? LIMIT 1");
|
||||
$insert = $pdo->prepare(
|
||||
"INSERT INTO user (id_role, username, password_hash, nama_lengkap, email, aktif)
|
||||
VALUES (?, ?, ?, ?, ?, 1)"
|
||||
);
|
||||
$update = $pdo->prepare(
|
||||
"UPDATE user
|
||||
SET id_role = ?, password_hash = ?, nama_lengkap = ?, email = ?, aktif = 1
|
||||
WHERE username = ?"
|
||||
);
|
||||
|
||||
foreach ($users as [$username, $roleId, $name, $email]) {
|
||||
$select->execute([$username]);
|
||||
$row = $select->fetch();
|
||||
$hash = password_hash('admin123', PASSWORD_BCRYPT);
|
||||
|
||||
if (!$row) {
|
||||
$insert->execute([$roleId, $username, $hash, $name, $email]);
|
||||
} elseif (!password_verify('admin123', $row['password_hash'])) {
|
||||
$update->execute([$roleId, $hash, $name, $email, $username]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,11 +292,11 @@ CREATE TABLE `peristiwa_kependudukan` (
|
||||
-- ================================================================
|
||||
-- Password: admin123 (bcrypt hash contoh)
|
||||
INSERT INTO `user` (`id_role`,`username`,`password_hash`,`nama_lengkap`,`email`) VALUES
|
||||
(1, 'admin', '$2y$10$SCqLjlnUWWOlz6DIB8cXB.aABZyThMWfnf0facH2Lylv4jbs5NQiS', 'Administrator Sistem', 'admin@webgis-ptk.id'),
|
||||
(2, 'pengurus_jami','$2y$10$SCqLjlnUWWOlz6DIB8cXB.aABZyThMWfnf0facH2Lylv4jbs5NQiS', 'Ahmad Fauzi (Masjid Jami)', 'fauzi@webgis-ptk.id'),
|
||||
(2, 'pengurus_ktdr','$2y$10$SCqLjlnUWWOlz6DIB8cXB.aABZyThMWfnf0facH2Lylv4jbs5NQiS', 'Romo Benediktus (Katedral)', 'romo@webgis-ptk.id'),
|
||||
(3, 'pimpinan', '$2y$10$SCqLjlnUWWOlz6DIB8cXB.aABZyThMWfnf0facH2Lylv4jbs5NQiS', 'Camat Pontianak Kota', 'camat@webgis-ptk.id'),
|
||||
(4, 'warga1', '$2y$10$SCqLjlnUWWOlz6DIB8cXB.aABZyThMWfnf0facH2Lylv4jbs5NQiS', 'Budi Santoso', 'budi@gmail.com');
|
||||
(1, 'admin', '$2y$10$9JkAyeakwNYcOvjtrxLeb.teP0iJCFQ9Eeru0LOfodabdjDyAXNTC', 'Administrator Sistem', 'admin@webgis-ptk.id'),
|
||||
(2, 'pengurus_jami','$2y$10$9JkAyeakwNYcOvjtrxLeb.teP0iJCFQ9Eeru0LOfodabdjDyAXNTC', 'Ahmad Fauzi (Masjid Jami)', 'fauzi@webgis-ptk.id'),
|
||||
(2, 'pengurus_ktdr','$2y$10$9JkAyeakwNYcOvjtrxLeb.teP0iJCFQ9Eeru0LOfodabdjDyAXNTC', 'Romo Benediktus (Katedral)', 'romo@webgis-ptk.id'),
|
||||
(3, 'pimpinan', '$2y$10$9JkAyeakwNYcOvjtrxLeb.teP0iJCFQ9Eeru0LOfodabdjDyAXNTC', 'Camat Pontianak Kota', 'camat@webgis-ptk.id'),
|
||||
(4, 'warga1', '$2y$10$9JkAyeakwNYcOvjtrxLeb.teP0iJCFQ9Eeru0LOfodabdjDyAXNTC', 'Budi Santoso', 'budi@gmail.com');
|
||||
|
||||
-- ================================================================
|
||||
-- SEED DATA — Rumah Ibadah
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
FROM php:8.2-apache
|
||||
|
||||
RUN docker-php-ext-install mysqli pdo pdo_mysql \
|
||||
&& a2enmod rewrite \
|
||||
&& echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||
|
||||
COPY . /var/www/html/
|
||||
|
||||
RUN chown -R www-data:www-data /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
+29
-6
@@ -1,13 +1,36 @@
|
||||
<?php
|
||||
$host = getenv('DB_HOST') ?: '127.0.0.1';
|
||||
$user = getenv('DB_USER') ?: 'root';
|
||||
$pass = getenv('DB_PASSWORD') !== false ? getenv('DB_PASSWORD') : '';
|
||||
$db = getenv('SPBU_DB_NAME') ?: 'db_spbu';
|
||||
mysqli_report(MYSQLI_REPORT_OFF);
|
||||
|
||||
$conn = mysqli_connect($host, $user, $pass, $db);
|
||||
function env_first(array $keys, $default = '') {
|
||||
foreach ($keys as $key) {
|
||||
$value = getenv($key);
|
||||
if ($value !== false && $value !== '') return $value;
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
$hosts = array_filter(array_unique([
|
||||
env_first(['DB_HOST', 'MYSQL_HOST', 'MARIADB_HOST']),
|
||||
'mysql',
|
||||
'mariadb',
|
||||
'db',
|
||||
'database',
|
||||
'host.docker.internal',
|
||||
'127.0.0.1',
|
||||
]));
|
||||
|
||||
$user = env_first(['DB_USER', 'MYSQL_USER', 'MARIADB_USER'], 'root');
|
||||
$pass = env_first(['DB_PASSWORD', 'MYSQL_PASSWORD', 'MARIADB_PASSWORD'], '');
|
||||
$db = env_first(['SPBU_DB_NAME', 'DB_NAME_SPBU', 'DB_NAME', 'MYSQL_DATABASE', 'MARIADB_DATABASE'], 'db_spbu');
|
||||
|
||||
$conn = false;
|
||||
foreach ($hosts as $host) {
|
||||
$conn = mysqli_connect($host, $user, $pass, $db);
|
||||
if ($conn) break;
|
||||
}
|
||||
|
||||
if (!$conn) {
|
||||
die("Koneksi database gagal: " . mysqli_connect_error());
|
||||
die("Koneksi database gagal. Pastikan MySQL service berjalan, environment DB_HOST/DB_USER/DB_PASSWORD benar, dan database '$db' sudah diimport. Error: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
mysqli_set_charset($conn, 'utf8mb4');
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
FROM php:8.2-apache
|
||||
|
||||
RUN docker-php-ext-install mysqli pdo pdo_mysql \
|
||||
&& a2enmod rewrite \
|
||||
&& echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||
|
||||
COPY . /var/www/html/
|
||||
|
||||
RUN mkdir -p \
|
||||
/var/www/html/uploads/jalan \
|
||||
/var/www/html/uploads/parsil \
|
||||
/var/www/html/uploads/jalan_rusak \
|
||||
&& chown -R www-data:www-data /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
+29
-6
@@ -1,15 +1,38 @@
|
||||
<?php
|
||||
$host = getenv('DB_HOST') ?: '127.0.0.1';
|
||||
$user = getenv('DB_USER') ?: 'root';
|
||||
$pass = getenv('DB_PASSWORD') !== false ? getenv('DB_PASSWORD') : '';
|
||||
$db = getenv('WEBGIS02_DB_NAME') ?: 'webgis_db';
|
||||
mysqli_report(MYSQLI_REPORT_OFF);
|
||||
|
||||
$conn = mysqli_connect($host, $user, $pass, $db);
|
||||
function env_first(array $keys, $default = '') {
|
||||
foreach ($keys as $key) {
|
||||
$value = getenv($key);
|
||||
if ($value !== false && $value !== '') return $value;
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
$hosts = array_filter(array_unique([
|
||||
env_first(['DB_HOST', 'MYSQL_HOST', 'MARIADB_HOST']),
|
||||
'mysql',
|
||||
'mariadb',
|
||||
'db',
|
||||
'database',
|
||||
'host.docker.internal',
|
||||
'127.0.0.1',
|
||||
]));
|
||||
|
||||
$user = env_first(['DB_USER', 'MYSQL_USER', 'MARIADB_USER'], 'root');
|
||||
$pass = env_first(['DB_PASSWORD', 'MYSQL_PASSWORD', 'MARIADB_PASSWORD'], '');
|
||||
$db = env_first(['WEBGIS02_DB_NAME', 'DB_NAME_WEBGIS02', 'DB_NAME', 'MYSQL_DATABASE', 'MARIADB_DATABASE'], 'webgis_db');
|
||||
|
||||
$conn = false;
|
||||
foreach ($hosts as $host) {
|
||||
$conn = mysqli_connect($host, $user, $pass, $db);
|
||||
if ($conn) break;
|
||||
}
|
||||
|
||||
if (!$conn) {
|
||||
die(json_encode([
|
||||
'status' => 'error',
|
||||
'message' => 'Koneksi database gagal: ' . mysqli_connect_error()
|
||||
'message' => "Koneksi database gagal. Pastikan MySQL service berjalan, environment DB_HOST/DB_USER/DB_PASSWORD benar, dan database '$db' sudah diimport. Error: " . mysqli_connect_error()
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
+24
-44
@@ -316,17 +316,6 @@ const layerJalan = L.layerGroup().addTo(map);
|
||||
const layerParsil = L.layerGroup().addTo(map);
|
||||
const layerRusak = L.layerGroup().addTo(map);
|
||||
|
||||
function parseGeojsonSafe(raw){
|
||||
try{
|
||||
const gj = typeof raw === 'string' ? JSON.parse(raw) : raw;
|
||||
if(!gj || !gj.geometry || !gj.geometry.type) return null;
|
||||
return gj;
|
||||
}catch(e){
|
||||
console.warn('GeoJSON tidak valid:', raw);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================
|
||||
// 2. WARNA & IKON
|
||||
// =============================================================
|
||||
@@ -699,19 +688,16 @@ async function loadJalan(q=''){
|
||||
if(!data.length){ list.innerHTML='<div class="empty-state"><i class="fas fa-road"></i><p>'+(q?'Tidak ada hasil pencarian':'Belum ada data jalan')+'</p></div>'; return; }
|
||||
list.innerHTML='';
|
||||
data.forEach(item=>{
|
||||
const gj = parseGeojsonSafe(item.geojson);
|
||||
const gj = JSON.parse(item.geojson);
|
||||
const style = WARNA_JALAN[item.status_jalan]||WARNA_JALAN['Kabupaten'];
|
||||
let layer = null;
|
||||
if(gj){
|
||||
layer = L.geoJSON(gj,{style}).addTo(layerJalan);
|
||||
layer.bindPopup(`
|
||||
<div class="popup-title">${item.nama_jalan}</div>
|
||||
<div class="popup-row">Status: <span>${item.status_jalan}</span></div>
|
||||
<div class="popup-row">Panjang: <span>${parseFloat(item.panjang_meter).toFixed(2)} m</span></div>
|
||||
${item.keterangan?`<div class="popup-row">Ket: <span>${item.keterangan}</span></div>`:''}
|
||||
${item.foto?`<img class="popup-foto" src="${item.foto}" alt="foto">`:''}
|
||||
`);
|
||||
}
|
||||
const layer = L.geoJSON(gj,{style}).addTo(layerJalan);
|
||||
layer.bindPopup(`
|
||||
<div class="popup-title">${item.nama_jalan}</div>
|
||||
<div class="popup-row">Status: <span>${item.status_jalan}</span></div>
|
||||
<div class="popup-row">Panjang: <span>${parseFloat(item.panjang_meter).toFixed(2)} m</span></div>
|
||||
${item.keterangan?`<div class="popup-row">Ket: <span>${item.keterangan}</span></div>`:''}
|
||||
${item.foto?`<img class="popup-foto" src="${item.foto}" alt="foto">`:''}
|
||||
`);
|
||||
const card = document.createElement('div');
|
||||
card.className='data-card';
|
||||
card.innerHTML=`
|
||||
@@ -722,12 +708,12 @@ async function loadJalan(q=''){
|
||||
<div class="card-meta"><span><i class="fas fa-ruler"></i>${parseFloat(item.panjang_meter).toFixed(0)} m</span></div>
|
||||
${item.foto?`<img class="card-thumb" src="${item.foto}" alt="foto">`:''}
|
||||
<div class="card-actions">
|
||||
<button class="btn-sm btn-zoom" ${layer ? `onclick="zoomJalan${item.id}()"` : 'disabled title="Lokasi belum valid"'}><i class="fas fa-search-location"></i> Zoom</button>
|
||||
<button class="btn-sm btn-zoom" onclick="zoomJalan${item.id}()"><i class="fas fa-search-location"></i> Zoom</button>
|
||||
<button class="btn-sm btn-edit" onclick="editJalan(${item.id})"><i class="fas fa-edit"></i> Edit</button>
|
||||
<button class="btn-sm btn-hapus" onclick="hapusJalan(${item.id})"><i class="fas fa-trash"></i> Hapus</button>
|
||||
</div>`;
|
||||
list.appendChild(card);
|
||||
if(layer) window[`zoomJalan${item.id}`]=()=>map.fitBounds(layer.getBounds(),{padding:[50,50]});
|
||||
window[`zoomJalan${item.id}`]=()=>map.fitBounds(layer.getBounds(),{padding:[50,50]});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -753,20 +739,17 @@ async function loadParsil(q=''){
|
||||
if(!data.length){ list.innerHTML='<div class="empty-state"><i class="fas fa-map"></i><p>'+(q?'Tidak ada hasil pencarian':'Belum ada data parsil')+'</p></div>'; return; }
|
||||
list.innerHTML='';
|
||||
data.forEach(item=>{
|
||||
const gj = parseGeojsonSafe(item.geojson);
|
||||
const gj = JSON.parse(item.geojson);
|
||||
const style = WARNA_PARSIL[item.status_kepemilikan]||WARNA_PARSIL['SHM'];
|
||||
let layer = null;
|
||||
if(gj){
|
||||
layer = L.geoJSON(gj,{style}).addTo(layerParsil);
|
||||
layer.bindPopup(`
|
||||
const layer = L.geoJSON(gj,{style}).addTo(layerParsil);
|
||||
layer.bindPopup(`
|
||||
<div class="popup-title">${item.nama_pemilik}</div>
|
||||
<div class="popup-row">No. Sertifikat: <span>${item.no_sertifikat}</span></div>
|
||||
<div class="popup-row">Status: <span>${item.status_kepemilikan}</span></div>
|
||||
<div class="popup-row">Luas: <span>${parseFloat(item.luas_m2).toFixed(2)} m²</span></div>
|
||||
${item.alamat?`<div class="popup-row">Alamat: <span>${item.alamat}</span></div>`:''}
|
||||
${item.foto?`<img class="popup-foto" src="${item.foto}" alt="foto">`:''}
|
||||
`);
|
||||
}
|
||||
`);
|
||||
const card = document.createElement('div');
|
||||
card.className='data-card';
|
||||
card.innerHTML=`
|
||||
@@ -780,12 +763,12 @@ async function loadParsil(q=''){
|
||||
</div>
|
||||
${item.foto?`<img class="card-thumb" src="${item.foto}" alt="foto">`:''}
|
||||
<div class="card-actions">
|
||||
<button class="btn-sm btn-zoom" ${layer ? `onclick="zoomParsil${item.id}()"` : 'disabled title="Lokasi belum valid"'}><i class="fas fa-search-location"></i> Zoom</button>
|
||||
<button class="btn-sm btn-zoom" onclick="zoomParsil${item.id}()"><i class="fas fa-search-location"></i> Zoom</button>
|
||||
<button class="btn-sm btn-edit" onclick="editParsil(${item.id})"><i class="fas fa-edit"></i> Edit</button>
|
||||
<button class="btn-sm btn-hapus" onclick="hapusParsil(${item.id})"><i class="fas fa-trash"></i> Hapus</button>
|
||||
</div>`;
|
||||
list.appendChild(card);
|
||||
if(layer) window[`zoomParsil${item.id}`]=()=>map.fitBounds(layer.getBounds(),{padding:[50,50]});
|
||||
window[`zoomParsil${item.id}`]=()=>map.fitBounds(layer.getBounds(),{padding:[50,50]});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -811,21 +794,18 @@ async function loadRusak(q=''){
|
||||
if(!data.length){ list.innerHTML='<div class="empty-state"><i class="fas fa-exclamation-triangle"></i><p>'+(q?'Tidak ada hasil pencarian':'Belum ada data jalan rusak')+'</p></div>'; return; }
|
||||
list.innerHTML='';
|
||||
data.forEach(item=>{
|
||||
const gj = parseGeojsonSafe(item.geojson);
|
||||
const gj = JSON.parse(item.geojson);
|
||||
const cfg = WARNA_RUSAK[item.tingkat]||WARNA_RUSAK['Sedang'];
|
||||
const coord = gj && Array.isArray(gj.geometry.coordinates) ? gj.geometry.coordinates : null; // [lng, lat]
|
||||
let layer = null;
|
||||
if(coord){
|
||||
layer = L.circleMarker([coord[1],coord[0]], cfg).addTo(layerRusak);
|
||||
layer.bindPopup(`
|
||||
const coord = gj.geometry.coordinates; // [lng, lat]
|
||||
const layer = L.circleMarker([coord[1],coord[0]], cfg).addTo(layerRusak);
|
||||
layer.bindPopup(`
|
||||
<div class="popup-title"><i class="fas fa-exclamation-triangle" style="color:#ef4444;margin-right:5px"></i>${item.lokasi}</div>
|
||||
<div class="popup-row">Tingkat: <span style="color:${cfg.color};font-weight:700">${item.tingkat}</span></div>
|
||||
${item.jenis?`<div class="popup-row">Jenis: <span>${item.jenis}</span></div>`:''}
|
||||
<div class="popup-row">Dilaporkan: <span>${item.tanggal_lapor||'-'}</span></div>
|
||||
${item.keterangan?`<div class="popup-row">Ket: <span>${item.keterangan}</span></div>`:''}
|
||||
${item.foto?`<img class="popup-foto" src="${item.foto}" alt="foto">`:''}
|
||||
`);
|
||||
}
|
||||
`);
|
||||
const card = document.createElement('div');
|
||||
card.className='data-card';
|
||||
card.innerHTML=`
|
||||
@@ -839,12 +819,12 @@ async function loadRusak(q=''){
|
||||
</div>
|
||||
${item.foto?`<img class="card-thumb" src="${item.foto}" alt="foto">`:''}
|
||||
<div class="card-actions">
|
||||
<button class="btn-sm btn-zoom" ${layer ? `onclick="zoomRusak${item.id}()"` : 'disabled title="Lokasi belum valid"'}><i class="fas fa-search-location"></i> Zoom</button>
|
||||
<button class="btn-sm btn-zoom" onclick="zoomRusak${item.id}()"><i class="fas fa-search-location"></i> Zoom</button>
|
||||
<button class="btn-sm btn-edit" onclick="editRusak(${item.id})"><i class="fas fa-edit"></i> Edit</button>
|
||||
<button class="btn-sm btn-hapus" onclick="hapusRusak(${item.id})"><i class="fas fa-trash"></i> Hapus</button>
|
||||
</div>`;
|
||||
list.appendChild(card);
|
||||
if(layer) window[`zoomRusak${item.id}`]=()=>map.setView([coord[1],coord[0]],17);
|
||||
window[`zoomRusak${item.id}`]=()=>map.setView([coord[1],coord[0]],17);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
FROM php:8.2-apache
|
||||
|
||||
RUN docker-php-ext-install mysqli pdo pdo_mysql \
|
||||
&& a2enmod rewrite \
|
||||
&& echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||
|
||||
COPY . /var/www/html/
|
||||
|
||||
RUN chown -R www-data:www-data /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
@@ -0,0 +1,11 @@
|
||||
FROM php:8.2-apache
|
||||
|
||||
RUN docker-php-ext-install mysqli pdo pdo_mysql \
|
||||
&& a2enmod rewrite \
|
||||
&& echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||
|
||||
COPY . /var/www/html/
|
||||
|
||||
RUN chown -R www-data:www-data /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
+29
-6
@@ -1,13 +1,36 @@
|
||||
<?php
|
||||
$host = getenv('DB_HOST') ?: '127.0.0.1';
|
||||
$user = getenv('DB_USER') ?: 'root';
|
||||
$pass = getenv('DB_PASSWORD') !== false ? getenv('DB_PASSWORD') : '';
|
||||
$db = getenv('SPBU_DB_NAME') ?: 'db_spbu';
|
||||
mysqli_report(MYSQLI_REPORT_OFF);
|
||||
|
||||
$conn = mysqli_connect($host, $user, $pass, $db);
|
||||
function env_first(array $keys, $default = '') {
|
||||
foreach ($keys as $key) {
|
||||
$value = getenv($key);
|
||||
if ($value !== false && $value !== '') return $value;
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
$hosts = array_filter(array_unique([
|
||||
env_first(['DB_HOST', 'MYSQL_HOST', 'MARIADB_HOST']),
|
||||
'mysql',
|
||||
'mariadb',
|
||||
'db',
|
||||
'database',
|
||||
'host.docker.internal',
|
||||
'127.0.0.1',
|
||||
]));
|
||||
|
||||
$user = env_first(['DB_USER', 'MYSQL_USER', 'MARIADB_USER'], 'root');
|
||||
$pass = env_first(['DB_PASSWORD', 'MYSQL_PASSWORD', 'MARIADB_PASSWORD'], '');
|
||||
$db = env_first(['SPBU_DB_NAME', 'DB_NAME_SPBU', 'DB_NAME', 'MYSQL_DATABASE', 'MARIADB_DATABASE'], 'db_spbu');
|
||||
|
||||
$conn = false;
|
||||
foreach ($hosts as $host) {
|
||||
$conn = mysqli_connect($host, $user, $pass, $db);
|
||||
if ($conn) break;
|
||||
}
|
||||
|
||||
if (!$conn) {
|
||||
die("Koneksi database gagal: " . mysqli_connect_error());
|
||||
die("Koneksi database gagal. Pastikan MySQL service berjalan, environment DB_HOST/DB_USER/DB_PASSWORD benar, dan database '$db' sudah diimport. Error: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
mysqli_set_charset($conn, 'utf8mb4');
|
||||
|
||||
Reference in New Issue
Block a user