@qite/tide-booking-component 1.4.2 → 1.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/build/build-cjs/booking-wizard/components/phone-input.d.ts +17 -0
  2. package/build/build-cjs/booking-wizard/features/booking/selectors.d.ts +41 -12
  3. package/build/build-cjs/booking-wizard/features/summary/summary-flight.d.ts +2 -2
  4. package/build/build-cjs/booking-wizard/features/travelers-form/controls/gender-control.d.ts +5 -0
  5. package/build/build-cjs/booking-wizard/features/travelers-form/travelers-form-util.d.ts +7 -0
  6. package/build/build-cjs/booking-wizard/features/travelers-form/validate-form.d.ts +2 -2
  7. package/build/build-cjs/booking-wizard/types.d.ts +13 -0
  8. package/build/build-cjs/index.js +460 -273
  9. package/build/build-esm/booking-wizard/components/phone-input.d.ts +17 -0
  10. package/build/build-esm/booking-wizard/features/booking/selectors.d.ts +41 -12
  11. package/build/build-esm/booking-wizard/features/summary/summary-flight.d.ts +2 -2
  12. package/build/build-esm/booking-wizard/features/travelers-form/controls/gender-control.d.ts +5 -0
  13. package/build/build-esm/booking-wizard/features/travelers-form/travelers-form-util.d.ts +7 -0
  14. package/build/build-esm/booking-wizard/features/travelers-form/validate-form.d.ts +2 -2
  15. package/build/build-esm/booking-wizard/types.d.ts +13 -0
  16. package/build/build-esm/index.js +462 -275
  17. package/package.json +1 -1
  18. package/src/booking-wizard/api-settings-slice.ts +5 -0
  19. package/src/booking-wizard/components/phone-input.tsx +181 -0
  20. package/src/booking-wizard/features/booking/booking.tsx +28 -28
  21. package/src/booking-wizard/features/booking/selectors.ts +17 -14
  22. package/src/booking-wizard/features/sidebar/sidebar-flight.tsx +4 -2
  23. package/src/booking-wizard/features/sidebar/sidebar-util.ts +2 -0
  24. package/src/booking-wizard/features/summary/summary-flight.tsx +7 -6
  25. package/src/booking-wizard/features/summary/summary.tsx +91 -62
  26. package/src/booking-wizard/features/travelers-form/controls/gender-control.tsx +70 -0
  27. package/src/booking-wizard/features/travelers-form/travelers-form-util.ts +11 -0
  28. package/src/booking-wizard/features/travelers-form/travelers-form.tsx +451 -313
  29. package/src/booking-wizard/features/travelers-form/validate-form.ts +84 -98
  30. package/src/booking-wizard/types.ts +15 -0
  31. package/src/shared/translations/en-GB.json +3 -0
  32. package/src/shared/translations/fr-BE.json +3 -0
  33. package/src/shared/translations/nl-BE.json +3 -0
  34. package/styles/booking-wizard.scss +1 -0
  35. package/styles/components/_phone-input.scss +8 -0
@@ -1,6 +1,6 @@
1
1
  import { FormikErrors } from "formik";
2
2
  import { isEmpty, set } from "lodash";
3
- import { TravelersFormValues } from "../../types";
3
+ import { FormField, TravelersFormValues } from "../../types";
4
4
  import { CHILD_MAX_AGE } from "./travelers-form-slice";
5
5
  import { format } from "../../../shared/utils/localization-util";
6
6
 
