@qite/tide-components 1.0.8 → 1.0.10

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 (79) hide show
  1. package/build/build-cjs/index.js +585 -319
  2. package/build/build-cjs/src/booking-product/types.d.ts +10 -0
  3. package/build/build-cjs/src/search-results/components/itinerary/itinerary-utils.d.ts +12 -0
  4. package/build/build-cjs/src/search-results/types.d.ts +12 -0
  5. package/build/build-esm/index.js +586 -320
  6. package/build/build-esm/src/booking-product/types.d.ts +10 -0
  7. package/build/build-esm/src/search-results/components/itinerary/itinerary-utils.d.ts +12 -0
  8. package/build/build-esm/src/search-results/types.d.ts +12 -0
  9. package/package.json +2 -2
  10. package/styles/abstracts/_mixins.scss +74 -74
  11. package/styles/abstracts/_variables.scss +57 -57
  12. package/styles/base/_fonts.scss +2 -2
  13. package/styles/base/_normalize.scss +227 -227
  14. package/styles/base/_typography.scss +35 -35
  15. package/styles/booking-joker-variables.scss +596 -596
  16. package/styles/booking-product-variables.scss +330 -330
  17. package/styles/booking-product.scss +438 -438
  18. package/styles/booking-qsm-variables.scss +501 -501
  19. package/styles/booking-qsm.scss +52 -52
  20. package/styles/booking-search-results-variables.scss +734 -734
  21. package/styles/booking-search-results.scss +53 -53
  22. package/styles/booking-wizard-variables.scss +603 -603
  23. package/styles/booking-wizard.scss +61 -61
  24. package/styles/components/_accordion.scss +67 -67
  25. package/styles/components/_animations.scss +39 -39
  26. package/styles/components/_base.scss +107 -107
  27. package/styles/components/_booking.scss +906 -906
  28. package/styles/components/_breadcrumb.scss +92 -92
  29. package/styles/components/_button.scss +238 -238
  30. package/styles/components/_checkbox.scss +230 -230
  31. package/styles/components/_contact.scss +255 -255
  32. package/styles/components/_content.scss +336 -336
  33. package/styles/components/_cta.scss +238 -238
  34. package/styles/components/_date-list.scss +41 -41
  35. package/styles/components/_date-range-picker.scss +223 -223
  36. package/styles/components/_decrement-increment.scss +35 -35
  37. package/styles/components/_dropdown.scss +77 -77
  38. package/styles/components/_error.scss +50 -50
  39. package/styles/components/_faq.scss +30 -30
  40. package/styles/components/_flight-option.scss +1432 -1432
  41. package/styles/components/_flyin.scss +830 -830
  42. package/styles/components/_footer.scss +135 -135
  43. package/styles/components/_form.scss +1693 -1693
  44. package/styles/components/_gallery.scss +317 -317
  45. package/styles/components/_header.scss +113 -113
  46. package/styles/components/_image-with-text.scss +206 -206
  47. package/styles/components/_img-slider.scss +175 -175
  48. package/styles/components/_info-message.scss +75 -75
  49. package/styles/components/_input.scss +35 -35
  50. package/styles/components/_list.scss +185 -185
  51. package/styles/components/_loader.scss +152 -152
  52. package/styles/components/_login.scss +140 -140
  53. package/styles/components/_map-view.scss +1100 -1100
  54. package/styles/components/_mixins.scss +579 -579
  55. package/styles/components/_navbar.scss +765 -765
  56. package/styles/components/_passenger-picker.scss +306 -306
  57. package/styles/components/_phone-input.scss +8 -8
  58. package/styles/components/_placeholders.scss +165 -165
  59. package/styles/components/_pricing-summary.scss +163 -163
  60. package/styles/components/_qsm.scss +17 -17
  61. package/styles/components/_radiobutton.scss +170 -170
  62. package/styles/components/_search.scss +2197 -2178
  63. package/styles/components/_select-wrapper.scss +81 -81
  64. package/styles/components/_slider.scss +128 -128
  65. package/styles/components/_spinner.scss +29 -29
  66. package/styles/components/_step-indicators.scss +187 -187
  67. package/styles/components/_table.scss +81 -81
  68. package/styles/components/_tide-form.scss +578 -578
  69. package/styles/components/_tree.scss +648 -648
  70. package/styles/components/_typeahead.scss +275 -275
  71. package/styles/components/_variables.scss +89 -89
  72. package/styles/content-blocks-variables.scss +543 -543
  73. package/styles/content-blocks.scss +66 -66
  74. package/styles/font.scss +2 -2
  75. package/styles/qsm/_calendar.scss +274 -274
  76. package/styles/qsm/_qsm.scss +1097 -1097
  77. package/styles/search.scss +1200 -1200
  78. package/styles/tide-form-variables.scss +275 -275
  79. package/styles/tide-form.scss +56 -56
