@qite/tide-booking-component 1.4.102 → 1.4.104

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 (55) hide show
  1. package/build/build-cjs/index.js +1773 -877
  2. package/build/build-cjs/src/search-results/components/filters/filters.d.ts +2 -0
  3. package/build/build-cjs/src/search-results/components/flight/flight-selection/independent-flight-option.d.ts +3 -0
  4. package/build/build-cjs/src/search-results/components/hotel/hotel-accommodation-results.d.ts +1 -0
  5. package/build/build-cjs/src/search-results/store/search-results-selectors.d.ts +424 -0
  6. package/build/build-cjs/src/search-results/store/search-results-slice.d.ts +27 -8
  7. package/build/build-cjs/src/search-results/types.d.ts +14 -2
  8. package/build/build-cjs/src/search-results/utils/search-results-utils.d.ts +8 -6
  9. package/build/build-cjs/src/shared/components/flyin/flyin.d.ts +3 -3
  10. package/build/build-cjs/src/shared/components/flyin/packaging-flights-flyin.d.ts +7 -0
  11. package/build/build-cjs/src/shared/utils/localization-util.d.ts +2 -0
  12. package/build/build-esm/index.js +1747 -861
  13. package/build/build-esm/src/search-results/components/filters/filters.d.ts +2 -0
  14. package/build/build-esm/src/search-results/components/flight/flight-selection/independent-flight-option.d.ts +3 -0
  15. package/build/build-esm/src/search-results/components/hotel/hotel-accommodation-results.d.ts +1 -0
  16. package/build/build-esm/src/search-results/store/search-results-selectors.d.ts +424 -0
  17. package/build/build-esm/src/search-results/store/search-results-slice.d.ts +27 -8
  18. package/build/build-esm/src/search-results/types.d.ts +14 -2
  19. package/build/build-esm/src/search-results/utils/search-results-utils.d.ts +8 -6
  20. package/build/build-esm/src/shared/components/flyin/flyin.d.ts +3 -3
  21. package/build/build-esm/src/shared/components/flyin/packaging-flights-flyin.d.ts +7 -0
  22. package/build/build-esm/src/shared/utils/localization-util.d.ts +2 -0
  23. package/package.json +2 -2
  24. package/src/booking-wizard/features/flight-options/index.tsx +6 -2
  25. package/src/search-results/components/filters/filters.tsx +8 -9
  26. package/src/search-results/components/flight/flight-selection/independent-flight-option.tsx +31 -4
  27. package/src/search-results/components/hotel/hotel-accommodation-results.tsx +81 -25
  28. package/src/search-results/components/icon.tsx +1 -1
  29. package/src/search-results/components/search-results-container/search-results-container.tsx +194 -130
  30. package/src/search-results/store/search-results-selectors.ts +73 -0
  31. package/src/search-results/store/search-results-slice.ts +94 -14
  32. package/src/search-results/types.ts +14 -2
  33. package/src/search-results/utils/search-results-utils.ts +310 -58
  34. package/src/shared/components/flyin/flyin.tsx +102 -19
  35. package/src/shared/components/flyin/packaging-flights-flyin.tsx +164 -0
  36. package/src/shared/translations/ar-SA.json +2 -0
  37. package/src/shared/translations/da-DK.json +2 -0
  38. package/src/shared/translations/de-DE.json +2 -0
  39. package/src/shared/translations/en-GB.json +2 -0
  40. package/src/shared/translations/es-ES.json +2 -0
  41. package/src/shared/translations/fr-BE.json +2 -0
  42. package/src/shared/translations/fr-FR.json +2 -0
  43. package/src/shared/translations/is-IS.json +2 -0
  44. package/src/shared/translations/it-IT.json +2 -0
  45. package/src/shared/translations/ja-JP.json +2 -0
  46. package/src/shared/translations/nl-BE.json +2 -0
  47. package/src/shared/translations/nl-NL.json +2 -0
  48. package/src/shared/translations/no-NO.json +2 -0
  49. package/src/shared/translations/pl-PL.json +2 -0
  50. package/src/shared/translations/pt-PT.json +2 -0
  51. package/src/shared/translations/sv-SE.json +2 -0
  52. package/src/shared/utils/localization-util.ts +5 -2
  53. package/styles/components/_flight-option.scss +14 -1
  54. package/styles/components/_flyin.scss +16 -0
  55. package/styles/components/_search.scss +9 -1
