Files
carmanagement/docs/ProgressiveReservationCreation.md
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

18 KiB
Raw Permalink Blame History

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:

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:

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.

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:

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.