@qite/tide-booking-component 1.4.104 → 1.4.105

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 (56) hide show
  1. package/build/build-cjs/index.js +1079 -116
  2. package/build/build-cjs/src/search-results/components/excursions/day-by-day-excursions.d.ts +4 -0
  3. package/build/build-cjs/src/search-results/components/excursions/excursion-details.d.ts +3 -0
  4. package/build/build-cjs/src/search-results/components/excursions/excursion-results.d.ts +8 -0
  5. package/build/build-cjs/src/search-results/store/search-results-selectors.d.ts +122 -0
  6. package/build/build-cjs/src/search-results/store/search-results-slice.d.ts +30 -2
  7. package/build/build-cjs/src/search-results/types.d.ts +27 -1
  8. package/build/build-cjs/src/search-results/utils/query-utils.d.ts +1 -0
  9. package/build/build-cjs/src/shared/components/flyin/flyin.d.ts +2 -1
  10. package/build/build-cjs/src/shared/utils/localization-util.d.ts +3 -0
  11. package/build/build-cjs/src/shared/utils/tide-api-utils.d.ts +6 -0
  12. package/build/build-esm/index.js +1071 -116
  13. package/build/build-esm/src/search-results/components/excursions/day-by-day-excursions.d.ts +4 -0
  14. package/build/build-esm/src/search-results/components/excursions/excursion-details.d.ts +3 -0
  15. package/build/build-esm/src/search-results/components/excursions/excursion-results.d.ts +8 -0
  16. package/build/build-esm/src/search-results/store/search-results-selectors.d.ts +122 -0
  17. package/build/build-esm/src/search-results/store/search-results-slice.d.ts +30 -2
  18. package/build/build-esm/src/search-results/types.d.ts +27 -1
  19. package/build/build-esm/src/search-results/utils/query-utils.d.ts +1 -0
  20. package/build/build-esm/src/shared/components/flyin/flyin.d.ts +2 -1
  21. package/build/build-esm/src/shared/utils/localization-util.d.ts +3 -0
  22. package/build/build-esm/src/shared/utils/tide-api-utils.d.ts +6 -0
  23. package/package.json +2 -2
  24. package/src/search-results/components/excursions/day-by-day-excursions.tsx +169 -0
  25. package/src/search-results/components/excursions/excursion-details.tsx +340 -0
  26. package/src/search-results/components/excursions/excursion-results.tsx +186 -0
  27. package/src/search-results/components/hotel/hotel-card.tsx +0 -3
  28. package/src/search-results/components/icon.tsx +1 -4
  29. package/src/search-results/components/search-results-container/search-results-container.tsx +90 -28
  30. package/src/search-results/store/search-results-selectors.ts +11 -0
  31. package/src/search-results/store/search-results-slice.ts +46 -3
  32. package/src/search-results/types.ts +42 -1
  33. package/src/search-results/utils/query-utils.ts +1 -0
  34. package/src/shared/components/flyin/accommodation-flyin.tsx +4 -2
  35. package/src/shared/components/flyin/flights-flyin.tsx +3 -1
  36. package/src/shared/components/flyin/flyin.tsx +18 -6
  37. package/src/shared/components/flyin/group-tour-flyin.tsx +3 -1
  38. package/src/shared/translations/ar-SA.json +4 -2
  39. package/src/shared/translations/da-DK.json +4 -2
  40. package/src/shared/translations/de-DE.json +4 -2
  41. package/src/shared/translations/en-GB.json +4 -2
  42. package/src/shared/translations/es-ES.json +4 -2
  43. package/src/shared/translations/fr-BE.json +4 -2
  44. package/src/shared/translations/fr-FR.json +4 -2
  45. package/src/shared/translations/is-IS.json +4 -2
  46. package/src/shared/translations/it-IT.json +4 -2
  47. package/src/shared/translations/ja-JP.json +4 -2
  48. package/src/shared/translations/nl-BE.json +4 -2
  49. package/src/shared/translations/nl-NL.json +4 -2
  50. package/src/shared/translations/no-NO.json +4 -2
  51. package/src/shared/translations/pl-PL.json +4 -2
  52. package/src/shared/translations/pt-PT.json +4 -2
  53. package/src/shared/translations/sv-SE.json +4 -2
  54. package/src/shared/utils/localization-util.ts +14 -0
  55. package/src/shared/utils/tide-api-utils.ts +8 -0
  56. package/styles/components/_search.scss +11 -1
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ interface DayByDayExcursionsProps {}
3
+ declare const DayByDayExcursions: React.FC<DayByDayExcursionsProps>;
4
+ export default DayByDayExcursions;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const ExcursionDetails: React.FC;
3
+ export default ExcursionDetails;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { SearchSeed } from '../../types';
3
+ interface ExcursionResultsProps {
4
+ isFlyIn?: boolean;
5
+ activeSearchSeed?: SearchSeed | null;
6
+ }
7
+ declare const ExcursionResults: React.FC<ExcursionResultsProps>;
8
+ export default ExcursionResults;
@@ -1,5 +1,127 @@
1
1
  import { SearchResultsRootState } from './search-results-store';
