feat(sync-logs): tambahkan fitur download file CSV
- Tambahkan tombol download file di modal detail sinkronisasi. - Implementasikan pengecekan dan mekanisme download file di `SyncLogsController`. - Tambahkan route baru untuk mendukung proses download file. - Perbarui tampilan dan logika modal untuk mendukung fitur download. - Pastikan validasi file sebelum proses download dan berikan pesan error jika file tidak ditemukan. Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
This commit is contained in:
@@ -123,4 +123,32 @@ class SyncLogsController extends Controller
|
|||||||
|
|
||||||
return response()->json($syncLog, 200, ['Content-Type' => 'application/json'], JSON_PRETTY_PRINT);
|
return response()->json($syncLog, 200, ['Content-Type' => 'application/json'], JSON_PRETTY_PRINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download file
|
||||||
|
*/
|
||||||
|
public function downloadFile($id)
|
||||||
|
{
|
||||||
|
$log = KartuSyncLog::findOrFail($id);
|
||||||
|
|
||||||
|
// Periksa apakah file sudah dibuat
|
||||||
|
if (!$log->is_csv || !$log->file_name) {
|
||||||
|
return redirect()->back()->with('error', 'File CSV belum dibuat');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Periksa apakah file ada di lokasi yang ditunjukkan
|
||||||
|
if ($log->file_path && File::exists($log->file_path)) {
|
||||||
|
return response()->download($log->file_path, $log->file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jika tidak ada di path spesifik, coba cari di direktori umum
|
||||||
|
$path = storage_path('app/biaya_kartu/' . $log->file_name);
|
||||||
|
if (File::exists($path)) {
|
||||||
|
return response()->download($path, $log->file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jika masih tidak ditemukan, beri pesan error
|
||||||
|
return redirect()->back()->with('error', 'File tidak ditemukan di server');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
@extends('layouts.main')
|
@extends('layouts.main')
|
||||||
|
|
||||||
@section('breadcrumbs')
|
@section('breadcrumbs')
|
||||||
@@ -168,8 +167,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a href="#" id="btn-download-file" class="btn btn-success btn-sm me-3 hidden">
|
||||||
|
<i class="ki-outline ki-file-down me-1"></i> Download File
|
||||||
|
</a>
|
||||||
|
<button type="button" class="btn btn-light" data-modal-dismiss="true">Tutup</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@push('scripts')
|
@push('scripts')
|
||||||
@@ -180,7 +186,7 @@
|
|||||||
const filterCsv = document.getElementById('filter-csv');
|
const filterCsv = document.getElementById('filter-csv');
|
||||||
const filterFtp = document.getElementById('filter-ftp');
|
const filterFtp = document.getElementById('filter-ftp');
|
||||||
const detailModal = document.getElementById('detail-modal');
|
const detailModal = document.getElementById('detail-modal');
|
||||||
console.log(detailModal);
|
const btnDownloadFile = document.getElementById('btn-download-file');
|
||||||
|
|
||||||
const apiUrl = element.getAttribute('data-api-url');
|
const apiUrl = element.getAttribute('data-api-url');
|
||||||
const dataTableOptions = {
|
const dataTableOptions = {
|
||||||
@@ -250,6 +256,14 @@
|
|||||||
actions += `<button class="btn btn-sm btn-icon btn-light btn-detail" data-id="${data.id}">
|
actions += `<button class="btn btn-sm btn-icon btn-light btn-detail" data-id="${data.id}">
|
||||||
<i class="ki-outline ki-eye fs-3"></i>
|
<i class="ki-outline ki-eye fs-3"></i>
|
||||||
</button>`;
|
</button>`;
|
||||||
|
|
||||||
|
if (data.is_csv && data.file_name) {
|
||||||
|
actions += `<a href="{{ url('sync-logs/download') }}/${data.id}" class="btn btn-sm btn-icon btn-success" title="Download File">
|
||||||
|
<i class="ki-outline ki-file-down fs-3"></i>
|
||||||
|
</a>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
actions += `</div>`;
|
actions += `</div>`;
|
||||||
return actions;
|
return actions;
|
||||||
},
|
},
|
||||||
@@ -287,7 +301,7 @@
|
|||||||
filterFtp.addEventListener('change', applyFilters);
|
filterFtp.addEventListener('change', applyFilters);
|
||||||
|
|
||||||
// Detail modal functionality
|
// Detail modal functionality
|
||||||
document.addEventListener('click', function(e) {
|
document.addEventListener('click', function (e) {
|
||||||
if (e.target.closest('.btn-detail')) {
|
if (e.target.closest('.btn-detail')) {
|
||||||
const id = e.target.closest('.btn-detail').getAttribute('data-id');
|
const id = e.target.closest('.btn-detail').getAttribute('data-id');
|
||||||
|
|
||||||
@@ -295,7 +309,13 @@
|
|||||||
fetch(`{{ url('sync-logs') }}/${id}`)
|
fetch(`{{ url('sync-logs') }}/${id}`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
console.log(data);
|
if (data.is_csv && data.file_name) {
|
||||||
|
btnDownloadFile.classList.remove('hidden');
|
||||||
|
btnDownloadFile.href = `{{ url('sync-logs/download') }}/${data.id}`;
|
||||||
|
} else {
|
||||||
|
btnDownloadFile.classList.add('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
// Populate modal with data
|
// Populate modal with data
|
||||||
document.getElementById('detail-periode').textContent = data.periode;
|
document.getElementById('detail-periode').textContent = data.periode;
|
||||||
document.getElementById('detail-total-records').textContent = data.total_records;
|
document.getElementById('detail-total-records').textContent = data.total_records;
|
||||||
@@ -329,7 +349,6 @@
|
|||||||
document.getElementById('detail-ftp-notes').textContent = data.ftp_notes || '-';
|
document.getElementById('detail-ftp-notes').textContent = data.ftp_notes || '-';
|
||||||
|
|
||||||
// Show modal
|
// Show modal
|
||||||
|
|
||||||
const modalEl = KTDom.getElement('#detail-modal');
|
const modalEl = KTDom.getElement('#detail-modal');
|
||||||
const modal = KTModal.getInstance(modalEl);
|
const modal = KTModal.getInstance(modalEl);
|
||||||
modal.show();
|
modal.show();
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ Route::middleware(['auth'])->group(function () {
|
|||||||
|
|
||||||
Route::prefix('sync-logs')->name('sync-logs.')->group(function () {
|
Route::prefix('sync-logs')->name('sync-logs.')->group(function () {
|
||||||
Route::get('datatables', [SyncLogsController::class, 'dataForDatatables'])->name('datatables');
|
Route::get('datatables', [SyncLogsController::class, 'dataForDatatables'])->name('datatables');
|
||||||
|
Route::get('/download/{id}', [SyncLogsController::class, 'downloadFile'])->name('download');
|
||||||
|
|
||||||
});
|
});
|
||||||
Route::resource('sync-logs', SyncLogsController::class);
|
Route::resource('sync-logs', SyncLogsController::class);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user