@qite/tide-booking-component 1.4.93 → 1.4.95

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 (181) hide show
  1. package/.prettierrc +9 -9
  2. package/.vs/ProjectSettings.json +3 -3
  3. package/.vs/VSWorkspaceState.json +5 -5
  4. package/build/build-cjs/index.js +81 -27
  5. package/build/build-cjs/src/booking-wizard/features/booking/booking-slice.d.ts +2 -1
  6. package/build/build-cjs/src/booking-wizard/features/booking/selectors.d.ts +4 -3
  7. package/build/build-cjs/src/booking-wizard/features/price-details/price-details-slice.d.ts +1 -0
  8. package/build/build-cjs/src/booking-wizard/features/price-details/selectors.d.ts +1 -0
  9. package/build/build-cjs/src/booking-wizard/features/sidebar/sidebar.d.ts +1 -0
  10. package/build/build-cjs/src/booking-wizard/types.d.ts +1 -0
  11. package/build/build-cjs/src/shared/utils/localization-util.d.ts +1 -0
  12. package/build/build-esm/index.js +81 -27
  13. package/build/build-esm/src/booking-wizard/features/booking/booking-slice.d.ts +2 -1
  14. package/build/build-esm/src/booking-wizard/features/booking/selectors.d.ts +4 -3
  15. package/build/build-esm/src/booking-wizard/features/price-details/price-details-slice.d.ts +1 -0
  16. package/build/build-esm/src/booking-wizard/features/price-details/selectors.d.ts +1 -0
  17. package/build/build-esm/src/booking-wizard/features/sidebar/sidebar.d.ts +1 -0
  18. package/build/build-esm/src/booking-wizard/types.d.ts +1 -0
  19. package/build/build-esm/src/shared/utils/localization-util.d.ts +1 -0
  20. package/package.json +83 -83
  21. package/src/booking-product/components/age-select.tsx +35 -35
  22. package/src/booking-product/components/amount-input.tsx +51 -51
  23. package/src/booking-product/components/date-range-picker/calendar.tsx +155 -155
  24. package/src/booking-product/components/footer.tsx +54 -54
  25. package/src/booking-product/components/header.tsx +57 -57
  26. package/src/booking-product/components/icon.tsx +200 -200
  27. package/src/booking-product/components/list-view.tsx +54 -54
  28. package/src/booking-product/components/rating.tsx +21 -21
  29. package/src/booking-product/components/rooms.tsx +171 -171
  30. package/src/booking-product/constants.ts +1 -1
  31. package/src/booking-product/index.tsx +21 -21
  32. package/src/booking-product/settings-context.ts +16 -16
  33. package/src/booking-product/types.ts +30 -30
  34. package/src/booking-product/utils/api.ts +26 -26
  35. package/src/booking-product/utils/price.ts +28 -28
  36. package/src/booking-wizard/api-settings-slice.ts +24 -24
  37. package/src/booking-wizard/components/icon.tsx +398 -398
  38. package/src/booking-wizard/components/labeled-input.tsx +56 -56
  39. package/src/booking-wizard/components/labeled-select.tsx +54 -54
  40. package/src/booking-wizard/components/message.tsx +21 -21
  41. package/src/booking-wizard/components/multi-range-filter.tsx +99 -99
  42. package/src/booking-wizard/components/phone-input.tsx +146 -146
  43. package/src/booking-wizard/components/print-offer-button.tsx +53 -53
  44. package/src/booking-wizard/components/product-card.tsx +23 -23
  45. package/src/booking-wizard/declarations.d.ts +4 -4
  46. package/src/booking-wizard/features/booking/booking-self-contained.tsx +16 -1
  47. package/src/booking-wizard/features/booking/booking-slice.ts +9 -1
  48. package/src/booking-wizard/features/booking/booking.tsx +16 -1
  49. package/src/booking-wizard/features/booking/selectors.ts +5 -0
  50. package/src/booking-wizard/features/flight-options/flight-filter.tsx +371 -371
  51. package/src/booking-wizard/features/flight-options/flight-option-flight.tsx +354 -354
  52. package/src/booking-wizard/features/flight-options/flight-option-modal.tsx +211 -211
  53. package/src/booking-wizard/features/flight-options/flight-option.tsx +57 -57
  54. package/src/booking-wizard/features/flight-options/flight-utils.ts +423 -423
  55. package/src/booking-wizard/features/price-details/price-details-api.ts +20 -20
  56. package/src/booking-wizard/features/price-details/price-details-slice.ts +2 -0
  57. package/src/booking-wizard/features/price-details/selectors.ts +1 -0
  58. package/src/booking-wizard/features/price-details/util.ts +115 -115
  59. package/src/booking-wizard/features/product-options/no-options.tsx +18 -18
  60. package/src/booking-wizard/features/product-options/none-option.tsx +73 -73
  61. package/src/booking-wizard/features/product-options/option-booking-airline-group.tsx +53 -53
  62. package/src/booking-wizard/features/product-options/option-booking-group.tsx +152 -152
  63. package/src/booking-wizard/features/product-options/option-item.tsx +236 -236
  64. package/src/booking-wizard/features/product-options/option-pax-card.tsx +159 -159
  65. package/src/booking-wizard/features/product-options/option-pax-group.tsx +122 -122
  66. package/src/booking-wizard/features/product-options/option-room.tsx +226 -226
  67. package/src/booking-wizard/features/product-options/option-unit-group.tsx +138 -138
  68. package/src/booking-wizard/features/room-options/room-utils.ts +154 -154
  69. package/src/booking-wizard/features/room-options/room.tsx +123 -123
  70. package/src/booking-wizard/features/room-options/traveler-rooms.tsx +64 -64
  71. package/src/booking-wizard/features/sidebar/index.tsx +2 -0
  72. package/src/booking-wizard/features/sidebar/sidebar-flight.tsx +66 -66
  73. package/src/booking-wizard/features/sidebar/sidebar.tsx +17 -1
  74. package/src/booking-wizard/features/summary/summary-booking-option-pax.tsx +23 -23
  75. package/src/booking-wizard/features/summary/summary-booking-option-unit.tsx +23 -23
  76. package/src/booking-wizard/features/summary/summary-flight.tsx +36 -36
  77. package/src/booking-wizard/features/summary/summary-per-booking-option-group.tsx +60 -60
  78. package/src/booking-wizard/features/summary/summary-per-pax-option-group.tsx +56 -56
  79. package/src/booking-wizard/features/summary/summary-per-unit-option-group.tsx +58 -58
  80. package/src/booking-wizard/features/summary/summary-slice.ts +27 -27
  81. package/src/booking-wizard/features/travelers-form/travelers-form-slice.ts +157 -157
  82. package/src/booking-wizard/features/travelers-form/travelers-form-util.ts +10 -10
  83. package/src/booking-wizard/features/travelers-form/type-ahead-input.tsx +85 -85
  84. package/src/booking-wizard/features/travelers-form/validate-form.ts +178 -178
  85. package/src/booking-wizard/index.tsx +27 -27
  86. package/src/booking-wizard/store.ts +26 -26
  87. package/src/booking-wizard/types.ts +1 -0
  88. package/src/booking-wizard/use-offer-printer.ts +108 -108
  89. package/src/content/components/LanguageSwitcher.tsx +158 -158
  90. package/src/content/components/accordion.tsx +30 -30
  91. package/src/content/components/contact.tsx +211 -211
  92. package/src/content/components/personal-contact-form.tsx +809 -809
  93. package/src/content/header/index.tsx +43 -43
  94. package/src/content/header/types.ts +26 -26
  95. package/src/qsm/components/date-picker/index.tsx +152 -152
  96. package/src/qsm/components/date-range-picker/calendar-day.tsx +49 -49
  97. package/src/qsm/components/date-range-picker/calendar.tsx +211 -211
  98. package/src/qsm/components/date-range-picker/index.tsx +404 -404
  99. package/src/qsm/index.tsx +26 -26
  100. package/src/qsm/store/qsm-store.ts +13 -13
  101. package/src/search-results/components/flight/flight-card.tsx +38 -38
  102. package/src/search-results/components/flight/flight-leg.tsx +61 -61
  103. package/src/search-results/components/flight/flight-path.tsx +23 -23
  104. package/src/search-results/components/multi-range-filter.tsx +104 -104
  105. package/src/search-results/components/search-results-container/search-results-container.tsx +2 -2
  106. package/src/search-results/index.tsx +24 -24
  107. package/src/search-results/search-results-configuration-context.ts +6 -6
  108. package/src/search-results/store/search-results-store.ts +13 -13
  109. package/src/shared/components/loader.tsx +16 -16
  110. package/src/shared/translations/ar-SA.json +2 -1
  111. package/src/shared/translations/da-DK.json +2 -1
  112. package/src/shared/translations/de-DE.json +2 -1
  113. package/src/shared/translations/en-GB.json +2 -1
  114. package/src/shared/translations/es-ES.json +2 -1
  115. package/src/shared/translations/fr-BE.json +2 -1
  116. package/src/shared/translations/fr-FR.json +2 -1
  117. package/src/shared/translations/is-IS.json +2 -1
  118. package/src/shared/translations/it-IT.json +2 -1
  119. package/src/shared/translations/ja-JP.json +2 -1
  120. package/src/shared/translations/nl-BE.json +2 -1
  121. package/src/shared/translations/nl-NL.json +2 -1
  122. package/src/shared/translations/no-NO.json +2 -1
  123. package/src/shared/translations/pl-PL.json +2 -1
  124. package/src/shared/translations/pt-PT.json +2 -1
  125. package/src/shared/translations/sv-SE.json +2 -1
  126. package/src/shared/utils/class-util.ts +7 -7
  127. package/src/shared/utils/query-string-util.ts +91 -91
  128. package/src/shared/utils/tide-api-utils.ts +34 -34
  129. package/src/shared/utils/use-media-query-util.ts +19 -19
  130. package/styles/abstracts/_mixins.scss +74 -74
  131. package/styles/abstracts/_variables.scss +57 -57
  132. package/styles/base/_fonts.scss +2 -2
  133. package/styles/base/_normalize.scss +227 -227
  134. package/styles/base/_typography.scss +35 -35
  135. package/styles/booking-joker-variables.scss +596 -596
  136. package/styles/booking-product-variables.scss +330 -330
  137. package/styles/booking-product.scss +438 -438
  138. package/styles/booking-qsm-variables.scss +501 -501
  139. package/styles/booking-qsm.scss +52 -52
  140. package/styles/booking-wizard-variables.scss +603 -603
  141. package/styles/booking-wizard.scss +61 -61
  142. package/styles/components/_accordion.scss +67 -67
  143. package/styles/components/_animations.scss +39 -39
  144. package/styles/components/_base.scss +107 -107
  145. package/styles/components/_breadcrumb.scss +92 -92
  146. package/styles/components/_button.scss +238 -238
  147. package/styles/components/_checkbox.scss +230 -230
  148. package/styles/components/_contact.scss +239 -239
  149. package/styles/components/_cta.scss +238 -238
  150. package/styles/components/_date-list.scss +41 -41
  151. package/styles/components/_date-range-picker.scss +223 -223
  152. package/styles/components/_decrement-increment.scss +35 -35
  153. package/styles/components/_dropdown.scss +72 -72
  154. package/styles/components/_faq.scss +27 -27
  155. package/styles/components/_flight-option.scss +1419 -1419
  156. package/styles/components/_gallery.scss +314 -314
  157. package/styles/components/_header.scss +113 -113
  158. package/styles/components/_img-slider.scss +175 -175
  159. package/styles/components/_info-message.scss +75 -75
  160. package/styles/components/_input.scss +35 -35
  161. package/styles/components/_list.scss +185 -185
  162. package/styles/components/_loader.scss +70 -70
  163. package/styles/components/_mixins.scss +579 -579
  164. package/styles/components/_passenger-picker.scss +306 -306
  165. package/styles/components/_phone-input.scss +8 -8
  166. package/styles/components/_placeholders.scss +165 -165
  167. package/styles/components/_qsm.scss +17 -17
  168. package/styles/components/_radiobutton.scss +170 -170
  169. package/styles/components/_select-wrapper.scss +76 -76
  170. package/styles/components/_slider.scss +128 -128
  171. package/styles/components/_spinner.scss +29 -29
  172. package/styles/components/_step-indicators.scss +161 -161
  173. package/styles/components/_table.scss +81 -81
  174. package/styles/components/_typeahead.scss +275 -275
  175. package/styles/components/_variables.scss +89 -89
  176. package/styles/content-blocks-variables.scss +507 -507
  177. package/styles/font.scss +2 -2
  178. package/styles/qsm/_calendar.scss +274 -274
  179. package/styles/qsm/_qsm.scss +1094 -1094
  180. package/styles/search.scss +1200 -1200
  181. package/tsconfig.json +24 -24