@@ -24,70 +24,71 @@ const validateForm = (
24
24
  values: TravelersFormValues,
25
25
  agentRequired?: boolean,
26
26
  bookingType?: string,
27
- translations?: any
27
+ translations?: any,
28
+ formFields?: FormField[],
29
+ mainBookerFormFields?: FormField[],
28
30
  ) => {
29
31
  const errors: FormikErrors<TravelersFormValues> = {};
32
+ const isFormFieldPresent = (type: string) => {
33
+ return formFields?.some((f) => f.type === type) ?? true;
34
+ }
35
+ const isMainBookerFormFieldPresent = (type: string) => {
36
+ return mainBookerFormFields?.some((f) => f.type === type) ?? true;
37
+ }
38
+
39
+ const formatTravelerField = (room: number, pax: number, field: string) => {
40
+ return values.rooms.length > 1 ? format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [room, pax, field]) : format(translations.TRAVELERS_FORM.VALIDATION.SINGLE_ROOM_TRAVELER_X_FIELD, [pax, field]);
41
+ }
42
+ const formatTravelerIsNoAdult = (room: number, pax: number) => {
43
+ return values.rooms.length > 1 ? format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_IS_NO_ADULT, [room, pax]) : format(translations.TRAVELERS_FORM.VALIDATION.SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT, [pax]);
44
+ }
45
+ const formatTravelerIsNoChild = (room: number, pax: number) => {
46
+ return values.rooms.length > 1 ? format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_IS_NO_CHILD, [room, pax]) : format(translations.TRAVELERS_FORM.VALIDATION.SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD, [pax]);
47
+ }
30
48
 
31
49
  values.rooms.forEach((r, rIndex) =>
32
50
  r.adults.forEach((adult, index) => {
33
- if (isEmpty(adult.gender)) {
51
+ if (isEmpty(adult.gender) && isFormFieldPresent("gender")) {
34
52
  set(
35
53
  errors,
36
54
  `rooms[${rIndex}].adults[${index}].gender`,
37
- format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
38
- rIndex + 1,
39
- index + 1,
40
- translations.TRAVELERS_FORM.GENDER,
41
- ])
55
+ formatTravelerField(rIndex + 1, index + 1, translations.TRAVELERS_FORM.GENDER)
42
56
  );
43
57
  }
44
58
 
45
- if (isEmpty(adult.firstName)) {
59
+ if (isEmpty(adult.firstName) && isFormFieldPresent("firstName")) {
46
60
  set(
47
61
  errors,
48
62
  `rooms[${rIndex}].adults[${index}].firstName`,
49
- format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
50
- rIndex + 1,
51
- index + 1,
52
- translations.TRAVELERS_FORM.FIRST_NAME,
53
- ])
63
+ formatTravelerField(rIndex + 1, index + 1, translations.TRAVELERS_FORM.FIRST_NAME)
54
64
  );
55
65
  }
56
66
 
57
- if (isEmpty(adult.lastName)) {
67
+ if (isEmpty(adult.lastName) && isFormFieldPresent("lastName")) {
58
68
  set(
59
69
  errors,
60
70
  `rooms[${rIndex}].adults[${index}].lastName`,
61
- format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
62
- rIndex + 1,
63
- index + 1,
64
- translations.TRAVELERS_FORM.LAST_NAME,
65
- ])
71
+ formatTravelerField(rIndex + 1, index + 1, translations.TRAVELERS_FORM.LAST_NAME)
66
72
  );
67
73
  }
68
74
 
69
- if (isEmpty(adult.birthDate)) {
70
- set(
71
- errors,
72
- `rooms[${rIndex}].adults[${index}].birthDate`,
73
- format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
74
- rIndex + 1,
75
- index + 1,
76
- translations.TRAVELERS_FORM.BIRTHDATE,
77
- ])
78
- );
79
- } else if (values.startDate) {
80
- const age = getAge(adult.birthDate, values.startDate);
81
-
82
- if (age <= CHILD_MAX_AGE) {
75
+ if (isFormFieldPresent("birthDate")) {
76
+ if (isEmpty(adult.birthDate)) {
83
77
  set(
84
78
  errors,
85
79
  `rooms[${rIndex}].adults[${index}].birthDate`,
86
- format(
87
- translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_IS_NO_ADULT,
88
- [rIndex + 1, index + 1]
89
- )
80
+ formatTravelerField(rIndex + 1, index + 1, translations.TRAVELERS_FORM.BIRTHDATE)
90
81
  );
82
+ } else if (values.startDate) {
83
+ const age = getAge(adult.birthDate, values.startDate);
84
+
85
+ if (age <= CHILD_MAX_AGE) {
86
+ set(
87
+ errors,
88
+ `rooms[${rIndex}].adults[${index}].birthDate`,
89
+ formatTravelerIsNoAdult(rIndex + 1, index + 1)
90
+ );
91
+ }
91
92
  }
92
93
  }
93
94
  })