@@ -1,23 +1,31 @@
1
- import React, { useEffect, useRef } from 'react';
1
+ import React, { useContext, useEffect, useRef } from 'react';
2
2
  import Icon from '../icon';
3
3
  import { useFlightSearch } from '../../../search-results/components/flight/flight-search-context';
4
- import { useDispatch } from 'react-redux';
4
+ import { useDispatch, useSelector } from 'react-redux';
5
5
  import {
6
- setAccommodationFlyInStep,
6
+ resetFilters,
7
+ setFilters,
8
+ setFlyInType,
7
9
  setSelectedFlight,
8
10
  setSelectedFlightDetails,
9
11
  setSelectedPackagingAccoResult,
10
- setSelectedSearchResult
12
+ setSelectedSearchResult,
13
+ setSortType
11
14
  } from '../../../search-results/store/search-results-slice';
12
15
  import FlightsFlyIn from './flights-flyin';
13
16
  import AccommodationFlyIn from './accommodation-flyin';
14
17
  import { PortalQsmType } from '@qite/tide-client';
15
18
  import GroupTourFlyIn from './group-tour-flyin';
16
- import { AccommodationFlyInStep } from '../../../search-results/types';
19
+ import { FlyInType, SortByType } from '../../../search-results/types';
17
20
  import HotelAccommodationResults from '../../../search-results/components/hotel/hotel-accommodation-results';
21
+ import PackageingFlightsFlyIn from './packaging-flights-flyin';
22
+ import SearchResultsConfigurationContext from '../../../search-results/search-results-configuration-context';
23
+ import { findSortByType, getSortingName, getTranslations } from '../../utils/localization-util';
24
+ import Filters from '../../../search-results/components/filters/filters';
25
+ import { SearchResultsRootState } from '../../../search-results/store/search-results-store';
26
+ import ItemPicker from '../../../search-results/components/item-picker';
18
27
 
