@qite/tide-components 1.0.6 → 1.0.7

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 (23) hide show
  1. package/build/build-cjs/index.js +1046 -340
  2. package/build/build-cjs/src/search-results/components/itinerary/itinerary-utils.d.ts +12 -0
  3. package/build/build-cjs/src/search-results/components/itinerary/traject-itinerary.d.ts +9 -0
  4. package/build/build-cjs/src/search-results/components/traject/traject-day-activities-flyin.d.ts +6 -0
  5. package/build/build-cjs/src/search-results/components/traject/traject-flights-flyin.d.ts +13 -0
  6. package/build/build-cjs/src/search-results/components/traject/traject-node-card.d.ts +6 -3
  7. package/build/build-cjs/src/search-results/hooks/use-traject-day-activities.d.ts +6 -0
  8. package/build/build-cjs/src/search-results/store/search-results-slice.d.ts +11 -1
  9. package/build/build-cjs/src/search-results/types.d.ts +12 -2
  10. package/build/build-cjs/src/search-results/utils/traject-utils.d.ts +37 -1
  11. package/build/build-esm/index.js +1046 -340
  12. package/build/build-esm/src/search-results/components/itinerary/itinerary-utils.d.ts +12 -0
  13. package/build/build-esm/src/search-results/components/itinerary/traject-itinerary.d.ts +9 -0
  14. package/build/build-esm/src/search-results/components/traject/traject-day-activities-flyin.d.ts +6 -0
  15. package/build/build-esm/src/search-results/components/traject/traject-flights-flyin.d.ts +13 -0
  16. package/build/build-esm/src/search-results/components/traject/traject-node-card.d.ts +6 -3
  17. package/build/build-esm/src/search-results/hooks/use-traject-day-activities.d.ts +6 -0
  18. package/build/build-esm/src/search-results/store/search-results-slice.d.ts +11 -1
  19. package/build/build-esm/src/search-results/types.d.ts +12 -2
  20. package/build/build-esm/src/search-results/utils/traject-utils.d.ts +37 -1
  21. package/package.json +2 -2
  22. package/styles/booking-search-results-variables.scss +6 -0
  23. package/styles/components/_search.scss +94 -5