@@ -124,7 +124,7 @@ var PRODUCT$f = {
124
124
  PER_PERSON_PER_NIGHT: "لكل شخص / لكل ليلة",
125
125
  BOOK_NOW: "احجز الآن",
126
126
  TO_YOUR_OFFER: "إلى عرضك",
127
- NOT_AVAILABLE: "غير متاح",
127
+ NOT_AVAILABLE: "غير متاح — يرجى اختيار تاريخ آخر",
128
128
  NUMBER_OF_ROOMS: "عدد الغرف",
129
129
  AGE_BY_DEPARTURE_DATE: "عمر الأطفال عند تاريخ المغادرة",
130
130
  YEAR: "سنة/سنوات",
@@ -417,6 +417,8 @@ var SRP$f = {
417
417
  DEPARTURE_ASC: "تاريخ المغادرة (الأقرب أولاً)",
418
418
  FILTERS: "عوامل التصفية",
419
419
  SHOW_ITINERARY: "عرض خط سير الرحلة",
420
+ VIEW_FULL_ITINERARY: "عرض خط السير الكامل",
421
+ SHOW_SERVICES: "عرض الخدمات",
420
422
  VIEW_BOOKING: "عرض الحجز",
421
423
  ITINERARY_TITLE: "ملخص رحلتك",
422
424
  DOSSIER_NUMBER: "رقم الملف",
@@ -466,7 +468,7 @@ var SRP$f = {
466
468
  };
467
469
  var ITINERARY$f = {
468
470
  DAY: "اليوم",
469
- NO_ITEMS: "لا توجد عناصر لهذا اليوم."
471
+ NO_ITEMS: "لم يتم اختيار أنشطة لهذا اليوم."
470
472
  };
471
473
  var FORM$f = {
472
474
  LOADING: "جاري تحميل النموذج...",
@@ -569,7 +571,7 @@ var PRODUCT$e = {
569
571
  PER_PERSON_PER_NIGHT: "Per person / per nat",
570
572
  BOOK_NOW: "Book nu",
571
573
  TO_YOUR_OFFER: "Til dit tilbud",
572
- NOT_AVAILABLE: "Ikke tilgængelig",
574
+ NOT_AVAILABLE: "Ikke tilgængelig — vælg venligst en anden dato",
573
575
  NUMBER_OF_ROOMS: "Antal værelser",
574
576
  AGE_BY_DEPARTURE_DATE: "Børns alder på afrejsedato",
575
577
  YEAR: "år",
@@ -862,6 +864,8 @@ var SRP$e = {
862
864
  DEPARTURE_ASC: "Afrejsedato (snarest først)",
863
865
  FILTERS: "Filtre",
864
866
  SHOW_ITINERARY: "Vis rejseplan",
867
+ VIEW_FULL_ITINERARY: "Se hele rejseplanen",
868
+ SHOW_SERVICES: "Vis ydelser",
865
869
  VIEW_BOOKING: "Se booking",
866
870
  ITINERARY_TITLE: "Din rejseoversigt",
867
871
  DOSSIER_NUMBER: "Sagsnummer",
@@ -911,7 +915,7 @@ var SRP$e = {
911
915
  };
912
916
  var ITINERARY$e = {
913
917
  DAY: "Dag",
914
- NO_ITEMS: "Ingen elementer for denne dag."
918
+ NO_ITEMS: "Ingen aktiviteter valgt for denne dag."
915
919
  };
916
920
  var FORM$e = {
917
921
  LOADING: "Indlæser formular...",
@@ -1014,7 +1018,7 @@ var PRODUCT$d = {
1014
1018
  PER_PERSON_PER_NIGHT: "Pro Person / pro Nacht",
1015
1019
  BOOK_NOW: "Jetzt buchen",
1016
1020
  TO_YOUR_OFFER: "Zu Ihrem Angebot",
1017
- NOT_AVAILABLE: "Nicht verfügbar",
1021
+ NOT_AVAILABLE: "Nicht verfügbar — bitte wählen Sie ein anderes Datum",
1018
1022
  NUMBER_OF_ROOMS: "Anzahl der Zimmer",
1019
1023
  AGE_BY_DEPARTURE_DATE: "Alter der Kinder am Abreisedatum",
1020
1024
  YEAR: "Jahr(e)",
@@ -1311,6 +1315,8 @@ var SRP$d = {
1311
1315
  DEPARTURE_ASC: "Abreisedatum (früheste zuerst)",
1312
1316
  FILTERS: "Filter",
1313
1317
  SHOW_ITINERARY: "Reiseverlauf anzeigen",
1318
+ VIEW_FULL_ITINERARY: "Vollständigen Reiseverlauf ansehen",
1319
+ SHOW_SERVICES: "Leistungen anzeigen",
1314
1320
  VIEW_BOOKING: "Buchung anzeigen",
1315
1321
  ITINERARY_TITLE: "Ihre Reiseübersicht",
1316
1322
  DOSSIER_NUMBER: "Vorgangsnummer",
@@ -1356,7 +1362,7 @@ var SRP$d = {
1356
1362
  };
1357
1363
  var ITINERARY$d = {
1358
1364
  DAY: "Tag",
1359
- NO_ITEMS: "Keine Elemente für diesen Tag."
1365
+ NO_ITEMS: "Keine Aktivitäten für diesen Tag ausgewählt."
1360
1366
  };
1361
1367
  var FORM$d = {
1362
1368
  LOADING: "Formular wird geladen...",
@@ -1459,7 +1465,7 @@ var PRODUCT$c = {
1459
1465
  PER_PERSON_PER_NIGHT: "Per person / per night",
1460
1466
  BOOK_NOW: "Book now",
1461
1467
  TO_YOUR_OFFER: "To your quote",
1462
- NOT_AVAILABLE: "Not available",
1468
+ NOT_AVAILABLE: "Not available — please select a different date",
1463
1469
  NUMBER_OF_ROOMS: "Number of rooms",
1464
1470
  AGE_BY_DEPARTURE_DATE: "Age of children on departure date",
1465
1471
  YEAR: "Year(s)",
@@ -1760,6 +1766,8 @@ var SRP$c = {
1760
1766
  DEPARTURE_ASC: "Departure date (soonest first)",
1761
1767
  FILTERS: "Filters",
1762
1768
  SHOW_ITINERARY: "Show itinerary",
1769
+ VIEW_FULL_ITINERARY: "View full itinerary",
1770
+ SHOW_SERVICES: "Show services",
1763
1771
  VIEW_BOOKING: "View booking",
1764
1772
  ITINERARY_TITLE: "Your trip summary",
1765
1773
  DOSSIER_NUMBER: "File number",
@@ -1805,7 +1813,7 @@ var SRP$c = {
1805
1813
  };
1806
1814
  var ITINERARY$c = {
1807
1815
  DAY: "Day",
1808
- NO_ITEMS: "No items for this day."
1816
+ NO_ITEMS: "No activities selected for this day."
1809
1817
  };
1810
1818
  var FORM$c = {
1811
1819
  LOADING: "Loading form...",
@@ -1908,7 +1916,7 @@ var PRODUCT$b = {
1908
1916
  PER_PERSON_PER_NIGHT: "Por persona / por noche",
1909
1917
  BOOK_NOW: "Reservar ahora",
1910
1918
  TO_YOUR_OFFER: "A su presupuesto",
1911
- NOT_AVAILABLE: "No disponible",
1919
+ NOT_AVAILABLE: "No disponible — seleccione otra fecha",
1912
1920
  NUMBER_OF_ROOMS: "Número de habitaciones",
1913
1921
  AGE_BY_DEPARTURE_DATE: "Edad de los niños en la fecha de salida",
1914
1922
  YEAR: "Año(s)",
@@ -2205,6 +2213,8 @@ var SRP$b = {
2205
2213
  DEPARTURE_ASC: "Fecha de salida (más próxima primero)",
2206
2214
  FILTERS: "Filtros",
2207
2215
  SHOW_ITINERARY: "Mostrar itinerario",
2216
+ VIEW_FULL_ITINERARY: "Ver itinerario completo",
2217
+ SHOW_SERVICES: "Ver servicios",
2208
2218
  VIEW_BOOKING: "Ver reserva",
2209
2219
  ITINERARY_TITLE: "Resumen de tu viaje",
2210
2220
  DOSSIER_NUMBER: "Número de expediente",
@@ -2250,7 +2260,7 @@ var SRP$b = {
2250
2260
  };
2251
2261
  var ITINERARY$b = {
2252
2262
  DAY: "Día",
2253
- NO_ITEMS: "No hay elementos para este día."
2263
+ NO_ITEMS: "No hay actividades seleccionadas para este día."
2254
2264
  };
2255
2265
  var FORM$b = {
2256
2266
  LOADING: "Cargando formulario...",
@@ -2353,7 +2363,7 @@ var PRODUCT$a = {
2353
2363
  PER_PERSON_PER_NIGHT: "Par personne / par nuit",
2354
2364
  BOOK_NOW: "Réserver maintenant",
2355
2365
  TO_YOUR_OFFER: "Vers votre devis",
2356
- NOT_AVAILABLE: "Non disponible",
2366
+ NOT_AVAILABLE: "Non disponible — veuillez sélectionner une autre date",
2357
2367
  NUMBER_OF_ROOMS: "Nombre de chambres",
2358
2368
  AGE_BY_DEPARTURE_DATE: "Âge des enfants à la date de départ",
2359
2369
  YEAR: "An(s)",
@@ -2654,6 +2664,8 @@ var SRP$a = {
2654
2664
  DEPARTURE_ASC: "Date de départ (la plus proche d’abord)",
2655
2665
  FILTERS: "Filtres",
2656
2666
  SHOW_ITINERARY: "Afficher l’itinéraire",
2667
+ VIEW_FULL_ITINERARY: "Voir l'itinéraire complet",
2668
+ SHOW_SERVICES: "Voir les services",
2657
2669
  VIEW_BOOKING: "Voir la réservation",
2658
2670
  ITINERARY_TITLE: "Résumé de votre voyage",
2659
2671
  DOSSIER_NUMBER: "Numéro de dossier",
@@ -2699,7 +2711,7 @@ var SRP$a = {
2699
2711
  };
2700
2712
  var ITINERARY$a = {
2701
2713
  DAY: "Jour",
2702
- NO_ITEMS: "Aucun élément pour ce jour."
2714
+ NO_ITEMS: "Aucune activité sélectionnée pour ce jour."
2703
2715
  };
2704
2716
  var FORM$a = {
2705
2717
  LOADING: "Chargement du formulaire...",
@@ -2802,7 +2814,7 @@ var PRODUCT$9 = {
2802
2814
  PER_PERSON_PER_NIGHT: "Par personne / par nuit",
2803
2815
  BOOK_NOW: "Réservez maintenant",
2804
2816
  TO_YOUR_OFFER: "Vers votre devis",
2805
- NOT_AVAILABLE: "Indisponible",
2817
+ NOT_AVAILABLE: "Indisponible — veuillez sélectionner une autre date",
2806
2818
  NUMBER_OF_ROOMS: "Nombre de chambres",
2807
2819
  AGE_BY_DEPARTURE_DATE: "Âge des enfants à la date de départ",
2808
2820
  YEAR: "An(s)",
@@ -3099,6 +3111,8 @@ var SRP$9 = {
3099
3111
  DEPARTURE_ASC: "Date de départ (la plus proche d’abord)",
3100
3112
  FILTERS: "Filtres",
3101
3113
  SHOW_ITINERARY: "Afficher l’itinéraire",
3114
+ VIEW_FULL_ITINERARY: "Voir l'itinéraire complet",
3115
+ SHOW_SERVICES: "Voir les services",
3102
3116
  VIEW_BOOKING: "Voir la réservation",
3103
3117
  ITINERARY_TITLE: "Résumé de votre voyage",
3104
3118
  DOSSIER_NUMBER: "Numéro de dossier",
@@ -3144,7 +3158,7 @@ var SRP$9 = {
3144
3158
  };
3145
3159
  var ITINERARY$9 = {
3146
3160
  DAY: "Jour",
3147
- NO_ITEMS: "Aucun élément pour ce jour."
3161
+ NO_ITEMS: "Aucune activité sélectionnée pour ce jour."
3148
3162
  };
3149
3163
  var FORM$9 = {
3150
3164
  LOADING: "Chargement du formulaire...",
@@ -3247,7 +3261,7 @@ var PRODUCT$8 = {
3247
3261
  PER_PERSON_PER_NIGHT: "Á mann / á nótt",
3248
3262
  BOOK_NOW: "Panta núna",
3249
3263
  TO_YOUR_OFFER: "Til tilboðsins þíns",
3250
- NOT_AVAILABLE: "Ekki í boði",
3264
+ NOT_AVAILABLE: "Ekki í boði — vinsamlegast veldu aðra dagsetningu",
3251
3265
  NUMBER_OF_ROOMS: "Fjöldi herbergja",
3252
3266
  AGE_BY_DEPARTURE_DATE: "Aldur barna á brottfarardegi",
3253
3267
  YEAR: "ár",
@@ -3544,6 +3558,8 @@ var SRP$8 = {
3544
3558
  DEPARTURE_ASC: "Brottfarardagur (nærst fyrst)",
3545
3559
  FILTERS: "Síur",
3546
3560
  SHOW_ITINERARY: "Sýna ferðaráætlun",
3561
+ VIEW_FULL_ITINERARY: "Skoða alla ferðaáætlunina",
3562
+ SHOW_SERVICES: "Sýna þjónustu",
3547
3563
  VIEW_BOOKING: "Skoða bókun",
3548
3564
  ITINERARY_TITLE: "Yfirlit ferðarinnar",
3549
3565
  DOSSIER_NUMBER: "Skrárnúmer",
@@ -3589,7 +3605,7 @@ var SRP$8 = {
3589
3605
  };
3590
3606
  var ITINERARY$8 = {
3591
3607
  DAY: "Dagur",
3592
- NO_ITEMS: "Engar upplýsingar fyrir þennan dag."
3608
+ NO_ITEMS: "Engin afþreying valin fyrir þennan dag."
3593
3609
  };
3594
3610
  var FORM$8 = {
3595
3611
  LOADING: "Hleður eyðublað...",
@@ -3692,7 +3708,7 @@ var PRODUCT$7 = {
3692
3708
  PER_PERSON_PER_NIGHT: "A persona / a notte",
3693
3709
  BOOK_NOW: "Prenota ora",
3694
3710
  TO_YOUR_OFFER: "Vai al preventivo",
3695
- NOT_AVAILABLE: "Non disponibile",
3711
+ NOT_AVAILABLE: "Non disponibile — seleziona un'altra data",
3696
3712
  NUMBER_OF_ROOMS: "Numero di camere",
3697
3713
  AGE_BY_DEPARTURE_DATE: "Età dei bambini alla data di partenza",
3698
3714
  YEAR: "Anno/i",
@@ -3989,6 +4005,8 @@ var SRP$7 = {
3989
4005
  DEPARTURE_ASC: "Data di partenza (prima la più vicina)",
3990
4006
  FILTERS: "Filtri",
3991
4007
  SHOW_ITINERARY: "Mostra itinerario",
4008
+ VIEW_FULL_ITINERARY: "Vedi l'itinerario completo",
4009
+ SHOW_SERVICES: "Mostra i servizi",
3992
4010
  VIEW_BOOKING: "Visualizza prenotazione",
3993
4011
  ITINERARY_TITLE: "Riepilogo del tuo viaggio",
3994
4012
  DOSSIER_NUMBER: "Numero di pratica",
@@ -4034,7 +4052,7 @@ var SRP$7 = {
4034
4052
  };
4035
4053
  var ITINERARY$7 = {
4036
4054
  DAY: "Giorno",
4037
- NO_ITEMS: "Nessun elemento per questo giorno."
4055
+ NO_ITEMS: "Nessuna attività selezionata per questo giorno."
4038
4056
  };
4039
4057
  var FORM$7 = {
4040
4058
  LOADING: "Caricamento modulo...",
@@ -4137,7 +4155,7 @@ var PRODUCT$6 = {
4137
4155
  PER_PERSON_PER_NIGHT: "Per persoon / per nacht",
4138
4156
  BOOK_NOW: "Boek nu",
4139
4157
  TO_YOUR_OFFER: "Naar uw offerte",
4140
- NOT_AVAILABLE: "Niet beschikbaar",
4158
+ NOT_AVAILABLE: "Niet beschikbaar — kies een andere datum",
4141
4159
  NUMBER_OF_ROOMS: "Aantal kamers",
4142
4160
  AGE_BY_DEPARTURE_DATE: "Leeftijd kinderen op vertrekdatum",
4143
4161
  YEAR: "Jaar",
@@ -4438,6 +4456,8 @@ var SRP$6 = {
4438
4456
  DEPARTURE_ASC: "Vertrekdatum (dichtstbij eerst)",
4439
4457
  FILTERS: "Filters",
4440
4458
  SHOW_ITINERARY: "Toon reisplan",
4459
+ VIEW_FULL_ITINERARY: "Bekijk volledige reisroute",
4460
+ SHOW_SERVICES: "Toon diensten",
4441
4461
  VIEW_BOOKING: "Bekijk boeking",
4442
4462
  ITINERARY_TITLE: "Overzicht van je reis",
4443
4463
  DOSSIER_NUMBER: "Dossiernummer",
@@ -4483,7 +4503,7 @@ var SRP$6 = {
4483
4503
  };
4484
4504
  var ITINERARY$6 = {
4485
4505
  DAY: "Dag",
4486
- NO_ITEMS: "Geen elementen voor deze dag."
4506
+ NO_ITEMS: "Geen activiteiten geselecteerd voor deze dag."
4487
4507
  };
4488
4508
  var FORM$6 = {
4489
4509
  LOADING: "Formulier laden...",
@@ -4586,7 +4606,7 @@ var PRODUCT$5 = {
4586
4606
  PER_PERSON_PER_NIGHT: "Per persoon / per nacht",
4587
4607
  BOOK_NOW: "Nu boeken",
4588
4608
  TO_YOUR_OFFER: "Naar uw offerte",
4589
- NOT_AVAILABLE: "Niet beschikbaar",
4609
+ NOT_AVAILABLE: "Niet beschikbaar — kies een andere datum",
4590
4610
  NUMBER_OF_ROOMS: "Aantal kamers",
4591
4611
  AGE_BY_DEPARTURE_DATE: "Leeftijd van kinderen op vertrekdatum",
4592
4612
  YEAR: "Jaar",
@@ -4883,6 +4903,8 @@ var SRP$5 = {
4883
4903
  DEPARTURE_ASC: "Vertrekdatum (dichtstbij eerst)",
4884
4904
  FILTERS: "Filters",
4885
4905
  SHOW_ITINERARY: "Toon reisplan",
4906
+ VIEW_FULL_ITINERARY: "Bekijk volledige reisroute",
4907
+ SHOW_SERVICES: "Toon diensten",
4886
4908
  VIEW_BOOKING: "Bekijk boeking",
4887
4909
  ITINERARY_TITLE: "Overzicht van je reis",
4888
4910
  DOSSIER_NUMBER: "Dossiernummer",
@@ -4928,7 +4950,7 @@ var SRP$5 = {
4928
4950
  };
4929
4951
  var ITINERARY$5 = {
4930
4952
  DAY: "Dag",
4931
- NO_ITEMS: "Geen elementen voor deze dag."
4953
+ NO_ITEMS: "Geen activiteiten geselecteerd voor deze dag."
4932
4954
  };
4933
4955
  var FORM$5 = {
4934
4956
  LOADING: "Formulier laden...",
@@ -5031,7 +5053,7 @@ var PRODUCT$4 = {
5031
5053
  PER_PERSON_PER_NIGHT: "Per person / per natt",
5032
5054
  BOOK_NOW: "Bestill nå",
5033
5055
  TO_YOUR_OFFER: "Til ditt tilbud",
5034
- NOT_AVAILABLE: "Ikke tilgjengelig",
5056
+ NOT_AVAILABLE: "Ikke tilgjengelig — velg en annen dato",
5035
5057
  NUMBER_OF_ROOMS: "Antall rom",
5036
5058
  AGE_BY_DEPARTURE_DATE: "Barnas alder på avreisedato",
5037
5059
  YEAR: "År",
@@ -5328,6 +5350,8 @@ var SRP$4 = {
5328
5350
  DEPARTURE_ASC: "Avreisedato (nærmeste først)",
5329
5351
  FILTERS: "Filtre",
5330
5352
  SHOW_ITINERARY: "Vis reiserute",
5353
+ VIEW_FULL_ITINERARY: "Se hele reiseruten",
5354
+ SHOW_SERVICES: "Vis tjenester",
5331
5355
  VIEW_BOOKING: "Se bestilling",
5332
5356
  ITINERARY_TITLE: "Din reisemåloversikt",
5333
5357
  DOSSIER_NUMBER: "Saksnummer",
@@ -5373,7 +5397,7 @@ var SRP$4 = {
5373
5397
  };
5374
5398
  var ITINERARY$4 = {
5375
5399
  DAY: "Dag",
5376
- NO_ITEMS: "Ingen elementer for denne dagen."
5400
+ NO_ITEMS: "Ingen aktiviteter valgt for denne dagen."
5377
5401
  };
5378
5402
  var FORM$4 = {
5379
5403
  LOADING: "Laster inn skjema...",
@@ -5476,7 +5500,7 @@ var PRODUCT$3 = {
5476
5500
  PER_PERSON_PER_NIGHT: "Za osobę / za noc",
5477
5501
  BOOK_NOW: "Zarezerwuj teraz",
5478
5502
  TO_YOUR_OFFER: "Do oferty",
5479
- NOT_AVAILABLE: "Niedostępne",
5503
+ NOT_AVAILABLE: "Niedostępne — wybierz inną datę",
5480
5504
  NUMBER_OF_ROOMS: "Liczba pokoi",
5481
5505
  AGE_BY_DEPARTURE_DATE: "Wiek dzieci w dniu wyjazdu",
5482
5506
  YEAR: "Rok(lata)",
@@ -5773,6 +5797,8 @@ var SRP$3 = {
5773
5797
  DEPARTURE_ASC: "Data wyjazdu (najbliższa najpierw)",
5774
5798
  FILTERS: "Filtry",
5775
5799
  SHOW_ITINERARY: "Pokaż plan podróży",
5800
+ VIEW_FULL_ITINERARY: "Zobacz pełny plan podróży",
5801
+ SHOW_SERVICES: "Pokaż usługi",
5776
5802
  VIEW_BOOKING: "Zobacz rezerwację",
5777
5803
  ITINERARY_TITLE: "Podsumowanie Twojej podróży",
5778
5804
  DOSSIER_NUMBER: "Numer pliku",
@@ -5818,7 +5844,7 @@ var SRP$3 = {
5818
5844
  };
5819
5845
  var ITINERARY$3 = {
5820
5846
  DAY: "Dzień",
5821
- NO_ITEMS: "Brak elementów dla tego dnia."
5847
+ NO_ITEMS: "Nie wybrano atrakcji na ten dzień."
5822
5848
  };
5823
5849
  var FORM$3 = {
5824
5850
  LOADING: "Ładowanie formularza...",
@@ -5921,7 +5947,7 @@ var PRODUCT$2 = {
5921
5947
  PER_PERSON_PER_NIGHT: "Por pessoa / por noite",
5922
5948
  BOOK_NOW: "Reservar agora",
5923
5949
  TO_YOUR_OFFER: "Ir para o orçamento",
5924
- NOT_AVAILABLE: "Indisponível",
5950
+ NOT_AVAILABLE: "Indisponível — selecione outra data",
5925
5951
  NUMBER_OF_ROOMS: "Número de quartos",
5926
5952
  AGE_BY_DEPARTURE_DATE: "Idade das crianças à data de partida",
5927
5953
  YEAR: "Ano(s)",
@@ -6218,6 +6244,8 @@ var SRP$2 = {
6218
6244
  DEPARTURE_ASC: "Data de partida (mais próxima primeiro)",
6219
6245
  FILTERS: "Filtros",
6220
6246
  SHOW_ITINERARY: "Mostrar itinerário",
6247
+ VIEW_FULL_ITINERARY: "Ver itinerário completo",
6248
+ SHOW_SERVICES: "Ver serviços",
6221
6249
  VIEW_BOOKING: "Ver reserva",
6222
6250
  ITINERARY_TITLE: "Resumo da sua viagem",
6223
6251
  DOSSIER_NUMBER: "Número do processo",
@@ -6263,7 +6291,7 @@ var SRP$2 = {
6263
6291
  };
6264
6292
  var ITINERARY$2 = {
6265
6293
  DAY: "Dia",
6266
- NO_ITEMS: "Nenhum item para este dia."
6294
+ NO_ITEMS: "Nenhuma atividade selecionada para este dia."
6267
6295
  };
6268
6296
  var FORM$2 = {
6269
6297
  LOADING: "A carregar formulário...",
@@ -6366,7 +6394,7 @@ var PRODUCT$1 = {
6366
6394
  PER_PERSON_PER_NIGHT: "Per person / per natt",
6367
6395
  BOOK_NOW: "Boka nu",
6368
6396
  TO_YOUR_OFFER: "Till din offert",
6369
- NOT_AVAILABLE: "Ej tillgänglig",
6397
+ NOT_AVAILABLE: "Ej tillgänglig — välj ett annat datum",
6370
6398
  NUMBER_OF_ROOMS: "Antal rum",
6371
6399
  AGE_BY_DEPARTURE_DATE: "Barnens ålder vid avresedatum",
6372
6400
  YEAR: "År",
@@ -6663,6 +6691,8 @@ var SRP$1 = {
6663
6691
  DEPARTURE_ASC: "Avresedatum (närmast först)",
6664
6692
  FILTERS: "Filter",
6665
6693
  SHOW_ITINERARY: "Visa resplan",
6694
+ VIEW_FULL_ITINERARY: "Visa hela resplanen",
6695
+ SHOW_SERVICES: "Visa tjänster",
6666
6696
  VIEW_BOOKING: "Visa bokning",
6667
6697
  ITINERARY_TITLE: "Din resesammanfattning",
6668
6698
  DOSSIER_NUMBER: "Filnummer",
@@ -6708,7 +6738,7 @@ var SRP$1 = {
6708
6738
  };
6709
6739
  var ITINERARY$1 = {
6710
6740
  DAY: "Dag",
6711
- NO_ITEMS: "Inga element för denna dag."
6741
+ NO_ITEMS: "Inga aktiviteter valda för denna dag."
6712
6742
  };
6713
6743
  var FORM$1 = {
6714
6744
  LOADING: "Laddar formulär...",
@@ -6811,7 +6841,7 @@ var PRODUCT = {
6811
6841
  PER_PERSON_PER_NIGHT: "1名・1泊あたり",
6812
6842
  BOOK_NOW: "今すぐ予約",
6813
6843
  TO_YOUR_OFFER: "見積もりへ",
6814
- NOT_AVAILABLE: "利用不可",
6844
+ NOT_AVAILABLE: "利用不可 — 別の日付をお選びください",
6815
6845
  NUMBER_OF_ROOMS: "客室数",
6816
6846
  AGE_BY_DEPARTURE_DATE: "出発日時点での子供の年齢",
6817
6847
  YEAR: "歳",
@@ -7108,6 +7138,8 @@ var SRP = {
7108
7138
  DEPARTURE_ASC: "出発日(早い順)",
7109
7139
  FILTERS: "フィルター",
7110
7140
  SHOW_ITINERARY: "旅程を表示",
7141
+ VIEW_FULL_ITINERARY: "旅程の詳細を見る",
7142
+ SHOW_SERVICES: "サービスを表示",
7111
7143
  VIEW_BOOKING: "予約を見る",
7112
7144
  ITINERARY_TITLE: "あなたの旅行概要",
7113
7145
  DOSSIER_NUMBER: "ファイル番号",
@@ -7153,7 +7185,7 @@ var SRP = {
7153
7185
  };
7154
7186
  var ITINERARY = {
7155
7187
  DAY: "日",
7156
- NO_ITEMS: "この日のアイテムはありません。"
7188
+ NO_ITEMS: "この日に選択されたアクティビティはありません。"
7157
7189
  };
7158
7190
  var FORM = {
7159
7191
  LOADING: "フォームを読み込んでいます...",
@@ -7817,6 +7849,33 @@ var TrajectNodeType = {
7817
7849
  subroute: 3,
7818
7850
  };
7819
7851
 
7852
+ var DurationType = {
7853
+ hours: 0,
7854
+ days: 1,
7855
+ nights: 2,
7856
+ minutes: 3,
7857
+ };
7858
+
7859
+ var RouteTransportType = {
7860
+ none: 0,
7861
+ privateTransport: 1,
7862
+ publicTransport: 2,
7863
+ rentalCar: 3,
7864
+ bus: 4,
7865
+ camper: 5,
7866
+ car: 6,
7867
+ charter: 7,
7868
+ cruise: 8,
7869
+ ferry: 9,
7870
+ flight: 10,
7871
+ taxi: 11,
7872
+ train: 12,
7873
+ transfer: 13,
7874
+ rocket: 14,
7875
+ walking: 15,
7876
+ cycling: 16,
7877
+ };
7878
+
7820
7879
  /******************************************************************************
7821
7880
  Copyright (c) Microsoft Corporation.
7822
7881
 
@@ -15168,6 +15227,7 @@ var submitForm = function (config, id, request, signal) {
15168
15227
  exports.AllotmentType = AllotmentType;
15169
15228
  exports.DataType = DataType;
15170
15229
  exports.DossierType = DossierType;
15230
+ exports.DurationType = DurationType;
15171
15231
  exports.EntryLineFlag = EntryLineFlag;
15172
15232
  exports.EntryLineStatus = EntryLineStatus;
15173
15233
  exports.ExportStatus = ExportStatus;
@@ -15180,6 +15240,7 @@ exports.PaymentType = PaymentType;
15180
15240
  exports.PriceChartType = PriceChartType;
15181
15241
  exports.RequirementType = RequirementType;
15182
15242
  exports.RoomType = RoomType;
15243
+ exports.RouteTransportType = RouteTransportType;
15183
15244
  exports.SaleType = SaleType;
15184
15245
  exports.ServiceTokenError = ServiceTokenError;
15185
15246
  exports.ServiceType = ServiceType;
@@ -16657,6 +16718,16 @@ const Icon = ({ name, className, title, width, height, fill }) => {
16657
16718
  React__default["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." }),
16658
16719
  title && React__default["default"].createElement("title", null, title),
16659
16720
  React__default["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" })));
16721
+ case 'ui-cycling':
16722
+ return (React__default["default"].createElement("svg", { className: ['icon', `icon--${name}`, className].filter((className) => !lodash.isEmpty(className)).join(' '), width: width, height: height, viewBox: "0 0 640 512", fill: fill ?? 'currentColor' },
16723
+ React__default["default"].createElement(HTMLComment, { text: "!Font Awesome Free v5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc." }),
16724
+ title && React__default["default"].createElement("title", null, title),
16725
+ React__default["default"].createElement("path", { d: "M512.509 192.001c-16.373-.064-32.03 2.955-46.436 8.495l-77.68-125.153A24 24 0 0 0 368.001 64h-64c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h50.649l14.896 24H256.002v-16c0-8.837-7.163-16-16-16h-87.459c-13.441 0-24.777 10.999-24.536 24.437.232 13.044 10.876 23.563 23.995 23.563h48.726l-29.417 47.52c-13.433-4.83-27.904-7.483-42.992-7.52C58.094 191.83.412 249.012.002 319.236-.413 390.279 57.055 448 128.002 448c59.642 0 109.758-40.793 123.967-96h52.033a24 24 0 0 0 20.406-11.367L410.37 201.77l14.938 24.067c-25.455 23.448-41.385 57.081-41.307 94.437.145 68.833 57.899 127.051 126.729 127.719 70.606.685 128.181-55.803 129.255-125.996 1.086-70.941-56.526-129.72-127.476-129.996zM186.75 265.772c9.727 10.529 16.673 23.661 19.642 38.228h-43.306l23.664-38.228zM128.002 400c-44.112 0-80-35.888-80-80s35.888-80 80-80c5.869 0 11.586.653 17.099 1.859l-45.505 73.509C89.715 331.327 101.213 352 120.002 352h81.3c-12.37 28.225-40.562 48-73.3 48zm162.63-96h-35.624c-3.96-31.756-19.556-59.894-42.383-80.026L237.371 184h127.547l-74.286 120zm217.057 95.886c-41.036-2.165-74.049-35.692-75.627-76.755-.812-21.121 6.633-40.518 19.335-55.263l44.433 71.586c4.66 7.508 14.524 9.816 22.032 5.156l13.594-8.437c7.508-4.66 9.817-14.524 5.156-22.032l-44.468-71.643a79.901 79.901 0 0 1 19.858-2.497c44.112 0 80 35.888 80 80-.001 45.54-38.252 82.316-84.313 79.885z", fill: "currentColor" })));
16726
+ case 'ui-walking':
16727
+ return (React__default["default"].createElement("svg", { className: ['icon', `icon--${name}`, className].filter((className) => !lodash.isEmpty(className)).join(' '), width: width, height: height, viewBox: "0 0 320 512", fill: fill ?? 'currentColor' },
16728
+ React__default["default"].createElement(HTMLComment, { text: "!Font Awesome Free v5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc." }),
16729
+ title && React__default["default"].createElement("title", null, title),
16730
+ React__default["default"].createElement("path", { d: "M208 96c26.5 0 48-21.5 48-48S234.5 0 208 0s-48 21.5-48 48 21.5 48 48 48zm94.5 149.1l-23.3-11.8-9.7-29.4c-14.7-44.6-55.7-75.8-102.2-75.9-36-.1-55.9 10.1-93.3 25.2-21.6 8.7-39.3 25.2-49.7 46.2L17.6 213c-7.8 15.8-1.5 35 14.2 42.9 15.6 7.9 34.6 1.5 42.5-14.3L81 228c3.5-7 9.3-12.5 16.5-15.4l26.8-10.8-15.2 60.7c-5.2 20.8.4 42.9 14.9 58.8l59.9 65.4c7.2 7.9 12.3 17.4 14.9 27.7l18.3 73.3c4.3 17.1 21.7 27.6 38.8 23.3 17.1-4.3 27.6-21.7 23.3-38.8l-22.2-89c-2.6-10.3-7.7-19.9-14.9-27.7l-45.5-49.7 17.2-68.7 5.5 16.5c5.3 16.1 16.7 29.4 31.7 37l23.3 11.8c15.6 7.9 34.6 1.5 42.5-14.3 7.7-15.7 1.4-35.1-14.3-43zM73.6 385.8c-3.2 8.1-8 15.4-14.2 21.5l-50 50.1c-12.5 12.5-12.5 32.8 0 45.3s32.7 12.5 45.2 0l59.4-59.4c6.1-6.1 10.9-13.4 14.2-21.5l13.5-33.8c-55.3-60.3-38.7-41.8-47.4-53.7l-20.7 51.5z", fill: "currentColor" })));
16660
16731
  case 'ui-bus':
16661
16732
  return (React__default["default"].createElement("svg", { className: ['icon', `icon--${name}`, className].filter((className) => !lodash.isEmpty(className)).join(' '), width: width, height: height, viewBox: "0 0 512 512", fill: fill ?? 'currentColor' },
16662
16733
  title && React__default["default"].createElement("title", null, title),
@@ -16970,10 +17041,10 @@ const DateRangePicker$1 = (props) => {
16970
17041
  month: dateFns.getMonth(new Date())
16971
17042
  });
16972
17043
  const [isWaitingForToDate, setWaitingForToDate] = React.useState(false);
16973
- const { searchType = 0 } = React.useContext(SettingsContext$1);
17044
+ const { searchType = 0, allowSingleDayDateSelect = false } = React.useContext(SettingsContext$1);
16974
17045
  const handleDayClick = (day) => {
16975
17046
  const { onSelectionChange } = props;
16976
- if (isWaitingForToDate && !lodash.isNil(fromDate) && dateFns.isAfter(day, fromDate)) {
17047
+ if (isWaitingForToDate && !lodash.isNil(fromDate) && (dateFns.isAfter(day, fromDate) || (allowSingleDayDateSelect && dateFns.isSameDay(day, fromDate)))) {
16977
17048
  if (searchType === 1) {
16978
17049
  // Only allow selecting the exact toDate
16979
17050
  const expectedToDate = props.toDateByFromDate?.(fromDate);
@@ -17014,7 +17085,7 @@ const DateRangePicker$1 = (props) => {
17014
17085
  }
17015
17086
  };
17016
17087
  const handleDayMouseOver = (day) => {
17017
- if (isWaitingForToDate && (lodash.isNil(fromDate) || dateFns.isEqual(day, fromDate) || dateFns.isAfter(day, fromDate))) {
17088
+ if (isWaitingForToDate && (lodash.isNil(fromDate) || dateFns.isSameDay(day, fromDate) || dateFns.isAfter(day, fromDate))) {
17018
17089
  setToDate(day);
17019
17090
  }
17020
17091
  };
@@ -21782,6 +21853,7 @@ const OptionRoom = ({ packageRoom, pax, optionPax, onRoomChange, includedService
21782
21853
 
21783
21854
  function useOfferPrinter({ bookingPackage, getPax, tagIds = [], printActionId = null, onPrinted }) {
21784
21855
  const settings = React.useContext(SettingsContext);
21856
+ const apiSettings = reactRedux.useSelector(selectApiSettings);
21785
21857
  if (!settings)
21786
21858
  throw new Error('useOfferPrinter must be used inside <BookingWizard>');
21787
21859
  const { language, officeId } = settings;
@@ -21810,9 +21882,9 @@ function useOfferPrinter({ bookingPackage, getPax, tagIds = [], printActionId =
21810
21882
  customerRequests: []
21811
21883
  }
21812
21884
  };
21813
- const cfg = buildTideClientConfig();
21885
+ const cfg = buildTideClientConfig(apiSettings);
21814
21886
  return build.book(cfg, request, undefined, language);
21815
- }, [agentId, bookingPackage, getPax, language, officeId, tagIds]);
21887
+ }, [agentId, apiSettings, bookingPackage, getPax, language, officeId, tagIds]);
21816
21888
  const languageData = [
21817
21889
  { code: 'nl-BE', tideId: 1 },
21818
21890
  { code: 'fr-BE', tideId: 2 },
@@ -21822,7 +21894,7 @@ function useOfferPrinter({ bookingPackage, getPax, tagIds = [], printActionId =
21822
21894
  return languageData.find((l) => l.code === code)?.tideId || 1;
21823
21895
  }
21824
21896
  const printOffer = React.useCallback(async (offer) => {
21825
- const cfg = buildTideClientConfig();
21897
+ const cfg = buildTideClientConfig(apiSettings);
21826
21898
  const req = {
21827
21899
  id: printActionId ?? 0,
21828
21900
  dossierNumber: offer.dossierNumber ?? offer.number,
@@ -21833,7 +21905,7 @@ function useOfferPrinter({ bookingPackage, getPax, tagIds = [], printActionId =
21833
21905
  const url = URL.createObjectURL(new Blob([buf], { type: 'application/pdf' }));
21834
21906
  onPrinted?.(url);
21835
21907
  window.open(url);
21836
- }, [language, onPrinted]);
21908
+ }, [apiSettings, language, onPrinted, printActionId]);
21837
21909
  const handlePrint = React.useCallback(async () => {
21838
21910
  try {
21839
21911
  setStage('creating');
@@ -28033,8 +28105,97 @@ const getServiceTypeBadgeModifier = (serviceType) => {
28033
28105
  return '';
28034
28106
  }
28035
28107
  };
28108
+ // DurationType, as the SDK numbers it.
28109
+ const DURATION_HOURS = 0;
28110
+ const DURATION_DAYS = 1;
28111
+ const DURATION_NIGHTS = 2;
28112
+ const DURATION_MINUTES = 3;
28113
+ /**
28114
+ * How long a node takes, in the same shape the flight legs are written in — an hour count only
28115
+ * once there is one, so a short drive reads as plain minutes.
28116
+ */
28117
+ const getTrajectNodeDuration = (node) => {
28118
+ const minutes = toMinutes(node);
28119
+ if (!minutes)
28120
+ return '';
28121
+ const hours = Math.floor(minutes / 60);
28122
+ const rest = minutes % 60;
28123
+ return hours ? `${hours}h ${rest.toString().padStart(2, '0')}m` : `${rest} min`;
28124
+ };
28125
+ const toMinutes = (node) => {
28126
+ const duration = node.duration ?? 0;
28127
+ if (duration <= 0)
28128
+ return 0;
28129
+ switch (node.durationType) {
28130
+ case DURATION_MINUTES:
28131
+ return duration;
28132
+ case DURATION_HOURS:
28133
+ return duration * 60;
28134
+ case DURATION_DAYS:
28135
+ case DURATION_NIGHTS:
28136
+ return duration * 24 * 60;
28137
+ default:
28138
+ return 0;
28139
+ }
28140
+ };
28141
+ // RouteTransportType, as the SDK numbers it. It says how a leg is travelled, which is not the
28142
+ // same question as what was sold: cycling and walking have no service type of their own.
28143
+ const TRANSPORT_PRIVATE = 1;
28144
+ const TRANSPORT_PUBLIC = 2;
28145
+ const TRANSPORT_RENTAL_CAR = 3;
28146
+ const TRANSPORT_BUS = 4;
28147
+ const TRANSPORT_CAMPER = 5;
28148
+ const TRANSPORT_CAR = 6;
28149
+ const TRANSPORT_CHARTER = 7;
28150
+ const TRANSPORT_CRUISE = 8;
28151
+ const TRANSPORT_FERRY = 9;
28152
+ const TRANSPORT_FLIGHT = 10;
28153
+ const TRANSPORT_TAXI = 11;
28154
+ const TRANSPORT_TRAIN = 12;
28155
+ const TRANSPORT_TRANSFER = 13;
28156
+ const TRANSPORT_WALKING = 15;
28157
+ const TRANSPORT_CYCLING = 16;
28158
+ /** Icon per way of travelling, where the route records one. */
28159
+ const getTransportTypeIcon = (transportType) => {
28160
+ switch (transportType) {
28161
+ case TRANSPORT_WALKING:
28162
+ return 'ui-walking';
28163
+ case TRANSPORT_CYCLING:
28164
+ return 'ui-cycling';
28165
+ case TRANSPORT_PRIVATE:
28166
+ case TRANSPORT_RENTAL_CAR:
28167
+ case TRANSPORT_CAMPER:
28168
+ case TRANSPORT_CAR:
28169
+ return 'ui-car';
28170
+ case TRANSPORT_TAXI:
28171
+ case TRANSPORT_TRANSFER:
28172
+ return 'ui-transfer';
28173
+ case TRANSPORT_PUBLIC:
28174
+ case TRANSPORT_BUS:
28175
+ return 'ui-bus';
28176
+ case TRANSPORT_TRAIN:
28177
+ return 'ui-train';
28178
+ case TRANSPORT_CRUISE:
28179
+ case TRANSPORT_FERRY:
28180
+ return 'ui-ship';
28181
+ case TRANSPORT_FLIGHT:
28182
+ case TRANSPORT_CHARTER:
28183
+ return 'ui-plane';
28184
+ default:
28185
+ return null;
28186
+ }
28187
+ };
28036
28188
  const POI_TRAJECT_NODE_TYPE = 2;
28037
- const getTrajectNodeIcon = (node) => node.trajectNodeType === POI_TRAJECT_NODE_TYPE ? 'ui-location' : getServiceTypeIcon(node.serviceType);
28189
+ /**
28190
+ * A point of interest is a place on the map rather than a service, so it gets a marker. Anything
28191
+ * else goes by how it is travelled where the route says so — a leg on foot or by bike is sold as
28192
+ * nothing, and its service type falls back to a transfer — and by what it is where it does not.
28193
+ */
28194
+ const getTrajectNodeIcon = (node) => {
28195
+ if (node.trajectNodeType === POI_TRAJECT_NODE_TYPE)
28196
+ return 'ui-location';
28197
+ return getTransportTypeIcon(node.transportType) ?? getServiceTypeIcon(node.serviceType);
28198
+ };
28038
28199
  const getTrajectNodeBadgeModifier = (node) => node.trajectNodeType === POI_TRAJECT_NODE_TYPE ? 'poi' : getServiceTypeBadgeModifier(node.serviceType);
28039
28200
 
28040
28201
  const REGULAR_TRAJECT_NODE_TYPE = 0;
@@ -28101,8 +28262,6 @@ const buildTrajectNodeRequest = ({ node, line }, context, productCode, destinati
28101
28262
  language: context.language,
28102
28263
  serviceType: node.serviceType,
28103
28264
  fromDate: toDateOnlyString(line.from),
28104
- // An excursion happens on a day rather than over a span. The traject gives its line an end a day
28105
- // out, the way a night is counted, which asks the search for a window it does not have.
28106
28265
  toDate: toDateOnlyString(node.serviceType === EXCURSION_SERVICE_TYPE ? line.from : line.to),
28107
28266
  destination: destination ?? buildDestination(line, node),
28108
28267
  productCode,
@@ -28473,6 +28632,8 @@ const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
28473
28632
  trajectNodeType: REGULAR_TRAJECT_NODE_TYPE,
28474
28633
  requirementType: 0,
28475
28634
  contentSource: 0,
28635
+ duration: 0,
28636
+ durationType: 0,
28476
28637
  alternatives: [],
28477
28638
  from: line.from,
28478
28639
  to: line.to
@@ -28506,6 +28667,8 @@ const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
28506
28667
  React__default["default"].createElement("p", null, dateFns.format(new Date(value), 'MMM'))));
28507
28668
  const renderConnectingNode = ({ node }) => {
28508
28669
  const distance = node.distanceInKm ? `${Math.round(node.distanceInKm)} km` : '';
28670
+ // How long the hop takes and how far it is, the way the traject editor puts them.
28671
+ const journey = [getTrajectNodeDuration(node), distance].filter(Boolean).join(' · ');
28509
28672
  return (React__default["default"].createElement("div", { className: "search__filter__itinerary__transport", key: `connect-${node.nodeId}` },
28510
28673
  React__default["default"].createElement("div", { className: "search__filter__itinerary__transport-timeline" },
28511
28674
  React__default["default"].createElement("div", { className: "search__filter__itinerary__transport-timeline-line" })),
@@ -28514,8 +28677,8 @@ const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
28514
28677
  React__default["default"].createElement("div", { className: badgeClass('transport', getTrajectNodeBadgeModifier(node)) },
28515
28678
  React__default["default"].createElement(Icon, { name: getTrajectNodeIcon(node), height: 15 })),
28516
28679
  React__default["default"].createElement("div", { className: "search__filter__itinerary__transport-details" },
28517
- React__default["default"].createElement("h6", null, node.name || distance),
28518
- !!node.name && !!distance && React__default["default"].createElement("p", { className: "search__filter__itinerary__transport-details-time" }, distance)))));
28680
+ React__default["default"].createElement("h6", null, node.name || journey),
28681
+ !!node.name && !!journey && React__default["default"].createElement("p", { className: "search__filter__itinerary__transport-details-time" }, journey)))));
28519
28682
  };
28520
28683
  const renderOvernight = (item, index) => {
28521
28684
  const { dayOrder } = item.node;
@@ -28659,7 +28822,7 @@ const getServiceTypePriority = (serviceType) => {
28659
28822
  const Itinerary = ({ isOpen, handleSetIsOpen, isLoading, onEditAccommodation }) => {
28660
28823
  const context = React.useContext(SearchResultsConfigurationContext);
28661
28824
  const translations = getTranslations(context?.languageCode ?? 'en-GB');
28662
- const { editablePackagingEntry, priceDetails } = reactRedux.useSelector((state) => state.searchResults);
28825
+ const { editablePackagingEntry, priceDetails, trajectItineraryView } = reactRedux.useSelector((state) => state.searchResults);
28663
28826
  const dispatch = reactRedux.useDispatch();
28664
28827
  const packagingEntry = editablePackagingEntry ?? context?.packagingEntry;
28665
28828
  const sortedLines = React.useMemo(() => {
@@ -28702,6 +28865,11 @@ const Itinerary = ({ isOpen, handleSetIsOpen, isLoading, onEditAccommodation })
28702
28865
  const handleConfirm = () => {
28703
28866
  dispatch(setBookPackagingEntry(true));
28704
28867
  };
28868
+ const handleTrajectView = (itinerary) => {
28869
+ dispatch(setTrajectItineraryView(itinerary));
28870
+ if (typeof window !== 'undefined')
28871
+ window.scrollTo(0, 0);
28872
+ };
28705
28873
  return (React__default["default"].createElement("div", { className: `search__filters--modal ${isOpen ? 'is-open' : ''}` },
28706
28874
  React__default["default"].createElement("div", { className: "search__filters--background", onClick: handleSetIsOpen }),
28707
28875
  React__default["default"].createElement("button", { className: "search__filters--close", onClick: handleSetIsOpen },
@@ -28729,7 +28897,8 @@ const Itinerary = ({ isOpen, handleSetIsOpen, isLoading, onEditAccommodation })
28729
28897
  " ",
28730
28898
  translations.SRP.TOTAL,
28731
28899
  ")"))),
28732
- React__default["default"].createElement("button", { className: "cta", onClick: handleConfirm }, translations.QSM.CONFIRM)))),
28900
+ React__default["default"].createElement("button", { className: "cta", onClick: handleConfirm }, translations.QSM.CONFIRM),
28901
+ !!context?.trajectEntry && (React__default["default"].createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleTrajectView(!trajectItineraryView) }, trajectItineraryView ? translations.SRP.SHOW_SERVICES : translations.SRP.VIEW_FULL_ITINERARY))))),
28733
28902
  React__default["default"].createElement("div", { className: "search__filter__itinerary" },
28734
28903
  React__default["default"].createElement("p", null, translations.SRP.DAY_BY_DAY),
28735
28904
  firstEntryLine && (React__default["default"].createElement("div", { className: "search__filter__itinerary__country" },
@@ -31012,7 +31181,7 @@ const Filters = ({ initialFilters, filters, isOpen, handleSetIsOpen, isLoading,
31012
31181
  const max = filter.max ?? 100;
31013
31182
  const selectedMin = filter.selectedMin ?? min;
31014
31183
  const selectedMax = filter.selectedMax ?? max;
31015
- return (React__default["default"].createElement(MultiRangeFilter, { min: min, max: max, selectedMin: selectedMin, selectedMax: selectedMax, valueFormatter: (value) => `${value}`, onChange: (newMin, newMax) => {
31184
+ return (React__default["default"].createElement(MultiRangeFilter, { min: min, max: max, selectedMin: selectedMin, selectedMax: selectedMax, valueFormatter: (value) => (filter.property === 'price' ? value.toFixed(2).replace('.', ',') : `${value}`), onChange: (newMin, newMax) => {
31016
31185
  handleSliderChange(filter, newMin, newMax);
31017
31186
  } }));
31018
31187
  })(),
@@ -31715,7 +31884,7 @@ const FlyIn = ({ srpType, isOpen, setIsOpen, className = '', onPanelRef, details
31715
31884
  dispatch(setBookPackagingEntry(true));
31716
31885
  }
31717
31886
  };
31718
- return (React__default["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' : ''}
31887
+ return (React__default["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' : ''}
31719
31888
  ${flyInType === 'flight-outward-results' || flyInType === 'flight-return-results' || flyInType === 'traject-flight-results' ? 'flyin--flight' : ''}` },
31720
31889
  React__default["default"].createElement("div", { className: `flyin__panel ${isOpen ? 'flyin__panel--active' : ''}`, ref: panelRef },
31721
31890
  React__default["default"].createElement("div", { className: "flyin__content" },
@@ -32504,7 +32673,7 @@ const FlightFilters = ({ isOpen, handleSetIsOpen, isLoading }) => {
32504
32673
  !lodash.isEmpty(priceRangeValues) &&
32505
32674
  (() => {
32506
32675
  return (React__default["default"].createElement("div", { className: "search__filter-rows" },
32507
- React__default["default"].createElement(MultiRangeFilter, { min: minPrice, max: maxPrice, selectedMin: lodash.first(priceRangeValues) ?? minPrice, selectedMax: lodash.last(priceRangeValues) ?? maxPrice, valueFormatter: (value) => `€${value}`, onChange: (newMin, newMax) => {
32676
+ React__default["default"].createElement(MultiRangeFilter, { min: minPrice, max: maxPrice, selectedMin: lodash.first(priceRangeValues) ?? minPrice, selectedMax: lodash.last(priceRangeValues) ?? maxPrice, valueFormatter: (value) => `€${value.toFixed(2).replace('.', ',')}`, onChange: (newMin, newMax) => {
32508
32677
  handlePriceSliderChange([newMin, newMax]);
32509
32678
  } })));
32510
32679
  })()))))));
@@ -33182,6 +33351,27 @@ const getRequestRoomsFromPackagingSegments = (entry, segments) => {
33182
33351
  }));
33183
33352
  };
33184
33353
 
33354
+ /**
33355
+ * The entry to send to the backend, as opposed to the one the page works with.
33356
+ *
33357
+ * They differ only for a traject: the page keeps the line guids the traject was rendered with,
33358
+ * because that is what joins its nodes to its lines, while pricing and booking need the guids the
33359
+ * searches cached their lines under. Anything else passes through untouched, so this can be used
33360
+ * wherever the entry leaves the component without checking which flow is running.
33361
+ */
33362
+ const useBookableEntry = () => {
33363
+ const context = React.useContext(SearchResultsConfigurationContext);
33364
+ const { editablePackagingEntry, trajectNodeAvailability, trajectFlightAvailability } = reactRedux.useSelector((state) => state.searchResults);
33365
+ const trajectEntry = context?.trajectEntry;
33366
+ return React.useMemo(() => {
33367
+ if (!editablePackagingEntry)
33368
+ return null;
33369
+ if (!trajectEntry)
33370
+ return editablePackagingEntry;
33371
+ return withCachedEntryLineGuids(editablePackagingEntry, trajectEntry, trajectNodeAvailability, trajectFlightAvailability);
33372
+ }, [editablePackagingEntry, trajectEntry, trajectNodeAvailability, trajectFlightAvailability]);
33373
+ };
33374
+
33185
33375
  const escapeHtml = (value) => {
33186
33376
  if (!value)
33187
33377
  return '';
@@ -33240,12 +33430,62 @@ const findAccommodationForDay = (nodes, currentDay) => {
33240
33430
  }
33241
33431
  return null;
33242
33432
  };
33243
- const buildItineraryHtml = (itinerary, translations) => {
33433
+ const formatTime = (time) => (time ? time.slice(0, 5) : '');
33434
+ /**
33435
+ * Whether generated content actually shows something.
33436
+ *
33437
+ * A content view whose data is missing still returns its wrapper markup, or the whitespace left by
33438
+ * a guard around its body — markup that renders as a blank gap. Only text or an image counts as
33439
+ * something the traveller can read.
33440
+ */
33441
+ const hasVisibleContent = (contents) => {
33442
+ if (!contents)
33443
+ return false;
33444
+ if (/<(img|svg|picture|video|iframe)\b/i.test(contents))
33445
+ return true;
33446
+ return (contents
33447
+ .replace(/<[^>]*>/g, ' ')
33448
+ .replace(/&nbsp;/gi, ' ')
33449
+ .trim().length > 0);
33450
+ };
33451
+ /** The legs of a flight, as the entry line records them. */
33452
+ const buildFlightHtml = (line) => {
33453
+ const flightLines = line.flightInformation?.flightLines ?? [];
33454
+ if (!flightLines.length)
33455
+ return '';
33456
+ const legs = flightLines
33457
+ .map((leg) => {
33458
+ const from = escapeHtml(leg.departureAirportDescription || leg.departureAirportCode);
33459
+ const to = escapeHtml(leg.arrivalAirportDescription || leg.arrivalAirportCode);
33460
+ const carrier = escapeHtml([leg.airlineDescription, leg.flightNumber].filter(Boolean).join(' '));
33461
+ return `<li>${from} ${formatTime(leg.departureTime)} &rarr; ${to} ${formatTime(leg.arrivalTime)}${carrier ? ` &middot; ${carrier}` : ''}</li>`;
33462
+ })
33463
+ .join('');
33464
+ return `<ul class="itinerary-item__legs">${legs}</ul>`;
33465
+ };
33466
+ /**
33467
+ * What to show for an item the generator returned no content for.
33468
+ *
33469
+ * An item comes back with a title and a template but an empty body whenever its template has no
33470
+ * content view of its own — flights, today. Rendering that empty body leaves a blank where a
33471
+ * service should be, so what the entry already knows about the line is drawn instead.
33472
+ */
33473
+ const buildFallbackHtml = (item, line) => {
33474
+ const details = [line?.accommodationName, line?.regimeName].filter(Boolean).join(' — ');
33475
+ return `
33476
+ <div class="itinerary-item__fallback">
33477
+ <h3 class="itinerary-item__fallback-title">${escapeHtml(item.title)}</h3>
33478
+ ${line ? buildFlightHtml(line) : ''}
33479
+ ${details ? `<p class="itinerary-item__fallback-details">${escapeHtml(details)}</p>` : ''}
33480
+ </div>
33481
+ `;
33482
+ };
33483
+ const buildItineraryHtml = (itinerary, translations, lines) => {
33244
33484
  if (!itinerary) {
33245
- return `
33246
- <div class="itinerary-shell">
33247
- <div class="itinerary-empty">Geen reisroute beschikbaar.</div>
33248
- </div>
33485
+ return `
33486
+ <div class="itinerary-shell">
33487
+ <div class="itinerary-empty">Geen reisroute beschikbaar.</div>
33488
+ </div>
33249
33489
  `;
33250
33490
  }
33251
33491
  const allNodes = itinerary.nodes ?? [];
@@ -33259,75 +33499,81 @@ const buildItineraryHtml = (itinerary, translations) => {
33259
33499
  const hasAccommodationInCurrentNode = uniqueItems.some(isAccommodationItem);
33260
33500
  const activeAccommodation = findAccommodationForDay(allNodes, startDay);
33261
33501
  const accommodationBanner = !hasAccommodationInCurrentNode && activeAccommodation
33262
- ? `
33263
- <div class="itinerary-node__accommodation-banner">
33264
- Accommodatie voor deze dag: <strong>${escapeHtml(getAccommodationName(activeAccommodation))}</strong>
33265
- </div>
33502
+ ? `
33503
+ <div class="itinerary-node__accommodation-banner">
33504
+ Accommodatie voor deze dag: <strong>${escapeHtml(getAccommodationName(activeAccommodation))}</strong>
33505
+ </div>
33266
33506
  `
33267
33507
  : '';
33268
33508
  const itemsHtml = hasItems
33269
33509
  ? uniqueItems
33270
- .map((item) => `
33271
- <article class="itinerary-item" data-template="${escapeHtml(item.templateName)}">
33272
- ${item.contents ?? ''}
33273
- </article>
33510
+ .map((item) => `
33511
+ <article class="itinerary-item" data-template="${escapeHtml(item.templateName)}">
33512
+ ${hasVisibleContent(item.contents)
33513
+ ? item.contents
33514
+ : buildFallbackHtml(item, lines.find((line) => line.guid === item.itemGuid))}
33515
+ </article>
33274
33516
  `)
33275
33517
  .join('')
33276
33518
  : `<div class="itinerary-node__empty">${translations.ITINERARY.NO_ITEMS}</div>`;
33277
- return `
33278
- <section class="itinerary-node">
33279
- <header class="itinerary-node__header">
33280
-
33281
- <div class="itinerary-node__day">
33282
- <p class="itinerary-node__day-day">${day}</p>
33283
- <p class="itinerary-node__day-month">${month}</p>
33284
- </div>
33285
-
33286
- <div>
33287
- <h2 class="itinerary-node__title">${escapeHtml(node.title)}</h2>
33288
- </div>
33289
- </header>
33290
-
33291
- <div class="itinerary-node__content">
33292
- ${accommodationBanner}
33293
- ${itemsHtml}
33294
- </div>
33295
- </section>
33519
+ return `
33520
+ <section class="itinerary-node">
33521
+ <header class="itinerary-node__header">
33522
+
33523
+ <div class="itinerary-node__day">
33524
+ <p class="itinerary-node__day-day">${day}</p>
33525
+ <p class="itinerary-node__day-month">${month}</p>
33526
+ </div>
33527
+
33528
+ <div>
33529
+ <h2 class="itinerary-node__title">${escapeHtml(node.title)}</h2>
33530
+ </div>
33531
+ </header>
33532
+
33533
+ <div class="itinerary-node__content">
33534
+ ${accommodationBanner}
33535
+ ${itemsHtml}
33536
+ </div>
33537
+ </section>
33296
33538
  `;
33297
33539
  })
33298
33540
  .join('');
33299
33541
  const defaultItemsHtml = itinerary.defaultItems && itinerary.defaultItems.length > 0
33300
- ? `
33301
- <section class="itinerary-default-items">
33302
- <h2 class="itinerary-default-items__title">Algemene info</h2>
33542
+ ? `
33543
+ <section class="itinerary-default-items">
33544
+ <h2 class="itinerary-default-items__title">Algemene info</h2>
33303
33545
  ${getUniqueItems(itinerary.defaultItems)
33304
- .map((item) => `
33305
- <article class="itinerary-item" data-template="${escapeHtml(item.templateName)}">
33306
- ${item.contents ?? ''}
33307
- </article>
33546
+ .map((item) => `
33547
+ <article class="itinerary-item" data-template="${escapeHtml(item.templateName)}">
33548
+ ${hasVisibleContent(item.contents)
33549
+ ? item.contents
33550
+ : buildFallbackHtml(item, lines.find((line) => line.guid === item.itemGuid))}
33551
+ </article>
33308
33552
  `)
33309
- .join('')}
33310
- </section>
33553
+ .join('')}
33554
+ </section>
33311
33555
  `
33312
33556
  : '';
33313
- return `
33314
- <div class="itinerary-shell">
33315
- ${itinerary.title ? `<header class="itinerary-shell__header"><h1 class="itinerary-shell__title">${escapeHtml(itinerary.title)}</h1></header>` : ''}
33316
-
33317
- <div class="itinerary-shell__content">
33318
- ${nodesHtml}
33319
- ${defaultItemsHtml}
33320
- </div>
33321
- </div>
33557
+ return `
33558
+ <div class="itinerary-shell">
33559
+ ${itinerary.title ? `<header class="itinerary-shell__header"><h1 class="itinerary-shell__title">${escapeHtml(itinerary.title)}</h1></header>` : ''}
33560
+
33561
+ <div class="itinerary-shell__content">
33562
+ ${nodesHtml}
33563
+ ${defaultItemsHtml}
33564
+ </div>
33565
+ </div>
33322
33566
  `;
33323
33567
  };
33324
33568
  const FullItinerary = ({ isLoading }) => {
33325
33569
  const { itinerary } = reactRedux.useSelector((state) => state.searchResults);
33326
33570
  const context = React.useContext(SearchResultsConfigurationContext);
33571
+ // The entry as it was sent: its line guids are the ones the itinerary items carry back.
33572
+ const bookableEntry = useBookableEntry();
33327
33573
  const translations = getTranslations(context?.languageCode ?? 'en-GB');
33328
33574
  const hostRef = React.useRef(null);
33329
33575
  const shadowRootRef = React.useRef(null);
33330
- const html = React.useMemo(() => buildItineraryHtml(itinerary, translations), [itinerary, translations]);
33576
+ const html = React.useMemo(() => buildItineraryHtml(itinerary, translations, bookableEntry?.lines ?? []), [itinerary, translations, bookableEntry]);
33331
33577
  React.useEffect(() => {
33332
33578
  if (isLoading) {
33333
33579
  return;
@@ -33338,141 +33584,170 @@ const FullItinerary = ({ isLoading }) => {
33338
33584
  }
33339
33585
  const shadowRoot = host.shadowRoot ?? host.attachShadow({ mode: 'open' });
33340
33586
  shadowRootRef.current = shadowRoot;
33341
- shadowRoot.innerHTML = `
33342
- <style>
33343
- :host {
33344
- all: initial;
33345
- display: block;
33346
- width: 100%;
33347
- }
33348
-
33349
- *,
33350
- *::before,
33351
- *::after {
33352
- box-sizing: border-box;
33353
- }
33354
-
33355
- .itinerary-shell {
33356
- width: 100%;
33357
- margin: 0 auto;
33358
- font-family: 'Outfit', sans-serif;
33359
- color: #222;
33360
- }
33361
-
33362
- .itinerary-shell__header {
33363
- margin-bottom: 24px;
33364
- }
33365
-
33366
- .itinerary-shell__title {
33367
- margin: 0;
33368
- font-size: 32px;
33369
- line-height: 1.2;
33370
- }
33371
-
33372
- .itinerary-shell__content {
33373
- display: grid;
33374
- gap: 24px;
33375
- }
33376
-
33377
- .itinerary-node {
33378
- border: 1px solid #e5e7eb;
33379
- border-radius: 16px;
33380
- overflow: hidden;
33381
- background: #fff;
33382
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
33383
- }
33384
-
33385
- .itinerary-node__header {
33386
- display: flex;
33387
- gap: 16px;
33388
- align-items: center;
33389
- border-bottom: 1px solid #eef0f2;
33390
- background: #fafafa;
33391
- }
33392
-
33393
- .itinerary-node__day {
33394
- flex: 50px 0 0;
33395
- display: flex;
33396
- flex-flow: column;
33397
- align-items: center;
33398
- justify-content: center;
33399
- background: #1f9470;
33400
- color: white;
33401
- border: 1.5px solid var(--tide-booking-color-secondary);
33402
- }
33403
-
33404
- .itinerary-node__day-month {
33405
- margin: 0px;
33406
- }
33407
-
33408
- .itinerary-node__day-day {
33409
- margin: 0px;
33410
- font-weight: var(--tide-booking-search-results-label-date-month-font-weight);
33411
- color: var(--tide-booking-search-results-label-date-month-color);
33412
- font-size: 24px;
33413
- }
33414
-
33415
- .itinerary-node__title {
33416
- margin: 0;
33417
- font-size: 22px;
33418
- line-height: 1.25;
33419
- }
33420
-
33421
- .itinerary-node__content {
33422
- display: grid;
33423
- gap: 20px;
33424
- padding: 20px;
33425
- }
33426
-
33427
- .itinerary-node__accommodation-banner {
33428
- padding: 12px 16px;
33429
- border: 1px solid #dbeafe;
33430
- border-radius: 12px;
33431
- background: #eff6ff;
33432
- color: #1e3a8a;
33433
- font-size: 14px;
33434
- line-height: 1.4;
33435
- }
33436
-
33437
- .itinerary-item {
33438
- display: block;
33439
- border-radius: 12px;
33440
- overflow: hidden;
33441
- background: #fff;
33442
- }
33443
-
33444
- .itinerary-node__empty,
33445
- .itinerary-empty {
33446
- padding: 20px;
33447
- border: 1px dashed #d1d5db;
33448
- border-radius: 12px;
33449
- color: #6b7280;
33450
- background: #fafafa;
33451
- }
33452
-
33453
- .itinerary-default-items {
33454
- border: 1px solid #e5e7eb;
33455
- border-radius: 16px;
33456
- padding: 20px;
33457
- background: #fff;
33458
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
33459
- }
33460
-
33461
- .itinerary-default-items__title {
33462
- margin: 0 0 16px;
33463
- font-size: 22px;
33464
- }
33465
-
33466
- @media (max-width: 768px) {
33467
- .itinerary-shell {
33468
- padding: 16px;
33469
- }
33470
- }
33471
-
33472
- ${itinerary?.styleSheetBody ?? ''}
33473
- </style>
33474
-
33475
- ${html}
33587
+ shadowRoot.innerHTML = `
33588
+ <style>
33589
+ :host {
33590
+ all: initial;
33591
+ display: block;
33592
+ width: 100%;
33593
+ }
33594
+
33595
+ *,
33596
+ *::before,
33597
+ *::after {
33598
+ box-sizing: border-box;
33599
+ }
33600
+
33601
+ .itinerary-shell {
33602
+ width: 100%;
33603
+ margin: 0 auto;
33604
+ font-family: 'Outfit', sans-serif;
33605
+ color: #222;
33606
+ }
33607
+
33608
+ .itinerary-shell__header {
33609
+ margin-bottom: 24px;
33610
+ }
33611
+
33612
+ .itinerary-shell__title {
33613
+ margin: 0;
33614
+ font-size: 32px;
33615
+ line-height: 1.2;
33616
+ }
33617
+
33618
+ .itinerary-shell__content {
33619
+ display: grid;
33620
+ gap: 24px;
33621
+ }
33622
+
33623
+ .itinerary-node {
33624
+ border: 1px solid #e5e7eb;
33625
+ border-radius: 16px;
33626
+ overflow: hidden;
33627
+ background: #fff;
33628
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
33629
+ }
33630
+
33631
+ .itinerary-node__header {
33632
+ display: flex;
33633
+ gap: 16px;
33634
+ align-items: center;
33635
+ border-bottom: 1px solid #eef0f2;
33636
+ background: #fafafa;
33637
+ }
33638
+
33639
+ .itinerary-node__day {
33640
+ flex: 50px 0 0;
33641
+ display: flex;
33642
+ flex-flow: column;
33643
+ align-items: center;
33644
+ justify-content: center;
33645
+ background: #1f9470;
33646
+ color: white;
33647
+ border: 1.5px solid var(--tide-booking-color-secondary);
33648
+ }
33649
+
33650
+ .itinerary-node__day-month {
33651
+ margin: 0px;
33652
+ }
33653
+
33654
+ .itinerary-node__day-day {
33655
+ margin: 0px;
33656
+ font-weight: var(--tide-booking-search-results-label-date-month-font-weight);
33657
+ color: var(--tide-booking-search-results-label-date-month-color);
33658
+ font-size: 24px;
33659
+ }
33660
+
33661
+ .itinerary-node__title {
33662
+ margin: 0;
33663
+ font-size: 22px;
33664
+ line-height: 1.25;
33665
+ }
33666
+
33667
+ .itinerary-node__content {
33668
+ display: grid;
33669
+ gap: 20px;
33670
+ padding: 20px;
33671
+ }
33672
+
33673
+ .itinerary-node__accommodation-banner {
33674
+ padding: 12px 16px;
33675
+ border: 1px solid #dbeafe;
33676
+ border-radius: 12px;
33677
+ background: #eff6ff;
33678
+ color: #1e3a8a;
33679
+ font-size: 14px;
33680
+ line-height: 1.4;
33681
+ }
33682
+
33683
+ .itinerary-item {
33684
+ display: block;
33685
+ border-radius: 12px;
33686
+ overflow: hidden;
33687
+ background: #fff;
33688
+ }
33689
+
33690
+ /* An item whose template has no content view of its own still has to read as a service. */
33691
+ .itinerary-item__fallback {
33692
+ padding: 16px 20px;
33693
+ border: 1px solid #e5e7eb;
33694
+ border-radius: 12px;
33695
+ }
33696
+
33697
+ .itinerary-item__fallback-title {
33698
+ margin: 0;
33699
+ font-size: 16px;
33700
+ font-weight: 600;
33701
+ color: #111827;
33702
+ }
33703
+
33704
+ .itinerary-item__legs {
33705
+ margin: 8px 0 0;
33706
+ padding-left: 18px;
33707
+ color: #374151;
33708
+ }
33709
+
33710
+ .itinerary-item__legs li + li {
33711
+ margin-top: 4px;
33712
+ }
33713
+
33714
+ .itinerary-item__fallback-details {
33715
+ margin: 8px 0 0;
33716
+ color: #6b7280;
33717
+ }
33718
+
33719
+ .itinerary-node__empty,
33720
+ .itinerary-empty {
33721
+ padding: 20px;
33722
+ border: 1px dashed #d1d5db;
33723
+ border-radius: 12px;
33724
+ color: #6b7280;
33725
+ background: #fafafa;
33726
+ }
33727
+
33728
+ .itinerary-default-items {
33729
+ border: 1px solid #e5e7eb;
33730
+ border-radius: 16px;
33731
+ padding: 20px;
33732
+ background: #fff;
33733
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
33734
+ }
33735
+
33736
+ .itinerary-default-items__title {
33737
+ margin: 0 0 16px;
33738
+ font-size: 22px;
33739
+ }
33740
+
33741
+ @media (max-width: 768px) {
33742
+ .itinerary-shell {
33743
+ padding: 16px;
33744
+ }
33745
+ }
33746
+
33747
+ ${itinerary?.styleSheetBody ?? ''}
33748
+ </style>
33749
+
33750
+ ${html}
33476
33751
  `;
33477
33752
  }, [html, itinerary?.styleSheetBody, isLoading]);
33478
33753
  return (React__default["default"].createElement(React__default["default"].Fragment, null,
@@ -33576,27 +33851,6 @@ const DayByDayExcursions = () => {
33576
33851
  })));
33577
33852
  };
33578
33853
 
33579
- /**
33580
- * The entry to send to the backend, as opposed to the one the page works with.
33581
- *
33582
- * They differ only for a traject: the page keeps the line guids the traject was rendered with,
33583
- * because that is what joins its nodes to its lines, while pricing and booking need the guids the
33584
- * searches cached their lines under. Anything else passes through untouched, so this can be used
33585
- * wherever the entry leaves the component without checking which flow is running.
33586
- */
33587
- const useBookableEntry = () => {
33588
- const context = React.useContext(SearchResultsConfigurationContext);
33589
- const { editablePackagingEntry, trajectNodeAvailability, trajectFlightAvailability } = reactRedux.useSelector((state) => state.searchResults);
33590
- const trajectEntry = context?.trajectEntry;
33591
- return React.useMemo(() => {
33592
- if (!editablePackagingEntry)
33593
- return null;
33594
- if (!trajectEntry)
33595
- return editablePackagingEntry;
33596
- return withCachedEntryLineGuids(editablePackagingEntry, trajectEntry, trajectNodeAvailability, trajectFlightAvailability);
33597
- }, [editablePackagingEntry, trajectEntry, trajectNodeAvailability, trajectFlightAvailability]);
33598
- };
33599
-
33600
33854
  const renderEditablePackagingEntrySummaryOptions = (editablePackagingEntry, priceDetails, translations, currencyCode) => {
33601
33855
  const priceDetailsByProduct = lodash.groupBy(priceDetails?.details ?? [], (detail) => `${detail.productCode}|${detail.accommodationCode}`);
33602
33856
  return (editablePackagingEntry?.lines ?? []).map((line) => {
@@ -34087,15 +34341,18 @@ const getNodeIcon = (node) => {
34087
34341
  const isRenderableNode = (node) => node.trajectNodeType === REGULAR_TRAJECT_NODE_TYPE &&
34088
34342
  (node.serviceType === ACCOMMODATION_SERVICE_TYPE || node.serviceType === EXCURSION_SERVICE_TYPE || node.serviceType === FLIGHT_SERVICE_TYPE);
34089
34343
  const MAX_DAY_ACTIVITIES = 6;
34344
+ const MAX_HOTEL_RESULTS = 6;
34090
34345
  const TrajectResults = ({ isLoading }) => {
34091
34346
  const context = React.useContext(SearchResultsConfigurationContext);
34092
34347
  const dispatch = reactRedux.useDispatch();
34093
34348
  const loadDay = useTrajectDayActivities();
34094
34349
  const translations = getTranslations(context?.languageCode ?? 'en-GB');
34095
34350
  const locale = getLocale(context?.languageCode ?? 'en-GB');
34096
- const { trajectNodeAvailability, trajectFlightAvailability, trajectDaySuggestions, editablePackagingEntry, trajectResolving } = reactRedux.useSelector((state) => state.searchResults);
34351
+ const { trajectNodeAvailability, trajectFlightAvailability, trajectDaySuggestions, editablePackagingEntry } = reactRedux.useSelector((state) => state.searchResults);
34097
34352
  const trajectEntry = context?.trajectEntry;
34098
34353
  const hideShowMoreResults = !!context?.hideShowMoreResults;
34354
+ const loadDayActivitiesOnDemand = !!context?.loadDayActivitiesOnDemand;
34355
+ const showNonPreferredHotels = !!context?.showNonPreferredHotels;
34099
34356
  const nodesWithLines = React.useMemo(() => (trajectEntry ? getTrajectNodesWithLines(trajectEntry) : []), [trajectEntry]);
34100
34357
  const lineByNodeId = React.useMemo(() => new Map(nodesWithLines.map((x) => [x.node.nodeId, x])), [nodesWithLines]);
34101
34358
  const nodesByDay = React.useMemo(() => {
@@ -34123,6 +34380,24 @@ const TrajectResults = ({ isLoading }) => {
34123
34380
  });
34124
34381
  return { stayByDay: byDay, stayStartByNodeId: byNodeId };
34125
34382
  }, [nodesWithLines]);
34383
+ /** Whether every node of the trip has an answer, one way or the other. */
34384
+ const tripResolved = React.useMemo(() => nodesWithLines
34385
+ .filter((x) => isSearchableTrajectNode(x.node) || isTrajectFlightNode(x.node))
34386
+ .every((x) => {
34387
+ const status = isTrajectFlightNode(x.node) ? trajectFlightAvailability[x.line.guid]?.status : trajectNodeAvailability[x.line.guid]?.status;
34388
+ return !!status && status !== 'loading';
34389
+ }), [nodesWithLines, trajectNodeAvailability, trajectFlightAvailability]);
34390
+ /**
34391
+ * Each day's activities are one more search, and a traject has as many as it has days. They go
34392
+ * out together, but only once the trip itself has resolved — sharing the connections with the
34393
+ * searches the trip cannot do without would only make those slower. A portal can turn the
34394
+ * automatic load off, and then each day waits for its own "show activities" click instead.
34395
+ */
34396
+ React.useEffect(() => {
34397
+ if (!trajectEntry || !tripResolved || loadDayActivitiesOnDemand)
34398
+ return;
34399
+ (trajectEntry.traject.days ?? []).filter((day) => stayByDay.has(day.order)).forEach((day) => loadDay(day));
34400
+ }, [trajectEntry, tripResolved, stayByDay, loadDayActivitiesOnDemand]);
34126
34401
  if (!context || !trajectEntry)
34127
34402
  return null;
34128
34403
  const handleSelect = (item, code) => {
@@ -34196,6 +34471,10 @@ const TrajectResults = ({ isLoading }) => {
34196
34471
  const selected = results.find((x) => x.code === availability?.selectedCode) ?? null;
34197
34472
  const configured = results.filter((x) => x.code !== selected?.code && !!findCandidateForResult(node, x));
34198
34473
  const others = results.filter((x) => x.code !== selected?.code && !findCandidateForResult(node, x));
34474
+ // A hotel row holds the hotels configured on the node; a portal can also let it fill up with
34475
+ // non-preferred hotels found in the area, the rest staying behind "show more".
34476
+ const fill = showNonPreferredHotels && node.serviceType === ACCOMMODATION_SERVICE_TYPE ? others.slice(0, Math.max(MAX_HOTEL_RESULTS - 1 - configured.length, 0)) : [];
34477
+ const remaining = others.length - fill.length;
34199
34478
  // No entry yet means the node's search has been queued but not dispatched — still loading.
34200
34479
  const status = availability?.status ?? 'loading';
34201
34480
  return (React__default["default"].createElement(React__default["default"].Fragment, { key: line.guid },
@@ -34215,12 +34494,12 @@ const TrajectResults = ({ isLoading }) => {
34215
34494
  node.preferredAccommodationName,
34216
34495
  " \u2014 ",
34217
34496
  translations.SRP.NO_RESULTS))),
34218
- React__default["default"].createElement("div", { className: "search__results__cards search__results__cards--scroll" }, [selected, ...configured].map((result) => (React__default["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 })))),
34219
- others.length > 0 && !hideShowMoreResults && (React__default["default"].createElement("div", { className: "search__results__cards__actions" },
34497
+ React__default["default"].createElement("div", { className: "search__results__cards search__results__cards--scroll" }, [selected, ...configured, ...fill].map((result) => (React__default["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 })))),
34498
+ remaining > 0 && !hideShowMoreResults && (React__default["default"].createElement("div", { className: "search__results__cards__actions" },
34220
34499
  React__default["default"].createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleShowMore(item) },
34221
34500
  translations.SRP.SHOW_MORE,
34222
34501
  " (",
34223
- others.length,
34502
+ remaining,
34224
34503
  ")")))))));
34225
34504
  };
34226
34505
  const handleSelectFlight = (item, flight) => {
@@ -34279,11 +34558,6 @@ const TrajectResults = ({ isLoading }) => {
34279
34558
  if (lines.length)
34280
34559
  dispatch(addEditableEntryLines(lines));
34281
34560
  };
34282
- const handleShowItinerary = () => {
34283
- dispatch(setTrajectItineraryView(true));
34284
- if (typeof window !== 'undefined')
34285
- window.scrollTo(0, 0);
34286
- };
34287
34561
  const handleShowMoreActivities = (dayOrder) => {
34288
34562
  dispatch(setTrajectActivitiesDayOrder(dayOrder));
34289
34563
  dispatch(setFlyInType('traject-day-activities'));
@@ -34308,16 +34582,17 @@ const TrajectResults = ({ isLoading }) => {
34308
34582
  const cards = buildDayActivityCards(items, trajectNodeAvailability, suggestions?.results ?? []);
34309
34583
  const nodesResolving = items.some((item) => (trajectNodeAvailability[item.line.guid]?.status ?? 'loading') === 'loading');
34310
34584
  const isSearching = suggestions?.status === 'loading';
34311
- const canSearch = !!getDayDestination(nodesWithLines, trajectNodeAvailability, day.order);
34585
+ // A day is worth filling only if the party is staying somewhere that night. The day they fly
34586
+ // home is covered by no stay — the last night was the night before — and nobody is looking for
34587
+ // something to do on it.
34588
+ const canSearch = stayByDay.has(day.order) && !!getDayDestination(nodesWithLines, trajectNodeAvailability, day.order);
34312
34589
  if (!items.length && !canSearch)
34313
34590
  return null;
34314
34591
  const visible = cards.slice(0, MAX_DAY_ACTIVITIES);
34315
34592
  const hidden = cards.length - visible.length;
34593
+ const awaitsRequest = loadDayActivitiesOnDemand && !suggestions && canSearch && !nodesResolving && hidden === 0;
34316
34594
  return (React__default["default"].createElement(React__default["default"].Fragment, { key: `activities-${day.order}` },
34317
- React__default["default"].createElement("div", { className: "search__results__label search__results__label--secondary" },
34318
- React__default["default"].createElement("div", { className: "search__results__label__date" },
34319
- React__default["default"].createElement("p", { className: "search__results__label__date-date" }, dateFns.format(new Date(day.date), 'd', { locale })),
34320
- React__default["default"].createElement("p", null, dateFns.format(new Date(day.date), 'MMM', { locale }))),
34595
+ React__default["default"].createElement("div", { className: "search__results__label search__results__label--sub" },
34321
34596
  React__default["default"].createElement("div", { className: "search__results__label__text" },
34322
34597
  React__default["default"].createElement(Icon, { name: "ui-excursion", height: 16 }),
34323
34598
  React__default["default"].createElement("h3", null,
@@ -34326,7 +34601,7 @@ const TrajectResults = ({ isLoading }) => {
34326
34601
  !!cards.length && React__default["default"].createElement("div", { className: "search__results__cards search__results__cards--scroll" }, visible.map(renderActivityCard)),
34327
34602
  !nodesResolving && !isSearching && !cards.length && (!!items.length || !!suggestions) && (React__default["default"].createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS)),
34328
34603
  React__default["default"].createElement("div", { className: "search__results__cards__actions" },
34329
- !suggestions && canSearch && !cards.length && !hideShowMoreResults && (React__default["default"].createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => loadDay(day) }, translations.SRP.SHOW_ACTIVITIES)),
34604
+ awaitsRequest && (React__default["default"].createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => loadDay(day) }, translations.SRP.SHOW_ACTIVITIES)),
34330
34605
  hidden > 0 && !hideShowMoreResults && (React__default["default"].createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleShowMoreActivities(day.order) },
34331
34606
  translations.SRP.SHOW_MORE,
34332
34607
  " (",
@@ -34343,35 +34618,32 @@ const TrajectResults = ({ isLoading }) => {
34343
34618
  };
34344
34619
  if (isLoading)
34345
34620
  return React__default["default"].createElement(Spinner, { label: translations.SRP.LOADING_ITINERARY });
34346
- return (React__default["default"].createElement(React__default["default"].Fragment, null,
34347
- trajectEntry.traject.days.map((day) => {
34348
- const stay = stayByDay.get(day.order);
34349
- const dayNodes = (nodesByDay.get(day.order) ?? []).filter((node) => isRenderableNode(node) && lineByNodeId.has(node.nodeId));
34350
- const stayLeadsDay = !!stay && (stay.night > 0 || dayNodes[0]?.nodeId === stay.item.node.nodeId);
34351
- // Where the day's activities belong in the order: with the first excursion it carries.
34352
- const firstExcursionNodeId = dayNodes.find((node) => node.serviceType === EXCURSION_SERVICE_TYPE)?.nodeId;
34353
- const showDayHeader = stayLeadsDay || !!day.name?.trim();
34354
- return (React__default["default"].createElement(React__default["default"].Fragment, { key: `day-${day.order}` },
34355
- showDayHeader && renderDayHeader(day, stayLeadsDay ? stay : undefined),
34356
- dayNodes.map((node) => {
34357
- const item = lineByNodeId.get(node.nodeId);
34358
- if (node.serviceType === ACCOMMODATION_SERVICE_TYPE) {
34359
- const stayStart = stayStartByNodeId.get(node.nodeId);
34360
- const titledByDayHeader = stayLeadsDay && stay.item.node.nodeId === node.nodeId;
34361
- return renderServiceNode(item, !titledByDayHeader, stayStart && getStayTitle(stayStart));
34362
- }
34363
- // Every excursion the day holds is drawn once, in one block, where the first of
34364
- // them falls in the order — so the activities still sit between the stay and the
34365
- // flight that follow them.
34366
- if (node.serviceType === EXCURSION_SERVICE_TYPE) {
34367
- return node.nodeId === firstExcursionNodeId ? renderDayActivities(day) : null;
34368
- }
34369
- return renderFlightNode(item);
34370
- }),
34371
- firstExcursionNodeId === undefined && renderDayActivities(day)));
34372
- }),
34373
- React__default["default"].createElement("div", { className: "search__results__cards__actions" },
34374
- React__default["default"].createElement("button", { type: "button", className: "cta", disabled: trajectResolving, onClick: handleShowItinerary }, translations.STEPS.NEXT))));
34621
+ return (React__default["default"].createElement(React__default["default"].Fragment, null, trajectEntry.traject.days.map((day) => {
34622
+ const stay = stayByDay.get(day.order);
34623
+ const dayNodes = (nodesByDay.get(day.order) ?? []).filter((node) => isRenderableNode(node) && lineByNodeId.has(node.nodeId));
34624
+ const stayLeadsDay = !!stay && (stay.night > 0 || dayNodes[0]?.nodeId === stay.item.node.nodeId);
34625
+ // Where the day's activities belong in the order: with the first excursion it carries.
34626
+ const firstExcursionNodeId = dayNodes.find((node) => node.serviceType === EXCURSION_SERVICE_TYPE)?.nodeId;
34627
+ const showDayHeader = stayLeadsDay || !!day.name?.trim();
34628
+ return (React__default["default"].createElement(React__default["default"].Fragment, { key: `day-${day.order}` },
34629
+ showDayHeader && renderDayHeader(day, stayLeadsDay ? stay : undefined),
34630
+ dayNodes.map((node) => {
34631
+ const item = lineByNodeId.get(node.nodeId);
34632
+ if (node.serviceType === ACCOMMODATION_SERVICE_TYPE) {
34633
+ const stayStart = stayStartByNodeId.get(node.nodeId);
34634
+ const titledByDayHeader = stayLeadsDay && stay.item.node.nodeId === node.nodeId;
34635
+ return renderServiceNode(item, !titledByDayHeader, stayStart && getStayTitle(stayStart));
34636
+ }
34637
+ // Every excursion the day holds is drawn once, in one block, where the first of
34638
+ // them falls in the order — so the activities still sit between the stay and the
34639
+ // flight that follow them.
34640
+ if (node.serviceType === EXCURSION_SERVICE_TYPE) {
34641
+ return node.nodeId === firstExcursionNodeId ? renderDayActivities(day) : null;
34642
+ }
34643
+ return renderFlightNode(item);
34644
+ }),
34645
+ firstExcursionNodeId === undefined && renderDayActivities(day)));
34646
+ })));
34375
34647
  };
34376
34648
 
34377
34649
  const useTrajectAvailability = () => {
@@ -35318,6 +35590,9 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
35318
35590
  setPricesAreLoading(false);
35319
35591
  }
35320
35592
  };
35593
+ fetchPriceDetails();
35594
+ }, [editablePackagingEntry, bookableEntry, trajectResolving]);
35595
+ React.useEffect(() => {
35321
35596
  const fetchItinerary = async () => {
35322
35597
  if (!context || !context.packagingEntry || !editablePackagingEntry || lodash.isEmpty(editablePackagingEntry.lines))
35323
35598
  return;
@@ -35347,7 +35622,6 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
35347
35622
  setItineraryIsLoading(false);
35348
35623
  }
35349
35624
  };
35350
- fetchPriceDetails();
35351
35625
  fetchItinerary();
35352
35626
  }, [editablePackagingEntry, bookableEntry, trajectResolving, trajectItineraryView]);
35353
35627
  // Flight selection
@@ -35698,11 +35972,6 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
35698
35972
  address: {}
35699
35973
  };
35700
35974
  };
35701
- const handleComposeTraject = () => {
35702
- dispatch(setTrajectItineraryView(false));
35703
- if (typeof window !== 'undefined')
35704
- window.scrollTo(0, 0);
35705
- };
35706
35975
  const handleShowMoreFlights = (flyInType) => {
35707
35976
  dispatch(setFlyInType(flyInType));
35708
35977
  dispatch(setFlyInIsOpen(true));
@@ -35793,10 +36062,7 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
35793
36062
  selectedReturnKey && selectedReturn && (React__default["default"].createElement(IndependentFlightOption, { key: `flight-${selectedReturnKey}`, item: selectedReturn.return, guid: selectedReturn.outwardGuid, selectedGuid: selectedReturn.outwardGuid, isOutward: false, showSelectedState: true, price: selectedReturn.price })),
35794
36063
  uniqueReturnFlights.map((result) => (React__default["default"].createElement(IndependentFlightOption, { key: `flight-${result.outwardGuid}`, item: result.return, onSelect: () => dispatch(setSelectedReturnKey(getFlightKey(result.return.segments))), guid: result.outwardGuid, isOutward: false, currentSelectedPrice: selectedReturn?.price, price: result.price })))))),
35795
36064
  context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.trajectEntry && !trajectItineraryView && (React__default["default"].createElement(TrajectResults, { isLoading: isLoading })),
35796
- context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.trajectEntry && trajectItineraryView && (React__default["default"].createElement(React__default["default"].Fragment, null,
35797
- React__default["default"].createElement("div", { className: "search__results__cards__actions" },
35798
- React__default["default"].createElement("button", { type: "button", className: "cta cta--secondary", onClick: handleComposeTraject }, translations.STEPS.PREVIOUS)),
35799
- React__default["default"].createElement(FullItinerary, { isLoading: itineraryIsLoading }))),
36065
+ context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.trajectEntry && trajectItineraryView && (React__default["default"].createElement(FullItinerary, { isLoading: itineraryIsLoading })),
35800
36066
  context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.packagingEntry && !context.trajectEntry && (React__default["default"].createElement(FullItinerary, { isLoading: itineraryIsLoading })))),
35801
36067
  React__default["default"].createElement(FlyIn, { srpType: context.searchConfiguration.qsmType, isOpen: flyInIsOpen, setIsOpen: handleFlyInToggle, handleConfirm: () => handleConfirmHotelSwap(), onPanelRef: (el) => (panelRef.current = el), detailsLoading: detailsIsLoading, flyInType: flyInType, isPackageEditFlow: !!context.packagingEntry, sortByTypes: sortByTypes, activeSearchSeed: activeSearchSeed, toggleFilters: () => setFiltersOpen(!filtersOpen), filtersOpen: filtersOpen })))))))));
35802
36068
  };
@@ -38705,20 +38971,20 @@ function ItineraryMapView({ destinations: propDestinations, adults = 2, dateFrom
38705
38971
  const isStartEnd = dest.isStart || dest.isEnd;
38706
38972
  let iconHtml;
38707
38973
  if (isStartEnd) {
38708
- iconHtml = `
38709
- <div class="map-view__marker map-view__marker--plane">
38710
- <svg viewBox="0 0 576 512" fill="currentColor" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
38711
- <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"/>
38712
- </svg>
38974
+ iconHtml = `
38975
+ <div class="map-view__marker map-view__marker--plane">
38976
+ <svg viewBox="0 0 576 512" fill="currentColor" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
38977
+ <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"/>
38978
+ </svg>
38713
38979
  </div>`;
38714
38980
  }
38715
38981
  else {
38716
38982
  stopIndex++;
38717
38983
  const imgStyle = dest.imageUrl ? `style="background-image:url('${dest.imageUrl}')"` : '';
38718
- iconHtml = `
38719
- <div class="map-view__marker map-view__marker--stop" ${imgStyle}>
38720
- ${!dest.imageUrl ? `<span class="map-view__marker-number">${stopIndex}</span>` : ''}
38721
- <span class="map-view__marker-badge">${stopIndex}</span>
38984
+ iconHtml = `
38985
+ <div class="map-view__marker map-view__marker--stop" ${imgStyle}>
38986
+ ${!dest.imageUrl ? `<span class="map-view__marker-number">${stopIndex}</span>` : ''}
38987
+ <span class="map-view__marker-badge">${stopIndex}</span>
38722
38988
  </div>`;
38723
38989
  }
38724
38990
  const icon = L.divIcon({