Files
carmanagement/docs/ProgressiveReservationCreation.md
T
root 3d6607e6c8
Build & Deploy / Build & Push Docker Image (push) Successful in 8m27s
Test / Type Check (all packages) (push) Successful in 3m34s
Build & Deploy / Deploy to VPS (push) Successful in 2s
Test / API Unit Tests (push) Failing after 3m16s
Test / Homepage Unit Tests (push) Failing after 2m40s
Test / Storefront Unit Tests (push) Failing after 24s
Test / Admin Unit Tests (push) Failing after 22s
Test / Dashboard Unit Tests (push) Failing after 24s
Test / API Integration Tests (push) Failing after 33s
make the booking in many steps
2026-06-29 08:54:41 -04:00

635 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Progressive Reservation Creation: Action Plan
## 1. Objective
Replace the single long reservation form at:
`/dashboard/reservations/new`
with a progressive wizard that:
* Shows one focused section at a time.
* Validates only the current section before continuing.
* Preserves entered information when moving backward or forward.
* Provides a final review before creating the reservation.
* Works correctly in English, French, and Arabic.
* Supports desktop, mobile, light mode, dark mode, LTR, and RTL.
* Prevents duplicate submissions and handles partial API failures safely.
The reservation should not be created until the user confirms the final review step.
---
## 2. Problems in the Current Implementation
The existing page combines all responsibilities inside one component:
* Customer search and selection.
* New customer creation.
* Customer identity information.
* Driver license information.
* License image upload.
* Vehicle selection.
* Rental dates and locations.
* Deposit and payment method.
* Additional driver information.
* Notes.
* Validation.
* Customer creation and updates.
* Reservation submission.
* Translated copy.
This creates several practical problems:
1. The user sees too much information at once.
2. Validation returns one generic error instead of identifying the exact field.
3. Adding a customer is confusing because required identity and license fields appear outside the customer creation panel.
4. Navigation away from the page loses the entire form.
5. Customer updates, license uploads, and reservation creation can partially succeed.
6. The component will become increasingly difficult to maintain.
7. Vehicle availability is currently based only on `status === 'AVAILABLE'`, not the selected rental dates. That does not reliably prevent conflicting reservations.
---
## 3. Proposed Wizard Structure
Use six fixed steps. Six is the upper reasonable limit here. More steps would create needless clicking; fewer would leave several sections overloaded.
### Step 1: Customer
Purpose: Identify who is making the reservation.
Fields and actions:
* Choose `Existing customer` or `New customer`.
* Search existing customers.
* Select an existing customer.
* For a new customer:
* First name.
* Arabic first name.
* Last name.
* Arabic last name.
* Email.
* Phone.
Completion requirements:
* Existing customer mode: a customer must be selected.
* New customer mode: first name, last name, email, and phone must be valid.
Important behavior:
* Selecting an existing customer preloads known identity and license data.
* Creating a new customer should not call the API at this step.
* Switching between existing and new customer modes must not silently mix the two records.
* Changing the selected customer after editing loaded data should display a confirmation before replacing those edits.
### Step 2: Identity
Purpose: Verify the renters personal information.
Fields:
* Date of birth.
* Nationality.
* CIN or passport number.
* Full address.
* International permit number, optional.
Completion requirements:
* Date of birth is present and in the past.
* Nationality is present.
* Identity document number is present.
* Full address is present.
The section should display whether values were loaded from an existing customer and allow the user to correct them.
### Step 3: Driver License
Purpose: Verify that the primary renter is legally eligible to drive.
Fields:
* Driver license number.
* License country.
* License issue date.
* License expiry date.
* License category.
* License image, optional unless business rules later require it.
Completion requirements:
* Required license fields are complete.
* Issue date is not in the future.
* Expiry date is after the issue date.
* Expiry date has not already passed.
* Uploaded file is a supported image type and within the configured size limit.
The current image and newly selected preview should be clearly distinguished.
### Step 4: Rental Details
Purpose: Define what is being rented and when.
Recommended field order:
1. Start date and time.
2. End date and time.
3. Vehicle.
4. Pickup location.
5. Return location.
Completion requirements:
* Start date is valid.
* End date is later than the start date.
* A vehicle is selected.
* The vehicle remains available for the chosen period.
Important correction:
The current implementation lists vehicles using only their general `AVAILABLE` status. The final implementation should request or revalidate date-based availability. A vehicle can be marked available now while already reserved for the requested dates.
If the API does not currently support date-based availability, this must be recorded as a backend dependency rather than pretending the status filter is sufficient.
### Step 5: Payment and Extras
Purpose: Collect optional and commercial details.
Main fields:
* Deposit amount.
* Payment method.
* Notes.
Optional additional driver:
* Display a compact `Add another driver` control.
* Opening it reveals an additional-driver panel or nested form.
* Allow removal before submission.
* Structure the state as an array even if the current interface initially supports only one driver.
Additional-driver fields:
* First and last name.
* Arabic first and last name.
* Email, optional.
* Phone, optional.
* Date of birth, optional.
* Nationality, optional.
* License number.
* License issue date, optional.
* License expiry date, optional.
Completion requirements:
* Deposit cannot be negative.
* A payment method must be selected.
* If an additional driver is enabled, name and license number are required.
* Any entered additional-driver dates must be logically valid.
### Step 6: Review and Confirm
Purpose: Prevent avoidable mistakes before committing data.
Display concise summaries for:
* Customer.
* Identity.
* Primary driver license.
* Vehicle.
* Rental period.
* Pickup and return locations.
* Payment.
* Additional drivers.
* Notes.
Each summary section should include an `Edit` action that returns directly to the relevant step.
Final actions:
* Back.
* Cancel.
* Create reservation.
The final button must display a loading state and remain disabled after the first click until the request succeeds or fails.
---
## 4. Navigation and Progress Behavior
### Desktop
Use a horizontal stepper containing:
* Step number.
* Short step label.
* Completed state.
* Current state.
* Future state.
### Mobile
Use a compact header:
`Step 3 of 6 · Driver license`
Include a progress bar rather than compressing all six labels into unusable decorative confetti.
### Navigation rules
* `Continue` validates the current step.
* `Back` never discards information.
* Completed steps may be revisited.
* Future incomplete steps cannot be opened directly.
* The final review step is available only after all previous steps are valid.
* Pressing Enter must not accidentally submit the final reservation from an earlier step.
* The footer containing Back and Continue should remain visible on long steps where practical.
---
## 5. Validation Strategy
Replace the current generic `Please fill all required fields` behavior with step-specific validation.
Use Zod, which is already installed, to create separate schemas:
* `customerStepSchema`
* `identityStepSchema`
* `licenseStepSchema`
* `rentalStepSchema`
* `paymentExtrasStepSchema`
* `completeReservationSchema`
Validation behavior:
* Validate on Continue.
* Show the message beside the invalid field.
* Focus the first invalid field.
* Clear an error once the value becomes valid.
* Run complete validation again before final submission.
* Translate validation messages into English, French, and Arabic.
Do not depend on disabled buttons alone. A disabled button gives the user no useful explanation and is a remarkably efficient way to make software feel broken.
---
## 6. State Management Refactor
Replace the large collection of independent `useState` calls with one structured draft state managed by `useReducer`.
Suggested shape:
```ts
type ReservationDraft = {
customer: {
mode: 'existing' | 'new'
selectedCustomerId: string | null
firstName: BilingualField
lastName: BilingualField
email: string
phone: string
}
identity: {
dateOfBirth: string
nationality: string
fullAddress: string
identityDocumentNumber: string
internationalLicenseNumber: string
}
license: {
number: string
country: string
issuedAt: string
expiry: string
category: string
existingImageUrl: string | null
newImageFile: File | null
}
rental: {
vehicleId: string
startDate: string
endDate: string
pickupLocation: string
returnLocation: string
}
payment: {
depositAmount: string
paymentMode: string
notes: string
}
additionalDrivers: AdditionalDriverDraft[]
}
```
The reducer should support explicit actions such as:
* Select existing customer.
* Start new customer.
* Update step field.
* Add additional driver.
* Remove additional driver.
* Hydrate customer information.
* Clear customer information.
* Store a newly created customer ID after partial submission.
* Reset the entire draft.
This makes state transitions testable and prevents unrelated fields from being scattered throughout the page.
---
## 7. Component Structure
Reduce `page.tsx` to a data-loading and route-level shell.
Suggested structure:
```text
src/components/reservations/new/
├── ReservationWizard.tsx
├── ReservationStepper.tsx
├── ReservationWizardActions.tsx
├── ReservationReview.tsx
├── reservationWizard.types.ts
├── reservationWizard.reducer.ts
├── reservationWizard.schemas.ts
├── reservationWizard.copy.ts
├── reservationWizard.submit.ts
├── steps/
│ ├── CustomerStep.tsx
│ ├── IdentityStep.tsx
│ ├── LicenseStep.tsx
│ ├── RentalDetailsStep.tsx
│ ├── PaymentExtrasStep.tsx
│ └── ReviewStep.tsx
└── __tests__/
```
Responsibilities:
* `page.tsx`: load customers and vehicles, render the wizard.
* `ReservationWizard`: control current step and draft state.
* Step components: render fields only.
* Schemas: validation only.
* Reducer: state transitions only.
* Submission module: API orchestration only.
* Copy file: typed English, French, and Arabic labels.
* Review component: display formatted summaries only.
---
## 8. API Submission Strategy
No customer or reservation records should be created merely because the user moved to another step.
On final confirmation:
1. Validate the complete draft.
2. Revalidate vehicle availability.
3. For a new customer:
* Create the customer using the accumulated customer, identity, and license fields.
4. For an existing customer:
* Patch only changed customer fields.
5. Upload the license image when a new image was selected.
6. Create the reservation.
7. Redirect to the new reservation details page.
### Partial-failure handling
The current operations are not atomic. For example, customer creation may succeed while reservation creation fails.
The wizard must therefore:
* Remember the newly created customer ID in memory.
* Retry using that customer instead of creating another duplicate.
* Show which operation failed.
* Keep all form data available for correction or retry.
* Never redirect until reservation creation succeeds.
### Recommended backend improvement
The strongest solution is a dedicated backend operation that creates or updates the customer, uploads document metadata, validates vehicle availability, and creates the reservation as one controlled workflow.
Without such an endpoint, the frontend can handle retries carefully, but it cannot provide a true database transaction across the current independent requests.
---
## 9. Data Loading and Customer Hydration
Current customer and vehicle loading should be extracted from the form component.
Required behavior:
* Show a proper loading state for the wizard shell.
* Show separate customer-load and vehicle-load errors where possible.
* Do not overwrite user-edited customer data when background data refreshes.
* Hydrate fields only when the selected customer actually changes.
* Cancel or ignore stale requests when the component unmounts.
* Avoid loading arbitrary large lists indefinitely as the database grows.
Future improvement:
Replace `pageSize=100` customer loading with server-side customer search. Loading the first 100 customers and searching them in the browser will eventually fail as a business grows, which is traditionally when software chooses to reveal its assumptions.
---
## 10. Draft-Loss Protection
For the first implementation:
* Keep all information when navigating between wizard steps.
* Warn before leaving the page when unsaved changes exist.
* Do not persist license images in browser storage.
* Clear the draft after successful creation.
* Clear object URLs used for image previews.
Do not automatically store sensitive customer identity and license information in long-lived local storage.
A server-side draft feature can be designed separately if staff need to resume reservations across devices or sessions.
---
## 11. Accessibility and Localization
The wizard must preserve the applications existing multilingual requirements.
Requirements:
* English and French use LTR.
* Arabic uses true RTL.
* Step order and navigation layout adapt correctly in RTL.
* Every field has an associated label.
* Required fields are announced to assistive technology.
* Errors use `aria-describedby`.
* The active step uses `aria-current="step"`.
* Focus moves to the step heading after navigation.
* Keyboard users can operate all controls.
* Color is not the only indicator of progress or error.
* Buttons and inputs remain usable in dark mode.
* Dates and amounts are presented using the active locale on the review screen.
The current hardcoded English license-image alt text must also be localized.
---
## 12. Testing Plan
### Unit tests
Test:
* Reducer actions.
* Step validation schemas.
* Date relationships.
* Deposit normalization.
* Existing customer hydration.
* Switching customer modes.
* Additional-driver add and remove behavior.
* Final payload construction.
### Component tests
Test:
* Only the active step is displayed.
* Continue blocks invalid data.
* Back preserves data.
* Completed steps can be revisited.
* Existing customer details are prefilled.
* New customer information remains in draft state.
* Additional-driver fields appear conditionally.
* Edit actions on the review page open the correct step.
* Arabic step layout uses RTL correctly.
### Submission tests
Test:
* Existing customer reservation.
* New customer reservation.
* License image upload.
* Customer update failure.
* Image upload failure.
* Reservation creation failure after customer creation.
* Retry without duplicate customer creation.
* Double-click prevention.
* Vehicle availability conflict.
### Required verification
Run:
```bash
npm run type-check
npm run test
npm run build
```
for the dashboard workspace after implementation.
---
## 13. Implementation Sequence
### Phase 1: Extract and stabilize
* Create typed draft models.
* Extract copy, validation, and payload-building logic.
* Add tests around current behavior.
* Do not change the visible interface yet.
### Phase 2: Build the wizard shell
* Add stepper.
* Add reducer.
* Add navigation.
* Add shared action footer.
* Render one step at a time.
### Phase 3: Move form sections
* Move customer fields.
* Move identity fields.
* Move license fields.
* Move rental fields.
* Move payment and optional driver fields.
* Build the review screen.
### Phase 4: Correct submission behavior
* Delay new-customer creation until final confirmation.
* Add partial-failure recovery.
* Prevent duplicate requests.
* Revalidate vehicle availability.
* Preserve the draft after recoverable errors.
### Phase 5: Accessibility and responsive refinement
* Add keyboard and screen-reader behavior.
* Verify mobile presentation.
* Verify dark mode.
* Verify Arabic RTL.
* Verify translated error messages.
### Phase 6: Testing and regression review
* Complete unit and component tests.
* Run type-check, tests, and production build.
* Verify both existing-customer and new-customer flows manually.
* Confirm redirect to the created reservation.
---
## 14. Acceptance Criteria
The work is complete only when:
* Exactly one focused step is displayed at a time.
* The user can see their current position and progress.
* Invalid current-step fields prevent progression and explain why.
* Going backward does not lose information.
* New customers are not created before final confirmation.
* Existing-customer data is loaded without repeatedly overwriting edits.
* Additional drivers remain optional.
* The final review contains all reservation information.
* Every review section can be edited.
* Duplicate reservations cannot be created by repeated clicks.
* Partial API failures do not force the user to restart.
* Vehicle availability is revalidated for the selected dates.
* English, French, and Arabic are complete.
* Arabic layout is true RTL.
* Mobile, desktop, light mode, and dark mode work.
* Type-check, tests, and production build pass.
---
## 15. Scope Boundaries
Included:
* Progressive reservation wizard.
* Refactoring of the current new-reservation page.
* Step validation.
* Review screen.
* Existing and new customer flows.
* License image handling.
* Additional-driver handling.
* API failure recovery.
* Responsive, multilingual, and accessible behavior.
* Relevant tests.
Not included unless separately approved:
* Redesigning the reservation details page.
* Server-side saved drafts.
* OCR extraction from driver licenses.
* Multiple primary renters.
* Payment processing.
* Contract generation.
* Changing unrelated dashboard pages.
* Broad customer-management redesign.