diff --git a/admin/api/config_api.php b/admin/api/config_api.php new file mode 100644 index 0000000..28b00c0 --- /dev/null +++ b/admin/api/config_api.php @@ -0,0 +1,5 @@ + diff --git a/admin/api/ocr_helper.php b/admin/api/ocr_helper.php new file mode 100644 index 0000000..283596f --- /dev/null +++ b/admin/api/ocr_helper.php @@ -0,0 +1,95 @@ + false, 'message' => 'Invalid request method']); + exit; +} + +if (!isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) { + echo json_encode(['success' => false, 'message' => 'Upload failed or no image provided']); + exit; +} + +$type = $_POST['type'] ?? 'ktp'; // 'ktp' or 'kk' +$imagePath = $_FILES['image']['tmp_name']; +$imageData = base64_encode(file_get_contents($imagePath)); +$mimeType = mime_content_type($imagePath); + +// Construct Prompt based on Type +if ($type === 'kk') { + $promptText = "Extract strictly from this Indonesian Family Card (Kartu Keluarga). Return ONLY a raw JSON object with these keys: 'no_kk' (16 digits), 'kepala_keluarga' (Name), 'alamat', 'rt', 'rw', 'desa', 'kecamatan', 'kabupaten', 'provinsi', 'kode_pos', 'anggota': [ { 'nik': '...', 'nama': '...', 'hubungan': '...' } ] (Array of all family members found in the table. 'hubungan' examples: KEPALA KELUARGA, ISTRI, ANAK, FAMILI LAIN). Value must be string. If not found, use empty string."; +} else { + // Default to KTP + $promptText = "Extract data from this Indonesian KTP. Return ONLY a raw JSON object with keys: 'nik' (16 digits), 'nama' (Name), 'tempat_lh' (Place of Birth), 'tgl_lh' (YYYY-MM-DD), 'je_kel' (LK/PR), 'alamat' (Street only), 'rt', 'rw', 'desa' (Kel/Desa), 'kecamatan', 'kabupaten' (or Kota), 'provinsi', 'agama', 'status' (Sudah/Belum/Cerai Hidup/Cerai Mati), 'pekerjaan', 'kewarganegaraan' (WNI/WNA). Clean up text. If field is unclear, return empty string."; +} + +// Payload for Gemini +$data = [ + "contents" => [ + [ + "parts" => [ + ["text" => $promptText], + [ + "inline_data" => [ + "mime_type" => $mimeType, + "data" => $imageData + ] + ] + ] + ] + ] +]; + +// Send Request +$ch = curl_init(GEMINI_API_URL . '?key=' . GEMINI_API_KEY); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_POST, true); +curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); +curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); + +$response = curl_exec($ch); +$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); +$error = curl_error($ch); +curl_close($ch); + +if ($error) { + echo json_encode(['success' => false, 'message' => 'CURL Error: ' . $error]); + exit; +} + +$result = json_decode($response, true); + +// Debugging check +if (isset($result['error'])) { + echo json_encode(['success' => false, 'message' => 'API Error: ' . $result['error']['message']]); + exit; +} + +if (!isset($result['candidates'][0]['content']['parts'][0]['text'])) { + echo json_encode(['success' => false, 'message' => 'No text returned from AI', 'raw' => $result]); + exit; +} + +// Parse AI Response +$rawText = $result['candidates'][0]['content']['parts'][0]['text']; + +// Remove Markdown Code Blocks if any (```json ... ```) +$cleanJson = preg_replace('/^```json\s*|\s*```$/', '', trim($rawText)); +$parsedData = json_decode($cleanJson, true); + +if (json_last_error() !== JSON_ERROR_NONE) { + // Fallback: try to find JSON object structure in text + if (preg_match('/\{.*\}/s', $cleanJson, $matches)) { + $parsedData = json_decode($matches[0], true); + } +} + +if (!$parsedData) { + echo json_encode(['success' => false, 'message' => 'Failed to parse AI response', 'raw_text' => $rawText]); + exit; +} + +echo json_encode(['success' => true, 'data' => $parsedData]); +?> diff --git a/admin/kartu/add_kartu.php b/admin/kartu/add_kartu.php index 9c6115c..d2218f8 100644 --- a/admin/kartu/add_kartu.php +++ b/admin/kartu/add_kartu.php @@ -6,10 +6,49 @@
+
+ +
+ + + + Pilih foto, crop, lalu scan. + +
+
+ + + +
+
@@ -58,12 +97,7 @@
-
- -
- -
-
+
+ + 0){ + echo ""; + return; + } + + // Sanitize Inputs + $no_kk = mysqli_real_escape_string($koneksi, $_POST['no_kk']); + $kepala = mysqli_real_escape_string($koneksi, $_POST['kepala']); + $desa = mysqli_real_escape_string($koneksi, $_POST['desa']); + $rt = mysqli_real_escape_string($koneksi, $_POST['rt']); + $rw = mysqli_real_escape_string($koneksi, $_POST['rw']); + $kec = mysqli_real_escape_string($koneksi, $_POST['kec']); + $kab = mysqli_real_escape_string($koneksi, $_POST['kab']); + $prov = mysqli_real_escape_string($koneksi, $_POST['prov']); + $sql_simpan = "INSERT INTO tb_kk (no_kk, kepala, desa, rt, rw, kec, kab, prov, foto_kk) VALUES ( - '".$_POST['no_kk']."', - '".$_POST['kepala']."', - '".$_POST['desa']."', - '".$_POST['rt']."', - '".$_POST['rw']."', - '".$_POST['kec']."', - '".$_POST['kab']."', - '".$_POST['prov']."', - '".$nama_file."')"; + '$no_kk', + '$kepala', + '$desa', + '$rt', + '$rw', + '$kec', + '$kab', + '$prov', + '$nama_file')"; $query_simpan = mysqli_query($koneksi, $sql_simpan); + + // Process Auto-Linking Members + if ($query_simpan && !empty($_POST['anggota_json'])) { + $id_kk_baru = mysqli_insert_id($koneksi); + $anggota_list = json_decode($_POST['anggota_json'], true); + + if (is_array($anggota_list)) { + foreach ($anggota_list as $mem) { + $nik_mem = mysqli_real_escape_string($koneksi, $mem['nik']); + $hub_mem = mysqli_real_escape_string($koneksi, $mem['hubungan']); + + // Search Resident by NIK + $sql_cek_pend = "SELECT id_pend FROM tb_pdd WHERE nik='$nik_mem'"; + $q_cek_pend = mysqli_query($koneksi, $sql_cek_pend); + if ($row_pend = mysqli_fetch_assoc($q_cek_pend)) { + $id_pend_found = $row_pend['id_pend']; + + // Insert into tb_anggota + $sql_add_ang = "INSERT INTO tb_anggota (id_kk, id_pend, hubungan) VALUES ('$id_kk_baru', '$id_pend_found', '$hub_mem')"; + mysqli_query($koneksi, $sql_add_ang); + } + } + } + } + mysqli_close($koneksi); if ($query_simpan) { diff --git a/admin/kartu/data_kartu.php b/admin/kartu/data_kartu.php index 5bc0d70..4a8bce5 100644 --- a/admin/kartu/data_kartu.php +++ b/admin/kartu/data_kartu.php @@ -56,8 +56,7 @@ - + @@ -71,4 +70,24 @@ - \ No newline at end of file + + + + \ No newline at end of file diff --git a/admin/kartu/edit_kartu.php b/admin/kartu/edit_kartu.php index bf96034..6faab1a 100644 --- a/admin/kartu/edit_kartu.php +++ b/admin/kartu/edit_kartu.php @@ -15,6 +15,49 @@
+
+ +
+ + + + + + + + + Pilih foto, crop, lalu scan. + +
+
+ + + +
@@ -84,23 +127,7 @@
-
- -
- - - - - -
-
-
- -
- -
-
+ +
+
+ +
+ + + + Pilih foto, crop, lalu scan. + +
+
+ + + +
@@ -21,7 +59,7 @@
- +
@@ -31,12 +69,13 @@
- +
@@ -48,6 +87,27 @@
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+
@@ -86,12 +146,14 @@
- +
- +
+ +
+ + 0){ + echo ""; + return; + } + + // Sanitize Input to prevent SQL Injection & Syntax Errors + $nik = mysqli_real_escape_string($koneksi, $_POST['nik']); + $nama = mysqli_real_escape_string($koneksi, $_POST['nama']); + $tempat_lh = mysqli_real_escape_string($koneksi, $_POST['tempat_lh']); + $tgl_lh = mysqli_real_escape_string($koneksi, $_POST['tgl_lh']); + $jekel = mysqli_real_escape_string($koneksi, $_POST['jekel']); + $desa = mysqli_real_escape_string($koneksi, $_POST['desa']); + $rt = mysqli_real_escape_string($koneksi, $_POST['rt']); + $rw = mysqli_real_escape_string($koneksi, $_POST['rw']); + $agama = mysqli_real_escape_string($koneksi, $_POST['agama']); + $kawin = mysqli_real_escape_string($koneksi, $_POST['kawin']); + $pekerjaan = mysqli_real_escape_string($koneksi, $_POST['pekerjaan']); + $kecamatan = mysqli_real_escape_string($koneksi, $_POST['kecamatan']); + $kabupaten = mysqli_real_escape_string($koneksi, $_POST['kabupaten']); + $provinsi = mysqli_real_escape_string($koneksi, $_POST['provinsi']); + $kewarganegaraan = mysqli_real_escape_string($koneksi, $_POST['kewarganegaraan']); + + $sql_simpan = "INSERT INTO tb_pdd (nik, nama, tempat_lh, tgl_lh, jekel, desa, rt, rw, agama, kawin, pekerjaan, foto_ktp, status, kecamatan, kabupaten, provinsi, kewarganegaraan) VALUES ( + '$nik', + '$nama', + '$tempat_lh', + '$tgl_lh', + '$jekel', + '$desa', + '$rt', + '$rw', + '$agama', + '$kawin', + '$pekerjaan', + '$nama_file', + 'Ada', + '$kecamatan', + '$kabupaten', + '$provinsi', + '$kewarganegaraan')"; $query_simpan = mysqli_query($koneksi, $sql_simpan); mysqli_close($koneksi); @@ -136,7 +454,7 @@ })"; }else{ echo " \ No newline at end of file diff --git a/admin/pend/edit_pend.php b/admin/pend/edit_pend.php index 5e1dc1c..90d6fc3 100644 --- a/admin/pend/edit_pend.php +++ b/admin/pend/edit_pend.php @@ -23,11 +23,54 @@
+
+ +
+ + + + + + + + + Pilih foto, crop, lalu scan. + +
+
+ + + +
+ required>
@@ -40,7 +83,7 @@
- +
@@ -58,11 +101,12 @@ LK"; - else echo ""; + //menhecek data yg dipilih sebelumnya + if ($data_cek['jekel'] == "LK") echo ""; + else echo ""; - if ($data_cek['jekel'] == "PR") echo ""; - else echo ""; + if ($data_cek['jekel'] == "PR") echo ""; + else echo ""; ?>
@@ -72,7 +116,31 @@
+ required> +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+
@@ -123,26 +191,19 @@
-
-
- -
- - - - - + required>
- +
- +
+ + + - TTL + Tempat/Tanggal Lahir : @@ -61,7 +61,11 @@ Jenis Kelamin : - + @@ -74,6 +78,30 @@ + + + Kecamatan + + : + + + + + + Kabupaten + + : + + + + + + Provinsi + + : + + + Agama @@ -97,6 +125,15 @@ : + + + + + Kewarganegaraan + + : + + diff --git a/fix_kk_db.php b/fix_kk_db.php new file mode 100644 index 0000000..f0460ad --- /dev/null +++ b/fix_kk_db.php @@ -0,0 +1,22 @@ +query($sql) === TRUE) { + echo "Success: $sql
"; + } else { + echo "Error: " . $koneksi->error . "
"; + } + } + + $koneksi->close(); +?> diff --git a/index.php b/index.php index 7c0f46b..7350676 100644 --- a/index.php +++ b/index.php @@ -37,6 +37,8 @@ + + @@ -701,6 +703,8 @@ + +