@@ -409,6 +409,11 @@ var SRP$f = {
409
409
  ACCOMMODATION: "الإقامة",
410
410
  VIEW_DETAILS: "عرض التفاصيل",
411
411
  NIGHTS: "ليالٍ",
412
+ OF: "من",
413
+ ADD: "إضافة",
414
+ REMOVE: "إزالة",
415
+ ACTIVITIES: "الأنشطة",
416
+ SHOW_ACTIVITIES: "عرض الأنشطة",
412
417
  MORNING_RANGE: "الصباح",
413
418
  AFTERNOON_RANGE: "بعد الظهر",
414
419
  EVENING_RANGE: "المساء",
@@ -848,6 +853,11 @@ var SRP$e = {
848
853
  ACCOMMODATION: "Indkvartering",
849
854
  VIEW_DETAILS: "Se detaljer",
850
855
  NIGHTS: "nætter",
856
+ OF: "af",
857
+ ADD: "Tilføj",
858
+ REMOVE: "Fjern",
859
+ ACTIVITIES: "Aktiviteter",
860
+ SHOW_ACTIVITIES: "Vis aktiviteter",
851
861
  MORNING_RANGE: "Morgen",
852
862
  AFTERNOON_RANGE: "Eftermiddag",
853
863
  EVENING_RANGE: "Aften",
@@ -1291,6 +1301,11 @@ var SRP$d = {
1291
1301
  ACCOMMODATION: "Unterkunft",
1292
1302
  VIEW_DETAILS: "Details anzeigen",
1293
1303
  NIGHTS: "Nächte",
1304
+ OF: "von",
1305
+ ADD: "Hinzufügen",
1306
+ REMOVE: "Entfernen",
1307
+ ACTIVITIES: "Aktivitäten",
1308
+ SHOW_ACTIVITIES: "Aktivitäten anzeigen",
1294
1309
  MORNING_RANGE: "Morgen",
1295
1310
  AFTERNOON_RANGE: "Nachmittag",
1296
1311
  EVENING_RANGE: "Abend",
@@ -1734,6 +1749,11 @@ var SRP$c = {
1734
1749
  ACCOMMODATION: "Accommodation",
1735
1750
  VIEW_DETAILS: "View details",
1736
1751
  NIGHTS: "nights",
1752
+ OF: "of",
1753
+ ADD: "Add",
1754
+ REMOVE: "Remove",
1755
+ ACTIVITIES: "Activities",
1756
+ SHOW_ACTIVITIES: "Show activities",
1737
1757
  PRICE: "Price",
1738
1758
  MORNING_RANGE: "Morning",
1739
1759
  AFTERNOON_RANGE: "Afternoon",
@@ -2173,6 +2193,11 @@ var SRP$b = {
2173
2193
  ACCOMMODATION: "Alojamiento",
2174
2194
  VIEW_DETAILS: "Ver detalles",
2175
2195
  NIGHTS: "noches",
2196
+ OF: "de",
2197
+ ADD: "Añadir",
2198
+ REMOVE: "Eliminar",
2199
+ ACTIVITIES: "Actividades",
2200
+ SHOW_ACTIVITIES: "Ver actividades",
2176
2201
  MORNING_RANGE: "Mañana",
2177
2202
  AFTERNOON_RANGE: "Tarde",
2178
2203
  EVENING_RANGE: "Noche",
@@ -2616,6 +2641,11 @@ var SRP$a = {
2616
2641
  ACCOMMODATION: "Hébergement",
2617
2642
  VIEW_DETAILS: "Voir les détails",
2618
2643
  NIGHTS: "nuits",
2644
+ OF: "sur",
2645
+ ADD: "Ajouter",
2646
+ REMOVE: "Supprimer",
2647
+ ACTIVITIES: "Activités",
2648
+ SHOW_ACTIVITIES: "Voir les activités",
2619
2649
  MORNING_RANGE: "Matin",
2620
2650
  AFTERNOON_RANGE: "Après-midi",
2621
2651
  EVENING_RANGE: "Soir",
@@ -3055,6 +3085,11 @@ var SRP$9 = {
3055
3085
  ACCOMMODATION: "Hébergement",
3056
3086
  VIEW_DETAILS: "Voir les détails",
3057
3087
  NIGHTS: "nuits",
3088
+ OF: "sur",
3089
+ ADD: "Ajouter",
3090
+ REMOVE: "Supprimer",
3091
+ ACTIVITIES: "Activités",
3092
+ SHOW_ACTIVITIES: "Voir les activités",
3058
3093
  MORNING_RANGE: "Matin",
3059
3094
  AFTERNOON_RANGE: "Après-midi",
3060
3095
  EVENING_RANGE: "Soir",
@@ -3494,6 +3529,11 @@ var SRP$8 = {
3494
3529
  ACCOMMODATION: "Gisting",
3495
3530
  VIEW_DETAILS: "Skoða upplýsingar",
3496
3531
  NIGHTS: "nætur",
3532
+ OF: "af",
3533
+ ADD: "Bæta við",
3534
+ REMOVE: "Fjarlægja",
3535
+ ACTIVITIES: "Afþreying",
3536
+ SHOW_ACTIVITIES: "Sýna afþreyingu",
3497
3537
  MORNING_RANGE: "Morgunn",
3498
3538
  AFTERNOON_RANGE: "Síðdegi",
3499
3539
  EVENING_RANGE: "Kvöld",
@@ -3933,6 +3973,11 @@ var SRP$7 = {
3933
3973
  ACCOMMODATION: "Alloggio",
3934
3974
  VIEW_DETAILS: "Visualizza dettagli",
3935
3975
  NIGHTS: "notti",
3976
+ OF: "di",
3977
+ ADD: "Aggiungi",
3978
+ REMOVE: "Rimuovi",
3979
+ ACTIVITIES: "Attività",
3980
+ SHOW_ACTIVITIES: "Mostra attività",
3936
3981
  MORNING_RANGE: "Mattina",
3937
3982
  AFTERNOON_RANGE: "Pomeriggio",
3938
3983
  EVENING_RANGE: "Sera",
@@ -4376,6 +4421,11 @@ var SRP$6 = {
4376
4421
  ACCOMMODATION: "Accommodatie",
4377
4422
  VIEW_DETAILS: "Bekijk details",
4378
4423
  NIGHTS: "nachten",
4424
+ OF: "van",
4425
+ ADD: "Toevoegen",
4426
+ REMOVE: "Verwijderen",
4427
+ ACTIVITIES: "Activiteiten",
4428
+ SHOW_ACTIVITIES: "Toon activiteiten",
4379
4429
  MORNING_RANGE: "Ochtend",
4380
4430
  AFTERNOON_RANGE: "Namiddag",
4381
4431
  EVENING_RANGE: "Avond",
@@ -4815,6 +4865,11 @@ var SRP$5 = {
4815
4865
  ACCOMMODATION: "Accommodatie",
4816
4866
  VIEW_DETAILS: "Bekijk details",
4817
4867
  NIGHTS: "nachten",
4868
+ OF: "van",
4869
+ ADD: "Toevoegen",
4870
+ REMOVE: "Verwijderen",
4871
+ ACTIVITIES: "Activiteiten",
4872
+ SHOW_ACTIVITIES: "Toon activiteiten",
4818
4873
  MORNING_RANGE: "Ochtend",
4819
4874
  AFTERNOON_RANGE: "Namiddag",
4820
4875
  EVENING_RANGE: "Avond",
@@ -5254,6 +5309,11 @@ var SRP$4 = {
5254
5309
  ACCOMMODATION: "Overnatting",
5255
5310
  VIEW_DETAILS: "Se detaljer",
5256
5311
  NIGHTS: "netter",
5312
+ OF: "av",
5313
+ ADD: "Legg til",
5314
+ REMOVE: "Fjern",
5315
+ ACTIVITIES: "Aktiviteter",
5316
+ SHOW_ACTIVITIES: "Vis aktiviteter",
5257
5317
  MORNING_RANGE: "Morgen",
5258
5318
  AFTERNOON_RANGE: "Ettermiddag",
5259
5319
  EVENING_RANGE: "Kveld",
@@ -5693,6 +5753,11 @@ var SRP$3 = {
5693
5753
  ACCOMMODATION: "Zakwaterowanie",
5694
5754
  VIEW_DETAILS: "Zobacz szczegóły",
5695
5755
  NIGHTS: "noce",
5756
+ OF: "z",
5757
+ ADD: "Dodaj",
5758
+ REMOVE: "Usuń",
5759
+ ACTIVITIES: "Atrakcje",
5760
+ SHOW_ACTIVITIES: "Pokaż atrakcje",
5696
5761
  MORNING_RANGE: "Poranek",
5697
5762
  AFTERNOON_RANGE: "Popołudnie",
5698
5763
  EVENING_RANGE: "Wieczór",
@@ -6132,6 +6197,11 @@ var SRP$2 = {
6132
6197
  ACCOMMODATION: "Alojamento",
6133
6198
  VIEW_DETAILS: "Ver detalhes",
6134
6199
  NIGHTS: "noites",
6200
+ OF: "de",
6201
+ ADD: "Adicionar",
6202
+ REMOVE: "Remover",
6203
+ ACTIVITIES: "Atividades",
6204
+ SHOW_ACTIVITIES: "Ver atividades",
6135
6205
  MORNING_RANGE: "Manhã",
6136
6206
  AFTERNOON_RANGE: "Tarde",
6137
6207
  EVENING_RANGE: "Noite",
@@ -6571,6 +6641,11 @@ var SRP$1 = {
6571
6641
  ACCOMMODATION: "Boende",
6572
6642
  VIEW_DETAILS: "Visa detaljer",
6573
6643
  NIGHTS: "nätter",
6644
+ OF: "av",
6645
+ ADD: "Lägg till",
6646
+ REMOVE: "Ta bort",
6647
+ ACTIVITIES: "Aktiviteter",
6648
+ SHOW_ACTIVITIES: "Visa aktiviteter",
6574
6649
  MORNING_RANGE: "Morgon",
6575
6650
  AFTERNOON_RANGE: "Eftermiddag",
6576
6651
  EVENING_RANGE: "Kväll",
@@ -7010,6 +7085,11 @@ var SRP = {
7010
7085
  ACCOMMODATION: "宿泊",
7011
7086
  VIEW_DETAILS: "詳細を見る",
7012
7087
  NIGHTS: "泊",
7088
+ OF: "/",
7089
+ ADD: "追加",
7090
+ REMOVE: "削除",
7091
+ ACTIVITIES: "アクティビティ",
7092
+ SHOW_ACTIVITIES: "アクティビティを表示",
7013
7093
  MORNING_RANGE: "朝",
7014
7094
  AFTERNOON_RANGE: "午後",
7015
7095
  EVENING_RANGE: "夕方",
@@ -16503,7 +16583,7 @@ const Icon = ({ name, className, title, width, height, fill }) => {
16503
16583
  title && React__default.createElement("title", null, title),
16504
16584
  React__default.createElement("path", { d: "M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z" })));
16505
16585
  case 'ui-hotel':
16506
- return (React__default.createElement("svg", { className: ['icon', `icon--${name}`, className].filter((className) => !isEmpty$1(className)).join(' '), width: width, height: height, viewBox: "0 0 640 640", fill: fill ?? 'currentColor' },
16586
+ return (React__default.createElement("svg", { className: ['icon', `icon--${name}`, className].filter((className) => !isEmpty$1(className)).join(' '), width: width, height: height, viewBox: "0 0 512 512", fill: fill ?? 'currentColor' },
16507
16587
  React__default.createElement(HTMLComment, { text: "!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." }),
16508
16588
  title && React__default.createElement("title", null, title),
16509
16589
  React__default.createElement("path", { d: "M16 24C16 10.7 26.7 0 40 0L472 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-8 0 0 416 8 0c13.3 0 24 10.7 24 24s-10.7 24-24 24L40 512c-13.3 0-24-10.7-24-24s10.7-24 24-24l8 0 0-416-8 0C26.7 48 16 37.3 16 24zm208 88l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l0-32c0-8.8-7.2-16-16-16l-32 0c-8.8 0-16 7.2-16 16zM128 96c-8.8 0-16 7.2-16 16l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l0-32c0-8.8-7.2-16-16-16l-32 0zm96 112l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l0-32c0-8.8-7.2-16-16-16l-32 0c-8.8 0-16 7.2-16 16zM352 96c-8.8 0-16 7.2-16 16l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l0-32c0-8.8-7.2-16-16-16l-32 0zM112 208l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l0-32c0-8.8-7.2-16-16-16l-32 0c-8.8 0-16 7.2-16 16zm240-16c-8.8 0-16 7.2-16 16l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l0-32c0-8.8-7.2-16-16-16l-32 0zM288 384l43.8 0c9.9 0 17.5-9 14-18.2-13.8-36.1-48.8-61.8-89.7-61.8s-75.9 25.7-89.7 61.8c-3.5 9.2 4.1 18.2 14 18.2l43.8 0 0 80 64 0 0-80z", fill: "currentColor" })));
@@ -16532,6 +16612,16 @@ const Icon = ({ name, className, title, width, height, fill }) => {
16532
16612
  React__default.createElement(HTMLComment, { text: "!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." }),
16533
16613
  title && React__default.createElement("title", null, title),
16534
16614
  React__default.createElement("path", { d: "M135.2 117.4l-26.1 74.6 293.8 0-26.1-74.6C372.3 104.6 360.2 96 346.6 96L165.4 96c-13.6 0-25.7 8.6-30.2 21.4zM39.6 196.8L74.8 96.3C88.3 57.8 124.6 32 165.4 32l181.2 0c40.8 0 77.1 25.8 90.6 64.3l35.2 100.5c23.2 9.6 39.6 32.5 39.6 59.2l0 192c0 17.7-14.3 32-32 32l-32 0c-17.7 0-32-14.3-32-32l0-32-320 0 0 32c0 17.7-14.3 32-32 32l-32 0c-17.7 0-32-14.3-32-32L0 256c0-26.7 16.4-49.6 39.6-59.2zM128 304a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm288 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z", fill: "currentColor" })));
16615
+ case 'ui-bus':
16616
+ return (React__default.createElement("svg", { className: ['icon', `icon--${name}`, className].filter((className) => !isEmpty$1(className)).join(' '), width: width, height: height, viewBox: "0 0 512 512", fill: fill ?? 'currentColor' },
16617
+ title && React__default.createElement("title", null, title),
16618
+ React__default.createElement("path", { d: "M112 32h288a64 64 0 0 1 64 64v256a64 64 0 0 1-64 64h-288a64 64 0 0 1-64-64V96a64 64 0 0 1 64-64zM96 112v104h136V112H96zm184 0v104h136V112H280zM160 352a36 36 0 1 0-72 0 36 36 0 1 0 72 0zm264 0a36 36 0 1 0-72 0 36 36 0 1 0 72 0z", fill: "currentColor", fillRule: "evenodd" }),
16619
+ React__default.createElement("path", { d: "M112 416h64v48a24 24 0 0 1-24 24h-16a24 24 0 0 1-24-24v-48zm224 0h64v48a24 24 0 0 1-24 24h-16a24 24 0 0 1-24-24v-48z", fill: "currentColor" })));
16620
+ case 'ui-train':
16621
+ return (React__default.createElement("svg", { className: ['icon', `icon--${name}`, className].filter((className) => !isEmpty$1(className)).join(' '), width: width, height: height, viewBox: "0 0 512 512", fill: fill ?? 'currentColor' },
16622
+ title && React__default.createElement("title", null, title),
16623
+ React__default.createElement("path", { d: "M160 32h192a64 64 0 0 1 64 64v224a64 64 0 0 1-64 64h-192a64 64 0 0 1-64-64V96a64 64 0 0 1 64-64zm-24 80v104h240V112H136zm56 168a28 28 0 1 0-56 0 28 28 0 1 0 56 0zm192 0a28 28 0 1 0-56 0 28 28 0 1 0 56 0z", fill: "currentColor", fillRule: "evenodd" }),
16624
+ React__default.createElement("path", { d: "M168 416h72l-48 64h-72l48-64zm104 0h72l48 64h-72l-48-64z", fill: "currentColor" })));
16535
16625
  case 'ui-ship':
16536
16626
  return (React__default.createElement("svg", { className: ['icon', `icon--${name}`, className].filter((className) => !isEmpty$1(className)).join(' '), width: width, height: height, viewBox: "0 0 640 512", fill: fill ?? 'currentColor' },
16537
16627
  React__default.createElement(HTMLComment, { text: "!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." }),
@@ -27350,7 +27440,9 @@ const initialState$1 = {
27350
27440
  bookingNumber: undefined,
27351
27441
  trajectNodeAvailability: {},
27352
27442
  trajectFlightAvailability: {},
27353
- trajectEditLineGuid: null
27443
+ trajectDaySuggestions: {},
27444
+ trajectEditLineGuid: null,
27445
+ trajectActivitiesDayOrder: null
27354
27446
  };
27355
27447
  const searchResultsSlice = createSlice({
27356
27448
  name: 'searchResults',
@@ -27566,6 +27658,11 @@ const searchResultsSlice = createSlice({
27566
27658
  return;
27567
27659
  state.editablePackagingEntry.lines[index] = action.payload;
27568
27660
  },
27661
+ addEditableEntryLines(state, action) {
27662
+ if (!state.editablePackagingEntry)
27663
+ return;
27664
+ state.editablePackagingEntry.lines = [...(state.editablePackagingEntry.lines ?? []), ...action.payload];
27665
+ },
27569
27666
  removeEditableEntryLines(state, action) {
27570
27667
  if (!state.editablePackagingEntry)
27571
27668
  return;
@@ -27597,9 +27694,24 @@ const searchResultsSlice = createSlice({
27597
27694
  flight.selectedGuid = action.payload.guid;
27598
27695
  flight.status = 'resolved';
27599
27696
  },
27697
+ setTrajectDaySuggestionsLoading(state, action) {
27698
+ const dayOrder = action.payload;
27699
+ state.trajectDaySuggestions[dayOrder] = {
27700
+ dayOrder,
27701
+ status: 'loading',
27702
+ results: state.trajectDaySuggestions[dayOrder]?.results ?? []
27703
+ };
27704
+ },
27705
+ setTrajectDaySuggestions(state, action) {
27706
+ const { dayOrder, results } = action.payload;
27707
+ state.trajectDaySuggestions[dayOrder] = { dayOrder, status: 'resolved', results };
27708
+ },
27600
27709
  setTrajectEditLineGuid(state, action) {
27601
27710
  state.trajectEditLineGuid = action.payload;
27602
27711
  },
27712
+ setTrajectActivitiesDayOrder(state, action) {
27713
+ state.trajectActivitiesDayOrder = action.payload;
27714
+ },
27603
27715
  updateTrajectNodeResult(state, action) {
27604
27716
  const { lineGuid, result } = action.payload;
27605
27717
  const node = state.trajectNodeAvailability[lineGuid];
@@ -27612,11 +27724,13 @@ const searchResultsSlice = createSlice({
27612
27724
  resetTrajectAvailability(state) {
27613
27725
  state.trajectNodeAvailability = {};
27614
27726
  state.trajectFlightAvailability = {};
27727
+ state.trajectDaySuggestions = {};
27615
27728
  state.trajectEditLineGuid = null;
27729
+ state.trajectActivitiesDayOrder = null;
27616
27730
  }
27617
27731
  }
27618
27732
  });
27619
- const { setResults, setFilteredResults, setSelectedSearchResult, setPackagingAccoResults, setFilteredPackagingAccoResults, setFilteredPackagingFlightResults, setPackagingAccoSearchDetails, setSelectedPackagingAccoResult, setPackagingFlightResults, setSelectedPackagingFlight, setSelectedFlight, setSelectedFlightDetails, setBookingPackageDetails, selectFlight, setIsLoading, setFlightsLoading, setInitialFilters, setFilters, resetFilters, setInitialFlightFilters, setFlightFilters, resetFlightFilters, setSortType, setFlightSortType, setActiveTab, setCurrentPage, resetSearchState, setFlyInIsOpen, setEditablePackagingEntry, setTransactionId, setFlyInType, setPriceDetails, setItinerary, setSelectedOutwardKey, setSelectedReturnKey, resetFlightSelection, setExcursionSearchParams, setSelectedExcursionSearchResult, confirmExcursionForDay, removeConfirmedExcursionForDay, clearConfirmedExcursionsForDay, setBookPackagingEntry, setCurrentStep, setBookingNumber, setTrajectNodeLoading, setTrajectNodeAvailability, setTrajectNodeSelection, setTrajectFlightLoading, setTrajectFlightAvailability, setTrajectFlightSelection, setTrajectEditLineGuid, updateTrajectNodeResult, resetTrajectAvailability, updateEditableEntryLine, removeEditableEntryLines } = searchResultsSlice.actions;
27733
+ const { setResults, setFilteredResults, setSelectedSearchResult, setPackagingAccoResults, setFilteredPackagingAccoResults, setFilteredPackagingFlightResults, setPackagingAccoSearchDetails, setSelectedPackagingAccoResult, setPackagingFlightResults, setSelectedPackagingFlight, setSelectedFlight, setSelectedFlightDetails, setBookingPackageDetails, selectFlight, setIsLoading, setFlightsLoading, setInitialFilters, setFilters, resetFilters, setInitialFlightFilters, setFlightFilters, resetFlightFilters, setSortType, setFlightSortType, setActiveTab, setCurrentPage, resetSearchState, setFlyInIsOpen, setEditablePackagingEntry, setTransactionId, setFlyInType, setPriceDetails, setItinerary, setSelectedOutwardKey, setSelectedReturnKey, resetFlightSelection, setExcursionSearchParams, setSelectedExcursionSearchResult, confirmExcursionForDay, removeConfirmedExcursionForDay, clearConfirmedExcursionsForDay, setBookPackagingEntry, setCurrentStep, setBookingNumber, setTrajectNodeLoading, setTrajectNodeAvailability, setTrajectNodeSelection, setTrajectFlightLoading, setTrajectFlightAvailability, setTrajectFlightSelection, setTrajectEditLineGuid, setTrajectActivitiesDayOrder, setTrajectDaySuggestionsLoading, setTrajectDaySuggestions, addEditableEntryLines, updateTrajectNodeResult, resetTrajectAvailability, updateEditableEntryLine, removeEditableEntryLines } = searchResultsSlice.actions;
27620
27734
  var searchResultsReducer = searchResultsSlice.reducer;
27621
27735
 
27622
27736
  const ItemPicker = ({ items, selection, selectedSortByType, label, placeholder, classModifier, onPick, valueFormatter }) => {
@@ -27801,6 +27915,518 @@ const getDuration = (flight) => {
27801
27915
  const numberOfNights = (segment) => {
27802
27916
  return differenceInCalendarDays(new Date(segment.to), new Date(segment.from));
27803
27917
  };
27918
+ const CHARTER_SERVICE_TYPE = 10;
27919
+ const CRUISE_SERVICE_TYPE = 11;
27920
+ const FERRY_SERVICE_TYPE = 12;
27921
+ const TRANSFER_SERVICE_TYPE = 13;
27922
+ const BUS_SERVICE_TYPE = 14;
27923
+ const CAR_SERVICE_TYPE = 17;
27924
+ const CAMPER_SERVICE_TYPE = 18;
27925
+ const TRAIN_SERVICE_TYPE = 20;
27926
+ const RENTAL_SERVICE_TYPE = 22;
27927
+ const RESTAURANT_SERVICE_TYPE = 23;
27928
+ const EVENT_SERVICE_TYPE = 24;
27929
+ const TRAINING_SERVICE_TYPE = 25;
27930
+ /** Icon per service type, so every node on the itinerary reads at a glance. */
27931
+ const getServiceTypeIcon = (serviceType) => {
27932
+ switch (serviceType) {
27933
+ case ACCOMMODATION_SERVICE_TYPE:
27934
+ return 'ui-hotel';
27935
+ case EXCURSION_SERVICE_TYPE:
27936
+ return 'ui-excursion';
27937
+ case FLIGHT_SERVICE_TYPE:
27938
+ case CHARTER_SERVICE_TYPE:
27939
+ return 'ui-plane';
27940
+ case RESTAURANT_SERVICE_TYPE:
27941
+ return 'ui-utensils';
27942
+ case CRUISE_SERVICE_TYPE:
27943
+ case FERRY_SERVICE_TYPE:
27944
+ return 'ui-ship';
27945
+ case CAR_SERVICE_TYPE:
27946
+ case CAMPER_SERVICE_TYPE:
27947
+ case RENTAL_SERVICE_TYPE:
27948
+ return 'ui-car';
27949
+ case BUS_SERVICE_TYPE:
27950
+ return 'ui-bus';
27951
+ case TRAIN_SERVICE_TYPE:
27952
+ return 'ui-train';
27953
+ case TRANSFER_SERVICE_TYPE:
27954
+ return 'ui-transfer';
27955
+ case EVENT_SERVICE_TYPE:
27956
+ return 'ui-ticket';
27957
+ case TRAINING_SERVICE_TYPE:
27958
+ return 'ui-group';
27959
+ default:
27960
+ return 'ui-location';
27961
+ }
27962
+ };
27963
+ const getServiceTypeBadgeModifier = (serviceType) => {
27964
+ switch (serviceType) {
27965
+ case FLIGHT_SERVICE_TYPE:
27966
+ case CHARTER_SERVICE_TYPE:
27967
+ case CRUISE_SERVICE_TYPE:
27968
+ case FERRY_SERVICE_TYPE:
27969
+ return 'flight';
27970
+ case ACCOMMODATION_SERVICE_TYPE:
27971
+ return 'hotel';
27972
+ case EXCURSION_SERVICE_TYPE:
27973
+ case EVENT_SERVICE_TYPE:
27974
+ return 'excursion';
27975
+ case RESTAURANT_SERVICE_TYPE:
27976
+ return 'restaurant';
27977
+ default:
27978
+ return '';
27979
+ }
27980
+ };
27981
+ const POI_TRAJECT_NODE_TYPE = 2;
27982
+ const getTrajectNodeIcon = (node) => node.trajectNodeType === POI_TRAJECT_NODE_TYPE ? 'ui-location' : getServiceTypeIcon(node.serviceType);
27983
+ const getTrajectNodeBadgeModifier = (node) => node.trajectNodeType === POI_TRAJECT_NODE_TYPE ? 'poi' : getServiceTypeBadgeModifier(node.serviceType);
27984
+
27985
+ const REGULAR_TRAJECT_NODE_TYPE = 0;
27986
+ const CONNECTING_TRAJECT_NODE_TYPE = 1;
27987
+ const isSearchableTrajectNode = (node) => node.serviceType === ACCOMMODATION_SERVICE_TYPE || node.serviceType === EXCURSION_SERVICE_TYPE;
27988
+ const isTrajectFlightNode = (node) => node.serviceType === FLIGHT_SERVICE_TYPE;
27989
+ const getTrajectNodesWithLines = (trajectEntry) => {
27990
+ const linesByGuid = new Map((trajectEntry.entry.lines ?? []).map((line) => [line.guid, line]));
27991
+ return [...(trajectEntry.nodes ?? [])]
27992
+ .sort((a, b) => a.dayOrder - b.dayOrder || a.order - b.order)
27993
+ .map((node) => {
27994
+ const guids = node.lineGuids?.length ? node.lineGuids : [node.lineGuid];
27995
+ const lines = guids.map((guid) => linesByGuid.get(guid)).filter((x) => !!x);
27996
+ return { node, line: lines[0], lines };
27997
+ })
27998
+ .filter((x) => !!x.line);
27999
+ };
28000
+ const getCoordinates = (line, node, result) => {
28001
+ const sources = [
28002
+ ...(result ? [result] : []),
28003
+ ...(line ? [line] : []),
28004
+ ...(node?.alternatives ?? []).filter((x) => x.isPreferred),
28005
+ ...(node?.alternatives ?? [])
28006
+ ];
28007
+ const found = sources.find((x) => !!x.latitude && !!x.longitude);
28008
+ return found ? { latitude: found.latitude, longitude: found.longitude } : null;
28009
+ };
28010
+ const buildDestination = (line, node, result) => {
28011
+ const coordinates = getCoordinates(line, node, result);
28012
+ const place = (result?.locationId && { id: result.locationId, isLocation: true }) ||
28013
+ (result?.oordId && { id: result.oordId, isOord: true }) ||
28014
+ (result?.regionId && { id: result.regionId, isRegion: true }) ||
28015
+ (result?.countryId && { id: result.countryId, isCountry: true }) ||
28016
+ (line.location?.id && { id: line.location.id, isLocation: true }) ||
28017
+ (line.oord?.id && { id: line.oord.id, isOord: true }) ||
28018
+ (line.region?.id && { id: line.region.id, isRegion: true }) ||
28019
+ (line.country?.id && { id: line.country.id, isCountry: true }) ||
28020
+ null;
28021
+ return { id: 0, ...place, ...coordinates };
28022
+ };
28023
+ const buildTrajectNodeRequest = ({ node, line }, context, productCode) => ({
28024
+ transactionId: context.transactionId,
28025
+ officeId: context.officeId,
28026
+ agentId: context.agentId ?? null,
28027
+ catalogueId: context.catalogueId,
28028
+ searchConfigurationId: context.searchConfigurationId,
28029
+ portalId: context.portalId ?? null,
28030
+ vendorConfigurationId: node.externalVendorId ?? null,
28031
+ language: context.language,
28032
+ serviceType: node.serviceType,
28033
+ fromDate: toDateOnlyString(line.from),
28034
+ toDate: toDateOnlyString(line.to),
28035
+ destination: buildDestination(line, node),
28036
+ productCode,
28037
+ rooms: context.rooms,
28038
+ tagIds: []
28039
+ });
28040
+ /**
28041
+ * Entry lines for an excursion the traveller picked out of the suggestions.
28042
+ *
28043
+ * A traject node already has its lines and only needs stamping; a suggestion has none, so this
28044
+ * builds them — one per selected option, as the regular day-by-day excursion flow does, since an
28045
+ * excursion's options are ticket types (adult, child) rather than rooms. Where the search marks no
28046
+ * default, the first option of each room stands in.
28047
+ */
28048
+ const buildTrajectExcursionLines = (result) => {
28049
+ const options = (result.rooms ?? []).flatMap((room) => {
28050
+ const selected = (room.options ?? []).filter((x) => x.isSelected);
28051
+ return selected.length ? selected : (room.options ?? []).slice(0, 1);
28052
+ });
28053
+ if (!options.length)
28054
+ return [];
28055
+ const guids = options.map((option) => option.guid || crypto.randomUUID());
28056
+ return options.map((option, index) => ({
28057
+ guid: guids[index],
28058
+ moment: '',
28059
+ parentGuid: index === 0 ? null : guids[0],
28060
+ order: index,
28061
+ isChanged: true,
28062
+ from: result.fromDate,
28063
+ to: result.toDate,
28064
+ serviceType: EXCURSION_SERVICE_TYPE,
28065
+ productName: result.name,
28066
+ productCode: result.code,
28067
+ accommodationName: option.accommodationName,
28068
+ accommodationCode: option.accommodationCode,
28069
+ regimeName: option.regimeName,
28070
+ regimeCode: option.regimeCode,
28071
+ country: result.countryId ? { id: result.countryId, name: result.countryName, localizations: [] } : null,
28072
+ region: result.regionId ? { id: result.regionId, name: result.regionName, localizations: [] } : null,
28073
+ oord: result.oordId ? { id: result.oordId, name: result.oordName, localizations: [] } : null,
28074
+ location: result.locationId ? { id: result.locationId, name: result.locationName, localizations: [] } : null,
28075
+ longitude: result.longitude ?? null,
28076
+ latitude: result.latitude ?? null,
28077
+ pax: (option.paxIds ?? []).map((paxId, paxIndex) => ({ paxId, room: 0, order: paxIndex })),
28078
+ flightInformation: null
28079
+ }));
28080
+ };
28081
+ const buildDayActivityCards = (items, availability, suggestions) => {
28082
+ const cards = [];
28083
+ const seen = new Set();
28084
+ const push = (result, item) => {
28085
+ if (!result || seen.has(result.code))
28086
+ return;
28087
+ seen.add(result.code);
28088
+ cards.push({ result, item });
28089
+ };
28090
+ items.forEach((item) => {
28091
+ const results = availability[item.line.guid]?.results ?? [];
28092
+ const selected = results.find((x) => x.code === availability[item.line.guid]?.selectedCode);
28093
+ push(selected, item);
28094
+ results.filter((x) => !!findCandidateForResult(item.node, x)).forEach((result) => push(result, item));
28095
+ });
28096
+ suggestions.forEach((result) => push(result));
28097
+ // Whatever the nodes' own destination search found and the day's search did not — normally
28098
+ // nothing, as they are the same search, but a node can resolve where a day has no place to look.
28099
+ items.forEach((item) => (availability[item.line.guid]?.results ?? []).forEach((result) => push(result, item)));
28100
+ return cards;
28101
+ };
28102
+ const getNodeCandidates = (node) => {
28103
+ const configured = (node.alternatives ?? []).filter((x) => !!x.code && x.code.trim().length > 0);
28104
+ if (configured.length)
28105
+ return configured;
28106
+ const fallbackCode = node.code ?? node.preferredAccommodationCode;
28107
+ if (!fallbackCode || !fallbackCode.trim().length)
28108
+ return [];
28109
+ return [
28110
+ {
28111
+ code: fallbackCode,
28112
+ name: node.name,
28113
+ description: node.description,
28114
+ imageUrl: node.imageUrl,
28115
+ contentSource: node.contentSource,
28116
+ vendor: node.vendor,
28117
+ externalVendorId: node.externalVendorId,
28118
+ isPreferred: true
28119
+ }
28120
+ ];
28121
+ };
28122
+ const findCandidateForResult = (node, result) => getNodeCandidates(node).find((candidate) => matchesCode(result, candidate.code)) ?? null;
28123
+ const matchesCode = (result, code) => {
28124
+ if (result.code === code)
28125
+ return true;
28126
+ return (result.rooms ?? []).some((room) => (room.options ?? []).some((option) => option.accommodationCode === code));
28127
+ };
28128
+ const getPackagingRoomsFromEntry = (entry) => {
28129
+ const paxById = new Map((entry.pax ?? []).map((p) => [p.id, p]));
28130
+ const rooms = (entry.rooms ?? []).map((room) => ({
28131
+ travellers: (room.paxIds ?? []).map((paxId) => {
28132
+ const pax = paxById.get(paxId);
28133
+ return {
28134
+ id: paxId,
28135
+ age: pax?.age ?? null,
28136
+ dateOfBirth: pax?.dateOfBirth ?? null
28137
+ };
28138
+ })
28139
+ }));
28140
+ return rooms.filter((room) => room.travellers.length > 0);
28141
+ };
28142
+ const pickCheapest = (results) => [...results].sort((a, b) => a.price - b.price)[0] ?? null;
28143
+ const applyResultToLines = (lines, result) => lines.map((line, index) => applyResultToLine(line, result, index));
28144
+ const getOptionForRoom = (result, roomIndex) => {
28145
+ const room = (result.rooms ?? [])[roomIndex];
28146
+ if (room)
28147
+ return (room.options ?? []).find((x) => x.isSelected) ?? (room.options ?? [])[0];
28148
+ return (result.rooms ?? []).flatMap((x) => x.options ?? []).find((x) => x.isSelected) ?? (result.rooms ?? [])[0]?.options?.[0];
28149
+ };
28150
+ const applyResultToLine = (line, result, roomIndex = 0) => {
28151
+ const option = getOptionForRoom(result, roomIndex);
28152
+ return {
28153
+ ...line,
28154
+ productName: result.name ?? line.productName,
28155
+ productCode: result.code ?? line.productCode,
28156
+ accommodationCode: option?.accommodationCode ?? line.accommodationCode,
28157
+ accommodationName: option?.accommodationName ?? line.accommodationName,
28158
+ regimeCode: option?.regimeCode ?? line.regimeCode,
28159
+ regimeName: option?.regimeName ?? line.regimeName,
28160
+ latitude: result.latitude ?? line.latitude,
28161
+ longitude: result.longitude ?? line.longitude,
28162
+ isChanged: true
28163
+ };
28164
+ };
28165
+ const toDateOnlyUtcString = (value) => {
28166
+ const date = new Date(value);
28167
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())).toISOString();
28168
+ };
28169
+ const toTimeOnlyString = (value) => {
28170
+ const date = new Date(value);
28171
+ const hh = String(date.getUTCHours()).padStart(2, '0');
28172
+ const mm = String(date.getUTCMinutes()).padStart(2, '0');
28173
+ const ss = String(date.getUTCSeconds()).padStart(2, '0');
28174
+ return `${hh}:${mm}:${ss}`;
28175
+ };
28176
+ const mapFlightSegmentsToFlightLines = (segments) => segments.map((segment) => ({
28177
+ airlineCode: segment.marketingAirlineCode,
28178
+ airlineDescription: segment.marketingAirlineName,
28179
+ operatingAirlineCode: segment.operatingAirlineCode,
28180
+ operatingAirlineDescription: segment.operatingAirlineName,
28181
+ flightNumber: segment.flightNumber,
28182
+ operatingFlightNumber: segment.operatingFlightNumber ?? null,
28183
+ departureDate: toDateOnlyUtcString(segment.departureDateTime),
28184
+ departureTime: toTimeOnlyString(segment.departureDateTime),
28185
+ departureAirportCode: segment.departureAirportCode,
28186
+ departureAirportDescription: segment.departureAirportName,
28187
+ arrivalDate: toDateOnlyUtcString(segment.arrivalDateTime),
28188
+ arrivalTime: toTimeOnlyString(segment.arrivalDateTime),
28189
+ arrivalAirportCode: segment.arrivalAirportCode,
28190
+ arrivalAirportDescription: segment.arrivalAirportName,
28191
+ durationInTicks: segment.durationInTicks
28192
+ }));
28193
+ const buildTrajectFlightRequest = ({ node, line }, context, pax) => ({
28194
+ transactionId: context.transactionId,
28195
+ officeId: context.officeId,
28196
+ catalogueId: context.catalogueId,
28197
+ agentId: context.agentId ?? null,
28198
+ language: context.language,
28199
+ departureAirportCode: node.departureAirportCode ?? '',
28200
+ arrivalAirportCode: node.arrivalAirportCode ?? '',
28201
+ returnAirportCode: null,
28202
+ luggageIncluded: null,
28203
+ maxStops: null,
28204
+ travelClass: null,
28205
+ vendorConfigurationId: node.externalVendorId ?? null,
28206
+ pax,
28207
+ outward: { date: dateToDateStruct(new Date(line.from)) },
28208
+ return: null
28209
+ });
28210
+ const pickCheapestFlight = (flights) => [...flights].sort((a, b) => a.price - b.price)[0] ?? null;
28211
+ const applyFlightToLine = (line, flight) => {
28212
+ const segments = flight.outward?.segments ?? [];
28213
+ if (!segments.length)
28214
+ return line;
28215
+ const firstSegment = segments[0];
28216
+ const lastSegment = segments[segments.length - 1];
28217
+ return {
28218
+ ...line,
28219
+ from: new Date(firstSegment.departureDateTime).toISOString(),
28220
+ to: new Date(lastSegment.arrivalDateTime).toISOString(),
28221
+ productName: `${firstSegment.departureAirportName} - ${lastSegment.arrivalAirportName} (${firstSegment.marketingAirlineName})`,
28222
+ productCode: `${firstSegment.departureAirportCode} ${lastSegment.arrivalAirportCode}/${firstSegment.marketingAirlineCode}`,
28223
+ accommodationName: firstSegment.metaData?.farePriceClassName ?? line.accommodationName,
28224
+ accommodationCode: firstSegment.metaData?.fareCode ?? line.accommodationCode,
28225
+ flightInformation: {
28226
+ pnr: '',
28227
+ flightLines: mapFlightSegmentsToFlightLines(segments)
28228
+ },
28229
+ isChanged: true
28230
+ };
28231
+ };
28232
+ /**
28233
+ * Externally sourced products carry a vendor configuration; products held internally in Tide have
28234
+ * none. `vendorType` is not a reliable signal — the packaging service nulls it out when the search
28235
+ * configuration has ExposeProvider off — so the vendor ids are what we go on.
28236
+ */
28237
+ const isExternalResult = (result) => result.vendorId != null || result.vendorConfigurationId != null;
28238
+ const isExternalCandidate = (candidate) => candidate.externalVendorId != null || candidate.vendor != null;
28239
+
28240
+ const badgeClass = (kind, modifier) => {
28241
+ const base = `search__filter__itinerary__${kind}-badge`;
28242
+ const fallback = kind === 'segment' ? `${base}--secondary` : `${base}--default`;
28243
+ return `${base} ${modifier ? `${base}--${modifier}` : fallback}`;
28244
+ };
28245
+ const nightsOf = (node, line) => differenceInCalendarDays(new Date(line?.to ?? node.to), new Date(line?.from ?? node.from));
28246
+ const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
28247
+ const timeline = useMemo(() => {
28248
+ const linesByGuid = new Map((packagingEntry.lines ?? []).map((line) => [line.guid, line]));
28249
+ const nodes = [...(trajectEntry.nodes ?? [])]
28250
+ .sort((a, b) => a.dayOrder - b.dayOrder || a.order - b.order)
28251
+ .map((node) => {
28252
+ const guids = node.lineGuids?.length ? node.lineGuids : [node.lineGuid];
28253
+ const lines = guids.map((guid) => linesByGuid.get(guid)).filter((x) => !!x);
28254
+ return { node, lines };
28255
+ });
28256
+ const claimed = new Set(nodes.flatMap((item) => item.lines.map((line) => line.guid)));
28257
+ const extras = (packagingEntry.lines ?? []).filter((line) => !claimed.has(line.guid));
28258
+ if (!extras.length)
28259
+ return nodes;
28260
+ const dayOrderOf = (date) => trajectEntry.traject.days.find((day) => isSameDay(new Date(day.date), new Date(date)))?.order ??
28261
+ Math.max(differenceInCalendarDays(new Date(date), new Date(trajectEntry.traject.startDate)), 0);
28262
+ // One product bought once, however many option lines it took (an adult and a child ticket).
28263
+ const grouped = new Map();
28264
+ extras.forEach((line) => {
28265
+ const key = `${line.productCode}|${line.from}`;
28266
+ grouped.set(key, [...(grouped.get(key) ?? []), line]);
28267
+ });
28268
+ const byDay = new Map();
28269
+ nodes.forEach((item) => byDay.set(item.node.dayOrder, [...(byDay.get(item.node.dayOrder) ?? []), item]));
28270
+ [...grouped.values()].forEach((lines, index) => {
28271
+ const line = lines[0];
28272
+ const dayOrder = dayOrderOf(line.from);
28273
+ const item = {
28274
+ lines,
28275
+ node: {
28276
+ nodeId: -(index + 1),
28277
+ lineGuid: line.guid,
28278
+ lineGuids: lines.map((x) => x.guid),
28279
+ dayOrder,
28280
+ order: Number.MAX_SAFE_INTEGER,
28281
+ name: line.productName,
28282
+ serviceType: line.serviceType,
28283
+ trajectNodeType: REGULAR_TRAJECT_NODE_TYPE,
28284
+ requirementType: 0,
28285
+ contentSource: 0,
28286
+ alternatives: [],
28287
+ from: line.from,
28288
+ to: line.to
28289
+ }
28290
+ };
28291
+ const dayItems = [...(byDay.get(dayOrder) ?? [])];
28292
+ let at = dayItems.length;
28293
+ while (at > 0 && dayItems[at - 1].node.trajectNodeType === CONNECTING_TRAJECT_NODE_TYPE)
28294
+ at--;
28295
+ dayItems.splice(at, 0, item);
28296
+ byDay.set(dayOrder, dayItems);
28297
+ });
28298
+ return [...byDay.keys()].sort((a, b) => a - b).flatMap((dayOrder) => byDay.get(dayOrder));
28299
+ }, [trajectEntry, packagingEntry]);
28300
+ const stayByDay = useMemo(() => {
28301
+ const map = new Map();
28302
+ timeline
28303
+ .filter(({ node }) => node.trajectNodeType === REGULAR_TRAJECT_NODE_TYPE && node.serviceType === ACCOMMODATION_SERVICE_TYPE)
28304
+ .forEach(({ node, lines }) => {
28305
+ const line = lines[0];
28306
+ const nights = Math.max(nightsOf(node, line), 1);
28307
+ const name = line?.productName || node.preferredAccommodationName || node.name || '';
28308
+ for (let night = 0; night < nights; night++)
28309
+ map.set(node.dayOrder + night, { name, night, nights });
28310
+ });
28311
+ return map;
28312
+ }, [timeline]);
28313
+ const renderDate = (value) => (React__default.createElement("div", { className: "search__filter__itinerary__transport-date" },
28314
+ React__default.createElement("p", { className: "search__filter__itinerary__transport-date-date" },
28315
+ React__default.createElement("strong", null, format$2(new Date(value), 'd'))),
28316
+ React__default.createElement("p", null, format$2(new Date(value), 'MMM'))));
28317
+ const renderConnectingNode = ({ node }) => {
28318
+ const distance = node.distanceInKm ? `${Math.round(node.distanceInKm)} km` : '';
28319
+ return (React__default.createElement("div", { className: "search__filter__itinerary__transport", key: `connect-${node.nodeId}` },
28320
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline" },
28321
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline-line" })),
28322
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-item" },
28323
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-date" }),
28324
+ React__default.createElement("div", { className: badgeClass('transport', getTrajectNodeBadgeModifier(node)) },
28325
+ React__default.createElement(Icon, { name: getTrajectNodeIcon(node), height: 15 })),
28326
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-details" },
28327
+ React__default.createElement("h6", null, node.name || distance),
28328
+ !!node.name && !!distance && React__default.createElement("p", { className: "search__filter__itinerary__transport-details-time" }, distance)))));
28329
+ };
28330
+ const renderOvernight = (item, index) => {
28331
+ const { dayOrder } = item.node;
28332
+ const closesTheDay = timeline[index + 1]?.node.dayOrder !== dayOrder;
28333
+ const stay = stayByDay.get(dayOrder);
28334
+ if (!closesTheDay || !stay)
28335
+ return null;
28336
+ return (React__default.createElement("div", { className: "search__filter__itinerary__transport", key: `overnight-${item.node.nodeId}` },
28337
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline" },
28338
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline-line" })),
28339
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-item" },
28340
+ renderDate(item.node.from),
28341
+ React__default.createElement("div", { className: badgeClass('transport', getServiceTypeBadgeModifier(ACCOMMODATION_SERVICE_TYPE)) },
28342
+ React__default.createElement(Icon, { name: "ui-bed", height: 15 })),
28343
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-details" },
28344
+ React__default.createElement("h6", null, stay.name),
28345
+ React__default.createElement("p", { className: "search__filter__itinerary__transport-details-time" },
28346
+ stay.night + 1,
28347
+ " ",
28348
+ translations.SRP.OF,
28349
+ " ",
28350
+ stay.nights,
28351
+ " ",
28352
+ translations.SRP.NIGHTS)))));
28353
+ };
28354
+ const renderFlightNode = ({ node, lines }) => {
28355
+ const line = lines[0];
28356
+ return (React__default.createElement("div", { className: "search__filter__itinerary__transport", key: `flight-${node.nodeId}` },
28357
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline" },
28358
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline-line" })),
28359
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-item" },
28360
+ renderDate(line?.from ?? node.from),
28361
+ React__default.createElement("div", { className: badgeClass('transport', getServiceTypeBadgeModifier(FLIGHT_SERVICE_TYPE)) },
28362
+ React__default.createElement(Icon, { name: "ui-plane", height: 15 })),
28363
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-details" },
28364
+ React__default.createElement("h6", null, line?.productName || node.name),
28365
+ !!getDepartureTime(line) && (React__default.createElement("p", { className: "search__filter__itinerary__transport-details-plane" },
28366
+ React__default.createElement("span", null,
28367
+ React__default.createElement(Icon, { name: "ui-plane-depart", height: 14 }),
28368
+ " ",
28369
+ React__default.createElement("strong", null, getDepartureTime(line))),
28370
+ ' ',
28371
+ "-",
28372
+ ' ',
28373
+ React__default.createElement("span", null,
28374
+ React__default.createElement(Icon, { name: "ui-plane-arrive", height: 14 }),
28375
+ " ",
28376
+ React__default.createElement("strong", null, getArrivalTime(line))))),
28377
+ !!getDuration(line) && (React__default.createElement("p", { className: "search__filter__itinerary__transport-details-time" },
28378
+ React__default.createElement("span", null,
28379
+ React__default.createElement(Icon, { name: "ui-clock", height: 20 }),
28380
+ " ",
28381
+ getDuration(line))))))));
28382
+ };
28383
+ const renderServiceNode = ({ node, lines }) => {
28384
+ const line = lines[0];
28385
+ const isStay = node.serviceType === ACCOMMODATION_SERVICE_TYPE;
28386
+ const nights = isStay ? nightsOf(node, line) : 0;
28387
+ return (React__default.createElement("div", { className: "search__filter__itinerary__segments", key: `node-${node.nodeId}` },
28388
+ React__default.createElement("div", { className: "search__filter__itinerary__segments__wrapper" },
28389
+ React__default.createElement("div", { className: "search__filter__itinerary__segments-timeline" },
28390
+ React__default.createElement("div", { className: "search__filter__itinerary__segments-timeline-line" })),
28391
+ React__default.createElement("div", { className: "search__filter__itinerary__segment" },
28392
+ React__default.createElement("div", { className: "search__filter__itinerary__segment-item" },
28393
+ React__default.createElement("div", { className: `search__filter__itinerary__segment-date ${isStay && nights > 0 ? 'search__filter__itinerary__segment-nights' : ''}` }, isStay && nights > 0 ? (React__default.createElement(React__default.Fragment, null,
28394
+ React__default.createElement("p", { className: "search__filter__itinerary__segment-date-date" },
28395
+ React__default.createElement("strong", null, nights)),
28396
+ React__default.createElement(Icon, { name: "ui-moon", width: 16, height: 16 }))) : (React__default.createElement(React__default.Fragment, null,
28397
+ React__default.createElement("p", { className: "search__filter__itinerary__segment-date-date" },
28398
+ React__default.createElement("strong", null, format$2(new Date(line?.from ?? node.from), 'd'))),
28399
+ React__default.createElement("p", null, format$2(new Date(line?.from ?? node.from), 'MMM'))))),
28400
+ React__default.createElement("div", { className: badgeClass('segment', getTrajectNodeBadgeModifier(node)) },
28401
+ React__default.createElement(Icon, { name: getTrajectNodeIcon(node), width: 15, height: 15 })),
28402
+ React__default.createElement("div", { className: "search__filter__itinerary__segment-details" },
28403
+ React__default.createElement("h6", null, line?.productName || node.preferredAccommodationName || node.name),
28404
+ isStay &&
28405
+ lines.map((roomLine, index) => (React__default.createElement(React__default.Fragment, { key: roomLine.guid },
28406
+ lines.length > 1 && (React__default.createElement("strong", null,
28407
+ translations.SHARED.ROOM,
28408
+ "\u00A0",
28409
+ index + 1)),
28410
+ roomLine.accommodationName && (React__default.createElement("div", { className: "search__filter__itinerary__segment-details__room" },
28411
+ React__default.createElement(Icon, { name: "ui-bed", width: 12, height: 12 }),
28412
+ roomLine.accommodationName)),
28413
+ roomLine.regimeName && (React__default.createElement("div", { className: "search__filter__itinerary__segment-details__room" },
28414
+ React__default.createElement(Icon, { name: "ui-utensils", width: 12, height: 12 }),
28415
+ roomLine.regimeName))))),
28416
+ !isStay && React__default.createElement("p", { className: "search__filter__itinerary__segment-details-text" }, format$2(new Date(line?.from ?? node.from), 'EEE. d MMM yyyy'))))))));
28417
+ };
28418
+ return (React__default.createElement(React__default.Fragment, null, timeline.map((item, index) => {
28419
+ if (item.node.trajectNodeType === CONNECTING_TRAJECT_NODE_TYPE) {
28420
+ return (React__default.createElement(React__default.Fragment, { key: `connect-${item.node.nodeId}` },
28421
+ renderConnectingNode(item),
28422
+ renderOvernight(item, index)));
28423
+ }
28424
+ if (item.node.trajectNodeType === REGULAR_TRAJECT_NODE_TYPE && item.node.serviceType === FLIGHT_SERVICE_TYPE)
28425
+ return renderFlightNode(item);
28426
+ return renderServiceNode(item);
28427
+ })));
28428
+ };
28429
+
27804
28430
  const getSegmentIcon = (segment) => {
27805
28431
  switch (segment.serviceType) {
27806
28432
  case 3:
@@ -27924,116 +28550,119 @@ const Itinerary = ({ isOpen, handleSetIsOpen, isLoading, onEditAccommodation })
27924
28550
  format$2(new Date(firstEntryLine.from), 'EEE. d MMM yyyy'),
27925
28551
  " - ",
27926
28552
  React__default.createElement("strong", null, translations.SRP.START))))),
27927
- outboundFlight && (React__default.createElement("div", { className: "search__filter__itinerary__transport" },
27928
- React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline" },
27929
- React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline-line" })),
27930
- React__default.createElement("div", { className: "search__filter__itinerary__transport-item" },
27931
- React__default.createElement("div", { className: "search__filter__itinerary__transport-date" },
27932
- React__default.createElement("p", { className: "search__filter__itinerary__transport-date-date" },
27933
- React__default.createElement("strong", null, format$2(new Date(outboundFlight.from), 'd'))),
27934
- React__default.createElement("p", null, format$2(new Date(outboundFlight.from), 'MMM'))),
27935
- React__default.createElement("div", { className: "search__filter__itinerary__transport-badge" },
27936
- React__default.createElement(Icon, { name: "ui-plane", height: 15 })),
27937
- React__default.createElement("div", { className: "search__filter__itinerary__transport-details" },
27938
- React__default.createElement("h6", null, outboundFlight.productName),
27939
- React__default.createElement("p", { className: "search__filter__itinerary__transport-details-plane" },
27940
- React__default.createElement("span", null,
27941
- React__default.createElement(Icon, { name: "ui-plane-depart", height: 14 }),
27942
- " ",
27943
- React__default.createElement("strong", null, getDepartureTime(outboundFlight))),
27944
- ' ',
27945
- "-",
27946
- ' ',
27947
- React__default.createElement("span", null,
27948
- React__default.createElement(Icon, { name: "ui-plane-arrive", height: 14 }),
27949
- " ",
27950
- React__default.createElement("strong", null, getArrivalTime(outboundFlight)))),
27951
- React__default.createElement("p", { className: "search__filter__itinerary__transport-details-time" },
27952
- React__default.createElement("span", null,
27953
- React__default.createElement(Icon, { name: "ui-clock", height: 20 }),
27954
- " ",
27955
- getDuration(outboundFlight))))))),
27956
- !isEmpty$1(groupedOtherSegments) &&
27957
- groupedOtherSegments.map((group) => {
27958
- const firstSegment = first(group.segments);
27959
- if (!firstSegment)
27960
- return null;
27961
- return (React__default.createElement("div", { className: "search__filter__itinerary__segments" },
27962
- React__default.createElement("div", { className: "search__filter__itinerary__segments__wrapper", key: group.key },
27963
- React__default.createElement("div", { className: "search__filter__itinerary__segments-timeline" },
27964
- React__default.createElement("div", { className: "search__filter__itinerary__segments-timeline-line" })),
27965
- React__default.createElement("div", { className: "search__filter__itinerary__segment" },
27966
- React__default.createElement("div", { className: "search__filter__itinerary__segment-item search__filter__itinerary__segment-item--start" },
27967
- React__default.createElement("div", { className: "search__filter__itinerary__transport-date" },
27968
- React__default.createElement("p", { className: "search__filter__itinerary__transport-date-date" },
27969
- React__default.createElement("strong", null, format$2(new Date(firstSegment.from), 'd'))),
27970
- React__default.createElement("p", null, format$2(new Date(firstSegment.from), 'MMM'))),
27971
- React__default.createElement("div", { className: "search__filter__itinerary__segment-badge" },
27972
- React__default.createElement(Icon, { name: "ui-location", width: 15, height: 15 })),
27973
- React__default.createElement("div", { className: "search__filter__itinerary__segment-details" },
27974
- React__default.createElement("h6", null,
27975
- firstSegment.location?.name || firstSegment.oord?.name || firstSegment.region?.name,
27976
- (firstSegment.location?.name || firstSegment.oord?.name || firstSegment.region?.name) && firstSegment.country?.name ? ', ' : '',
27977
- firstSegment.country?.name),
27978
- React__default.createElement("p", { className: "search__filter__itinerary__segment-details-text" },
27979
- format$2(new Date(firstSegment.from), 'EEE. d MMM yyyy'),
27980
- "> ",
27981
- format$2(new Date(firstSegment.to), 'EEE. d MMM yyyy'))))),
27982
- React__default.createElement("div", { className: "search__filter__itinerary__segment" },
27983
- React__default.createElement("div", { className: `search__filter__itinerary__segment-item ${canEdit(firstSegment) ? 'search__filter__itinerary__segment-item--editable' : ''}`, onClick: () => {
27984
- if (canEdit(firstSegment) && onEditAccommodation) {
27985
- onEditAccommodation(group.segments);
27986
- }
27987
- } },
27988
- React__default.createElement("div", { className: "search__filter__itinerary__segment-date search__filter__itinerary__segment-nights" }, firstSegment.serviceType === ACCOMMODATION_SERVICE_TYPE && (React__default.createElement(React__default.Fragment, null,
27989
- React__default.createElement("p", { className: "search__filter__itinerary__segment-date-date" },
27990
- React__default.createElement("strong", null, numberOfNights(firstSegment))),
27991
- React__default.createElement(Icon, { name: "ui-moon", width: 16, height: 16 })))),
27992
- getSegmentIcon(firstSegment),
27993
- React__default.createElement("div", { className: "search__filter__itinerary__segment-details" },
27994
- React__default.createElement("h6", null, getSegmentTitle(firstSegment)),
27995
- firstSegment.serviceType === ACCOMMODATION_SERVICE_TYPE &&
27996
- group.segments.map((segment, index) => (React__default.createElement(React__default.Fragment, { key: segment.guid },
27997
- React__default.createElement("strong", null,
27998
- translations.SHARED.ROOM,
27999
- "\u00A0",
28000
- index + 1),
28001
- segment.productName && segment.accommodationName && (React__default.createElement("div", { className: "search__filter__itinerary__segment-details__room" },
28002
- React__default.createElement(Icon, { name: "ui-bed", width: 12, height: 12 }),
28003
- segment.accommodationName)),
28004
- segment.regimeName && (React__default.createElement("div", { className: "search__filter__itinerary__segment-details__room" },
28005
- React__default.createElement(Icon, { name: "ui-utensils", width: 12, height: 12 }),
28006
- segment.regimeName)))))))))));
28007
- }),
28008
- returnFlight && returnFlight !== outboundFlight && (React__default.createElement("div", { className: "search__filter__itinerary__transport" },
28009
- React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline" },
28010
- React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline-line" })),
28011
- React__default.createElement("div", { className: "search__filter__itinerary__transport-item" },
28012
- React__default.createElement("div", { className: "search__filter__itinerary__transport-date" },
28013
- React__default.createElement("p", { className: "search__filter__itinerary__transport-date-date" },
28014
- React__default.createElement("strong", null, format$2(new Date(returnFlight.from), 'd'))),
28015
- React__default.createElement("p", null, format$2(new Date(returnFlight.from), 'MMM'))),
28016
- React__default.createElement("div", { className: "search__filter__itinerary__transport-badge" },
28017
- React__default.createElement(Icon, { name: "ui-plane", height: 15 })),
28018
- React__default.createElement("div", { className: "search__filter__itinerary__transport-details" },
28019
- React__default.createElement("h6", null, returnFlight.productName),
28020
- React__default.createElement("p", { className: "search__filter__itinerary__transport-details-plane" },
28021
- React__default.createElement("span", null,
28022
- React__default.createElement(Icon, { name: "ui-plane-depart", height: 14 }),
28023
- " ",
28024
- React__default.createElement("strong", null, getDepartureTime(returnFlight))),
28025
- ' ',
28026
- "-",
28027
- ' ',
28028
- React__default.createElement("span", null,
28029
- React__default.createElement(Icon, { name: "ui-plane-arrive", height: 14 }),
28030
- " ",
28031
- React__default.createElement("strong", null, getArrivalTime(returnFlight)))),
28032
- React__default.createElement("p", { className: "search__filter__itinerary__transport-details-time" },
28033
- React__default.createElement("span", null,
28034
- React__default.createElement(Icon, { name: "ui-clock", height: 20 }),
28035
- " ",
28036
- getDuration(returnFlight))))))),
28553
+ context?.trajectEntry ? (React__default.createElement(TrajectItinerary, { trajectEntry: context.trajectEntry, packagingEntry: packagingEntry, translations: translations })) : (React__default.createElement(React__default.Fragment, null,
28554
+ outboundFlight && (React__default.createElement("div", { className: "search__filter__itinerary__transport" },
28555
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline" },
28556
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline-line" })),
28557
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-item" },
28558
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-date" },
28559
+ React__default.createElement("p", { className: "search__filter__itinerary__transport-date-date" },
28560
+ React__default.createElement("strong", null, format$2(new Date(outboundFlight.from), 'd'))),
28561
+ React__default.createElement("p", null, format$2(new Date(outboundFlight.from), 'MMM'))),
28562
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-badge" },
28563
+ React__default.createElement(Icon, { name: "ui-plane", height: 15 })),
28564
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-details" },
28565
+ React__default.createElement("h6", null, outboundFlight.productName),
28566
+ React__default.createElement("p", { className: "search__filter__itinerary__transport-details-plane" },
28567
+ React__default.createElement("span", null,
28568
+ React__default.createElement(Icon, { name: "ui-plane-depart", height: 14 }),
28569
+ " ",
28570
+ React__default.createElement("strong", null, getDepartureTime(outboundFlight))),
28571
+ ' ',
28572
+ "-",
28573
+ ' ',
28574
+ React__default.createElement("span", null,
28575
+ React__default.createElement(Icon, { name: "ui-plane-arrive", height: 14 }),
28576
+ " ",
28577
+ React__default.createElement("strong", null, getArrivalTime(outboundFlight)))),
28578
+ React__default.createElement("p", { className: "search__filter__itinerary__transport-details-time" },
28579
+ React__default.createElement("span", null,
28580
+ React__default.createElement(Icon, { name: "ui-clock", height: 20 }),
28581
+ " ",
28582
+ getDuration(outboundFlight))))))),
28583
+ !isEmpty$1(groupedOtherSegments) &&
28584
+ groupedOtherSegments.map((group) => {
28585
+ const firstSegment = first(group.segments);
28586
+ if (!firstSegment)
28587
+ return null;
28588
+ return (React__default.createElement("div", { className: "search__filter__itinerary__segments" },
28589
+ React__default.createElement("div", { className: "search__filter__itinerary__segments__wrapper", key: group.key },
28590
+ React__default.createElement("div", { className: "search__filter__itinerary__segments-timeline" },
28591
+ React__default.createElement("div", { className: "search__filter__itinerary__segments-timeline-line" })),
28592
+ React__default.createElement("div", { className: "search__filter__itinerary__segment" },
28593
+ React__default.createElement("div", { className: "search__filter__itinerary__segment-item search__filter__itinerary__segment-item--start" },
28594
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-date" },
28595
+ React__default.createElement("p", { className: "search__filter__itinerary__transport-date-date" },
28596
+ React__default.createElement("strong", null, format$2(new Date(firstSegment.from), 'd'))),
28597
+ React__default.createElement("p", null, format$2(new Date(firstSegment.from), 'MMM'))),
28598
+ React__default.createElement("div", { className: "search__filter__itinerary__segment-badge" },
28599
+ React__default.createElement(Icon, { name: "ui-location", width: 15, height: 15 })),
28600
+ React__default.createElement("div", { className: "search__filter__itinerary__segment-details" },
28601
+ React__default.createElement("h6", null,
28602
+ firstSegment.location?.name || firstSegment.oord?.name || firstSegment.region?.name,
28603
+ (firstSegment.location?.name || firstSegment.oord?.name || firstSegment.region?.name) && firstSegment.country?.name
28604
+ ? ', '
28605
+ : '',
28606
+ firstSegment.country?.name),
28607
+ React__default.createElement("p", { className: "search__filter__itinerary__segment-details-text" },
28608
+ format$2(new Date(firstSegment.from), 'EEE. d MMM yyyy'),
28609
+ "> ",
28610
+ format$2(new Date(firstSegment.to), 'EEE. d MMM yyyy'))))),
28611
+ React__default.createElement("div", { className: "search__filter__itinerary__segment" },
28612
+ React__default.createElement("div", { className: `search__filter__itinerary__segment-item ${canEdit(firstSegment) ? 'search__filter__itinerary__segment-item--editable' : ''}`, onClick: () => {
28613
+ if (canEdit(firstSegment) && onEditAccommodation) {
28614
+ onEditAccommodation(group.segments);
28615
+ }
28616
+ } },
28617
+ React__default.createElement("div", { className: "search__filter__itinerary__segment-date search__filter__itinerary__segment-nights" }, firstSegment.serviceType === ACCOMMODATION_SERVICE_TYPE && (React__default.createElement(React__default.Fragment, null,
28618
+ React__default.createElement("p", { className: "search__filter__itinerary__segment-date-date" },
28619
+ React__default.createElement("strong", null, numberOfNights(firstSegment))),
28620
+ React__default.createElement(Icon, { name: "ui-moon", width: 16, height: 16 })))),
28621
+ getSegmentIcon(firstSegment),
28622
+ React__default.createElement("div", { className: "search__filter__itinerary__segment-details" },
28623
+ React__default.createElement("h6", null, getSegmentTitle(firstSegment)),
28624
+ firstSegment.serviceType === ACCOMMODATION_SERVICE_TYPE &&
28625
+ group.segments.map((segment, index) => (React__default.createElement(React__default.Fragment, { key: segment.guid },
28626
+ React__default.createElement("strong", null,
28627
+ translations.SHARED.ROOM,
28628
+ "\u00A0",
28629
+ index + 1),
28630
+ segment.productName && segment.accommodationName && (React__default.createElement("div", { className: "search__filter__itinerary__segment-details__room" },
28631
+ React__default.createElement(Icon, { name: "ui-bed", width: 12, height: 12 }),
28632
+ segment.accommodationName)),
28633
+ segment.regimeName && (React__default.createElement("div", { className: "search__filter__itinerary__segment-details__room" },
28634
+ React__default.createElement(Icon, { name: "ui-utensils", width: 12, height: 12 }),
28635
+ segment.regimeName)))))))))));
28636
+ }),
28637
+ returnFlight && returnFlight !== outboundFlight && (React__default.createElement("div", { className: "search__filter__itinerary__transport" },
28638
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline" },
28639
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline-line" })),
28640
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-item" },
28641
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-date" },
28642
+ React__default.createElement("p", { className: "search__filter__itinerary__transport-date-date" },
28643
+ React__default.createElement("strong", null, format$2(new Date(returnFlight.from), 'd'))),
28644
+ React__default.createElement("p", null, format$2(new Date(returnFlight.from), 'MMM'))),
28645
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-badge" },
28646
+ React__default.createElement(Icon, { name: "ui-plane", height: 15 })),
28647
+ React__default.createElement("div", { className: "search__filter__itinerary__transport-details" },
28648
+ React__default.createElement("h6", null, returnFlight.productName),
28649
+ React__default.createElement("p", { className: "search__filter__itinerary__transport-details-plane" },
28650
+ React__default.createElement("span", null,
28651
+ React__default.createElement(Icon, { name: "ui-plane-depart", height: 14 }),
28652
+ " ",
28653
+ React__default.createElement("strong", null, getDepartureTime(returnFlight))),
28654
+ ' ',
28655
+ "-",
28656
+ ' ',
28657
+ React__default.createElement("span", null,
28658
+ React__default.createElement(Icon, { name: "ui-plane-arrive", height: 14 }),
28659
+ " ",
28660
+ React__default.createElement("strong", null, getArrivalTime(returnFlight)))),
28661
+ React__default.createElement("p", { className: "search__filter__itinerary__transport-details-time" },
28662
+ React__default.createElement("span", null,
28663
+ React__default.createElement(Icon, { name: "ui-clock", height: 20 }),
28664
+ " ",
28665
+ getDuration(returnFlight))))))))),
28037
28666
  lastEntryLine && (React__default.createElement("div", { className: "search__filter__itinerary__country" },
28038
28667
  React__default.createElement("div", { className: "search__filter__itinerary__country-icon" },
28039
28668
  React__default.createElement(Icon, { name: "ui-flag", width: 17.5, height: 20 })),
@@ -30596,181 +31225,6 @@ const ExcursionDetails = () => {
30596
31225
  React__default.createElement("button", { type: "button", className: "cta cta--primary", onClick: handleConfirm }, translations?.QSM.CONFIRM))));
30597
31226
  };
30598
31227
 
30599
- const REGULAR_TRAJECT_NODE_TYPE = 0;
30600
- const isSearchableTrajectNode = (node) => node.serviceType === ACCOMMODATION_SERVICE_TYPE || node.serviceType === EXCURSION_SERVICE_TYPE;
30601
- const isTrajectFlightNode = (node) => node.serviceType === FLIGHT_SERVICE_TYPE;
30602
- const getTrajectNodesWithLines = (trajectEntry) => {
30603
- const linesByGuid = new Map((trajectEntry.entry.lines ?? []).map((line) => [line.guid, line]));
30604
- return [...(trajectEntry.nodes ?? [])]
30605
- .sort((a, b) => a.dayOrder - b.dayOrder || a.order - b.order)
30606
- .map((node) => {
30607
- const guids = node.lineGuids?.length ? node.lineGuids : [node.lineGuid];
30608
- const lines = guids.map((guid) => linesByGuid.get(guid)).filter((x) => !!x);
30609
- return { node, line: lines[0], lines };
30610
- })
30611
- .filter((x) => !!x.line);
30612
- };
30613
- const buildDestination = (line) => {
30614
- if (line.location?.id)
30615
- return { id: line.location.id, isLocation: true };
30616
- if (line.oord?.id)
30617
- return { id: line.oord.id, isOord: true };
30618
- if (line.region?.id)
30619
- return { id: line.region.id, isRegion: true };
30620
- if (line.country?.id)
30621
- return { id: line.country.id, isCountry: true };
30622
- if (line.latitude && line.longitude)
30623
- return { latitude: line.latitude, longitude: line.longitude };
30624
- return { id: 0 };
30625
- };
30626
- const buildTrajectNodeRequest = ({ node, line }, context, productCode) => ({
30627
- transactionId: context.transactionId,
30628
- officeId: context.officeId,
30629
- agentId: context.agentId ?? null,
30630
- catalogueId: context.catalogueId,
30631
- searchConfigurationId: context.searchConfigurationId,
30632
- portalId: context.portalId ?? null,
30633
- vendorConfigurationId: node.externalVendorId ?? null,
30634
- language: context.language,
30635
- serviceType: node.serviceType,
30636
- fromDate: toDateOnlyString(line.from),
30637
- toDate: toDateOnlyString(line.to),
30638
- destination: buildDestination(line),
30639
- productCode,
30640
- rooms: context.rooms,
30641
- tagIds: []
30642
- });
30643
- const getNodeCandidates = (node) => {
30644
- const configured = (node.alternatives ?? []).filter((x) => !!x.code && x.code.trim().length > 0);
30645
- if (configured.length)
30646
- return configured;
30647
- const fallbackCode = node.code ?? node.preferredAccommodationCode;
30648
- if (!fallbackCode || !fallbackCode.trim().length)
30649
- return [];
30650
- return [
30651
- {
30652
- code: fallbackCode,
30653
- name: node.name,
30654
- description: node.description,
30655
- imageUrl: node.imageUrl,
30656
- contentSource: node.contentSource,
30657
- vendor: node.vendor,
30658
- externalVendorId: node.externalVendorId,
30659
- isPreferred: true
30660
- }
30661
- ];
30662
- };
30663
- const findCandidateForResult = (node, result) => getNodeCandidates(node).find((candidate) => matchesCode(result, candidate.code)) ?? null;
30664
- const matchesCode = (result, code) => {
30665
- if (result.code === code)
30666
- return true;
30667
- return (result.rooms ?? []).some((room) => (room.options ?? []).some((option) => option.accommodationCode === code));
30668
- };
30669
- const getPackagingRoomsFromEntry = (entry) => {
30670
- const paxById = new Map((entry.pax ?? []).map((p) => [p.id, p]));
30671
- const rooms = (entry.rooms ?? []).map((room) => ({
30672
- travellers: (room.paxIds ?? []).map((paxId) => {
30673
- const pax = paxById.get(paxId);
30674
- return {
30675
- id: paxId,
30676
- age: pax?.age ?? null,
30677
- dateOfBirth: pax?.dateOfBirth ?? null
30678
- };
30679
- })
30680
- }));
30681
- return rooms.filter((room) => room.travellers.length > 0);
30682
- };
30683
- const pickCheapest = (results) => [...results].sort((a, b) => a.price - b.price)[0] ?? null;
30684
- const applyResultToLines = (lines, result) => lines.map((line, index) => applyResultToLine(line, result, index));
30685
- const getOptionForRoom = (result, roomIndex) => {
30686
- const room = (result.rooms ?? [])[roomIndex];
30687
- if (room)
30688
- return (room.options ?? []).find((x) => x.isSelected) ?? (room.options ?? [])[0];
30689
- return (result.rooms ?? []).flatMap((x) => x.options ?? []).find((x) => x.isSelected) ?? (result.rooms ?? [])[0]?.options?.[0];
30690
- };
30691
- const applyResultToLine = (line, result, roomIndex = 0) => {
30692
- const option = getOptionForRoom(result, roomIndex);
30693
- return {
30694
- ...line,
30695
- productName: result.name ?? line.productName,
30696
- productCode: result.code ?? line.productCode,
30697
- accommodationCode: option?.accommodationCode ?? line.accommodationCode,
30698
- accommodationName: option?.accommodationName ?? line.accommodationName,
30699
- regimeCode: option?.regimeCode ?? line.regimeCode,
30700
- regimeName: option?.regimeName ?? line.regimeName,
30701
- latitude: result.latitude ?? line.latitude,
30702
- longitude: result.longitude ?? line.longitude,
30703
- isChanged: true
30704
- };
30705
- };
30706
- const toDateOnlyUtcString = (value) => {
30707
- const date = new Date(value);
30708
- return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())).toISOString();
30709
- };
30710
- const toTimeOnlyString = (value) => {
30711
- const date = new Date(value);
30712
- const hh = String(date.getUTCHours()).padStart(2, '0');
30713
- const mm = String(date.getUTCMinutes()).padStart(2, '0');
30714
- const ss = String(date.getUTCSeconds()).padStart(2, '0');
30715
- return `${hh}:${mm}:${ss}`;
30716
- };
30717
- const mapFlightSegmentsToFlightLines = (segments) => segments.map((segment) => ({
30718
- airlineCode: segment.marketingAirlineCode,
30719
- airlineDescription: segment.marketingAirlineName,
30720
- operatingAirlineCode: segment.operatingAirlineCode,
30721
- operatingAirlineDescription: segment.operatingAirlineName,
30722
- flightNumber: segment.flightNumber,
30723
- operatingFlightNumber: segment.operatingFlightNumber ?? null,
30724
- departureDate: toDateOnlyUtcString(segment.departureDateTime),
30725
- departureTime: toTimeOnlyString(segment.departureDateTime),
30726
- departureAirportCode: segment.departureAirportCode,
30727
- departureAirportDescription: segment.departureAirportName,
30728
- arrivalDate: toDateOnlyUtcString(segment.arrivalDateTime),
30729
- arrivalTime: toTimeOnlyString(segment.arrivalDateTime),
30730
- arrivalAirportCode: segment.arrivalAirportCode,
30731
- arrivalAirportDescription: segment.arrivalAirportName,
30732
- durationInTicks: segment.durationInTicks
30733
- }));
30734
- const buildTrajectFlightRequest = ({ node, line }, context, pax) => ({
30735
- transactionId: context.transactionId,
30736
- officeId: context.officeId,
30737
- catalogueId: context.catalogueId,
30738
- agentId: context.agentId ?? null,
30739
- language: context.language,
30740
- departureAirportCode: node.departureAirportCode ?? '',
30741
- arrivalAirportCode: node.arrivalAirportCode ?? '',
30742
- returnAirportCode: null,
30743
- luggageIncluded: null,
30744
- maxStops: null,
30745
- travelClass: null,
30746
- vendorConfigurationId: node.externalVendorId ?? null,
30747
- pax,
30748
- outward: { date: dateToDateStruct(new Date(line.from)) },
30749
- return: null
30750
- });
30751
- const pickCheapestFlight = (flights) => [...flights].sort((a, b) => a.price - b.price)[0] ?? null;
30752
- const applyFlightToLine = (line, flight) => {
30753
- const segments = flight.outward?.segments ?? [];
30754
- if (!segments.length)
30755
- return line;
30756
- const firstSegment = segments[0];
30757
- const lastSegment = segments[segments.length - 1];
30758
- return {
30759
- ...line,
30760
- from: new Date(firstSegment.departureDateTime).toISOString(),
30761
- to: new Date(lastSegment.arrivalDateTime).toISOString(),
30762
- productName: `${firstSegment.departureAirportName} - ${lastSegment.arrivalAirportName} (${firstSegment.marketingAirlineName})`,
30763
- productCode: `${firstSegment.departureAirportCode} ${lastSegment.arrivalAirportCode}/${firstSegment.marketingAirlineCode}`,
30764
- accommodationName: firstSegment.metaData?.farePriceClassName ?? line.accommodationName,
30765
- accommodationCode: firstSegment.metaData?.fareCode ?? line.accommodationCode,
30766
- flightInformation: {
30767
- pnr: '',
30768
- flightLines: mapFlightSegmentsToFlightLines(segments)
30769
- },
30770
- isChanged: true
30771
- };
30772
- };
30773
-
30774
31228
  const getLocation = (result) => {
30775
31229
  const place = result.locationName || result.regionName || result.oordName;
30776
31230
  if (!place)
@@ -30785,13 +31239,12 @@ const toPlainText = (value) => {
30785
31239
  .replace(/\s+/g, ' ')
30786
31240
  .trim();
30787
31241
  };
30788
- const TrajectNodeCard = ({ item, result, isSelected, languageCode, translations, onSelect, onEditOptions, showNights }) => {
30789
- const { node } = item;
31242
+ const TrajectNodeCard = ({ node, result, isSelected, languageCode, translations, onSelect, onEditOptions, showNights, selectLabel, selectedLabel }) => {
30790
31243
  const selectedPerRoom = (result.rooms ?? []).map((room) => (room.options ?? []).find((x) => x.isSelected) ?? (room.options ?? [])[0]);
30791
31244
  const isMultiRoom = selectedPerRoom.length > 1;
30792
31245
  const price = formatPrice$3(result.price, result.currencyCode, languageCode);
30793
31246
  const nights = calculateNights(new Date(result.fromDate), new Date(result.toDate));
30794
- const candidate = findCandidateForResult(node, result);
31247
+ const candidate = node ? findCandidateForResult(node, result) : null;
30795
31248
  const image = candidate?.imageUrl ?? null;
30796
31249
  const description = toPlainText(candidate?.description);
30797
31250
  const title = candidate?.name ?? result.name;
@@ -30800,7 +31253,7 @@ const TrajectNodeCard = ({ item, result, isSelected, languageCode, translations,
30800
31253
  React__default.createElement("span", { className: "search__result-card__price" }, price)));
30801
31254
  const canEditOptions = isSelected && !!onEditOptions && (result.rooms ?? []).some((room) => (room.options ?? []).length > 1);
30802
31255
  const selectButton = (React__default.createElement(React__default.Fragment, null,
30803
- React__default.createElement("button", { type: "button", className: `cta ${isSelected ? 'cta--selected' : 'cta--select'}`, onClick: onSelect }, isSelected ? translations?.SHARED.SELECTED : translations?.SHARED.SELECT),
31256
+ React__default.createElement("button", { type: "button", className: `cta ${isSelected ? 'cta--selected' : 'cta--select'}`, onClick: onSelect }, isSelected ? selectedLabel ?? translations?.SHARED.SELECTED : selectLabel ?? translations?.SHARED.SELECT),
30804
31257
  canEditOptions && (React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: onEditOptions },
30805
31258
  translations?.SRP.SELECT,
30806
31259
  " ",
@@ -30880,7 +31333,112 @@ const TrajectResultsFlyIn = ({ isLoading }) => {
30880
31333
  ordered.length,
30881
31334
  "\u00A0",
30882
31335
  translations.SRP.TOTAL_RESULTS_LABEL)),
30883
- ordered.length === 0 ? (React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS)) : (React__default.createElement("div", { className: "search__results__cards search__results__cards--compact" }, ordered.map((result) => (React__default.createElement(TrajectNodeCard, { key: result.code, item: item, result: result, isSelected: result.code === availability?.selectedCode, languageCode: context.languageCode, translations: translations, onSelect: () => handleSelect(result.code), showNights: item.node.serviceType === ACCOMMODATION_SERVICE_TYPE })))))));
31336
+ ordered.length === 0 ? (React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS)) : (React__default.createElement("div", { className: "search__results__cards" }, ordered.map((result) => (React__default.createElement(TrajectNodeCard, { key: result.code, node: item.node, result: result, isSelected: result.code === availability?.selectedCode, languageCode: context.languageCode, translations: translations, onSelect: () => handleSelect(result.code), showNights: item.node.serviceType === ACCOMMODATION_SERVICE_TYPE })))))));
31337
+ };
31338
+
31339
+ /**
31340
+ * Every flight found for one traject leg, shown in the fly-in.
31341
+ *
31342
+ * A one-way search can return far more options than belong in the results column, so the column
31343
+ * keeps three and hands the rest to this list — the same shape the regular flight results use.
31344
+ * Each leg is searched on its own, so the single leg of a result always sits in `outward`.
31345
+ */
31346
+ const TrajectFlightsFlyIn = ({ isLoading }) => {
31347
+ const context = useContext(SearchResultsConfigurationContext);
31348
+ const dispatch = useDispatch();
31349
+ const translations = getTranslations(context?.languageCode ?? 'en-GB');
31350
+ const { trajectFlightAvailability, trajectEditLineGuid, flightsLoading } = useSelector((state) => state.searchResults);
31351
+ const trajectEntry = context?.trajectEntry;
31352
+ const item = useMemo(() => {
31353
+ if (!trajectEntry || !trajectEditLineGuid)
31354
+ return null;
31355
+ return getTrajectNodesWithLines(trajectEntry).find((x) => x.line.guid === trajectEditLineGuid) ?? null;
31356
+ }, [trajectEntry, trajectEditLineGuid]);
31357
+ if (!context || !item)
31358
+ return null;
31359
+ const availability = trajectFlightAvailability[item.line.guid];
31360
+ const flights = availability?.results ?? [];
31361
+ const selectedGuid = availability?.selectedGuid;
31362
+ const selected = flights.find((x) => x.outwardGuid === selectedGuid) ?? null;
31363
+ const handleSelect = (outwardGuid) => {
31364
+ const flight = flights.find((x) => x.outwardGuid === outwardGuid);
31365
+ if (!flight)
31366
+ return;
31367
+ dispatch(setTrajectFlightSelection({ lineGuid: item.line.guid, guid: flight.outwardGuid }));
31368
+ dispatch(updateEditableEntryLine(applyFlightToLine(item.line, flight)));
31369
+ dispatch(setTrajectEditLineGuid(null));
31370
+ dispatch(setFlyInIsOpen(false));
31371
+ };
31372
+ if (isLoading || flightsLoading) {
31373
+ return React__default.createElement(React__default.Fragment, null, context.customSpinner ?? React__default.createElement(Spinner, { label: translations.SRP.LOADING_FLIGHTS }));
31374
+ }
31375
+ // The picked flight stays at the top; the rest follow by price.
31376
+ const ordered = [...flights].sort((a, b) => {
31377
+ if (a.outwardGuid === selectedGuid)
31378
+ return -1;
31379
+ if (b.outwardGuid === selectedGuid)
31380
+ return 1;
31381
+ return a.price - b.price;
31382
+ });
31383
+ return (React__default.createElement("div", { className: "flyin__content" },
31384
+ React__default.createElement("div", { className: "search__result-row" },
31385
+ React__default.createElement("span", { className: "search__result-row-text" },
31386
+ ordered.length,
31387
+ "\u00A0",
31388
+ translations.SRP.TOTAL_RESULTS_LABEL)),
31389
+ ordered.length === 0 ? (React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS)) : (React__default.createElement("div", { className: "search__results__cards search__results__cards--extended" }, ordered.map((result) => (React__default.createElement(IndependentFlightOption, { key: `flight-${result.outwardGuid}`, item: result.outward, guid: result.outwardGuid, selectedGuid: selectedGuid ?? undefined, isOutward: true, showSelectedState: true, price: result.price, currentSelectedPrice: selected?.price, onSelect: result.outwardGuid === selectedGuid ? undefined : () => handleSelect(result.outwardGuid) })))))));
31390
+ };
31391
+
31392
+ const TrajectDayActivitiesFlyIn = ({ isLoading }) => {
31393
+ const context = useContext(SearchResultsConfigurationContext);
31394
+ const dispatch = useDispatch();
31395
+ const translations = getTranslations(context?.languageCode ?? 'en-GB');
31396
+ const { trajectNodeAvailability, trajectDaySuggestions, trajectActivitiesDayOrder, editablePackagingEntry } = useSelector((state) => state.searchResults);
31397
+ const trajectEntry = context?.trajectEntry;
31398
+ const items = useMemo(() => {
31399
+ if (!trajectEntry || trajectActivitiesDayOrder === null)
31400
+ return [];
31401
+ return getTrajectNodesWithLines(trajectEntry).filter(({ node }) => node.dayOrder === trajectActivitiesDayOrder && node.trajectNodeType === REGULAR_TRAJECT_NODE_TYPE && node.serviceType === EXCURSION_SERVICE_TYPE);
31402
+ }, [trajectEntry, trajectActivitiesDayOrder]);
31403
+ if (!context || trajectActivitiesDayOrder === null)
31404
+ return null;
31405
+ const suggestions = trajectDaySuggestions[trajectActivitiesDayOrder];
31406
+ const cards = buildDayActivityCards(items, trajectNodeAvailability, suggestions?.results ?? []);
31407
+ const getAddedLines = (result) => (editablePackagingEntry?.lines ?? []).filter((line) => line.serviceType === EXCURSION_SERVICE_TYPE && line.productCode === result.code && isSameDay(new Date(line.from), new Date(result.fromDate)));
31408
+ /** Adding is not a decision that ends the list — the traveller may want several. */
31409
+ const handleToggle = (result) => {
31410
+ const added = getAddedLines(result);
31411
+ if (added.length) {
31412
+ dispatch(removeEditableEntryLines(added.map((line) => line.guid)));
31413
+ return;
31414
+ }
31415
+ const lines = buildTrajectExcursionLines(result);
31416
+ if (lines.length)
31417
+ dispatch(addEditableEntryLines(lines));
31418
+ };
31419
+ /** Swapping what the traject books is one decision, so the list closes behind it. */
31420
+ const handleSelect = ({ result, item }) => {
31421
+ if (!item)
31422
+ return;
31423
+ dispatch(setTrajectNodeSelection({ lineGuid: item.line.guid, code: result.code }));
31424
+ applyResultToLines(item.lines, result).forEach((line) => dispatch(updateEditableEntryLine(line)));
31425
+ dispatch(setTrajectActivitiesDayOrder(null));
31426
+ dispatch(setFlyInIsOpen(false));
31427
+ };
31428
+ if (isLoading || suggestions?.status === 'loading') {
31429
+ return React__default.createElement(React__default.Fragment, null, context.customSpinner ?? React__default.createElement(Spinner, { label: translations.SRP.LOADING_EXCURSIONS }));
31430
+ }
31431
+ return (React__default.createElement("div", { className: "flyin__content" },
31432
+ React__default.createElement("div", { className: "search__result-row" },
31433
+ React__default.createElement("span", { className: "search__result-row-text" },
31434
+ cards.length,
31435
+ "\u00A0",
31436
+ translations.SRP.TOTAL_RESULTS_LABEL)),
31437
+ cards.length === 0 ? (React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS)) : (React__default.createElement("div", { className: "search__results__cards" }, cards.map((card) => {
31438
+ const { result, item } = card;
31439
+ const isSelected = item ? trajectNodeAvailability[item.line.guid]?.selectedCode === result.code : getAddedLines(result).length > 0;
31440
+ return (React__default.createElement(TrajectNodeCard, { key: `activity-${result.code}`, node: item?.node, result: result, isSelected: isSelected, languageCode: context.languageCode, translations: translations, onSelect: () => (item ? handleSelect(card) : handleToggle(result)), selectLabel: item ? undefined : translations.SRP.ADD, selectedLabel: item ? undefined : translations.SRP.REMOVE }));
31441
+ })))));
30884
31442
  };
