@nuitee/booking-widget 1.0.3 → 1.0.4
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/dist/booking-widget-standalone.js +8 -5
- package/dist/booking-widget.css +2 -1
- package/dist/booking-widget.js +8 -5
- package/dist/core/styles.css +2 -1
- package/dist/react/BookingWidget.jsx +2 -2
- package/dist/react/styles.css +2 -1
- package/dist/utils/config-service.js +13 -9
- package/dist/vue/BookingWidget.vue +4 -1
- package/dist/vue/styles.css +2 -1
- package/package.json +1 -1
|
@@ -1189,18 +1189,21 @@ if (typeof window !== 'undefined') {
|
|
|
1189
1189
|
_fetchRuntimeConfig() {
|
|
1190
1190
|
const self = this;
|
|
1191
1191
|
const key = String(this.options.propertyKey).trim();
|
|
1192
|
+
const isSandbox = this.options.mode === 'sandbox';
|
|
1193
|
+
// Cache key is mode-aware so sandbox and live configs are stored separately.
|
|
1194
|
+
const cacheKey = isSandbox ? key + ':sandbox' : key;
|
|
1192
1195
|
|
|
1193
|
-
if (__bwConfigCache[
|
|
1194
|
-
this._applyApiColors(__bwConfigCache[
|
|
1196
|
+
if (__bwConfigCache[cacheKey]) {
|
|
1197
|
+
this._applyApiColors(__bwConfigCache[cacheKey]);
|
|
1195
1198
|
this._configState = 'loaded';
|
|
1196
1199
|
this.applyColors();
|
|
1197
|
-
return Promise.resolve(__bwConfigCache[
|
|
1200
|
+
return Promise.resolve(__bwConfigCache[cacheKey]);
|
|
1198
1201
|
}
|
|
1199
1202
|
|
|
1200
1203
|
this._configState = 'loading';
|
|
1201
1204
|
this.render();
|
|
1202
1205
|
|
|
1203
|
-
const url = 'https://ai.thehotelplanet.com/load-config?apikey=' + encodeURIComponent(key) + '&mode=sandbox';
|
|
1206
|
+
const url = 'https://ai.thehotelplanet.com/load-config?apikey=' + encodeURIComponent(key) + (isSandbox ? '&mode=sandbox' : '');
|
|
1204
1207
|
this._configPromise = fetch(url)
|
|
1205
1208
|
.then(function (res) {
|
|
1206
1209
|
if (!res.ok) throw new Error('Failed to load widget configuration (HTTP ' + res.status + ').');
|
|
@@ -1213,7 +1216,7 @@ if (typeof window !== 'undefined') {
|
|
|
1213
1216
|
if (data.primaryColor) apiColors.primary = data.primaryColor;
|
|
1214
1217
|
if (data.buttonTextColor) apiColors.primaryText = data.buttonTextColor;
|
|
1215
1218
|
if (data.widgetCardColor) apiColors.card = data.widgetCardColor;
|
|
1216
|
-
__bwConfigCache[
|
|
1219
|
+
__bwConfigCache[cacheKey] = apiColors;
|
|
1217
1220
|
self._applyApiColors(apiColors);
|
|
1218
1221
|
self._configState = 'loaded';
|
|
1219
1222
|
self.applyColors();
|
package/dist/booking-widget.css
CHANGED
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
--bg: hsl(30, 10%, 8%);
|
|
82
82
|
--fg: hsl(40, 20%, 90%);
|
|
83
83
|
--card: hsl(30, 8%, 12%);
|
|
84
|
+
--card-solid: hsl(30, 8%, 12%);
|
|
84
85
|
--card-fg: hsl(40, 20%, 90%);
|
|
85
86
|
--primary: hsl(38, 60%, 55%);
|
|
86
87
|
--primary-fg: hsl(30, 10%, 8%);
|
|
@@ -611,7 +612,7 @@
|
|
|
611
612
|
max-width: calc(100vw - 2em);
|
|
612
613
|
box-sizing: border-box;
|
|
613
614
|
z-index: 10;
|
|
614
|
-
background: var(--card-solid
|
|
615
|
+
background: var(--card-solid);
|
|
615
616
|
border: 1px solid var(--border);
|
|
616
617
|
border-radius: var(--radius);
|
|
617
618
|
padding: 1em;
|
package/dist/booking-widget.js
CHANGED
|
@@ -467,18 +467,21 @@ class BookingWidget {
|
|
|
467
467
|
const self = this;
|
|
468
468
|
const propertyKey = this.options.propertyKey;
|
|
469
469
|
const key = String(propertyKey).trim();
|
|
470
|
+
const isSandbox = this.options.mode === 'sandbox';
|
|
471
|
+
// Cache key is mode-aware so sandbox and live configs are stored separately.
|
|
472
|
+
const cacheKey = isSandbox ? key + ':sandbox' : key;
|
|
470
473
|
|
|
471
|
-
if (__bwConfigCache[
|
|
472
|
-
this._applyApiColors(__bwConfigCache[
|
|
474
|
+
if (__bwConfigCache[cacheKey]) {
|
|
475
|
+
this._applyApiColors(__bwConfigCache[cacheKey]);
|
|
473
476
|
this._configState = 'loaded';
|
|
474
477
|
this.applyColors();
|
|
475
|
-
return Promise.resolve(__bwConfigCache[
|
|
478
|
+
return Promise.resolve(__bwConfigCache[cacheKey]);
|
|
476
479
|
}
|
|
477
480
|
|
|
478
481
|
this._configState = 'loading';
|
|
479
482
|
this.render();
|
|
480
483
|
|
|
481
|
-
const url = 'https://ai.thehotelplanet.com/load-config?apikey=' + encodeURIComponent(key) + '&mode=sandbox';
|
|
484
|
+
const url = 'https://ai.thehotelplanet.com/load-config?apikey=' + encodeURIComponent(key) + (isSandbox ? '&mode=sandbox' : '');
|
|
482
485
|
this._configPromise = fetch(url)
|
|
483
486
|
.then(function (res) {
|
|
484
487
|
if (!res.ok) throw new Error('Failed to load widget configuration (HTTP ' + res.status + ').');
|
|
@@ -491,7 +494,7 @@ class BookingWidget {
|
|
|
491
494
|
if (data.primaryColor) apiColors.primary = data.primaryColor;
|
|
492
495
|
if (data.buttonTextColor) apiColors.primaryText = data.buttonTextColor;
|
|
493
496
|
if (data.widgetCardColor) apiColors.card = data.widgetCardColor;
|
|
494
|
-
__bwConfigCache[
|
|
497
|
+
__bwConfigCache[cacheKey] = apiColors;
|
|
495
498
|
self._applyApiColors(apiColors);
|
|
496
499
|
self._configState = 'loaded';
|
|
497
500
|
self.applyColors();
|
package/dist/core/styles.css
CHANGED
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
--bg: hsl(30, 10%, 8%);
|
|
82
82
|
--fg: hsl(40, 20%, 90%);
|
|
83
83
|
--card: hsl(30, 8%, 12%);
|
|
84
|
+
--card-solid: hsl(30, 8%, 12%);
|
|
84
85
|
--card-fg: hsl(40, 20%, 90%);
|
|
85
86
|
--primary: hsl(38, 60%, 55%);
|
|
86
87
|
--primary-fg: hsl(30, 10%, 8%);
|
|
@@ -611,7 +612,7 @@
|
|
|
611
612
|
max-width: calc(100vw - 2em);
|
|
612
613
|
box-sizing: border-box;
|
|
613
614
|
z-index: 10;
|
|
614
|
-
background: var(--card-solid
|
|
615
|
+
background: var(--card-solid);
|
|
615
616
|
border: 1px solid var(--border);
|
|
616
617
|
border-radius: var(--radius);
|
|
617
618
|
padding: 1em;
|
|
@@ -240,7 +240,7 @@ const BookingWidget = ({
|
|
|
240
240
|
setConfigLoading(true);
|
|
241
241
|
setConfigError(null);
|
|
242
242
|
setConfigLoaded(false);
|
|
243
|
-
fetchRuntimeConfig(propertyKey, colors)
|
|
243
|
+
fetchRuntimeConfig(propertyKey, colors, mode)
|
|
244
244
|
.then(({ widgetStyles }) => {
|
|
245
245
|
if (cancelled) return;
|
|
246
246
|
setRuntimeWidgetStyles(widgetStyles);
|
|
@@ -253,7 +253,7 @@ const BookingWidget = ({
|
|
|
253
253
|
setConfigLoading(false);
|
|
254
254
|
});
|
|
255
255
|
return () => { cancelled = true; };
|
|
256
|
-
}, [propertyKey, colors, configRetryCount]);
|
|
256
|
+
}, [propertyKey, colors, mode, configRetryCount]);
|
|
257
257
|
|
|
258
258
|
// Apply resolved CSS custom properties to the widget element.
|
|
259
259
|
useEffect(() => {
|
package/dist/react/styles.css
CHANGED
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
--bg: hsl(30, 10%, 8%);
|
|
82
82
|
--fg: hsl(40, 20%, 90%);
|
|
83
83
|
--card: hsl(30, 8%, 12%);
|
|
84
|
+
--card-solid: hsl(30, 8%, 12%);
|
|
84
85
|
--card-fg: hsl(40, 20%, 90%);
|
|
85
86
|
--primary: hsl(38, 60%, 55%);
|
|
86
87
|
--primary-fg: hsl(30, 10%, 8%);
|
|
@@ -611,7 +612,7 @@
|
|
|
611
612
|
max-width: calc(100vw - 2em);
|
|
612
613
|
box-sizing: border-box;
|
|
613
614
|
z-index: 10;
|
|
614
|
-
background: var(--card-solid
|
|
615
|
+
background: var(--card-solid);
|
|
615
616
|
border: 1px solid var(--border);
|
|
616
617
|
border-radius: var(--radius);
|
|
617
618
|
padding: 1em;
|
|
@@ -64,27 +64,31 @@ export function mergeColors(mappedApiColors, installerColors) {
|
|
|
64
64
|
* - Throws synchronously (or rejects) when propertyKey is null, undefined, or
|
|
65
65
|
* an empty string. Callers must catch this and render a "Missing Configuration"
|
|
66
66
|
* error state rather than attempting to render the normal widget UI.
|
|
67
|
-
* - Caches the raw API color payload by propertyKey. Subsequent calls for
|
|
68
|
-
* same key re-use the cache and only re-merge installer overrides.
|
|
67
|
+
* - Caches the raw API color payload by propertyKey + mode. Subsequent calls for
|
|
68
|
+
* the same key+mode re-use the cache and only re-merge installer overrides.
|
|
69
69
|
*
|
|
70
|
-
* @param {string}
|
|
71
|
-
* @param {object|null} installerColors
|
|
70
|
+
* @param {string} propertyKey - The hotel property key / API key.
|
|
71
|
+
* @param {object|null} installerColors - Optional installer color overrides.
|
|
72
|
+
* @param {string} [mode] - Pass 'sandbox' to append &mode=sandbox to the request.
|
|
72
73
|
* @returns {Promise<{ apiColors: object, colors: object, widgetStyles: object }>}
|
|
73
74
|
*/
|
|
74
|
-
export async function fetchRuntimeConfig(propertyKey, installerColors = null) {
|
|
75
|
+
export async function fetchRuntimeConfig(propertyKey, installerColors = null, mode = null) {
|
|
75
76
|
if (!propertyKey || !String(propertyKey).trim()) {
|
|
76
77
|
throw new Error('propertyKey is required to initialize the booking widget.');
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
const key = String(propertyKey).trim();
|
|
81
|
+
const isSandbox = mode === 'sandbox';
|
|
82
|
+
// Cache separately for sandbox vs live so switching modes gets a fresh fetch.
|
|
83
|
+
const cacheKey = isSandbox ? `${key}:sandbox` : key;
|
|
80
84
|
|
|
81
|
-
if (_configCache.has(
|
|
82
|
-
const apiColors = _configCache.get(
|
|
85
|
+
if (_configCache.has(cacheKey)) {
|
|
86
|
+
const apiColors = _configCache.get(cacheKey);
|
|
83
87
|
const colors = mergeColors(apiColors, installerColors);
|
|
84
88
|
return { apiColors, colors, widgetStyles: deriveWidgetStyles(colors) };
|
|
85
89
|
}
|
|
86
90
|
|
|
87
|
-
const url = `${CONFIG_BASE_URL}?apikey=${encodeURIComponent(key)}&mode=sandbox`;
|
|
91
|
+
const url = `${CONFIG_BASE_URL}?apikey=${encodeURIComponent(key)}${isSandbox ? '&mode=sandbox' : ''}`;
|
|
88
92
|
const res = await fetch(url);
|
|
89
93
|
if (!res.ok) {
|
|
90
94
|
throw new Error(`Failed to load widget configuration (HTTP ${res.status}).`);
|
|
@@ -92,7 +96,7 @@ export async function fetchRuntimeConfig(propertyKey, installerColors = null) {
|
|
|
92
96
|
|
|
93
97
|
const data = await res.json();
|
|
94
98
|
const apiColors = mapApiColors(data);
|
|
95
|
-
_configCache.set(
|
|
99
|
+
_configCache.set(cacheKey, apiColors);
|
|
96
100
|
|
|
97
101
|
const colors = mergeColors(apiColors, installerColors);
|
|
98
102
|
return { apiColors, colors, widgetStyles: deriveWidgetStyles(colors) };
|
|
@@ -730,6 +730,9 @@ export default {
|
|
|
730
730
|
propertyKey() {
|
|
731
731
|
this._initRuntimeConfig();
|
|
732
732
|
},
|
|
733
|
+
mode() {
|
|
734
|
+
this._initRuntimeConfig();
|
|
735
|
+
},
|
|
733
736
|
colors: {
|
|
734
737
|
deep: true,
|
|
735
738
|
handler() { this._initRuntimeConfig(); },
|
|
@@ -779,7 +782,7 @@ export default {
|
|
|
779
782
|
this.configError = null;
|
|
780
783
|
this.configLoaded = false;
|
|
781
784
|
try {
|
|
782
|
-
const { widgetStyles } = await fetchRuntimeConfig(this.propertyKey, this.colors);
|
|
785
|
+
const { widgetStyles } = await fetchRuntimeConfig(this.propertyKey, this.colors, this.mode);
|
|
783
786
|
this.runtimeWidgetStyles = widgetStyles;
|
|
784
787
|
this.configLoaded = true;
|
|
785
788
|
} catch (err) {
|
package/dist/vue/styles.css
CHANGED
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
--bg: hsl(30, 10%, 8%);
|
|
82
82
|
--fg: hsl(40, 20%, 90%);
|
|
83
83
|
--card: hsl(30, 8%, 12%);
|
|
84
|
+
--card-solid: hsl(30, 8%, 12%);
|
|
84
85
|
--card-fg: hsl(40, 20%, 90%);
|
|
85
86
|
--primary: hsl(38, 60%, 55%);
|
|
86
87
|
--primary-fg: hsl(30, 10%, 8%);
|
|
@@ -611,7 +612,7 @@
|
|
|
611
612
|
max-width: calc(100vw - 2em);
|
|
612
613
|
box-sizing: border-box;
|
|
613
614
|
z-index: 10;
|
|
614
|
-
background: var(--card-solid
|
|
615
|
+
background: var(--card-solid);
|
|
615
616
|
border: 1px solid var(--border);
|
|
616
617
|
border-radius: var(--radius);
|
|
617
618
|
padding: 1em;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuitee/booking-widget",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
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",
|