19
28
  type FlyInProps = {
20
- title: string;
21
29
  srpType: PortalQsmType;
22
30
  isOpen: boolean;
23
31
  setIsOpen: (open: boolean) => void;
@@ -25,23 +33,32 @@ type FlyInProps = {
25
33
  onPanelRef?: (el: HTMLDivElement | null) => void;
26
34
  detailsLoading: boolean;
27
35
  handleConfirm?: () => void;
28
- accommodationStep?: AccommodationFlyInStep;
36
+ flyInType?: FlyInType | null;
29
37
  isPackageEditFlow?: boolean;
38
+ sortByTypes?: SortByType[];
30
39
  };
31
40
 
32
41
  const FlyIn: React.FC<FlyInProps> = ({
33
- title,
34
42
  srpType,
35
43
  isOpen,
36
44
  setIsOpen,
37
45
  className = '',
38
46
  onPanelRef,
39
47
  detailsLoading,
40
- accommodationStep,
48
+ flyInType,
41
49
  isPackageEditFlow,
42
- handleConfirm
50
+ handleConfirm,
51
+ sortByTypes
43
52
  }) => {
44
53
  const dispatch = useDispatch();
54
+ const context = useContext(SearchResultsConfigurationContext);
55
+ const language = context?.languageCode ?? 'en-GB';
56
+ const translations = getTranslations(language);
57
+
58
+ const { isLoading, initialFilters, filters, filteredPackagingAccoResults, selectedSortType } = useSelector(
59
+ (state: SearchResultsRootState) => state.searchResults
60
+ );
61
+
45
62
  const { onCancelSearch } = useFlightSearch();
46
63
  const panelRef = useRef<HTMLDivElement>(null);
47
64
 
@@ -81,26 +98,52 @@ const FlyIn: React.FC<FlyInProps> = ({
81
98
  dispatch(setSelectedSearchResult(null));
82
99
  dispatch(setSelectedPackagingAccoResult(null));
83
100
  }
84
- dispatch(setAccommodationFlyInStep('details'));
101
+ dispatch(setFlyInType('acco-details'));
85
102
  setIsOpen(false);
86
103
  }
87
104
  };
88
105
 
89
106
  const handleGoBack = () => {
90
- dispatch(setAccommodationFlyInStep('results'));
107
+ dispatch(setFlyInType('acco-results'));
108
+ };
109
+
110
+ const handleSortChange = (newSortKey: string, direction?: string) => {
111
+ if (sortByTypes === undefined) return;
112
+ const newSortByType = findSortByType(sortByTypes, newSortKey, direction ?? 'asc');
113
+ if (newSortByType) {
114
+ dispatch(setSortType(newSortByType));
115
+ }
91
116
  };
92
117
 
93
118
  return (
94
- <div className={`flyin ${isOpen ? 'flyin--active' : ''} ${className} ${isPackageEditFlow ? 'flyin--large' : ''}`}>
119
+ <div
120
+ className={`flyin ${isOpen ? 'flyin--active' : ''} ${className} ${
121
+ isPackageEditFlow || flyInType === 'flight-outward-results' || flyInType === 'flight-return-results' || flyInType === 'acco-results'
122
+ ? 'flyin--large'
123
+ : ''
124
+ }`}>
95
125
  <div className={`flyin__panel ${isOpen ? 'flyin__panel--active' : ''}`} ref={panelRef}>
96
126
  <div className="flyin__content">
97
127
  <div className="flyin__content-title-row">
98
- <h3 className="flyin__content-title">{title}</h3>
128
+ <h3 className="flyin__content-title">
129
+ {srpType === PortalQsmType.Flight && 'Select your fare'}
130
+ {srpType === PortalQsmType.Accommodation ||
131
+ (srpType === PortalQsmType.AccommodationAndFlight &&
132
+ (flyInType === 'acco-results' || flyInType === 'acco-details') &&
133
+ `${translations.SRP.SELECT} ${translations.SRP.ACCOMMODATION}`)}
134
+ {srpType === PortalQsmType.AccommodationAndFlight &&
135
+ flyInType === 'flight-outward-results' &&
136
+ `${translations.SRP.SELECT} ${translations.FLIGHTS_FORM.OUTWARD_FLIGHT}`}
137
+ {srpType === PortalQsmType.AccommodationAndFlight &&
138
+ flyInType === 'flight-return-results' &&
139
+ `${translations.SRP.SELECT} ${translations.FLIGHTS_FORM.RETURN_FLIGHT}`}
140
+ {srpType === PortalQsmType.AccommodationAndFlight && flyInType === 'flight-details' && 'Select your fare'}
141
+ </h3>
99
142
  <span className="flyin__close" onClick={() => handleClose()}>
100
143
  <Icon name="ui-close" width={30} height={30} aria-hidden="true" />
101
144
  </span>
102
145
  </div>
103
- {isPackageEditFlow && accommodationStep === 'details' && (
146
+ {isPackageEditFlow && flyInType === 'acco-details' && (
104
147
  <div className="flyin__content-title-row">
105
148
  <div onClick={handleGoBack} className="flyin__content-title__back">
106
149
  <Icon name="ui-chevron" width={14} height={14} aria-hidden="true" />
@@ -111,16 +154,56 @@ const FlyIn: React.FC<FlyInProps> = ({
111
154
  </div>
112
155
  {srpType === PortalQsmType.Flight && <FlightsFlyIn isOpen={isOpen} setIsOpen={setIsOpen} />}
113
156
 
114
- {(srpType === PortalQsmType.Accommodation || srpType === PortalQsmType.AccommodationAndFlight) && accommodationStep === 'results' && (
115
- <div className="flyin__content">
116
- <HotelAccommodationResults isLoading={detailsLoading} />
157
+ {(srpType === PortalQsmType.Accommodation || srpType === PortalQsmType.AccommodationAndFlight) && flyInType === 'acco-results' && (
158
+ <div className="flyin__content flyin__content--columns">
159
+ <Filters
160
+ initialFilters={initialFilters}
161
+ filters={filters}
162
+ isOpen={false}
163
+ handleSetIsOpen={() => {}}
164
+ // handleApplyFilters={() => setSearchTrigger((prev) => prev + 1)}
165
+ isLoading={isLoading}
166
+ setFilters={(filters) => dispatch(setFilters(filters))}
167
+ resetFilters={(filters) => dispatch(resetFilters(filters))}
168
+ />
169
+ <div className="search__results__wrapper">
170
+ <div className="search__result-row">
171
+ <span className="search__result-row-text">
172
+ {!isLoading && (
173
+ <>
174
+ {filteredPackagingAccoResults?.length && filteredPackagingAccoResults.length}
175
+ &nbsp;{translations.SRP.TOTAL_RESULTS_LABEL}
176
+ </>
177
+ )}
178
+ </span>
179
+ {sortByTypes && sortByTypes.length > 0 && (
180
+ <div className="search__result-row-filter">
181
+ <ItemPicker
182
+ items={sortByTypes}
183
+ selection={selectedSortType?.label || undefined}
184
+ selectedSortByType={selectedSortType}
185
+ label={translations.SRP.SORTBY}
186
+ placeholder={translations.SRP.SORTBY}
187
+ classModifier="travel-class-picker__items"
188
+ valueFormatter={(value, direction) => getSortingName(translations, findSortByType(sortByTypes, value, direction ?? 'asc'))}
189
+ onPick={(newSortKey, direction) => handleSortChange(newSortKey, direction)}
190
+ />
191
+ </div>
192
+ )}
193
+ </div>
194
+ <HotelAccommodationResults isLoading={detailsLoading} isFlyIn={true} />
195
+ </div>
117
196
  </div>
118
197
  )}
119
198
 
120
- {(srpType === PortalQsmType.Accommodation || srpType === PortalQsmType.AccommodationAndFlight) && accommodationStep === 'details' && (
199
+ {(srpType === PortalQsmType.Accommodation || srpType === PortalQsmType.AccommodationAndFlight) && flyInType === 'acco-details' && (
121
200
  <AccommodationFlyIn isLoading={detailsLoading} handleConfirm={handleConfirm!} />
122
201
  )}
123
202
 
203
+ {srpType === PortalQsmType.AccommodationAndFlight && (flyInType === 'flight-outward-results' || flyInType === 'flight-return-results') && (
204
+ <PackageingFlightsFlyIn isOpen={isOpen} setIsOpen={setIsOpen} />
205
+ )}
206
+
124
207
  {srpType === PortalQsmType.GroupTour && <GroupTourFlyIn isLoading={detailsLoading} isOpen={isOpen} setIsOpen={setIsOpen} />}
125
208
  </div>
126
209
  </div>
@@ -0,0 +1,164 @@
1
+ import React, { useContext, useState } from 'react';
2
+ import { useDispatch, useSelector } from 'react-redux';
3
+ import {
4
+ resetFlightFilters,
5
+ setFlightFilters,
6
+ setFlightSortType,
7
+ setFlyInIsOpen,
8
+ setFlyInType,
9
+ setSelectedOutwardKey,
10
+ setSelectedReturnKey
11
+ } from '../../../search-results/store/search-results-slice';
12
+ import { SearchResultsRootState } from '../../../search-results/store/search-results-store';
13
+ import Spinner from '../../../search-results/components/spinner/spinner';
14
+ import SearchResultsConfigurationContext from '../../../search-results/search-results-configuration-context';
15
+ import { findSortByType, getSortingName, getTranslations } from '../../utils/localization-util';
16
+ import { getFlightKey } from '../../../search-results/utils/flight-utils';
17
+ import {
18
+ selectSelectedOutward,
19
+ selectSelectedReturn,
20
+ selectUniqueOutwardFlights,
21
+ selectUniqueReturnFlights
22
+ } from '../../../search-results/store/search-results-selectors';
23
+ import IndependentFlightOption from '../../../search-results/components/flight/flight-selection/independent-flight-option';
24
+ import Filters from '../../../search-results/components/filters/filters';
25
+ import { SortByType } from '../../../search-results/types';
26
+ import ItemPicker from '../../../search-results/components/item-picker';
27
+
28
+ type FlightsFlyInProps = {
29
+ isOpen: boolean;
30
+ setIsOpen: (open: boolean) => void;
31
+ };
32
+
33
+ const PackageingFlightsFlyIn: React.FC<FlightsFlyInProps> = ({ isOpen, setIsOpen }) => {
34
+ const context = useContext(SearchResultsConfigurationContext);
35
+ const language = context?.languageCode ?? 'en-GB';
36
+ const translations = getTranslations(language);
37
+
38
+ const dispatch = useDispatch();
39
+ const { flightsLoading, initialFlightFilters, flightFilters, flyInType, selectedFlightSortType } = useSelector(
40
+ (state: SearchResultsRootState) => state.searchResults
41
+ );
42
+ const uniqueOutwardFlights = useSelector(selectUniqueOutwardFlights);
43
+ const uniqueReturnFlights = useSelector(selectUniqueReturnFlights);
44
+ const selectedOutward = useSelector(selectSelectedOutward);
45
+ const selectedReturn = useSelector(selectSelectedReturn);
46
+
47
+ const [outwardStepComplete, setOutwardStepComplete] = useState<boolean>(false);
48
+
49
+ const handleConfirm = (): void => {
50
+ if (!outwardStepComplete) {
51
+ setOutwardStepComplete(true);
52
+ dispatch(setFlyInType('flight-return-results'));
53
+ return;
54
+ } else {
55
+ dispatch(setFlyInType(null));
56
+ setOutwardStepComplete(false);
57
+ dispatch(setFlyInIsOpen(false));
58
+ }
59
+ };
60
+
61
+ const sortByTypes = [
62
+ { direction: 'asc', label: 'default' } as SortByType,
63
+ { direction: 'asc', label: 'price' } as SortByType,
64
+ { direction: 'desc', label: 'price' } as SortByType,
65
+ { direction: 'asc', label: 'departureTime' } as SortByType,
66
+ { direction: 'desc', label: 'departureTime' } as SortByType,
67
+ { direction: 'asc', label: 'durationInTicks' } as SortByType,
68
+ { direction: 'desc', label: 'durationInTicks' } as SortByType
69
+ ];
70
+
71
+ const handleSortChange = (newSortKey: string, direction?: string) => {
72
+ if (sortByTypes === undefined) return;
73
+ const newSortByType = findSortByType(sortByTypes, newSortKey, direction ?? 'asc');
74
+ if (newSortByType) {
75
+ dispatch(setFlightSortType(newSortByType));
76
+ }
77
+ };
78
+
79
+ return (
80
+ <>
81
+ <div className="flyin__content flyin__content--columns">
82
+ {flightsLoading ? (
83
+ <Spinner />
84
+ ) : (
85
+ <>
86
+ <Filters
87
+ initialFilters={initialFlightFilters}
88
+ filters={flightFilters}
89
+ isOpen={false}
90
+ handleSetIsOpen={() => {}}
91
+ // handleApplyFilters={() => setSearchTrigger((prev) => prev + 1)}
92
+ isLoading={flightsLoading}
93
+ setFilters={(filters) => dispatch(setFlightFilters(filters))}
94
+ resetFilters={(filters) => dispatch(resetFlightFilters(filters))}
95
+ />
96
+ <div className="search__results__wrapper">
97
+ <div className="search__result-row">
98
+ <span className="search__result-row-text">
99
+ {uniqueOutwardFlights?.length && uniqueOutwardFlights.length}
100
+ &nbsp;{translations.FLIGHTS_FORM.FLIGHTS_FOUND_2}&nbsp;{translations.FLIGHTS_FORM.FLIGHTS_FOUND_3}
101
+ </span>
102
+ {sortByTypes && sortByTypes.length > 0 && (
103
+ <div className="search__result-row-filter">
104
+ <ItemPicker
105
+ items={sortByTypes}
106
+ selection={selectedFlightSortType?.label || undefined}
107
+ selectedSortByType={selectedFlightSortType || undefined}
108
+ label={translations.SRP.SORTBY}
109
+ placeholder={translations.SRP.SORTBY}
110
+ classModifier=""
111
+ valueFormatter={(value, direction) => getSortingName(translations, findSortByType(sortByTypes, value, direction ?? 'asc'))}
112
+ // onPick={handleSortChange}
113
+ onPick={(newSortKey, direction) => handleSortChange(newSortKey, direction)}
114
+ />
115
+ </div>
116
+ )}
117
+ </div>
118
+ <div className="search__results__cards search__results__cards--extended">
119
+ {flyInType == 'flight-outward-results' &&
120
+ uniqueOutwardFlights.map((result) => (
121
+ <IndependentFlightOption
122
+ key={`flight-${result.outwardGuid}`}
123
+ item={result.outward}
124
+ onSelect={() => dispatch(setSelectedOutwardKey(getFlightKey(result.outward.segments)))}
125
+ guid={result.outwardGuid}
126
+ isOutward={true}
127
+ price={result.price}
128
+ currentSelectedPrice={selectedOutward?.price}
129
+ selectedGuid={selectedOutward?.outwardGuid}
130
+ showSelectedState={true}
131
+ />
132
+ ))}
133
+ {flyInType == 'flight-return-results' &&
134
+ uniqueReturnFlights.map((result) => (
135
+ <IndependentFlightOption
136
+ key={`flight-${result.outwardGuid}`}
137
+ item={result.return}
138
+ onSelect={() => dispatch(setSelectedReturnKey(getFlightKey(result.return.segments)))}
139
+ guid={result.outwardGuid}
140
+ isOutward={false}
141
+ price={result.price}
142
+ currentSelectedPrice={selectedReturn?.price}
143
+ selectedGuid={selectedReturn?.outwardGuid}
144
+ showSelectedState={true}
145
+ />
146
+ ))}
147
+ </div>
148
+ </div>
149
+ </>
150
+ )}
151
+ </div>
152
+ <div className="flyin__footer">
153
+ <div className="flyin__footer__price"></div>
154
+ <div className="flyin__button-wrapper">
155
+ <button className="cta cta--select" onClick={() => handleConfirm()}>
156
+ {translations.QSM.CONFIRM}
157
+ </button>
158
+ </div>
159
+ </div>
160
+ </>
161
+ );
162
+ };
163
+
164
+ export default PackageingFlightsFlyIn;
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "جولة جماعية"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "عرض المزيد",
335
+ "SHOW_LESS": "عرض أقل",
334
336
  "NO_RESULTS": "لم يتم العثور على نتائج.",
335
337
  "TOTAL_RESULTS_LABEL": "تم العثور على باقات",
336
338
  "RESET": "إعادة تعيين",
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "Grupperejse"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "Vis flere",
335
+ "SHOW_LESS": "Vis færre",
334
336
  "NO_RESULTS": "Ingen resultater fundet.",
335
337
  "TOTAL_RESULTS_LABEL": "Fundne pakker",
336
338
  "RESET": "Nulstil",
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "Gruppentour"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "Mehr anzeigen",
335
+ "SHOW_LESS": "Weniger anzeigen",
334
336
  "NO_RESULTS": "Keine Ergebnisse gefunden.",
335
337
  "TOTAL_RESULTS_LABEL": "Gefundene Pakete",
336
338
  "RESET": "Zurücksetzen",
@@ -335,6 +335,8 @@
335
335
  "GROUP_TOUR": "Group tour"
336
336
  },
337
337
  "SRP": {
338
+ "SHOW_MORE": "Show more",
339
+ "SHOW_LESS": "Show less",
338
340
  "NO_RESULTS": "No results found.",
339
341
  "TOTAL_RESULTS_LABEL": "Packages found",
340
342
  "RESET": "Reset",
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "Tour grupal"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "Mostrar más",
335
+ "SHOW_LESS": "Mostrar menos",
334
336
  "NO_RESULTS": "No se han encontrado resultados.",
335
337
  "TOTAL_RESULTS_LABEL": "Paquetes encontrados",
336
338
  "RESET": "Restablecer",
@@ -335,6 +335,8 @@
335
335
  "GROUP_TOUR": "Tour en groupe"
336
336
  },
337
337
  "SRP": {
338
+ "SHOW_MORE": "Afficher plus",
339
+ "SHOW_LESS": "Afficher moins",
338
340
  "NO_RESULTS": "Aucun résultat trouvé.",
339
341
  "TOTAL_RESULTS_LABEL": "Forfaits trouvés",
340
342
  "RESET": "Réinitialiser",
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "Tour en groupe"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "Afficher plus",
335
+ "SHOW_LESS": "Afficher moins",
334
336
  "NO_RESULTS": "Aucun résultat trouvé.",
335
337
  "TOTAL_RESULTS_LABEL": "Forfaits trouvés",
336
338
  "RESET": "Réinitialiser",
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "Ferð í hóp"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "Sýna meira",
335
+ "SHOW_LESS": "Sýna minna",
334
336
  "NO_RESULTS": "Engar niðurstöður fundust.",
335
337
  "TOTAL_RESULTS_LABEL": "Fundnar pakkar",
336
338
  "RESET": "Endurstilla",
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "Tour di gruppo"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "Mostra di più",
335
+ "SHOW_LESS": "Mostra di meno",
334
336
  "NO_RESULTS": "Nessun risultato trovato.",
335
337
  "TOTAL_RESULTS_LABEL": "Pacchetti trovati",
336
338
  "RESET": "Reimposta",
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "グループツアー"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "もっと見る",
335
+ "SHOW_LESS": "閉じる",
334
336
  "NO_RESULTS": "結果が見つかりませんでした。",
335
337
  "TOTAL_RESULTS_LABEL": "見つかったパッケージ",
336
338
  "RESET": "リセット",
@@ -335,6 +335,8 @@
335
335
  "GROUP_TOUR": "Groepsreis"
336
336
  },
337
337
  "SRP": {
338
+ "SHOW_MORE": "Toon meer",
339
+ "SHOW_LESS": "Toon minder",
338
340
  "NO_RESULTS": "Geen resultaten gevonden.",
339
341
  "TOTAL_RESULTS_LABEL": "Gevonden pakketten",
340
342
  "RESET": "Resetten",
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "Groepsreis"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "Toon meer",
335
+ "SHOW_LESS": "Toon minder",
334
336
  "NO_RESULTS": "Geen resultaten gevonden.",
335
337
  "TOTAL_RESULTS_LABEL": "Gevonden pakketten",
336
338
  "RESET": "Resetten",
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "Gruppetur"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "Vis mer",
335
+ "SHOW_LESS": "Vis mindre",
334
336
  "NO_RESULTS": "Ingen resultater funnet.",
335
337
  "TOTAL_RESULTS_LABEL": "Fant pakker",
336
338
  "RESET": "Tilbakestill",
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "Tour w grupie"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "Pokaż więcej",
335
+ "SHOW_LESS": "Pokaż mniej",
334
336
  "NO_RESULTS": "Nie znaleziono wyników.",
335
337
  "TOTAL_RESULTS_LABEL": "Znalezione pakiety",
336
338
  "RESET": "Resetuj",
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "Tour em grupo"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "Mostrar mais",
335
+ "SHOW_LESS": "Mostrar menos",
334
336
  "NO_RESULTS": "Nenhum resultado encontrado.",
335
337
  "TOTAL_RESULTS_LABEL": "Pacotes encontrados",
336
338
  "RESET": "Redefinir",
@@ -331,6 +331,8 @@
331
331
  "GROUP_TOUR": "Gruppresa"
332
332
  },
333
333
  "SRP": {
334
+ "SHOW_MORE": "Visa mer",
335
+ "SHOW_LESS": "Visa mindre",
334
336
  "NO_RESULTS": "Inga resultat hittades.",
335
337
  "TOTAL_RESULTS_LABEL": "Hittade paket",
336
338
  "RESET": "Återställ",
@@ -188,9 +188,12 @@ export const timeFromDateTime = (dateTime: Date | undefined): string => {
188
188
  if (!dateTime) {
189
189
  return '';
190
190
  }
191
+
191
192
  const date = new Date(dateTime);
192
- const hours = date.getHours();
193
- const minutes = date.getMinutes();
193
+
194
+ const hours = date.getUTCHours();
195
+ const minutes = date.getUTCMinutes();
196
+
194
197
  return `${hours}:${minutes < 10 ? '0' : ''}${minutes}`;
195
198
  };
196
199
 
@@ -110,6 +110,7 @@
110
110
  text-align: center;
111
111
  justify-content: center;
112
112
  align-self: flex-end;
113
+
113
114
  @include media-md {
114
115
  max-width: 162px;
115
116
  min-width: 162px;
@@ -490,6 +491,7 @@
490
491
  &__title {
491
492
  display: flex;
492
493
  flex-direction: column;
494
+
493
495
  h2 {
494
496
  font-size: 20px;
495
497
  font-family: var(--tide-booking-font-heading);
@@ -875,6 +877,7 @@
875
877
  width: 100%;
876
878
  text-align: center;
877
879
  justify-content: center;
880
+
878
881
  @include media-md {
879
882
  max-width: 162px;
880
883
  }
@@ -933,6 +936,7 @@
933
936
  width: 100%;
934
937
  text-align: center;
935
938
  justify-content: center;
939
+
936
940
  @include media-md {
937
941
  max-width: 162px;
938
942
  }
@@ -1268,7 +1272,8 @@
1268
1272
  cursor: pointer;
1269
1273
  box-shadow: 0 1.25px 5.625px -1.25px rgba(0, 0, 0, 0.25);
1270
1274
  position: relative;
1271
- z-index: 2; /* Ensure thumbs appear above the track */
1275
+ z-index: 2;
1276
+ /* Ensure thumbs appear above the track */
1272
1277
  }
1273
1278
 
1274
1279
  input[type='range']::-moz-range-thumb {
@@ -1336,6 +1341,14 @@
1336
1341
  transform: translateX(50%);
1337
1342
  }
1338
1343
  }
1344
+
1345
+ &--selected {
1346
+ .flight__option {
1347
+ border: 2px solid #29297c20;
1348
+ box-shadow: 1px 5px 5px 4px #29297c20;
1349
+ margin-bottom: 10px;
1350
+ }
1351
+ }
1339
1352
  }
1340
1353
 
1341
1354
  // .flight-option {
@@ -537,6 +537,20 @@
537
537
  }
538
538
  }
539
539
  }
540
+
541
+ &--columns {
542
+ display: flex;
543
+ gap: 10px;
544
+
545
+ .search__results__wrapper {
546
+ width: 100%;
547
+ }
548
+
549
+ .search__results__cards {
550
+ grid-template-rows: auto;
551
+ align-content: flex-start;
552
+ }
553
+ }
540
554
  }
541
555
 
542
556
  &__button {
@@ -601,6 +615,8 @@
601
615
 
602
616
  background: var(--tide-booking-white);
603
617
 
618
+ z-index: 1;
619
+
604
620
  @include mixins.media-sm {
605
621
  margin-top: auto;
606
622
  padding: 30px;
@@ -361,9 +361,12 @@
361
361
  }
362
362
 
363
363
  &__prices {
364
- padding: 0 20px;
365
364
  display: flex;
366
365
  flex-direction: column;
366
+ justify-content: center;
367
+
368
+ height: 173.5px;
369
+ padding: 0 20px;
367
370
 
368
371
  &__wrapper {
369
372
  padding: 20px 0px;
@@ -761,6 +764,11 @@
761
764
  @include mixins.media-xgl {
762
765
  grid-template-columns: repeat(3, 1fr);
763
766
  }
767
+
768
+ &__actions {
769
+ display: flex;
770
+ justify-content: flex-end;
771
+ }
764
772
  }
765
773
 
766
774
  &__wrapper {