@datlv-trustshop/shopify-inapp-components 0.2.9 โ 0.2.11
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/components/WhatsNew.d.ts +2 -0
- package/dist/components/WhatsNew.d.ts.map +1 -1
- package/dist/components/WhatsNew.js +10 -13
- package/dist/components/WhatsNew.js.map +1 -1
- package/dist/core/SDKManager.d.ts +36 -4
- package/dist/core/SDKManager.d.ts.map +1 -1
- package/dist/core/SDKManager.js +210 -63
- package/dist/core/SDKManager.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -3
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -3
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useApps.d.ts +1 -1
- package/dist/hooks/useApps.d.ts.map +1 -1
- package/dist/hooks/useApps.js +15 -7
- package/dist/hooks/useApps.js.map +1 -1
- package/dist/hooks/useArticles.d.ts.map +1 -1
- package/dist/hooks/useArticles.js +12 -12
- package/dist/hooks/useArticles.js.map +1 -1
- package/dist/hooks/useBanner.d.ts +1 -1
- package/dist/hooks/useBanner.d.ts.map +1 -1
- package/dist/hooks/useBanner.js +15 -13
- package/dist/hooks/useBanner.js.map +1 -1
- package/dist/hooks/useDashboard.d.ts.map +1 -1
- package/dist/hooks/useDashboard.js +13 -7
- package/dist/hooks/useDashboard.js.map +1 -1
- package/dist/hooks/useFloatingCards.d.ts +1 -0
- package/dist/hooks/useFloatingCards.d.ts.map +1 -1
- package/dist/hooks/useFloatingCards.js +45 -94
- package/dist/hooks/useFloatingCards.js.map +1 -1
- package/dist/hooks/usePartnerIntegration.d.ts +7 -3
- package/dist/hooks/usePartnerIntegration.d.ts.map +1 -1
- package/dist/hooks/usePartnerIntegration.js +62 -7
- package/dist/hooks/usePartnerIntegration.js.map +1 -1
- package/dist/hooks/useWhatsNew.d.ts.map +1 -1
- package/dist/hooks/useWhatsNew.js +10 -10
- package/dist/hooks/useWhatsNew.js.map +1 -1
- package/package.json +1 -1
- package/dist/hooks/useFloatingCardActions.d.ts +0 -18
- package/dist/hooks/useFloatingCardActions.d.ts.map +0 -1
- package/dist/hooks/useFloatingCardActions.js +0 -55
- package/dist/hooks/useFloatingCardActions.js.map +0 -1
- package/dist/hooks/useFloatingCardEngine.d.ts +0 -22
- package/dist/hooks/useFloatingCardEngine.d.ts.map +0 -1
- package/dist/hooks/useFloatingCardEngine.js +0 -40
- package/dist/hooks/useFloatingCardEngine.js.map +0 -1
- package/dist/hooks/useGrowApps.d.ts +0 -11
- package/dist/hooks/useGrowApps.d.ts.map +0 -1
- package/dist/hooks/useGrowApps.js +0 -15
- package/dist/hooks/useGrowApps.js.map +0 -1
package/dist/core/SDKManager.js
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* SDK Manager - Internal singleton for managing global state
|
|
3
3
|
* Components automatically connect to this without manual provider setup
|
|
4
4
|
*/
|
|
5
|
-
import { loadTranslations, getTranslations, mergeTranslations } from
|
|
6
|
-
import { generateDashboardConfig } from
|
|
7
|
-
import { COMPONENT_DEFAULTS } from
|
|
5
|
+
import { loadTranslations, getTranslations, mergeTranslations, } from "../translations/translation-manager";
|
|
6
|
+
import { generateDashboardConfig, } from "../config/internal-config";
|
|
7
|
+
import { COMPONENT_DEFAULTS } from "../config/component-defaults";
|
|
8
|
+
import { DashboardEngine } from "./engine";
|
|
8
9
|
// ============================================
|
|
9
10
|
// SDK Manager Singleton
|
|
10
11
|
// ============================================
|
|
@@ -16,16 +17,16 @@ class SDKManagerClass {
|
|
|
16
17
|
*/
|
|
17
18
|
this.handleCustomLocaleChange = (event) => {
|
|
18
19
|
const newLocale = event.detail?.locale || event.detail;
|
|
19
|
-
if (newLocale && typeof newLocale ===
|
|
20
|
+
if (newLocale && typeof newLocale === "string") {
|
|
20
21
|
const normalizedLocale = this.normalizeLocale(newLocale);
|
|
21
|
-
console.log(
|
|
22
|
+
// console.log("Received locale change event:", normalizedLocale);
|
|
22
23
|
this.handleLocaleChange(normalizedLocale);
|
|
23
24
|
}
|
|
24
25
|
};
|
|
25
26
|
this.state = {
|
|
26
27
|
initialized: false,
|
|
27
|
-
locale:
|
|
28
|
-
translations: getTranslations(
|
|
28
|
+
locale: "en",
|
|
29
|
+
translations: getTranslations("en"),
|
|
29
30
|
config: generateDashboardConfig(),
|
|
30
31
|
loading: false,
|
|
31
32
|
};
|
|
@@ -38,7 +39,7 @@ class SDKManagerClass {
|
|
|
38
39
|
* Auto-detect current locale from browser/Shopify context
|
|
39
40
|
*/
|
|
40
41
|
autoDetectLocale() {
|
|
41
|
-
if (typeof window ===
|
|
42
|
+
if (typeof window === "undefined")
|
|
42
43
|
return;
|
|
43
44
|
try {
|
|
44
45
|
// Method 1: Check Shopify Admin locale (if available)
|
|
@@ -46,7 +47,7 @@ class SDKManagerClass {
|
|
|
46
47
|
if (shopifyLocale) {
|
|
47
48
|
this.currentDetectedLocale = shopifyLocale;
|
|
48
49
|
this.updateLocale(shopifyLocale);
|
|
49
|
-
console.log(
|
|
50
|
+
// console.log("Auto-detected Shopify locale:", shopifyLocale);
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
53
|
// Method 2: Browser language
|
|
@@ -55,11 +56,11 @@ class SDKManagerClass {
|
|
|
55
56
|
const normalizedLocale = this.normalizeLocale(browserLocale);
|
|
56
57
|
this.currentDetectedLocale = normalizedLocale;
|
|
57
58
|
this.updateLocale(normalizedLocale);
|
|
58
|
-
console.log(
|
|
59
|
+
// console.log("Auto-detected browser locale:", normalizedLocale);
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
catch (error) {
|
|
62
|
-
console.warn(
|
|
63
|
+
console.warn("Failed to auto-detect locale:", error);
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
/**
|
|
@@ -69,14 +70,14 @@ class SDKManagerClass {
|
|
|
69
70
|
try {
|
|
70
71
|
// Check if we can detect locale from Shopify admin
|
|
71
72
|
const html = document.documentElement;
|
|
72
|
-
const lang = html.getAttribute(
|
|
73
|
+
const lang = html.getAttribute("lang") || html.getAttribute("xml:lang");
|
|
73
74
|
if (lang) {
|
|
74
75
|
return this.normalizeLocale(lang);
|
|
75
76
|
}
|
|
76
77
|
// Check meta tags
|
|
77
78
|
const metaLang = document.querySelector('meta[http-equiv="content-language"]');
|
|
78
79
|
if (metaLang) {
|
|
79
|
-
const content = metaLang.getAttribute(
|
|
80
|
+
const content = metaLang.getAttribute("content");
|
|
80
81
|
if (content) {
|
|
81
82
|
return this.normalizeLocale(content);
|
|
82
83
|
}
|
|
@@ -91,16 +92,22 @@ class SDKManagerClass {
|
|
|
91
92
|
* Setup watcher for locale changes in the DOM
|
|
92
93
|
*/
|
|
93
94
|
setupLocaleWatcher() {
|
|
94
|
-
if (typeof window ===
|
|
95
|
+
if (typeof window === "undefined")
|
|
95
96
|
return;
|
|
96
97
|
try {
|
|
97
98
|
this.localeObserver = new MutationObserver((mutations) => {
|
|
98
99
|
mutations.forEach((mutation) => {
|
|
99
|
-
if (mutation.type ===
|
|
100
|
-
(mutation.attributeName ===
|
|
100
|
+
if (mutation.type === "attributes" &&
|
|
101
|
+
(mutation.attributeName === "lang" ||
|
|
102
|
+
mutation.attributeName === "xml:lang")) {
|
|
101
103
|
const newLocale = this.getShopifyAdminLocale();
|
|
102
104
|
if (newLocale && newLocale !== this.currentDetectedLocale) {
|
|
103
|
-
console.log(
|
|
105
|
+
// console.log(
|
|
106
|
+
// "Detected locale change:",
|
|
107
|
+
// this.currentDetectedLocale,
|
|
108
|
+
// "โ",
|
|
109
|
+
// newLocale,
|
|
110
|
+
// );
|
|
104
111
|
this.currentDetectedLocale = newLocale;
|
|
105
112
|
this.handleLocaleChange(newLocale);
|
|
106
113
|
}
|
|
@@ -110,15 +117,15 @@ class SDKManagerClass {
|
|
|
110
117
|
// Watch for changes to document element attributes
|
|
111
118
|
this.localeObserver.observe(document.documentElement, {
|
|
112
119
|
attributes: true,
|
|
113
|
-
attributeFilter: [
|
|
120
|
+
attributeFilter: ["lang", "xml:lang"],
|
|
114
121
|
});
|
|
115
122
|
// Also listen for custom locale change events
|
|
116
|
-
window.addEventListener(
|
|
117
|
-
window.addEventListener(
|
|
118
|
-
console.log(
|
|
123
|
+
window.addEventListener("trustshop-locale-change", this.handleCustomLocaleChange.bind(this));
|
|
124
|
+
window.addEventListener("shopify-locale-change", this.handleCustomLocaleChange.bind(this));
|
|
125
|
+
// console.log("Locale watcher initialized");
|
|
119
126
|
}
|
|
120
127
|
catch (error) {
|
|
121
|
-
console.warn(
|
|
128
|
+
console.warn("Failed to setup locale watcher:", error);
|
|
122
129
|
}
|
|
123
130
|
}
|
|
124
131
|
/**
|
|
@@ -128,48 +135,161 @@ class SDKManagerClass {
|
|
|
128
135
|
if (newLocale === this.state.locale)
|
|
129
136
|
return;
|
|
130
137
|
try {
|
|
131
|
-
console.log(
|
|
138
|
+
// console.log(Updating SDK locale:", this.state.locale, "โ", newLocale);
|
|
132
139
|
this.updateState({ loading: true });
|
|
133
140
|
// Load new translations
|
|
134
141
|
const baseTranslations = await loadTranslations(newLocale);
|
|
135
142
|
const translations = mergeTranslations(baseTranslations);
|
|
143
|
+
// Update config with new locale
|
|
144
|
+
const newConfig = { ...this.state.config, locale: newLocale };
|
|
136
145
|
// Update state
|
|
137
146
|
this.updateState({
|
|
138
147
|
locale: newLocale,
|
|
139
148
|
translations,
|
|
149
|
+
config: newConfig,
|
|
140
150
|
loading: false,
|
|
141
151
|
});
|
|
142
152
|
// Trigger re-fetch of API data with new locale
|
|
143
|
-
this.
|
|
144
|
-
console.log(
|
|
153
|
+
await this.refreshDashboardData(newLocale);
|
|
154
|
+
// console.log("SDK locale updated successfully");
|
|
145
155
|
}
|
|
146
156
|
catch (error) {
|
|
147
|
-
console.error(
|
|
157
|
+
console.error(" Failed to update SDK locale:", error);
|
|
148
158
|
this.updateState({ loading: false, error: error });
|
|
149
159
|
}
|
|
150
160
|
}
|
|
151
161
|
/**
|
|
152
|
-
* Refresh
|
|
162
|
+
* Refresh dashboard data with new locale
|
|
153
163
|
*/
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
164
|
+
async refreshDashboardData(locale) {
|
|
165
|
+
try {
|
|
166
|
+
this.updateState({ dashboardLoading: true, dashboardError: null });
|
|
167
|
+
const currentLocale = locale || this.state.locale;
|
|
168
|
+
const config = { ...this.state.config, locale: currentLocale };
|
|
169
|
+
// Initialize or update dashboard engine
|
|
170
|
+
if (!this.dashboardEngine) {
|
|
171
|
+
this.dashboardEngine = DashboardEngine.getInstance(config);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// Update engine config with new locale
|
|
175
|
+
await this.dashboardEngine.setLocale(currentLocale);
|
|
176
|
+
}
|
|
177
|
+
// Fetch dashboard data
|
|
178
|
+
await this.dashboardEngine.init();
|
|
179
|
+
const dashboardData = this.dashboardEngine.getData();
|
|
180
|
+
this.updateState({
|
|
181
|
+
dashboardData,
|
|
182
|
+
dashboardLoading: false,
|
|
183
|
+
dashboardError: null,
|
|
184
|
+
});
|
|
185
|
+
// Also refresh campaigns data
|
|
186
|
+
await this.refreshCampaignsData(currentLocale);
|
|
187
|
+
// Emit event for components to refresh
|
|
188
|
+
window.dispatchEvent(new CustomEvent("trustshop-data-refresh", {
|
|
189
|
+
detail: {
|
|
190
|
+
locale: currentLocale,
|
|
191
|
+
reason: "locale-change",
|
|
192
|
+
data: dashboardData,
|
|
193
|
+
},
|
|
194
|
+
}));
|
|
195
|
+
// console.log(`Dashboard data refreshed for locale: ${currentLocale}`);
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
console.error("Failed to refresh dashboard data:", error);
|
|
199
|
+
this.updateState({
|
|
200
|
+
dashboardLoading: false,
|
|
201
|
+
dashboardError: error,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Refresh campaigns data with new locale
|
|
207
|
+
*/
|
|
208
|
+
async refreshCampaignsData(locale) {
|
|
209
|
+
try {
|
|
210
|
+
// Only fetch campaigns if we have a shop ID
|
|
211
|
+
if (!this.state.shopInfo?.id) {
|
|
212
|
+
// console.log("Skipping campaigns fetch - no shop ID available");
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
this.updateState({ campaignsLoading: true, campaignsError: null });
|
|
216
|
+
const currentLocale = locale || this.state.locale;
|
|
217
|
+
const shopId = this.state.shopInfo.id;
|
|
218
|
+
// Build campaigns API URL
|
|
219
|
+
let baseUrl;
|
|
220
|
+
if (this.state.config?.apiUrl) {
|
|
221
|
+
const configUrl = this.state.config.apiUrl;
|
|
222
|
+
if (configUrl.includes("/dashboard")) {
|
|
223
|
+
baseUrl = configUrl.replace("/dashboard", "");
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
baseUrl = configUrl;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
baseUrl =
|
|
231
|
+
typeof window !== "undefined" &&
|
|
232
|
+
window.location.hostname === "localhost"
|
|
233
|
+
? "/api"
|
|
234
|
+
: "https://ops.trustshop.io/api";
|
|
235
|
+
}
|
|
236
|
+
const apiUrl = `${baseUrl}/campaigns?shop_id=${shopId}&locale=${currentLocale}`;
|
|
237
|
+
const response = await fetch(apiUrl, {
|
|
238
|
+
method: "GET",
|
|
239
|
+
headers: {
|
|
240
|
+
Accept: "application/json",
|
|
241
|
+
"Content-Type": "application/json",
|
|
242
|
+
"Accept-Language": currentLocale,
|
|
243
|
+
...(this.state.config?.headers || {}),
|
|
244
|
+
},
|
|
245
|
+
credentials: "include",
|
|
246
|
+
});
|
|
247
|
+
if (!response.ok) {
|
|
248
|
+
throw new Error(`Failed to fetch campaigns: ${response.statusText}`);
|
|
249
|
+
}
|
|
250
|
+
const data = await response.json();
|
|
251
|
+
const campaignsData = data.success && Array.isArray(data.data) ? data.data : [];
|
|
252
|
+
this.updateState({
|
|
253
|
+
campaignsData,
|
|
254
|
+
campaignsLoading: false,
|
|
255
|
+
campaignsError: null,
|
|
256
|
+
});
|
|
257
|
+
// Emit event for campaigns refresh
|
|
258
|
+
window.dispatchEvent(new CustomEvent("trustshop-campaigns-refresh", {
|
|
259
|
+
detail: { locale: currentLocale, data: campaignsData, shopId },
|
|
260
|
+
}));
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
console.error("Failed to refresh campaigns data:", error);
|
|
264
|
+
this.updateState({
|
|
265
|
+
campaignsLoading: false,
|
|
266
|
+
campaignsError: error,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
162
269
|
}
|
|
163
270
|
/**
|
|
164
271
|
* Normalize locale string to supported format
|
|
165
272
|
*/
|
|
166
273
|
normalizeLocale(locale) {
|
|
167
274
|
if (!locale)
|
|
168
|
-
return
|
|
275
|
+
return "en";
|
|
169
276
|
// Use the same normalization as translation manager
|
|
170
277
|
const SUPPORTED_LOCALES = [
|
|
171
|
-
|
|
172
|
-
|
|
278
|
+
"cn",
|
|
279
|
+
"de",
|
|
280
|
+
"dk",
|
|
281
|
+
"en",
|
|
282
|
+
"es",
|
|
283
|
+
"fr",
|
|
284
|
+
"ie",
|
|
285
|
+
"in",
|
|
286
|
+
"it",
|
|
287
|
+
"jp",
|
|
288
|
+
"nl",
|
|
289
|
+
"nz",
|
|
290
|
+
"pt",
|
|
291
|
+
"se",
|
|
292
|
+
"vi",
|
|
173
293
|
];
|
|
174
294
|
// Direct match
|
|
175
295
|
if (SUPPORTED_LOCALES.includes(locale)) {
|
|
@@ -179,19 +299,19 @@ class SDKManagerClass {
|
|
|
179
299
|
const base = locale.split(/[-_]/)[0].toLowerCase();
|
|
180
300
|
// Special mappings
|
|
181
301
|
const mappings = {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
302
|
+
zh: "cn",
|
|
303
|
+
da: "dk",
|
|
304
|
+
ga: "ie",
|
|
305
|
+
hi: "in",
|
|
306
|
+
ja: "jp",
|
|
307
|
+
mi: "nz",
|
|
308
|
+
sv: "se",
|
|
189
309
|
};
|
|
190
310
|
const mapped = mappings[base] || base;
|
|
191
311
|
if (SUPPORTED_LOCALES.includes(mapped)) {
|
|
192
312
|
return mapped;
|
|
193
313
|
}
|
|
194
|
-
return
|
|
314
|
+
return "en";
|
|
195
315
|
}
|
|
196
316
|
/**
|
|
197
317
|
* Manually update locale (for programmatic changes)
|
|
@@ -204,14 +324,12 @@ class SDKManagerClass {
|
|
|
204
324
|
* Auto-detect shop info from Shopify App Bridge or URL
|
|
205
325
|
*/
|
|
206
326
|
autoDetectShopInfo() {
|
|
207
|
-
if (typeof window ===
|
|
327
|
+
if (typeof window === "undefined")
|
|
208
328
|
return;
|
|
209
329
|
try {
|
|
210
330
|
// Method 1: Check if Shopify App Bridge is available
|
|
211
331
|
const shopifyApp = window.ShopifyApp;
|
|
212
332
|
if (shopifyApp) {
|
|
213
|
-
// Extract from App Bridge context if available
|
|
214
|
-
console.log('๐ Detected Shopify App Bridge context');
|
|
215
333
|
}
|
|
216
334
|
// Method 2: Parse from URL (admin.shopify.com)
|
|
217
335
|
const currentUrl = window.location.href;
|
|
@@ -222,13 +340,12 @@ class SDKManagerClass {
|
|
|
222
340
|
shopInfo: {
|
|
223
341
|
domain: `${storeName}.myshopify.com`,
|
|
224
342
|
id: storeName,
|
|
225
|
-
}
|
|
343
|
+
},
|
|
226
344
|
});
|
|
227
|
-
console.log('๐ Auto-detected shop from URL:', storeName);
|
|
228
345
|
}
|
|
229
346
|
}
|
|
230
347
|
catch (error) {
|
|
231
|
-
console.warn(
|
|
348
|
+
console.warn("Failed to auto-detect shop info:", error);
|
|
232
349
|
}
|
|
233
350
|
}
|
|
234
351
|
/**
|
|
@@ -249,8 +366,11 @@ class SDKManagerClass {
|
|
|
249
366
|
// Load translations
|
|
250
367
|
const baseTranslations = await loadTranslations(locale);
|
|
251
368
|
const translations = mergeTranslations(baseTranslations, options.translations);
|
|
252
|
-
// Generate config
|
|
253
|
-
const config =
|
|
369
|
+
// Generate config with locale
|
|
370
|
+
const config = {
|
|
371
|
+
...generateDashboardConfig(shopInfo, options.config),
|
|
372
|
+
locale,
|
|
373
|
+
};
|
|
254
374
|
this.updateState({
|
|
255
375
|
initialized: true,
|
|
256
376
|
locale,
|
|
@@ -260,14 +380,19 @@ class SDKManagerClass {
|
|
|
260
380
|
loading: false,
|
|
261
381
|
error: undefined,
|
|
262
382
|
});
|
|
263
|
-
|
|
383
|
+
// Automatically fetch dashboard data after initialization
|
|
384
|
+
await this.refreshDashboardData(locale);
|
|
385
|
+
// console.log("SDK initialized successfully with dashboard data", {
|
|
386
|
+
// locale,
|
|
387
|
+
// shopInfo,
|
|
388
|
+
// });
|
|
264
389
|
}
|
|
265
390
|
catch (error) {
|
|
266
391
|
this.updateState({
|
|
267
392
|
loading: false,
|
|
268
393
|
error: error,
|
|
269
394
|
});
|
|
270
|
-
console.error(
|
|
395
|
+
console.error("SDK initialization failed:", error);
|
|
271
396
|
throw error;
|
|
272
397
|
}
|
|
273
398
|
}
|
|
@@ -303,7 +428,7 @@ class SDKManagerClass {
|
|
|
303
428
|
return () => this.listeners.delete(listener);
|
|
304
429
|
}
|
|
305
430
|
notifyListeners() {
|
|
306
|
-
this.listeners.forEach(listener => listener());
|
|
431
|
+
this.listeners.forEach((listener) => listener());
|
|
307
432
|
}
|
|
308
433
|
/**
|
|
309
434
|
* Get component defaults
|
|
@@ -311,11 +436,32 @@ class SDKManagerClass {
|
|
|
311
436
|
getDefaults() {
|
|
312
437
|
return COMPONENT_DEFAULTS;
|
|
313
438
|
}
|
|
439
|
+
/**
|
|
440
|
+
* Get dashboard engine instance
|
|
441
|
+
*/
|
|
442
|
+
getDashboardEngine() {
|
|
443
|
+
return this.dashboardEngine;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Get dashboard data
|
|
447
|
+
*/
|
|
448
|
+
getDashboardData() {
|
|
449
|
+
return this.state.dashboardData;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Get campaigns data
|
|
453
|
+
*/
|
|
454
|
+
getCampaignsData() {
|
|
455
|
+
return this.state.campaignsData;
|
|
456
|
+
}
|
|
314
457
|
/**
|
|
315
458
|
* Check if SDK is ready for use
|
|
316
459
|
*/
|
|
317
460
|
isReady() {
|
|
318
|
-
return this.state.initialized &&
|
|
461
|
+
return (this.state.initialized &&
|
|
462
|
+
!this.state.loading &&
|
|
463
|
+
!this.state.error &&
|
|
464
|
+
!this.state.dashboardLoading);
|
|
319
465
|
}
|
|
320
466
|
/**
|
|
321
467
|
* Cleanup observers and listeners
|
|
@@ -324,12 +470,12 @@ class SDKManagerClass {
|
|
|
324
470
|
if (this.localeObserver) {
|
|
325
471
|
this.localeObserver.disconnect();
|
|
326
472
|
}
|
|
327
|
-
if (typeof window !==
|
|
328
|
-
window.removeEventListener(
|
|
329
|
-
window.removeEventListener(
|
|
473
|
+
if (typeof window !== "undefined") {
|
|
474
|
+
window.removeEventListener("trustshop-locale-change", this.handleCustomLocaleChange);
|
|
475
|
+
window.removeEventListener("shopify-locale-change", this.handleCustomLocaleChange);
|
|
330
476
|
}
|
|
331
477
|
this.listeners.clear();
|
|
332
|
-
console.log(
|
|
478
|
+
// console.log("SDK Manager cleaned up");
|
|
333
479
|
}
|
|
334
480
|
}
|
|
335
481
|
// ============================================
|
|
@@ -339,7 +485,7 @@ export const SDKManager = new SDKManagerClass();
|
|
|
339
485
|
// ============================================
|
|
340
486
|
// React Hook for Components
|
|
341
487
|
// ============================================
|
|
342
|
-
import { useState, useEffect } from
|
|
488
|
+
import { useState, useEffect } from "react";
|
|
343
489
|
/**
|
|
344
490
|
* Hook for components to connect to SDK Manager
|
|
345
491
|
* Automatically initializes SDK on first use
|
|
@@ -374,6 +520,7 @@ export function useSDK(options = {}) {
|
|
|
374
520
|
isInitializing,
|
|
375
521
|
defaults: SDKManager.getDefaults(),
|
|
376
522
|
isReady: SDKManager.isReady(),
|
|
523
|
+
dashboardEngine: SDKManager.getDashboardEngine(),
|
|
377
524
|
};
|
|
378
525
|
}
|
|
379
526
|
export default SDKManager;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SDKManager.js","sourceRoot":"","sources":["../../src/core/SDKManager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SDK Manager - Internal singleton for managing global state\n * Components automatically connect to this without manual provider setup\n */\n\nimport { \n loadTranslations, \n getTranslations, \n mergeTranslations,\n type SupportedLocale,\n type SDKTranslations \n} from '../translations/translation-manager';\nimport { generateDashboardConfig, type ShopInfo, type SDKInternalConfig } from '../config/internal-config';\nimport { COMPONENT_DEFAULTS } from '../config/component-defaults';\n\n// ============================================\n// SDK Global State\n// ============================================\n\ninterface SDKState {\n initialized: boolean;\n shopInfo?: ShopInfo;\n locale: SupportedLocale;\n translations: SDKTranslations;\n config: SDKInternalConfig;\n loading: boolean;\n error?: Error;\n}\n\ninterface SDKOptions {\n shopInfo?: ShopInfo;\n locale?: SupportedLocale;\n translations?: Partial<SDKTranslations>;\n config?: Partial<SDKInternalConfig>;\n}\n\n// ============================================\n// SDK Manager Singleton\n// ============================================\n\nclass SDKManagerClass {\n private state: SDKState;\n private listeners: Set<() => void> = new Set();\n private initPromise?: Promise<void>;\n private localeObserver?: MutationObserver;\n private currentDetectedLocale?: SupportedLocale;\n\n constructor() {\n this.state = {\n initialized: false,\n locale: 'en',\n translations: getTranslations('en'),\n config: generateDashboardConfig(),\n loading: false,\n };\n\n // Try to auto-detect Shopify context and locale\n this.autoDetectShopInfo();\n this.autoDetectLocale();\n this.setupLocaleWatcher();\n }\n\n /**\n * Auto-detect current locale from browser/Shopify context\n */\n private autoDetectLocale(): void {\n if (typeof window === 'undefined') return;\n\n try {\n // Method 1: Check Shopify Admin locale (if available)\n const shopifyLocale = this.getShopifyAdminLocale();\n if (shopifyLocale) {\n this.currentDetectedLocale = shopifyLocale;\n this.updateLocale(shopifyLocale);\n console.log('๐ Auto-detected Shopify locale:', shopifyLocale);\n return;\n }\n\n // Method 2: Browser language\n const browserLocale = navigator.language || navigator.languages?.[0];\n if (browserLocale) {\n const normalizedLocale = this.normalizeLocale(browserLocale);\n this.currentDetectedLocale = normalizedLocale;\n this.updateLocale(normalizedLocale);\n console.log('๐ Auto-detected browser locale:', normalizedLocale);\n }\n } catch (error) {\n console.warn('Failed to auto-detect locale:', error);\n }\n }\n\n /**\n * Get locale from Shopify Admin context\n */\n private getShopifyAdminLocale(): SupportedLocale | null {\n try {\n // Check if we can detect locale from Shopify admin\n const html = document.documentElement;\n const lang = html.getAttribute('lang') || html.getAttribute('xml:lang');\n \n if (lang) {\n return this.normalizeLocale(lang);\n }\n\n // Check meta tags\n const metaLang = document.querySelector('meta[http-equiv=\"content-language\"]');\n if (metaLang) {\n const content = metaLang.getAttribute('content');\n if (content) {\n return this.normalizeLocale(content);\n }\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Setup watcher for locale changes in the DOM\n */\n private setupLocaleWatcher(): void {\n if (typeof window === 'undefined') return;\n\n try {\n this.localeObserver = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (mutation.type === 'attributes' && \n (mutation.attributeName === 'lang' || mutation.attributeName === 'xml:lang')) {\n const newLocale = this.getShopifyAdminLocale();\n if (newLocale && newLocale !== this.currentDetectedLocale) {\n console.log('๐ Detected locale change:', this.currentDetectedLocale, 'โ', newLocale);\n this.currentDetectedLocale = newLocale;\n this.handleLocaleChange(newLocale);\n }\n }\n });\n });\n\n // Watch for changes to document element attributes\n this.localeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['lang', 'xml:lang']\n });\n\n // Also listen for custom locale change events\n window.addEventListener('trustshop-locale-change', this.handleCustomLocaleChange.bind(this));\n window.addEventListener('shopify-locale-change', this.handleCustomLocaleChange.bind(this));\n \n console.log('๐ Locale watcher initialized');\n } catch (error) {\n console.warn('Failed to setup locale watcher:', error);\n }\n }\n\n /**\n * Handle custom locale change events\n */\n private handleCustomLocaleChange = (event: any) => {\n const newLocale = event.detail?.locale || event.detail;\n if (newLocale && typeof newLocale === 'string') {\n const normalizedLocale = this.normalizeLocale(newLocale);\n console.log('๐ก Received locale change event:', normalizedLocale);\n this.handleLocaleChange(normalizedLocale);\n }\n };\n\n /**\n * Handle locale changes (re-fetch data and translations)\n */\n private async handleLocaleChange(newLocale: SupportedLocale): Promise<void> {\n if (newLocale === this.state.locale) return;\n\n try {\n console.log('๐ Updating SDK locale:', this.state.locale, 'โ', newLocale);\n this.updateState({ loading: true });\n\n // Load new translations\n const baseTranslations = await loadTranslations(newLocale);\n const translations = mergeTranslations(baseTranslations);\n\n // Update state\n this.updateState({\n locale: newLocale,\n translations,\n loading: false,\n });\n\n // Trigger re-fetch of API data with new locale\n this.refreshDataWithNewLocale(newLocale);\n\n console.log('โ
SDK locale updated successfully');\n } catch (error) {\n console.error('โ Failed to update SDK locale:', error);\n this.updateState({ loading: false, error: error as Error });\n }\n }\n\n /**\n * Refresh API data with new locale\n */\n private refreshDataWithNewLocale(locale: SupportedLocale): void {\n // Clear any cached data and trigger re-fetch\n // This will cause all components to re-fetch their data\n \n // Emit event for hooks to re-fetch data\n window.dispatchEvent(new CustomEvent('trustshop-data-refresh', {\n detail: { locale, reason: 'locale-change' }\n }));\n\n console.log('๐ก Triggered data refresh for locale:', locale);\n }\n\n /**\n * Normalize locale string to supported format\n */\n private normalizeLocale(locale: string): SupportedLocale {\n if (!locale) return 'en';\n \n // Use the same normalization as translation manager\n const SUPPORTED_LOCALES: SupportedLocale[] = [\n 'cn', 'de', 'dk', 'en', 'es', 'fr', 'ie', 'in',\n 'it', 'jp', 'nl', 'nz', 'pt', 'se', 'vi'\n ];\n \n // Direct match\n if (SUPPORTED_LOCALES.includes(locale as SupportedLocale)) {\n return locale as SupportedLocale;\n }\n \n // Extract base locale (en-US โ en)\n const base = locale.split(/[-_]/)[0].toLowerCase();\n \n // Special mappings\n const mappings: Record<string, SupportedLocale> = {\n 'zh': 'cn',\n 'da': 'dk',\n 'ga': 'ie',\n 'hi': 'in',\n 'ja': 'jp',\n 'mi': 'nz',\n 'sv': 'se',\n };\n \n const mapped = mappings[base] || base;\n \n if (SUPPORTED_LOCALES.includes(mapped as SupportedLocale)) {\n return mapped as SupportedLocale;\n }\n \n return 'en';\n }\n\n /**\n * Manually update locale (for programmatic changes)\n */\n async updateLocale(newLocale: string | SupportedLocale): Promise<void> {\n const normalizedLocale = this.normalizeLocale(newLocale);\n await this.handleLocaleChange(normalizedLocale);\n }\n\n /**\n * Auto-detect shop info from Shopify App Bridge or URL\n */\n private autoDetectShopInfo(): void {\n if (typeof window === 'undefined') return;\n\n try {\n // Method 1: Check if Shopify App Bridge is available\n const shopifyApp = (window as any).ShopifyApp;\n if (shopifyApp) {\n // Extract from App Bridge context if available\n console.log('๐ Detected Shopify App Bridge context');\n }\n\n // Method 2: Parse from URL (admin.shopify.com)\n const currentUrl = window.location.href;\n const shopifyAdminMatch = currentUrl.match(\n /https:\\/\\/admin\\.shopify\\.com\\/store\\/([^\\/]+)/\n );\n \n if (shopifyAdminMatch) {\n const [, storeName] = shopifyAdminMatch;\n this.updateState({\n shopInfo: {\n domain: `${storeName}.myshopify.com`,\n id: storeName,\n }\n });\n console.log('๐ Auto-detected shop from URL:', storeName);\n }\n } catch (error) {\n console.warn('Failed to auto-detect shop info:', error);\n }\n }\n\n /**\n * Initialize SDK with options (called automatically by components)\n */\n async initialize(options: SDKOptions = {}): Promise<void> {\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = this.performInitialization(options);\n return this.initPromise;\n }\n\n private async performInitialization(options: SDKOptions): Promise<void> {\n try {\n this.updateState({ loading: true });\n\n const locale = options.locale || this.state.locale;\n const shopInfo = options.shopInfo || this.state.shopInfo;\n\n // Load translations\n const baseTranslations = await loadTranslations(locale);\n const translations = mergeTranslations(baseTranslations, options.translations);\n\n // Generate config\n const config = generateDashboardConfig(shopInfo, options.config);\n\n this.updateState({\n initialized: true,\n locale,\n shopInfo,\n translations,\n config,\n loading: false,\n error: undefined,\n });\n\n console.log('โ
SDK initialized successfully', { locale, shopInfo });\n } catch (error) {\n this.updateState({\n loading: false,\n error: error as Error,\n });\n console.error('โ SDK initialization failed:', error);\n throw error;\n }\n }\n\n /**\n * Update SDK state and notify listeners\n */\n private updateState(updates: Partial<SDKState>): void {\n this.state = { ...this.state, ...updates };\n this.notifyListeners();\n }\n\n /**\n * Update configuration (called when components pass new props)\n */\n async updateConfig(options: SDKOptions): Promise<void> {\n const hasChanges = \n options.locale !== this.state.locale ||\n JSON.stringify(options.shopInfo) !== JSON.stringify(this.state.shopInfo);\n\n if (hasChanges) {\n this.initPromise = undefined; // Reset init promise to allow re-initialization\n await this.initialize(options);\n }\n }\n\n /**\n * Get current state\n */\n getState(): SDKState {\n return this.state;\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private notifyListeners(): void {\n this.listeners.forEach(listener => listener());\n }\n\n /**\n * Get component defaults\n */\n getDefaults() {\n return COMPONENT_DEFAULTS;\n }\n\n /**\n * Check if SDK is ready for use\n */\n isReady(): boolean {\n return this.state.initialized && !this.state.loading && !this.state.error;\n }\n\n /**\n * Cleanup observers and listeners\n */\n destroy(): void {\n if (this.localeObserver) {\n this.localeObserver.disconnect();\n }\n \n if (typeof window !== 'undefined') {\n window.removeEventListener('trustshop-locale-change', this.handleCustomLocaleChange);\n window.removeEventListener('shopify-locale-change', this.handleCustomLocaleChange);\n }\n \n this.listeners.clear();\n console.log('๐งน SDK Manager cleaned up');\n }\n}\n\n// ============================================\n// Export Singleton Instance\n// ============================================\n\nexport const SDKManager = new SDKManagerClass();\n\n// ============================================\n// React Hook for Components\n// ============================================\n\nimport { useState, useEffect } from 'react';\n\nexport interface UseSDKOptions {\n shopInfo?: ShopInfo;\n locale?: SupportedLocale;\n translations?: Partial<SDKTranslations>;\n config?: Partial<SDKInternalConfig>;\n}\n\n/**\n * Hook for components to connect to SDK Manager\n * Automatically initializes SDK on first use\n */\nexport function useSDK(options: UseSDKOptions = {}) {\n const [state, setState] = useState(() => SDKManager.getState());\n const [isInitializing, setIsInitializing] = useState(false);\n\n // Subscribe to state changes\n useEffect(() => {\n const unsubscribe = SDKManager.subscribe(() => {\n setState(SDKManager.getState());\n });\n return unsubscribe;\n }, []);\n\n // Auto-initialize SDK when component mounts\n useEffect(() => {\n if (!state.initialized && !isInitializing) {\n setIsInitializing(true);\n SDKManager.initialize(options).finally(() => {\n setIsInitializing(false);\n });\n }\n }, [state.initialized, isInitializing]);\n\n // Update config if options change\n useEffect(() => {\n if (state.initialized) {\n SDKManager.updateConfig(options);\n }\n }, [state.initialized, JSON.stringify(options)]);\n\n return {\n ...state,\n isInitializing,\n defaults: SDKManager.getDefaults(),\n isReady: SDKManager.isReady(),\n };\n}\n\nexport default SDKManager;"]}
|
|
1
|
+
{"version":3,"file":"SDKManager.js","sourceRoot":"","sources":["../../src/core/SDKManager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SDK Manager - Internal singleton for managing global state\n * Components automatically connect to this without manual provider setup\n */\n\nimport {\n loadTranslations,\n getTranslations,\n mergeTranslations,\n type SupportedLocale,\n type SDKTranslations,\n} from \"../translations/translation-manager\";\nimport {\n generateDashboardConfig,\n type ShopInfo,\n type SDKInternalConfig,\n} from \"../config/internal-config\";\nimport { COMPONENT_DEFAULTS } from \"../config/component-defaults\";\nimport { DashboardEngine } from \"./engine\";\nimport { DashboardData } from \"../types\";\n\n// ============================================\n// SDK Global State\n// ============================================\n\ninterface SDKState {\n initialized: boolean;\n shopInfo?: ShopInfo;\n locale: SupportedLocale;\n translations: SDKTranslations;\n config: SDKInternalConfig;\n loading: boolean;\n error?: Error;\n dashboardData?: DashboardData | null;\n dashboardLoading?: boolean;\n dashboardError?: Error | null;\n campaignsData?: any[] | null;\n campaignsLoading?: boolean;\n campaignsError?: Error | null;\n}\n\ninterface SDKOptions {\n shopInfo?: ShopInfo;\n locale?: SupportedLocale;\n translations?: Partial<SDKTranslations>;\n config?: Partial<SDKInternalConfig>;\n}\n\n// ============================================\n// SDK Manager Singleton\n// ============================================\n\nclass SDKManagerClass {\n private state: SDKState;\n private listeners: Set<() => void> = new Set();\n private initPromise?: Promise<void>;\n private localeObserver?: MutationObserver;\n private currentDetectedLocale?: SupportedLocale;\n private dashboardEngine?: DashboardEngine;\n\n constructor() {\n this.state = {\n initialized: false,\n locale: \"en\",\n translations: getTranslations(\"en\"),\n config: generateDashboardConfig(),\n loading: false,\n };\n\n // Try to auto-detect Shopify context and locale\n this.autoDetectShopInfo();\n this.autoDetectLocale();\n this.setupLocaleWatcher();\n }\n\n /**\n * Auto-detect current locale from browser/Shopify context\n */\n private autoDetectLocale(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n // Method 1: Check Shopify Admin locale (if available)\n const shopifyLocale = this.getShopifyAdminLocale();\n if (shopifyLocale) {\n this.currentDetectedLocale = shopifyLocale;\n this.updateLocale(shopifyLocale);\n // console.log(\"Auto-detected Shopify locale:\", shopifyLocale);\n return;\n }\n\n // Method 2: Browser language\n const browserLocale = navigator.language || navigator.languages?.[0];\n if (browserLocale) {\n const normalizedLocale = this.normalizeLocale(browserLocale);\n this.currentDetectedLocale = normalizedLocale;\n this.updateLocale(normalizedLocale);\n // console.log(\"Auto-detected browser locale:\", normalizedLocale);\n }\n } catch (error) {\n console.warn(\"Failed to auto-detect locale:\", error);\n }\n }\n\n /**\n * Get locale from Shopify Admin context\n */\n private getShopifyAdminLocale(): SupportedLocale | null {\n try {\n // Check if we can detect locale from Shopify admin\n const html = document.documentElement;\n const lang = html.getAttribute(\"lang\") || html.getAttribute(\"xml:lang\");\n\n if (lang) {\n return this.normalizeLocale(lang);\n }\n\n // Check meta tags\n const metaLang = document.querySelector(\n 'meta[http-equiv=\"content-language\"]',\n );\n if (metaLang) {\n const content = metaLang.getAttribute(\"content\");\n if (content) {\n return this.normalizeLocale(content);\n }\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Setup watcher for locale changes in the DOM\n */\n private setupLocaleWatcher(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n this.localeObserver = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (\n mutation.type === \"attributes\" &&\n (mutation.attributeName === \"lang\" ||\n mutation.attributeName === \"xml:lang\")\n ) {\n const newLocale = this.getShopifyAdminLocale();\n if (newLocale && newLocale !== this.currentDetectedLocale) {\n // console.log(\n // \"Detected locale change:\",\n // this.currentDetectedLocale,\n // \"โ\",\n // newLocale,\n // );\n this.currentDetectedLocale = newLocale;\n this.handleLocaleChange(newLocale);\n }\n }\n });\n });\n\n // Watch for changes to document element attributes\n this.localeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"lang\", \"xml:lang\"],\n });\n\n // Also listen for custom locale change events\n window.addEventListener(\n \"trustshop-locale-change\",\n this.handleCustomLocaleChange.bind(this),\n );\n window.addEventListener(\n \"shopify-locale-change\",\n this.handleCustomLocaleChange.bind(this),\n );\n\n // console.log(\"Locale watcher initialized\");\n } catch (error) {\n console.warn(\"Failed to setup locale watcher:\", error);\n }\n }\n\n /**\n * Handle custom locale change events\n */\n private handleCustomLocaleChange = (event: any) => {\n const newLocale = event.detail?.locale || event.detail;\n if (newLocale && typeof newLocale === \"string\") {\n const normalizedLocale = this.normalizeLocale(newLocale);\n // console.log(\"Received locale change event:\", normalizedLocale);\n this.handleLocaleChange(normalizedLocale);\n }\n };\n\n /**\n * Handle locale changes (re-fetch data and translations)\n */\n private async handleLocaleChange(newLocale: SupportedLocale): Promise<void> {\n if (newLocale === this.state.locale) return;\n\n try {\n // console.log(Updating SDK locale:\", this.state.locale, \"โ\", newLocale);\n this.updateState({ loading: true });\n\n // Load new translations\n const baseTranslations = await loadTranslations(newLocale);\n const translations = mergeTranslations(baseTranslations);\n\n // Update config with new locale\n const newConfig = { ...this.state.config, locale: newLocale };\n\n // Update state\n this.updateState({\n locale: newLocale,\n translations,\n config: newConfig,\n loading: false,\n });\n\n // Trigger re-fetch of API data with new locale\n await this.refreshDashboardData(newLocale);\n\n // console.log(\"SDK locale updated successfully\");\n } catch (error) {\n console.error(\" Failed to update SDK locale:\", error);\n this.updateState({ loading: false, error: error as Error });\n }\n }\n\n /**\n * Refresh dashboard data with new locale\n */\n private async refreshDashboardData(locale?: SupportedLocale): Promise<void> {\n try {\n this.updateState({ dashboardLoading: true, dashboardError: null });\n\n const currentLocale = locale || this.state.locale;\n const config = { ...this.state.config, locale: currentLocale };\n\n // Initialize or update dashboard engine\n if (!this.dashboardEngine) {\n this.dashboardEngine = DashboardEngine.getInstance(config);\n } else {\n // Update engine config with new locale\n await this.dashboardEngine.setLocale(currentLocale);\n }\n\n // Fetch dashboard data\n await this.dashboardEngine.init();\n const dashboardData = this.dashboardEngine.getData();\n\n this.updateState({\n dashboardData,\n dashboardLoading: false,\n dashboardError: null,\n });\n\n // Also refresh campaigns data\n await this.refreshCampaignsData(currentLocale);\n\n // Emit event for components to refresh\n window.dispatchEvent(\n new CustomEvent(\"trustshop-data-refresh\", {\n detail: {\n locale: currentLocale,\n reason: \"locale-change\",\n data: dashboardData,\n },\n }),\n );\n\n // console.log(`Dashboard data refreshed for locale: ${currentLocale}`);\n } catch (error) {\n console.error(\"Failed to refresh dashboard data:\", error);\n this.updateState({\n dashboardLoading: false,\n dashboardError: error as Error,\n });\n }\n }\n\n /**\n * Refresh campaigns data with new locale\n */\n private async refreshCampaignsData(locale?: SupportedLocale): Promise<void> {\n try {\n // Only fetch campaigns if we have a shop ID\n if (!this.state.shopInfo?.id) {\n // console.log(\"Skipping campaigns fetch - no shop ID available\");\n return;\n }\n\n this.updateState({ campaignsLoading: true, campaignsError: null });\n\n const currentLocale = locale || this.state.locale;\n const shopId = this.state.shopInfo.id;\n\n // Build campaigns API URL\n let baseUrl: string;\n if (this.state.config?.apiUrl) {\n const configUrl = this.state.config.apiUrl;\n if (configUrl.includes(\"/dashboard\")) {\n baseUrl = configUrl.replace(\"/dashboard\", \"\");\n } else {\n baseUrl = configUrl;\n }\n } else {\n baseUrl =\n typeof window !== \"undefined\" &&\n window.location.hostname === \"localhost\"\n ? \"/api\"\n : \"https://ops.trustshop.io/api\";\n }\n\n const apiUrl = `${baseUrl}/campaigns?shop_id=${shopId}&locale=${currentLocale}`;\n\n const response = await fetch(apiUrl, {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n \"Accept-Language\": currentLocale,\n ...(this.state.config?.headers || {}),\n },\n credentials: \"include\",\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch campaigns: ${response.statusText}`);\n }\n\n const data = await response.json();\n\n const campaignsData =\n data.success && Array.isArray(data.data) ? data.data : [];\n\n this.updateState({\n campaignsData,\n campaignsLoading: false,\n campaignsError: null,\n });\n\n // Emit event for campaigns refresh\n window.dispatchEvent(\n new CustomEvent(\"trustshop-campaigns-refresh\", {\n detail: { locale: currentLocale, data: campaignsData, shopId },\n }),\n );\n } catch (error) {\n console.error(\"Failed to refresh campaigns data:\", error);\n this.updateState({\n campaignsLoading: false,\n campaignsError: error as Error,\n });\n }\n }\n\n /**\n * Normalize locale string to supported format\n */\n private normalizeLocale(locale: string): SupportedLocale {\n if (!locale) return \"en\";\n\n // Use the same normalization as translation manager\n const SUPPORTED_LOCALES: SupportedLocale[] = [\n \"cn\",\n \"de\",\n \"dk\",\n \"en\",\n \"es\",\n \"fr\",\n \"ie\",\n \"in\",\n \"it\",\n \"jp\",\n \"nl\",\n \"nz\",\n \"pt\",\n \"se\",\n \"vi\",\n ];\n\n // Direct match\n if (SUPPORTED_LOCALES.includes(locale as SupportedLocale)) {\n return locale as SupportedLocale;\n }\n\n // Extract base locale (en-US โ en)\n const base = locale.split(/[-_]/)[0].toLowerCase();\n\n // Special mappings\n const mappings: Record<string, SupportedLocale> = {\n zh: \"cn\",\n da: \"dk\",\n ga: \"ie\",\n hi: \"in\",\n ja: \"jp\",\n mi: \"nz\",\n sv: \"se\",\n };\n\n const mapped = mappings[base] || base;\n\n if (SUPPORTED_LOCALES.includes(mapped as SupportedLocale)) {\n return mapped as SupportedLocale;\n }\n\n return \"en\";\n }\n\n /**\n * Manually update locale (for programmatic changes)\n */\n async updateLocale(newLocale: string | SupportedLocale): Promise<void> {\n const normalizedLocale = this.normalizeLocale(newLocale);\n await this.handleLocaleChange(normalizedLocale);\n }\n\n /**\n * Auto-detect shop info from Shopify App Bridge or URL\n */\n private autoDetectShopInfo(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n // Method 1: Check if Shopify App Bridge is available\n const shopifyApp = (window as any).ShopifyApp;\n if (shopifyApp) {\n }\n\n // Method 2: Parse from URL (admin.shopify.com)\n const currentUrl = window.location.href;\n const shopifyAdminMatch = currentUrl.match(\n /https:\\/\\/admin\\.shopify\\.com\\/store\\/([^\\/]+)/,\n );\n\n if (shopifyAdminMatch) {\n const [, storeName] = shopifyAdminMatch;\n this.updateState({\n shopInfo: {\n domain: `${storeName}.myshopify.com`,\n id: storeName,\n },\n });\n }\n } catch (error) {\n console.warn(\"Failed to auto-detect shop info:\", error);\n }\n }\n\n /**\n * Initialize SDK with options (called automatically by components)\n */\n async initialize(options: SDKOptions = {}): Promise<void> {\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = this.performInitialization(options);\n return this.initPromise;\n }\n\n private async performInitialization(options: SDKOptions): Promise<void> {\n try {\n this.updateState({ loading: true });\n\n const locale = options.locale || this.state.locale;\n const shopInfo = options.shopInfo || this.state.shopInfo;\n\n // Load translations\n const baseTranslations = await loadTranslations(locale);\n const translations = mergeTranslations(\n baseTranslations,\n options.translations,\n );\n\n // Generate config with locale\n const config = {\n ...generateDashboardConfig(shopInfo, options.config),\n locale,\n };\n\n this.updateState({\n initialized: true,\n locale,\n shopInfo,\n translations,\n config,\n loading: false,\n error: undefined,\n });\n\n // Automatically fetch dashboard data after initialization\n await this.refreshDashboardData(locale);\n\n // console.log(\"SDK initialized successfully with dashboard data\", {\n // locale,\n // shopInfo,\n // });\n } catch (error) {\n this.updateState({\n loading: false,\n error: error as Error,\n });\n console.error(\"SDK initialization failed:\", error);\n throw error;\n }\n }\n\n /**\n * Update SDK state and notify listeners\n */\n private updateState(updates: Partial<SDKState>): void {\n this.state = { ...this.state, ...updates };\n this.notifyListeners();\n }\n\n /**\n * Update configuration (called when components pass new props)\n */\n async updateConfig(options: SDKOptions): Promise<void> {\n const hasChanges =\n options.locale !== this.state.locale ||\n JSON.stringify(options.shopInfo) !== JSON.stringify(this.state.shopInfo);\n\n if (hasChanges) {\n this.initPromise = undefined; // Reset init promise to allow re-initialization\n await this.initialize(options);\n }\n }\n\n /**\n * Get current state\n */\n getState(): SDKState {\n return this.state;\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private notifyListeners(): void {\n this.listeners.forEach((listener) => listener());\n }\n\n /**\n * Get component defaults\n */\n getDefaults() {\n return COMPONENT_DEFAULTS;\n }\n\n /**\n * Get dashboard engine instance\n */\n getDashboardEngine(): DashboardEngine | undefined {\n return this.dashboardEngine;\n }\n\n /**\n * Get dashboard data\n */\n getDashboardData(): DashboardData | null | undefined {\n return this.state.dashboardData;\n }\n\n /**\n * Get campaigns data\n */\n getCampaignsData(): any[] | null | undefined {\n return this.state.campaignsData;\n }\n\n /**\n * Check if SDK is ready for use\n */\n isReady(): boolean {\n return (\n this.state.initialized &&\n !this.state.loading &&\n !this.state.error &&\n !this.state.dashboardLoading\n );\n }\n\n /**\n * Cleanup observers and listeners\n */\n destroy(): void {\n if (this.localeObserver) {\n this.localeObserver.disconnect();\n }\n\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\n \"trustshop-locale-change\",\n this.handleCustomLocaleChange,\n );\n window.removeEventListener(\n \"shopify-locale-change\",\n this.handleCustomLocaleChange,\n );\n }\n\n this.listeners.clear();\n // console.log(\"SDK Manager cleaned up\");\n }\n}\n\n// ============================================\n// Export Singleton Instance\n// ============================================\n\nexport const SDKManager = new SDKManagerClass();\n\n// ============================================\n// React Hook for Components\n// ============================================\n\nimport { useState, useEffect } from \"react\";\n\nexport interface UseSDKOptions {\n shopInfo?: ShopInfo;\n locale?: SupportedLocale;\n translations?: Partial<SDKTranslations>;\n config?: Partial<SDKInternalConfig>;\n}\n\n/**\n * Hook for components to connect to SDK Manager\n * Automatically initializes SDK on first use\n */\nexport function useSDK(options: UseSDKOptions = {}) {\n const [state, setState] = useState(() => SDKManager.getState());\n const [isInitializing, setIsInitializing] = useState(false);\n\n // Subscribe to state changes\n useEffect(() => {\n const unsubscribe = SDKManager.subscribe(() => {\n setState(SDKManager.getState());\n });\n return unsubscribe;\n }, []);\n\n // Auto-initialize SDK when component mounts\n useEffect(() => {\n if (!state.initialized && !isInitializing) {\n setIsInitializing(true);\n SDKManager.initialize(options).finally(() => {\n setIsInitializing(false);\n });\n }\n }, [state.initialized, isInitializing]);\n\n // Update config if options change\n useEffect(() => {\n if (state.initialized) {\n SDKManager.updateConfig(options);\n }\n }, [state.initialized, JSON.stringify(options)]);\n\n return {\n ...state,\n isInitializing,\n defaults: SDKManager.getDefaults(),\n isReady: SDKManager.isReady(),\n dashboardEngine: SDKManager.getDashboardEngine(),\n };\n}\n\nexport default SDKManager;\n"]}
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -3,10 +3,8 @@ export * from "./useBanner";
|
|
|
3
3
|
export * from "./useApps";
|
|
4
4
|
export * from "./useArticles";
|
|
5
5
|
export * from "./useWhatsNew";
|
|
6
|
-
export * from "./useGrowApps";
|
|
7
6
|
export * from "./usePartnerIntegration";
|
|
8
7
|
export * from "./useFloatingCards";
|
|
9
8
|
export * from "./useCampaignTracking";
|
|
10
|
-
export * from "./
|
|
11
|
-
export * from "./useFloatingCardEngine";
|
|
9
|
+
export * from "./useTranslations";
|
|
12
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC"}
|
package/dist/hooks/index.js
CHANGED
|
@@ -3,10 +3,8 @@ export * from "./useBanner";
|
|
|
3
3
|
export * from "./useApps";
|
|
4
4
|
export * from "./useArticles";
|
|
5
5
|
export * from "./useWhatsNew";
|
|
6
|
-
export * from "./useGrowApps";
|
|
7
6
|
export * from "./usePartnerIntegration";
|
|
8
7
|
export * from "./useFloatingCards";
|
|
9
8
|
export * from "./useCampaignTracking";
|
|
10
|
-
export * from "./
|
|
11
|
-
export * from "./useFloatingCardEngine";
|
|
9
|
+
export * from "./useTranslations";
|
|
12
10
|
//# sourceMappingURL=index.js.map
|