@tagadapay/plugin-sdk 2.1.2 โ 2.1.3
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/react/hooks/useCheckout.d.ts +0 -5
- package/dist/react/hooks/useCheckout.js +15 -32
- package/dist/react/hooks/useISOData.js +37 -5
- package/dist/react/hooks/useLogin.js +4 -4
- package/dist/react/hooks/useOffers.js +7 -2
- package/dist/react/hooks/useProducts.js +3 -2
- package/dist/react/index.d.ts +2 -4
- package/dist/react/index.js +1 -3
- package/dist/react/providers/TagadaProvider.d.ts +1 -3
- package/dist/react/providers/TagadaProvider.js +89 -43
- package/dist/react/services/apiService.d.ts +4 -2
- package/dist/react/services/apiService.js +6 -2
- package/package.json +1 -2
- package/dist/react/components/AddressForm.example.d.ts +0 -1
- package/dist/react/components/AddressForm.example.js +0 -32
- package/dist/react/hooks/useAddress.d.ts +0 -59
- package/dist/react/hooks/useAddress.js +0 -557
- package/dist/react/hooks/useAddressV2.d.ts +0 -53
- package/dist/react/hooks/useAddressV2.js +0 -379
|
@@ -228,12 +228,7 @@ export interface CheckoutData {
|
|
|
228
228
|
availablePromotions: Promotion[];
|
|
229
229
|
}
|
|
230
230
|
export interface UseCheckoutOptions {
|
|
231
|
-
autoRefresh?: boolean;
|
|
232
|
-
refreshInterval?: number;
|
|
233
|
-
realTimeUpdates?: boolean;
|
|
234
|
-
autoInitFromUrl?: boolean;
|
|
235
231
|
checkoutToken?: string;
|
|
236
|
-
fallbackToken?: string;
|
|
237
232
|
autoLoadFromToken?: boolean;
|
|
238
233
|
}
|
|
239
234
|
export interface UseCheckoutResult {
|
|
@@ -1,27 +1,19 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { useCurrency } from '../hooks/useCurrency';
|
|
3
3
|
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
4
|
-
import { getCheckoutToken } from '../utils/urlUtils';
|
|
5
4
|
import { collectTrackingData } from '../utils/trackingUtils';
|
|
5
|
+
import { usePluginConfig } from './usePluginConfig';
|
|
6
6
|
export function useCheckout(options = {}) {
|
|
7
|
-
const { apiService, updateCheckoutDebugData, refreshCoordinator,
|
|
7
|
+
const { apiService, updateCheckoutDebugData, refreshCoordinator, currency } = useTagadaContext();
|
|
8
|
+
const { storeId } = usePluginConfig();
|
|
8
9
|
const { code: currentCurrency } = useCurrency();
|
|
9
10
|
const [checkout, setCheckout] = useState(null);
|
|
10
11
|
const [isLoading, setIsLoading] = useState(false);
|
|
11
12
|
const [error, setError] = useState(null);
|
|
12
13
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
13
|
-
const {
|
|
14
|
-
const refreshTimeoutRef = useRef(null);
|
|
14
|
+
const { checkoutToken: providedToken, autoLoadFromToken = true, } = options;
|
|
15
15
|
const currentCheckoutTokenRef = useRef(null);
|
|
16
16
|
const hasAutoLoadedRef = useRef(false);
|
|
17
|
-
// Clear refresh timeout on unmount
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
return () => {
|
|
20
|
-
if (refreshTimeoutRef.current) {
|
|
21
|
-
clearTimeout(refreshTimeoutRef.current);
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
}, []);
|
|
25
17
|
// Update debug data whenever checkout state changes with comprehensive information
|
|
26
18
|
useEffect(() => {
|
|
27
19
|
const debugData = checkout
|
|
@@ -73,6 +65,7 @@ export function useCheckout(options = {}) {
|
|
|
73
65
|
};
|
|
74
66
|
const requestBody = {
|
|
75
67
|
...params,
|
|
68
|
+
storeId: params.storeId || storeId, // Use storeId from params or from usePluginConfig
|
|
76
69
|
returnUrl: params.returnUrl || window.location.origin,
|
|
77
70
|
customer: {
|
|
78
71
|
...params.customer,
|
|
@@ -111,7 +104,7 @@ export function useCheckout(options = {}) {
|
|
|
111
104
|
finally {
|
|
112
105
|
setIsLoading(false);
|
|
113
106
|
}
|
|
114
|
-
}, [apiService, currentCurrency, providedToken]);
|
|
107
|
+
}, [apiService, currentCurrency, providedToken, storeId]);
|
|
115
108
|
const getCheckout = useCallback(async (checkoutToken) => {
|
|
116
109
|
setIsLoading(true);
|
|
117
110
|
setError(null);
|
|
@@ -425,7 +418,7 @@ export function useCheckout(options = {}) {
|
|
|
425
418
|
method: 'POST',
|
|
426
419
|
body: {
|
|
427
420
|
lineItems,
|
|
428
|
-
storeId
|
|
421
|
+
storeId,
|
|
429
422
|
currency: currency.code,
|
|
430
423
|
promotionIds: promotionIds ?? [],
|
|
431
424
|
},
|
|
@@ -436,41 +429,31 @@ export function useCheckout(options = {}) {
|
|
|
436
429
|
const error = err instanceof Error ? err : new Error('Failed to preview checkout session');
|
|
437
430
|
throw error;
|
|
438
431
|
}
|
|
439
|
-
}, [apiService,
|
|
432
|
+
}, [apiService, storeId, currency.code]);
|
|
440
433
|
const clear = useCallback(() => {
|
|
441
434
|
setCheckout(null);
|
|
442
435
|
setError(null);
|
|
443
436
|
setIsInitialized(false);
|
|
444
437
|
currentCheckoutTokenRef.current = null;
|
|
445
438
|
hasAutoLoadedRef.current = false;
|
|
446
|
-
if (refreshTimeoutRef.current) {
|
|
447
|
-
clearTimeout(refreshTimeoutRef.current);
|
|
448
|
-
}
|
|
449
439
|
}, []);
|
|
450
|
-
// Auto-load existing checkout session from provided token
|
|
440
|
+
// Auto-load existing checkout session from provided token
|
|
451
441
|
useEffect(() => {
|
|
452
|
-
if (!autoLoadFromToken || hasAutoLoadedRef.current || isInitialized) {
|
|
442
|
+
if (!autoLoadFromToken || hasAutoLoadedRef.current || isInitialized || !providedToken) {
|
|
453
443
|
return;
|
|
454
444
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
currentUrl: true,
|
|
459
|
-
fallbackToken,
|
|
460
|
-
});
|
|
461
|
-
if (token && !isLoading) {
|
|
462
|
-
console.debug('[Checkout] Auto-loading from token:', {
|
|
463
|
-
source: providedToken ? 'provided' : 'url/fallback',
|
|
464
|
-
tokenPreview: token.substring(0, 8) + '...',
|
|
445
|
+
if (!isLoading) {
|
|
446
|
+
console.debug('[Checkout] Auto-loading from provided token:', {
|
|
447
|
+
tokenPreview: providedToken.substring(0, 8) + '...',
|
|
465
448
|
});
|
|
466
449
|
hasAutoLoadedRef.current = true;
|
|
467
|
-
getCheckout(
|
|
450
|
+
getCheckout(providedToken).catch((err) => {
|
|
468
451
|
console.error('Auto-load failed:', err);
|
|
469
452
|
setError(err instanceof Error ? err : new Error('Auto-load failed'));
|
|
470
453
|
hasAutoLoadedRef.current = false; // Reset to allow retry
|
|
471
454
|
});
|
|
472
455
|
}
|
|
473
|
-
}, [autoLoadFromToken, providedToken,
|
|
456
|
+
}, [autoLoadFromToken, providedToken, isInitialized, isLoading, getCheckout]);
|
|
474
457
|
return {
|
|
475
458
|
checkout,
|
|
476
459
|
isLoading,
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
3
|
-
// @ts-ignore - iso3166-2-db doesn't have TypeScript definitions
|
|
4
|
-
import { getDataSet, reduce } from 'iso3166-2-db';
|
|
1
|
+
import { useMemo, useState, useEffect } from 'react';
|
|
5
2
|
/**
|
|
6
3
|
* React hook for accessing ISO3166 countries and regions data
|
|
7
4
|
* @param language - Language code (en, fr, de, es, etc.)
|
|
@@ -9,8 +6,43 @@ import { getDataSet, reduce } from 'iso3166-2-db';
|
|
|
9
6
|
* @returns Object with countries data and helper functions
|
|
10
7
|
*/
|
|
11
8
|
export function useISOData(language = 'en', disputeSetting = 'UN') {
|
|
9
|
+
const [isoModule, setIsoModule] = useState(null);
|
|
10
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
let isMounted = true;
|
|
13
|
+
const loadModule = async () => {
|
|
14
|
+
try {
|
|
15
|
+
// Try dynamic import first (ES modules)
|
|
16
|
+
const isoModule = await import('iso3166-2-db');
|
|
17
|
+
if (isMounted) {
|
|
18
|
+
setIsoModule(isoModule);
|
|
19
|
+
setIsLoading(false);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch (importError) {
|
|
23
|
+
console.error(`Failed to load ISO data module:`, importError);
|
|
24
|
+
if (isMounted) {
|
|
25
|
+
setIsoModule(null);
|
|
26
|
+
setIsLoading(false);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
void loadModule();
|
|
31
|
+
return () => {
|
|
32
|
+
isMounted = false;
|
|
33
|
+
};
|
|
34
|
+
}, []);
|
|
12
35
|
const data = useMemo(() => {
|
|
36
|
+
if (isLoading || !isoModule) {
|
|
37
|
+
return {
|
|
38
|
+
countries: {},
|
|
39
|
+
getRegions: () => [],
|
|
40
|
+
findRegion: () => null,
|
|
41
|
+
mapGoogleToISO: () => null,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
13
44
|
try {
|
|
45
|
+
const { getDataSet, reduce } = isoModule;
|
|
14
46
|
// Get the dataset using the iso3166-2-db library
|
|
15
47
|
const worldDatabase = reduce(getDataSet(), language);
|
|
16
48
|
// Transform to our expected format
|
|
@@ -85,7 +117,7 @@ export function useISOData(language = 'en', disputeSetting = 'UN') {
|
|
|
85
117
|
mapGoogleToISO: () => null,
|
|
86
118
|
};
|
|
87
119
|
}
|
|
88
|
-
}, [language, disputeSetting]);
|
|
120
|
+
}, [isoModule, isLoading, language, disputeSetting]);
|
|
89
121
|
return data;
|
|
90
122
|
}
|
|
91
123
|
/**
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { useCallback, useState } from 'react';
|
|
2
2
|
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
3
|
+
import { usePluginConfig } from './usePluginConfig';
|
|
3
4
|
import { setClientToken } from '../utils/tokenStorage';
|
|
4
5
|
export function useLogin() {
|
|
5
6
|
const [isLoading, setIsLoading] = useState(false);
|
|
6
7
|
const [error, setError] = useState(null);
|
|
7
8
|
const { apiService } = useTagadaContext();
|
|
9
|
+
const { storeId } = usePluginConfig();
|
|
8
10
|
const requestCode = useCallback(async (email) => {
|
|
9
11
|
setIsLoading(true);
|
|
10
12
|
try {
|
|
11
|
-
const storeId = apiService.getStoredStoreId();
|
|
12
13
|
if (!storeId) {
|
|
13
14
|
throw new Error('Store ID not found. Make sure the TagadaProvider is properly configured.');
|
|
14
15
|
}
|
|
@@ -33,11 +34,10 @@ export function useLogin() {
|
|
|
33
34
|
finally {
|
|
34
35
|
setIsLoading(false);
|
|
35
36
|
}
|
|
36
|
-
}, [apiService]);
|
|
37
|
+
}, [apiService, storeId]);
|
|
37
38
|
const verifyCode = useCallback(async (email, code) => {
|
|
38
39
|
setIsLoading(true);
|
|
39
40
|
try {
|
|
40
|
-
const storeId = apiService.getStoredStoreId();
|
|
41
41
|
if (!storeId) {
|
|
42
42
|
throw new Error('Store ID not found. Make sure the TagadaProvider is properly configured.');
|
|
43
43
|
}
|
|
@@ -65,7 +65,7 @@ export function useLogin() {
|
|
|
65
65
|
finally {
|
|
66
66
|
setIsLoading(false);
|
|
67
67
|
}
|
|
68
|
-
}, [apiService]);
|
|
68
|
+
}, [apiService, storeId]);
|
|
69
69
|
return {
|
|
70
70
|
error,
|
|
71
71
|
isLoading,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
3
|
+
import { usePluginConfig } from './usePluginConfig';
|
|
3
4
|
export function useOffers(options) {
|
|
4
5
|
const { apiService, environment } = useTagadaContext();
|
|
6
|
+
const { storeId } = usePluginConfig();
|
|
5
7
|
const [offers, setOffers] = useState([]);
|
|
6
8
|
const [isLoading, setIsLoading] = useState(false);
|
|
7
9
|
const [error, setError] = useState(null);
|
|
@@ -12,7 +14,10 @@ export function useOffers(options) {
|
|
|
12
14
|
setIsLoading(true);
|
|
13
15
|
setError(null);
|
|
14
16
|
try {
|
|
15
|
-
|
|
17
|
+
if (!storeId) {
|
|
18
|
+
throw new Error('Store ID not found. Make sure the TagadaProvider is properly configured.');
|
|
19
|
+
}
|
|
20
|
+
const responseData = await apiService.fetch(`/api/v1/stores/${storeId}/offers`, {
|
|
16
21
|
method: 'GET',
|
|
17
22
|
headers: {
|
|
18
23
|
'Content-Type': 'application/json',
|
|
@@ -31,7 +36,7 @@ export function useOffers(options) {
|
|
|
31
36
|
finally {
|
|
32
37
|
setIsLoading(false);
|
|
33
38
|
}
|
|
34
|
-
}, [apiService, environment.apiConfig.baseUrl, offerIds, enabled]);
|
|
39
|
+
}, [apiService, storeId, environment.apiConfig.baseUrl, offerIds, enabled]);
|
|
35
40
|
const initCheckoutSession = useCallback(async (offerId, orderId) => {
|
|
36
41
|
const response = await apiService.fetch(`/api/v1/checkout/offer/init`, {
|
|
37
42
|
method: 'POST',
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { useState, useCallback, useEffect, useMemo } from 'react';
|
|
2
2
|
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
3
|
+
import { usePluginConfig } from './usePluginConfig';
|
|
3
4
|
export function useProducts(options = {}) {
|
|
4
5
|
const { apiService } = useTagadaContext();
|
|
6
|
+
const { storeId } = usePluginConfig();
|
|
5
7
|
const [products, setProducts] = useState([]);
|
|
6
8
|
const [isLoading, setIsLoading] = useState(false);
|
|
7
9
|
const [error, setError] = useState(null);
|
|
@@ -27,7 +29,6 @@ export function useProducts(options = {}) {
|
|
|
27
29
|
setIsLoading(true);
|
|
28
30
|
setError(null);
|
|
29
31
|
try {
|
|
30
|
-
const storeId = apiService.getStoredStoreId();
|
|
31
32
|
if (!storeId) {
|
|
32
33
|
throw new Error('Store ID not found. Make sure the TagadaProvider is properly configured.');
|
|
33
34
|
}
|
|
@@ -67,7 +68,7 @@ export function useProducts(options = {}) {
|
|
|
67
68
|
finally {
|
|
68
69
|
setIsLoading(false);
|
|
69
70
|
}
|
|
70
|
-
}, [apiService, productIds, enabled, includeVariants, includePrices]);
|
|
71
|
+
}, [apiService, storeId, productIds, enabled, includeVariants, includePrices]);
|
|
71
72
|
const getProduct = useCallback((productId) => {
|
|
72
73
|
return products.find((product) => product.id === productId);
|
|
73
74
|
}, [products]);
|
package/dist/react/index.d.ts
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* React SDK exports
|
|
3
3
|
*/
|
|
4
4
|
export { TagadaProvider } from './providers/TagadaProvider';
|
|
5
|
-
export { useAddress } from './hooks/useAddress';
|
|
6
5
|
export { useAuth } from './hooks/useAuth';
|
|
7
6
|
export { useCheckout } from './hooks/useCheckout';
|
|
8
7
|
export { useCurrency } from './hooks/useCurrency';
|
|
9
8
|
export { useCustomer } from './hooks/useCustomer';
|
|
10
9
|
export { useEnvironment } from './hooks/useEnvironment';
|
|
10
|
+
export { useGoogleAutocomplete } from './hooks/useGoogleAutocomplete';
|
|
11
11
|
export { useLocale } from './hooks/useLocale';
|
|
12
12
|
export { useLogin } from './hooks/useLogin';
|
|
13
13
|
export { useOffers } from './hooks/useOffers';
|
|
@@ -18,10 +18,9 @@ export { useSession } from './hooks/useSession';
|
|
|
18
18
|
export { useTagadaContext } from './providers/TagadaProvider';
|
|
19
19
|
export { usePluginConfig, useBasePath, getPluginConfig, clearPluginConfigCache, debugPluginConfig } from './hooks/usePluginConfig';
|
|
20
20
|
export type { PluginConfig } from './hooks/usePluginConfig';
|
|
21
|
-
export { useGoogleAutocomplete, useGoogleMapsLoaded } from './hooks/useGoogleAutocomplete';
|
|
22
|
-
export type { GooglePrediction, GoogleAddressComponent, GooglePlaceDetails, ExtractedAddress, UseGoogleAutocompleteOptions, UseGoogleAutocompleteResult } from './hooks/useGoogleAutocomplete';
|
|
23
21
|
export { useISOData, useCountryOptions, useRegionOptions, getAvailableLanguages } from './hooks/useISOData';
|
|
24
22
|
export type { ISOCountry, ISORegion, UseISODataResult } from './hooks/useISOData';
|
|
23
|
+
export type { GooglePrediction, GoogleAddressComponent, GooglePlaceDetails, ExtractedAddress, UseGoogleAutocompleteOptions, UseGoogleAutocompleteResult } from './hooks/useGoogleAutocomplete';
|
|
25
24
|
export { useOrder } from './hooks/useOrder';
|
|
26
25
|
export type { UseOrderOptions, UseOrderResult } from './hooks/useOrder';
|
|
27
26
|
export { usePayment } from './hooks/usePayment';
|
|
@@ -32,7 +31,6 @@ export type { AuthState, Currency, Customer, Environment, EnvironmentConfig, Loc
|
|
|
32
31
|
export type { CheckoutSessionPreview, CheckoutData, CheckoutInitParams, CheckoutLineItem, CheckoutSession, Promotion, UseCheckoutOptions, UseCheckoutResult, } from './hooks/useCheckout';
|
|
33
32
|
export type { OrderBumpPreview, UseOrderBumpOptions, UseOrderBumpResult } from './hooks/useOrderBump';
|
|
34
33
|
export type { PostPurchaseOffer, PostPurchaseOfferItem, PostPurchaseOfferLineItem, PostPurchaseOfferSummary, UsePostPurchasesOptions, UsePostPurchasesResult, } from './hooks/usePostPurchases';
|
|
35
|
-
export type { AddressData, AddressField, Country, State, UseAddressOptions, UseAddressResult, } from './hooks/useAddress';
|
|
36
34
|
export type { Payment, PaymentPollingHook, PollingOptions } from './hooks/usePaymentPolling';
|
|
37
35
|
export type { PaymentInstrument, ThreedsChallenge, ThreedsHook, ThreedsOptions, ThreedsProvider, ThreedsSession, } from './hooks/useThreeds';
|
|
38
36
|
export type { ApplePayToken, CardPaymentMethod, PaymentHook, PaymentInstrumentResponse, PaymentOptions, PaymentResponse, } from './hooks/usePayment';
|
package/dist/react/index.js
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
// Provider exports
|
|
6
6
|
export { TagadaProvider } from './providers/TagadaProvider';
|
|
7
7
|
// Hook exports
|
|
8
|
-
export { useAddress } from './hooks/useAddress';
|
|
9
8
|
export { useAuth } from './hooks/useAuth';
|
|
10
9
|
export { useCheckout } from './hooks/useCheckout';
|
|
11
10
|
export { useCurrency } from './hooks/useCurrency';
|
|
12
11
|
export { useCustomer } from './hooks/useCustomer';
|
|
13
12
|
export { useEnvironment } from './hooks/useEnvironment';
|
|
13
|
+
export { useGoogleAutocomplete } from './hooks/useGoogleAutocomplete';
|
|
14
14
|
export { useLocale } from './hooks/useLocale';
|
|
15
15
|
export { useLogin } from './hooks/useLogin';
|
|
16
16
|
export { useOffers } from './hooks/useOffers';
|
|
@@ -21,8 +21,6 @@ export { useSession } from './hooks/useSession';
|
|
|
21
21
|
export { useTagadaContext } from './providers/TagadaProvider';
|
|
22
22
|
// Plugin configuration hooks
|
|
23
23
|
export { usePluginConfig, useBasePath, getPluginConfig, clearPluginConfigCache, debugPluginConfig } from './hooks/usePluginConfig';
|
|
24
|
-
// Google Places hooks
|
|
25
|
-
export { useGoogleAutocomplete, useGoogleMapsLoaded } from './hooks/useGoogleAutocomplete';
|
|
26
24
|
// ISO Data hooks
|
|
27
25
|
export { useISOData, useCountryOptions, useRegionOptions, getAvailableLanguages } from './hooks/useISOData';
|
|
28
26
|
// Order hook exports
|
|
@@ -51,11 +51,9 @@ interface TagadaProviderProps {
|
|
|
51
51
|
environment?: Environment;
|
|
52
52
|
customApiConfig?: Partial<EnvironmentConfig>;
|
|
53
53
|
debugMode?: boolean;
|
|
54
|
-
storeId?: string;
|
|
55
|
-
accountId?: string;
|
|
56
54
|
localConfig?: string;
|
|
57
55
|
}
|
|
58
56
|
export declare function TagadaProvider({ children, environment, customApiConfig, debugMode, // Remove default, will be set based on environment
|
|
59
|
-
|
|
57
|
+
localConfig, }: TagadaProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
60
58
|
export declare function useTagadaContext(): TagadaContextValue;
|
|
61
59
|
export {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx,
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
/**
|
|
4
4
|
* TagadaProvider - Main provider component for the Tagada Pay React SDK
|
|
5
5
|
*/
|
|
6
|
-
import { createContext, useContext, useState, useEffect, useRef, useCallback } from 'react';
|
|
6
|
+
import { createContext, useContext, useState, useEffect, useRef, useCallback, useMemo, } from 'react';
|
|
7
7
|
import { getEnvironmentConfig, detectEnvironment } from '../config/environment';
|
|
8
8
|
import { ApiService } from '../services/apiService';
|
|
9
9
|
import { setClientToken, getClientToken, clearClientToken } from '../utils/tokenStorage';
|
|
@@ -12,39 +12,58 @@ import { collectDeviceInfo, getBrowserLocale, getUrlParams } from '../utils/devi
|
|
|
12
12
|
import DebugDrawer from '../components/DebugDrawer';
|
|
13
13
|
import { loadPluginConfig } from '../hooks/usePluginConfig';
|
|
14
14
|
import { formatMoney, getCurrencyInfo, moneyStringOrNumberToMinorUnits, minorUnitsToMajorUnits, formatMoneyWithoutSymbol, convertCurrency, formatSimpleMoney, } from '../utils/money';
|
|
15
|
-
//
|
|
16
|
-
const InitializationLoader = () => (
|
|
15
|
+
// Professional, subtle loading component for initialization
|
|
16
|
+
const InitializationLoader = () => (_jsxs("div", { style: {
|
|
17
17
|
position: 'fixed',
|
|
18
|
-
top:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
top: '24px',
|
|
19
|
+
right: '24px',
|
|
20
|
+
display: 'flex',
|
|
21
|
+
alignItems: 'center',
|
|
22
|
+
gap: '8px',
|
|
23
|
+
padding: '8px 12px',
|
|
24
|
+
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
|
25
|
+
border: '1px solid rgba(229, 231, 235, 0.8)',
|
|
26
|
+
borderRadius: '8px',
|
|
27
|
+
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.04)',
|
|
28
|
+
backdropFilter: 'blur(8px)',
|
|
29
|
+
zIndex: 999999,
|
|
30
|
+
fontSize: '13px',
|
|
31
|
+
color: '#6b7280',
|
|
32
|
+
fontFamily: 'system-ui, -apple-system, sans-serif',
|
|
33
|
+
fontWeight: '500',
|
|
34
|
+
}, children: [_jsx("div", { style: {
|
|
35
|
+
width: '12px',
|
|
36
|
+
height: '12px',
|
|
37
|
+
border: '1.5px solid #e5e7eb',
|
|
38
|
+
borderTop: '1.5px solid #9ca3af',
|
|
39
|
+
borderRadius: '50%',
|
|
40
|
+
animation: 'tagada-spin 1s linear infinite',
|
|
41
|
+
} }), _jsx("span", { children: "Loading..." }), _jsx("style", { children: `
|
|
42
|
+
@keyframes tagada-spin {
|
|
43
|
+
0% { transform: rotate(0deg); }
|
|
44
|
+
100% { transform: rotate(360deg); }
|
|
30
45
|
}
|
|
31
|
-
` }) }));
|
|
46
|
+
` })] }));
|
|
32
47
|
const TagadaContext = createContext(null);
|
|
33
48
|
export function TagadaProvider({ children, environment, customApiConfig, debugMode, // Remove default, will be set based on environment
|
|
34
|
-
|
|
49
|
+
localConfig, }) {
|
|
35
50
|
// LOCAL DEV ONLY: Use localConfig override if in local development, otherwise use default
|
|
36
51
|
const isLocalDev = typeof window !== 'undefined' &&
|
|
37
52
|
(window.location.hostname === 'localhost' ||
|
|
38
53
|
window.location.hostname.includes('.localhost') ||
|
|
39
54
|
window.location.hostname.includes('127.0.0.1'));
|
|
40
55
|
const configVariant = isLocalDev ? localConfig || 'default' : 'default';
|
|
41
|
-
// Debug logging
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
// Debug logging (only log once during initial render)
|
|
57
|
+
const hasLoggedRef = useRef(false);
|
|
58
|
+
if (!hasLoggedRef.current) {
|
|
59
|
+
console.log('๐ TagadaProvider Config Debug:', {
|
|
60
|
+
hostname: typeof window !== 'undefined' ? window.location.hostname : 'SSR',
|
|
61
|
+
isLocalDev,
|
|
62
|
+
localConfig,
|
|
63
|
+
configVariant,
|
|
64
|
+
});
|
|
65
|
+
hasLoggedRef.current = true;
|
|
66
|
+
}
|
|
48
67
|
// Load plugin configuration directly (not using hook to avoid circular dependency)
|
|
49
68
|
const [pluginConfig, setPluginConfig] = useState({ basePath: '/', config: {} });
|
|
50
69
|
const [configLoading, setConfigLoading] = useState(true);
|
|
@@ -53,10 +72,20 @@ storeId: propStoreId, accountId: propAccountId, localConfig, }) {
|
|
|
53
72
|
const loadConfig = async () => {
|
|
54
73
|
try {
|
|
55
74
|
const config = await loadPluginConfig(configVariant);
|
|
75
|
+
// Ensure we have required store ID before proceeding
|
|
76
|
+
if (!config.storeId) {
|
|
77
|
+
console.warn('โ ๏ธ No store ID found in plugin config. This may cause hooks to fail.');
|
|
78
|
+
}
|
|
56
79
|
setPluginConfig(config);
|
|
80
|
+
console.log('โ
Plugin config loaded:', {
|
|
81
|
+
storeId: config.storeId,
|
|
82
|
+
accountId: config.accountId,
|
|
83
|
+
basePath: config.basePath,
|
|
84
|
+
hasConfig: !!config.config,
|
|
85
|
+
});
|
|
57
86
|
}
|
|
58
87
|
catch (error) {
|
|
59
|
-
console.
|
|
88
|
+
console.error('โ Failed to load plugin config in TagadaProvider:', error);
|
|
60
89
|
setPluginConfig({ basePath: '/', config: {} });
|
|
61
90
|
}
|
|
62
91
|
finally {
|
|
@@ -65,12 +94,9 @@ storeId: propStoreId, accountId: propAccountId, localConfig, }) {
|
|
|
65
94
|
};
|
|
66
95
|
void loadConfig();
|
|
67
96
|
}, [configVariant]);
|
|
68
|
-
// Extract store/account IDs from plugin config
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
// Use props if provided, otherwise use config from hook
|
|
72
|
-
const storeId = propStoreId || configStoreId;
|
|
73
|
-
const accountId = propAccountId || configAccountId;
|
|
97
|
+
// Extract store/account IDs from plugin config (only source now)
|
|
98
|
+
const storeId = pluginConfig.storeId;
|
|
99
|
+
const accountId = pluginConfig.accountId;
|
|
74
100
|
const [isLoading, setIsLoading] = useState(true);
|
|
75
101
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
76
102
|
const [token, setToken] = useState(null);
|
|
@@ -117,10 +143,9 @@ storeId: propStoreId, accountId: propAccountId, localConfig, }) {
|
|
|
117
143
|
clearClientToken();
|
|
118
144
|
},
|
|
119
145
|
});
|
|
120
|
-
// Store
|
|
146
|
+
// Store ID is managed by plugin configuration system
|
|
121
147
|
if (storeId) {
|
|
122
|
-
console.log(`[SDK] Using
|
|
123
|
-
service.storeStoreId(storeId);
|
|
148
|
+
console.log(`[SDK] Using store ID from config: ${storeId}`);
|
|
124
149
|
}
|
|
125
150
|
return service;
|
|
126
151
|
});
|
|
@@ -319,8 +344,8 @@ storeId: propStoreId, accountId: propAccountId, localConfig, }) {
|
|
|
319
344
|
if (isInitializing.current) {
|
|
320
345
|
return;
|
|
321
346
|
}
|
|
322
|
-
// Wait for plugin config to load before initializing
|
|
323
|
-
if (configLoading) {
|
|
347
|
+
// Wait for plugin config to load AND ensure we have a store ID before initializing
|
|
348
|
+
if (configLoading || !storeId) {
|
|
324
349
|
return;
|
|
325
350
|
}
|
|
326
351
|
isInitializing.current = true;
|
|
@@ -388,7 +413,7 @@ storeId: propStoreId, accountId: propAccountId, localConfig, }) {
|
|
|
388
413
|
// Refresh coordinator for bidirectional hook communication
|
|
389
414
|
const checkoutRefreshRef = useRef(null);
|
|
390
415
|
const orderBumpRefreshRef = useRef(null);
|
|
391
|
-
const refreshCoordinator = {
|
|
416
|
+
const refreshCoordinator = useMemo(() => ({
|
|
392
417
|
registerCheckoutRefresh: (refreshFn) => {
|
|
393
418
|
checkoutRefreshRef.current = refreshFn;
|
|
394
419
|
console.log('๐ [RefreshCoordinator] Checkout refresh function registered');
|
|
@@ -429,8 +454,9 @@ storeId: propStoreId, accountId: propAccountId, localConfig, }) {
|
|
|
429
454
|
orderBumpRefreshRef.current = null;
|
|
430
455
|
console.log('๐งน [RefreshCoordinator] Order bump refresh function unregistered');
|
|
431
456
|
},
|
|
432
|
-
};
|
|
433
|
-
|
|
457
|
+
}), []);
|
|
458
|
+
// Memoize the context value to prevent unnecessary re-renders
|
|
459
|
+
const contextValue = useMemo(() => ({
|
|
434
460
|
auth,
|
|
435
461
|
session,
|
|
436
462
|
customer,
|
|
@@ -464,8 +490,28 @@ storeId: propStoreId, accountId: propAccountId, localConfig, }) {
|
|
|
464
490
|
convertCurrency,
|
|
465
491
|
formatSimpleMoney,
|
|
466
492
|
},
|
|
467
|
-
}
|
|
468
|
-
|
|
493
|
+
}), [
|
|
494
|
+
auth,
|
|
495
|
+
session,
|
|
496
|
+
customer,
|
|
497
|
+
locale,
|
|
498
|
+
currency,
|
|
499
|
+
store,
|
|
500
|
+
environmentConfig,
|
|
501
|
+
apiService,
|
|
502
|
+
isLoading,
|
|
503
|
+
isInitialized,
|
|
504
|
+
finalDebugMode,
|
|
505
|
+
pluginConfig,
|
|
506
|
+
configLoading,
|
|
507
|
+
debugCheckout,
|
|
508
|
+
refreshCoordinator,
|
|
509
|
+
]);
|
|
510
|
+
// Determine if we should show loading
|
|
511
|
+
// Show loading if: config is loading OR (config loaded but no store ID and session not initialized)
|
|
512
|
+
const shouldShowLoading = configLoading || (!storeId && !isInitialized);
|
|
513
|
+
const canRenderChildren = !configLoading && storeId && isInitialized;
|
|
514
|
+
return (_jsxs(TagadaContext.Provider, { value: contextValue, children: [shouldShowLoading && _jsx(InitializationLoader, {}), finalDebugMode && canRenderChildren && (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => setIsDebugDrawerOpen(true), style: {
|
|
469
515
|
position: 'fixed',
|
|
470
516
|
bottom: '16px',
|
|
471
517
|
right: '16px',
|
|
@@ -486,7 +532,7 @@ storeId: propStoreId, accountId: propAccountId, localConfig, }) {
|
|
|
486
532
|
}, onMouseLeave: (e) => {
|
|
487
533
|
e.currentTarget.style.backgroundColor = '#f97316';
|
|
488
534
|
e.currentTarget.style.transform = 'scale(1)';
|
|
489
|
-
}, title: "Open TagadaPay SDK Debug Panel", children: "\uD83D\uDC1B" }), _jsx(DebugDrawer, { isOpen: isDebugDrawerOpen, onClose: () => setIsDebugDrawerOpen(false) })] })),
|
|
535
|
+
}, title: "Open TagadaPay SDK Debug Panel", children: "\uD83D\uDC1B" }), _jsx(DebugDrawer, { isOpen: isDebugDrawerOpen, onClose: () => setIsDebugDrawerOpen(false) })] })), canRenderChildren && children] }));
|
|
490
536
|
}
|
|
491
537
|
export function useTagadaContext() {
|
|
492
538
|
const context = useContext(TagadaContext);
|
|
@@ -51,11 +51,13 @@ export declare class ApiService {
|
|
|
51
51
|
updateToken(token: string | null): void;
|
|
52
52
|
updateConfig(config: EnvironmentConfig): void;
|
|
53
53
|
/**
|
|
54
|
-
* Store the store ID in localStorage
|
|
54
|
+
* Store the store ID in localStorage (deprecated - use usePluginConfig instead)
|
|
55
|
+
* @deprecated Use usePluginConfig hook to get storeId
|
|
55
56
|
*/
|
|
56
57
|
storeStoreId(storeId: string): void;
|
|
57
58
|
/**
|
|
58
|
-
* Get the store ID from localStorage
|
|
59
|
+
* Get the store ID from localStorage (deprecated - use usePluginConfig instead)
|
|
60
|
+
* @deprecated Use usePluginConfig hook to get storeId
|
|
59
61
|
*/
|
|
60
62
|
getStoredStoreId(): string | null;
|
|
61
63
|
/**
|
|
@@ -14,9 +14,11 @@ export class ApiService {
|
|
|
14
14
|
this.config = config;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
* Store the store ID in localStorage
|
|
17
|
+
* Store the store ID in localStorage (deprecated - use usePluginConfig instead)
|
|
18
|
+
* @deprecated Use usePluginConfig hook to get storeId
|
|
18
19
|
*/
|
|
19
20
|
storeStoreId(storeId) {
|
|
21
|
+
console.warn('[SDK] storeStoreId is deprecated. Use usePluginConfig hook to get storeId.');
|
|
20
22
|
try {
|
|
21
23
|
if (typeof window !== 'undefined' && window.localStorage) {
|
|
22
24
|
window.localStorage.setItem('tagada_store_id', storeId);
|
|
@@ -27,9 +29,11 @@ export class ApiService {
|
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
/**
|
|
30
|
-
* Get the store ID from localStorage
|
|
32
|
+
* Get the store ID from localStorage (deprecated - use usePluginConfig instead)
|
|
33
|
+
* @deprecated Use usePluginConfig hook to get storeId
|
|
31
34
|
*/
|
|
32
35
|
getStoredStoreId() {
|
|
36
|
+
console.warn('[SDK] getStoredStoreId is deprecated. Use usePluginConfig hook to get storeId.');
|
|
33
37
|
try {
|
|
34
38
|
if (typeof window !== 'undefined' && window.localStorage) {
|
|
35
39
|
return window.localStorage.getItem('tagada_store_id');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tagadapay/plugin-sdk",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.3",
|
|
4
4
|
"description": "Modern React SDK for building Tagada Pay plugins",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -51,7 +51,6 @@
|
|
|
51
51
|
"@basis-theory/web-threeds": "^1.0.1",
|
|
52
52
|
"axios": "^1.6.0",
|
|
53
53
|
"iso3166-2-db": "^2.3.11",
|
|
54
|
-
"react-google-autocomplete": "^2.7.3",
|
|
55
54
|
"react-intl": "^7.1.11"
|
|
56
55
|
},
|
|
57
56
|
"devDependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const AddressFormExample: () => import("react/jsx-runtime").JSX.Element;
|