promotion page batch delete works
This commit is contained in:
parent
6a4998e64e
commit
0d94f37c4b
|
@ -371,13 +371,17 @@ public function store(Request $request)
|
||||||
$accessToken = $user['access_token'] ?? null;
|
$accessToken = $user['access_token'] ?? null;
|
||||||
|
|
||||||
if (!$accessToken) {
|
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', []);
|
$uuids = $request->input('promotion_uuid', []);
|
||||||
|
|
||||||
if (empty($uuids)) {
|
if (!is_array($uuids) || empty($uuids)) {
|
||||||
return redirect()->back()->with('error', 'No promotions selected for deletion.');
|
return response()->json([
|
||||||
|
'message' => 'No promotions selected for deletion.'
|
||||||
|
], 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = Http::withHeaders([
|
$response = Http::withHeaders([
|
||||||
|
@ -389,14 +393,20 @@ public function store(Request $request)
|
||||||
|
|
||||||
if ($response->successful()) {
|
if ($response->successful()) {
|
||||||
Log::info('Promotions batch deleted successfully: ', $uuids);
|
Log::info('Promotions batch deleted successfully: ', $uuids);
|
||||||
return redirect()->route('promotions')->with('success', 'Selected promotions deleted successfully.');
|
return response()->json([
|
||||||
} else {
|
'message' => $response->json()['message'] ?? 'Selected promotions deleted successfully.'
|
||||||
Log::warning('Failed to batch delete promotions: ', $response->json());
|
], 200);
|
||||||
return redirect()->back()->with('error', $response->json()['message'] ?? 'Failed to delete promotions. Please try again.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
} catch (\Exception $e) {
|
||||||
Log::error('Error batch deleting promotions: ' . $e->getMessage());
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,6 +25,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<!-- Alerts -->
|
||||||
|
<div id="alert-container"></div>
|
||||||
|
|
||||||
<!-- Search and Filters -->
|
<!-- Search and Filters -->
|
||||||
<div class="row mb-3 align-items-center">
|
<div class="row mb-3 align-items-center">
|
||||||
<div class="col-12 col-md-6 mb-2 mb-md-0">
|
<div class="col-12 col-md-6 mb-2 mb-md-0">
|
||||||
|
@ -138,7 +141,6 @@
|
||||||
const rowsPerPage = 5;
|
const rowsPerPage = 5;
|
||||||
let currentPage = tableConfig.currentPage;
|
let currentPage = tableConfig.currentPage;
|
||||||
let filteredRows = [...tableConfig.data];
|
let filteredRows = [...tableConfig.data];
|
||||||
let originalRows = [...tableConfig.data].map(row => ({ ...row }));
|
|
||||||
let sortDirection = {};
|
let sortDirection = {};
|
||||||
|
|
||||||
function renderTable() {
|
function renderTable() {
|
||||||
|
@ -200,8 +202,7 @@
|
||||||
if (!pagination) return;
|
if (!pagination) return;
|
||||||
pagination.innerHTML = '';
|
pagination.innerHTML = '';
|
||||||
|
|
||||||
const totalPages = Math.ceil(filteredRows.length / rowsPerPage);
|
const totalPages = Math.max(1, Math.ceil(filteredRows.length / rowsPerPage));
|
||||||
const routeName = tableConfig.pageTitle === 'Promotions' ? 'promotions.index' : '';
|
|
||||||
|
|
||||||
const prevLi = document.createElement('li');
|
const prevLi = document.createElement('li');
|
||||||
prevLi.className = `page-item ${currentPage === 1 ? 'disabled' : ''}`;
|
prevLi.className = `page-item ${currentPage === 1 ? 'disabled' : ''}`;
|
||||||
|
@ -210,7 +211,8 @@
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (currentPage > 1) {
|
if (currentPage > 1) {
|
||||||
currentPage--;
|
currentPage--;
|
||||||
window.location.href = `/promotions?page=${currentPage}&_search=${tableConfig.search || ''}`;
|
renderTable();
|
||||||
|
renderPagination();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
pagination.appendChild(prevLi);
|
pagination.appendChild(prevLi);
|
||||||
|
@ -222,7 +224,8 @@
|
||||||
li.addEventListener('click', (e) => {
|
li.addEventListener('click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
currentPage = i;
|
currentPage = i;
|
||||||
window.location.href = `/promotions?page=${currentPage}&_search=${tableConfig.search || ''}`;
|
renderTable();
|
||||||
|
renderPagination();
|
||||||
});
|
});
|
||||||
pagination.appendChild(li);
|
pagination.appendChild(li);
|
||||||
}
|
}
|
||||||
|
@ -234,16 +237,17 @@
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (currentPage < totalPages) {
|
if (currentPage < totalPages) {
|
||||||
currentPage++;
|
currentPage++;
|
||||||
window.location.href = `/promotions?page=${currentPage}&_search=${tableConfig.search || ''}`;
|
renderTable();
|
||||||
|
renderPagination();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
pagination.appendChild(nextLi);
|
pagination.appendChild(nextLi);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateNoDataMessage() {
|
function updateNoDataMessage() {
|
||||||
const noDataMessage = document.getElementById('no-data-message');
|
const tableBody = document.getElementById('tableBody');
|
||||||
if (noDataMessage) {
|
if (filteredRows.length === 0) {
|
||||||
noDataMessage.style.display = filteredRows.length === 0 ? 'block' : 'none';
|
tableBody.innerHTML = `<tr><td colspan="${tableConfig.columns.length + (tableConfig.showCheckboxes ? 1 : 0) + (tableConfig.actions.length > 0 ? 1 : 0)}" class="text-center">No data available</td></tr>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,13 +264,6 @@
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
renderTable();
|
renderTable();
|
||||||
renderPagination();
|
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;
|
currentPage = 1;
|
||||||
renderTable();
|
renderTable();
|
||||||
renderPagination();
|
renderPagination();
|
||||||
const url = new URL(window.location);
|
|
||||||
url.searchParams.delete('_search');
|
|
||||||
window.history.pushState({}, '', url);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,29 +334,44 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleteSelected) {
|
if (tableConfig.showBatchDelete && deleteSelected) {
|
||||||
deleteSelected.addEventListener('click', function() {
|
deleteSelected.addEventListener('click', function() {
|
||||||
const selectedUuids = Array.from(document.querySelectorAll('.rowCheckbox:checked')).map(cb => cb.value);
|
const checkboxes = document.querySelectorAll('.rowCheckbox:checked');
|
||||||
if (selectedUuids.length > 0 && confirm('Are you sure you want to delete the selected promotions?')) {
|
const selectedIds = Array.from(checkboxes)
|
||||||
fetch('/promotions/batch-delete', {
|
.map(cb => cb.closest('tr').getAttribute('data-id'));
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
if (selectedIds.length === 0) {
|
||||||
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
showAlert('danger', 'Please select at least one promotion to delete.');
|
||||||
'Content-Type': 'application/json',
|
return;
|
||||||
'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 => {
|
if (confirm('Are you sure you want to delete the selected promotions?')) {
|
||||||
console.error('Error:', error);
|
axios({
|
||||||
alert('An error occurred while deleting the promotions.');
|
method: 'post',
|
||||||
|
url: '{{ route('promotions.batchDelete') }}',
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': tableConfig.csrfToken,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
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,11 +388,25 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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}
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
`;
|
||||||
|
alertContainer.prepend(alert);
|
||||||
|
setTimeout(() => alert.remove(), 5000);
|
||||||
|
}
|
||||||
|
|
||||||
function updateDeleteButton() {
|
function updateDeleteButton() {
|
||||||
const deleteSelected = document.getElementById('deleteSelected');
|
const deleteSelected = document.getElementById('deleteSelected');
|
||||||
const checkedBoxes = document.querySelectorAll('.rowCheckbox:checked');
|
const checkedBoxes = document.querySelectorAll('.rowCheckbox:checked');
|
||||||
|
if (deleteSelected) {
|
||||||
deleteSelected.disabled = checkedBoxes.length === 0;
|
deleteSelected.disabled = checkedBoxes.length === 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderTable();
|
renderTable();
|
||||||
renderPagination();
|
renderPagination();
|
||||||
|
|
|
@ -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::get('/photo-slider/{id}', [PhotoSliderController::class, 'show'])->name('photo-slider.show');
|
||||||
Route::delete('/photo-slider/{id}', [PhotoSliderController::class, 'destroy'])->name('photo-slider.destroy');
|
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');
|
Route::post('photo-slider/batchDelete', [App\Http\Controllers\PhotoSliderController::class, 'batchDelete'])->name('photo-slider.batchDelete');
|
||||||
|
|
||||||
//Notification
|
//Notification
|
||||||
Route::get('/notification', [NotificationController::class, 'index'])->name('notification');
|
Route::get('/notification', [NotificationController::class, 'index'])->name('notification');
|
||||||
Route::get('/notification/create', [NotificationController::class, 'create'])->name('notification.create');
|
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::get('/promotions/{uuid}/edit', [PromotionController::class, 'edit'])->name('promotions.edit');
|
||||||
Route::put('/promotions/{uuid}', [PromotionController::class, 'update'])->name('promotions.update');
|
Route::put('/promotions/{uuid}', [PromotionController::class, 'update'])->name('promotions.update');
|
||||||
Route::delete('/promotions/{uuid}', [PromotionController::class, 'destroy'])->name('promotions.destroy');
|
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
|
//Terms-and-Privacy
|
||||||
Route::get('/terms-and-privacy', [TermsAndPrivacyController::class, 'index'])->name('terms-and-privacy');
|
Route::get('/terms-and-privacy', [TermsAndPrivacyController::class, 'index'])->name('terms-and-privacy');
|
||||||
|
|
Loading…
Reference in New Issue