@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
@@ -2,7 +2,7 @@
2
2
  import * as React from 'react';
3
3
  import React__default, { useLayoutEffect as useLayoutEffect$1, useEffect, useContext, useState, useRef, useCallback, useMemo } from 'react';
4
4
  import JsonURL from '@jsonurl/jsonurl';
5
- import { format as format$2, isToday, getDate, startOfWeek, startOfMonth, endOfWeek, addWeeks, endOfMonth, eachDayOfInterval, getYear, getMonth, getISOWeek, getISODay, isSameMonth, startOfDay, isAfter, isEqual, isWithinInterval, endOfDay, isBefore, isSameDay, differenceInCalendarDays, addMonths, addDays, formatISO, addYears, differenceInYears, parseISO, differenceInMinutes, isValid, parse, startOfToday } from 'date-fns';
5
+ import { format as format$2, isToday, getDate, startOfWeek, startOfMonth, endOfWeek, addWeeks, endOfMonth, eachDayOfInterval, getYear, getMonth, getISOWeek, getISODay, isSameMonth, startOfDay, isAfter, isSameDay, isEqual, isWithinInterval, endOfDay, isBefore, differenceInCalendarDays, addMonths, addDays, formatISO, addYears, differenceInYears, parseISO, differenceInMinutes, isValid, parse, startOfToday } from 'date-fns';
6
6
  import { merge, cloneDeep, isNil, isArray as isArray$1, compact, isEmpty as isEmpty$1, range, chunk, isFunction as isFunction$1, clamp, now, omit, isPlainObject as isPlainObject$1, mapValues, pickBy, first, orderBy, uniq, uniqBy, sortBy, sum, last, findIndex as findIndex$1, set, get, isEqual as isEqual$1, groupBy, minBy, concat, flatMap } from 'lodash';
7
7
  import { arSA, da, de, enGB, es, fr, is, it, nl, nb, pl, pt, sv, ja, enUS } from 'date-fns/locale';
8
8
  import { usePopper } from 'react-popper';
