@tagadapay/plugin-sdk 2.7.21 → 2.7.24
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.
|
@@ -6,12 +6,41 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
|
6
6
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
7
7
|
import { PostPurchasesResource } from '../../core/resources/postPurchases';
|
|
8
8
|
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
9
|
-
import { getGlobalApiClient } from './useApiQuery';
|
|
9
|
+
import { getGlobalApiClient, getGlobalApiClientOrNull } from './useApiQuery';
|
|
10
10
|
export function usePostPurchasesQuery(options) {
|
|
11
11
|
console.log('usePostPurchasesQuery');
|
|
12
12
|
const { orderId, enabled = true, autoInitializeCheckout = false } = options;
|
|
13
13
|
const queryClient = useQueryClient();
|
|
14
|
-
const { session } = useTagadaContext();
|
|
14
|
+
const { session, isSessionInitialized, apiService } = useTagadaContext();
|
|
15
|
+
// Track if token is available on API service
|
|
16
|
+
const [hasToken, setHasToken] = useState(() => apiService.getCurrentToken() !== null);
|
|
17
|
+
// Update token availability when session is initialized
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (isSessionInitialized) {
|
|
20
|
+
const checkToken = () => {
|
|
21
|
+
const token = apiService.getCurrentToken();
|
|
22
|
+
const tokenAvailable = token !== null;
|
|
23
|
+
setHasToken(tokenAvailable);
|
|
24
|
+
// Also ensure API client has the token
|
|
25
|
+
const apiClient = getGlobalApiClientOrNull();
|
|
26
|
+
if (apiClient && token) {
|
|
27
|
+
apiClient.updateToken(token);
|
|
28
|
+
}
|
|
29
|
+
return tokenAvailable;
|
|
30
|
+
};
|
|
31
|
+
// Check immediately
|
|
32
|
+
if (checkToken()) {
|
|
33
|
+
return; // Token is available, no need to poll
|
|
34
|
+
}
|
|
35
|
+
// Poll for token if not immediately available (handles async token setting)
|
|
36
|
+
const interval = setInterval(() => {
|
|
37
|
+
if (checkToken()) {
|
|
38
|
+
clearInterval(interval);
|
|
39
|
+
}
|
|
40
|
+
}, 100); // Check every 100ms
|
|
41
|
+
return () => clearInterval(interval);
|
|
42
|
+
}
|
|
43
|
+
}, [isSessionInitialized, apiService]);
|
|
15
44
|
// State for checkout sessions per offer
|
|
16
45
|
const [checkoutSessions, setCheckoutSessions] = useState({});
|
|
17
46
|
// Ref to track checkout sessions for synchronous access
|
|
@@ -138,14 +167,33 @@ export function usePostPurchasesQuery(options) {
|
|
|
138
167
|
// Main post-purchase offers query
|
|
139
168
|
const { data: offers = [], isLoading, error, refetch, } = useQuery({
|
|
140
169
|
queryKey: ['post-purchase-offers', orderId],
|
|
141
|
-
queryFn: () =>
|
|
142
|
-
|
|
170
|
+
queryFn: async () => {
|
|
171
|
+
// Double-check token is available before making the request
|
|
172
|
+
const token = apiService.getCurrentToken();
|
|
173
|
+
if (!token) {
|
|
174
|
+
throw new Error('No authentication token available. Please wait for session initialization.');
|
|
175
|
+
}
|
|
176
|
+
// Ensure API client has the token
|
|
177
|
+
const apiClient = getGlobalApiClientOrNull();
|
|
178
|
+
if (apiClient && token) {
|
|
179
|
+
apiClient.updateToken(token);
|
|
180
|
+
}
|
|
181
|
+
return postPurchasesResource.getPostPurchaseOffers(orderId);
|
|
182
|
+
},
|
|
183
|
+
enabled: enabled && !!orderId && isSessionInitialized && hasToken, // Wait for CMS token/session to be ready AND token to be set on API client
|
|
143
184
|
staleTime: 30000, // 30 seconds
|
|
144
185
|
refetchOnWindowFocus: false,
|
|
186
|
+
retry: (failureCount, error) => {
|
|
187
|
+
// Retry if token is not available yet (might be a timing issue)
|
|
188
|
+
if (error instanceof Error && error.message.includes('No authentication token')) {
|
|
189
|
+
return failureCount < 3; // Retry up to 3 times
|
|
190
|
+
}
|
|
191
|
+
return false; // Don't retry other errors
|
|
192
|
+
},
|
|
145
193
|
});
|
|
146
194
|
// Auto-initialize checkout sessions if enabled
|
|
147
195
|
useEffect(() => {
|
|
148
|
-
if (autoInitializeCheckout && offers.length > 0 && session?.customerId) {
|
|
196
|
+
if (autoInitializeCheckout && offers.length > 0 && session?.customerId && isSessionInitialized) {
|
|
149
197
|
// Initialize checkout sessions for all offers
|
|
150
198
|
offers.forEach((offer) => {
|
|
151
199
|
// The initializeOfferCheckout function will check if already initialized or initializing
|
|
@@ -155,7 +203,7 @@ export function usePostPurchasesQuery(options) {
|
|
|
155
203
|
});
|
|
156
204
|
});
|
|
157
205
|
}
|
|
158
|
-
}, [autoInitializeCheckout, offers, session?.customerId, initializeOfferCheckout]);
|
|
206
|
+
}, [autoInitializeCheckout, offers, session?.customerId, isSessionInitialized, initializeOfferCheckout]);
|
|
159
207
|
// Accept offer mutation
|
|
160
208
|
const acceptMutation = useMutation({
|
|
161
209
|
mutationFn: ({ offerId, items }) => {
|
|
@@ -51,10 +51,13 @@ import React, { useCallback, useMemo } from 'react';
|
|
|
51
51
|
* ```
|
|
52
52
|
*/
|
|
53
53
|
export const useTranslation = (options = {}) => {
|
|
54
|
-
const { defaultLanguage
|
|
54
|
+
const { defaultLanguage } = options;
|
|
55
55
|
// Get the current language from query params, browser, or fallback to default
|
|
56
56
|
const locale = useMemo(() => {
|
|
57
57
|
// Check for language query parameter
|
|
58
|
+
if (defaultLanguage) {
|
|
59
|
+
return defaultLanguage;
|
|
60
|
+
}
|
|
58
61
|
if (typeof window !== 'undefined') {
|
|
59
62
|
const urlParams = new URLSearchParams(window.location.search);
|
|
60
63
|
const langFromQuery = urlParams.get('locale');
|
|
@@ -66,7 +69,7 @@ export const useTranslation = (options = {}) => {
|
|
|
66
69
|
const browserLang = navigator.language.split('-')[0]; // e.g., 'en-US' -> 'en'
|
|
67
70
|
return browserLang;
|
|
68
71
|
}
|
|
69
|
-
return
|
|
72
|
+
return 'en';
|
|
70
73
|
}, [defaultLanguage]);
|
|
71
74
|
const t = useCallback((text, fallback, params, languageCode) => {
|
|
72
75
|
// Helper function to interpolate params into the translated string
|
|
@@ -160,7 +163,7 @@ export const useTranslation = (options = {}) => {
|
|
|
160
163
|
else if (fallback) {
|
|
161
164
|
translatedText = fallback;
|
|
162
165
|
}
|
|
163
|
-
else if (text[defaultLanguage]) {
|
|
166
|
+
else if (defaultLanguage && text[defaultLanguage]) {
|
|
164
167
|
translatedText = text[defaultLanguage];
|
|
165
168
|
}
|
|
166
169
|
else {
|