30885
31443
 
30886
31444
  const FlyIn = ({ srpType, isOpen, setIsOpen, className = '', onPanelRef, detailsLoading, flyInType, isPackageEditFlow, handleConfirm, sortByTypes, activeSearchSeed, toggleFilters, filtersOpen }) => {
@@ -30955,8 +31513,8 @@ const FlyIn = ({ srpType, isOpen, setIsOpen, className = '', onPanelRef, details
30955
31513
  dispatch(setBookPackagingEntry(true));
30956
31514
  }
30957
31515
  };
30958
- return (React__default.createElement("div", { className: `flyin ${isOpen ? 'flyin--active' : ''} ${className} ${isPackageEditFlow || flyInType === 'acco-results' ? 'flyin--large' : ''} ${flyInType === 'excursion-results' || flyInType === 'excursion-details' ? 'flyin--medium' : ''}
30959
- ${flyInType === 'flight-outward-results' || flyInType === 'flight-return-results' ? 'flyin--flight' : ''}` },
31516
+ return (React__default.createElement("div", { className: `flyin ${isOpen ? 'flyin--active' : ''} ${className} ${isPackageEditFlow || flyInType === 'acco-results' || flyInType === 'traject-day-activities' ? 'flyin--large' : ''} ${flyInType === 'excursion-results' || flyInType === 'excursion-details' ? 'flyin--medium' : ''}
31517
+ ${flyInType === 'flight-outward-results' || flyInType === 'flight-return-results' || flyInType === 'traject-flight-results' ? 'flyin--flight' : ''}` },
30960
31518
  React__default.createElement("div", { className: `flyin__panel ${isOpen ? 'flyin__panel--active' : ''}`, ref: panelRef },
30961
31519
  React__default.createElement("div", { className: "flyin__content" },
30962
31520
  React__default.createElement("div", { className: "flyin__content-title-row" },
@@ -30973,6 +31531,8 @@ const FlyIn = ({ srpType, isOpen, setIsOpen, className = '', onPanelRef, details
30973
31531
  flyInType === 'flight-return-results' &&
30974
31532
  `${translations.SRP.SELECT} ${translations.FLIGHTS_FORM.RETURN_FLIGHT}`,
30975
31533
  srpType === build.PortalQsmType.AccommodationAndFlight && flyInType === 'flight-details' && 'Select your fare',
31534
+ flyInType === 'traject-flight-results' && `${translations.SRP.SELECT} ${translations.SRP.DEPARTURE}`,
31535
+ flyInType === 'traject-day-activities' && translations.SRP.ACTIVITIES,
30976
31536
  flyInType === 'excursion-results' || (flyInType === 'excursion-details' && 'Select excursion')),
30977
31537
  React__default.createElement("span", { className: "flyin__close", onClick: () => handleClose() },
30978
31538
  React__default.createElement(Icon, { name: "ui-close", width: 30, height: 30, "aria-hidden": "true" }))),
@@ -30982,6 +31542,8 @@ const FlyIn = ({ srpType, isOpen, setIsOpen, className = '', onPanelRef, details
30982
31542
  "Go Back")))),
30983
31543
  srpType === build.PortalQsmType.Flight && React__default.createElement(FlightsFlyIn, { isOpen: isOpen, setIsOpen: setIsOpen }),
30984
31544
  context?.trajectEntry && flyInType === 'acco-results' && React__default.createElement(TrajectResultsFlyIn, { isLoading: detailsLoading }),
31545
+ context?.trajectEntry && flyInType === 'traject-flight-results' && React__default.createElement(TrajectFlightsFlyIn, { isLoading: detailsLoading }),
31546
+ context?.trajectEntry && flyInType === 'traject-day-activities' && React__default.createElement(TrajectDayActivitiesFlyIn, { isLoading: detailsLoading }),
30985
31547
  !context?.trajectEntry &&
30986
31548
  (srpType === build.PortalQsmType.Accommodation || srpType === build.PortalQsmType.AccommodationAndFlight) &&
30987
31549
  flyInType === 'acco-results' && (React__default.createElement("div", { className: "flyin__content flyin__content--columns" },
@@ -33266,14 +33828,17 @@ const getNodeIcon = (node) => {
33266
33828
  return 'ui-bed';
33267
33829
  return 'ui-location';
33268
33830
  };
33831
+ const isRenderableNode = (node) => node.trajectNodeType === REGULAR_TRAJECT_NODE_TYPE &&
33832
+ (node.serviceType === ACCOMMODATION_SERVICE_TYPE || node.serviceType === EXCURSION_SERVICE_TYPE || node.serviceType === FLIGHT_SERVICE_TYPE);
33833
+ const MAX_DAY_ACTIVITIES = 6;
33269
33834
  const TrajectResults = ({ isLoading }) => {
33270
33835
  const context = useContext(SearchResultsConfigurationContext);
33271
33836
  const dispatch = useDispatch();
33272
33837
  const translations = getTranslations(context?.languageCode ?? 'en-GB');
33273
33838
  const locale = getLocale(context?.languageCode ?? 'en-GB');
33274
- const { trajectNodeAvailability, trajectFlightAvailability } = useSelector((state) => state.searchResults);
33275
- const [expandedNodes, setExpandedNodes] = useState({});
33839
+ const { trajectNodeAvailability, trajectFlightAvailability, trajectDaySuggestions, editablePackagingEntry } = useSelector((state) => state.searchResults);
33276
33840
  const trajectEntry = context?.trajectEntry;
33841
+ const hideShowMoreResults = !!context?.hideShowMoreResults;
33277
33842
  const nodesWithLines = useMemo(() => (trajectEntry ? getTrajectNodesWithLines(trajectEntry) : []), [trajectEntry]);
33278
33843
  const lineByNodeId = useMemo(() => new Map(nodesWithLines.map((x) => [x.node.nodeId, x])), [nodesWithLines]);
33279
33844
  const nodesByDay = useMemo(() => {
@@ -33287,9 +33852,22 @@ const TrajectResults = ({ isLoading }) => {
33287
33852
  });
33288
33853
  return map;
33289
33854
  }, [trajectEntry]);
33855
+ const { stayByDay, stayStartByNodeId } = useMemo(() => {
33856
+ const byDay = new Map();
33857
+ const byNodeId = new Map();
33858
+ nodesWithLines
33859
+ .filter((x) => x.node.serviceType === ACCOMMODATION_SERVICE_TYPE)
33860
+ .forEach((item) => {
33861
+ const nights = Math.max(differenceInCalendarDays(new Date(item.line.to), new Date(item.line.from)), 1);
33862
+ byNodeId.set(item.node.nodeId, { item, night: 0, nights });
33863
+ for (let night = 0; night < nights; night++) {
33864
+ byDay.set(item.node.dayOrder + night, { item, night, nights });
33865
+ }
33866
+ });
33867
+ return { stayByDay: byDay, stayStartByNodeId: byNodeId };
33868
+ }, [nodesWithLines]);
33290
33869
  if (!context || !trajectEntry)
33291
33870
  return null;
33292
- const toggleExpanded = (lineGuid) => setExpandedNodes((prev) => ({ ...prev, [lineGuid]: !prev[lineGuid] }));
33293
33871
  const handleSelect = (item, code) => {
33294
33872
  const availability = trajectNodeAvailability[item.line.guid];
33295
33873
  const result = availability?.results.find((x) => x.code === code);
@@ -33298,6 +33876,12 @@ const TrajectResults = ({ isLoading }) => {
33298
33876
  dispatch(setTrajectNodeSelection({ lineGuid: item.line.guid, code }));
33299
33877
  applyResultToLines(item.lines, result).forEach((line) => dispatch(updateEditableEntryLine(line)));
33300
33878
  };
33879
+ /** The remaining legs for a flight node open in the fly-in, as the regular flight results do. */
33880
+ const handleShowMoreFlights = (item) => {
33881
+ dispatch(setTrajectEditLineGuid(item.line.guid));
33882
+ dispatch(setFlyInType('traject-flight-results'));
33883
+ dispatch(setFlyInIsOpen(true));
33884
+ };
33301
33885
  const handleShowMore = (item) => {
33302
33886
  dispatch(setTrajectEditLineGuid(item.line.guid));
33303
33887
  dispatch(setFlyInType('acco-results'));
@@ -33314,8 +33898,41 @@ const TrajectResults = ({ isLoading }) => {
33314
33898
  dispatch(setFlyInType('acco-details'));
33315
33899
  dispatch(setFlyInIsOpen(true));
33316
33900
  };
33317
- const renderServiceNode = (item) => {
33318
- console.log('renderServiceNode', item);
33901
+ const getStayLocation = (item) => {
33902
+ const availability = trajectNodeAvailability[item.line.guid];
33903
+ const result = availability?.results.find((x) => x.code === availability?.selectedCode);
33904
+ return (result?.locationName ||
33905
+ result?.oordName ||
33906
+ result?.regionName ||
33907
+ result?.countryName ||
33908
+ item.line.location?.name ||
33909
+ item.line.oord?.name ||
33910
+ item.line.region?.name ||
33911
+ item.line.country?.name ||
33912
+ item.node.alternatives?.find((x) => x.isPreferred)?.city ||
33913
+ '');
33914
+ };
33915
+ const getStayName = (item) => {
33916
+ const availability = trajectNodeAvailability[item.line.guid];
33917
+ const result = availability?.results.find((x) => x.code === availability?.selectedCode);
33918
+ return result?.name || item.node.preferredAccommodationName || item.node.name || '';
33919
+ };
33920
+ const getStayTitle = (stay) => [getStayLocation(stay.item), getStayName(stay.item), `${stay.night + 1} ${translations.SRP.OF} ${stay.nights} ${translations.SRP.NIGHTS}`]
33921
+ .filter(Boolean)
33922
+ .join(' - ');
33923
+ const renderDayHeader = (day, stay) => {
33924
+ const date = new Date(day.date);
33925
+ const title = stay ? getStayTitle(stay) : day.name;
33926
+ return (React__default.createElement("div", { className: "search__results__label search__results__label--secondary" },
33927
+ React__default.createElement("div", { className: "search__results__label__date" },
33928
+ React__default.createElement("p", { className: "search__results__label__date-date" }, format$2(date, 'd', { locale })),
33929
+ React__default.createElement("p", null, format$2(date, 'MMM', { locale }))),
33930
+ React__default.createElement("div", { className: "search__results__label__text" },
33931
+ React__default.createElement(Icon, { name: stay ? 'ui-bed' : 'ui-location', height: 16 }),
33932
+ React__default.createElement("h3", null,
33933
+ React__default.createElement("strong", null, title)))));
33934
+ };
33935
+ const renderServiceNode = (item, showHeader = true, headerTitle) => {
33319
33936
  const { node, line } = item;
33320
33937
  const availability = trajectNodeAvailability[line.guid];
33321
33938
  const results = availability?.results ?? [];
@@ -33325,12 +33942,14 @@ const TrajectResults = ({ isLoading }) => {
33325
33942
  // No entry yet means the node's search has been queued but not dispatched — still loading.
33326
33943
  const status = availability?.status ?? 'loading';
33327
33944
  return (React__default.createElement(React__default.Fragment, { key: line.guid },
33328
- React__default.createElement("div", { className: "search__results__label search__results__label--secondary" },
33945
+ showHeader && (React__default.createElement("div", { className: "search__results__label search__results__label--secondary" },
33329
33946
  React__default.createElement("div", { className: "search__results__label__date" },
33330
33947
  React__default.createElement("p", { className: "search__results__label__date-date" }, format$2(new Date(line.from), 'd', { locale })),
33331
33948
  React__default.createElement("p", null, format$2(new Date(line.from), 'MMM', { locale }))),
33332
33949
  React__default.createElement("div", { className: "search__results__label__text" },
33333
- React__default.createElement(Icon, { name: getNodeIcon(node), height: 16 }))),
33950
+ React__default.createElement(Icon, { name: getNodeIcon(node), height: 16 }),
33951
+ React__default.createElement("h3", null,
33952
+ React__default.createElement("strong", null, headerTitle || node.name))))),
33334
33953
  status === 'loading' && (React__default.createElement(Spinner, { label: node.serviceType === EXCURSION_SERVICE_TYPE ? translations.SRP.LOADING_EXCURSIONS : translations.SRP.LOADING_ACCOMMODATIONS })),
33335
33954
  status === 'unavailable' && React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS),
33336
33955
  status === 'resolved' && selected && (React__default.createElement(React__default.Fragment, null,
@@ -33339,8 +33958,8 @@ const TrajectResults = ({ isLoading }) => {
33339
33958
  node.preferredAccommodationName,
33340
33959
  " \u2014 ",
33341
33960
  translations.SRP.NO_RESULTS))),
33342
- React__default.createElement("div", { className: "search__results__cards search__results__cards--compact" }, [selected, ...configured].map((result) => (React__default.createElement(TrajectNodeCard, { key: result.code, item: item, result: result, isSelected: result.code === selected.code, languageCode: context.languageCode, translations: translations, onSelect: () => handleSelect(item, result.code), onEditOptions: node.serviceType === ACCOMMODATION_SERVICE_TYPE ? () => handleEditOptions(item) : undefined, showNights: node.serviceType === ACCOMMODATION_SERVICE_TYPE })))),
33343
- others.length > 0 && (React__default.createElement("div", { className: "search__results__cards__actions" },
33961
+ React__default.createElement("div", { className: "search__results__cards search__results__cards--scroll" }, [selected, ...configured].map((result) => (React__default.createElement(TrajectNodeCard, { key: result.code, node: node, result: result, isSelected: result.code === selected.code, languageCode: context.languageCode, translations: translations, onSelect: () => handleSelect(item, result.code), onEditOptions: node.serviceType === ACCOMMODATION_SERVICE_TYPE ? () => handleEditOptions(item) : undefined, showNights: node.serviceType === ACCOMMODATION_SERVICE_TYPE })))),
33962
+ others.length > 0 && !hideShowMoreResults && (React__default.createElement("div", { className: "search__results__cards__actions" },
33344
33963
  React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleShowMore(item) },
33345
33964
  translations.SRP.SHOW_MORE,
33346
33965
  " (",
@@ -33358,8 +33977,7 @@ const TrajectResults = ({ isLoading }) => {
33358
33977
  const flights = availability?.results ?? [];
33359
33978
  const selected = flights.find((x) => x.outwardGuid === availability?.selectedGuid) ?? null;
33360
33979
  const others = flights.filter((x) => x.outwardGuid !== availability?.selectedGuid);
33361
- const isExpanded = !!expandedNodes[line.guid];
33362
- const visible = isExpanded ? others : others.slice(0, 2);
33980
+ const visible = others.slice(0, 2);
33363
33981
  return (React__default.createElement(React__default.Fragment, { key: line.guid },
33364
33982
  React__default.createElement("div", { className: "search__results__label search__results__label--secondary" },
33365
33983
  React__default.createElement("div", { className: "search__results__label__date" },
@@ -33380,28 +33998,109 @@ const TrajectResults = ({ isLoading }) => {
33380
33998
  React__default.createElement("div", { className: "search__results__cards search__results__cards--extended" },
33381
33999
  React__default.createElement(IndependentFlightOption, { key: `flight-${selected.outwardGuid}`, item: selected.outward, guid: selected.outwardGuid, selectedGuid: selected.outwardGuid, isOutward: true, showSelectedState: true, price: selected.price }),
33382
34000
  visible.map((result) => (React__default.createElement(IndependentFlightOption, { key: `flight-${result.outwardGuid}`, item: result.outward, guid: result.outwardGuid, isOutward: true, price: result.price, currentSelectedPrice: selected.price, onSelect: () => handleSelectFlight(item, result) })))),
33383
- others.length > 2 && (React__default.createElement("div", { className: "search__results__cards__actions" },
33384
- React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => toggleExpanded(line.guid) }, isExpanded ? translations.SRP.SHOW_LESS : `${translations.SRP.SHOW_MORE} (${others.length - 2})`)))))));
34001
+ others.length > 2 && !hideShowMoreResults && (React__default.createElement("div", { className: "search__results__cards__actions" },
34002
+ React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleShowMoreFlights(item) },
34003
+ translations.SRP.SHOW_MORE,
34004
+ " (",
34005
+ others.length - 2,
34006
+ ")")))))));
34007
+ };
34008
+ /** The lines a suggested activity put on the entry, which is also how we know it was added. */
34009
+ const getAddedExcursionLines = (result) => (editablePackagingEntry?.lines ?? []).filter((line) => line.serviceType === EXCURSION_SERVICE_TYPE && line.productCode === result.code && isSameDay(new Date(line.from), new Date(result.fromDate)));
34010
+ const handleToggleActivity = (result) => {
34011
+ const added = getAddedExcursionLines(result);
34012
+ if (added.length) {
34013
+ dispatch(removeEditableEntryLines(added.map((line) => line.guid)));
34014
+ return;
34015
+ }
34016
+ const lines = buildTrajectExcursionLines(result);
34017
+ if (lines.length)
34018
+ dispatch(addEditableEntryLines(lines));
34019
+ };
34020
+ const handleShowMoreActivities = (dayOrder) => {
34021
+ dispatch(setTrajectActivitiesDayOrder(dayOrder));
34022
+ dispatch(setFlyInType('traject-day-activities'));
34023
+ dispatch(setFlyInIsOpen(true));
34024
+ };
34025
+ /** The excursion nodes the traject itself puts on a day. */
34026
+ const getDayExcursionItems = (dayOrder) => (nodesByDay.get(dayOrder) ?? [])
34027
+ .filter((node) => node.trajectNodeType === REGULAR_TRAJECT_NODE_TYPE && node.serviceType === EXCURSION_SERVICE_TYPE)
34028
+ .map((node) => lineByNodeId.get(node.nodeId))
34029
+ .filter((x) => !!x);
34030
+ /**
34031
+ * One block per day for everything there is to do that day.
34032
+ *
34033
+ * What the traject books sits first and stays selected; the rest of the day follows as things
34034
+ * the traveller may add. They share a row because they answer the same question — an excursion
34035
+ * on the traject and one found for the day are alternatives to each other, and a block apiece
34036
+ * would only hide that.
34037
+ */
34038
+ const renderDayActivities = (day) => {
34039
+ const items = getDayExcursionItems(day.order);
34040
+ const suggestions = trajectDaySuggestions[day.order];
34041
+ const cards = buildDayActivityCards(items, trajectNodeAvailability, suggestions?.results ?? []);
34042
+ const isResolving = items.some((item) => (trajectNodeAvailability[item.line.guid]?.status ?? 'loading') === 'loading') || suggestions?.status === 'loading';
34043
+ // A day with nothing configured and nothing found has nothing to say. A day whose own
34044
+ // excursion came back empty does, so the gap is not passed off as a day without activities.
34045
+ if (!cards.length && !items.length)
34046
+ return null;
34047
+ const visible = cards.slice(0, MAX_DAY_ACTIVITIES);
34048
+ const hidden = cards.length - visible.length;
34049
+ return (React__default.createElement(React__default.Fragment, { key: `activities-${day.order}` },
34050
+ React__default.createElement("div", { className: "search__results__label search__results__label--secondary" },
34051
+ React__default.createElement("div", { className: "search__results__label__date" },
34052
+ React__default.createElement("p", { className: "search__results__label__date-date" }, format$2(new Date(day.date), 'd', { locale })),
34053
+ React__default.createElement("p", null, format$2(new Date(day.date), 'MMM', { locale }))),
34054
+ React__default.createElement("div", { className: "search__results__label__text" },
34055
+ React__default.createElement(Icon, { name: "ui-excursion", height: 16 }),
34056
+ React__default.createElement("h3", null,
34057
+ React__default.createElement("strong", null, translations.SRP.ACTIVITIES)))),
34058
+ isResolving && !cards.length && React__default.createElement(Spinner, { label: translations.SRP.LOADING_EXCURSIONS }),
34059
+ !isResolving && !cards.length && React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS),
34060
+ !!cards.length && (React__default.createElement(React__default.Fragment, null,
34061
+ React__default.createElement("div", { className: "search__results__cards search__results__cards--scroll" }, visible.map(renderActivityCard)),
34062
+ hidden > 0 && !hideShowMoreResults && (React__default.createElement("div", { className: "search__results__cards__actions" },
34063
+ React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleShowMoreActivities(day.order) },
34064
+ translations.SRP.SHOW_MORE,
34065
+ " (",
34066
+ hidden,
34067
+ ")")))))));
34068
+ };
34069
+ /**
34070
+ * An activity the traject books is swapped for another, the way a hotel is; one the traveller
34071
+ * found for themselves is added to the trip or taken back off it.
34072
+ */
34073
+ const renderActivityCard = ({ result, item }) => {
34074
+ const isSelected = item ? trajectNodeAvailability[item.line.guid]?.selectedCode === result.code : getAddedExcursionLines(result).length > 0;
34075
+ return (React__default.createElement(TrajectNodeCard, { key: `activity-${result.code}`, node: item?.node, result: result, isSelected: isSelected, languageCode: context.languageCode, translations: translations, onSelect: () => (item ? handleSelect(item, result.code) : handleToggleActivity(result)), selectLabel: item ? undefined : translations.SRP.ADD, selectedLabel: item ? undefined : translations.SRP.REMOVE }));
33385
34076
  };
33386
34077
  if (isLoading)
33387
34078
  return React__default.createElement(Spinner, { label: translations.SRP.LOADING_ITINERARY });
33388
34079
  return (React__default.createElement(React__default.Fragment, null, trajectEntry.traject.days.map((day) => {
33389
- const dayNodes = nodesByDay.get(day.order) ?? [];
33390
- if (!dayNodes.length)
33391
- return null;
33392
- return (React__default.createElement(React__default.Fragment, { key: `day-${day.order}` }, dayNodes.map((node) => {
33393
- if (node.serviceType !== ACCOMMODATION_SERVICE_TYPE && node.serviceType !== EXCURSION_SERVICE_TYPE && node.serviceType !== FLIGHT_SERVICE_TYPE)
33394
- return null;
33395
- // if (node.trajectNodeType === CONNECTING_TRAJECT_NODE_TYPE) return null;
33396
- // if (node.trajectNodeType !== REGULAR_TRAJECT_NODE_TYPE) return renderContextNode(node);
33397
- if (node.trajectNodeType !== REGULAR_TRAJECT_NODE_TYPE)
33398
- return null;
33399
- const item = lineByNodeId.get(node.nodeId);
33400
- // if (!item) return renderContextNode(node);
33401
- if (!item)
33402
- return null;
33403
- return isTrajectFlightNode(node) ? renderFlightNode(item) : renderServiceNode(item);
33404
- })));
34080
+ const stay = stayByDay.get(day.order);
34081
+ const dayNodes = (nodesByDay.get(day.order) ?? []).filter((node) => isRenderableNode(node) && lineByNodeId.has(node.nodeId));
34082
+ const stayLeadsDay = !!stay && (stay.night > 0 || dayNodes[0]?.nodeId === stay.item.node.nodeId);
34083
+ // Where the day's activities belong in the order: with the first excursion it carries.
34084
+ const firstExcursionNodeId = dayNodes.find((node) => node.serviceType === EXCURSION_SERVICE_TYPE)?.nodeId;
34085
+ const showDayHeader = stayLeadsDay || !!day.name?.trim();
34086
+ return (React__default.createElement(React__default.Fragment, { key: `day-${day.order}` },
34087
+ showDayHeader && renderDayHeader(day, stayLeadsDay ? stay : undefined),
34088
+ dayNodes.map((node) => {
34089
+ const item = lineByNodeId.get(node.nodeId);
34090
+ if (node.serviceType === ACCOMMODATION_SERVICE_TYPE) {
34091
+ const stayStart = stayStartByNodeId.get(node.nodeId);
34092
+ const titledByDayHeader = stayLeadsDay && stay.item.node.nodeId === node.nodeId;
34093
+ return renderServiceNode(item, !titledByDayHeader, stayStart && getStayTitle(stayStart));
34094
+ }
34095
+ // Every excursion the day holds is drawn once, in one block, where the first of
34096
+ // them falls in the order — so the activities still sit between the stay and the
34097
+ // flight that follow them.
34098
+ if (node.serviceType === EXCURSION_SERVICE_TYPE) {
34099
+ return node.nodeId === firstExcursionNodeId ? renderDayActivities(day) : null;
34100
+ }
34101
+ return renderFlightNode(item);
34102
+ }),
34103
+ firstExcursionNodeId === undefined && renderDayActivities(day)));
33405
34104
  })));
33406
34105
  };
33407
34106
 
@@ -33409,7 +34108,8 @@ const useTrajectAvailability = () => {
33409
34108
  const context = useContext(SearchResultsConfigurationContext);
33410
34109
  const dispatch = useDispatch();
33411
34110
  const trajectEntry = context?.trajectEntry;
33412
- const showNonPreferredItems = !!context?.showNonPreferredItems;
34111
+ const showApiItems = !!context?.showApiItems;
34112
+ const hideShowMoreResults = !!context?.hideShowMoreResults;
33413
34113
  useEffect(() => {
33414
34114
  if (!context || !trajectEntry)
33415
34115
  return;
@@ -33442,7 +34142,8 @@ const useTrajectAvailability = () => {
33442
34142
  const search = item.node.serviceType === EXCURSION_SERVICE_TYPE ? build.searchPackagingExcursions : build.searchPackagingAccommodations;
33443
34143
  dispatch(setTrajectNodeLoading(lineGuid));
33444
34144
  try {
33445
- const candidates = getNodeCandidates(item.node);
34145
+ // With external items switched off the node only looks at products held inside Tide.
34146
+ const candidates = getNodeCandidates(item.node).filter((x) => showApiItems || !isExternalCandidate(x));
33446
34147
  const attempts = await Promise.all(candidates.map(async (candidate) => {
33447
34148
  try {
33448
34149
  const attempt = await search(config, buildTrajectNodeRequest(item, searchContext, candidate.code), controller.signal);
@@ -33459,11 +34160,16 @@ const useTrajectAvailability = () => {
33459
34160
  .filter((x, i, all) => all.findIndex((y) => y.code === x.code) === i);
33460
34161
  const preferredCandidate = candidates.find((x) => x.isPreferred) ?? candidates[0];
33461
34162
  let preferredUnavailable = !!preferredCandidate && !configuredResults.some((x) => matchesCode(x, preferredCandidate.code));
33462
- const destinationResults = showNonPreferredItems
33463
- ? ((await search(config, buildTrajectNodeRequest(item, searchContext, ''), controller.signal)) ?? []).filter((x) => !configuredResults.some((configured) => configured.code === x.code))
33464
- : [];
33465
- const results = [...configuredResults, ...destinationResults];
34163
+ // The destination search exists only to stock the show-more fly-in. With the button hidden
34164
+ // a node is limited to its configured products; if none are available it simply reports so,
34165
+ // rather than quietly substituting a hotel nobody configured.
34166
+ const destinationResults = hideShowMoreResults
34167
+ ? []
34168
+ : ((await search(config, buildTrajectNodeRequest(item, searchContext, ''), controller.signal)) ?? [])
34169
+ .filter((x) => showApiItems || !isExternalResult(x))
34170
+ .filter((x) => !configuredResults.some((configured) => configured.code === x.code));
33466
34171
  const picked = configuredResults[0] ?? pickCheapest(destinationResults);
34172
+ const results = [...configuredResults, ...destinationResults];
33467
34173
  if (!configuredResults.length)
33468
34174
  preferredUnavailable = candidates.length > 0;
33469
34175
  if (controller.signal.aborted)
@@ -33526,7 +34232,7 @@ const useTrajectAvailability = () => {
33526
34232
  dispatch(removeEditableEntryLines(emptyLineGuids));
33527
34233
  })();
33528
34234
  return () => controller.abort();
33529
- }, [trajectEntry, showNonPreferredItems]);
34235
+ }, [trajectEntry, showApiItems, hideShowMoreResults]);
33530
34236
  };
33531
34237
 
33532
34238
  const SearchResultsContainer = ({ onBookingStarted }) => {
@@ -37703,20 +38409,20 @@ function ItineraryMapView({ destinations: propDestinations, adults = 2, dateFrom
37703
38409
  const isStartEnd = dest.isStart || dest.isEnd;
37704
38410
  let iconHtml;
37705
38411
  if (isStartEnd) {
37706
- iconHtml = `
37707
- <div class="map-view__marker map-view__marker--plane">
37708
- <svg viewBox="0 0 576 512" fill="currentColor" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
37709
- <path d="M482.3 192c34.2 0 93.7 29 93.7 64c0 36-59.5 64-93.7 64l-116.6 0L265.2 495.9c-5.7 10.1-16.3 16.1-27.8 16.1l-56.2 0c-10.6 0-18.3-10.3-15.8-20.6l49-196.3L112 288 68.8 377.6c-3 6.1-9.2 10.4-16 10.4l-2.8 0c-9.2 0-16-8.8-13.3-17.6L80 256L36.7 141.6C34 132.8 40.8 124 50 124l2.8 0c6.8 0 13 4.3 16 10.4L112 224l102.9 0-49-196.3C163.5 17.3 171.2 7 181.8 7l56.2 0c11.5 0 22.1 6 27.8 16.1L365.7 192l116.6 0z"/>
37710
- </svg>
38412
+ iconHtml = `
38413
+ <div class="map-view__marker map-view__marker--plane">
38414
+ <svg viewBox="0 0 576 512" fill="currentColor" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
38415
+ <path d="M482.3 192c34.2 0 93.7 29 93.7 64c0 36-59.5 64-93.7 64l-116.6 0L265.2 495.9c-5.7 10.1-16.3 16.1-27.8 16.1l-56.2 0c-10.6 0-18.3-10.3-15.8-20.6l49-196.3L112 288 68.8 377.6c-3 6.1-9.2 10.4-16 10.4l-2.8 0c-9.2 0-16-8.8-13.3-17.6L80 256L36.7 141.6C34 132.8 40.8 124 50 124l2.8 0c6.8 0 13 4.3 16 10.4L112 224l102.9 0-49-196.3C163.5 17.3 171.2 7 181.8 7l56.2 0c11.5 0 22.1 6 27.8 16.1L365.7 192l116.6 0z"/>
38416
+ </svg>
37711
38417
  </div>`;
37712
38418
  }
37713
38419
  else {
37714
38420
  stopIndex++;
37715
38421
  const imgStyle = dest.imageUrl ? `style="background-image:url('${dest.imageUrl}')"` : '';
37716
- iconHtml = `
37717
- <div class="map-view__marker map-view__marker--stop" ${imgStyle}>
37718
- ${!dest.imageUrl ? `<span class="map-view__marker-number">${stopIndex}</span>` : ''}
37719
- <span class="map-view__marker-badge">${stopIndex}</span>
38422
+ iconHtml = `
38423
+ <div class="map-view__marker map-view__marker--stop" ${imgStyle}>
38424
+ ${!dest.imageUrl ? `<span class="map-view__marker-number">${stopIndex}</span>` : ''}
38425
+ <span class="map-view__marker-badge">${stopIndex}</span>
37720
38426
  </div>`;
37721
38427
  }
37722
38428
  const icon = L.divIcon({