2
2
  import { PackagingFlightResponse } from '@qite/tide-client';
3
+ export declare const selectPackagingAccoResults: ((state: {
4
+ searchResults: import('./search-results-slice').SearchResultsState;
5
+ }) => import('@qite/tide-client').PackagingAccommodationResponse[]) & {
6
+ clearCache: () => void;
7
+ resultsCount: () => number;
8
+ resetResultsCount: () => void;
9
+ } & {
10
+ resultFunc: (resultFuncArgs_0: import('./search-results-slice').SearchResultsState) => import('@qite/tide-client').PackagingAccommodationResponse[];
11
+ memoizedResultFunc: ((
12
+ resultFuncArgs_0: import('./search-results-slice').SearchResultsState
13
+ ) => import('@qite/tide-client').PackagingAccommodationResponse[]) & {
14
+ clearCache: () => void;
15
+ resultsCount: () => number;
16
+ resetResultsCount: () => void;
17
+ };
18
+ lastResult: () => import('@qite/tide-client').PackagingAccommodationResponse[];
19
+ dependencies: [(state: SearchResultsRootState) => import('./search-results-slice').SearchResultsState];
20
+ recomputations: () => number;
21
+ resetRecomputations: () => void;
22
+ dependencyRecomputations: () => number;
23
+ resetDependencyRecomputations: () => void;
24
+ } & {
25
+ memoize: typeof import('reselect').weakMapMemoize;
26
+ argsMemoize: typeof import('reselect').weakMapMemoize;
27
+ };
28
+ export declare const selectSelectedPackagingAccoResultCode: ((state: {
29
+ searchResults: import('./search-results-slice').SearchResultsState;
30
+ }) => string | null) & {
31
+ clearCache: () => void;
32
+ resultsCount: () => number;
33
+ resetResultsCount: () => void;
34
+ } & {
35
+ resultFunc: (resultFuncArgs_0: import('./search-results-slice').SearchResultsState) => string | null;
36
+ memoizedResultFunc: ((resultFuncArgs_0: import('./search-results-slice').SearchResultsState) => string | null) & {
37
+ clearCache: () => void;
38
+ resultsCount: () => number;
39
+ resetResultsCount: () => void;
40
+ };
41
+ lastResult: () => string | null;
42
+ dependencies: [(state: SearchResultsRootState) => import('./search-results-slice').SearchResultsState];
43
+ recomputations: () => number;
44
+ resetRecomputations: () => void;
45
+ dependencyRecomputations: () => number;
46
+ resetDependencyRecomputations: () => void;
47
+ } & {
48
+ memoize: typeof import('reselect').weakMapMemoize;
49
+ argsMemoize: typeof import('reselect').weakMapMemoize;
50
+ };
51
+ export declare const selectSelectedPackagingAccoResult: ((state: {
52
+ searchResults: import('./search-results-slice').SearchResultsState;
53
+ }) => import('@qite/tide-client').PackagingAccommodationResponse | null) & {
54
+ clearCache: () => void;
55
+ resultsCount: () => number;
56
+ resetResultsCount: () => void;
57
+ } & {
58
+ resultFunc: (
59
+ resultFuncArgs_0: import('@qite/tide-client').PackagingAccommodationResponse[],
60
+ resultFuncArgs_1: string | null
61
+ ) => import('@qite/tide-client').PackagingAccommodationResponse | null;
62
+ memoizedResultFunc: ((
63
+ resultFuncArgs_0: import('@qite/tide-client').PackagingAccommodationResponse[],
64
+ resultFuncArgs_1: string | null
65
+ ) => import('@qite/tide-client').PackagingAccommodationResponse | null) & {
66
+ clearCache: () => void;
67
+ resultsCount: () => number;
68
+ resetResultsCount: () => void;
69
+ };
70
+ lastResult: () => import('@qite/tide-client').PackagingAccommodationResponse | null;
71
+ dependencies: [
72
+ ((state: { searchResults: import('./search-results-slice').SearchResultsState }) => import('@qite/tide-client').PackagingAccommodationResponse[]) & {
73
+ clearCache: () => void;
74
+ resultsCount: () => number;
75
+ resetResultsCount: () => void;
76
+ } & {
77
+ resultFunc: (resultFuncArgs_0: import('./search-results-slice').SearchResultsState) => import('@qite/tide-client').PackagingAccommodationResponse[];
78
+ memoizedResultFunc: ((
79
+ resultFuncArgs_0: import('./search-results-slice').SearchResultsState
80
+ ) => import('@qite/tide-client').PackagingAccommodationResponse[]) & {
81
+ clearCache: () => void;
82
+ resultsCount: () => number;
83
+ resetResultsCount: () => void;
84
+ };
85
+ lastResult: () => import('@qite/tide-client').PackagingAccommodationResponse[];
86
+ dependencies: [(state: SearchResultsRootState) => import('./search-results-slice').SearchResultsState];
87
+ recomputations: () => number;
88
+ resetRecomputations: () => void;
89
+ dependencyRecomputations: () => number;
90
+ resetDependencyRecomputations: () => void;
91
+ } & {
92
+ memoize: typeof import('reselect').weakMapMemoize;
93
+ argsMemoize: typeof import('reselect').weakMapMemoize;
94
+ },
95
+ ((state: { searchResults: import('./search-results-slice').SearchResultsState }) => string | null) & {
96
+ clearCache: () => void;
97
+ resultsCount: () => number;
98
+ resetResultsCount: () => void;
99
+ } & {
100
+ resultFunc: (resultFuncArgs_0: import('./search-results-slice').SearchResultsState) => string | null;
101
+ memoizedResultFunc: ((resultFuncArgs_0: import('./search-results-slice').SearchResultsState) => string | null) & {
102
+ clearCache: () => void;
103
+ resultsCount: () => number;
104
+ resetResultsCount: () => void;
105
+ };
106
+ lastResult: () => string | null;
107
+ dependencies: [(state: SearchResultsRootState) => import('./search-results-slice').SearchResultsState];
108
+ recomputations: () => number;
109
+ resetRecomputations: () => void;
110
+ dependencyRecomputations: () => number;
111
+ resetDependencyRecomputations: () => void;
112
+ } & {
113
+ memoize: typeof import('reselect').weakMapMemoize;
114
+ argsMemoize: typeof import('reselect').weakMapMemoize;
115
+ }
116
+ ];
117
+ recomputations: () => number;
118
+ resetRecomputations: () => void;
119
+ dependencyRecomputations: () => number;
120
+ resetDependencyRecomputations: () => void;
121
+ } & {
122
+ memoize: typeof import('reselect').weakMapMemoize;
123
+ argsMemoize: typeof import('reselect').weakMapMemoize;
124
+ };
3
125
  export declare const selectPackagingFlightResults: ((state: {
4
126
  searchResults: import('./search-results-slice').SearchResultsState;
5
127
  }) => PackagingFlightResponse[]) & {
@@ -1,4 +1,4 @@
1
- import { ExtendedFlightSearchResponseItem, Filter, FlyInType, SortByType } from '../types';
1
+ import { ExcursionSearchParams, ExtendedFlightSearchResponseItem, Filter, FlyInType, SortByType } from '../types';
2
2
  import {
3
3
  BookingPackage,
4
4
  BookingPackageItem,
@@ -40,6 +40,9 @@ export interface SearchResultsState {
40
40
  flyInType: FlyInType | null;
41
41
  itinerary: ClientPortalItinerary | null;
42
42
  editablePackagingEntry: PackagingEntry | null;
43
+ excursionSearchParams: ExcursionSearchParams | null;
44
+ selectedExcursionSearchResult: PackagingAccommodationResponse | null;
45
+ confirmedExcursionsByDay: Record<string, PackagingAccommodationResponse[]>;
43
46
  }
44
47
  export declare const setResults: import('@reduxjs/toolkit').ActionCreatorWithPayload<BookingPackageItem[], 'searchResults/setResults'>,
45
48
  setFilteredResults: import('@reduxjs/toolkit').ActionCreatorWithPayload<BookingPackageItem[], 'searchResults/setFilteredResults'>,
@@ -99,6 +102,31 @@ export declare const setResults: import('@reduxjs/toolkit').ActionCreatorWithPay
99
102
  setItinerary: import('@reduxjs/toolkit').ActionCreatorWithPayload<ClientPortalItinerary | null, 'searchResults/setItinerary'>,
100
103
  setSelectedOutwardKey: import('@reduxjs/toolkit').ActionCreatorWithPayload<string | null, 'searchResults/setSelectedOutwardKey'>,
101
104
  setSelectedReturnKey: import('@reduxjs/toolkit').ActionCreatorWithPayload<string | null, 'searchResults/setSelectedReturnKey'>,
102
- resetFlightSelection: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<'searchResults/resetFlightSelection'>;
105
+ resetFlightSelection: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<'searchResults/resetFlightSelection'>,
106
+ setExcursionSearchParams: import('@reduxjs/toolkit').ActionCreatorWithPayload<ExcursionSearchParams, 'searchResults/setExcursionSearchParams'>,
107
+ setSelectedExcursionSearchResult: import('@reduxjs/toolkit').ActionCreatorWithPayload<
108
+ PackagingAccommodationResponse | null,
109
+ 'searchResults/setSelectedExcursionSearchResult'
110
+ >,
111
+ confirmExcursionForDay: import('@reduxjs/toolkit').ActionCreatorWithPayload<
112
+ {
113
+ dayKey: string;
114
+ excursion: PackagingAccommodationResponse;
115
+ },
116
+ 'searchResults/confirmExcursionForDay'
117
+ >,
118
+ removeConfirmedExcursionForDay: import('@reduxjs/toolkit').ActionCreatorWithPayload<
119
+ {
120
+ dayKey: string;
121
+ excursionCode: string;
122
+ },
123
+ 'searchResults/removeConfirmedExcursionForDay'
124
+ >,
125
+ clearConfirmedExcursionsForDay: import('@reduxjs/toolkit').ActionCreatorWithPayload<
126
+ {
127
+ dayKey: string;
128
+ },
129
+ 'searchResults/clearConfirmedExcursionsForDay'
130
+ >;
103
131
  declare const _default: import('@reduxjs/toolkit').Reducer<SearchResultsState>;
104
132
  export default _default;
@@ -2,6 +2,7 @@ import {
2
2
  BookingPackage,
3
3
  BookingPackageRequestRoom,
4
4
  FlightSearchResponseItem,
5
+ PackageMainRoom,
5
6
  PackagingEntry,
6
7
  WebsiteConfigurationSearchConfiguration
7
8
  } from '@qite/tide-client';
@@ -178,4 +179,29 @@ export type SearchSeed = {
178
179
  destinationAirport?: string | null;
179
180
  rooms: BookingPackageRequestRoom[];
180
181
  };
181
- export type FlyInType = 'flight-outward-results' | 'flight-return-results' | 'flight-details' | 'acco-results' | 'acco-details';
182
+ export type FlyInType =
183
+ | 'flight-outward-results'
184
+ | 'flight-return-results'
185
+ | 'flight-details'
186
+ | 'acco-results'
187
+ | 'acco-details'
188
+ | 'excursion-results'
189
+ | 'excursion-details';
190
+ export interface ExcursionSearchParams {
191
+ date: string;
192
+ fromDate: string;
193
+ toDate: string;
194
+ countryId?: number | null;
195
+ regionId?: number | null;
196
+ oordId?: number | null;
197
+ locationId?: number | null;
198
+ locationName?: string;
199
+ hotelCode: string;
200
+ hotelName: string;
201
+ accommodationCode: string | null;
202
+ accommodationName: string | null;
203
+ rooms?: PackageMainRoom[];
204
+ currencyCode?: string;
205
+ languageCode?: string;
206
+ source?: 'day-by-day-excursions';
207
+ }
@@ -1,6 +1,7 @@
1
1
  import { PackagingEntryLine, PackagingEntry, BookingPackageRequestRoom, PackagingRoom } from '@qite/tide-client';
2
2
  export declare const GROUP_TOUR_SERVICE_TYPE = 1;
3
3
  export declare const ACCOMMODATION_SERVICE_TYPE = 3;
4
+ export declare const EXCURSION_SERVICE_TYPE = 4;
4
5
  export declare const FLIGHT_SERVICE_TYPE = 7;
5
6
  export declare const toDateOnlyString: (value: string | Date) => string;
6
7
  export declare const getPrimaryAccommodationLine: (lines: PackagingEntryLine[]) => PackagingEntryLine | undefined;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { PortalQsmType } from '@qite/tide-client';
3
- import { FlyInType, SortByType } from '../../../search-results/types';
3
+ import { FlyInType, SearchSeed, SortByType } from '../../../search-results/types';
4
4
  type FlyInProps = {
5
5
  srpType: PortalQsmType;
6
6
  isOpen: boolean;
@@ -12,6 +12,7 @@ type FlyInProps = {
12
12
  flyInType?: FlyInType | null;
13
13
  isPackageEditFlow?: boolean;
14
14
  sortByTypes?: SortByType[];
15
+ activeSearchSeed?: SearchSeed | null;
15
16
  };
16
17
  declare const FlyIn: React.FC<FlyInProps>;
17
18
  export default FlyIn;
@@ -335,6 +335,7 @@ export declare const getTranslations: (language: string) => {
335
335
  CONFIRM: string;
336
336
  TRAVELERS: string;
337
337
  GROUP_TOUR: string;
338
+ ALL_TRAVELERS: string;
338
339
  };
339
340
  SRP: {
340
341
  SHOW_MORE: string;
@@ -386,6 +387,7 @@ export declare const getTranslations: (language: string) => {
386
387
  DURATION_ASC: string;
387
388
  DURATION_DESC: string;
388
389
  TRAVEL_GROUP: string;
390
+ EXCURSION: string;
389
391
  };
390
392
  };
391
393
  export declare const locales: {
@@ -422,3 +424,4 @@ export declare const calculateNights: (fromDate: Date, toDate: Date) => number;
422
424
  export declare const calculateDays: (fromDate: Date, toDate: Date) => number;
423
425
  export declare const getSortingName: (translations: any, sortByType: SortByType) => string;
424
426
  export declare const findSortByType: (sortByTypes: SortByType[], sortKey: string, direction: string) => SortByType;
427
+ export declare const getDatesBetween: (fromDate: string, toDate: string) => Date[];
@@ -1,4 +1,10 @@
1
1
  import { TideClientConfig } from '@qite/tide-client';
2
2
  import { ApiSettingsState } from '../types';
3
+ export declare const tideConnection: {
4
+ host: string;
5
+ apiKey: string;
6
+ catalogueIds: number[];
7
+ officeId: number;
8
+ };
3
9
  export declare function buildTideClientConfig(settings?: ApiSettingsState): TideClientConfig;
4
10
  export declare const selectAgentToken: () => string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qite/tide-booking-component",
3
- "version": "1.4.104",
3
+ "version": "1.4.105",
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",
@@ -29,7 +29,7 @@
29
29
  "devDependencies": {
30
30
  "@jsonurl/jsonurl": "^1.1.4",
31
31
  "@popperjs/core": "^2.10.2",
32
- "@qite/tide-client": "^1.1.163",
32
+ "@qite/tide-client": "^1.1.166",
33
33
  "@reduxjs/toolkit": "^2.8.2",
34
34
  "@rollup/plugin-commonjs": "^19.0.1",
35
35
  "@rollup/plugin-json": "^4.1.0",
@@ -0,0 +1,169 @@
1
+ import React, { useContext, useMemo } from 'react';
2
+ import { useDispatch, useSelector } from 'react-redux';
3
+ import { SearchResultsRootState } from '../../store/search-results-store';
4
+ import SearchResultsConfigurationContext from '../../search-results-configuration-context';
5
+ import { getDatesBetween, getTranslations } from '../../../shared/utils/localization-util';
6
+ import { selectSelectedPackagingAccoResult } from '../../store/search-results-selectors';
7
+ import { removeConfirmedExcursionForDay, setExcursionSearchParams, setFlyInIsOpen, setFlyInType } from '../../store/search-results-slice';
8
+ import { ExcursionSearchParams } from '../../types';
9
+ import { format } from 'date-fns';
10
+ import he from 'he';
11
+ import Icon from '../icon';
12
+ import { PackagingAccommodationResponse } from '@qite/tide-client';
13
+
14
+ interface DayByDayExcursionsProps {}
15
+
16
+ const getExcursionContentWithUpdatedPrice = (contents: string | null | undefined, totalPrice: number, currencyCode?: string | null) => {
17
+ if (!contents) return '';
18
+
19
+ const decodedHtml = he.decode(contents);
20
+ const parser = new DOMParser();
21
+ const doc = parser.parseFromString(decodedHtml, 'text/html');
22
+
23
+ const priceElement = doc.querySelector('[data-excursion-price]');
24
+
25
+ if (priceElement) {
26
+ priceElement.textContent = new Intl.NumberFormat('nl-BE', {
27
+ style: 'currency',
28
+ currency: currencyCode ?? 'EUR'
29
+ }).format(totalPrice);
30
+ }
31
+
32
+ return doc.body.innerHTML;
33
+ };
34
+
35
+ const DayByDayExcursions: React.FC<DayByDayExcursionsProps> = () => {
36
+ const context = useContext(SearchResultsConfigurationContext);
37
+ const translations = getTranslations(context?.languageCode ?? 'en-GB');
38
+ const dispatch = useDispatch();
39
+
40
+ const { confirmedExcursionsByDay } = useSelector((state: SearchResultsRootState) => state.searchResults);
41
+ const selectedPackagingAccoResult = useSelector(selectSelectedPackagingAccoResult);
42
+
43
+ const stayDates = useMemo(() => {
44
+ if (!selectedPackagingAccoResult?.fromDate || !selectedPackagingAccoResult?.toDate) {
45
+ return [];
46
+ }
47
+
48
+ return getDatesBetween(selectedPackagingAccoResult.fromDate, selectedPackagingAccoResult.toDate);
49
+ }, [selectedPackagingAccoResult?.fromDate, selectedPackagingAccoResult?.toDate]);
50
+
51
+ const handleSearchExcursions = (day: Date) => {
52
+ if (!selectedPackagingAccoResult) {
53
+ return;
54
+ }
55
+
56
+ const searchParams: ExcursionSearchParams = {
57
+ date: day.toISOString(),
58
+ fromDate: day.toISOString(),
59
+ toDate: day.toISOString(),
60
+ countryId: selectedPackagingAccoResult.countryId,
61
+ regionId: selectedPackagingAccoResult.regionId,
62
+ oordId: selectedPackagingAccoResult.oordId,
63
+ locationId: selectedPackagingAccoResult.locationId,
64
+ locationName: selectedPackagingAccoResult.locationName,
65
+ accommodationCode: selectedPackagingAccoResult.rooms?.[0]?.options?.find((option) => option.isSelected)?.accommodationCode ?? null,
66
+ accommodationName: selectedPackagingAccoResult.rooms?.[0]?.options?.find((option) => option.isSelected)?.accommodationName ?? null,
67
+ hotelCode: selectedPackagingAccoResult.code,
68
+ hotelName: selectedPackagingAccoResult.name,
69
+ rooms: selectedPackagingAccoResult?.rooms ?? []
70
+ };
71
+
72
+ dispatch(setExcursionSearchParams(searchParams));
73
+ dispatch(setFlyInIsOpen(true));
74
+ dispatch(setFlyInType('excursion-results'));
75
+ };
76
+
77
+ const getSelectedOptionsSummary = (excursion: PackagingAccommodationResponse) => {
78
+ const options = excursion.rooms.flatMap((room) => room.options ?? []);
79
+ return options.filter((option) => option.isSelected);
80
+ };
81
+
82
+ if (!selectedPackagingAccoResult || stayDates.length === 0) {
83
+ return null;
84
+ }
85
+
86
+ return (
87
+ <>
88
+ {stayDates.map((day) => {
89
+ const dayKey = format(day, 'yyyy-MM-dd');
90
+ const formattedDay = format(day, 'd');
91
+ const formattedMonth = format(day, 'MMM');
92
+ const confirmedExcursions = confirmedExcursionsByDay[dayKey] ?? [];
93
+
94
+ return (
95
+ <React.Fragment key={dayKey}>
96
+ <div className="search__results__label search__results__label--secondary">
97
+ <div className="search__results__label__date">
98
+ <p className="search__results__label__date-date">{formattedDay}</p>
99
+ <p>{formattedMonth}</p>
100
+ </div>
101
+ <div className="search__results__label__text">
102
+ <h3>
103
+ {translations.SRP.SELECT} <strong>{translations.SRP.EXCURSION}</strong>
104
+ </h3>
105
+ </div>
106
+ </div>
107
+
108
+ <div className="search__results__cards__actions">
109
+ <span>Accommodation for this day: {selectedPackagingAccoResult.name}</span>
110
+
111
+ <button type="button" className="cta cta--secondary" onClick={() => handleSearchExcursions(day)}>
112
+ {confirmedExcursions.length > 0 ? 'Add another excursion' : `${translations.SRP.SELECT} ${translations.SRP.EXCURSION}`}
113
+ </button>
114
+ </div>
115
+
116
+ <div className="search__results__cards search__results__cards--compact">
117
+ {confirmedExcursions &&
118
+ confirmedExcursions.length > 0 &&
119
+ confirmedExcursions.map((excursion) => {
120
+ const selectedOptions = getSelectedOptionsSummary(excursion);
121
+ const totalPrice = selectedOptions.reduce((sum: number, option: any) => sum + (option.price || 0), 0);
122
+ const updatedContents = getExcursionContentWithUpdatedPrice(excursion.contents, totalPrice, excursion.currencyCode);
123
+ return (
124
+ <div
125
+ key={excursion.code}
126
+ className="search__result-card__wrapper search__result-card__wrapper--custom"
127
+ onMouseEnter={(e) => (e.currentTarget.style.transform = 'scale(1.02)')}
128
+ onMouseLeave={(e) => (e.currentTarget.style.transform = 'scale(1)')}>
129
+ <div dangerouslySetInnerHTML={{ __html: updatedContents }}></div>
130
+ <div className="search__result-card__content--extra">
131
+ <div className="search__result-card__content__wrapper">
132
+ <div className="search__result-card__options">
133
+ {selectedOptions.length > 0 &&
134
+ selectedOptions.map((option) => (
135
+ <div className="search__result-card__option" key={option.guid}>
136
+ <Icon name="ui-ticket" width={14} height={14} aria-hidden="true" />
137
+ <span>
138
+ {option.accommodationName}
139
+ {/* {option.paxIds?.length > 0 && (
140
+ <>
141
+ {' '}(Traveller{option.paxIds.length > 1 ? 's' : ''}{' '}{option.paxIds.map((id) => id + 1).join(', ')})
142
+ </>
143
+ )} */}
144
+ </span>
145
+ </div>
146
+ ))}
147
+ </div>
148
+ </div>
149
+ </div>
150
+ <div className="search__result-card__footer">
151
+ <button
152
+ type="button"
153
+ className="cta cta--remove"
154
+ onClick={() => dispatch(removeConfirmedExcursionForDay({ dayKey, excursionCode: excursion.code }))}>
155
+ Remove
156
+ </button>
157
+ </div>
158
+ </div>
159
+ );
160
+ })}
161
+ </div>
162
+ </React.Fragment>
163
+ );
164
+ })}
165
+ </>
166
+ );
167
+ };
168
+
169
+ export default DayByDayExcursions;