The booking list at /bookings is the central hub for managing your charging reservations. But until today, if you wanted to cancel an active session, there was no obvious way to do it from the list view. You had to know the endpoint existed or dig through other flows.
That's fixed now. Every booking card — whether pending, confirmed, or actively charging — now has a Cancel button. Click it and a clean confirmation dialog appears, explaining what happens when you cancel: the booking is terminated and any holds or fees are released per the station's policy.
The confirmation dialog is not the browser's clunky confirm() box. It's a proper themed modal that matches the ChargePeer design system — dark background, danger-red accent, clear two-button choice between "Keep Booking" and "Yes, Cancel Booking". A loading state prevents double-submission while the request processes.
Under the hood, the cancel flow calls POST /api/bookings/{id}/cancel — an endpoint that has existed server-side but lacked a UI entry point for active bookings. The modal pattern is reusable: CancelConfirmModal.svelte accepts a bookingId and onConfirm callback, making it easy to add cancellation confirmation anywhere in the app.
After a successful cancellation, the booking disappears from the list and a success toast confirms the action. If the API fails (network issue, server error), an error toast appears instead and the booking stays in place — no silent failures.
This is a small UX improvement with big impact: one less context switch, one less moment of uncertainty. Cancel with confidence.