@qite/tide-booking-component 1.4.33 → 1.4.35

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 (64) hide show
  1. package/build/build-cjs/index.js +1674 -416
  2. package/build/build-cjs/qsm/types.d.ts +0 -1
  3. package/build/build-cjs/search-results/components/filters/filters.d.ts +2 -2
  4. package/build/build-cjs/search-results/components/flight/flight-results.d.ts +2 -0
  5. package/build/build-cjs/search-results/components/hotel/hotel-card.d.ts +1 -0
  6. package/build/build-cjs/search-results/components/itinerary/index.d.ts +2 -2
  7. package/build/build-cjs/search-results/store/search-results-slice.d.ts +11 -2
  8. package/build/build-cjs/search-results/types.d.ts +0 -14
  9. package/build/build-esm/index.js +1674 -416
  10. package/build/build-esm/qsm/types.d.ts +0 -1
  11. package/build/build-esm/search-results/components/filters/filters.d.ts +2 -2
  12. package/build/build-esm/search-results/components/flight/flight-results.d.ts +2 -0
  13. package/build/build-esm/search-results/components/hotel/hotel-card.d.ts +1 -0
  14. package/build/build-esm/search-results/components/itinerary/index.d.ts +2 -2
  15. package/build/build-esm/search-results/store/search-results-slice.d.ts +11 -2
  16. package/build/build-esm/search-results/types.d.ts +0 -14
  17. package/package.json +77 -77
  18. package/src/booking-product/components/product.tsx +26 -22
  19. package/src/booking-wizard/features/booking/booking-self-contained.tsx +303 -304
  20. package/src/booking-wizard/features/travelers-form/controls/gender-control.tsx +5 -5
  21. package/src/booking-wizard/features/travelers-form/travelers-form.tsx +10 -10
  22. package/src/content/components/icon.tsx +1 -1
  23. package/src/content/features/content-page/content-page-self-contained.tsx +0 -1
  24. package/src/qsm/components/QSMContainer/qsm-container.tsx +217 -218
  25. package/src/qsm/components/mobile-filter-modal/index.tsx +12 -10
  26. package/src/qsm/components/travel-class-picker/index.tsx +5 -3
  27. package/src/qsm/components/travel-input/index.tsx +15 -12
  28. package/src/qsm/components/travel-input-group/index.tsx +14 -3
  29. package/src/qsm/components/travel-nationality-picker/index.tsx +5 -3
  30. package/src/qsm/components/travel-type-picker/index.tsx +5 -3
  31. package/src/qsm/qsm-configuration-context.ts +0 -1
  32. package/src/qsm/store/qsm-slice.ts +261 -261
  33. package/src/qsm/types.ts +144 -145
  34. package/src/search-results/components/filters/filters.tsx +15 -16
  35. package/src/search-results/components/flight/flight-results.tsx +168 -1099
  36. package/src/search-results/components/hotel/hotel-accommodation-results.tsx +21 -24
  37. package/src/search-results/components/hotel/hotel-card.tsx +4 -3
  38. package/src/search-results/components/icon.tsx +1 -1
  39. package/src/search-results/components/itinerary/index.tsx +229 -129
  40. package/src/search-results/components/round-trip/round-trip-results.tsx +1 -1
  41. package/src/search-results/components/search-results-container/search-results-container.tsx +353 -337
  42. package/src/search-results/components/spinner/spinner.tsx +3 -1
  43. package/src/search-results/components/tab-views/index.tsx +13 -7
  44. package/src/search-results/features/flights/flight-search-results-self-contained.tsx +1 -14
  45. package/src/search-results/features/hotels/hotel-search-results-self-contained.tsx +1 -14
  46. package/src/search-results/store/search-results-slice.ts +37 -3
  47. package/src/search-results/types.ts +0 -15
  48. package/src/shared/translations/ar-SA.json +70 -0
  49. package/src/shared/translations/da-DK.json +70 -0
  50. package/src/shared/translations/de-DE.json +70 -0
  51. package/src/shared/translations/en-GB.json +71 -1
  52. package/src/shared/translations/es-ES.json +70 -0
  53. package/src/shared/translations/fr-BE.json +71 -1
  54. package/src/shared/translations/fr-FR.json +70 -0
  55. package/src/shared/translations/is-IS.json +72 -2
  56. package/src/shared/translations/it-IT.json +70 -0
  57. package/src/shared/translations/ja-JP.json +72 -2
  58. package/src/shared/translations/nl-BE.json +70 -0
  59. package/src/shared/translations/nl-NL.json +70 -0
  60. package/src/shared/translations/no-NO.json +72 -2
  61. package/src/shared/translations/pl-PL.json +70 -0
  62. package/src/shared/translations/pt-PT.json +70 -0
  63. package/src/shared/translations/sv-SE.json +72 -2
  64. package/styles/components/_search.scss +7 -1
