Cancel a specific seat request while keeping other seats in the same issue with a DELETE request:
POST /seat-booked-blocked-cancel
Content-Type: application/json
Authorization: Bearer {your_access_token}
{
"seat_inventory_id": 456,
"trip_id": 1
}
{
"status": "success",
"code": 200,
"message": "Seat request cancelled successfully",
"data": {
"cancelled_seat_request_id": 123,
"seat_inventory_id": 456,
"trip_id": 789,
"seat_info": {
"seat_id": 101,
"seat_number": "A1",
"row_position": 1,
"col_position": 1,
"seat_type": "window"
},
"seat_status": "available",
"request_status": "cancelled",
"blocked_until": null,
"user_id": 25,
"cancelled_at": "2025-08-28T10:30:15.000000Z",
}
}
{
"status": "error",
"code": 404,
"message": "Seat request not found, already cancelled, or you do not have permission to remove it",
"data": null
}
{
"status": "error",
"code": 403,
"message": "You do not have permission to remove this seat request",
"data": null
}
{
"status": "error",
"code": 422,
"message": "The given data was invalid.",
"data": {
"seat_inventory_id": ["The seat inventory id field is required."],
"issue_id": ["The issue id field is required."]
}
}
async function cancelIndividualSeat(seatInventoryId, issueId) {
try {
const response = await fetch('/api/seat-requests/cancel', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('access_token')}`
},
body: JSON.stringify({
seat_inventory_id: seatInventoryId,
issue_id: issueId
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message);
}
const data = await response.json();
console.log('Seat cancelled successfully:');
console.log(`- Cancelled seat: ${data.data.seat_info.seat_number}`);
console.log(`- Remaining seats in issue: ${data.data.remaining_seats_in_issue.total_remaining_seats}`);
// Update UI to reflect cancellation
updateSeatUI(data.data.seat_inventory_id, 'available');
// Update issue summary
updateIssueSummary(data.data.remaining_seats_in_issue);
return data;
} catch (error) {
console.error('Error cancelling seat:', error);
showErrorMessage(`Failed to cancel seat: ${error.message}`);
throw error;
}
}
// Usage example with confirmation
async function cancelSeatWithConfirmation(seatNumber, seatInventoryId, issueId) {
const confirm = window.confirm(`Are you sure you want to cancel seat ${seatNumber}?`);
if (confirm) {
try {
const result = await cancelIndividualSeat(seatInventoryId, issueId);
showSuccessMessage(`Seat ${seatNumber} cancelled successfully`);
// Check if this was the last seat in the issue
if (result.data.remaining_seats_in_issue.total_remaining_seats === 0) {
showInfoMessage('All seats have been cancelled from this issue');
redirectToSeatSelection();
}
return result;
} catch (error) {
// Error handling is done in cancelIndividualSeat
}
} else {
console.log('Seat cancellation aborted by user');
}
}
// Helper functions
function updateSeatUI(seatInventoryId, status) {
const seatElement = document.querySelector(`[data-seat-inventory-id="${seatInventoryId}"]`);
if (seatElement) {
seatElement.classList.remove('selected', 'blocked');
seatElement.classList.add(status);
}
}
function updateIssueSummary(remainingSeats) {
const summaryElement = document.getElementById('issue-summary');
if (summaryElement) {
summaryElement.innerHTML = `
Issue: ${remainingSeats.issue_id}
Remaining seats: ${remainingSeats.total_remaining_seats}
`;
}
}
function showSuccessMessage(message) {
// Your success notification implementation
console.log('[SUCCESS]', message);
}
function showErrorMessage(message) {
// Your error notification implementation
console.log('[ERROR]', message);
}
function showInfoMessage(message) {
// Your info notification implementation
console.log('[INFO]', message);
}
function redirectToSeatSelection() {
// Redirect to seat selection page
window.location.href = '/select-seats';
}