# Loading Indicators Implementation Plan
## Overview
Add loading indicators to Step 3 and Step 4 of the booking flow to provide visual feedback during slow API calls.
**Date:** 2025-10-06
**Status:** π Planned (not yet implemented)
## Problem Statement
**Current User Experience:**
- Step 3: User clicks "Weiter" β 2-3 second wait (inquiry API) β No visual feedback
- Step 4: User clicks "Verbindlich buchen" β 1-2 second wait (booking API) β No visual feedback
- Users may click multiple times thinking the form didn't submit
- No indication that processing is happening
## Solution
Use HTMX for form submissions with built-in loading indicators.
### Why HTMX?
1. β
Already extensively used in the project (Step 2 form refreshes)
2. β
Built-in loading state management via `hx-indicator`
3. β
Better error handling (no page reload on validation errors)
4. β
Progressive enhancement (graceful degradation)
5. β
Consistent with existing architecture
## Implementation Details
### Step 1: Add HTMX Indicator Styles
**File:** `assets/styles/app.css`
Add global styles for HTMX loading indicators:
```css
/* HTMX Loading Indicator */
.htmx-indicator {
display: none;
}
.htmx-request .htmx-indicator {
display: flex;
}
.htmx-request.htmx-indicator {
display: flex;
}
```
### Step 2: Update Step 3 Form
**File:** `templates/booking/create_step_3.html.twig`
**Changes:**
1. Add HTMX attributes to form:
```twig
{{ form_start(form, {
'attr': {
'novalidate': 'novalidate',
'hx-post': path('app_booking_create_step_3'),
'hx-swap': 'none',
'hx-indicator': '#step3-loading'
}
}) }}
```
2. Add loading overlay before form close:
```twig
{# Loading indicator #}
Buchung wird validiert...
{{ form_end(form) }}
```
**File:** `src/Controller/Booking/CreateStep3Controller.php`
**Changes:**
Add HTMX detection and response handling:
```php
public function step3(Request $request): Response
{
// ... existing validation logic ...
if ($form->isSubmitted() && $form->isValid()) {
try {
// ... existing inquiry + price validation logic ...
// Validation successful - proceed to confirmation step
$bookingCreateDto->currentStep = 4;
$this->bookingService->saveBookingCreateDto($request, $bookingCreateDto);
// Handle HTMX requests
if ($request->headers->get('HX-Request')) {
return new Response('', 200, [
'HX-Redirect' => $this->generateUrl('app_booking_create_step_4')
]);
}
return $this->redirectToRoute('app_booking_create_step_4');
} catch (\Exception $e) {
// ... existing error handling ...
}
}
return $this->render('booking/create_step_3.html.twig', [
'bookingCreateDto' => $bookingCreateDto,
'form' => $form->createView(),
...$this->getSummaryVariables($bookingCreateDto),
]);
}
```
### Step 3: Update Step 4 Form
**File:** `templates/booking/create_step_4.html.twig`
**Changes:**
1. Add HTMX attributes to form (find `form_start`):
```twig
{{ form_start(form, {
'attr': {
'novalidate': 'novalidate',
'hx-post': path('app_booking_create_step_4'),
'hx-swap': 'none',
'hx-indicator': '#step4-loading'
}
}) }}
```
2. Add loading overlay before submit button:
```twig
{# Loading indicator #}
Buchung wird durchgefΓΌhrt...
{{ form_end(form) }}
```
**File:** `src/Controller/Booking/CreateStep4Controller.php`
**Changes:**
Add HTMX response handling:
```php
public function step4(Request $request): Response
{
// ... existing code ...
if ($form->isSubmitted() && $form->isValid()) {
try {
// Submit final booking (already validated in Step 3)
$bookingResponse = $this->apiClient->createBooking($bookingCreateDto);
// ... existing error handling ...
// Success: Store booking number in flash and clear session
$this->addFlash('booking_number', $bookingResponse->transactionNumber);
$this->bookingService->clearBookingCreateDto($request);
// Handle HTMX requests
if ($request->headers->get('HX-Request')) {
return new Response('', 200, [
'HX-Redirect' => $this->generateUrl('app_booking_success')
]);
}
return $this->redirectToRoute('app_booking_success');
} catch (\Exception $e) {
// ... existing error handling ...
}
}
return $this->render('booking/create_step_4.html.twig', [
'bookingCreateDto' => $bookingCreateDto,
'form' => $form->createView(),
...$this->getSummaryVariables($bookingCreateDto),
]);
}
```
## Alternative: Stimulus-Only Approach
If HTMX is not desired, use the existing `loading_controller.js`:
**Template:**
```twig
{{ form_start(form, {'attr': {'data-action': 'submit->loading#toggle'}}) }}
{{ form_end(form) }}
```
**Pros:** Simpler, no controller changes
**Cons:**
- Loading indicator persists if server returns error
- Page reload happens anyway
- No error handling improvement
## Files to Modify
### Templates:
1. `templates/booking/create_step_3.html.twig` - Add HTMX attributes + loading indicator
2. `templates/booking/create_step_4.html.twig` - Add HTMX attributes + loading indicator
### Controllers:
3. `src/Controller/Booking/CreateStep3Controller.php` - Add HTMX response handling
4. `src/Controller/Booking/CreateStep4Controller.php` - Add HTMX response handling
### Styles:
5. `assets/styles/app.css` - Add `.htmx-indicator` styles (if not already present)
## Benefits
**User Experience:**
- β
Clear visual feedback during API calls
- β
Prevents duplicate submissions (button disabled during request)
- β
Professional loading experience
- β
Reduced user confusion and frustration
**Technical:**
- β
Better error handling (no page reload on validation errors)
- β
Consistent with existing HTMX usage in Step 2
- β
Progressive enhancement (works without JavaScript)
- β
Flash messages still work via HX-Redirect
## Testing Checklist
- [ ] Step 3: Loading indicator shows during inquiry API call
- [ ] Step 3: Form disabled during submission
- [ ] Step 3: Success redirects to Step 4
- [ ] Step 3: Validation errors show inline without reload
- [ ] Step 4: Loading indicator shows during booking API call
- [ ] Step 4: Form disabled during submission
- [ ] Step 4: Success redirects to success page with flash message
- [ ] Step 4: Errors show inline without reload
- [ ] Works without JavaScript (graceful degradation)
- [ ] No duplicate submissions possible
## Implementation Priority
**High Priority** - Significantly improves UX during slow API operations
## Notes
- HTMX already included in project dependencies
- Loading indicators match existing design system
- Compatible with all existing validation logic
- No changes to backend business logic required