package/src/qsm/types.ts CHANGED
@@ -1,145 +1,144 @@
1
- import { ReactNode } from 'react';
2
-
3
- export interface QSMConfiguration {
4
- // Type specification and dedicated parameters
5
- type: 'hotel' | 'roundTrip' | 'flight';
6
- askRooms?: boolean; // hotel || roundTrip
7
- askTravelType?: boolean; // hotel || roundTrip
8
- allowOpenJaw?: boolean; // flight
9
- allowMultiCity?: boolean; // flight
10
- askTravelClass?: boolean; // flight
11
- allowOneWay?: boolean; // flight
12
- additionalFilters?: AdditionalFilters; // flight
13
- askTravelers: boolean;
14
-
15
- // Fields (form)
16
- searchFields: FieldConfig[];
17
-
18
- // Origins and destinations
19
- origins: Origin[];
20
- originTypeAhead: boolean;
21
- onOriginChange: (origin: string) => void;
22
- destinations: Destination[];
23
- destinationTypeAhead: boolean;
24
- destinationIcon: ReactNode;
25
- onDestinationChange: (destination: string) => void;
26
-
27
- // Airports
28
- airports: Airport[];
29
- airportTypeAhead: boolean;
30
- airportIcon: ReactNode;
31
- onAirportChange: (airport: string) => void;
32
-
33
- // Travel types
34
- travelTypes: TravelType[];
35
- travelTypeIcon: ReactNode;
36
-
37
- // Travel classes
38
- travelClasses: TravelClass[];
39
- travelClassIcon: ReactNode;
40
-
41
- // Date flexibility
42
- dateFlexibility?: DateFlexibility[];
43
- minDate?: Date;
44
- maxDate?: Date;
45
- showReturnDate: boolean;
46
- datesIcon: ReactNode;
47
-
48
- // Travelers
49
- defaultTravelers?: number;
50
- maxTravelers?: number;
51
- maxChildAge?: number;
52
- maxInfantAge?: number;
53
-
54
- onSubmit: (data: any) => void;
55
- submitLabel: string;
56
- submitIcon: ReactNode;
57
-
58
- nationalities: Nationality[];
59
- languageCode?: string;
60
- }
61
-
62
- export interface BaseFieldConfig {
63
- fieldKey: string;
64
- label: string;
65
- placeholder: string;
66
- options: TypeaheadOption[];
67
- autoComplete?: boolean;
68
- }
69
-
70
- export interface TypeaheadOption {
71
- key: string;
72
- value: string;
73
- iataCode?: string;
74
- country?: string;
75
- type: OptionType;
76
- }
77
-
78
- export type OptionType = 'country' | 'region' | 'oord' | 'location' | 'airport' | 'hotel' | 'other';
79
-
80
- export interface SingleFieldConfig extends BaseFieldConfig {
81
- type: 'single';
82
- }
83
-
84
- export interface DoubleFieldConfig {
85
- type: 'double';
86
- fieldKey: string;
87
- showReverse?: boolean;
88
- fields: BaseFieldConfig[];
89
- }
90
-
91
- export type FieldConfig = SingleFieldConfig | DoubleFieldConfig;
92
-
93
- export interface AdditionalFilters {
94
- showDirectFlights: boolean;
95
- includeLuggage: boolean;
96
- }
97
-
98
- export interface Origin {
99
- key: string;
100
- value: string;
101
- }
102
-
103
- export interface Destination {
104
- key: string;
105
- value: string;
106
- }
107
-
108
- export interface Airport {
109
- key: string;
110
- value: string;
111
- }
112
-
113
- export interface DateFlexibility {
114
- name: string;
115
- before: number;
116
- after: number;
117
- }
118
-
119
- export type MobileFilterType = 'search' | 'date' | 'traveler' | null;
120
-
121
- export type TravelerType = 'adults' | 'kids' | 'babies';
122
-
123
- export interface Room {
124
- adults: number;
125
- kids: number;
126
- babies: number;
127
- }
128
-
129
- export interface TravelType {
130
- id: number;
131
- label: string;
132
- icon?: ReactNode;
133
- }
134
-
135
- export interface TravelClass {
136
- id: number;
137
- label: string;
138
- icon?: ReactNode;
139
- }
140
-
141
- export interface Nationality {
142
- id: number;
143
- label: string;
144
- icon?: ReactNode;
145
- }
1
+ import { ReactNode } from 'react';
2
+
3
+ export interface QSMConfiguration {
4
+ // Type specification and dedicated parameters
5
+ type: 'hotel' | 'roundTrip' | 'flight';
6
+ askRooms?: boolean; // hotel || roundTrip
7
+ askTravelType?: boolean; // hotel || roundTrip
8
+ allowOpenJaw?: boolean; // flight
9
+ allowMultiCity?: boolean; // flight
10
+ askTravelClass?: boolean; // flight
11
+ allowOneWay?: boolean; // flight
12
+ additionalFilters?: AdditionalFilters; // flight
13
+ askTravelers: boolean;
14
+
15
+ // Fields (form)
16
+ searchFields: FieldConfig[];
17
+
18
+ // Origins and destinations
19
+ origins: Origin[];
20
+ originTypeAhead: boolean;
21
+ onOriginChange: (origin: string) => void;
22
+ destinations: Destination[];
23
+ destinationTypeAhead: boolean;
24
+ destinationIcon: ReactNode;
25
+ onDestinationChange: (destination: string) => void;
26
+
27
+ // Airports
28
+ airports: Airport[];
29
+ airportTypeAhead: boolean;
30
+ airportIcon: ReactNode;
31
+ onAirportChange: (airport: string) => void;
32
+
33
+ // Travel types
34
+ travelTypes: TravelType[];
35
+ travelTypeIcon: ReactNode;
36
+
37
+ // Travel classes
38
+ travelClasses: TravelClass[];
39
+ travelClassIcon: ReactNode;
40
+
41
+ // Date flexibility
42
+ dateFlexibility?: DateFlexibility[];
43
+ minDate?: Date;
44
+ maxDate?: Date;
45
+ showReturnDate: boolean;
46
+ datesIcon: ReactNode;
47
+
48
+ // Travelers
49
+ defaultTravelers?: number;
50
+ maxTravelers?: number;
51
+ maxChildAge?: number;
52
+ maxInfantAge?: number;
53
+
54
+ onSubmit: (data: any) => void;
55
+ submitIcon: ReactNode;
56
+
57
+ nationalities: Nationality[];
58
+ languageCode?: string;
59
+ }
60
+
61
+ export interface BaseFieldConfig {
62
+ fieldKey: string;
63
+ label: string;
64
+ placeholder: string;
65
+ options: TypeaheadOption[];
66
+ autoComplete?: boolean;
67
+ }
68
+
69
+ export interface TypeaheadOption {
70
+ key: string;
71
+ value: string;
72
+ iataCode?: string;
73
+ country?: string;
74
+ type: OptionType;
75
+ }
76
+
77
+ export type OptionType = 'country' | 'region' | 'oord' | 'location' | 'airport' | 'hotel' | 'other';
78
+
79
+ export interface SingleFieldConfig extends BaseFieldConfig {
80
+ type: 'single';
81
+ }
82
+
83
+ export interface DoubleFieldConfig {
84
+ type: 'double';
85
+ fieldKey: string;
86
+ showReverse?: boolean;
87
+ fields: BaseFieldConfig[];
88
+ }
89
+
90
+ export type FieldConfig = SingleFieldConfig | DoubleFieldConfig;
91
+
92
+ export interface AdditionalFilters {
93
+ showDirectFlights: boolean;
94
+ includeLuggage: boolean;
95
+ }
96
+
97
+ export interface Origin {
98
+ key: string;
99
+ value: string;
100
+ }
101
+
102
+ export interface Destination {
103
+ key: string;
104
+ value: string;
105
+ }
106
+
107
+ export interface Airport {
108
+ key: string;
109
+ value: string;
110
+ }
111
+
112
+ export interface DateFlexibility {
113
+ name: string;
114
+ before: number;
115
+ after: number;
116
+ }
117
+
118
+ export type MobileFilterType = 'search' | 'date' | 'traveler' | null;
119
+
120
+ export type TravelerType = 'adults' | 'kids' | 'babies';
121
+
122
+ export interface Room {
123
+ adults: number;
124
+ kids: number;
125
+ babies: number;
126
+ }
127
+
128
+ export interface TravelType {
129
+ id: number;
130
+ label: string;
131
+ icon?: ReactNode;
132
+ }
133
+
134
+ export interface TravelClass {
135
+ id: number;
136
+ label: string;
137
+ icon?: ReactNode;
138
+ }
139
+
140
+ export interface Nationality {
141
+ id: number;
142
+ label: string;
143
+ icon?: ReactNode;
144
+ }
@@ -6,11 +6,12 @@ import { resetFilters, setFilters } from '../../store/search-results-slice';
6
6
  import { useDispatch } from 'react-redux';
