@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: () => postPurchasesResource.getPostPurchaseOffers(orderId),
142
- enabled: enabled && !!orderId,
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 = 'en' } = options;
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 defaultLanguage;
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 {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tagadapay/plugin-sdk",
3
- "version": "2.7.21",
3
+ "version": "2.7.24",
4
4
  "description": "Modern React SDK for building Tagada Pay plugins",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",