feat: loading indicator on initial page load
This commit is contained in:
@@ -37,26 +37,46 @@ class IndexController extends AbstractController
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point for starting a new booking.
|
||||
*
|
||||
* Renders a loading page that triggers the actual initialization via HTMX.
|
||||
* This provides immediate visual feedback while BusProNet API calls are made.
|
||||
*/
|
||||
#[Route(
|
||||
path: '/bookings/create',
|
||||
name: 'app_booking_create',
|
||||
)]
|
||||
public function index(#[MapQueryString] ?BookingQueryParams $params): Response
|
||||
{
|
||||
if (null === $params) {
|
||||
throw $this->createNotFoundException('Invalid booking parameters provided');
|
||||
}
|
||||
|
||||
return $this->render('booking/create/index.html.twig', [
|
||||
'params' => $params,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a fresh booking session and redirects to the login page.
|
||||
*
|
||||
* This endpoint provides a clean way to start the booking flow with just
|
||||
* dateId and hotelId parameters. It clears any existing booking session,
|
||||
* creates a fresh BookingDto, and redirects to the login page where users
|
||||
* can authenticate (for prepopulation) or continue as guest.
|
||||
* This endpoint is triggered via HTMX from the loading page. It clears any
|
||||
* existing booking session, creates a fresh BookingDto, and redirects to
|
||||
* the login page where users can authenticate or continue as guest.
|
||||
*
|
||||
* Optionally accepts an agency code parameter. If provided and valid, the
|
||||
* corresponding agency ID is stored in the booking. If not provided or invalid,
|
||||
* defaults to agency code '0001'.
|
||||
*/
|
||||
#[Route(
|
||||
path: '/bookings/create',
|
||||
path: '/bookings/create/init',
|
||||
name: 'app_booking_create_init',
|
||||
)]
|
||||
public function init(Request $request, #[MapQueryString] ?BookingQueryParams $params): Response
|
||||
{
|
||||
if (null === $params) {
|
||||
throw $this->createNotFoundException('Invalid booking parameters provided');
|
||||
return $this->htmxRedirect($request, $this->generateUrl('app_booking_create_error'));
|
||||
}
|
||||
|
||||
$dateId = $params->dateId;
|
||||
@@ -85,15 +105,9 @@ class IndexController extends AbstractController
|
||||
);
|
||||
|
||||
// Redirect to login page (optional authentication before Step 1)
|
||||
return $this->redirectToRoute('app_login');
|
||||
} catch (TravelNotFoundException) {
|
||||
throw $this->createNotFoundException(sprintf('Travel not found for date ID %d', $dateId));
|
||||
} catch (HotelNotFoundException) {
|
||||
throw $this->createNotFoundException(sprintf('Hotel not found for hotel ID %d', $hotelId));
|
||||
} catch (HotelNotInTravelException) {
|
||||
throw $this->createNotFoundException(sprintf('Hotel ID %d is not available for travel ID %d', $hotelId, $dateId));
|
||||
} catch (NoRoomsAvailableException) {
|
||||
throw $this->createNotFoundException('No rooms available for this travel.');
|
||||
return $this->htmxRedirect($request, $this->generateUrl('app_login'));
|
||||
} catch (TravelNotFoundException|HotelNotFoundException|HotelNotInTravelException|NoRoomsAvailableException) {
|
||||
return $this->htmxRedirect($request, $this->generateUrl('app_booking_create_error'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{% extends 'layout_booking.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="flex-1 flex items-center justify-center"
|
||||
hx-get="{{ path('app_booking_create_init', {
|
||||
date_id: params.dateId,
|
||||
hotel_id: params.hotelId,
|
||||
agency: params.agency,
|
||||
theme: params.theme,
|
||||
r: params.returnUrl
|
||||
}) }}"
|
||||
hx-trigger="load"
|
||||
hx-swap="none">
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user