Files
carmanagement/apps/dashboard/src/components/reservations/new/reservationWizard.reducer.ts
T
root 5649ab02c7
Build & Push / Pipeline Tests (push) Failing after 1m31s
Build & Push / Build & Push Docker Image (push) Has been skipped
Test / Type Check (all packages) (push) Successful in 55s
Test / API Unit Tests (push) Successful in 1m8s
Test / Homepage Unit Tests (push) Successful in 47s
Test / Carplace Unit Tests (push) Successful in 44s
Test / Admin Unit Tests (push) Successful in 43s
Test / Dashboard Unit Tests (push) Failing after 46s
Test / API Integration Tests (push) Successful in 1m7s
fix the booking and contract
2026-07-27 23:04:26 -04:00

166 lines
6.1 KiB
TypeScript

import { emptyBilingual } from '@/components/ui/BilingualInput'
import type { AdditionalDriverDraft, Customer, ReservationDraft } from './reservationWizard.types'
function readCustomerAddressValue(customer: Customer | undefined, key: string) {
const address = customer?.address
if (!address || typeof address !== 'object' || Array.isArray(address)) return ''
const value = address[key]
return typeof value === 'string' ? value : ''
}
export function createAdditionalDriver(): AdditionalDriverDraft {
return {
id: crypto.randomUUID(),
firstName: emptyBilingual(),
lastName: emptyBilingual(),
email: '',
phone: '',
driverLicense: '',
licenseExpiry: '',
licenseIssuedAt: '',
dateOfBirth: '',
nationality: emptyBilingual(),
}
}
export function createInitialDraft(): ReservationDraft {
return {
customer: {
mode: 'existing',
selectedCustomerId: null,
createdCustomerId: null,
firstName: emptyBilingual(),
lastName: emptyBilingual(),
email: '',
phone: '',
hydratedFromCustomerId: null,
},
identity: {
dateOfBirth: '',
nationality: '',
fullAddress: '',
identityDocumentNumber: '',
internationalLicenseNumber: '',
},
license: {
number: '',
country: '',
issuedAt: '',
expiry: '',
category: '',
existingImageUrl: null,
newImageFile: null,
},
rental: {
vehicleId: '',
startDate: '',
endDate: '',
pickupLocation: '',
returnLocation: '',
},
payment: {
depositAmount: '0',
paymentMode: 'CASH',
spareWheel: false,
radioCd: false,
notes: '',
},
additionalDrivers: [],
}
}
export type ReservationDraftAction =
| { type: 'setCustomerMode'; mode: 'existing' | 'new' }
| { type: 'selectExistingCustomer'; customer: Customer }
| { type: 'setCreatedCustomerId'; customerId: string }
| { type: 'updateCustomer'; field: keyof ReservationDraft['customer']; value: any }
| { type: 'updateIdentity'; field: keyof ReservationDraft['identity']; value: string }
| { type: 'updateLicense'; field: keyof ReservationDraft['license']; value: any }
| { type: 'updateRental'; field: keyof ReservationDraft['rental']; value: string }
| { type: 'updatePayment'; field: keyof ReservationDraft['payment']; value: string | boolean }
| { type: 'addAdditionalDriver' }
| { type: 'removeAdditionalDriver'; id: string }
| { type: 'updateAdditionalDriver'; id: string; field: keyof AdditionalDriverDraft; value: any }
| { type: 'reset' }
export function reservationDraftReducer(draft: ReservationDraft, action: ReservationDraftAction): ReservationDraft {
switch (action.type) {
case 'setCustomerMode':
if (action.mode === draft.customer.mode) return draft
if (action.mode === 'new') {
return {
...draft,
customer: {
...createInitialDraft().customer,
mode: 'new',
createdCustomerId: draft.customer.createdCustomerId,
},
identity: createInitialDraft().identity,
license: createInitialDraft().license,
}
}
return {
...draft,
customer: createInitialDraft().customer,
identity: createInitialDraft().identity,
license: createInitialDraft().license,
}
case 'selectExistingCustomer':
return {
...draft,
customer: {
mode: 'existing',
selectedCustomerId: action.customer.id,
createdCustomerId: null,
firstName: { fr: action.customer.firstName ?? '', ar: action.customer.firstNameAr ?? '' },
lastName: { fr: action.customer.lastName ?? '', ar: action.customer.lastNameAr ?? '' },
email: action.customer.email ?? '',
phone: action.customer.phone ?? '',
hydratedFromCustomerId: action.customer.id,
},
identity: {
dateOfBirth: action.customer.dateOfBirth ? action.customer.dateOfBirth.slice(0, 10) : '',
nationality: action.customer.nationality ?? '',
fullAddress: readCustomerAddressValue(action.customer, 'fullAddress'),
identityDocumentNumber: readCustomerAddressValue(action.customer, 'identityDocumentNumber'),
internationalLicenseNumber: readCustomerAddressValue(action.customer, 'internationalLicenseNumber'),
},
license: {
number: action.customer.driverLicense ?? action.customer.licenseNumber ?? '',
country: action.customer.licenseCountry ?? '',
issuedAt: action.customer.licenseIssuedAt ? action.customer.licenseIssuedAt.slice(0, 10) : '',
expiry: action.customer.licenseExpiry ? action.customer.licenseExpiry.slice(0, 10) : '',
category: action.customer.licenseCategory ?? '',
existingImageUrl: action.customer.licenseImageUrl ?? null,
newImageFile: null,
},
}
case 'setCreatedCustomerId':
return { ...draft, customer: { ...draft.customer, createdCustomerId: action.customerId } }
case 'updateCustomer':
return { ...draft, customer: { ...draft.customer, [action.field]: action.value } }
case 'updateIdentity':
return { ...draft, identity: { ...draft.identity, [action.field]: action.value } }
case 'updateLicense':
return { ...draft, license: { ...draft.license, [action.field]: action.value } }
case 'updateRental':
return { ...draft, rental: { ...draft.rental, [action.field]: action.value } }
case 'updatePayment':
return { ...draft, payment: { ...draft.payment, [action.field]: action.value } }
case 'addAdditionalDriver':
return { ...draft, additionalDrivers: [...draft.additionalDrivers, createAdditionalDriver()] }
case 'removeAdditionalDriver':
return { ...draft, additionalDrivers: draft.additionalDrivers.filter((driver) => driver.id !== action.id) }
case 'updateAdditionalDriver':
return {
...draft,
additionalDrivers: draft.additionalDrivers.map((driver) =>
driver.id === action.id ? { ...driver, [action.field]: action.value } : driver,
),
}
case 'reset':
return createInitialDraft()
}
}