CoolFace
Apppublic

devusman/indonesian

sourceHugging Faceupdated 11mo agoView on Hugging Face
0likes
index.ejs429 linesDownload Raw Back to views
1<!DOCTYPE html>2<html lang="id">3 4<head>5    <meta charset="UTF-8">6    <meta name="viewport" content="width=device-width, initial-scale=1.0">7    <title>Alat Bantu Pencarian Data Bantuan Sosial</title>8    <style>9        /* --- Gaya Dasar & Tata Letak --- */10        * {11            box-sizing: border-box;12        }13 14        body {15            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;16            color: #172b4d;17            margin: 1em;18            line-height: 1.5;19        }20 21        .cb-container {22            max-width: 900px;23            margin: auto;24            background: #ffffff;25            padding: 1.5em;26            border-radius: 8px;27            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);28        }29 30        .cb-grid {31            display: grid;32            grid-template-columns: 1fr;33            gap: 2.5em;34        }35 36        .cb-col h2,37        .cb-col h3 {38            border-bottom: 2px solid #dfe1e6;39            padding-bottom: 0.5em;40            margin-top: 0;41            margin-bottom: 1.2em;42            color: #091e42;43        }44 45        /* --- Formulir --- */46        .cb-label {47            display: block;48            margin-bottom: 0.5em;49            font-weight: bold;50            font-size: 0.95em;51            color: #42526e;52        }53 54        .cb-select,55        .cb-input {56            width: 100%;57            padding: 0.85em;58            margin-bottom: 1.2em;59            border: 2px solid #dfe1e6;60            border-radius: 6px;61            background-color: #fafbfc;62            font-size: 1em;63            color: #172b4d;64            text-transform: uppercase;65            transition: border-color 0.2s;66        }67 68        .cb-select:focus,69        .cb-input:focus {70            border-color: #0052cc;71            outline: none;72        }73 74        .cb-select:disabled {75            background-color: #f4f5f7;76            cursor: not-allowed;77        }78 79        /* --- Tombol --- */80        .cb-actions {81            display: flex;82            gap: 1em;83            margin-top: 1.5em;84            flex-direction: column;85        }86 87        .cb-btn {88            border: none;89            padding: 0.85em 1.5em;90            border-radius: 6px;91            cursor: pointer;92            font-weight: 600;93            text-decoration: none;94            text-align: center;95            font-size: 1em;96            width: 100%;97            transition: background-color 0.2s;98        }99 100        .cb-btn-primary {101            background-color: #0052cc;102            color: white;103        }104 105        .cb-btn-primary:hover {106            background-color: #0747a6;107        }108 109        .cb-btn-gray {110            background-color: #ebecf0;111            color: #42526e;112        }113 114        .cb-btn-gray:hover {115            background-color: #dfe1e6;116        }117 118        /* --- Info & Disclaimer --- */119        .cb-note,120        .cb-disclaimer {121            margin-top: 1.5em;122            padding: 1em;123            border-radius: 6px;124            font-size: 0.9em;125        }126 127        .cb-note {128            background-color: #e6fcff;129            border-left: 4px solid #00c7e6;130        }131 132        .cb-disclaimer {133            background-color: #fffae6;134            border-left: 4px solid #ffab00;135        }136 137        /* --- Kotak Hasil --- */138        .cb-result {139            display: none;140            margin-top: 2.5em;141            padding: 1.5em;142            border-radius: 8px;143            background-color: #fafbfc;144        }145 146        .cb-kv {147            display: grid;148            grid-template-columns: 1fr;149            gap: 0.5em 1em;150        }151 152        .cb-kv div:nth-child(odd) {153            font-weight: bold;154            color: #6b778c;155        }156 157        /* Styling untuk nama kini sama dengan value lainnya */158        .cb-kv div:nth-child(even) {159            font-weight: 600;160        }161 162        /* --- Desain Responsif --- */163        @media (min-width: 600px) {164            .cb-actions {165                flex-direction: row;166            }167 168            .cb-btn {169                width: auto;170            }171 172            .cb-kv {173                grid-template-columns: 140px 1fr;174            }175        }176 177        @media (min-width: 900px) {178            .cb-container {179                padding: 2em;180            }181 182            .cb-grid {183                grid-template-columns: 2fr 1fr;184            }185        }186    </style>187</head>188 189<body>190 191    <div class="cb-container" id="cek-bansos-tool">192        <div class="cb-grid">193            <div class="cb-col">194                <h2>Pencarian Data Penerima Manfaat</h2>195 196                <label class="cb-label" for="provinsi">Provinsi</label>197                <select id="provinsi" class="cb-select">198                    <option value="">=== PILIH PROVINSI ===</option>199                </select>200 201                <label class="cb-label" for="kabupaten">Kabupaten/Kota</label>202                <select id="kabupaten" class="cb-select" disabled>203                    <option value="">=== PILIH KABUPATEN/KOTA ===</option>204                </select>205 206                <label class="cb-label" for="kecamatan">Kecamatan</label>207                <select id="kecamatan" class="cb-select" disabled>208                    <option value="">=== PILIH KECAMATAN ===</option>209                </select>210 211                <label class="cb-label" for="desa">Desa/Kelurahan</label>212                <select id="desa" class="cb-select" disabled>213                    <option value="">=== PILIH DESA/KELURAHAN ===</option>214                </select>215 216                <label class="cb-label" for="nama">Nama Penerima (sesuai KTP)</label>217                <input id="nama" class="cb-input" type="text" placeholder="CONTOH: BUDI SANTOSO" />218 219                <div class="cb-actions">220                    <button type="button" id="resetButton" class="cb-btn cb-btn-gray">Atur Ulang</button>221                    <button type="button" id="searchButton" class="cb-btn cb-btn-primary">Cari Data</button>222                </div>223 224                <div class="cb-note">225                    <strong>Catatan:</strong> Ini adalah <em>alat bantu</em> untuk menyiapkan data Anda. Hasil resmi226                    hanya tersedia di situs Kemensos.227                </div>228            </div>229 230            <div class="cb-col">231                <h3>Cara Pakai (Singkat)</h3>232                <ol style="padding-left: 1.5em;">233                    <li>Pilih wilayah domisili lengkap secara berurutan.</li>234                    <li>Ketik nama lengkap sesuai KTP.</li>235                    <li>Klik <strong>Cari Data</strong> untuk melihat ringkasan & tombol menuju situs resmi.</li>236                </ol>237                <div class="cb-disclaimer">238                    <em>Sanggahan:</em> Website ini <strong>bukan</strong> situs resmi Kemensos. Kami hanya menyediakan239                    panduan & tombol akses cepat ke layanan resmi.240                </div>241            </div>242        </div>243 244        <!-- Result box -->245        <div id="resultBox" class="cb-result">246            <h3>Ringkasan Data Anda</h3>247            <div class="cb-kv">248                <div>Nama</div>249                <div id="r-nama">&#8211;</div>250                <div>Provinsi</div>251                <div id="r-prov">&#8211;</div>252                <div>Kab/Kota</div>253                <div id="r-kab">&#8211;</div>254                <div>Kecamatan</div>255                <div id="r-kec">&#8211;</div>256                <div>Desa/Kel</div>257                <div id="r-desa">&#8211;</div>258            </div>259            <p style="margin-top:1.5em; font-size: 0.95em;">260                Untuk <strong>hasil resmi</strong>, lanjut ke layanan Kemensos di tab baru. Siapkan data yang sama saat261                mengisi.262            </p>263            <div class="cb-actions">264                <a id="btn-resmi" class="cb-btn cb-btn-primary" href="https://cekbansos.kemensos.go.id" target="_blank"265                    rel="nofollow noopener">Buka Situs Resmi Kemensos &rarr;</a>266                <button type="button" id="btn-copy" class="cb-btn cb-btn-gray" aria-label="Salin ringkasan">267                    <span id="copy-text">Salin Ringkasan</span>268                </button>269            </div>270        </div>271    </div>272 273    <script>274        document.addEventListener('DOMContentLoaded', () => {275            const provinceSelect = document.getElementById('provinsi');276            const regencySelect = document.getElementById('kabupaten');277            const districtSelect = document.getElementById('kecamatan');278            const villageSelect = document.getElementById('desa');279            const nameInput = document.getElementById('nama');280            const searchButton = document.getElementById('searchButton');281            const resetButton = document.getElementById('resetButton');282            const resultBox = document.getElementById('resultBox');283            const copyButton = document.getElementById('btn-copy');284 285            function populateSelect(selectElement, data, defaultOptionText) {286                selectElement.innerHTML = `<option value="">=== ${defaultOptionText.toUpperCase()} ===</option>`;287                data.forEach(item => {288                    const option = document.createElement('option');289                    option.value = item.id;290                    option.textContent = item.value;291                    selectElement.appendChild(option);292                });293            }294 295            function resetSelects(...selects) {296                selects.forEach(select => {297                    const placeholder = select.options[0].text;298                    select.innerHTML = `<option value="">${placeholder}</option>`;299                    select.disabled = true;300                });301            }302 303            async function fetchData(url) {304                try {305                    const response = await fetch(url);306                    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);307                    return await response.json();308                } catch (error) {309                    console.error("Gagal mengambil data:", error);310                    alert("Gagal memuat data wilayah. Pastikan koneksi internet Anda stabil dan coba lagi.");311                    return [];312                }313            }314 315            (async () => {316                const provinces = await fetchData('/api/provinces');317                populateSelect(provinceSelect, provinces, 'Pilih Provinsi');318            })();319 320            provinceSelect.addEventListener('change', async () => {321                const provinceId = provinceSelect.value;322                resetSelects(regencySelect, districtSelect, villageSelect);323                resultBox.style.display = 'none';324 325                if (provinceId) {326                    let regencies = await fetchData(`/api/provinces/${provinceId}/regencies`);327                    const formattedRegencies = regencies.map(reg => {328                        const isCity = reg.value.toUpperCase().startsWith('KOTA');329                        return { id: reg.id, value: isCity ? reg.value : `KABUPATEN ${reg.value}` };330                    });331                    populateSelect(regencySelect, formattedRegencies, 'Pilih Kabupaten/Kota');332                    regencySelect.disabled = false;333                }334            });335 336            regencySelect.addEventListener('change', async () => {337                const provinceId = provinceSelect.value;338                const regencyId = regencySelect.value;339                resetSelects(districtSelect, villageSelect);340                if (regencyId) {341                    const districts = await fetchData(`/api/provinces/${provinceId}/regencies/${regencyId}/districts`);342                    populateSelect(districtSelect, districts, 'Pilih Kecamatan');343                    districtSelect.disabled = false;344                }345            });346 347            districtSelect.addEventListener('change', async () => {348                const provinceId = provinceSelect.value;349                const regencyId = regencySelect.value;350                const districtId = districtSelect.value;351                resetSelects(villageSelect);352                if (districtId) {353                    const villages = await fetchData(`/api/provinces/${provinceId}/regencies/${regencyId}/districts/${districtId}/villages`);354                    populateSelect(villageSelect, villages, 'Pilih Desa/Kelurahan');355                    villageSelect.disabled = false;356                }357            });358 359            searchButton.addEventListener('click', () => {360                if (!provinceSelect.value || !regencySelect.value || !districtSelect.value || !villageSelect.value || !nameInput.value.trim()) {361                    alert('Mohon lengkapi semua data wilayah dan nama sebelum melanjutkan.');362                    return;363                }364 365                document.getElementById('r-nama').textContent = nameInput.value.trim().toUpperCase();366                document.getElementById('r-prov').textContent = provinceSelect.options[provinceSelect.selectedIndex].text;367                document.getElementById('r-kab').textContent = regencySelect.options[regencySelect.selectedIndex].text;368                document.getElementById('r-kec').textContent = districtSelect.options[districtSelect.selectedIndex].text;369                document.getElementById('r-desa').textContent = villageSelect.options[villageSelect.selectedIndex].text;370 371                resultBox.style.display = 'block';372                resultBox.scrollIntoView({ behavior: 'smooth', block: 'center' });373            });374 375            resetButton.addEventListener('click', () => {376                provinceSelect.selectedIndex = 0;377                nameInput.value = '';378                resetSelects(regencySelect, districtSelect, villageSelect);379                resultBox.style.display = 'none';380            });381 382            copyButton.addEventListener('click', () => {383                const summaryText = `RINGKASAN DATA SAYA:\nNama: ${document.getElementById('r-nama').textContent}\nProvinsi: ${document.getElementById('r-prov').textContent}\nKab/Kota: ${document.getElementById('r-kab').textContent}\nKecamatan: ${document.getElementById('r-kec').textContent}\nDesa/Kel: ${document.getElementById('r-desa').textContent}`;384                navigator.clipboard.writeText(summaryText).then(() => {385                    const copyTextSpan = document.getElementById('copy-text');386                    copyTextSpan.textContent = "Berhasil Disalin! \u2713";387                    setTimeout(() => { copyTextSpan.textContent = "Salin Ringkasan"; }, 2000);388                }).catch(err => {389                    console.error('Gagal menyalin: ', err);390                    alert('Gagal menyalin data secara otomatis.');391                });392            });393        });394         function sendHeight() {395        if (window.parent) {396          const height = document.body.scrollHeight;397          window.parent.postMessage(398            {399              height: height,400            },401            "*"402          );403        }404      }405      // --- Logic for Embedding and Dynamic Resizing ---406      document.addEventListener("DOMContentLoaded", () => {407        // Initial animations on page load408        document.querySelectorAll(".animate__animated").forEach((el, i) => {409          el.style.animationDelay = `${i * 0.1}s`;410        });411 412        // Send initial height to parent window413        sendHeight();414 415        // Use a MutationObserver to watch for any changes in the page content416        // and send the new height to the parent window.417        const observer = new MutationObserver(() => sendHeight());418        observer.observe(document.body, {419          childList: true,420          subtree: true,421          attributes: true,422          characterData: true,423        });424      });425    </script>426 427</body>428 429</html>