From 5efa793db5c8b58633232e560bf766c8b01b229c Mon Sep 17 00:00:00 2001 From: ahmad afandi Date: Thu, 14 Aug 2025 14:13:55 +0700 Subject: [PATCH 1/3] Tambahkan kolom nama desa pada halaman menu bantuan OpenKab --- resources/views/bantuan/index.blade.php | 311 +++++++++--------- .../excel-download-button.blade.php | 205 ++++++++++++ resources/views/penduduk/index.blade.php | 153 +-------- 3 files changed, 367 insertions(+), 302 deletions(-) create mode 100644 resources/views/components/excel-download-button.blade.php diff --git a/resources/views/bantuan/index.blade.php b/resources/views/bantuan/index.blade.php index e5db85038..4466f0814 100644 --- a/resources/views/bantuan/index.blade.php +++ b/resources/views/bantuan/index.blade.php @@ -23,6 +23,7 @@ + @@ -80,6 +81,7 @@ class="fas fa-search"> No Aksi + Nama {{ config('app.sebutanDesa') }} Nama Program Asal Dana Jumlah Peseerta @@ -98,178 +100,187 @@ class="fas fa-search"> @endsection @section('js') - @endsection diff --git a/resources/views/components/excel-download-button.blade.php b/resources/views/components/excel-download-button.blade.php new file mode 100644 index 000000000..85ec96e5b --- /dev/null +++ b/resources/views/components/excel-download-button.blade.php @@ -0,0 +1,205 @@ +@props([ + 'id' => 'download-excel', + 'label' => 'Excel', + 'size' => 'btn-sm', + 'variant' => 'btn-success', + 'icon' => 'fa fa-file-excel', + 'disabled' => false, + 'loadingText' => 'Downloading...', + 'downloadUrl' => '', + 'tableId' => '', + 'filename' => 'data_export', + 'apiHeaders' => [], + 'additionalParams' => [], + 'class' => '', +]) + + + +@once + @push('js') + + @endpush +@endonce diff --git a/resources/views/penduduk/index.blade.php b/resources/views/penduduk/index.blade.php index 1add1f804..0f50d28d4 100644 --- a/resources/views/penduduk/index.blade.php +++ b/resources/views/penduduk/index.blade.php @@ -44,10 +44,7 @@ Cetak - + @@ -373,10 +370,6 @@ className: 'text-nowrap', window.open(`{{ url('penduduk/cetak') }}?${$.param(penduduk.ajax.params())}`, '_blank'); }); - $('#download-excel').on('click', function() { - downloadExcel(); - }); - $('select.select2-filter').each(function() { $(this).select2({ width: '100%', @@ -488,149 +481,5 @@ function getDataset(data, chart) { value: val.total })); } - - // Function to download Excel - async function downloadExcel() { - try { - const header = @include('layouts.components.header_bearer_api_gabungan'); - // Check if there's data to download - const tableData = $('#penduduk').DataTable(); - const info = tableData.page.info(); - const totalData = info.recordsTotal; - if (totalData === 0) { - Swal.fire({ - icon: 'warning', - title: 'Tidak Ada Data', - text: 'Tidak ada data penduduk untuk diunduh. Silakan periksa filter Anda.', - confirmButtonText: 'OK' - }); - return; - } - - // Show loading state - const $btnExcel = $('#download-excel'); - $btnExcel.prop('disabled', true).html( - ' Downloading...'); - - // Prepare URL for download - const downloadUrl = new URL( - `{{ config('app.databaseGabunganUrl') }}/api/v1/penduduk/download`); - - // Gunakan fungsi data yang sama persis dengan DataTable untuk konsistensi - const filterParams = tableData.ajax.params(); - - // Remove pagination parameters since we want all data - delete filterParams['page[size]']; - delete filterParams['page[number]']; - - // Handle umur filter - convert object to separate min/max parameters for backend - if (filterParams['filter[umur]'] && typeof filterParams['filter[umur]'] === 'object') { - const umurObj = filterParams['filter[umur]']; - - // Create separate parameters for min and max - if (umurObj.min && umurObj.min !== '') { - filterParams['filter[umur][min]'] = umurObj.min; - } - if (umurObj.max && umurObj.max !== '') { - filterParams['filter[umur][max]'] = umurObj.max; - } - if (umurObj.satuan) { - filterParams['filter[umur][satuan]'] = umurObj.satuan; - } - - // Remove the original object parameter - delete filterParams['filter[umur]']; - } - - // Convert filterParams to URLSearchParams for proper encoding - const urlParams = new URLSearchParams(); - Object.keys(filterParams).forEach(key => { - const value = filterParams[key]; - if (value !== null && value !== undefined && value !== '' && value !== 'null') { - urlParams.append(key, value); - } - }); - - urlParams.append('totalData', totalData); - - // Make fetch request - const response = await fetch(downloadUrl, { - method: 'POST', - headers: { - ...header, - 'Content-Type': 'application/x-www-form-urlencoded', - 'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - }, - body: urlParams - }); - - if (!response.ok) { - const errorText = await response.text(); - throw new Error(`HTTP ${response.status}: ${errorText}`); - } - - // Check if response is actually a file - const contentType = response.headers.get('content-type'); - if (!contentType || (!contentType.includes( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') && ! - contentType.includes('application/vnd.ms-excel'))) { - throw new Error('Response is not a valid Excel file'); - } - - // Get filename from response headers or generate one - const contentDisposition = response.headers.get('content-disposition'); - let filename = 'data_penduduk.xlsx'; - if (contentDisposition) { - const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(contentDisposition); - if (matches != null && matches[1]) { - filename = matches[1].replace(/['"]/g, ''); - } - } else { - // Generate filename with timestamp - const now = new Date(); - const timestamp = now.toISOString().slice(0, 19).replace(/[-:T]/g, ''); - filename = `data_penduduk_${timestamp}.xlsx`; - } - - // Create blob and download - const blob = await response.blob(); - const url = window.URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = filename; - document.body.appendChild(a); - a.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(a); - - // Show success message - Swal.fire({ - icon: 'success', - title: 'Berhasil!', - text: `File Excel "${filename}" berhasil diunduh`, - timer: 3000, - showConfirmButton: false - }); - - } catch (error) { - console.error('Download error:', error); - - // Show error message with SweetAlert - Swal.fire({ - icon: 'error', - title: 'Gagal Download!', - html: ` -

Terjadi kesalahan saat mengunduh file Excel:

-

${error.message}

-

Silakan coba lagi atau hubungi administrator.

- `, - confirmButtonText: 'OK' - }); - } finally { - // Reset button state - const $btnExcel = $('#download-excel'); - $btnExcel.prop('disabled', false).html(' Excel'); - } - } @endsection From 10733073bd299013da288c957afbd9cfb14affaf Mon Sep 17 00:00:00 2001 From: ahmad afandi Date: Thu, 14 Aug 2025 14:35:39 +0700 Subject: [PATCH 2/3] perbaikan cetak --- resources/views/bantuan/cetak.blade.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/resources/views/bantuan/cetak.blade.php b/resources/views/bantuan/cetak.blade.php index b006ffed0..2c67f42c4 100644 --- a/resources/views/bantuan/cetak.blade.php +++ b/resources/views/bantuan/cetak.blade.php @@ -10,24 +10,23 @@ try { const headers = @include('layouts.components.header_bearer_api_gabungan'); var create_url = new URL({{ json_encode(config('app.databaseGabunganUrl')) }} + '/api/v1/bantuan/cetak'); - + create_url.searchParams.set('kode_kecamatan', {{ json_encode(session('kecamatan.kode_kecamatan') ?? '') }}); create_url.searchParams.set('config_desa', {{ json_encode(session('desa.id') ?? '') }}); - + @foreach ($filter as $key => $value) - create_url.searchParams.append('filter[{{ $key }}]', {{ json_encode($value) }}); - @endforeach - + create_url.searchParams.append('filter[{{ $key }}]', {{ json_encode($value) }}); @endforeach + const response = await fetch(create_url.href, { method: 'GET', headers: headers }); - + if (!response.ok) throw new Error('Gagal mengambil data'); - + const result = await response.json(); this.data = result.data; - + await $nextTick(); window.print(); } catch (error) { @@ -40,6 +39,7 @@ No + Nama {{ config('app.sebutanDesa') }} Nama Program Asal Dana Jumlah Peserta @@ -52,6 +52,7 @@