@@ -95,64 +96,47 @@ const validateForm = (
95
96
 
96
97
  values.rooms.forEach((r, rIndex) =>
97
98
  r.children.forEach((child, index) => {
98
- if (isEmpty(child.gender)) {
99
+ if (isEmpty(child.gender) && isFormFieldPresent("gender")) {
99
100
  set(
100
101
  errors,
101
102
  `rooms[${rIndex}].children[${index}].gender`,
102
- format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
103
- rIndex + 1,
104
- r.adults.length + index + 1,
105
- translations.TRAVELERS_FORM.GENDER,
106
- ])
103
+ formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.GENDER)
107
104
  );
108
105
  }
109
106
 
110
- if (isEmpty(child.firstName)) {
107
+ if (isEmpty(child.firstName) && isFormFieldPresent("firstName")) {
111
108
  set(
112
109
  errors,
113
110
  `children[${index}].firstName`,
114
- format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
115
- rIndex + 1,
116
- r.adults.length + index + 1,
117
- translations.TRAVELERS_FORM.FIRST_NAME,
118
- ])
111
+ formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME)
119
112
  );
120
113
  }
121
114
 
122
- if (isEmpty(child.lastName)) {
115
+ if (isEmpty(child.lastName) && isFormFieldPresent("lastName")) {
123
116
  set(
124
117
  errors,
125
118
  `rooms[${rIndex}].children[${index}].lastName`,
126
- format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
127
- rIndex + 1,
128
- r.adults.length + index + 1,
129
- translations.TRAVELERS_FORM.LAST_NAME,
130
- ])
119
+ formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.LAST_NAME)
131
120
  );
132
121
  }
133
122
 
134
- if (isEmpty(child.birthDate)) {
135
- set(
136
- errors,
137
- `rooms[${rIndex}].children[${index}].birthDate`,
138
- format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
139
- rIndex + 1,
140
- r.adults.length + index + 1,
141
- translations.TRAVELERS_FORM.BIRTHDATE,
142
- ])
143
- );
144
- } else if (values.startDate) {
145
- const age = getAge(child.birthDate, values.startDate);
146
-
147
- if (age > CHILD_MAX_AGE) {
123
+ if (isFormFieldPresent("birthDate")) {
124
+ if (isEmpty(child.birthDate)) {
148
125
  set(
149
126
  errors,
150
127
  `rooms[${rIndex}].children[${index}].birthDate`,
151
- format(
152
- translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_IS_NO_CHILD,
153
- [rIndex + 1, r.adults.length + index + 1]
154
- )
128
+ formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.BIRTHDATE)
155
129
  );
130
+ } else if (values.startDate) {
131
+ const age = getAge(child.birthDate, values.startDate);
132
+
133
+ if (age > CHILD_MAX_AGE) {
134
+ set(
135
+ errors,
136
+ `rooms[${rIndex}].children[${index}].birthDate`,
137
+ formatTravelerIsNoChild(rIndex + 1, r.adults.length + index + 1)
138
+ );
139
+ }
156
140
  }
157
141
  }
158
142
  })
@@ -163,63 +147,65 @@ const validateForm = (
163
147
  translations.TRAVELERS_FORM.VALIDATION.NO_MAIN_BOOKER_SELECTED;
164
148
  }
165
149
 
