@nuitee/booking-widget 1.0.4 → 1.0.6
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.
- package/README.md +3 -3
- package/dist/booking-widget-standalone.js +44 -24
- package/dist/booking-widget.js +35 -17
- package/dist/core/booking-api.js +5 -4
- package/dist/react/BookingWidget.jsx +2 -4
- package/dist/utils/config-service.js +1 -1
- package/dist/vue/BookingWidget.vue +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -94,15 +94,15 @@ widget.open();
|
|
|
94
94
|
No bundler: load the script and CSS from the CDN, then create the widget.
|
|
95
95
|
|
|
96
96
|
```html
|
|
97
|
-
<link rel="stylesheet" href="https://cdn.thehotelplanet.com/booking-widget/v1.0.
|
|
98
|
-
<script src="https://cdn.thehotelplanet.com/booking-widget/v1.0.
|
|
97
|
+
<link rel="stylesheet" href="https://cdn.thehotelplanet.com/booking-widget/v1.0.6/dist/booking-widget.css">
|
|
98
|
+
<script src="https://cdn.thehotelplanet.com/booking-widget/v1.0.6/dist/booking-widget-standalone.js"></script>
|
|
99
99
|
|
|
100
100
|
<div id="booking-widget-container"></div>
|
|
101
101
|
|
|
102
102
|
<script>
|
|
103
103
|
const widget = new BookingWidget({
|
|
104
104
|
containerId: 'booking-widget-container',
|
|
105
|
-
cssUrl: 'https://cdn.thehotelplanet.com/booking-widget/v1.0.
|
|
105
|
+
cssUrl: 'https://cdn.thehotelplanet.com/booking-widget/v1.0.6/dist/booking-widget.css',
|
|
106
106
|
propertyKey: 'your-property-key',
|
|
107
107
|
onOpen: () => console.log('Opened'),
|
|
108
108
|
onClose: () => console.log('Closed'),
|
|
@@ -230,6 +230,7 @@ function createBookingApi(config = {}) {
|
|
|
230
230
|
const url = `${(base || '').replace(/\/$/, '')}${path}`;
|
|
231
231
|
const headers = {
|
|
232
232
|
'Content-Type': 'application/json',
|
|
233
|
+
'Source': 'booking_engine',
|
|
233
234
|
...staticHeaders,
|
|
234
235
|
...getHeaders(),
|
|
235
236
|
};
|
|
@@ -291,8 +292,8 @@ function createBookingApi(config = {}) {
|
|
|
291
292
|
? `${propertyBaseUrl}/ari/get_properties?id=${encodeURIComponent(propertyId)}`
|
|
292
293
|
: `/ari/get_properties?id=${encodeURIComponent(propertyId)}`;
|
|
293
294
|
try {
|
|
294
|
-
const getOpts = { method: 'GET' };
|
|
295
|
-
if (propFullUrl.includes('ngrok')) getOpts.headers
|
|
295
|
+
const getOpts = { method: 'GET', headers: { 'Source': 'booking_engine' } };
|
|
296
|
+
if (propFullUrl.includes('ngrok')) getOpts.headers['ngrok-skip-browser-warning'] = 'true';
|
|
296
297
|
const propRes = await fetch(propFullUrl, getOpts);
|
|
297
298
|
if (propRes.ok) {
|
|
298
299
|
const propData = await propRes.json();
|
|
@@ -692,7 +693,7 @@ async function decryptPropertyId(options = {}) {
|
|
|
692
693
|
const url = `${base}/${locale}/booking_engine/decrypt_property_id`;
|
|
693
694
|
const res = await fetch(url, {
|
|
694
695
|
method: 'POST',
|
|
695
|
-
headers: { 'Content-Type': 'application/json', ...headers },
|
|
696
|
+
headers: { 'Content-Type': 'application/json', 'Source': 'booking_engine', ...headers },
|
|
696
697
|
body: JSON.stringify({ hash: propertyKey }),
|
|
697
698
|
});
|
|
698
699
|
if (!res.ok) throw new Error(res.statusText || 'Failed to decrypt property id');
|
|
@@ -719,7 +720,7 @@ async function fetchBookingEnginePref(options = {}) {
|
|
|
719
720
|
const url = `${base}/api/core/${locale}/booking_engine/booking_engine_pref?property_id=${encodeURIComponent(propertyId)}`;
|
|
720
721
|
const res = await fetch(url, {
|
|
721
722
|
method: 'GET',
|
|
722
|
-
headers: { 'Content-Type': 'application/json', ...headers },
|
|
723
|
+
headers: { 'Content-Type': 'application/json', 'Source': 'booking_engine', ...headers },
|
|
723
724
|
});
|
|
724
725
|
if (!res.ok) throw new Error(res.statusText || 'Failed to fetch config');
|
|
725
726
|
|
|
@@ -872,6 +873,7 @@ if (typeof window !== 'undefined') {
|
|
|
872
873
|
var styles = { '--primary': primary, '--primary-fg': primaryFg, '--bg': bg, '--fg': fg, '--card-fg': fg };
|
|
873
874
|
if (primaryRgb) styles['--primary-rgb'] = primaryRgb[0] + ', ' + primaryRgb[1] + ', ' + primaryRgb[2];
|
|
874
875
|
styles['--card'] = c.card || (bgHsl ? 'hsl(' + bgHsl[0] + ', ' + bgHsl[1] + '%, ' + Math.min(95, bgHsl[2] + 2) + '%)' : bg);
|
|
876
|
+
styles['--card-solid'] = styles['--card'];
|
|
875
877
|
if (bgHsl) {
|
|
876
878
|
styles['--secondary'] = 'hsl(' + bgHsl[0] + ', ' + bgHsl[1] + '%, ' + Math.min(95, bgHsl[2] + 10) + '%)';
|
|
877
879
|
styles['--border'] = 'hsl(' + bgHsl[0] + ', ' + bgHsl[1] + '%, ' + Math.min(95, bgHsl[2] + 14) + '%)';
|
|
@@ -905,7 +907,7 @@ if (typeof window !== 'undefined') {
|
|
|
905
907
|
const url = defaultApiBase.replace(/\/$/, '') + '/proxy/create-payment-intent' + (options.mode === 'sandbox' ? '?sandbox=true' : '');
|
|
906
908
|
return fetch(url, {
|
|
907
909
|
method: 'POST',
|
|
908
|
-
headers: { 'Content-Type': 'application/json' },
|
|
910
|
+
headers: { 'Content-Type': 'application/json', 'Source': 'booking_engine' },
|
|
909
911
|
body: JSON.stringify(payload),
|
|
910
912
|
}).then(function (r) {
|
|
911
913
|
if (!r.ok) throw new Error(r.statusText || 'Payment intent failed');
|
|
@@ -1204,7 +1206,7 @@ if (typeof window !== 'undefined') {
|
|
|
1204
1206
|
this.render();
|
|
1205
1207
|
|
|
1206
1208
|
const url = 'https://ai.thehotelplanet.com/load-config?apikey=' + encodeURIComponent(key) + (isSandbox ? '&mode=sandbox' : '');
|
|
1207
|
-
this._configPromise = fetch(url)
|
|
1209
|
+
this._configPromise = fetch(url, { headers: { 'Source': 'booking_engine' } })
|
|
1208
1210
|
.then(function (res) {
|
|
1209
1211
|
if (!res.ok) throw new Error('Failed to load widget configuration (HTTP ' + res.status + ').');
|
|
1210
1212
|
return res.json();
|
|
@@ -1262,17 +1264,24 @@ if (typeof window !== 'undefined') {
|
|
|
1262
1264
|
}
|
|
1263
1265
|
|
|
1264
1266
|
injectCSS() {
|
|
1265
|
-
if (document.getElementById('booking-widget-styles'))
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1267
|
+
if (!document.getElementById('booking-widget-styles')) {
|
|
1268
|
+
if (this.options.cssUrl) {
|
|
1269
|
+
const link = document.createElement('link');
|
|
1270
|
+
link.id = 'booking-widget-styles';
|
|
1271
|
+
link.rel = 'stylesheet';
|
|
1272
|
+
link.href = this.options.cssUrl;
|
|
1273
|
+
document.head.appendChild(link);
|
|
1274
|
+
} else {
|
|
1275
|
+
// Inline CSS would go here in a real bundle
|
|
1276
|
+
console.warn('CSS not loaded. Please include booking-widget.css or provide cssUrl option.');
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
if (!document.getElementById('booking-widget-overrides')) {
|
|
1281
|
+
const style = document.createElement('style');
|
|
1282
|
+
style.id = 'booking-widget-overrides';
|
|
1283
|
+
style.textContent = '.booking-widget-modal .confirm-icon { font-size: 1em; }';
|
|
1284
|
+
document.head.appendChild(style);
|
|
1276
1285
|
}
|
|
1277
1286
|
}
|
|
1278
1287
|
|
|
@@ -1494,10 +1503,17 @@ if (typeof window !== 'undefined') {
|
|
|
1494
1503
|
this.render();
|
|
1495
1504
|
}
|
|
1496
1505
|
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1506
|
+
// force=true resets the view when the user opens the picker.
|
|
1507
|
+
// - If a check-in date is already selected, starts from that month/year.
|
|
1508
|
+
// - Otherwise starts from today.
|
|
1509
|
+
// force=false (default) preserves the current month/year so mid-pick re-renders
|
|
1510
|
+
// don't snap the calendar back to the current month.
|
|
1511
|
+
initCalendar(force = false) {
|
|
1512
|
+
if (force || this.calendarMonth === null || this.calendarYear === null) {
|
|
1513
|
+
const anchor = this.state.checkIn || new Date();
|
|
1514
|
+
this.calendarMonth = anchor.getMonth();
|
|
1515
|
+
this.calendarYear = anchor.getFullYear();
|
|
1516
|
+
}
|
|
1501
1517
|
// If we have check-in but no check-out, next click sets check-out; otherwise next click sets check-in (allows changing check-in when both are set)
|
|
1502
1518
|
this.pickState = (this.state.checkIn && !this.state.checkOut) ? 1 : 0;
|
|
1503
1519
|
}
|
|
@@ -1506,7 +1522,7 @@ if (typeof window !== 'undefined') {
|
|
|
1506
1522
|
const popup = this.widget.querySelector('.calendar-popup');
|
|
1507
1523
|
popup.classList.toggle('open');
|
|
1508
1524
|
if (popup.classList.contains('open')) {
|
|
1509
|
-
this.initCalendar();
|
|
1525
|
+
this.initCalendar(true);
|
|
1510
1526
|
this.renderCalendar();
|
|
1511
1527
|
}
|
|
1512
1528
|
}
|
|
@@ -1562,10 +1578,14 @@ if (typeof window !== 'undefined') {
|
|
|
1562
1578
|
|
|
1563
1579
|
pickDate(y, m, d) {
|
|
1564
1580
|
const date = new Date(y, m, d);
|
|
1581
|
+
// Save the current view so render() cannot shift the calendar.
|
|
1582
|
+
const savedMonth = this.calendarMonth;
|
|
1583
|
+
const savedYear = this.calendarYear;
|
|
1565
1584
|
if (this.pickState === 0 || (this.state.checkIn && date <= this.state.checkIn)) {
|
|
1566
1585
|
this.state.checkIn = date; this.state.checkOut = null; this.pickState = 1;
|
|
1567
1586
|
this.render();
|
|
1568
|
-
|
|
1587
|
+
// Restore view after render (render calls initCalendar which may reset month/year).
|
|
1588
|
+
if (savedMonth !== null) { this.calendarMonth = savedMonth; this.calendarYear = savedYear; }
|
|
1569
1589
|
this.pickState = 1;
|
|
1570
1590
|
const popup = this.widget.querySelector('.calendar-popup');
|
|
1571
1591
|
if (popup) popup.classList.add('open');
|
|
@@ -1972,7 +1992,7 @@ if (typeof window !== 'undefined') {
|
|
|
1972
1992
|
if (!token) throw new Error('Missing confirmation token');
|
|
1973
1993
|
const base = String(this.options.confirmationBaseUrl || 'https://ai.thehotelplanet.com').replace(/\/$/, '');
|
|
1974
1994
|
const url = base + '/proxy/confirmation/' + encodeURIComponent(token) + (this.options.mode === 'sandbox' ? '?sandbox=true' : '');
|
|
1975
|
-
const res = await fetch(url, { method: 'POST' });
|
|
1995
|
+
const res = await fetch(url, { method: 'POST', headers: { 'Source': 'booking_engine' } });
|
|
1976
1996
|
if (!res.ok) throw new Error(await res.text());
|
|
1977
1997
|
return await res.json();
|
|
1978
1998
|
}
|
package/dist/booking-widget.js
CHANGED
|
@@ -84,6 +84,7 @@ function deriveWidgetStyles(c) {
|
|
|
84
84
|
var styles = { '--primary': primary, '--primary-fg': primaryFg, '--bg': bg, '--fg': fg, '--card-fg': fg };
|
|
85
85
|
if (primaryRgb) styles['--primary-rgb'] = primaryRgb[0] + ', ' + primaryRgb[1] + ', ' + primaryRgb[2];
|
|
86
86
|
styles['--card'] = c.card || (bgHsl ? 'hsl(' + bgHsl[0] + ', ' + bgHsl[1] + '%, ' + Math.min(95, bgHsl[2] + 2) + '%)' : bg);
|
|
87
|
+
styles['--card-solid'] = styles['--card'];
|
|
87
88
|
if (bgHsl) {
|
|
88
89
|
styles['--secondary'] = 'hsl(' + bgHsl[0] + ', ' + bgHsl[1] + '%, ' + Math.min(95, bgHsl[2] + 10) + '%)';
|
|
89
90
|
styles['--border'] = 'hsl(' + bgHsl[0] + ', ' + bgHsl[1] + '%, ' + Math.min(95, bgHsl[2] + 14) + '%)';
|
|
@@ -121,7 +122,7 @@ class BookingWidget {
|
|
|
121
122
|
const url = apiBase.replace(/\/$/, '') + '/proxy/create-payment-intent' + (builtInMode === 'sandbox' ? '?sandbox=true' : '');
|
|
122
123
|
return fetch(url, {
|
|
123
124
|
method: 'POST',
|
|
124
|
-
headers: { 'Content-Type': 'application/json' },
|
|
125
|
+
headers: { 'Content-Type': 'application/json', 'Source': 'booking_engine' },
|
|
125
126
|
body: JSON.stringify(payload),
|
|
126
127
|
}).then(function (r) {
|
|
127
128
|
if (!r.ok) throw new Error(r.statusText || 'Payment intent failed');
|
|
@@ -482,7 +483,7 @@ class BookingWidget {
|
|
|
482
483
|
this.render();
|
|
483
484
|
|
|
484
485
|
const url = 'https://ai.thehotelplanet.com/load-config?apikey=' + encodeURIComponent(key) + (isSandbox ? '&mode=sandbox' : '');
|
|
485
|
-
this._configPromise = fetch(url)
|
|
486
|
+
this._configPromise = fetch(url, { headers: { 'Source': 'booking_engine' } })
|
|
486
487
|
.then(function (res) {
|
|
487
488
|
if (!res.ok) throw new Error('Failed to load widget configuration (HTTP ' + res.status + ').');
|
|
488
489
|
return res.json();
|
|
@@ -511,13 +512,20 @@ class BookingWidget {
|
|
|
511
512
|
}
|
|
512
513
|
|
|
513
514
|
injectCSS() {
|
|
514
|
-
if (document.getElementById('booking-widget-styles'))
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
515
|
+
if (!document.getElementById('booking-widget-styles')) {
|
|
516
|
+
const link = document.createElement('link');
|
|
517
|
+
link.id = 'booking-widget-styles';
|
|
518
|
+
link.rel = 'stylesheet';
|
|
519
|
+
link.href = this.options.cssUrl || './booking-widget.css';
|
|
520
|
+
document.head.appendChild(link);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
if (!document.getElementById('booking-widget-overrides')) {
|
|
524
|
+
const style = document.createElement('style');
|
|
525
|
+
style.id = 'booking-widget-overrides';
|
|
526
|
+
style.textContent = '.booking-widget-modal .confirm-icon { font-size: 1em; }';
|
|
527
|
+
document.head.appendChild(style);
|
|
528
|
+
}
|
|
521
529
|
}
|
|
522
530
|
|
|
523
531
|
// ===== Render =====
|
|
@@ -763,10 +771,17 @@ class BookingWidget {
|
|
|
763
771
|
}
|
|
764
772
|
|
|
765
773
|
// --- Calendar ---
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
774
|
+
// force=true resets the view when the user opens the picker.
|
|
775
|
+
// - If a check-in date is already selected, starts from that month/year.
|
|
776
|
+
// - Otherwise starts from today.
|
|
777
|
+
// force=false (default) preserves the current month/year so mid-pick re-renders
|
|
778
|
+
// don't snap the calendar back to the current month.
|
|
779
|
+
initCalendar(force = false) {
|
|
780
|
+
if (force || this.calendarMonth === null || this.calendarYear === null) {
|
|
781
|
+
const anchor = this.state.checkIn || new Date();
|
|
782
|
+
this.calendarMonth = anchor.getMonth();
|
|
783
|
+
this.calendarYear = anchor.getFullYear();
|
|
784
|
+
}
|
|
770
785
|
// If we have check-in but no check-out, next click sets check-out; otherwise next click sets check-in (allows changing check-in when both are set)
|
|
771
786
|
this.pickState = (this.state.checkIn && !this.state.checkOut) ? 1 : 0;
|
|
772
787
|
}
|
|
@@ -775,7 +790,7 @@ class BookingWidget {
|
|
|
775
790
|
const popup = this.widget.querySelector('.calendar-popup');
|
|
776
791
|
popup.classList.toggle('open');
|
|
777
792
|
if (popup.classList.contains('open')) {
|
|
778
|
-
this.initCalendar();
|
|
793
|
+
this.initCalendar(true);
|
|
779
794
|
this.renderCalendar();
|
|
780
795
|
}
|
|
781
796
|
}
|
|
@@ -831,6 +846,9 @@ class BookingWidget {
|
|
|
831
846
|
|
|
832
847
|
pickDate(y, m, d) {
|
|
833
848
|
const date = new Date(y, m, d);
|
|
849
|
+
// Save the current view so render() cannot shift the calendar.
|
|
850
|
+
const savedMonth = this.calendarMonth;
|
|
851
|
+
const savedYear = this.calendarYear;
|
|
834
852
|
if (this.pickState === 0 || (this.state.checkIn && date <= this.state.checkIn)) {
|
|
835
853
|
this.state.checkIn = date; this.state.checkOut = null; this.pickState = 1;
|
|
836
854
|
} else {
|
|
@@ -838,9 +856,9 @@ class BookingWidget {
|
|
|
838
856
|
this.widget.querySelector('.calendar-popup').classList.remove('open');
|
|
839
857
|
}
|
|
840
858
|
this.render();
|
|
859
|
+
// Restore view after render (render calls initCalendar which may reset month/year).
|
|
860
|
+
if (savedMonth !== null) { this.calendarMonth = savedMonth; this.calendarYear = savedYear; }
|
|
841
861
|
if (this.pickState === 1) {
|
|
842
|
-
this.initCalendar();
|
|
843
|
-
this.pickState = 1;
|
|
844
862
|
const popup = this.widget.querySelector('.calendar-popup');
|
|
845
863
|
if (popup) popup.classList.add('open');
|
|
846
864
|
this.renderCalendar();
|
|
@@ -1389,7 +1407,7 @@ class BookingWidget {
|
|
|
1389
1407
|
if (!token) throw new Error('Missing confirmation token');
|
|
1390
1408
|
const base = String(this.options.confirmationBaseUrl || 'https://ai.thehotelplanet.com').replace(/\/$/, '');
|
|
1391
1409
|
const url = `${base}/proxy/confirmation/${encodeURIComponent(token)}${this.options.mode === 'sandbox' ? '?sandbox=true' : ''}`;
|
|
1392
|
-
const res = await fetch(url, { method: 'POST' });
|
|
1410
|
+
const res = await fetch(url, { method: 'POST', headers: { 'Source': 'booking_engine' } });
|
|
1393
1411
|
if (!res.ok) throw new Error(await res.text());
|
|
1394
1412
|
return await res.json();
|
|
1395
1413
|
}
|
package/dist/core/booking-api.js
CHANGED
|
@@ -229,6 +229,7 @@ function createBookingApi(config = {}) {
|
|
|
229
229
|
const url = `${(base || '').replace(/\/$/, '')}${path}`;
|
|
230
230
|
const headers = {
|
|
231
231
|
'Content-Type': 'application/json',
|
|
232
|
+
'Source': 'booking_engine',
|
|
232
233
|
...staticHeaders,
|
|
233
234
|
...getHeaders(),
|
|
234
235
|
};
|
|
@@ -290,8 +291,8 @@ function createBookingApi(config = {}) {
|
|
|
290
291
|
? `${propertyBaseUrl}/ari/get_properties?id=${encodeURIComponent(propertyId)}`
|
|
291
292
|
: `/ari/get_properties?id=${encodeURIComponent(propertyId)}`;
|
|
292
293
|
try {
|
|
293
|
-
const getOpts = { method: 'GET' };
|
|
294
|
-
if (propFullUrl.includes('ngrok')) getOpts.headers
|
|
294
|
+
const getOpts = { method: 'GET', headers: { 'Source': 'booking_engine' } };
|
|
295
|
+
if (propFullUrl.includes('ngrok')) getOpts.headers['ngrok-skip-browser-warning'] = 'true';
|
|
295
296
|
const propRes = await fetch(propFullUrl, getOpts);
|
|
296
297
|
if (propRes.ok) {
|
|
297
298
|
const propData = await propRes.json();
|
|
@@ -691,7 +692,7 @@ async function decryptPropertyId(options = {}) {
|
|
|
691
692
|
const url = `${base}/${locale}/booking_engine/decrypt_property_id`;
|
|
692
693
|
const res = await fetch(url, {
|
|
693
694
|
method: 'POST',
|
|
694
|
-
headers: { 'Content-Type': 'application/json', ...headers },
|
|
695
|
+
headers: { 'Content-Type': 'application/json', 'Source': 'booking_engine', ...headers },
|
|
695
696
|
body: JSON.stringify({ hash: propertyKey }),
|
|
696
697
|
});
|
|
697
698
|
if (!res.ok) throw new Error(res.statusText || 'Failed to decrypt property id');
|
|
@@ -718,7 +719,7 @@ async function fetchBookingEnginePref(options = {}) {
|
|
|
718
719
|
const url = `${base}/api/core/${locale}/booking_engine/booking_engine_pref?property_id=${encodeURIComponent(propertyId)}`;
|
|
719
720
|
const res = await fetch(url, {
|
|
720
721
|
method: 'GET',
|
|
721
|
-
headers: { 'Content-Type': 'application/json', ...headers },
|
|
722
|
+
headers: { 'Content-Type': 'application/json', 'Source': 'booking_engine', ...headers },
|
|
722
723
|
});
|
|
723
724
|
if (!res.ok) throw new Error(res.statusText || 'Failed to fetch config');
|
|
724
725
|
|
|
@@ -57,7 +57,7 @@ const BookingWidget = ({
|
|
|
57
57
|
if (!effectivePaymentIntentUrl) return null;
|
|
58
58
|
return async (payload) => {
|
|
59
59
|
const url = effectivePaymentIntentUrl + (isSandbox ? '?sandbox=true' : '');
|
|
60
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
60
|
+
const headers = { 'Content-Type': 'application/json', 'Source': 'booking_engine' };
|
|
61
61
|
if (url.includes('ngrok')) headers['ngrok-skip-browser-warning'] = 'true';
|
|
62
62
|
const res = await fetch(url, { method: 'POST', headers, body: JSON.stringify(payload) });
|
|
63
63
|
if (!res.ok) throw new Error(await res.text());
|
|
@@ -205,7 +205,7 @@ const BookingWidget = ({
|
|
|
205
205
|
if (cancelled) return;
|
|
206
206
|
try {
|
|
207
207
|
const url = `${effectiveConfirmationBaseUrl}/proxy/confirmation/${encodeURIComponent(String(confirmationToken).trim())}${isSandbox ? '?sandbox=true' : ''}`;
|
|
208
|
-
const res = await fetch(url, { method: 'POST' });
|
|
208
|
+
const res = await fetch(url, { method: 'POST', headers: { 'Source': 'booking_engine' } });
|
|
209
209
|
if (!res.ok) throw new Error(await res.text());
|
|
210
210
|
const data = await res.json();
|
|
211
211
|
const status = data?.status != null ? String(data.status) : '';
|
|
@@ -399,8 +399,6 @@ const BookingWidget = ({
|
|
|
399
399
|
setCalendarOpen(false);
|
|
400
400
|
}
|
|
401
401
|
if (pickState === 0) {
|
|
402
|
-
setCalendarMonth(new Date().getMonth());
|
|
403
|
-
setCalendarYear(new Date().getFullYear());
|
|
404
402
|
setPickState(1);
|
|
405
403
|
}
|
|
406
404
|
};
|
|
@@ -89,7 +89,7 @@ export async function fetchRuntimeConfig(propertyKey, installerColors = null, mo
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
const url = `${CONFIG_BASE_URL}?apikey=${encodeURIComponent(key)}${isSandbox ? '&mode=sandbox' : ''}`;
|
|
92
|
-
const res = await fetch(url);
|
|
92
|
+
const res = await fetch(url, { headers: { 'Source': 'booking_engine' } });
|
|
93
93
|
if (!res.ok) {
|
|
94
94
|
throw new Error(`Failed to load widget configuration (HTTP ${res.status}).`);
|
|
95
95
|
}
|
|
@@ -604,7 +604,7 @@ export default {
|
|
|
604
604
|
if (!url) return null;
|
|
605
605
|
return async (payload) => {
|
|
606
606
|
const requestUrl = url + (this.isSandbox ? '?sandbox=true' : '');
|
|
607
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
607
|
+
const headers = { 'Content-Type': 'application/json', 'Source': 'booking_engine' };
|
|
608
608
|
if (requestUrl.includes('ngrok')) headers['ngrok-skip-browser-warning'] = 'true';
|
|
609
609
|
const res = await fetch(requestUrl, { method: 'POST', headers, body: JSON.stringify(payload) });
|
|
610
610
|
if (!res.ok) throw new Error(await res.text());
|
|
@@ -795,7 +795,7 @@ export default {
|
|
|
795
795
|
const t = String(token || '').trim();
|
|
796
796
|
if (!t) throw new Error('Missing confirmation token');
|
|
797
797
|
const url = `${this.effectiveConfirmationBaseUrl}/proxy/confirmation/${encodeURIComponent(t)}${this.isSandbox ? '?sandbox=true' : ''}`;
|
|
798
|
-
const res = await fetch(url, { method: 'POST' });
|
|
798
|
+
const res = await fetch(url, { method: 'POST', headers: { 'Source': 'booking_engine' } });
|
|
799
799
|
if (!res.ok) throw new Error(await res.text());
|
|
800
800
|
return await res.json();
|
|
801
801
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuitee/booking-widget",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "A beautiful, customizable booking widget modal that can be embedded in any website. Supports vanilla JavaScript, React, and Vue.js.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|