@@ -95,7 +95,7 @@ var PRODUCT$f = {
95
95
  PER_PERSON_PER_NIGHT: "لكل شخص / لكل ليلة",
96
96
  BOOK_NOW: "احجز الآن",
97
97
  TO_YOUR_OFFER: "إلى عرضك",
98
- NOT_AVAILABLE: "غير متاح",
98
+ NOT_AVAILABLE: "غير متاح — يرجى اختيار تاريخ آخر",
99
99
  NUMBER_OF_ROOMS: "عدد الغرف",
100
100
  AGE_BY_DEPARTURE_DATE: "عمر الأطفال عند تاريخ المغادرة",
101
101
  YEAR: "سنة/سنوات",
@@ -388,6 +388,8 @@ var SRP$f = {
388
388
  DEPARTURE_ASC: "تاريخ المغادرة (الأقرب أولاً)",
389
389
  FILTERS: "عوامل التصفية",
390
390
  SHOW_ITINERARY: "عرض خط سير الرحلة",
391
+ VIEW_FULL_ITINERARY: "عرض خط السير الكامل",
392
+ SHOW_SERVICES: "عرض الخدمات",
391
393
  VIEW_BOOKING: "عرض الحجز",
392
394
  ITINERARY_TITLE: "ملخص رحلتك",
393
395
  DOSSIER_NUMBER: "رقم الملف",
@@ -437,7 +439,7 @@ var SRP$f = {
437
439
  };
438
440
  var ITINERARY$f = {
439
441
  DAY: "اليوم",
440
- NO_ITEMS: "لا توجد عناصر لهذا اليوم."
442
+ NO_ITEMS: "لم يتم اختيار أنشطة لهذا اليوم."
441
443
  };
442
444
  var FORM$f = {
443
445
  LOADING: "جاري تحميل النموذج...",
@@ -540,7 +542,7 @@ var PRODUCT$e = {
540
542
  PER_PERSON_PER_NIGHT: "Per person / per nat",
541
543
  BOOK_NOW: "Book nu",
542
544
  TO_YOUR_OFFER: "Til dit tilbud",
543
- NOT_AVAILABLE: "Ikke tilgængelig",
545
+ NOT_AVAILABLE: "Ikke tilgængelig — vælg venligst en anden dato",
544
546
  NUMBER_OF_ROOMS: "Antal værelser",
545
547
  AGE_BY_DEPARTURE_DATE: "Børns alder på afrejsedato",
546
548
  YEAR: "år",
@@ -833,6 +835,8 @@ var SRP$e = {
833
835
  DEPARTURE_ASC: "Afrejsedato (snarest først)",
834
836
  FILTERS: "Filtre",
835
837
  SHOW_ITINERARY: "Vis rejseplan",
838
+ VIEW_FULL_ITINERARY: "Se hele rejseplanen",
839
+ SHOW_SERVICES: "Vis ydelser",
836
840
  VIEW_BOOKING: "Se booking",
837
841
  ITINERARY_TITLE: "Din rejseoversigt",
838
842
  DOSSIER_NUMBER: "Sagsnummer",
@@ -882,7 +886,7 @@ var SRP$e = {
882
886
  };
883
887
  var ITINERARY$e = {
884
888
  DAY: "Dag",
885
- NO_ITEMS: "Ingen elementer for denne dag."
889
+ NO_ITEMS: "Ingen aktiviteter valgt for denne dag."
886
890
  };
887
891
  var FORM$e = {
888
892
  LOADING: "Indlæser formular...",
@@ -985,7 +989,7 @@ var PRODUCT$d = {
985
989
  PER_PERSON_PER_NIGHT: "Pro Person / pro Nacht",
986
990
  BOOK_NOW: "Jetzt buchen",
987
991
  TO_YOUR_OFFER: "Zu Ihrem Angebot",
988
- NOT_AVAILABLE: "Nicht verfügbar",
992
+ NOT_AVAILABLE: "Nicht verfügbar — bitte wählen Sie ein anderes Datum",
989
993
  NUMBER_OF_ROOMS: "Anzahl der Zimmer",
990
994
  AGE_BY_DEPARTURE_DATE: "Alter der Kinder am Abreisedatum",
991
995
  YEAR: "Jahr(e)",
@@ -1282,6 +1286,8 @@ var SRP$d = {
1282
1286
  DEPARTURE_ASC: "Abreisedatum (früheste zuerst)",
1283
1287
  FILTERS: "Filter",
1284
1288
  SHOW_ITINERARY: "Reiseverlauf anzeigen",
1289
+ VIEW_FULL_ITINERARY: "Vollständigen Reiseverlauf ansehen",
1290
+ SHOW_SERVICES: "Leistungen anzeigen",
1285
1291
  VIEW_BOOKING: "Buchung anzeigen",
1286
1292
  ITINERARY_TITLE: "Ihre Reiseübersicht",
1287
1293
  DOSSIER_NUMBER: "Vorgangsnummer",
@@ -1327,7 +1333,7 @@ var SRP$d = {
1327
1333
  };
1328
1334
  var ITINERARY$d = {
1329
1335
  DAY: "Tag",
1330
- NO_ITEMS: "Keine Elemente für diesen Tag."
1336
+ NO_ITEMS: "Keine Aktivitäten für diesen Tag ausgewählt."
1331
1337
  };
1332
1338
  var FORM$d = {
1333
1339
  LOADING: "Formular wird geladen...",
@@ -1430,7 +1436,7 @@ var PRODUCT$c = {
1430
1436
  PER_PERSON_PER_NIGHT: "Per person / per night",
1431
1437
  BOOK_NOW: "Book now",
1432
1438
  TO_YOUR_OFFER: "To your quote",
1433
- NOT_AVAILABLE: "Not available",
1439
+ NOT_AVAILABLE: "Not available — please select a different date",
1434
1440
  NUMBER_OF_ROOMS: "Number of rooms",
1435
1441
  AGE_BY_DEPARTURE_DATE: "Age of children on departure date",
1436
1442
  YEAR: "Year(s)",
@@ -1731,6 +1737,8 @@ var SRP$c = {
1731
1737
  DEPARTURE_ASC: "Departure date (soonest first)",
1732
1738
  FILTERS: "Filters",
1733
1739
  SHOW_ITINERARY: "Show itinerary",
1740
+ VIEW_FULL_ITINERARY: "View full itinerary",
1741
+ SHOW_SERVICES: "Show services",
1734
1742
  VIEW_BOOKING: "View booking",
1735
1743
  ITINERARY_TITLE: "Your trip summary",
1736
1744
  DOSSIER_NUMBER: "File number",
@@ -1776,7 +1784,7 @@ var SRP$c = {
1776
1784
  };
1777
1785
  var ITINERARY$c = {
1778
1786
  DAY: "Day",
1779
- NO_ITEMS: "No items for this day."
1787
+ NO_ITEMS: "No activities selected for this day."
1780
1788
  };
1781
1789
  var FORM$c = {
1782
1790
  LOADING: "Loading form...",
@@ -1879,7 +1887,7 @@ var PRODUCT$b = {
1879
1887
  PER_PERSON_PER_NIGHT: "Por persona / por noche",
1880
1888
  BOOK_NOW: "Reservar ahora",
1881
1889
  TO_YOUR_OFFER: "A su presupuesto",
1882
- NOT_AVAILABLE: "No disponible",
1890
+ NOT_AVAILABLE: "No disponible — seleccione otra fecha",
1883
1891
  NUMBER_OF_ROOMS: "Número de habitaciones",
1884
1892
  AGE_BY_DEPARTURE_DATE: "Edad de los niños en la fecha de salida",
1885
1893
  YEAR: "Año(s)",
@@ -2176,6 +2184,8 @@ var SRP$b = {
2176
2184
  DEPARTURE_ASC: "Fecha de salida (más próxima primero)",
2177
2185
  FILTERS: "Filtros",
2178
2186
  SHOW_ITINERARY: "Mostrar itinerario",
2187
+ VIEW_FULL_ITINERARY: "Ver itinerario completo",
2188
+ SHOW_SERVICES: "Ver servicios",
2179
2189
  VIEW_BOOKING: "Ver reserva",
2180
2190
  ITINERARY_TITLE: "Resumen de tu viaje",
2181
2191
  DOSSIER_NUMBER: "Número de expediente",
@@ -2221,7 +2231,7 @@ var SRP$b = {
2221
2231
  };
2222
2232
  var ITINERARY$b = {
2223
2233
  DAY: "Día",
2224
- NO_ITEMS: "No hay elementos para este día."
2234
+ NO_ITEMS: "No hay actividades seleccionadas para este día."
2225
2235
  };
2226
2236
  var FORM$b = {
2227
2237
  LOADING: "Cargando formulario...",
@@ -2324,7 +2334,7 @@ var PRODUCT$a = {
2324
2334
  PER_PERSON_PER_NIGHT: "Par personne / par nuit",
2325
2335
  BOOK_NOW: "Réserver maintenant",
2326
2336
  TO_YOUR_OFFER: "Vers votre devis",
2327
- NOT_AVAILABLE: "Non disponible",
2337
+ NOT_AVAILABLE: "Non disponible — veuillez sélectionner une autre date",
2328
2338
  NUMBER_OF_ROOMS: "Nombre de chambres",
2329
2339
  AGE_BY_DEPARTURE_DATE: "Âge des enfants à la date de départ",
2330
2340
  YEAR: "An(s)",
@@ -2625,6 +2635,8 @@ var SRP$a = {
2625
2635
  DEPARTURE_ASC: "Date de départ (la plus proche d’abord)",
2626
2636
  FILTERS: "Filtres",
2627
2637
  SHOW_ITINERARY: "Afficher l’itinéraire",
2638
+ VIEW_FULL_ITINERARY: "Voir l'itinéraire complet",
2639
+ SHOW_SERVICES: "Voir les services",
2628
2640
  VIEW_BOOKING: "Voir la réservation",
2629
2641
  ITINERARY_TITLE: "Résumé de votre voyage",
2630
2642
  DOSSIER_NUMBER: "Numéro de dossier",
@@ -2670,7 +2682,7 @@ var SRP$a = {
2670
2682
  };
2671
2683
  var ITINERARY$a = {
2672
2684
  DAY: "Jour",
2673
- NO_ITEMS: "Aucun élément pour ce jour."
2685
+ NO_ITEMS: "Aucune activité sélectionnée pour ce jour."
2674
2686
  };
2675
2687
  var FORM$a = {
2676
2688
  LOADING: "Chargement du formulaire...",
@@ -2773,7 +2785,7 @@ var PRODUCT$9 = {
2773
2785
  PER_PERSON_PER_NIGHT: "Par personne / par nuit",
2774
2786
  BOOK_NOW: "Réservez maintenant",
2775
2787
  TO_YOUR_OFFER: "Vers votre devis",
2776
- NOT_AVAILABLE: "Indisponible",
2788
+ NOT_AVAILABLE: "Indisponible — veuillez sélectionner une autre date",
2777
2789
  NUMBER_OF_ROOMS: "Nombre de chambres",
2778
2790
  AGE_BY_DEPARTURE_DATE: "Âge des enfants à la date de départ",
2779
2791
  YEAR: "An(s)",
@@ -3070,6 +3082,8 @@ var SRP$9 = {
3070
3082
  DEPARTURE_ASC: "Date de départ (la plus proche d’abord)",
3071
3083
  FILTERS: "Filtres",
3072
3084
  SHOW_ITINERARY: "Afficher l’itinéraire",
3085
+ VIEW_FULL_ITINERARY: "Voir l'itinéraire complet",
3086
+ SHOW_SERVICES: "Voir les services",
3073
3087
  VIEW_BOOKING: "Voir la réservation",
3074
3088
  ITINERARY_TITLE: "Résumé de votre voyage",
3075
3089
  DOSSIER_NUMBER: "Numéro de dossier",
@@ -3115,7 +3129,7 @@ var SRP$9 = {
3115
3129
  };
3116
3130
  var ITINERARY$9 = {
3117
3131
  DAY: "Jour",
3118
- NO_ITEMS: "Aucun élément pour ce jour."
3132
+ NO_ITEMS: "Aucune activité sélectionnée pour ce jour."
3119
3133
  };
3120
3134
  var FORM$9 = {
3121
3135
  LOADING: "Chargement du formulaire...",
@@ -3218,7 +3232,7 @@ var PRODUCT$8 = {
3218
3232
  PER_PERSON_PER_NIGHT: "Á mann / á nótt",
3219
3233
  BOOK_NOW: "Panta núna",
3220
3234
  TO_YOUR_OFFER: "Til tilboðsins þíns",
3221
- NOT_AVAILABLE: "Ekki í boði",
3235
+ NOT_AVAILABLE: "Ekki í boði — vinsamlegast veldu aðra dagsetningu",
3222
3236
  NUMBER_OF_ROOMS: "Fjöldi herbergja",
3223
3237
  AGE_BY_DEPARTURE_DATE: "Aldur barna á brottfarardegi",
3224
3238
  YEAR: "ár",
@@ -3515,6 +3529,8 @@ var SRP$8 = {
3515
3529
  DEPARTURE_ASC: "Brottfarardagur (nærst fyrst)",
3516
3530
  FILTERS: "Síur",
3517
3531
  SHOW_ITINERARY: "Sýna ferðaráætlun",
3532
+ VIEW_FULL_ITINERARY: "Skoða alla ferðaáætlunina",
3533
+ SHOW_SERVICES: "Sýna þjónustu",
3518
3534
  VIEW_BOOKING: "Skoða bókun",
3519
3535
  ITINERARY_TITLE: "Yfirlit ferðarinnar",
3520
3536
  DOSSIER_NUMBER: "Skrárnúmer",
@@ -3560,7 +3576,7 @@ var SRP$8 = {
3560
3576
  };
3561
3577
  var ITINERARY$8 = {
3562
3578
  DAY: "Dagur",
3563
- NO_ITEMS: "Engar upplýsingar fyrir þennan dag."
3579
+ NO_ITEMS: "Engin afþreying valin fyrir þennan dag."
3564
3580
  };
3565
3581
  var FORM$8 = {
3566
3582
  LOADING: "Hleður eyðublað...",
@@ -3663,7 +3679,7 @@ var PRODUCT$7 = {
3663
3679
  PER_PERSON_PER_NIGHT: "A persona / a notte",
3664
3680
  BOOK_NOW: "Prenota ora",
3665
3681
  TO_YOUR_OFFER: "Vai al preventivo",
3666
- NOT_AVAILABLE: "Non disponibile",
3682
+ NOT_AVAILABLE: "Non disponibile — seleziona un'altra data",
3667
3683
  NUMBER_OF_ROOMS: "Numero di camere",
3668
3684
  AGE_BY_DEPARTURE_DATE: "Età dei bambini alla data di partenza",
3669
3685
  YEAR: "Anno/i",
@@ -3960,6 +3976,8 @@ var SRP$7 = {
3960
3976
  DEPARTURE_ASC: "Data di partenza (prima la più vicina)",
3961
3977
  FILTERS: "Filtri",
3962
3978
  SHOW_ITINERARY: "Mostra itinerario",
3979
+ VIEW_FULL_ITINERARY: "Vedi l'itinerario completo",
3980
+ SHOW_SERVICES: "Mostra i servizi",
3963
3981
  VIEW_BOOKING: "Visualizza prenotazione",
3964
3982
  ITINERARY_TITLE: "Riepilogo del tuo viaggio",
3965
3983
  DOSSIER_NUMBER: "Numero di pratica",
@@ -4005,7 +4023,7 @@ var SRP$7 = {
4005
4023
  };
4006
4024
  var ITINERARY$7 = {
4007
4025
  DAY: "Giorno",
4008
- NO_ITEMS: "Nessun elemento per questo giorno."
4026
+ NO_ITEMS: "Nessuna attività selezionata per questo giorno."
4009
4027
  };
4010
4028
  var FORM$7 = {
4011
4029
  LOADING: "Caricamento modulo...",
@@ -4108,7 +4126,7 @@ var PRODUCT$6 = {
4108
4126
  PER_PERSON_PER_NIGHT: "Per persoon / per nacht",
4109
4127
  BOOK_NOW: "Boek nu",
4110
4128
  TO_YOUR_OFFER: "Naar uw offerte",
4111
- NOT_AVAILABLE: "Niet beschikbaar",
4129
+ NOT_AVAILABLE: "Niet beschikbaar — kies een andere datum",
4112
4130
  NUMBER_OF_ROOMS: "Aantal kamers",
4113
4131
  AGE_BY_DEPARTURE_DATE: "Leeftijd kinderen op vertrekdatum",
4114
4132
  YEAR: "Jaar",
@@ -4409,6 +4427,8 @@ var SRP$6 = {
4409
4427
  DEPARTURE_ASC: "Vertrekdatum (dichtstbij eerst)",
4410
4428
  FILTERS: "Filters",
4411
4429
  SHOW_ITINERARY: "Toon reisplan",
4430
+ VIEW_FULL_ITINERARY: "Bekijk volledige reisroute",
4431
+ SHOW_SERVICES: "Toon diensten",
4412
4432
  VIEW_BOOKING: "Bekijk boeking",
4413
4433
  ITINERARY_TITLE: "Overzicht van je reis",
4414
4434
  DOSSIER_NUMBER: "Dossiernummer",
@@ -4454,7 +4474,7 @@ var SRP$6 = {
4454
4474
  };
4455
4475
  var ITINERARY$6 = {
4456
4476
  DAY: "Dag",
4457
- NO_ITEMS: "Geen elementen voor deze dag."
4477
+ NO_ITEMS: "Geen activiteiten geselecteerd voor deze dag."
4458
4478
  };
4459
4479
  var FORM$6 = {
4460
4480
  LOADING: "Formulier laden...",
@@ -4557,7 +4577,7 @@ var PRODUCT$5 = {
4557
4577
  PER_PERSON_PER_NIGHT: "Per persoon / per nacht",
4558
4578
  BOOK_NOW: "Nu boeken",
4559
4579
  TO_YOUR_OFFER: "Naar uw offerte",
4560
- NOT_AVAILABLE: "Niet beschikbaar",
4580
+ NOT_AVAILABLE: "Niet beschikbaar — kies een andere datum",
4561
4581
  NUMBER_OF_ROOMS: "Aantal kamers",
4562
4582
  AGE_BY_DEPARTURE_DATE: "Leeftijd van kinderen op vertrekdatum",
4563
4583
  YEAR: "Jaar",
@@ -4854,6 +4874,8 @@ var SRP$5 = {
4854
4874
  DEPARTURE_ASC: "Vertrekdatum (dichtstbij eerst)",
4855
4875
  FILTERS: "Filters",
4856
4876
  SHOW_ITINERARY: "Toon reisplan",
4877
+ VIEW_FULL_ITINERARY: "Bekijk volledige reisroute",
4878
+ SHOW_SERVICES: "Toon diensten",
4857
4879
  VIEW_BOOKING: "Bekijk boeking",
4858
4880
  ITINERARY_TITLE: "Overzicht van je reis",
4859
4881
  DOSSIER_NUMBER: "Dossiernummer",
@@ -4899,7 +4921,7 @@ var SRP$5 = {
4899
4921
  };
4900
4922
  var ITINERARY$5 = {
4901
4923
  DAY: "Dag",
4902
- NO_ITEMS: "Geen elementen voor deze dag."
4924
+ NO_ITEMS: "Geen activiteiten geselecteerd voor deze dag."
4903
4925
  };
4904
4926
  var FORM$5 = {
4905
4927
  LOADING: "Formulier laden...",
@@ -5002,7 +5024,7 @@ var PRODUCT$4 = {
5002
5024
  PER_PERSON_PER_NIGHT: "Per person / per natt",
5003
5025
  BOOK_NOW: "Bestill nå",
5004
5026
  TO_YOUR_OFFER: "Til ditt tilbud",
5005
- NOT_AVAILABLE: "Ikke tilgjengelig",
5027
+ NOT_AVAILABLE: "Ikke tilgjengelig — velg en annen dato",
5006
5028
  NUMBER_OF_ROOMS: "Antall rom",
5007
5029
  AGE_BY_DEPARTURE_DATE: "Barnas alder på avreisedato",
5008
5030
  YEAR: "År",
@@ -5299,6 +5321,8 @@ var SRP$4 = {
5299
5321
  DEPARTURE_ASC: "Avreisedato (nærmeste først)",
5300
5322
  FILTERS: "Filtre",
5301
5323
  SHOW_ITINERARY: "Vis reiserute",
5324
+ VIEW_FULL_ITINERARY: "Se hele reiseruten",
5325
+ SHOW_SERVICES: "Vis tjenester",
5302
5326
  VIEW_BOOKING: "Se bestilling",
5303
5327
  ITINERARY_TITLE: "Din reisemåloversikt",
5304
5328
  DOSSIER_NUMBER: "Saksnummer",
@@ -5344,7 +5368,7 @@ var SRP$4 = {
5344
5368
  };
5345
5369
  var ITINERARY$4 = {
5346
5370
  DAY: "Dag",
5347
- NO_ITEMS: "Ingen elementer for denne dagen."
5371
+ NO_ITEMS: "Ingen aktiviteter valgt for denne dagen."
5348
5372
  };
5349
5373
  var FORM$4 = {
5350
5374
  LOADING: "Laster inn skjema...",
@@ -5447,7 +5471,7 @@ var PRODUCT$3 = {
5447
5471
  PER_PERSON_PER_NIGHT: "Za osobę / za noc",
5448
5472
  BOOK_NOW: "Zarezerwuj teraz",
5449
5473
  TO_YOUR_OFFER: "Do oferty",
5450
- NOT_AVAILABLE: "Niedostępne",
5474
+ NOT_AVAILABLE: "Niedostępne — wybierz inną datę",
5451
5475
  NUMBER_OF_ROOMS: "Liczba pokoi",
5452
5476
  AGE_BY_DEPARTURE_DATE: "Wiek dzieci w dniu wyjazdu",
5453
5477
  YEAR: "Rok(lata)",
@@ -5744,6 +5768,8 @@ var SRP$3 = {
5744
5768
  DEPARTURE_ASC: "Data wyjazdu (najbliższa najpierw)",
5745
5769
  FILTERS: "Filtry",
5746
5770
  SHOW_ITINERARY: "Pokaż plan podróży",
5771
+ VIEW_FULL_ITINERARY: "Zobacz pełny plan podróży",
5772
+ SHOW_SERVICES: "Pokaż usługi",
5747
5773
  VIEW_BOOKING: "Zobacz rezerwację",
5748
5774
  ITINERARY_TITLE: "Podsumowanie Twojej podróży",
5749
5775
  DOSSIER_NUMBER: "Numer pliku",
@@ -5789,7 +5815,7 @@ var SRP$3 = {
5789
5815
  };
5790
5816
  var ITINERARY$3 = {
5791
5817
  DAY: "Dzień",
5792
- NO_ITEMS: "Brak elementów dla tego dnia."
5818
+ NO_ITEMS: "Nie wybrano atrakcji na ten dzień."
5793
5819
  };
5794
5820
  var FORM$3 = {
5795
5821
  LOADING: "Ładowanie formularza...",
@@ -5892,7 +5918,7 @@ var PRODUCT$2 = {
5892
5918
  PER_PERSON_PER_NIGHT: "Por pessoa / por noite",
5893
5919
  BOOK_NOW: "Reservar agora",
5894
5920
  TO_YOUR_OFFER: "Ir para o orçamento",
5895
- NOT_AVAILABLE: "Indisponível",
5921
+ NOT_AVAILABLE: "Indisponível — selecione outra data",
5896
5922
  NUMBER_OF_ROOMS: "Número de quartos",
5897
5923
  AGE_BY_DEPARTURE_DATE: "Idade das crianças à data de partida",
5898
5924
  YEAR: "Ano(s)",
@@ -6189,6 +6215,8 @@ var SRP$2 = {
6189
6215
  DEPARTURE_ASC: "Data de partida (mais próxima primeiro)",
6190
6216
  FILTERS: "Filtros",
6191
6217
  SHOW_ITINERARY: "Mostrar itinerário",
6218
+ VIEW_FULL_ITINERARY: "Ver itinerário completo",
6219
+ SHOW_SERVICES: "Ver serviços",
6192
6220
  VIEW_BOOKING: "Ver reserva",
6193
6221
  ITINERARY_TITLE: "Resumo da sua viagem",
6194
6222
  DOSSIER_NUMBER: "Número do processo",
@@ -6234,7 +6262,7 @@ var SRP$2 = {
6234
6262
  };
6235
6263
  var ITINERARY$2 = {
6236
6264
  DAY: "Dia",
6237
- NO_ITEMS: "Nenhum item para este dia."
6265
+ NO_ITEMS: "Nenhuma atividade selecionada para este dia."
6238
6266
  };
6239
6267
  var FORM$2 = {
6240
6268
  LOADING: "A carregar formulário...",
@@ -6337,7 +6365,7 @@ var PRODUCT$1 = {
6337
6365
  PER_PERSON_PER_NIGHT: "Per person / per natt",
6338
6366
  BOOK_NOW: "Boka nu",
6339
6367
  TO_YOUR_OFFER: "Till din offert",
6340
- NOT_AVAILABLE: "Ej tillgänglig",
6368
+ NOT_AVAILABLE: "Ej tillgänglig — välj ett annat datum",
6341
6369
  NUMBER_OF_ROOMS: "Antal rum",
6342
6370
  AGE_BY_DEPARTURE_DATE: "Barnens ålder vid avresedatum",
6343
6371
  YEAR: "År",
@@ -6634,6 +6662,8 @@ var SRP$1 = {
6634
6662
  DEPARTURE_ASC: "Avresedatum (närmast först)",
6635
6663
  FILTERS: "Filter",
6636
6664
  SHOW_ITINERARY: "Visa resplan",
6665
+ VIEW_FULL_ITINERARY: "Visa hela resplanen",
6666
+ SHOW_SERVICES: "Visa tjänster",
6637
6667
  VIEW_BOOKING: "Visa bokning",
6638
6668
  ITINERARY_TITLE: "Din resesammanfattning",
6639
6669
  DOSSIER_NUMBER: "Filnummer",
@@ -6679,7 +6709,7 @@ var SRP$1 = {
6679
6709
  };
6680
6710
  var ITINERARY$1 = {
6681
6711
  DAY: "Dag",
6682
- NO_ITEMS: "Inga element för denna dag."
6712
+ NO_ITEMS: "Inga aktiviteter valda för denna dag."
6683
6713
  };
6684
6714
  var FORM$1 = {
6685
6715
  LOADING: "Laddar formulär...",
@@ -6782,7 +6812,7 @@ var PRODUCT = {
6782
6812
  PER_PERSON_PER_NIGHT: "1名・1泊あたり",
6783
6813
  BOOK_NOW: "今すぐ予約",
6784
6814
  TO_YOUR_OFFER: "見積もりへ",
6785
- NOT_AVAILABLE: "利用不可",
6815
+ NOT_AVAILABLE: "利用不可 — 別の日付をお選びください",
6786
6816
  NUMBER_OF_ROOMS: "客室数",
6787
6817
  AGE_BY_DEPARTURE_DATE: "出発日時点での子供の年齢",
6788
6818
  YEAR: "歳",
@@ -7079,6 +7109,8 @@ var SRP = {
7079
7109
  DEPARTURE_ASC: "出発日(早い順)",
7080
7110
  FILTERS: "フィルター",
7081
7111
  SHOW_ITINERARY: "旅程を表示",
7112
+ VIEW_FULL_ITINERARY: "旅程の詳細を見る",
7113
+ SHOW_SERVICES: "サービスを表示",
7082
7114
  VIEW_BOOKING: "予約を見る",
7083
7115
  ITINERARY_TITLE: "あなたの旅行概要",
7084
7116
  DOSSIER_NUMBER: "ファイル番号",
@@ -7124,7 +7156,7 @@ var SRP = {
7124
7156
  };
7125
7157
  var ITINERARY = {
7126
7158
  DAY: "日",
7127
- NO_ITEMS: "この日のアイテムはありません。"
7159
+ NO_ITEMS: "この日に選択されたアクティビティはありません。"
7128
7160
  };
7129
7161
  var FORM = {
7130
7162
  LOADING: "フォームを読み込んでいます...",
@@ -7788,6 +7820,33 @@ var TrajectNodeType = {
7788
7820
  subroute: 3,
7789
7821
  };
7790
7822
 
7823
+ var DurationType = {
7824
+ hours: 0,
7825
+ days: 1,
7826
+ nights: 2,
7827
+ minutes: 3,
7828
+ };
7829
+
7830
+ var RouteTransportType = {
7831
+ none: 0,
7832
+ privateTransport: 1,
7833
+ publicTransport: 2,
7834
+ rentalCar: 3,
7835
+ bus: 4,
7836
+ camper: 5,
7837
+ car: 6,
7838
+ charter: 7,
7839
+ cruise: 8,
7840
+ ferry: 9,
7841
+ flight: 10,
7842
+ taxi: 11,
7843
+ train: 12,
7844
+ transfer: 13,
7845
+ rocket: 14,
7846
+ walking: 15,
7847
+ cycling: 16,
7848
+ };
7849
+
7791
7850
  /******************************************************************************
7792
7851
  Copyright (c) Microsoft Corporation.
7793
7852
 
@@ -15139,6 +15198,7 @@ var submitForm = function (config, id, request, signal) {
15139
15198
  exports.AllotmentType = AllotmentType;
15140
15199
  exports.DataType = DataType;
15141
15200
  exports.DossierType = DossierType;
15201
+ exports.DurationType = DurationType;
15142
15202
  exports.EntryLineFlag = EntryLineFlag;
15143
15203
  exports.EntryLineStatus = EntryLineStatus;
15144
15204
  exports.ExportStatus = ExportStatus;
@@ -15151,6 +15211,7 @@ exports.PaymentType = PaymentType;
15151
15211
  exports.PriceChartType = PriceChartType;
15152
15212
  exports.RequirementType = RequirementType;
15153
15213
  exports.RoomType = RoomType;
15214
+ exports.RouteTransportType = RouteTransportType;
15154
15215
  exports.SaleType = SaleType;
15155
15216
  exports.ServiceTokenError = ServiceTokenError;
15156
15217
  exports.ServiceType = ServiceType;
@@ -16628,6 +16689,16 @@ const Icon = ({ name, className, title, width, height, fill }) => {
16628
16689
  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." }),
16629
16690
  title && React__default.createElement("title", null, title),
16630
16691
  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" })));
16692
+ case 'ui-cycling':
16693
+ 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' },
16694
+ React__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." }),
16695
+ title && React__default.createElement("title", null, title),
16696
+ React__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" })));
16697
+ case 'ui-walking':
16698
+ return (React__default.createElement("svg", { className: ['icon', `icon--${name}`, className].filter((className) => !isEmpty$1(className)).join(' '), width: width, height: height, viewBox: "0 0 320 512", fill: fill ?? 'currentColor' },
16699
+ React__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." }),
16700
+ title && React__default.createElement("title", null, title),
16701
+ React__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" })));
16631
16702
  case 'ui-bus':
16632
16703
  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' },
16633
16704
  title && React__default.createElement("title", null, title),
@@ -16941,10 +17012,10 @@ const DateRangePicker$1 = (props) => {
16941
17012
  month: getMonth(new Date())
16942
17013
  });
16943
17014
  const [isWaitingForToDate, setWaitingForToDate] = useState(false);
16944
- const { searchType = 0 } = useContext(SettingsContext$1);
17015
+ const { searchType = 0, allowSingleDayDateSelect = false } = useContext(SettingsContext$1);
16945
17016
  const handleDayClick = (day) => {
16946
17017
  const { onSelectionChange } = props;
16947
- if (isWaitingForToDate && !isNil(fromDate) && isAfter(day, fromDate)) {
17018
+ if (isWaitingForToDate && !isNil(fromDate) && (isAfter(day, fromDate) || (allowSingleDayDateSelect && isSameDay(day, fromDate)))) {
16948
17019
  if (searchType === 1) {
16949
17020
  // Only allow selecting the exact toDate
16950
17021
  const expectedToDate = props.toDateByFromDate?.(fromDate);
@@ -16985,7 +17056,7 @@ const DateRangePicker$1 = (props) => {
16985
17056
  }
16986
17057
  };
16987
17058
  const handleDayMouseOver = (day) => {
16988
- if (isWaitingForToDate && (isNil(fromDate) || isEqual(day, fromDate) || isAfter(day, fromDate))) {
17059
+ if (isWaitingForToDate && (isNil(fromDate) || isSameDay(day, fromDate) || isAfter(day, fromDate))) {
16989
17060
  setToDate(day);
16990
17061
  }
16991
17062
  };
@@ -21753,6 +21824,7 @@ const OptionRoom = ({ packageRoom, pax, optionPax, onRoomChange, includedService
21753
21824
 
21754
21825
  function useOfferPrinter({ bookingPackage, getPax, tagIds = [], printActionId = null, onPrinted }) {
21755
21826
  const settings = useContext(SettingsContext);
21827
+ const apiSettings = useSelector(selectApiSettings);
21756
21828
  if (!settings)
21757
21829
  throw new Error('useOfferPrinter must be used inside <BookingWizard>');
21758
21830
  const { language, officeId } = settings;
@@ -21781,9 +21853,9 @@ function useOfferPrinter({ bookingPackage, getPax, tagIds = [], printActionId =
21781
21853
  customerRequests: []
21782
21854
  }
21783
21855
  };
21784
- const cfg = buildTideClientConfig();
21856
+ const cfg = buildTideClientConfig(apiSettings);
21785
21857
  return build.book(cfg, request, undefined, language);
21786
- }, [agentId, bookingPackage, getPax, language, officeId, tagIds]);
21858
+ }, [agentId, apiSettings, bookingPackage, getPax, language, officeId, tagIds]);
21787
21859
  const languageData = [
21788
21860
  { code: 'nl-BE', tideId: 1 },
21789
21861
  { code: 'fr-BE', tideId: 2 },
@@ -21793,7 +21865,7 @@ function useOfferPrinter({ bookingPackage, getPax, tagIds = [], printActionId =
21793
21865
  return languageData.find((l) => l.code === code)?.tideId || 1;
21794
21866
  }
21795
21867
  const printOffer = useCallback(async (offer) => {
21796
- const cfg = buildTideClientConfig();
21868
+ const cfg = buildTideClientConfig(apiSettings);
21797
21869
  const req = {
21798
21870
  id: printActionId ?? 0,
21799
21871
  dossierNumber: offer.dossierNumber ?? offer.number,
@@ -21804,7 +21876,7 @@ function useOfferPrinter({ bookingPackage, getPax, tagIds = [], printActionId =
21804
21876
  const url = URL.createObjectURL(new Blob([buf], { type: 'application/pdf' }));
21805
21877
  onPrinted?.(url);
21806
21878
  window.open(url);
21807
- }, [language, onPrinted]);
21879
+ }, [apiSettings, language, onPrinted, printActionId]);
21808
21880
  const handlePrint = useCallback(async () => {
21809
21881
  try {
21810
21882
  setStage('creating');
@@ -28004,8 +28076,97 @@ const getServiceTypeBadgeModifier = (serviceType) => {
28004
28076
  return '';
28005
28077
  }
28006
28078
  };
28079
+ // DurationType, as the SDK numbers it.
28080
+ const DURATION_HOURS = 0;
28081
+ const DURATION_DAYS = 1;
28082
+ const DURATION_NIGHTS = 2;
28083
+ const DURATION_MINUTES = 3;
28084
+ /**
28085
+ * How long a node takes, in the same shape the flight legs are written in — an hour count only
28086
+ * once there is one, so a short drive reads as plain minutes.
28087
+ */
28088
+ const getTrajectNodeDuration = (node) => {
28089
+ const minutes = toMinutes(node);
28090
+ if (!minutes)
28091
+ return '';
28092
+ const hours = Math.floor(minutes / 60);
28093
+ const rest = minutes % 60;
28094
+ return hours ? `${hours}h ${rest.toString().padStart(2, '0')}m` : `${rest} min`;
28095
+ };
28096
+ const toMinutes = (node) => {
28097
+ const duration = node.duration ?? 0;
28098
+ if (duration <= 0)
28099
+ return 0;
28100
+ switch (node.durationType) {
28101
+ case DURATION_MINUTES:
28102
+ return duration;
28103
+ case DURATION_HOURS:
28104
+ return duration * 60;
28105
+ case DURATION_DAYS:
28106
+ case DURATION_NIGHTS:
28107
+ return duration * 24 * 60;
28108
+ default:
28109
+ return 0;
28110
+ }
28111
+ };
28112
+ // RouteTransportType, as the SDK numbers it. It says how a leg is travelled, which is not the
28113
+ // same question as what was sold: cycling and walking have no service type of their own.
28114
+ const TRANSPORT_PRIVATE = 1;
28115
+ const TRANSPORT_PUBLIC = 2;
28116
+ const TRANSPORT_RENTAL_CAR = 3;
28117
+ const TRANSPORT_BUS = 4;
28118
+ const TRANSPORT_CAMPER = 5;
28119
+ const TRANSPORT_CAR = 6;
28120
+ const TRANSPORT_CHARTER = 7;
28121
+ const TRANSPORT_CRUISE = 8;
28122
+ const TRANSPORT_FERRY = 9;
28123
+ const TRANSPORT_FLIGHT = 10;
28124
+ const TRANSPORT_TAXI = 11;
28125
+ const TRANSPORT_TRAIN = 12;
28126
+ const TRANSPORT_TRANSFER = 13;
28127
+ const TRANSPORT_WALKING = 15;
28128
+ const TRANSPORT_CYCLING = 16;
28129
+ /** Icon per way of travelling, where the route records one. */
28130
+ const getTransportTypeIcon = (transportType) => {
28131
+ switch (transportType) {
28132
+ case TRANSPORT_WALKING:
28133
+ return 'ui-walking';
28134
+ case TRANSPORT_CYCLING:
28135
+ return 'ui-cycling';
28136
+ case TRANSPORT_PRIVATE:
28137
+ case TRANSPORT_RENTAL_CAR:
28138
+ case TRANSPORT_CAMPER:
28139
+ case TRANSPORT_CAR:
28140
+ return 'ui-car';
28141
+ case TRANSPORT_TAXI:
28142
+ case TRANSPORT_TRANSFER:
28143
+ return 'ui-transfer';
28144
+ case TRANSPORT_PUBLIC:
28145
+ case TRANSPORT_BUS:
28146
+ return 'ui-bus';
28147
+ case TRANSPORT_TRAIN:
28148
+ return 'ui-train';
28149
+ case TRANSPORT_CRUISE:
28150
+ case TRANSPORT_FERRY:
28151
+ return 'ui-ship';
28152
+ case TRANSPORT_FLIGHT:
28153
+ case TRANSPORT_CHARTER:
28154
+ return 'ui-plane';
28155
+ default:
28156
+ return null;
28157
+ }
28158
+ };
28007
28159
  const POI_TRAJECT_NODE_TYPE = 2;
28008
- const getTrajectNodeIcon = (node) => node.trajectNodeType === POI_TRAJECT_NODE_TYPE ? 'ui-location' : getServiceTypeIcon(node.serviceType);
28160
+ /**
28161
+ * A point of interest is a place on the map rather than a service, so it gets a marker. Anything
28162
+ * else goes by how it is travelled where the route says so — a leg on foot or by bike is sold as
28163
+ * nothing, and its service type falls back to a transfer — and by what it is where it does not.
28164
+ */
28165
+ const getTrajectNodeIcon = (node) => {
28166
+ if (node.trajectNodeType === POI_TRAJECT_NODE_TYPE)
28167
+ return 'ui-location';
28168
+ return getTransportTypeIcon(node.transportType) ?? getServiceTypeIcon(node.serviceType);
28169
+ };
28009
28170
  const getTrajectNodeBadgeModifier = (node) => node.trajectNodeType === POI_TRAJECT_NODE_TYPE ? 'poi' : getServiceTypeBadgeModifier(node.serviceType);
28010
28171
 
28011
28172
  const REGULAR_TRAJECT_NODE_TYPE = 0;
@@ -28072,8 +28233,6 @@ const buildTrajectNodeRequest = ({ node, line }, context, productCode, destinati
28072
28233
  language: context.language,
28073
28234
  serviceType: node.serviceType,
28074
28235
  fromDate: toDateOnlyString(line.from),
28075
- // An excursion happens on a day rather than over a span. The traject gives its line an end a day
28076
- // out, the way a night is counted, which asks the search for a window it does not have.
28077
28236
  toDate: toDateOnlyString(node.serviceType === EXCURSION_SERVICE_TYPE ? line.from : line.to),
28078
28237
  destination: destination ?? buildDestination(line, node),
28079
28238
  productCode,
@@ -28444,6 +28603,8 @@ const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
28444
28603
  trajectNodeType: REGULAR_TRAJECT_NODE_TYPE,
28445
28604
  requirementType: 0,
28446
28605
  contentSource: 0,
28606
+ duration: 0,
28607
+ durationType: 0,
28447
28608
  alternatives: [],
28448
28609
  from: line.from,
28449
28610
  to: line.to
@@ -28477,6 +28638,8 @@ const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
28477
28638
  React__default.createElement("p", null, format$2(new Date(value), 'MMM'))));
28478
28639
  const renderConnectingNode = ({ node }) => {
28479
28640
  const distance = node.distanceInKm ? `${Math.round(node.distanceInKm)} km` : '';
28641
+ // How long the hop takes and how far it is, the way the traject editor puts them.
28642
+ const journey = [getTrajectNodeDuration(node), distance].filter(Boolean).join(' · ');
28480
28643
  return (React__default.createElement("div", { className: "search__filter__itinerary__transport", key: `connect-${node.nodeId}` },
28481
28644
  React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline" },
28482
28645
  React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline-line" })),
@@ -28485,8 +28648,8 @@ const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
28485
28648
  React__default.createElement("div", { className: badgeClass('transport', getTrajectNodeBadgeModifier(node)) },
28486
28649
  React__default.createElement(Icon, { name: getTrajectNodeIcon(node), height: 15 })),
28487
28650
  React__default.createElement("div", { className: "search__filter__itinerary__transport-details" },
28488
- React__default.createElement("h6", null, node.name || distance),
28489
- !!node.name && !!distance && React__default.createElement("p", { className: "search__filter__itinerary__transport-details-time" }, distance)))));
28651
+ React__default.createElement("h6", null, node.name || journey),
28652
+ !!node.name && !!journey && React__default.createElement("p", { className: "search__filter__itinerary__transport-details-time" }, journey)))));
28490
28653
  };
28491
28654
  const renderOvernight = (item, index) => {
28492
28655
  const { dayOrder } = item.node;
@@ -28630,7 +28793,7 @@ const getServiceTypePriority = (serviceType) => {
28630
28793
  const Itinerary = ({ isOpen, handleSetIsOpen, isLoading, onEditAccommodation }) => {
28631
28794
  const context = useContext(SearchResultsConfigurationContext);
28632
28795
  const translations = getTranslations(context?.languageCode ?? 'en-GB');
28633
- const { editablePackagingEntry, priceDetails } = useSelector((state) => state.searchResults);
28796
+ const { editablePackagingEntry, priceDetails, trajectItineraryView } = useSelector((state) => state.searchResults);
28634
28797
  const dispatch = useDispatch();
28635
28798
  const packagingEntry = editablePackagingEntry ?? context?.packagingEntry;
28636
28799
  const sortedLines = useMemo(() => {
@@ -28673,6 +28836,11 @@ const Itinerary = ({ isOpen, handleSetIsOpen, isLoading, onEditAccommodation })
28673
28836
  const handleConfirm = () => {
28674
28837
  dispatch(setBookPackagingEntry(true));
28675
28838
  };
28839
+ const handleTrajectView = (itinerary) => {
28840
+ dispatch(setTrajectItineraryView(itinerary));
28841
+ if (typeof window !== 'undefined')
28842
+ window.scrollTo(0, 0);
28843
+ };
28676
28844
  return (React__default.createElement("div", { className: `search__filters--modal ${isOpen ? 'is-open' : ''}` },
28677
28845
  React__default.createElement("div", { className: "search__filters--background", onClick: handleSetIsOpen }),
28678
28846
  React__default.createElement("button", { className: "search__filters--close", onClick: handleSetIsOpen },
@@ -28700,7 +28868,8 @@ const Itinerary = ({ isOpen, handleSetIsOpen, isLoading, onEditAccommodation })
28700
28868
  " ",
28701
28869
  translations.SRP.TOTAL,
28702
28870
  ")"))),
28703
- React__default.createElement("button", { className: "cta", onClick: handleConfirm }, translations.QSM.CONFIRM)))),
28871
+ React__default.createElement("button", { className: "cta", onClick: handleConfirm }, translations.QSM.CONFIRM),
28872
+ !!context?.trajectEntry && (React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleTrajectView(!trajectItineraryView) }, trajectItineraryView ? translations.SRP.SHOW_SERVICES : translations.SRP.VIEW_FULL_ITINERARY))))),
28704
28873
  React__default.createElement("div", { className: "search__filter__itinerary" },
28705
28874
  React__default.createElement("p", null, translations.SRP.DAY_BY_DAY),
28706
28875
  firstEntryLine && (React__default.createElement("div", { className: "search__filter__itinerary__country" },
@@ -30983,7 +31152,7 @@ const Filters = ({ initialFilters, filters, isOpen, handleSetIsOpen, isLoading,
30983
31152
  const max = filter.max ?? 100;
30984
31153
  const selectedMin = filter.selectedMin ?? min;
30985
31154
  const selectedMax = filter.selectedMax ?? max;
30986
- return (React__default.createElement(MultiRangeFilter, { min: min, max: max, selectedMin: selectedMin, selectedMax: selectedMax, valueFormatter: (value) => `${value}`, onChange: (newMin, newMax) => {
31155
+ return (React__default.createElement(MultiRangeFilter, { min: min, max: max, selectedMin: selectedMin, selectedMax: selectedMax, valueFormatter: (value) => (filter.property === 'price' ? value.toFixed(2).replace('.', ',') : `${value}`), onChange: (newMin, newMax) => {
30987
31156
  handleSliderChange(filter, newMin, newMax);
30988
31157
  } }));
30989
31158
  })(),
@@ -31686,7 +31855,7 @@ const FlyIn = ({ srpType, isOpen, setIsOpen, className = '', onPanelRef, details
31686
31855
  dispatch(setBookPackagingEntry(true));
31687
31856
  }
31688
31857
  };
31689
- 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' : ''}
31858
+ 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' : ''}
31690
31859
  ${flyInType === 'flight-outward-results' || flyInType === 'flight-return-results' || flyInType === 'traject-flight-results' ? 'flyin--flight' : ''}` },
31691
31860
  React__default.createElement("div", { className: `flyin__panel ${isOpen ? 'flyin__panel--active' : ''}`, ref: panelRef },
31692
31861
  React__default.createElement("div", { className: "flyin__content" },
@@ -32475,7 +32644,7 @@ const FlightFilters = ({ isOpen, handleSetIsOpen, isLoading }) => {
32475
32644
  !isEmpty$1(priceRangeValues) &&
32476
32645
  (() => {
32477
32646
  return (React__default.createElement("div", { className: "search__filter-rows" },
32478
- React__default.createElement(MultiRangeFilter, { min: minPrice, max: maxPrice, selectedMin: first(priceRangeValues) ?? minPrice, selectedMax: last(priceRangeValues) ?? maxPrice, valueFormatter: (value) => `€${value}`, onChange: (newMin, newMax) => {
32647
+ React__default.createElement(MultiRangeFilter, { min: minPrice, max: maxPrice, selectedMin: first(priceRangeValues) ?? minPrice, selectedMax: last(priceRangeValues) ?? maxPrice, valueFormatter: (value) => `€${value.toFixed(2).replace('.', ',')}`, onChange: (newMin, newMax) => {
32479
32648
  handlePriceSliderChange([newMin, newMax]);
32480
32649
  } })));
32481
32650
  })()))))));
@@ -33153,6 +33322,27 @@ const getRequestRoomsFromPackagingSegments = (entry, segments) => {
33153
33322
  }));
33154
33323
  };
33155
33324
 
33325
+ /**
33326
+ * The entry to send to the backend, as opposed to the one the page works with.
33327
+ *
33328
+ * They differ only for a traject: the page keeps the line guids the traject was rendered with,
33329
+ * because that is what joins its nodes to its lines, while pricing and booking need the guids the
33330
+ * searches cached their lines under. Anything else passes through untouched, so this can be used
33331
+ * wherever the entry leaves the component without checking which flow is running.
33332
+ */
33333
+ const useBookableEntry = () => {
33334
+ const context = useContext(SearchResultsConfigurationContext);
33335
+ const { editablePackagingEntry, trajectNodeAvailability, trajectFlightAvailability } = useSelector((state) => state.searchResults);
33336
+ const trajectEntry = context?.trajectEntry;
33337
+ return useMemo(() => {
33338
+ if (!editablePackagingEntry)
33339
+ return null;
33340
+ if (!trajectEntry)
33341
+ return editablePackagingEntry;
33342
+ return withCachedEntryLineGuids(editablePackagingEntry, trajectEntry, trajectNodeAvailability, trajectFlightAvailability);
33343
+ }, [editablePackagingEntry, trajectEntry, trajectNodeAvailability, trajectFlightAvailability]);
33344
+ };
33345
+
33156
33346
  const escapeHtml = (value) => {
33157
33347
  if (!value)
33158
33348
  return '';
@@ -33211,12 +33401,62 @@ const findAccommodationForDay = (nodes, currentDay) => {
33211
33401
  }
33212
33402
  return null;
33213
33403
  };
33214
- const buildItineraryHtml = (itinerary, translations) => {
33404
+ const formatTime = (time) => (time ? time.slice(0, 5) : '');
33405
+ /**
33406
+ * Whether generated content actually shows something.
33407
+ *
33408
+ * A content view whose data is missing still returns its wrapper markup, or the whitespace left by
33409
+ * a guard around its body — markup that renders as a blank gap. Only text or an image counts as
33410
+ * something the traveller can read.
33411
+ */
33412
+ const hasVisibleContent = (contents) => {
33413
+ if (!contents)
33414
+ return false;
33415
+ if (/<(img|svg|picture|video|iframe)\b/i.test(contents))
33416
+ return true;
33417
+ return (contents
33418
+ .replace(/<[^>]*>/g, ' ')
33419
+ .replace(/&nbsp;/gi, ' ')
33420
+ .trim().length > 0);
33421
+ };
33422
+ /** The legs of a flight, as the entry line records them. */
33423
+ const buildFlightHtml = (line) => {
33424
+ const flightLines = line.flightInformation?.flightLines ?? [];
33425
+ if (!flightLines.length)
33426
+ return '';
33427
+ const legs = flightLines
33428
+ .map((leg) => {
33429
+ const from = escapeHtml(leg.departureAirportDescription || leg.departureAirportCode);
33430
+ const to = escapeHtml(leg.arrivalAirportDescription || leg.arrivalAirportCode);
33431
+ const carrier = escapeHtml([leg.airlineDescription, leg.flightNumber].filter(Boolean).join(' '));
33432
+ return `<li>${from} ${formatTime(leg.departureTime)} &rarr; ${to} ${formatTime(leg.arrivalTime)}${carrier ? ` &middot; ${carrier}` : ''}</li>`;
33433
+ })
33434
+ .join('');
33435
+ return `<ul class="itinerary-item__legs">${legs}</ul>`;
33436
+ };
33437
+ /**
33438
+ * What to show for an item the generator returned no content for.
33439
+ *
33440
+ * An item comes back with a title and a template but an empty body whenever its template has no
33441
+ * content view of its own — flights, today. Rendering that empty body leaves a blank where a
33442
+ * service should be, so what the entry already knows about the line is drawn instead.
33443
+ */
33444
+ const buildFallbackHtml = (item, line) => {
33445
+ const details = [line?.accommodationName, line?.regimeName].filter(Boolean).join(' — ');
33446
+ return `
33447
+ <div class="itinerary-item__fallback">
33448
+ <h3 class="itinerary-item__fallback-title">${escapeHtml(item.title)}</h3>
33449
+ ${line ? buildFlightHtml(line) : ''}
33450
+ ${details ? `<p class="itinerary-item__fallback-details">${escapeHtml(details)}</p>` : ''}
33451
+ </div>
33452
+ `;
33453
+ };
33454
+ const buildItineraryHtml = (itinerary, translations, lines) => {
33215
33455
  if (!itinerary) {
33216
- return `
33217
- <div class="itinerary-shell">
33218
- <div class="itinerary-empty">Geen reisroute beschikbaar.</div>
33219
- </div>
33456
+ return `
33457
+ <div class="itinerary-shell">
33458
+ <div class="itinerary-empty">Geen reisroute beschikbaar.</div>
33459
+ </div>
33220
33460
  `;
33221
33461
  }
33222
33462
  const allNodes = itinerary.nodes ?? [];
@@ -33230,75 +33470,81 @@ const buildItineraryHtml = (itinerary, translations) => {
33230
33470
  const hasAccommodationInCurrentNode = uniqueItems.some(isAccommodationItem);
33231
33471
  const activeAccommodation = findAccommodationForDay(allNodes, startDay);
33232
33472
  const accommodationBanner = !hasAccommodationInCurrentNode && activeAccommodation
33233
- ? `
33234
- <div class="itinerary-node__accommodation-banner">
33235
- Accommodatie voor deze dag: <strong>${escapeHtml(getAccommodationName(activeAccommodation))}</strong>
33236
- </div>
33473
+ ? `
33474
+ <div class="itinerary-node__accommodation-banner">
33475
+ Accommodatie voor deze dag: <strong>${escapeHtml(getAccommodationName(activeAccommodation))}</strong>
33476
+ </div>
33237
33477
  `
33238
33478
  : '';
33239
33479
  const itemsHtml = hasItems
33240
33480
  ? uniqueItems
33241
- .map((item) => `
33242
- <article class="itinerary-item" data-template="${escapeHtml(item.templateName)}">
33243
- ${item.contents ?? ''}
33244
- </article>
33481
+ .map((item) => `
33482
+ <article class="itinerary-item" data-template="${escapeHtml(item.templateName)}">
33483
+ ${hasVisibleContent(item.contents)
33484
+ ? item.contents
33485
+ : buildFallbackHtml(item, lines.find((line) => line.guid === item.itemGuid))}
33486
+ </article>
33245
33487
  `)
33246
33488
  .join('')
33247
33489
  : `<div class="itinerary-node__empty">${translations.ITINERARY.NO_ITEMS}</div>`;
33248
- return `
33249
- <section class="itinerary-node">
33250
- <header class="itinerary-node__header">
33251
-
33252
- <div class="itinerary-node__day">
33253
- <p class="itinerary-node__day-day">${day}</p>
33254
- <p class="itinerary-node__day-month">${month}</p>
33255
- </div>
33256
-
33257
- <div>
33258
- <h2 class="itinerary-node__title">${escapeHtml(node.title)}</h2>
33259
- </div>
33260
- </header>
33261
-
33262
- <div class="itinerary-node__content">
33263
- ${accommodationBanner}
33264
- ${itemsHtml}
33265
- </div>
33266
- </section>
33490
+ return `
33491
+ <section class="itinerary-node">
33492
+ <header class="itinerary-node__header">
33493
+
33494
+ <div class="itinerary-node__day">
33495
+ <p class="itinerary-node__day-day">${day}</p>
33496
+ <p class="itinerary-node__day-month">${month}</p>
33497
+ </div>
33498
+
33499
+ <div>
33500
+ <h2 class="itinerary-node__title">${escapeHtml(node.title)}</h2>
33501
+ </div>
33502
+ </header>
33503
+
33504
+ <div class="itinerary-node__content">
33505
+ ${accommodationBanner}
33506
+ ${itemsHtml}
33507
+ </div>
33508
+ </section>
33267
33509
  `;
33268
33510
  })
33269
33511
  .join('');
33270
33512
  const defaultItemsHtml = itinerary.defaultItems && itinerary.defaultItems.length > 0
33271
- ? `
33272
- <section class="itinerary-default-items">
33273
- <h2 class="itinerary-default-items__title">Algemene info</h2>
33513
+ ? `
33514
+ <section class="itinerary-default-items">
33515
+ <h2 class="itinerary-default-items__title">Algemene info</h2>
33274
33516
  ${getUniqueItems(itinerary.defaultItems)
33275
- .map((item) => `
33276
- <article class="itinerary-item" data-template="${escapeHtml(item.templateName)}">
33277
- ${item.contents ?? ''}
33278
- </article>
33517
+ .map((item) => `
33518
+ <article class="itinerary-item" data-template="${escapeHtml(item.templateName)}">
33519
+ ${hasVisibleContent(item.contents)
33520
+ ? item.contents
33521
+ : buildFallbackHtml(item, lines.find((line) => line.guid === item.itemGuid))}
33522
+ </article>
33279
33523
  `)
33280
- .join('')}
33281
- </section>
33524
+ .join('')}
33525
+ </section>
33282
33526
  `
33283
33527
  : '';
33284
- return `
33285
- <div class="itinerary-shell">
33286
- ${itinerary.title ? `<header class="itinerary-shell__header"><h1 class="itinerary-shell__title">${escapeHtml(itinerary.title)}</h1></header>` : ''}
33287
-
33288
- <div class="itinerary-shell__content">
33289
- ${nodesHtml}
33290
- ${defaultItemsHtml}
33291
- </div>
33292
- </div>
33528
+ return `
33529
+ <div class="itinerary-shell">
33530
+ ${itinerary.title ? `<header class="itinerary-shell__header"><h1 class="itinerary-shell__title">${escapeHtml(itinerary.title)}</h1></header>` : ''}
33531
+
33532
+ <div class="itinerary-shell__content">
33533
+ ${nodesHtml}
33534
+ ${defaultItemsHtml}
33535
+ </div>
33536
+ </div>
33293
33537
  `;
33294
33538
  };
33295
33539
  const FullItinerary = ({ isLoading }) => {
33296
33540
  const { itinerary } = useSelector((state) => state.searchResults);
33297
33541
  const context = useContext(SearchResultsConfigurationContext);
33542
+ // The entry as it was sent: its line guids are the ones the itinerary items carry back.
33543
+ const bookableEntry = useBookableEntry();
33298
33544
  const translations = getTranslations(context?.languageCode ?? 'en-GB');
33299
33545
  const hostRef = useRef(null);
33300
33546
  const shadowRootRef = useRef(null);
33301
- const html = useMemo(() => buildItineraryHtml(itinerary, translations), [itinerary, translations]);
33547
+ const html = useMemo(() => buildItineraryHtml(itinerary, translations, bookableEntry?.lines ?? []), [itinerary, translations, bookableEntry]);
33302
33548
  useEffect(() => {
33303
33549
  if (isLoading) {
33304
33550
  return;
@@ -33309,141 +33555,170 @@ const FullItinerary = ({ isLoading }) => {
33309
33555
  }
33310
33556
  const shadowRoot = host.shadowRoot ?? host.attachShadow({ mode: 'open' });
33311
33557
  shadowRootRef.current = shadowRoot;
33312
- shadowRoot.innerHTML = `
33313
- <style>
33314
- :host {
33315
- all: initial;
33316
- display: block;
33317
- width: 100%;
33318
- }
33319
-
33320
- *,
33321
- *::before,
33322
- *::after {
33323
- box-sizing: border-box;
33324
- }
33325
-
33326
- .itinerary-shell {
33327
- width: 100%;
33328
- margin: 0 auto;
33329
- font-family: 'Outfit', sans-serif;
33330
- color: #222;
33331
- }
33332
-
33333
- .itinerary-shell__header {
33334
- margin-bottom: 24px;
33335
- }
33336
-
33337
- .itinerary-shell__title {
33338
- margin: 0;
33339
- font-size: 32px;
33340
- line-height: 1.2;
33341
- }
33342
-
33343
- .itinerary-shell__content {
33344
- display: grid;
33345
- gap: 24px;
33346
- }
33347
-
33348
- .itinerary-node {
33349
- border: 1px solid #e5e7eb;
33350
- border-radius: 16px;
33351
- overflow: hidden;
33352
- background: #fff;
33353
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
33354
- }
33355
-
33356
- .itinerary-node__header {
33357
- display: flex;
33358
- gap: 16px;
33359
- align-items: center;
33360
- border-bottom: 1px solid #eef0f2;
33361
- background: #fafafa;
33362
- }
33363
-
33364
- .itinerary-node__day {
33365
- flex: 50px 0 0;
33366
- display: flex;
33367
- flex-flow: column;
33368
- align-items: center;
33369
- justify-content: center;
33370
- background: #1f9470;
33371
- color: white;
33372
- border: 1.5px solid var(--tide-booking-color-secondary);
33373
- }
33374
-
33375
- .itinerary-node__day-month {
33376
- margin: 0px;
33377
- }
33378
-
33379
- .itinerary-node__day-day {
33380
- margin: 0px;
33381
- font-weight: var(--tide-booking-search-results-label-date-month-font-weight);
33382
- color: var(--tide-booking-search-results-label-date-month-color);
33383
- font-size: 24px;
33384
- }
33385
-
33386
- .itinerary-node__title {
33387
- margin: 0;
33388
- font-size: 22px;
33389
- line-height: 1.25;
33390
- }
33391
-
33392
- .itinerary-node__content {
33393
- display: grid;
33394
- gap: 20px;
33395
- padding: 20px;
33396
- }
33397
-
33398
- .itinerary-node__accommodation-banner {
33399
- padding: 12px 16px;
33400
- border: 1px solid #dbeafe;
33401
- border-radius: 12px;
33402
- background: #eff6ff;
33403
- color: #1e3a8a;
33404
- font-size: 14px;
33405
- line-height: 1.4;
33406
- }
33407
-
33408
- .itinerary-item {
33409
- display: block;
33410
- border-radius: 12px;
33411
- overflow: hidden;
33412
- background: #fff;
33413
- }
33414
-
33415
- .itinerary-node__empty,
33416
- .itinerary-empty {
33417
- padding: 20px;
33418
- border: 1px dashed #d1d5db;
33419
- border-radius: 12px;
33420
- color: #6b7280;
33421
- background: #fafafa;
33422
- }
33423
-
33424
- .itinerary-default-items {
33425
- border: 1px solid #e5e7eb;
33426
- border-radius: 16px;
33427
- padding: 20px;
33428
- background: #fff;
33429
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
33430
- }
33431
-
33432
- .itinerary-default-items__title {
33433
- margin: 0 0 16px;
33434
- font-size: 22px;
33435
- }
33436
-
33437
- @media (max-width: 768px) {
33438
- .itinerary-shell {
33439
- padding: 16px;
33440
- }
33441
- }
33442
-
33443
- ${itinerary?.styleSheetBody ?? ''}
33444
- </style>
33445
-
33446
- ${html}
33558
+ shadowRoot.innerHTML = `
33559
+ <style>
33560
+ :host {
33561
+ all: initial;
33562
+ display: block;
33563
+ width: 100%;
33564
+ }
33565
+
33566
+ *,
33567
+ *::before,
33568
+ *::after {
33569
+ box-sizing: border-box;
33570
+ }
33571
+
33572
+ .itinerary-shell {
33573
+ width: 100%;
33574
+ margin: 0 auto;
33575
+ font-family: 'Outfit', sans-serif;
33576
+ color: #222;
33577
+ }
33578
+
33579
+ .itinerary-shell__header {
33580
+ margin-bottom: 24px;
33581
+ }
33582
+
33583
+ .itinerary-shell__title {
33584
+ margin: 0;
33585
+ font-size: 32px;
33586
+ line-height: 1.2;
33587
+ }
33588
+
33589
+ .itinerary-shell__content {
33590
+ display: grid;
33591
+ gap: 24px;
33592
+ }
33593
+
33594
+ .itinerary-node {
33595
+ border: 1px solid #e5e7eb;
33596
+ border-radius: 16px;
33597
+ overflow: hidden;
33598
+ background: #fff;
33599
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
33600
+ }
33601
+
33602
+ .itinerary-node__header {
33603
+ display: flex;
33604
+ gap: 16px;
33605
+ align-items: center;
33606
+ border-bottom: 1px solid #eef0f2;
33607
+ background: #fafafa;
33608
+ }
33609
+
33610
+ .itinerary-node__day {
33611
+ flex: 50px 0 0;
33612
+ display: flex;
33613
+ flex-flow: column;
33614
+ align-items: center;
33615
+ justify-content: center;
33616
+ background: #1f9470;
33617
+ color: white;
33618
+ border: 1.5px solid var(--tide-booking-color-secondary);
33619
+ }
33620
+
33621
+ .itinerary-node__day-month {
33622
+ margin: 0px;
33623
+ }
33624
+
33625
+ .itinerary-node__day-day {
33626
+ margin: 0px;
33627
+ font-weight: var(--tide-booking-search-results-label-date-month-font-weight);
33628
+ color: var(--tide-booking-search-results-label-date-month-color);
33629
+ font-size: 24px;
33630
+ }
33631
+
33632
+ .itinerary-node__title {
33633
+ margin: 0;
33634
+ font-size: 22px;
33635
+ line-height: 1.25;
33636
+ }
33637
+
33638
+ .itinerary-node__content {
33639
+ display: grid;
33640
+ gap: 20px;
33641
+ padding: 20px;
33642
+ }
33643
+
33644
+ .itinerary-node__accommodation-banner {
33645
+ padding: 12px 16px;
33646
+ border: 1px solid #dbeafe;
33647
+ border-radius: 12px;
33648
+ background: #eff6ff;
33649
+ color: #1e3a8a;
33650
+ font-size: 14px;
33651
+ line-height: 1.4;
33652
+ }
33653
+
33654
+ .itinerary-item {
33655
+ display: block;
33656
+ border-radius: 12px;
33657
+ overflow: hidden;
33658
+ background: #fff;
33659
+ }
33660
+
33661
+ /* An item whose template has no content view of its own still has to read as a service. */
33662
+ .itinerary-item__fallback {
33663
+ padding: 16px 20px;
33664
+ border: 1px solid #e5e7eb;
33665
+ border-radius: 12px;
33666
+ }
33667
+
33668
+ .itinerary-item__fallback-title {
33669
+ margin: 0;
33670
+ font-size: 16px;
33671
+ font-weight: 600;
33672
+ color: #111827;
33673
+ }
33674
+
33675
+ .itinerary-item__legs {
33676
+ margin: 8px 0 0;
33677
+ padding-left: 18px;
33678
+ color: #374151;
33679
+ }
33680
+
33681
+ .itinerary-item__legs li + li {
33682
+ margin-top: 4px;
33683
+ }
33684
+
33685
+ .itinerary-item__fallback-details {
33686
+ margin: 8px 0 0;
33687
+ color: #6b7280;
33688
+ }
33689
+
33690
+ .itinerary-node__empty,
33691
+ .itinerary-empty {
33692
+ padding: 20px;
33693
+ border: 1px dashed #d1d5db;
33694
+ border-radius: 12px;
33695
+ color: #6b7280;
33696
+ background: #fafafa;
33697
+ }
33698
+
33699
+ .itinerary-default-items {
33700
+ border: 1px solid #e5e7eb;
33701
+ border-radius: 16px;
33702
+ padding: 20px;
33703
+ background: #fff;
33704
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
33705
+ }
33706
+
33707
+ .itinerary-default-items__title {
33708
+ margin: 0 0 16px;
33709
+ font-size: 22px;
33710
+ }
33711
+
33712
+ @media (max-width: 768px) {
33713
+ .itinerary-shell {
33714
+ padding: 16px;
33715
+ }
33716
+ }
33717
+
33718
+ ${itinerary?.styleSheetBody ?? ''}
33719
+ </style>
33720
+
33721
+ ${html}
33447
33722
  `;
33448
33723
  }, [html, itinerary?.styleSheetBody, isLoading]);
33449
33724
  return (React__default.createElement(React__default.Fragment, null,
@@ -33547,27 +33822,6 @@ const DayByDayExcursions = () => {
33547
33822
  })));
33548
33823
  };
33549
33824
 
33550
- /**
33551
- * The entry to send to the backend, as opposed to the one the page works with.
33552
- *
33553
- * They differ only for a traject: the page keeps the line guids the traject was rendered with,
33554
- * because that is what joins its nodes to its lines, while pricing and booking need the guids the
33555
- * searches cached their lines under. Anything else passes through untouched, so this can be used
33556
- * wherever the entry leaves the component without checking which flow is running.
33557
- */
33558
- const useBookableEntry = () => {
33559
- const context = useContext(SearchResultsConfigurationContext);
33560
- const { editablePackagingEntry, trajectNodeAvailability, trajectFlightAvailability } = useSelector((state) => state.searchResults);
33561
- const trajectEntry = context?.trajectEntry;
33562
- return useMemo(() => {
33563
- if (!editablePackagingEntry)
33564
- return null;
33565
- if (!trajectEntry)
33566
- return editablePackagingEntry;
33567
- return withCachedEntryLineGuids(editablePackagingEntry, trajectEntry, trajectNodeAvailability, trajectFlightAvailability);
33568
- }, [editablePackagingEntry, trajectEntry, trajectNodeAvailability, trajectFlightAvailability]);
33569
- };
33570
-
33571
33825
  const renderEditablePackagingEntrySummaryOptions = (editablePackagingEntry, priceDetails, translations, currencyCode) => {
33572
33826
  const priceDetailsByProduct = groupBy(priceDetails?.details ?? [], (detail) => `${detail.productCode}|${detail.accommodationCode}`);
33573
33827
  return (editablePackagingEntry?.lines ?? []).map((line) => {
@@ -34058,15 +34312,18 @@ const getNodeIcon = (node) => {
34058
34312
  const isRenderableNode = (node) => node.trajectNodeType === REGULAR_TRAJECT_NODE_TYPE &&
34059
34313
  (node.serviceType === ACCOMMODATION_SERVICE_TYPE || node.serviceType === EXCURSION_SERVICE_TYPE || node.serviceType === FLIGHT_SERVICE_TYPE);
34060
34314
  const MAX_DAY_ACTIVITIES = 6;
34315
+ const MAX_HOTEL_RESULTS = 6;
34061
34316
  const TrajectResults = ({ isLoading }) => {
34062
34317
  const context = useContext(SearchResultsConfigurationContext);
34063
34318
  const dispatch = useDispatch();
34064
34319
  const loadDay = useTrajectDayActivities();
34065
34320
  const translations = getTranslations(context?.languageCode ?? 'en-GB');
34066
34321
  const locale = getLocale(context?.languageCode ?? 'en-GB');
34067
- const { trajectNodeAvailability, trajectFlightAvailability, trajectDaySuggestions, editablePackagingEntry, trajectResolving } = useSelector((state) => state.searchResults);
34322
+ const { trajectNodeAvailability, trajectFlightAvailability, trajectDaySuggestions, editablePackagingEntry } = useSelector((state) => state.searchResults);
34068
34323
  const trajectEntry = context?.trajectEntry;
34069
34324
  const hideShowMoreResults = !!context?.hideShowMoreResults;
34325
+ const loadDayActivitiesOnDemand = !!context?.loadDayActivitiesOnDemand;
34326
+ const showNonPreferredHotels = !!context?.showNonPreferredHotels;
34070
34327
  const nodesWithLines = useMemo(() => (trajectEntry ? getTrajectNodesWithLines(trajectEntry) : []), [trajectEntry]);
34071
34328
  const lineByNodeId = useMemo(() => new Map(nodesWithLines.map((x) => [x.node.nodeId, x])), [nodesWithLines]);
34072
34329
  const nodesByDay = useMemo(() => {
@@ -34094,6 +34351,24 @@ const TrajectResults = ({ isLoading }) => {
34094
34351
  });
34095
34352
  return { stayByDay: byDay, stayStartByNodeId: byNodeId };
34096
34353
  }, [nodesWithLines]);
34354
+ /** Whether every node of the trip has an answer, one way or the other. */
34355
+ const tripResolved = useMemo(() => nodesWithLines
34356
+ .filter((x) => isSearchableTrajectNode(x.node) || isTrajectFlightNode(x.node))
34357
+ .every((x) => {
34358
+ const status = isTrajectFlightNode(x.node) ? trajectFlightAvailability[x.line.guid]?.status : trajectNodeAvailability[x.line.guid]?.status;
34359
+ return !!status && status !== 'loading';
34360
+ }), [nodesWithLines, trajectNodeAvailability, trajectFlightAvailability]);
34361
+ /**
34362
+ * Each day's activities are one more search, and a traject has as many as it has days. They go
34363
+ * out together, but only once the trip itself has resolved — sharing the connections with the
34364
+ * searches the trip cannot do without would only make those slower. A portal can turn the
34365
+ * automatic load off, and then each day waits for its own "show activities" click instead.
34366
+ */
34367
+ useEffect(() => {
34368
+ if (!trajectEntry || !tripResolved || loadDayActivitiesOnDemand)
34369
+ return;
34370
+ (trajectEntry.traject.days ?? []).filter((day) => stayByDay.has(day.order)).forEach((day) => loadDay(day));
34371
+ }, [trajectEntry, tripResolved, stayByDay, loadDayActivitiesOnDemand]);
34097
34372
  if (!context || !trajectEntry)
34098
34373
  return null;
34099
34374
  const handleSelect = (item, code) => {
@@ -34167,6 +34442,10 @@ const TrajectResults = ({ isLoading }) => {
34167
34442
  const selected = results.find((x) => x.code === availability?.selectedCode) ?? null;
34168
34443
  const configured = results.filter((x) => x.code !== selected?.code && !!findCandidateForResult(node, x));
34169
34444
  const others = results.filter((x) => x.code !== selected?.code && !findCandidateForResult(node, x));
34445
+ // A hotel row holds the hotels configured on the node; a portal can also let it fill up with
34446
+ // non-preferred hotels found in the area, the rest staying behind "show more".
34447
+ const fill = showNonPreferredHotels && node.serviceType === ACCOMMODATION_SERVICE_TYPE ? others.slice(0, Math.max(MAX_HOTEL_RESULTS - 1 - configured.length, 0)) : [];
34448
+ const remaining = others.length - fill.length;
34170
34449
  // No entry yet means the node's search has been queued but not dispatched — still loading.
34171
34450
  const status = availability?.status ?? 'loading';
34172
34451
  return (React__default.createElement(React__default.Fragment, { key: line.guid },
@@ -34186,12 +34465,12 @@ const TrajectResults = ({ isLoading }) => {
34186
34465
  node.preferredAccommodationName,
34187
34466
  " \u2014 ",
34188
34467
  translations.SRP.NO_RESULTS))),
34189
- 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 })))),
34190
- others.length > 0 && !hideShowMoreResults && (React__default.createElement("div", { className: "search__results__cards__actions" },
34468
+ React__default.createElement("div", { className: "search__results__cards search__results__cards--scroll" }, [selected, ...configured, ...fill].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 })))),
34469
+ remaining > 0 && !hideShowMoreResults && (React__default.createElement("div", { className: "search__results__cards__actions" },
34191
34470
  React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleShowMore(item) },
34192
34471
  translations.SRP.SHOW_MORE,
34193
34472
  " (",
34194
- others.length,
34473
+ remaining,
34195
34474
  ")")))))));
34196
34475
  };
34197
34476
  const handleSelectFlight = (item, flight) => {
@@ -34250,11 +34529,6 @@ const TrajectResults = ({ isLoading }) => {
34250
34529
  if (lines.length)
34251
34530
  dispatch(addEditableEntryLines(lines));
34252
34531
  };
34253
- const handleShowItinerary = () => {
34254
- dispatch(setTrajectItineraryView(true));
34255
- if (typeof window !== 'undefined')
34256
- window.scrollTo(0, 0);
34257
- };
34258
34532
  const handleShowMoreActivities = (dayOrder) => {
34259
34533
  dispatch(setTrajectActivitiesDayOrder(dayOrder));
34260
34534
  dispatch(setFlyInType('traject-day-activities'));
@@ -34279,16 +34553,17 @@ const TrajectResults = ({ isLoading }) => {
34279
34553
  const cards = buildDayActivityCards(items, trajectNodeAvailability, suggestions?.results ?? []);
34280
34554
  const nodesResolving = items.some((item) => (trajectNodeAvailability[item.line.guid]?.status ?? 'loading') === 'loading');
34281
34555
  const isSearching = suggestions?.status === 'loading';
34282
- const canSearch = !!getDayDestination(nodesWithLines, trajectNodeAvailability, day.order);
34556
+ // A day is worth filling only if the party is staying somewhere that night. The day they fly
34557
+ // home is covered by no stay — the last night was the night before — and nobody is looking for
34558
+ // something to do on it.
34559
+ const canSearch = stayByDay.has(day.order) && !!getDayDestination(nodesWithLines, trajectNodeAvailability, day.order);
34283
34560
  if (!items.length && !canSearch)
34284
34561
  return null;
34285
34562
  const visible = cards.slice(0, MAX_DAY_ACTIVITIES);
34286
34563
  const hidden = cards.length - visible.length;
34564
+ const awaitsRequest = loadDayActivitiesOnDemand && !suggestions && canSearch && !nodesResolving && hidden === 0;
34287
34565
  return (React__default.createElement(React__default.Fragment, { key: `activities-${day.order}` },
34288
- React__default.createElement("div", { className: "search__results__label search__results__label--secondary" },
34289
- React__default.createElement("div", { className: "search__results__label__date" },
34290
- React__default.createElement("p", { className: "search__results__label__date-date" }, format$2(new Date(day.date), 'd', { locale })),
34291
- React__default.createElement("p", null, format$2(new Date(day.date), 'MMM', { locale }))),
34566
+ React__default.createElement("div", { className: "search__results__label search__results__label--sub" },
34292
34567
  React__default.createElement("div", { className: "search__results__label__text" },
34293
34568
  React__default.createElement(Icon, { name: "ui-excursion", height: 16 }),
34294
34569
  React__default.createElement("h3", null,
@@ -34297,7 +34572,7 @@ const TrajectResults = ({ isLoading }) => {
34297
34572
  !!cards.length && React__default.createElement("div", { className: "search__results__cards search__results__cards--scroll" }, visible.map(renderActivityCard)),
34298
34573
  !nodesResolving && !isSearching && !cards.length && (!!items.length || !!suggestions) && (React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS)),
34299
34574
  React__default.createElement("div", { className: "search__results__cards__actions" },
34300
- !suggestions && canSearch && !cards.length && !hideShowMoreResults && (React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => loadDay(day) }, translations.SRP.SHOW_ACTIVITIES)),
34575
+ awaitsRequest && (React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => loadDay(day) }, translations.SRP.SHOW_ACTIVITIES)),
34301
34576
  hidden > 0 && !hideShowMoreResults && (React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleShowMoreActivities(day.order) },
34302
34577
  translations.SRP.SHOW_MORE,
34303
34578
  " (",
@@ -34314,35 +34589,32 @@ const TrajectResults = ({ isLoading }) => {
34314
34589
  };
34315
34590
  if (isLoading)
34316
34591
  return React__default.createElement(Spinner, { label: translations.SRP.LOADING_ITINERARY });
34317
- return (React__default.createElement(React__default.Fragment, null,
34318
- trajectEntry.traject.days.map((day) => {
34319
- const stay = stayByDay.get(day.order);
34320
- const dayNodes = (nodesByDay.get(day.order) ?? []).filter((node) => isRenderableNode(node) && lineByNodeId.has(node.nodeId));
34321
- const stayLeadsDay = !!stay && (stay.night > 0 || dayNodes[0]?.nodeId === stay.item.node.nodeId);
34322
- // Where the day's activities belong in the order: with the first excursion it carries.
34323
- const firstExcursionNodeId = dayNodes.find((node) => node.serviceType === EXCURSION_SERVICE_TYPE)?.nodeId;
34324
- const showDayHeader = stayLeadsDay || !!day.name?.trim();
34325
- return (React__default.createElement(React__default.Fragment, { key: `day-${day.order}` },
34326
- showDayHeader && renderDayHeader(day, stayLeadsDay ? stay : undefined),
34327
- dayNodes.map((node) => {
34328
- const item = lineByNodeId.get(node.nodeId);
34329
- if (node.serviceType === ACCOMMODATION_SERVICE_TYPE) {
34330
- const stayStart = stayStartByNodeId.get(node.nodeId);
34331
- const titledByDayHeader = stayLeadsDay && stay.item.node.nodeId === node.nodeId;
34332
- return renderServiceNode(item, !titledByDayHeader, stayStart && getStayTitle(stayStart));
34333
- }
34334
- // Every excursion the day holds is drawn once, in one block, where the first of
34335
- // them falls in the order — so the activities still sit between the stay and the
34336
- // flight that follow them.
34337
- if (node.serviceType === EXCURSION_SERVICE_TYPE) {
34338
- return node.nodeId === firstExcursionNodeId ? renderDayActivities(day) : null;
34339
- }
34340
- return renderFlightNode(item);
34341
- }),
34342
- firstExcursionNodeId === undefined && renderDayActivities(day)));
34343
- }),
34344
- React__default.createElement("div", { className: "search__results__cards__actions" },
34345
- React__default.createElement("button", { type: "button", className: "cta", disabled: trajectResolving, onClick: handleShowItinerary }, translations.STEPS.NEXT))));
34592
+ return (React__default.createElement(React__default.Fragment, null, trajectEntry.traject.days.map((day) => {
34593
+ const stay = stayByDay.get(day.order);
34594
+ const dayNodes = (nodesByDay.get(day.order) ?? []).filter((node) => isRenderableNode(node) && lineByNodeId.has(node.nodeId));
34595
+ const stayLeadsDay = !!stay && (stay.night > 0 || dayNodes[0]?.nodeId === stay.item.node.nodeId);
34596
+ // Where the day's activities belong in the order: with the first excursion it carries.
34597
+ const firstExcursionNodeId = dayNodes.find((node) => node.serviceType === EXCURSION_SERVICE_TYPE)?.nodeId;
34598
+ const showDayHeader = stayLeadsDay || !!day.name?.trim();
34599
+ return (React__default.createElement(React__default.Fragment, { key: `day-${day.order}` },
34600
+ showDayHeader && renderDayHeader(day, stayLeadsDay ? stay : undefined),
34601
+ dayNodes.map((node) => {
34602
+ const item = lineByNodeId.get(node.nodeId);
34603
+ if (node.serviceType === ACCOMMODATION_SERVICE_TYPE) {
34604
+ const stayStart = stayStartByNodeId.get(node.nodeId);
34605
+ const titledByDayHeader = stayLeadsDay && stay.item.node.nodeId === node.nodeId;
34606
+ return renderServiceNode(item, !titledByDayHeader, stayStart && getStayTitle(stayStart));
34607
+ }
34608
+ // Every excursion the day holds is drawn once, in one block, where the first of
34609
+ // them falls in the order — so the activities still sit between the stay and the
34610
+ // flight that follow them.
34611
+ if (node.serviceType === EXCURSION_SERVICE_TYPE) {
34612
+ return node.nodeId === firstExcursionNodeId ? renderDayActivities(day) : null;
34613
+ }
34614
+ return renderFlightNode(item);
34615
+ }),
34616
+ firstExcursionNodeId === undefined && renderDayActivities(day)));
34617
+ })));
34346
34618
  };
34347
34619
 
34348
34620
  const useTrajectAvailability = () => {
@@ -35289,6 +35561,9 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
35289
35561
  setPricesAreLoading(false);
35290
35562
  }
35291
35563
  };
35564
+ fetchPriceDetails();
35565
+ }, [editablePackagingEntry, bookableEntry, trajectResolving]);
35566
+ useEffect(() => {
35292
35567
  const fetchItinerary = async () => {
35293
35568
  if (!context || !context.packagingEntry || !editablePackagingEntry || isEmpty$1(editablePackagingEntry.lines))
35294
35569
  return;
@@ -35318,7 +35593,6 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
35318
35593
  setItineraryIsLoading(false);
35319
35594
  }
35320
35595
  };
35321
- fetchPriceDetails();
35322
35596
  fetchItinerary();
35323
35597
  }, [editablePackagingEntry, bookableEntry, trajectResolving, trajectItineraryView]);
35324
35598
  // Flight selection
@@ -35669,11 +35943,6 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
35669
35943
  address: {}
35670
35944
  };
35671
35945
  };
35672
- const handleComposeTraject = () => {
35673
- dispatch(setTrajectItineraryView(false));
35674
- if (typeof window !== 'undefined')
35675
- window.scrollTo(0, 0);
35676
- };
35677
35946
  const handleShowMoreFlights = (flyInType) => {
35678
35947
  dispatch(setFlyInType(flyInType));
35679
35948
  dispatch(setFlyInIsOpen(true));
@@ -35764,10 +36033,7 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
35764
36033
  selectedReturnKey && selectedReturn && (React__default.createElement(IndependentFlightOption, { key: `flight-${selectedReturnKey}`, item: selectedReturn.return, guid: selectedReturn.outwardGuid, selectedGuid: selectedReturn.outwardGuid, isOutward: false, showSelectedState: true, price: selectedReturn.price })),
35765
36034
  uniqueReturnFlights.map((result) => (React__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 })))))),
35766
36035
  context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.trajectEntry && !trajectItineraryView && (React__default.createElement(TrajectResults, { isLoading: isLoading })),
35767
- context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.trajectEntry && trajectItineraryView && (React__default.createElement(React__default.Fragment, null,
35768
- React__default.createElement("div", { className: "search__results__cards__actions" },
35769
- React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: handleComposeTraject }, translations.STEPS.PREVIOUS)),
35770
- React__default.createElement(FullItinerary, { isLoading: itineraryIsLoading }))),
36036
+ context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.trajectEntry && trajectItineraryView && (React__default.createElement(FullItinerary, { isLoading: itineraryIsLoading })),
35771
36037
  context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.packagingEntry && !context.trajectEntry && (React__default.createElement(FullItinerary, { isLoading: itineraryIsLoading })))),
35772
36038
  React__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 })))))))));
35773
36039
  };
@@ -38676,20 +38942,20 @@ function ItineraryMapView({ destinations: propDestinations, adults = 2, dateFrom
38676
38942
  const isStartEnd = dest.isStart || dest.isEnd;
38677
38943
  let iconHtml;
38678
38944
  if (isStartEnd) {
38679
- iconHtml = `
38680
- <div class="map-view__marker map-view__marker--plane">
38681
- <svg viewBox="0 0 576 512" fill="currentColor" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
38682
- <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"/>
38683
- </svg>
38945
+ iconHtml = `
38946
+ <div class="map-view__marker map-view__marker--plane">
38947
+ <svg viewBox="0 0 576 512" fill="currentColor" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
38948
+ <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"/>
38949
+ </svg>
38684
38950
  </div>`;
38685
38951
  }
38686
38952
  else {
38687
38953
  stopIndex++;
38688
38954
  const imgStyle = dest.imageUrl ? `style="background-image:url('${dest.imageUrl}')"` : '';
38689
- iconHtml = `
38690
- <div class="map-view__marker map-view__marker--stop" ${imgStyle}>
38691
- ${!dest.imageUrl ? `<span class="map-view__marker-number">${stopIndex}</span>` : ''}
38692
- <span class="map-view__marker-badge">${stopIndex}</span>
38955
+ iconHtml = `
38956
+ <div class="map-view__marker map-view__marker--stop" ${imgStyle}>
38957
+ ${!dest.imageUrl ? `<span class="map-view__marker-number">${stopIndex}</span>` : ''}
38958
+ <span class="map-view__marker-badge">${stopIndex}</span>
38693
38959
  </div>`;
38694
38960
  }
38695
38961
  const icon = L.divIcon({