@@ -1,146 +1,146 @@
1
- import React, { useEffect, useMemo, useState } from 'react';
2
- import { buildClassName } from '../../shared/utils/class-util';
3
- import { compact } from 'lodash';
4
- import { Country } from '../types';
5
-
6
- interface PhoneInputProps {
7
- name: string;
8
- required?: boolean;
9
- value?: string | number;
10
- label?: string;
11
- placeholder?: string;
12
- hasError?: boolean;
13
- extraClassName?: string;
14
- countries: Country[];
15
- countryIso2?: string; // Initial country selection (ISO2 code)
16
- onChange?: React.ChangeEventHandler<HTMLElement>;
17
- onBlur?: React.FocusEventHandler<HTMLElement>;
18
- }
19
-
20
- const normalize = (v?: string | number) => (v == null ? '' : String(v));
21
-
22
- const parseCombined = (raw: string, countries: Country[]): { prefix: string; number: string } => {
23
- const value = normalize(raw).trim();
24
- if (!value) return { prefix: '', number: '' };
25
-
26
- // Try to match a known prefix at the start. Prefer longest match.
27
- const sorted = [...countries].sort((a, b) => b.phonePrefix.length - a.phonePrefix.length);
28
- const hit = sorted.find((c) => value.startsWith(c.phonePrefix));
29
- if (hit) {
30
- const rest = value
31
- .slice(hit.phonePrefix.length)
32
- .trim()
33
- .replace(/^[-\s]+/, '');
34
- return { prefix: hit.phonePrefix, number: rest };
35
- }
36
-
37
- // Fallback: split on first space if it looks like a +prefix number
38
- const m = value.match(/^(\+\d{1,4})[\s-]*(.*)$/);
39
- if (m) return { prefix: m[1], number: m[2] };
40
-
41
- return { prefix: '', number: value };
42
- };
43
-
44
- const PhoneInput: React.FC<PhoneInputProps> = ({
45
- name,
46
- required,
47
- value,
48
- label,
49
- placeholder,
50
- extraClassName,
51
- hasError,
52
- countries,
53
- countryIso2,
54
- onChange,
55
- onBlur
56
- }) => {
57
- // Derive initial state from `value`
58
- const initialCountry = countries.find((c) => c.iso2 === countryIso2);
59
-
60
- const initial = useMemo(() => parseCombined(normalize(value), countries), [value, countries]);
61
- const [prefix, setPrefix] = useState<string>(initial.prefix);
62
- const [number, setNumber] = useState<string>(initial.number);
63
-
64
- // Keep state in sync if the parent changes `value`
65
- useEffect(() => {
66
- const parsed = !prefix && !number && initialCountry ? { prefix: initialCountry.phonePrefix, number: '' } : parseCombined(normalize(value), countries);
67
- if (parsed.prefix) setPrefix(parsed.prefix);
68
- if (parsed.number) setNumber(parsed.number);
69
- }, [value, countries, countryIso2]);
70
-
71
- const emitCombinedChange = (e: React.ChangeEvent<HTMLElement>, nextPrefix: string, nextNumber: string) => {
72
- // Combine with a space, unless the number already starts with a dash or space
73
- const combined = nextPrefix && nextNumber ? compact([nextPrefix, nextNumber]).join(' ') : null;
74
- onChange?.({
75
- ...e,
76
- type: 'change',
77
- target: { name, value: combined },
78
- currentTarget: { name, value: combined }
79
- } as any);
80
- };
81
-
82
- const handleCountryBlur = (e: React.FocusEvent<HTMLSelectElement>) => {
83
- onBlur?.(e);
84
- };
85
-
86
- const onCountryChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
87
- const next = e.target.value;
88
- setPrefix(next);
89
- emitCombinedChange(e, next, number);
90
- };
91
-
92
- const onPhoneChange = (e: React.ChangeEvent<HTMLInputElement>) => {
93
- const cleaned = e.target.value.replace(/[^\d\s-]/g, '');
94
- setNumber(cleaned);
95
- emitCombinedChange(e, prefix, cleaned);
96
- };
97
-
98
- const handleNumberBlur = (e: React.FocusEvent<HTMLInputElement>) => {
99
- onBlur?.(e);
100
- };
101
-
102
- // Ensure the select shows a reasonable default when prefix is empty
103
- const selectValue = prefix || '';
104
-
105
- return (
106
- <label className={buildClassName(['form__group', extraClassName, hasError && 'form__group--error'])}>
107
- {label && <span className="form__label">{compact([label, required && '*']).join(' ')}</span>}
108
-
109
- <div className="phone-input">
110
- <div className="dropdown">
111
- <select
112
- aria-label={label ? `${label} – country code` : 'Country calling code'}
113
- name={`${name}__country`}
114
- value={selectValue}
115
- onBlur={handleCountryBlur}
116
- onChange={onCountryChange}>
117
- <option value="" disabled></option>
118
- {countries?.map((option) => (
119
- <option key={option.iso2} value={option.phonePrefix}>
120
- {option.name} ({option.phonePrefix})
121
- </option>
122
- ))}
123
- </select>
124
- </div>
125
-
126
- <input
127
- aria-label={label ? `${label} – number` : 'Phone number'}
128
- name={`${name}__number`}
129
- type="tel"
130
- inputMode="tel"
131
- required={required}
132
- className="form__input"
133
- placeholder={placeholder}
134
- onChange={onPhoneChange}
135
- onBlur={handleNumberBlur}
136
- value={number}
137
- />
138
-
139
- {/* Hidden merged value to integrate with forms that expect a single field */}
140
- <input type="hidden" name={name} value={compact([prefix, number]).join(' ')} />
141
- </div>
142
- </label>
143
- );
144
- };
145
-
146
- export default PhoneInput;
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import { buildClassName } from '../../shared/utils/class-util';
3
+ import { compact } from 'lodash';
4
+ import { Country } from '../types';
5
+
6
+ interface PhoneInputProps {
7
+ name: string;
8
+ required?: boolean;
9
+ value?: string | number;
10
+ label?: string;
11
+ placeholder?: string;
12
+ hasError?: boolean;
13
+ extraClassName?: string;
14
+ countries: Country[];
15
+ countryIso2?: string; // Initial country selection (ISO2 code)
16
+ onChange?: React.ChangeEventHandler<HTMLElement>;
17
+ onBlur?: React.FocusEventHandler<HTMLElement>;
18
+ }
19
+
20
+ const normalize = (v?: string | number) => (v == null ? '' : String(v));
21
+
22
+ const parseCombined = (raw: string, countries: Country[]): { prefix: string; number: string } => {
23
+ const value = normalize(raw).trim();
24
+ if (!value) return { prefix: '', number: '' };
25
+
26
+ // Try to match a known prefix at the start. Prefer longest match.
27
+ const sorted = [...countries].sort((a, b) => b.phonePrefix.length - a.phonePrefix.length);
28
+ const hit = sorted.find((c) => value.startsWith(c.phonePrefix));
29
+ if (hit) {
30
+ const rest = value
31
+ .slice(hit.phonePrefix.length)
32
+ .trim()
33
+ .replace(/^[-\s]+/, '');
34
+ return { prefix: hit.phonePrefix, number: rest };
35
+ }
36
+
37
+ // Fallback: split on first space if it looks like a +prefix number
38
+ const m = value.match(/^(\+\d{1,4})[\s-]*(.*)$/);
39
+ if (m) return { prefix: m[1], number: m[2] };
40
+
41
+ return { prefix: '', number: value };
42
+ };
43
+
44
+ const PhoneInput: React.FC<PhoneInputProps> = ({
45
+ name,
46
+ required,
47
+ value,
48
+ label,
49
+ placeholder,
50
+ extraClassName,
51
+ hasError,
52
+ countries,
53
+ countryIso2,
54
+ onChange,
55
+ onBlur
56
+ }) => {
57
+ // Derive initial state from `value`
58
+ const initialCountry = countries.find((c) => c.iso2 === countryIso2);
59
+
60
+ const initial = useMemo(() => parseCombined(normalize(value), countries), [value, countries]);
61
+ const [prefix, setPrefix] = useState<string>(initial.prefix);
62
+ const [number, setNumber] = useState<string>(initial.number);
63
+
64
+ // Keep state in sync if the parent changes `value`
65
+ useEffect(() => {
66
+ const parsed = !prefix && !number && initialCountry ? { prefix: initialCountry.phonePrefix, number: '' } : parseCombined(normalize(value), countries);
67
+ if (parsed.prefix) setPrefix(parsed.prefix);
68
+ if (parsed.number) setNumber(parsed.number);
69
+ }, [value, countries, countryIso2]);
70
+
71
+ const emitCombinedChange = (e: React.ChangeEvent<HTMLElement>, nextPrefix: string, nextNumber: string) => {
72
+ // Combine with a space, unless the number already starts with a dash or space
73
+ const combined = nextPrefix && nextNumber ? compact([nextPrefix, nextNumber]).join(' ') : null;
74
+ onChange?.({
75
+ ...e,
76
+ type: 'change',
77
+ target: { name, value: combined },
78
+ currentTarget: { name, value: combined }
79
+ } as any);
80
+ };
81
+
82
+ const handleCountryBlur = (e: React.FocusEvent<HTMLSelectElement>) => {
83
+ onBlur?.(e);
84
+ };
85
+
86
+ const onCountryChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
87
+ const next = e.target.value;
88
+ setPrefix(next);
89
+ emitCombinedChange(e, next, number);
90
+ };
91
+
92
+ const onPhoneChange = (e: React.ChangeEvent<HTMLInputElement>) => {
93
+ const cleaned = e.target.value.replace(/[^\d\s-]/g, '');
94
+ setNumber(cleaned);
95
+ emitCombinedChange(e, prefix, cleaned);
96
+ };
97
+
98
+ const handleNumberBlur = (e: React.FocusEvent<HTMLInputElement>) => {
99
+ onBlur?.(e);
100
+ };
101
+
102
+ // Ensure the select shows a reasonable default when prefix is empty
103
+ const selectValue = prefix || '';
104
+
105
+ return (
106
+ <label className={buildClassName(['form__group', extraClassName, hasError && 'form__group--error'])}>
107
+ {label && <span className="form__label">{compact([label, required && '*']).join(' ')}</span>}
108
+
109
+ <div className="phone-input">
110
+ <div className="dropdown">
111
+ <select
112
+ aria-label={label ? `${label} – country code` : 'Country calling code'}
113
+ name={`${name}__country`}
114
+ value={selectValue}
115
+ onBlur={handleCountryBlur}
116
+ onChange={onCountryChange}>
117
+ <option value="" disabled></option>
118
+ {countries?.map((option) => (
119
+ <option key={option.iso2} value={option.phonePrefix}>
120
+ {option.name} ({option.phonePrefix})
121
+ </option>
122
+ ))}
123
+ </select>
124
+ </div>
125
+
126
+ <input
127
+ aria-label={label ? `${label} – number` : 'Phone number'}
128
+ name={`${name}__number`}
129
+ type="tel"
130
+ inputMode="tel"
131
+ required={required}
132
+ className="form__input"
133
+ placeholder={placeholder}
134
+ onChange={onPhoneChange}
135
+ onBlur={handleNumberBlur}
136
+ value={number}
137
+ />
138
+
139
+ {/* Hidden merged value to integrate with forms that expect a single field */}
140
+ <input type="hidden" name={name} value={compact([prefix, number]).join(' ')} />
141
+ </div>
142
+ </label>
143
+ );
144
+ };
145
+
146
+ export default PhoneInput;
@@ -1,53 +1,53 @@
1
- import React from 'react';
2
- import { BookingPackage, Pax } from '@qite/tide-client/build/types';
3
- import { useOfferPrinter } from '../use-offer-printer';
4
-
5
- interface PrintOfferButtonProps {
6
- bookingPackage?: BookingPackage;
7
-
8
- getPax: () => Pax[] | undefined;
9
-
10
- tagIds?: number[];
11
-
12
- printActionId?: number | null;
13
-
14
- onPrinted?: (pdfUrl: string) => void;
15
-
16
- labelIdle?: string;
17
- labelCreating?: string;
18
- labelPrinting?: string;
19
- disabled?: boolean;
20
- className?: string;
21
- loader?: React.ReactNode;
22
- }
23
-
24
- const PrintOfferButton: React.FC<PrintOfferButtonProps> = ({
25
- bookingPackage,
26
- getPax,
27
- tagIds,
28
- printActionId = null,
29
- onPrinted,
30
- labelIdle = 'Print offer',
31
- labelCreating = 'Generating offer…',
32
- labelPrinting = 'Generating PDF…',
33
- disabled = false,
34
- className
35
- }) => {
36
- const { handlePrint, stage, loading } = useOfferPrinter({
37
- bookingPackage,
38
- getPax,
39
- tagIds,
40
- onPrinted,
41
- printActionId
42
- });
43
-
44
- const label = stage === 'creating' ? labelCreating : stage === 'printing' ? labelPrinting : labelIdle;
45
-
46
- return (
47
- <button type="button" onClick={handlePrint} disabled={disabled || loading} className={className}>
48
- {label}
49
- </button>
50
- );
51
- };
52
-
53
- export default PrintOfferButton;
1
+ import React from 'react';
2
+ import { BookingPackage, Pax } from '@qite/tide-client/build/types';
3
+ import { useOfferPrinter } from '../use-offer-printer';
4
+
5
+ interface PrintOfferButtonProps {
6
+ bookingPackage?: BookingPackage;
7
+
8
+ getPax: () => Pax[] | undefined;
9
+
10
+ tagIds?: number[];
11
+
12
+ printActionId?: number | null;
13
+
14
+ onPrinted?: (pdfUrl: string) => void;
15
+
16
+ labelIdle?: string;
17
+ labelCreating?: string;
18
+ labelPrinting?: string;
19
+ disabled?: boolean;
20
+ className?: string;
21
+ loader?: React.ReactNode;
22
+ }
23
+
24
+ const PrintOfferButton: React.FC<PrintOfferButtonProps> = ({
25
+ bookingPackage,
26
+ getPax,
27
+ tagIds,
28
+ printActionId = null,
29
+ onPrinted,
30
+ labelIdle = 'Print offer',
31
+ labelCreating = 'Generating offer…',
32
+ labelPrinting = 'Generating PDF…',
33
+ disabled = false,
34
+ className
35
+ }) => {
36
+ const { handlePrint, stage, loading } = useOfferPrinter({
37
+ bookingPackage,
38
+ getPax,
39
+ tagIds,
40
+ onPrinted,
41
+ printActionId
42
+ });
43
+
44
+ const label = stage === 'creating' ? labelCreating : stage === 'printing' ? labelPrinting : labelIdle;
45
+
46
+ return (
47
+ <button type="button" onClick={handlePrint} disabled={disabled || loading} className={className}>
48
+ {label}
49
+ </button>
50
+ );
51
+ };
52
+
53
+ export default PrintOfferButton;
@@ -1,23 +1,23 @@
1
- import React from 'react';
2
-
3
- interface ProductCardProps {
4
- productName: string;
5
- thumbnailUrl?: string;
6
- handleToggleClick: () => void;
7
- }
8
-
9
- const ProductCard: React.FC<ProductCardProps> = ({ productName, thumbnailUrl, handleToggleClick }) => {
10
- return (
11
- <div className="booking__product">
12
- <div className="booking__product-image">
13
- {thumbnailUrl && <img src={`${thumbnailUrl}?height=400&width=400`} alt={productName} className="mediacontent" />}
14
- </div>
15
- <div className="booking__product-text">
16
- <h3 className="booking__product-heading">{productName}</h3>
17
- </div>
18
- <button type="button" className="booking__product-toggle" onClick={handleToggleClick}></button>
19
- </div>
20
- );
21
- };
22
-
23
- export default ProductCard;
1
+ import React from 'react';
2
+
3
+ interface ProductCardProps {
4
+ productName: string;
5
+ thumbnailUrl?: string;
6
+ handleToggleClick: () => void;
7
+ }
8
+
9
+ const ProductCard: React.FC<ProductCardProps> = ({ productName, thumbnailUrl, handleToggleClick }) => {
10
+ return (
11
+ <div className="booking__product">
12
+ <div className="booking__product-image">
13
+ {thumbnailUrl && <img src={`${thumbnailUrl}?height=400&width=400`} alt={productName} className="mediacontent" />}
14
+ </div>
15
+ <div className="booking__product-text">
16
+ <h3 className="booking__product-heading">{productName}</h3>
17
+ </div>
18
+ <button type="button" className="booking__product-toggle" onClick={handleToggleClick}></button>
19
+ </div>
20
+ );
21
+ };
22
+
23
+ export default ProductCard;
@@ -1,4 +1,4 @@
1
- declare module '*.svg' {
2
- const content: string;
3
- export default content;
4
- }
1
+ declare module '*.svg' {
2
+ const content: string;
3
+ export default content;
4
+ }
@@ -22,6 +22,7 @@ import {
22
22
  setLanguageCode,
23
23
  setOfficeId,
24
24
  setProductAttributes,
25
+ setShowCommission,
25
26
  setSkipPayment,
26
27
  setTagIds,
27
28
  setTranslations
@@ -74,6 +75,7 @@ const BookingSelfContained: React.FC<BookingProps> = ({ productCode, productName
74
75
  officeId,
75
76
  bookingOptions,
76
77
  showSidebarDeposit,
78
+ showCommission,
77
79
  includeFlights,
78
80
  skipPaymentWithAgent,
79
81
  generatePaymentUrl,
@@ -199,6 +201,7 @@ const BookingSelfContained: React.FC<BookingProps> = ({ productCode, productName
199
201
  dispatch(setLanguageCode(language));
200
202
  dispatch(setBookingOptions(bookingOptions));
201
203
  dispatch(setCalculateDeposit(showSidebarDeposit));
204
+ dispatch(setShowCommission(showCommission));
202
205
  if (tagIds && tagIds.length > 0) {
203
206
  dispatch(setTagIds(tagIds ?? undefined));
204
207
  }
@@ -209,7 +212,19 @@ const BookingSelfContained: React.FC<BookingProps> = ({ productCode, productName
209
212
  if (accommodationViewId && accommodationViewId != 0) {
210
213
  dispatch(setAccommodationViewId(accommodationViewId));
211
214
  }
212
- }, [officeId, language, bookingOptions, showSidebarDeposit, setOfficeId, setLanguageCode, setCalculateDeposit, tagIds, agentAdressId, accommodationViewId]);
215
+ }, [
216
+ officeId,
217
+ language,
218
+ bookingOptions,
219
+ showSidebarDeposit,
220
+ showCommission,
221
+ setOfficeId,
222
+ setLanguageCode,
223
+ setCalculateDeposit,
224
+ tagIds,
225
+ agentAdressId,
226
+ accommodationViewId
227
+ ]);
213
228
 
214
229
  useEffect(() => {
215
230
  if (!productAttributes || !bookingAttributes || !rooms?.length || !isNil(bookingNumber) || !isNil(packageDetails)) {
@@ -29,6 +29,7 @@ import packageApi from './api';
29
29
  import { BookingStep, OPTIONS_FORM_STEP } from './constants';
30
30
  import {
31
31
  selectAccommodationCodes,
32
+ selectAgentAdressId,
32
33
  selectBookingAttributes,
33
34
  selectBookingRooms,
34
35
  selectLanguageCode,
@@ -43,6 +44,7 @@ export interface BookingState {
43
44
  productAttributes?: ProductAttributes;
44
45
  bookingAttributes?: BookingAttributes;
45
46
  calculateDeposit: boolean;
47
+ showCommission?: boolean;
46
48
  bookingNumber?: string;
47
49
  isRetry: boolean;
48
50
  package?: BookingPackage;
@@ -95,6 +97,7 @@ const initialState: BookingState = {
95
97
  productAttributes: undefined,
96
98
  bookingAttributes: undefined,
97
99
  calculateDeposit: false,
100
+ showCommission: false,
98
101
  bookingNumber: undefined,
99
102
  isRetry: false,
100
103
  package: undefined,
@@ -137,6 +140,7 @@ const fetchPackageDetails = createAsyncThunk('booking/details', async (_, { disp
137
140
  const productAttributes = selectProductAttributes(state);
138
141
  const bookingAttributes = selectBookingAttributes(state);
139
142
  const agentId = selectAgentId(state);
143
+ const agentAdressId = selectAgentAdressId(state);
140
144
  const rooms = selectBookingRooms(state);
141
145
  const languageCode = selectLanguageCode(state);
142
146
 
@@ -206,7 +210,7 @@ const fetchPackageDetails = createAsyncThunk('booking/details', async (_, { disp
206
210
 
207
211
  const request = {
208
212
  officeId: officeId,
209
- agentId: agentId,
213
+ agentId: agentId ?? agentAdressId,
210
214
  payload: {
211
215
  searchType: searchType,
212
216
  catalogueId: bookingAttributes.catalogueId,
@@ -380,6 +384,9 @@ const bookingSlice = createSlice({
380
384
  setCalculateDeposit(state, action: PayloadAction<boolean>) {
381
385
  state.calculateDeposit = action.payload;
382
386
  },
387
+ setShowCommission(state, action: PayloadAction<boolean | undefined>) {
388
+ state.showCommission = action.payload;
389
+ },
383
390
  setBookingNumber(state, action: PayloadAction<string>) {
384
391
  state.bookingNumber = action.payload;
385
392
  },
@@ -596,6 +603,7 @@ export const {
596
603
  setProductAttributes,
597
604
  setBookingAttributes,
598
605
  setCalculateDeposit,
606
+ setShowCommission,
599
607
  setBookingNumber,
600
608
  setIsRetry,
601
609
  setFetchingPackage,
@@ -25,6 +25,7 @@ import {
25
25
  setOfficeId,
26
26
  setPackage,
27
27
  setProductAttributes,
28
+ setShowCommission,
28
29
  setSkipPayment,
29
30
  setTagIds,
30
31
  setTranslations,
@@ -76,6 +77,7 @@ const Booking: React.FC<BookingProps> = ({ productCode, productName, thumbnailUr
76
77
  confirmation,
77
78
  error,
78
79
  showSidebarDeposit,
80
+ showCommission,
79
81
  includeFlights,
80
82
  loaderComponent,
81
83
  skipPaymentWithAgent,
@@ -232,6 +234,7 @@ const Booking: React.FC<BookingProps> = ({ productCode, productName, thumbnailUr
232
234
  dispatch(setLanguageCode(language));
233
235
  dispatch(setBookingOptions(bookingOptions));
234
236
  dispatch(setCalculateDeposit(showSidebarDeposit));
237
+ dispatch(setShowCommission(showCommission));
235
238
  if (tagIds && tagIds.length > 0) {
236
239
  dispatch(setTagIds(tagIds ?? undefined));
237
240
  }
@@ -242,7 +245,19 @@ const Booking: React.FC<BookingProps> = ({ productCode, productName, thumbnailUr
242
245
  if (accommodationViewId && accommodationViewId != 0) {
243
246
  dispatch(setAccommodationViewId(accommodationViewId));
244
247
  }
245
- }, [officeId, language, bookingOptions, showSidebarDeposit, setOfficeId, setLanguageCode, setCalculateDeposit, tagIds, agentAdressId, accommodationViewId]);
248
+ }, [
249
+ officeId,
250
+ language,
251
+ bookingOptions,
252
+ showSidebarDeposit,
253
+ showCommission,
254
+ setOfficeId,
255
+ setLanguageCode,
256
+ setCalculateDeposit,
257
+ tagIds,
258
+ agentAdressId,
259
+ accommodationViewId
260
+ ]);
246
261
 
247
262
  useEffect(() => {
248
263
  if (!productAttributes || !bookingAttributes || !rooms?.length || !isNil(bookingNumber) || !isNil(packageDetails)) {
@@ -151,6 +151,8 @@ export const selectVoucherCodes = (state: RootState) => state.booking.voucherCod
151
151
 
152
152
  export const selectCalculateDeposit = (state: RootState) => state.booking.calculateDeposit;
153
153
 
154
+ export const selectShowCommission = (state: RootState) => state.booking.showCommission;
155
+
154
156
  export const selectIsRetry = (state: RootState) => state.booking.isRetry;
155
157
 
156
158
  export const selectStartDate = (state: RootState) => state.booking.package?.options.find((x) => x.isSelected)?.fromDate;
@@ -289,6 +291,7 @@ export const selectBookingPackageBookRequest = createSelector(
289
291
  selectBookingAddress,
290
292
  selectPackageDetails,
291
293
  selectCalculateDeposit,
294
+ selectShowCommission,
292
295
  selectAgentId,
293
296
  selectGeneratePaymentUrl,
294
297
  selectSkipPaymentWithAgent,
@@ -304,6 +307,7 @@ export const selectBookingPackageBookRequest = createSelector(
304
307
  address,
305
308
  packageDetails,
306
309
  calculateDeposit,
310
+ showCommission,
307
311
  agentId,
308
312
  generatePaymentUrl,
309
313
  skipPaymentWithAgent,
@@ -367,6 +371,7 @@ export const selectBookingPackageBookRequest = createSelector(
367
371
  pax: pax?.length != 0 ? pax : packageDetails.options[0].requestRooms.flatMap((x) => x.pax),
368
372
  nonTravelPax: [],
369
373
  calculateDeposit: calculateDeposit,
374
+ showCommission: showCommission,
370
375
  returnPaymentUrl: returnPaymentUrl,
371
376
  notifications: notifications,
372
377
  tagIds: tagIds,