7
7
  import Spinner from '../spinner/spinner';
8
8
  import Icon from '../icon';
9
+ import { getTranslations } from '../../../shared/utils/localization-util';
9
10
 
10
11
  interface FiltersProps {
11
12
  filters: Filter[];
12
- isMobileFiltersOpen: boolean;
13
- handleSetIsMobileFiltersOpen: () => void;
13
+ isOpen: boolean;
14
+ handleSetIsOpen: () => void;
14
15
  handleApplyFilters: () => void;
15
16
  isLoading?: boolean;
16
17
  }
@@ -88,8 +89,9 @@ const initialFilters: Filter[] = [
88
89
  }
89
90
  ] as Filter[];
90
91
 
91
- const Filters: React.FC<FiltersProps> = ({ filters, isMobileFiltersOpen, handleSetIsMobileFiltersOpen, handleApplyFilters, isLoading }) => {
92
+ const Filters: React.FC<FiltersProps> = ({ filters, isOpen, handleSetIsOpen, handleApplyFilters, isLoading }) => {
92
93
  const context = useContext(SearchResultsConfigurationContext);
94
+ const translations = getTranslations(context?.languageCode ?? 'en-GB');
93
95
  const [visibleFilters, setVisibleFilters] = useState<Record<string, boolean>>({});
94
96
  const [pendingFilters, setPendingFilters] = useState<Filter[]>([]);
95
97
  useEffect(() => {
@@ -175,8 +177,8 @@ const Filters: React.FC<FiltersProps> = ({ filters, isMobileFiltersOpen, handleS
175
177
  context?.onFilterChange?.(pendingFilters);
176
178
  handleApplyFilters();
177
179
 
178
- if (isMobileFiltersOpen) {
179
- handleSetIsMobileFiltersOpen();
180
+ if (isOpen) {
181
+ handleSetIsOpen();
180
182
  }
181
183
  };
182
184
 
@@ -204,22 +206,19 @@ const Filters: React.FC<FiltersProps> = ({ filters, isMobileFiltersOpen, handleS
204
206
  {/* ---------------- Filters ---------------- */}
205
207
 
206
208
  {/* ---------------- Filters desktop ---------------- */}
207
- <div className={`search__filters--modal ${isMobileFiltersOpen ? 'is-open' : ''}`}>
208
- <div className="search__filters--background" onClick={() => handleSetIsMobileFiltersOpen()}></div>
209
- <button className="search__filters--close" onClick={() => handleSetIsMobileFiltersOpen()}>
209
+ <div className={`search__filters--modal ${isOpen ? 'is-open' : ''}`}>
210
+ <div className="search__filters--background" onClick={() => handleSetIsOpen()}></div>
211
+ <button className="search__filters--close" onClick={() => handleSetIsOpen()}>
210
212
  <Icon name="ui-close" height={24} />
211
213
  </button>
212
214
  <div className="search__filters">
213
215
  <div className="search__filter-row search__filter__header">
214
216
  <div className="search__filter-row-flex-title">
215
- <p className="search__filter-small-title">
216
- {/* */}
217
- Your trip summary
218
- </p>
217
+ <p className="search__filter-small-title">{translations.SRP.FILTERS}</p>
219
218
  </div>
220
219
  {!isLoading && (
221
220
  <a className="search__filter-reset" onClick={() => handleFullReset()}>
222
- {context.translations?.resetButton}
221
+ {translations.SRP.RESET}
223
222
  </a>
224
223
  )}
225
224
  {/* <Icon name="ui-info" height={16} /> */}
@@ -366,13 +365,13 @@ const Filters: React.FC<FiltersProps> = ({ filters, isMobileFiltersOpen, handleS
366
365
  className="cta--secondary "
367
366
  onClick={() => {
368
367
  handleResetPendingChanges();
369
- handleSetIsMobileFiltersOpen();
368
+ handleSetIsOpen();
370
369
  }}
371
370
  disabled={isLoading}>
372
- {context.translations?.cancel}
371
+ {translations.SRP.CANCEL}
373
372
  </button>
374
373
  <button className="cta" onClick={() => applyFilters()} disabled={isLoading}>
375
- {context.translations?.apply}
374
+ {translations.SRP.APPLY}
376
375
  </button>
377
376
  </div>
378
377
  )}