menambah fitur-poverty
This commit is contained in:
@@ -0,0 +1,325 @@
|
||||
const express = require("express");
|
||||
const db = require("../db");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
const JENIS_IBADAH = ["masjid", "gereja", "pura", "vihara", "kelenteng", "lainnya"];
|
||||
const KATEGORI_KEMISKINAN = ["sangat_miskin", "miskin", "rentan_miskin"];
|
||||
|
||||
let tablesReady = false;
|
||||
|
||||
function toFeatureCollection(rows) {
|
||||
return {
|
||||
type: "FeatureCollection",
|
||||
features: rows.map((row) => {
|
||||
const { lat, lng, ...properties } = row;
|
||||
return {
|
||||
type: "Feature",
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates: [Number(lng), Number(lat)],
|
||||
},
|
||||
properties: {
|
||||
...properties,
|
||||
lat: Number(lat),
|
||||
lng: Number(lng),
|
||||
},
|
||||
};
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
function validateCoordinate(lat, lng) {
|
||||
return Number.isFinite(Number(lat)) && Number.isFinite(Number(lng));
|
||||
}
|
||||
|
||||
function escapeCsv(value) {
|
||||
return `"${String(value ?? "").replace(/"/g, '""')}"`;
|
||||
}
|
||||
|
||||
async function createTableWithFallback(primarySql, fallbackSql) {
|
||||
try {
|
||||
await db.execute(primarySql);
|
||||
} catch (error) {
|
||||
if (!fallbackSql) throw error;
|
||||
await db.execute(fallbackSql);
|
||||
}
|
||||
}
|
||||
|
||||
async function ensureTables() {
|
||||
if (tablesReady) return;
|
||||
|
||||
const tempatIbadahWithGeom = `
|
||||
CREATE TABLE IF NOT EXISTS tempat_ibadah (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
nama VARCHAR(255) NOT NULL,
|
||||
jenis ENUM('masjid','gereja','pura','vihara','kelenteng','lainnya') NOT NULL,
|
||||
alamat TEXT,
|
||||
kelurahan VARCHAR(100),
|
||||
lat DOUBLE NOT NULL,
|
||||
lng DOUBLE NOT NULL,
|
||||
geom POINT GENERATED ALWAYS AS (ST_SRID(POINT(lng, lat), 4326)) STORED,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
SPATIAL INDEX idx_tempat_ibadah_geom (geom)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`;
|
||||
|
||||
const tempatIbadahFallback = `
|
||||
CREATE TABLE IF NOT EXISTS tempat_ibadah (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
nama VARCHAR(255) NOT NULL,
|
||||
jenis ENUM('masjid','gereja','pura','vihara','kelenteng','lainnya') NOT NULL,
|
||||
alamat TEXT,
|
||||
kelurahan VARCHAR(100),
|
||||
lat DOUBLE NOT NULL,
|
||||
lng DOUBLE NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_tempat_ibadah_lat_lng (lat, lng)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`;
|
||||
|
||||
const keluargaWithGeom = `
|
||||
CREATE TABLE IF NOT EXISTS keluarga_miskin (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
nama_kk VARCHAR(255) NOT NULL,
|
||||
jumlah_anggota INT NOT NULL DEFAULT 1,
|
||||
kategori ENUM('sangat_miskin','miskin','rentan_miskin') NOT NULL,
|
||||
alamat TEXT,
|
||||
rt VARCHAR(5),
|
||||
rw VARCHAR(5),
|
||||
kelurahan VARCHAR(100),
|
||||
keterangan TEXT,
|
||||
lat DOUBLE NOT NULL,
|
||||
lng DOUBLE NOT NULL,
|
||||
geom POINT GENERATED ALWAYS AS (ST_SRID(POINT(lng, lat), 4326)) STORED,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
SPATIAL INDEX idx_keluarga_geom (geom)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`;
|
||||
|
||||
const keluargaFallback = `
|
||||
CREATE TABLE IF NOT EXISTS keluarga_miskin (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
nama_kk VARCHAR(255) NOT NULL,
|
||||
jumlah_anggota INT NOT NULL DEFAULT 1,
|
||||
kategori ENUM('sangat_miskin','miskin','rentan_miskin') NOT NULL,
|
||||
alamat TEXT,
|
||||
rt VARCHAR(5),
|
||||
rw VARCHAR(5),
|
||||
kelurahan VARCHAR(100),
|
||||
keterangan TEXT,
|
||||
lat DOUBLE NOT NULL,
|
||||
lng DOUBLE NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_keluarga_lat_lng (lat, lng)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`;
|
||||
|
||||
await createTableWithFallback(tempatIbadahWithGeom, tempatIbadahFallback);
|
||||
await createTableWithFallback(keluargaWithGeom, keluargaFallback);
|
||||
await seedPovertyDataIfEmpty();
|
||||
tablesReady = true;
|
||||
}
|
||||
|
||||
async function seedPovertyDataIfEmpty() {
|
||||
const [[{ count: tempatCount }]] = await db.execute("SELECT COUNT(*) AS count FROM tempat_ibadah");
|
||||
if (Number(tempatCount) === 0) {
|
||||
const rows = [
|
||||
["Masjid Jami Sultan Syarif Abdurrahman", "masjid", "Jl. Tanjungpura", "Dalam Bugis", -0.0226, 109.3316],
|
||||
["Gereja Bethel Indonesia", "gereja", "Jl. Gajahmada", "Sungai Bangkong", -0.0334, 109.3253],
|
||||
["Vihara Bodhisattva", "vihara", "Jl. Diponegoro", "Mariana", -0.0289, 109.3401],
|
||||
];
|
||||
for (const row of rows) {
|
||||
await db.execute(
|
||||
"INSERT INTO tempat_ibadah (nama, jenis, alamat, kelurahan, lat, lng) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
row,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const [[{ count: keluargaCount }]] = await db.execute("SELECT COUNT(*) AS count FROM keluarga_miskin");
|
||||
if (Number(keluargaCount) === 0) {
|
||||
const rows = [
|
||||
["Ahmad Fauzi", 5, "sangat_miskin", "Dalam Bugis", -0.0231, 109.3321],
|
||||
["Siti Rahmah", 3, "miskin", "Dalam Bugis", -0.0219, 109.3308],
|
||||
["Budi Santoso", 6, "rentan_miskin", "Sungai Bangkong", -0.0341, 109.3261],
|
||||
["Maria Goretti", 4, "miskin", "Mariana", -0.0295, 109.3412],
|
||||
["Lim Ah Kow", 2, "sangat_miskin", "Mariana", -0.0501, 109.36],
|
||||
];
|
||||
for (const row of rows) {
|
||||
await db.execute(
|
||||
"INSERT INTO keluarga_miskin (nama_kk, jumlah_anggota, kategori, kelurahan, lat, lng) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
row,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
router.use(async (req, res, next) => {
|
||||
try {
|
||||
await ensureTables();
|
||||
next();
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.get("/tempat-ibadah", async (req, res) => {
|
||||
try {
|
||||
const [rows] = await db.execute(
|
||||
"SELECT id, nama, jenis, alamat, kelurahan, lat, lng, created_at FROM tempat_ibadah ORDER BY nama ASC",
|
||||
);
|
||||
res.json(toFeatureCollection(rows));
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.post("/tempat-ibadah", async (req, res) => {
|
||||
const { nama, jenis, alamat, kelurahan, lat, lng } = req.body;
|
||||
if (!nama || !JENIS_IBADAH.includes(jenis) || !validateCoordinate(lat, lng)) {
|
||||
return res.status(400).json({ success: false, message: "Nama, jenis, lat, dan lng wajib valid." });
|
||||
}
|
||||
|
||||
try {
|
||||
const [result] = await db.execute(
|
||||
"INSERT INTO tempat_ibadah (nama, jenis, alamat, kelurahan, lat, lng) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
[nama.trim(), jenis, alamat || null, kelurahan || null, Number(lat), Number(lng)],
|
||||
);
|
||||
res.status(201).json({ success: true, id: result.insertId, message: "Tempat ibadah berhasil ditambahkan." });
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.put("/tempat-ibadah/:id", async (req, res) => {
|
||||
const { nama, jenis, alamat, kelurahan, lat, lng } = req.body;
|
||||
if (!nama || !JENIS_IBADAH.includes(jenis) || !validateCoordinate(lat, lng)) {
|
||||
return res.status(400).json({ success: false, message: "Nama, jenis, lat, dan lng wajib valid." });
|
||||
}
|
||||
|
||||
try {
|
||||
const [result] = await db.execute(
|
||||
"UPDATE tempat_ibadah SET nama=?, jenis=?, alamat=?, kelurahan=?, lat=?, lng=? WHERE id=?",
|
||||
[nama.trim(), jenis, alamat || null, kelurahan || null, Number(lat), Number(lng), req.params.id],
|
||||
);
|
||||
if (!result.affectedRows) return res.status(404).json({ success: false, message: "Tempat ibadah tidak ditemukan." });
|
||||
res.json({ success: true, message: "Tempat ibadah berhasil diperbarui." });
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete("/tempat-ibadah/:id", async (req, res) => {
|
||||
try {
|
||||
const [result] = await db.execute("DELETE FROM tempat_ibadah WHERE id = ?", [req.params.id]);
|
||||
if (!result.affectedRows) return res.status(404).json({ success: false, message: "Tempat ibadah tidak ditemukan." });
|
||||
res.json({ success: true, message: "Tempat ibadah berhasil dihapus." });
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.get("/keluarga", async (req, res) => {
|
||||
try {
|
||||
const [rows] = await db.execute(
|
||||
`SELECT id, nama_kk, jumlah_anggota, kategori, alamat, rt, rw, kelurahan, keterangan, lat, lng, created_at, updated_at
|
||||
FROM keluarga_miskin
|
||||
ORDER BY nama_kk ASC`,
|
||||
);
|
||||
res.json(toFeatureCollection(rows));
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.post("/keluarga", async (req, res) => {
|
||||
const { nama_kk, jumlah_anggota, kategori, alamat, rt, rw, kelurahan, keterangan, lat, lng } = req.body;
|
||||
if (!nama_kk || !KATEGORI_KEMISKINAN.includes(kategori) || !validateCoordinate(lat, lng)) {
|
||||
return res.status(400).json({ success: false, message: "Nama KK, kategori, lat, dan lng wajib valid." });
|
||||
}
|
||||
|
||||
try {
|
||||
const [result] = await db.execute(
|
||||
`INSERT INTO keluarga_miskin
|
||||
(nama_kk, jumlah_anggota, kategori, alamat, rt, rw, kelurahan, keterangan, lat, lng)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[nama_kk.trim(), Number(jumlah_anggota) || 1, kategori, alamat || null, rt || null, rw || null, kelurahan || null, keterangan || null, Number(lat), Number(lng)],
|
||||
);
|
||||
res.status(201).json({ success: true, id: result.insertId, message: "Keluarga berhasil ditambahkan." });
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.put("/keluarga/:id", async (req, res) => {
|
||||
const { nama_kk, jumlah_anggota, kategori, alamat, rt, rw, kelurahan, keterangan, lat, lng } = req.body;
|
||||
if (!nama_kk || !KATEGORI_KEMISKINAN.includes(kategori) || !validateCoordinate(lat, lng)) {
|
||||
return res.status(400).json({ success: false, message: "Nama KK, kategori, lat, dan lng wajib valid." });
|
||||
}
|
||||
|
||||
try {
|
||||
const [result] = await db.execute(
|
||||
`UPDATE keluarga_miskin
|
||||
SET nama_kk=?, jumlah_anggota=?, kategori=?, alamat=?, rt=?, rw=?, kelurahan=?, keterangan=?, lat=?, lng=?
|
||||
WHERE id=?`,
|
||||
[nama_kk.trim(), Number(jumlah_anggota) || 1, kategori, alamat || null, rt || null, rw || null, kelurahan || null, keterangan || null, Number(lat), Number(lng), req.params.id],
|
||||
);
|
||||
if (!result.affectedRows) return res.status(404).json({ success: false, message: "Keluarga tidak ditemukan." });
|
||||
res.json({ success: true, message: "Keluarga berhasil diperbarui." });
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete("/keluarga/:id", async (req, res) => {
|
||||
try {
|
||||
const [result] = await db.execute("DELETE FROM keluarga_miskin WHERE id = ?", [req.params.id]);
|
||||
if (!result.affectedRows) return res.status(404).json({ success: false, message: "Keluarga tidak ditemukan." });
|
||||
res.json({ success: true, message: "Keluarga berhasil dihapus." });
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.get("/export", async (req, res) => {
|
||||
const ibadahId = Number(req.query.ibadah_id);
|
||||
const radius = Number(req.query.radius || 500);
|
||||
|
||||
if (!Number.isInteger(ibadahId) || !Number.isFinite(radius) || radius <= 0) {
|
||||
return res.status(400).json({ success: false, message: "ibadah_id dan radius wajib valid." });
|
||||
}
|
||||
|
||||
try {
|
||||
const [[ibadah]] = await db.execute("SELECT id, nama, lat, lng FROM tempat_ibadah WHERE id = ?", [ibadahId]);
|
||||
if (!ibadah) return res.status(404).json({ success: false, message: "Tempat ibadah tidak ditemukan." });
|
||||
|
||||
const [rows] = await db.execute(
|
||||
`SELECT
|
||||
k.id, k.nama_kk, k.jumlah_anggota, k.kategori, k.alamat, k.rt, k.rw, k.kelurahan, k.keterangan, k.lat, k.lng,
|
||||
ST_Distance_Sphere(POINT(k.lng, k.lat), POINT(?, ?)) AS jarak_meter
|
||||
FROM keluarga_miskin k
|
||||
WHERE ST_Distance_Sphere(POINT(k.lng, k.lat), POINT(?, ?)) <= ?
|
||||
ORDER BY jarak_meter ASC`,
|
||||
[ibadah.lng, ibadah.lat, ibadah.lng, ibadah.lat, radius],
|
||||
);
|
||||
|
||||
const header = ["nama_kk", "jumlah_anggota", "kategori", "kelurahan", "alamat", "rt", "rw", "jarak_meter"];
|
||||
const lines = [
|
||||
`Tempat Ibadah,${escapeCsv(ibadah.nama)}`,
|
||||
`Radius Meter,${escapeCsv(radius)}`,
|
||||
header.join(","),
|
||||
...rows.map((row) => header.map((key) => escapeCsv(key === "jarak_meter" ? Math.round(row.jarak_meter) : row[key])).join(",")),
|
||||
];
|
||||
|
||||
res.setHeader("Content-Type", "text/csv; charset=utf-8");
|
||||
res.setHeader("Content-Disposition", 'attachment; filename="laporan-keluarga-radius.csv"');
|
||||
res.send(lines.join("\n"));
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
+41
-58
@@ -3,6 +3,7 @@ const express = require("express");
|
||||
const cors = require("cors");
|
||||
const path = require("path");
|
||||
const db = require("./db");
|
||||
const povertyRoutes = require("./routes/poverty");
|
||||
require("dotenv").config();
|
||||
|
||||
const app = express();
|
||||
@@ -11,7 +12,7 @@ const PORT = process.env.PORT || 3000;
|
||||
// ─── Middleware ───────────────────────────────────────────────────────────────
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
|
||||
app.use("/api/poverty", povertyRoutes);
|
||||
// Sajikan folder frontend secara statis
|
||||
app.use(express.static(path.join(__dirname, "../frontend")));
|
||||
|
||||
@@ -284,12 +285,10 @@ app.post("/api/spbu", async (req, res) => {
|
||||
.json({ success: false, message: "Semua field wajib diisi." });
|
||||
}
|
||||
if (!Array.isArray(jenis_bbm) || jenis_bbm.length === 0) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({
|
||||
success: false,
|
||||
message: "Minimal satu jenis BBM harus dipilih.",
|
||||
});
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "Minimal satu jenis BBM harus dipilih.",
|
||||
});
|
||||
}
|
||||
try {
|
||||
const [result] = await db.execute(
|
||||
@@ -307,21 +306,17 @@ app.post("/api/spbu", async (req, res) => {
|
||||
manual_override || "auto",
|
||||
],
|
||||
);
|
||||
res
|
||||
.status(201)
|
||||
.json({
|
||||
success: true,
|
||||
message: "SPBU berhasil ditambahkan.",
|
||||
id: result.insertId,
|
||||
});
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: "SPBU berhasil ditambahkan.",
|
||||
id: result.insertId,
|
||||
});
|
||||
} catch (err) {
|
||||
if (err.code === "ER_DUP_ENTRY") {
|
||||
return res
|
||||
.status(409)
|
||||
.json({
|
||||
success: false,
|
||||
message: `Kode SPBU '${kode}' sudah digunakan.`,
|
||||
});
|
||||
return res.status(409).json({
|
||||
success: false,
|
||||
message: `Kode SPBU '${kode}' sudah digunakan.`,
|
||||
});
|
||||
}
|
||||
res.status(500).json({ success: false, message: err.message });
|
||||
}
|
||||
@@ -460,12 +455,10 @@ app.get("/api/jalan/:id", async (req, res) => {
|
||||
app.post("/api/jalan", async (req, res) => {
|
||||
const { nama_jalan, jenis_jalan, koordinat } = req.body;
|
||||
if (!nama_jalan || !jenis_jalan || !koordinat) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({
|
||||
success: false,
|
||||
message: "nama_jalan, jenis_jalan, dan koordinat wajib diisi.",
|
||||
});
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "nama_jalan, jenis_jalan, dan koordinat wajib diisi.",
|
||||
});
|
||||
}
|
||||
const jenisValid = ["nasional", "provinsi", "kota_kabupaten"];
|
||||
if (!jenisValid.includes(jenis_jalan)) {
|
||||
@@ -480,13 +473,11 @@ app.post("/api/jalan", async (req, res) => {
|
||||
"INSERT INTO jalan (nama_jalan, jenis_jalan, koordinat) VALUES (?, ?, ?)",
|
||||
[nama_jalan.trim(), jenis_jalan, koordinatStr],
|
||||
);
|
||||
res
|
||||
.status(201)
|
||||
.json({
|
||||
success: true,
|
||||
message: "Jalan berhasil ditambahkan.",
|
||||
id: result.insertId,
|
||||
});
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: "Jalan berhasil ditambahkan.",
|
||||
id: result.insertId,
|
||||
});
|
||||
} catch (err) {
|
||||
res.status(500).json({ success: false, message: err.message });
|
||||
}
|
||||
@@ -496,12 +487,10 @@ app.post("/api/jalan", async (req, res) => {
|
||||
app.put("/api/jalan/:id", async (req, res) => {
|
||||
const { nama_jalan, jenis_jalan, koordinat } = req.body;
|
||||
if (!nama_jalan || !jenis_jalan || !koordinat) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({
|
||||
success: false,
|
||||
message: "nama_jalan, jenis_jalan, dan koordinat wajib diisi.",
|
||||
});
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "nama_jalan, jenis_jalan, dan koordinat wajib diisi.",
|
||||
});
|
||||
}
|
||||
try {
|
||||
const koordinatStr =
|
||||
@@ -573,12 +562,10 @@ app.get("/api/bangunan/:id", async (req, res) => {
|
||||
app.post("/api/bangunan", async (req, res) => {
|
||||
const { nama_bangunan, jenis_bangunan, nama_jalan, koordinat } = req.body;
|
||||
if (!nama_bangunan || !jenis_bangunan || !koordinat) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({
|
||||
success: false,
|
||||
message: "nama_bangunan, jenis_bangunan, dan koordinat wajib diisi.",
|
||||
});
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "nama_bangunan, jenis_bangunan, dan koordinat wajib diisi.",
|
||||
});
|
||||
}
|
||||
const jenisValid = ["SHM", "HGB", "HGU", "HP", "HPL"];
|
||||
if (!jenisValid.includes(jenis_bangunan)) {
|
||||
@@ -598,13 +585,11 @@ app.post("/api/bangunan", async (req, res) => {
|
||||
koordinatStr,
|
||||
],
|
||||
);
|
||||
res
|
||||
.status(201)
|
||||
.json({
|
||||
success: true,
|
||||
message: "Bangunan berhasil ditambahkan.",
|
||||
id: result.insertId,
|
||||
});
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: "Bangunan berhasil ditambahkan.",
|
||||
id: result.insertId,
|
||||
});
|
||||
} catch (err) {
|
||||
res.status(500).json({ success: false, message: err.message });
|
||||
}
|
||||
@@ -614,12 +599,10 @@ app.post("/api/bangunan", async (req, res) => {
|
||||
app.put("/api/bangunan/:id", async (req, res) => {
|
||||
const { nama_bangunan, jenis_bangunan, nama_jalan, koordinat } = req.body;
|
||||
if (!nama_bangunan || !jenis_bangunan || !koordinat) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({
|
||||
success: false,
|
||||
message: "nama_bangunan, jenis_bangunan, dan koordinat wajib diisi.",
|
||||
});
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "nama_bangunan, jenis_bangunan, dan koordinat wajib diisi.",
|
||||
});
|
||||
}
|
||||
try {
|
||||
const koordinatStr =
|
||||
|
||||
Reference in New Issue
Block a user