166
- if (bookingType != "b2b") {
167
- if (isEmpty(values.street)) {
150
+ if (bookingType != "b2b" || mainBookerFormFields?.length) {
151
+ if (isEmpty(values.street) && isMainBookerFormFieldPresent("street")) {
168
152
  errors.street = format(
169
153
  translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
170
154
  [translations.TRAVELERS_FORM.STREET]
171
155
  );
172
156
  }
173
157
 
174
- if (isEmpty(values.houseNumber)) {
158
+ if (isEmpty(values.houseNumber) && isMainBookerFormFieldPresent("houseNumber")) {
175
159
  errors.houseNumber = format(
176
160
  translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
177
161
  [translations.TRAVELERS_FORM.HOUSE_NUMBER]
178
162
  );
179
163
  }
180
164
 
181
- if (isEmpty(values.zipCode)) {
165
+ if (isEmpty(values.zipCode) && isMainBookerFormFieldPresent("zipCode")) {
182
166
  errors.zipCode = format(
183
167
  translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
184
168
  [translations.TRAVELERS_FORM.ZIPCODE]
185
169
  );
186
170
  }
187
171
 
188
- if (isEmpty(values.place)) {
172
+ if (isEmpty(values.place) && isMainBookerFormFieldPresent("place")) {
189
173
  errors.place = format(
190
174
  translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
191
175
  [translations.TRAVELERS_FORM.CITY]
192
176
  );
193
177
  }
194
178
 
195
- if (isEmpty(values.email)) {
196
- errors.email = format(
197
- translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
198
- [translations.TRAVELERS_FORM.EMAIL]
199
- );
200
- } else if (isValidEmail(values.email)) {
201
- errors.email =
202
- translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_EMAIL_IS_INVALID;
203
- }
179
+ if (isMainBookerFormFieldPresent("email")) {
180
+ if (isEmpty(values.email)) {
181
+ errors.email = format(
182
+ translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
183
+ [translations.TRAVELERS_FORM.EMAIL]
184
+ );
185
+ } else if (isValidEmail(values.email)) {
186
+ errors.email =
187
+ translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_EMAIL_IS_INVALID;
188
+ }
204
189
 
205
- if (isEmpty(values.emailConfirmation)) {
206
- errors.emailConfirmation = format(
207
- translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
208
- [translations.TRAVELERS_FORM.REPEAT_EMAIL]
209
- );
210
- } else if (values.emailConfirmation !== values.email) {
211
- errors.emailConfirmation =
212
- translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_EMAIL_DOES_NOT_MATCH;
190
+ if (isEmpty(values.emailConfirmation)) {
191
+ errors.emailConfirmation = format(
192
+ translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
193
+ [translations.TRAVELERS_FORM.REPEAT_EMAIL]
194
+ );
195
+ } else if (values.emailConfirmation !== values.email) {
196
+ errors.emailConfirmation =
197
+ translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_EMAIL_DOES_NOT_MATCH;
198
+ }
213
199
  }
214
200
 
215
- if (isEmpty(values.country)) {
201
+ if (isEmpty(values.country) && isMainBookerFormFieldPresent("country")) {
216
202
  errors.country = format(
217
203
  translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
218
204
  [translations.TRAVELERS_FORM.COUNTRY]
219
205
  );
220
206
  }
221
207
 
222
- if (isEmpty(values.phone)) {
208
+ if (isEmpty(values.phone) && isMainBookerFormFieldPresent("phone")) {
223
209
  errors.phone = format(
224
210
  translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
225
211
  [translations.TRAVELERS_FORM.PHONE]
@@ -22,6 +22,9 @@ export interface Settings {
22
22
  travellers: {
23
23
  pathSuffix: string;
24
24
  compactForm?: boolean;
25
+ formFields?: FormField[];
26
+ mainBookerFormFields?: FormField[];
27
+ countries?: Country[];
25
28
  };
26
29
  summary: {
27
30
  pathSuffix: string;
@@ -68,6 +71,16 @@ export interface Settings {
68
71
  customValidateText?: string;
69
72
  }
70
73
 
74
+ export interface FormField {
75
+ type: string;
76
+ }
77
+
78
+ export interface Country {
79
+ iso2: string;
80
+ name: string;
81
+ phonePrefix: string;
82
+ }
83
+
71
84
  export interface BookingOptions {
72
85
  b2b: BookingOptionsDetail;
73
86
  b2b2c: BookingOptionsDetail;
@@ -170,6 +183,8 @@ export interface FlightLine {
170
183
  airlineDescription?: string;
171
184
  airlineNumber?: string;
172
185
  travelClass?: string;
186
+ number?: string;
187
+ airlineCode?: string;
173
188
  }
174
189
 
175
190
  export interface AccommodationContent {
@@ -163,8 +163,11 @@
163
163
  "CHOOSE_AGENT_PLACEHOLDER": "Choose your travel agent",
164
164
  "VALIDATION": {
165
165
  "TRAVELER_X_FIELD": "Room {0} - Traveler {1}: {2}",
166
+ "SINGLE_ROOM_TRAVELER_X_FIELD": "Traveler {0}: {1}",
166
167
  "TRAVELER_X_IS_NO_ADULT": "Room {0} - Traveler {1}: is not an adult",
168
+ "SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT": "Traveler {0}: is not an adult",
167
169
  "TRAVELER_X_IS_NO_CHILD": "Room {0} - Traveler {1}: is not a child",
170
+ "SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD": "Traveler {0}: is not a child",
168
171
  "NO_MAIN_BOOKER_SELECTED": "No main booker has been selected",
169
172
  "MAIN_BOOKER_FIELD": "Main booker: {0}",
170
173
  "MAIN_BOOKER_EMAIL_IS_INVALID": "Main booker: email is invalid",
@@ -163,8 +163,11 @@
163
163
  "CHOOSE_AGENT_PLACEHOLDER": "Choisissez votre agent de voyage",
164
164
  "VALIDATION": {
165
165
  "TRAVELER_X_FIELD": "Chambre {0} - Voyageur {1} : {2}",
166
+ "SINGLE_ROOM_TRAVELER_X_FIELD": "Voyageur {0} : {1}",
166
167
  "TRAVELER_X_IS_NO_ADULT": "Chambre {0} - Voyageur {1} : n'est pas un adulte",
168
+ "SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT": "Voyageur {0} : n'est pas un adulte",
167
169
  "TRAVELER_X_IS_NO_CHILD": "Chambre {0} - Voyageur {1} : n'est pas un enfant",
170
+ "SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD": "Voyageur {0} : n'est pas un enfant",
168
171
  "NO_MAIN_BOOKER_SELECTED": "Aucun réservant principal n'a été sélectionné",
169
172
  "MAIN_BOOKER_FIELD": "Principal réservant : {0}",
170
173
  "MAIN_BOOKER_EMAIL_IS_INVALID": "Principal réservant : e-mail invalide",
@@ -163,8 +163,11 @@
163
163
  "CHOOSE_AGENT_PLACEHOLDER": "Kies uw reisagent",
164
164
  "VALIDATION": {
165
165
  "TRAVELER_X_FIELD": "Kamer {0} - Reiziger {1}: {2}",
166
+ "SINGLE_ROOM_TRAVELER_X_FIELD": "Reiziger {0}: {1}",
166
167
  "TRAVELER_X_IS_NO_ADULT": "Kamer {0} - Reiziger {1}: is geen volwassene",
168
+ "SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT": "Reiziger {0}: is geen volwassene",
167
169
  "TRAVELER_X_IS_NO_CHILD": "Kamer {0} - Reiziger {1}: is geen kind",
170
+ "SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD": "Reiziger {0}: is geen kind",
168
171
  "NO_MAIN_BOOKER_SELECTED": "Er werd geen hoofdboeker geselecteerd",
169
172
  "MAIN_BOOKER_FIELD": "Hoofdboeker: {0}",
170
173
  "MAIN_BOOKER_EMAIL_IS_INVALID": "Hoofdboeker: e-mail is ongeldig",
@@ -23,6 +23,7 @@
23
23
  @import "./components/input";
24
24
  @import "./components/date-list";
25
25
  @import "./components/typeahead";
26
+ @import "./components/phone-input";
26
27
 
27
28
  @extend %reset;
28
29
  @include body;
@@ -0,0 +1,8 @@
1
+ .phone-input {
2
+ display: flex;
3
+ gap: 5px;
4
+
5
+ .dropdown {
6
+ width: 40%;
7
+ }
8
+ }