diff --git a/app/Http/Controllers/PromotionController.php b/app/Http/Controllers/PromotionController.php index 9b8f9cb..62abd78 100644 --- a/app/Http/Controllers/PromotionController.php +++ b/app/Http/Controllers/PromotionController.php @@ -371,13 +371,17 @@ public function store(Request $request) $accessToken = $user['access_token'] ?? null; if (!$accessToken) { - return redirect()->route('login')->with('error', 'Please log in to delete promotions.'); + return response()->json([ + 'message' => 'Please log in to delete promotions.' + ], 401); } $uuids = $request->input('promotion_uuid', []); - if (empty($uuids)) { - return redirect()->back()->with('error', 'No promotions selected for deletion.'); + if (!is_array($uuids) || empty($uuids)) { + return response()->json([ + 'message' => 'No promotions selected for deletion.' + ], 422); } $response = Http::withHeaders([ @@ -389,14 +393,20 @@ public function store(Request $request) if ($response->successful()) { Log::info('Promotions batch deleted successfully: ', $uuids); - return redirect()->route('promotions')->with('success', 'Selected promotions deleted successfully.'); - } else { - Log::warning('Failed to batch delete promotions: ', $response->json()); - return redirect()->back()->with('error', $response->json()['message'] ?? 'Failed to delete promotions. Please try again.'); + return response()->json([ + 'message' => $response->json()['message'] ?? 'Selected promotions deleted successfully.' + ], 200); } + + Log::warning('Failed to batch delete promotions: ', $response->json()); + return response()->json([ + 'message' => $response->json()['message'] ?? 'Failed to delete promotions. Please try again.' + ], $response->status()); } catch (\Exception $e) { Log::error('Error batch deleting promotions: ' . $e->getMessage()); - return redirect()->back()->with('error', 'An error occurred while deleting the promotions.'); + return response()->json([ + 'message' => 'An error occurred while deleting the promotions: ' . $e->getMessage() + ], 500); } } } \ No newline at end of file diff --git a/resources/views/components/promotion-component.blade.php b/resources/views/components/promotion-component.blade.php index b1f01a3..90ae395 100644 --- a/resources/views/components/promotion-component.blade.php +++ b/resources/views/components/promotion-component.blade.php @@ -25,6 +25,9 @@
+ +
+
@@ -138,7 +141,6 @@ const rowsPerPage = 5; let currentPage = tableConfig.currentPage; let filteredRows = [...tableConfig.data]; - let originalRows = [...tableConfig.data].map(row => ({ ...row })); let sortDirection = {}; function renderTable() { @@ -200,8 +202,7 @@ if (!pagination) return; pagination.innerHTML = ''; - const totalPages = Math.ceil(filteredRows.length / rowsPerPage); - const routeName = tableConfig.pageTitle === 'Promotions' ? 'promotions.index' : ''; + const totalPages = Math.max(1, Math.ceil(filteredRows.length / rowsPerPage)); const prevLi = document.createElement('li'); prevLi.className = `page-item ${currentPage === 1 ? 'disabled' : ''}`; @@ -210,7 +211,8 @@ e.preventDefault(); if (currentPage > 1) { currentPage--; - window.location.href = `/promotions?page=${currentPage}&_search=${tableConfig.search || ''}`; + renderTable(); + renderPagination(); } }); pagination.appendChild(prevLi); @@ -222,7 +224,8 @@ li.addEventListener('click', (e) => { e.preventDefault(); currentPage = i; - window.location.href = `/promotions?page=${currentPage}&_search=${tableConfig.search || ''}`; + renderTable(); + renderPagination(); }); pagination.appendChild(li); } @@ -234,16 +237,17 @@ e.preventDefault(); if (currentPage < totalPages) { currentPage++; - window.location.href = `/promotions?page=${currentPage}&_search=${tableConfig.search || ''}`; + renderTable(); + renderPagination(); } }); pagination.appendChild(nextLi); } function updateNoDataMessage() { - const noDataMessage = document.getElementById('no-data-message'); - if (noDataMessage) { - noDataMessage.style.display = filteredRows.length === 0 ? 'block' : 'none'; + const tableBody = document.getElementById('tableBody'); + if (filteredRows.length === 0) { + tableBody.innerHTML = `No data available`; } } @@ -260,13 +264,6 @@ currentPage = 1; renderTable(); renderPagination(); - const url = new URL(window.location); - if (searchTerm) { - url.searchParams.set('_search', searchTerm); - } else { - url.searchParams.delete('_search'); - } - window.history.pushState({}, '', url); }); } @@ -317,9 +314,6 @@ currentPage = 1; renderTable(); renderPagination(); - const url = new URL(window.location); - url.searchParams.delete('_search'); - window.history.pushState({}, '', url); }); } @@ -340,30 +334,45 @@ }); } - if (deleteSelected) { + if (tableConfig.showBatchDelete && deleteSelected) { deleteSelected.addEventListener('click', function() { - const selectedUuids = Array.from(document.querySelectorAll('.rowCheckbox:checked')).map(cb => cb.value); - if (selectedUuids.length > 0 && confirm('Are you sure you want to delete the selected promotions?')) { - fetch('/promotions/batch-delete', { - method: 'POST', + const checkboxes = document.querySelectorAll('.rowCheckbox:checked'); + const selectedIds = Array.from(checkboxes) + .map(cb => cb.closest('tr').getAttribute('data-id')); + + if (selectedIds.length === 0) { + showAlert('danger', 'Please select at least one promotion to delete.'); + return; + } + + if (confirm('Are you sure you want to delete the selected promotions?')) { + axios({ + method: 'post', + url: '{{ route('promotions.batchDelete') }}', headers: { - 'X-CSRF-TOKEN': '{{ csrf_token() }}', + 'X-CSRF-TOKEN': tableConfig.csrfToken, 'Content-Type': 'application/json', - 'Accept': 'application/json', }, - body: JSON.stringify({ promotion_uuid: selectedUuids }) - }).then(response => response.json()) - .then(data => { - if (data.success) { - location.reload(); - } else { - alert(data.message || 'Error deleting promotions'); - } - }) - .catch(error => { - console.error('Error:', error); - alert('An error occurred while deleting the promotions.'); - }); + data: { + promotion_uuid: selectedIds + } + }).then(response => { + // Remove deleted rows from filteredRows and tableConfig.data + filteredRows = filteredRows.filter(row => !selectedIds.includes(row.id)); + tableConfig.data = tableConfig.data.filter(row => !selectedIds.includes(row.id)); + tableConfig.total -= selectedIds.length; + tableConfig.lastPage = Math.max(1, Math.ceil(tableConfig.total / rowsPerPage)); + if (currentPage > tableConfig.lastPage) { + currentPage = tableConfig.lastPage; + } + renderTable(); + renderPagination(); + showAlert('success', response.data.message || 'Selected promotions deleted successfully.'); + }).catch(error => { + console.error('Batch delete error:', error); + const errorMessage = error.response?.data?.message || 'Failed to delete promotions.'; + showAlert('danger', errorMessage); + }); } }); } @@ -379,10 +388,24 @@ }); } + function showAlert(type, message) { + const alertContainer = document.getElementById('alert-container') || document.querySelector('.card-body'); + const alert = document.createElement('div'); + alert.className = `alert alert-${type} alert-dismissible fade show`; + alert.innerHTML = ` + ${message} + + `; + alertContainer.prepend(alert); + setTimeout(() => alert.remove(), 5000); + } + function updateDeleteButton() { const deleteSelected = document.getElementById('deleteSelected'); const checkedBoxes = document.querySelectorAll('.rowCheckbox:checked'); - deleteSelected.disabled = checkedBoxes.length === 0; + if (deleteSelected) { + deleteSelected.disabled = checkedBoxes.length === 0; + } } renderTable(); diff --git a/routes/web.php b/routes/web.php index 282c23c..6abad72 100644 --- a/routes/web.php +++ b/routes/web.php @@ -157,6 +157,7 @@ Route::put('/photo-slider/{id}', [PhotoSliderController::class, 'update'])->name Route::get('/photo-slider/{id}', [PhotoSliderController::class, 'show'])->name('photo-slider.show'); Route::delete('/photo-slider/{id}', [PhotoSliderController::class, 'destroy'])->name('photo-slider.destroy'); Route::post('photo-slider/batchDelete', [App\Http\Controllers\PhotoSliderController::class, 'batchDelete'])->name('photo-slider.batchDelete'); + //Notification Route::get('/notification', [NotificationController::class, 'index'])->name('notification'); Route::get('/notification/create', [NotificationController::class, 'create'])->name('notification.create'); @@ -177,7 +178,7 @@ Route::get('/promotions/{uuid}', [PromotionController::class, 'show'])->name('pr Route::get('/promotions/{uuid}/edit', [PromotionController::class, 'edit'])->name('promotions.edit'); Route::put('/promotions/{uuid}', [PromotionController::class, 'update'])->name('promotions.update'); Route::delete('/promotions/{uuid}', [PromotionController::class, 'destroy'])->name('promotions.destroy'); -Route::post('/promotions/batch-delete', [PromotionController::class, 'batchDelete'])->name('promotions.batch-delete'); +Route::post('/promotions/batch-delete', [PromotionController::class, 'batchDelete'])->name('promotions.batchDelete'); //Terms-and-Privacy Route::get('/terms-and-privacy', [TermsAndPrivacyController::class, 'index'])->name('terms-and-privacy');