@qite/tide-booking-component 1.4.77 → 1.4.78

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qite/tide-booking-component",
3
- "version": "1.4.77",
3
+ "version": "1.4.78",
4
4
  "description": "React Booking wizard & Booking product component for Tide",
5
5
  "main": "build/build-cjs/index.js",
6
6
  "types": "build/build-cjs/src/index.d.ts",
@@ -6,6 +6,7 @@ import ContactForm from '../../components/contact';
6
6
  import Slider from '../../components/slider';
7
7
  import { Nationality, QSMConfiguration, TypeaheadOption } from '../../../qsm/types';
8
8
  import QSM from '../../../qsm';
9
+ import { WebsiteConfigurationSearchConfiguration } from '@qite/tide-client';
9
10
 
10
11
  interface ContentPageSelfContainedProps {
11
12
  path: string;
@@ -52,8 +53,93 @@ const travelClasses = [
52
53
  { id: 8, label: 'First Class' }
53
54
  ];
54
55
 
56
+ const searchConfigurations: WebsiteConfigurationSearchConfiguration[] = [
57
+ {
58
+ id: 4,
59
+ name: 'Search Group tour',
60
+ icon: '',
61
+ defaultSearchType: 1,
62
+ serviceTypes: [0],
63
+ defaultCatalogueId: undefined,
64
+ defaultDuration: undefined,
65
+ fromDateAmount: 0,
66
+ fromDateAmountType: 0,
67
+ toDateAmount: 12,
68
+ toDateAmountType: 1,
69
+ enableManualPackaging: false,
70
+ allowFlights: false,
71
+ allowAccommodations: false,
72
+ allowCarRentals: false,
73
+ allowTransfers: false,
74
+ allowExcursions: false,
75
+ qsmType: 5
76
+ },
77
+ {
78
+ id: 5,
79
+ name: 'Search Hotels',
80
+ icon: '',
81
+ defaultSearchType: 0,
82
+ serviceTypes: [3],
83
+ defaultCatalogueId: undefined,
84
+ defaultDuration: undefined,
85
+ fromDateAmount: 1,
86
+ fromDateAmountType: 1,
87
+ toDateAmount: 7,
88
+ toDateAmountType: 0,
89
+ enableManualPackaging: false,
90
+ allowFlights: false,
91
+ allowAccommodations: false,
92
+ allowCarRentals: false,
93
+ allowTransfers: false,
94
+ allowExcursions: false,
95
+ qsmType: 1
96
+ },
97
+ {
98
+ id: 6,
99
+ name: 'Search Flights',
100
+ icon: '',
101
+ defaultSearchType: 3,
102
+ serviceTypes: [7],
103
+ defaultCatalogueId: undefined,
104
+ defaultDuration: undefined,
105
+ fromDateAmount: 1,
106
+ fromDateAmountType: 1,
107
+ toDateAmount: 7,
108
+ toDateAmountType: 0,
109
+ enableManualPackaging: false,
110
+ allowFlights: false,
111
+ allowAccommodations: false,
112
+ allowCarRentals: false,
113
+ allowTransfers: false,
114
+ allowExcursions: false,
115
+ qsmType: 3
116
+ },
117
+ {
118
+ id: 7,
119
+ name: 'Transport + hotel',
120
+ icon: '',
121
+ defaultSearchType: 0,
122
+ serviceTypes: [0],
123
+ defaultCatalogueId: undefined,
124
+ defaultDuration: undefined,
125
+ fromDateAmount: 1,
126
+ fromDateAmountType: 1,
127
+ toDateAmount: 7,
128
+ toDateAmountType: 0,
129
+ enableManualPackaging: true,
130
+ allowFlights: true,
131
+ allowAccommodations: true,
132
+ allowCarRentals: false,
133
+ allowTransfers: false,
134
+ allowExcursions: false,
135
+ qsmType: 2
136
+ }
137
+ ];
138
+
55
139
  let configuration: QSMConfiguration = {
56
140
  type: PortalQsmType.Accommodation,
141
+ searchConfigurations: searchConfigurations,
142
+
57
143
  askTravelers: true,
58
144
  askNationality: true,
59
145
  askTravelClass: true,
@@ -18,6 +18,7 @@ import { QSMState, setFromDate, setSelectedQsmType, setToDate, setTripType } fro
18
18
  import { BaseFieldConfig, DoubleFieldConfig } from '../../types';
19
19
  import { getTranslations } from '../../../shared/utils/localization-util';
20
20
  import { PortalQsmType } from '../../../shared/types';
21
+ import { DateAmountType } from '@qite/tide-client';
21
22
 
22
23
  const QSMContainer: React.FC = () => {
23
24
  const dispatch = useDispatch();
@@ -40,7 +41,8 @@ const QSMContainer: React.FC = () => {
40
41
  destination,
41
42
  allowOneWay,
42
43
  allowRoundtrip,
43
- allowOpenJaw
44
+ allowOpenJaw,
45
+ searchConfigurations
44
46
  } = useContext(QSMConfigurationContext);
45
47
  const translations = getTranslations(languageCode ?? 'en-GB');
46
48
 
@@ -80,14 +82,41 @@ const QSMContainer: React.FC = () => {
80
82
  const handleQsmTypeChange = (value: PortalQsmType) => {
81
83
  dispatch(setSelectedQsmType(value));
82
84
 
83
- let startDate = addMonths(new Date(), 1);
84
- let endDate = addDays(startDate, 7);
85
+ const now = new Date();
85
86
 
87
+ // Default fallback
88
+ let startDate = addMonths(now, 1);
89
+ let endDate = addDays(startDate, 7);
86
90
  if (value === PortalQsmType.GroupTour) {
87
- startDate = new Date();
91
+ startDate = now;
88
92
  endDate = addYears(startDate, 1);
89
93
  }
90
94
 
95
+ const searchConfig = searchConfigurations.find((config) => config.qsmType === value);
96
+
97
+ if (searchConfig) {
98
+ const applyAmount = (baseDate: Date, type: DateAmountType, amount?: number) => {
99
+ if (!amount || type == null) return baseDate;
100
+
101
+ switch (type) {
102
+ case DateAmountType.days:
103
+ return addDays(baseDate, amount);
104
+ case DateAmountType.months:
105
+ return addMonths(baseDate, amount);
106
+ default:
107
+ return baseDate;
108
+ }
109
+ };
110
+
111
+ if (searchConfig.fromDateAmount) {
112
+ startDate = applyAmount(now, searchConfig.fromDateAmountType, searchConfig.fromDateAmount);
113
+ }
114
+
115
+ if (searchConfig.toDateAmount) {
116
+ endDate = applyAmount(startDate, searchConfig.toDateAmountType, searchConfig.toDateAmount);
117
+ }
118
+ }
119
+
91
120
  handleDateChange({
92
121
  fromDate: startDate,
93
122
  toDate: endDate
@@ -180,10 +209,77 @@ const QSMContainer: React.FC = () => {
180
209
  };
181
210
  }, [fromDate, toDate, departureAirport, returnAirport, allowOpenJaw]);
182
211
 
212
+ const qsmTypeMeta: Record<PortalQsmType, { icon: string | string[]; label: string }> = {
213
+ [PortalQsmType.Multidestination]: {
214
+ icon: 'ui-location',
215
+ label: translations.QSM.MULTIDESTINATION
216
+ },
217
+ [PortalQsmType.Package]: {
218
+ icon: 'ui-suitcase',
219
+ label: translations.QSM.PACKAGES
220
+ },
221
+ [PortalQsmType.AccommodationAndFlight]: {
222
+ icon: ['ui-backforward', 'ui-bed'],
223
+ label: translations.QSM.TRANSPORT_HOTEL
224
+ },
225
+ [PortalQsmType.Accommodation]: {
226
+ icon: 'ui-bed',
227
+ label: translations.QSM.ACCOMMODATION
228
+ },
229
+ [PortalQsmType.Flight]: {
230
+ icon: 'ui-flight',
231
+ label: translations.QSM.TRANSPORTS
232
+ },
233
+ [PortalQsmType.GroupTour]: {
234
+ icon: 'ui-group',
235
+ label: translations.QSM.GROUP_TOUR
236
+ },
237
+ [PortalQsmType.RoundTrip]: {
238
+ icon: 'ui-group',
239
+ label: translations.QSM.ROUNDTRIP
240
+ },
241
+ [PortalQsmType.Ticket]: {
242
+ icon: 'ui-ticket',
243
+ label: translations.QSM.TICKET_ONLY
244
+ },
245
+ [PortalQsmType.Car]: {
246
+ icon: 'ui-car',
247
+ label: translations.QSM.RENT_A_CAR
248
+ },
249
+ [PortalQsmType.Transfer]: {
250
+ icon: 'ui-backforward',
251
+ label: translations.QSM.TRANSFERS
252
+ },
253
+ [PortalQsmType.Cruise]: {
254
+ icon: 'ui-ship',
255
+ label: translations.QSM.CRUISES
256
+ }
257
+ };
258
+
183
259
  return (
184
260
  <div className="qsm">
185
261
  <div className="qsm__content">
186
262
  <div className="qsm__tabs">
263
+ {searchConfigurations.map((searchConfig, index) => {
264
+ const meta = qsmTypeMeta[searchConfig.qsmType];
265
+
266
+ if (!meta) return null; // safety guard
267
+
268
+ return (
269
+ <button
270
+ key={`qsm-type-${index}`}
271
+ type="button"
272
+ className={`qsm__tab ${qsmType === searchConfig.qsmType ? 'qsm__tab--active' : ''}`}
273
+ onClick={() => handleQsmTypeChange(searchConfig.qsmType)}>
274
+ <span className="qsm__tab__icons">
275
+ {Array.isArray(meta.icon) ? meta.icon.map((icon, i) => <Icon key={i} name={icon} height={14} />) : <Icon name={meta.icon} height={16} />}
276
+ </span>
277
+
278
+ {meta.label}
279
+ </button>
280
+ );
281
+ })}
282
+ {/*
187
283
  <button
188
284
  type="button"
189
285
  className={`qsm__tab ${qsmType == PortalQsmType.Multidestination ? 'qsm__tab--active' : ''}`}
@@ -275,7 +371,7 @@ const QSMContainer: React.FC = () => {
275
371
  <Icon name="ui-ship" height={16} />
276
372
  </span>
277
373
  {translations.QSM.CRUISES}
278
- </button>
374
+ </button> */}
279
375
  </div>
280
376
  <div className="qsm__filter">
281
377
  {(qsmType === PortalQsmType.Accommodation || qsmType === PortalQsmType.AccommodationAndFlight || qsmType === PortalQsmType.GroupTour) && (
@@ -4,6 +4,7 @@ import { PortalQsmType } from '../shared/types';
4
4
 
5
5
  const QSMConfigurationContext = React.createContext<QSMConfiguration>({
6
6
  type: PortalQsmType.Accommodation,
7
+ searchConfigurations: [],
7
8
  askTravelers: false,
8
9
  askNationality: false,
9
10
  askTravelClass: false,
package/src/qsm/types.ts CHANGED
@@ -1,9 +1,12 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { PortalQsmType, TravelClass, TravelType } from '../shared/types';
3
+ import { WebsiteConfigurationSearchConfiguration } from '@qite/tide-client';
3
4
 
4
5
  export interface QSMConfiguration {
5
6
  type?: PortalQsmType;
6
- // Type specification and dedicated parameters
7
+
8
+ searchConfigurations: WebsiteConfigurationSearchConfiguration[];
9
+
7
10
  askRooms?: boolean; // hotel || roundTrip
8
11
  askTravelType?: boolean; // hotel || roundTrip
9
12
  allowOneWay?: boolean; // flight