@tagadapay/plugin-sdk 2.8.10 → 3.0.2
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/README.md +14 -14
- package/dist/index.js +1 -1
- package/dist/react/hooks/usePluginConfig.d.ts +1 -0
- package/dist/react/hooks/usePluginConfig.js +69 -18
- package/dist/react/providers/TagadaProvider.js +1 -4
- package/dist/v2/core/client.d.ts +18 -0
- package/dist/v2/core/client.js +45 -0
- package/dist/v2/core/config/environment.d.ts +8 -0
- package/dist/v2/core/config/environment.js +18 -0
- package/dist/v2/core/funnelClient.d.ts +84 -0
- package/dist/v2/core/funnelClient.js +252 -0
- package/dist/v2/core/index.d.ts +2 -0
- package/dist/v2/core/index.js +3 -0
- package/dist/v2/core/resources/apiClient.js +1 -1
- package/dist/v2/core/resources/funnel.d.ts +1 -0
- package/dist/v2/core/resources/offers.d.ts +182 -8
- package/dist/v2/core/resources/offers.js +25 -0
- package/dist/v2/core/resources/products.d.ts +5 -0
- package/dist/v2/core/resources/products.js +15 -1
- package/dist/v2/core/types.d.ts +1 -0
- package/dist/v2/core/utils/funnelQueryKeys.d.ts +23 -0
- package/dist/v2/core/utils/funnelQueryKeys.js +23 -0
- package/dist/v2/core/utils/index.d.ts +2 -0
- package/dist/v2/core/utils/index.js +2 -0
- package/dist/v2/core/utils/pluginConfig.js +44 -32
- package/dist/v2/core/utils/sessionStorage.d.ts +20 -0
- package/dist/v2/core/utils/sessionStorage.js +39 -0
- package/dist/v2/index.d.ts +4 -2
- package/dist/v2/index.js +1 -1
- package/dist/v2/react/components/DebugDrawer.js +99 -2
- package/dist/v2/react/hooks/__examples__/FunnelContextExample.d.ts +3 -0
- package/dist/v2/react/hooks/__examples__/FunnelContextExample.js +4 -3
- package/dist/v2/react/hooks/useClubOffers.d.ts +2 -2
- package/dist/v2/react/hooks/useFunnel.d.ts +27 -39
- package/dist/v2/react/hooks/useFunnel.js +22 -659
- package/dist/v2/react/hooks/useFunnelLegacy.d.ts +52 -0
- package/dist/v2/react/hooks/useFunnelLegacy.js +733 -0
- package/dist/v2/react/hooks/useOfferQuery.d.ts +109 -0
- package/dist/v2/react/hooks/useOfferQuery.js +483 -0
- package/dist/v2/react/hooks/useOffersQuery.d.ts +9 -75
- package/dist/v2/react/hooks/useProductsQuery.d.ts +1 -0
- package/dist/v2/react/hooks/useProductsQuery.js +10 -6
- package/dist/v2/react/index.d.ts +8 -4
- package/dist/v2/react/index.js +4 -2
- package/dist/v2/react/providers/TagadaProvider.d.ts +66 -5
- package/dist/v2/react/providers/TagadaProvider.js +120 -6
- package/dist/v2/standalone/index.d.ts +20 -0
- package/dist/v2/standalone/index.js +22 -0
- package/dist/v2/vue/index.d.ts +6 -0
- package/dist/v2/vue/index.js +10 -0
- package/package.json +6 -1
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Plugin Configuration Utility Functions
|
|
3
3
|
* Pure functions for plugin configuration management
|
|
4
4
|
*/
|
|
5
|
+
import { isLocalEnvironment } from '../config/environment';
|
|
5
6
|
import { resolveEnvValue } from './env';
|
|
6
7
|
/**
|
|
7
8
|
* Load local development configuration
|
|
@@ -15,13 +16,8 @@ const loadLocalDevConfig = async (configVariant = 'default') => {
|
|
|
15
16
|
return null;
|
|
16
17
|
}
|
|
17
18
|
// Only try to load local config in TRUE local development (not deployed CDN instances)
|
|
18
|
-
// Exclude CDN subdomains (e.g., instance-id.cdn.localhost)
|
|
19
|
-
|
|
20
|
-
(window.location.hostname === 'localhost' ||
|
|
21
|
-
window.location.hostname === '127.0.0.1' ||
|
|
22
|
-
window.location.hostname.includes('ngrok-free.app')) &&
|
|
23
|
-
!window.location.hostname.includes('.cdn.');
|
|
24
|
-
if (!isLocalDev) {
|
|
19
|
+
// Exclude CDN subdomains (e.g., instance-id.cdn.localhost)
|
|
20
|
+
if (!isLocalEnvironment(true)) {
|
|
25
21
|
return null;
|
|
26
22
|
}
|
|
27
23
|
// Load local store/account config
|
|
@@ -99,28 +95,23 @@ const loadStaticResources = async () => {
|
|
|
99
95
|
return null;
|
|
100
96
|
}
|
|
101
97
|
// Only try to load in TRUE local development (not deployed CDN instances)
|
|
102
|
-
// Exclude CDN subdomains (e.g., instance-id.cdn.localhost)
|
|
103
|
-
|
|
104
|
-
(window.location.hostname === 'localhost' ||
|
|
105
|
-
window.location.hostname === '127.0.0.1' ||
|
|
106
|
-
window.location.hostname.includes('ngrok-free.app')) &&
|
|
107
|
-
!window.location.hostname.includes('.cdn.');
|
|
108
|
-
if (!isLocalDev) {
|
|
98
|
+
// Exclude CDN subdomains (e.g., instance-id.cdn.localhost)
|
|
99
|
+
if (!isLocalEnvironment(true)) {
|
|
109
100
|
return null;
|
|
110
101
|
}
|
|
111
102
|
// Load static resources file
|
|
112
|
-
console.log('🛠️ Attempting to load /config/resources.static.json...');
|
|
103
|
+
console.log('🛠️ [V2] Attempting to load /config/resources.static.json...');
|
|
113
104
|
const response = await fetch('/config/resources.static.json');
|
|
114
105
|
if (!response.ok) {
|
|
115
|
-
console.log('🛠️ resources.static.json not found or failed to load');
|
|
106
|
+
console.log('🛠️ [V2] resources.static.json not found or failed to load');
|
|
116
107
|
return null;
|
|
117
108
|
}
|
|
118
109
|
const staticResources = await response.json();
|
|
119
|
-
console.log('🛠️ ✅ Loaded local static resources:', staticResources);
|
|
110
|
+
console.log('🛠️ [V2] ✅ Loaded local static resources:', staticResources);
|
|
120
111
|
return staticResources;
|
|
121
112
|
}
|
|
122
113
|
catch (error) {
|
|
123
|
-
console.error('🛠️ ❌ Error loading static resources:', error);
|
|
114
|
+
console.error('🛠️ [V2] ❌ Error loading static resources:', error);
|
|
124
115
|
return null;
|
|
125
116
|
}
|
|
126
117
|
};
|
|
@@ -180,41 +171,70 @@ const loadProductionConfig = async () => {
|
|
|
180
171
|
* Handles local dev, production, and raw config
|
|
181
172
|
*/
|
|
182
173
|
export const loadPluginConfig = async (configVariant = 'default', rawConfig) => {
|
|
174
|
+
console.log('🔧 [V2] loadPluginConfig called with variant:', configVariant);
|
|
183
175
|
// Load static resources first (only in local dev)
|
|
184
176
|
const staticResources = await loadStaticResources();
|
|
177
|
+
console.log('🔧 [V2] Static resources loaded:', {
|
|
178
|
+
hasStaticResources: !!staticResources,
|
|
179
|
+
staticResourcesKeys: staticResources ? Object.keys(staticResources) : [],
|
|
180
|
+
});
|
|
185
181
|
// If raw config is provided, use it directly
|
|
186
182
|
if (rawConfig) {
|
|
187
|
-
|
|
183
|
+
const result = {
|
|
188
184
|
storeId: rawConfig.storeId,
|
|
189
185
|
accountId: rawConfig.accountId,
|
|
190
186
|
basePath: rawConfig.basePath ?? '/',
|
|
191
187
|
config: rawConfig.config ?? {},
|
|
192
188
|
staticResources: staticResources ?? undefined,
|
|
193
189
|
};
|
|
190
|
+
console.log('🔧 [V2] Final config (raw):', {
|
|
191
|
+
hasStoreId: !!result.storeId,
|
|
192
|
+
hasStaticResources: !!result.staticResources,
|
|
193
|
+
staticResourcesKeys: result.staticResources ? Object.keys(result.staticResources) : [],
|
|
194
|
+
});
|
|
195
|
+
return result;
|
|
194
196
|
}
|
|
195
197
|
else {
|
|
196
198
|
const rawConfig = await createRawPluginConfig();
|
|
197
199
|
if (rawConfig) {
|
|
198
|
-
|
|
200
|
+
const result = {
|
|
199
201
|
...rawConfig,
|
|
200
202
|
staticResources: staticResources ?? undefined,
|
|
201
203
|
};
|
|
204
|
+
console.log('🔧 [V2] Final config (createRawPluginConfig):', {
|
|
205
|
+
hasStoreId: !!result.storeId,
|
|
206
|
+
hasStaticResources: !!result.staticResources,
|
|
207
|
+
staticResourcesKeys: result.staticResources ? Object.keys(result.staticResources) : [],
|
|
208
|
+
});
|
|
209
|
+
return result;
|
|
202
210
|
}
|
|
203
211
|
}
|
|
204
212
|
// Try local development config
|
|
205
213
|
const localConfig = await loadLocalDevConfig(configVariant);
|
|
206
214
|
if (localConfig) {
|
|
207
|
-
|
|
215
|
+
const result = {
|
|
208
216
|
...localConfig,
|
|
209
217
|
staticResources: staticResources ?? undefined,
|
|
210
218
|
};
|
|
219
|
+
console.log('🔧 [V2] Final config (local):', {
|
|
220
|
+
hasStoreId: !!result.storeId,
|
|
221
|
+
hasStaticResources: !!result.staticResources,
|
|
222
|
+
staticResourcesKeys: result.staticResources ? Object.keys(result.staticResources) : [],
|
|
223
|
+
});
|
|
224
|
+
return result;
|
|
211
225
|
}
|
|
212
226
|
// Fall back to production config
|
|
213
227
|
const productionConfig = await loadProductionConfig();
|
|
214
|
-
|
|
228
|
+
const result = {
|
|
215
229
|
...productionConfig,
|
|
216
230
|
staticResources: staticResources ?? undefined,
|
|
217
231
|
};
|
|
232
|
+
console.log('🔧 [V2] Final config (production):', {
|
|
233
|
+
hasStoreId: !!result.storeId,
|
|
234
|
+
hasStaticResources: !!result.staticResources,
|
|
235
|
+
staticResourcesKeys: result.staticResources ? Object.keys(result.staticResources) : [],
|
|
236
|
+
});
|
|
237
|
+
return result;
|
|
218
238
|
};
|
|
219
239
|
/**
|
|
220
240
|
* Helper to load local config file for development (from /config directory)
|
|
@@ -223,11 +243,7 @@ export const loadPluginConfig = async (configVariant = 'default', rawConfig) =>
|
|
|
223
243
|
export async function loadLocalConfig(configName = 'default', defaultConfig) {
|
|
224
244
|
try {
|
|
225
245
|
// Only load in localhost
|
|
226
|
-
|
|
227
|
-
(window.location.hostname === 'localhost' ||
|
|
228
|
-
window.location.hostname.includes('.localhost') ||
|
|
229
|
-
window.location.hostname.includes('127.0.0.1'));
|
|
230
|
-
if (!isLocalhost) {
|
|
246
|
+
if (!isLocalEnvironment()) {
|
|
231
247
|
return null;
|
|
232
248
|
}
|
|
233
249
|
if (defaultConfig) {
|
|
@@ -267,11 +283,7 @@ export async function loadLocalConfig(configName = 'default', defaultConfig) {
|
|
|
267
283
|
export async function createRawPluginConfig() {
|
|
268
284
|
try {
|
|
269
285
|
// Only run in true localhost - production should use meta tags
|
|
270
|
-
|
|
271
|
-
(window.location.hostname === 'localhost' ||
|
|
272
|
-
window.location.hostname.includes('.localhost') ||
|
|
273
|
-
window.location.hostname.includes('127.0.0.1'));
|
|
274
|
-
if (!isLocalhost) {
|
|
286
|
+
if (!isLocalEnvironment()) {
|
|
275
287
|
console.log('[createRawPluginConfig] Not localhost, skipping - will use meta tags in production');
|
|
276
288
|
return undefined;
|
|
277
289
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Storage Utilities - Core SDK (Framework-agnostic)
|
|
3
|
+
* Handles session persistence using browser cookies
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Save funnel session ID to browser cookie
|
|
7
|
+
*/
|
|
8
|
+
export declare function setFunnelSessionCookie(sessionId: string): void;
|
|
9
|
+
/**
|
|
10
|
+
* Retrieve funnel session ID from browser cookie
|
|
11
|
+
*/
|
|
12
|
+
export declare function getFunnelSessionCookie(): string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Clear funnel session cookie
|
|
15
|
+
*/
|
|
16
|
+
export declare function clearFunnelSessionCookie(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Check if a funnel session cookie exists
|
|
19
|
+
*/
|
|
20
|
+
export declare function hasFunnelSessionCookie(): boolean;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Storage Utilities - Core SDK (Framework-agnostic)
|
|
3
|
+
* Handles session persistence using browser cookies
|
|
4
|
+
*/
|
|
5
|
+
const FUNNEL_SESSION_COOKIE_NAME = 'tgd-funnel-session-id';
|
|
6
|
+
const SESSION_MAX_AGE = 30 * 24 * 60 * 60; // 30 days
|
|
7
|
+
/**
|
|
8
|
+
* Save funnel session ID to browser cookie
|
|
9
|
+
*/
|
|
10
|
+
export function setFunnelSessionCookie(sessionId) {
|
|
11
|
+
if (typeof document === 'undefined')
|
|
12
|
+
return;
|
|
13
|
+
document.cookie = `${FUNNEL_SESSION_COOKIE_NAME}=${sessionId}; path=/; max-age=${SESSION_MAX_AGE}; SameSite=Lax`;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Retrieve funnel session ID from browser cookie
|
|
17
|
+
*/
|
|
18
|
+
export function getFunnelSessionCookie() {
|
|
19
|
+
if (typeof document === 'undefined')
|
|
20
|
+
return undefined;
|
|
21
|
+
const cookie = document.cookie
|
|
22
|
+
.split('; ')
|
|
23
|
+
.find((row) => row.startsWith(`${FUNNEL_SESSION_COOKIE_NAME}=`));
|
|
24
|
+
return cookie ? cookie.split('=')[1] : undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Clear funnel session cookie
|
|
28
|
+
*/
|
|
29
|
+
export function clearFunnelSessionCookie() {
|
|
30
|
+
if (typeof document === 'undefined')
|
|
31
|
+
return;
|
|
32
|
+
document.cookie = `${FUNNEL_SESSION_COOKIE_NAME}=; path=/; max-age=0`;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Check if a funnel session cookie exists
|
|
36
|
+
*/
|
|
37
|
+
export function hasFunnelSessionCookie() {
|
|
38
|
+
return !!getFunnelSessionCookie();
|
|
39
|
+
}
|
package/dist/v2/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export * from './core/pathRemapping';
|
|
|
14
14
|
export type { CheckoutData, CheckoutInitParams, CheckoutLineItem, CheckoutSession, CheckoutSessionPreview, Promotion } from './core/resources/checkout';
|
|
15
15
|
export type { Order, OrderLineItem } from './core/utils/order';
|
|
16
16
|
export type { PostPurchaseOffer, PostPurchaseOfferItem, PostPurchaseOfferSummary } from './core/resources/postPurchases';
|
|
17
|
-
export type { Offer,
|
|
17
|
+
export type { Offer, OfferSummary, OfferSummaryItem } from './core/resources/offers';
|
|
18
18
|
export type { OrderBumpOffer, OrderBumpPreview } from './core/utils/orderBump';
|
|
19
19
|
export type { ApplePayToken, CardPaymentMethod, Payment, PaymentInstrumentCustomer, PaymentInstrumentCustomerResponse, PaymentInstrumentResponse, PaymentOptions, PaymentResponse } from './core/resources/payments';
|
|
20
20
|
export type { ShippingRate, ShippingRatesResponse } from './core/resources/shippingRates';
|
|
@@ -23,8 +23,10 @@ export type { ToggleOrderBumpResponse, VipOffer, VipPreviewResponse } from './co
|
|
|
23
23
|
export type { StoreConfig } from './core/resources/storeConfig';
|
|
24
24
|
export { FunnelActionType } from './core/resources/funnel';
|
|
25
25
|
export type { BackNavigationActionData, CartUpdatedActionData, DirectNavigationActionData, FormSubmitActionData, FunnelContextUpdateRequest, FunnelContextUpdateResponse, FunnelAction as FunnelEvent, FunnelInitializeRequest, FunnelInitializeResponse, FunnelNavigateRequest, FunnelNavigateResponse, FunnelNavigationAction, FunnelNavigationResult, NextAction, OfferAcceptedActionData, OfferDeclinedActionData, PaymentFailedActionData, PaymentSuccessActionData, SimpleFunnelContext } from './core/resources/funnel';
|
|
26
|
-
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCredits, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useLogin,
|
|
26
|
+
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCredits, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useFunnelLegacy, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffer, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useRemappableParams, useShippingRates, useSimpleFunnel, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers } from './react';
|
|
27
|
+
export type { DebugScript } from './react';
|
|
27
28
|
export type { TranslateFunction, TranslationText, UseTranslationOptions, UseTranslationResult } from './react/hooks/useTranslation';
|
|
29
|
+
export type { FunnelContextValue } from './react/hooks/useFunnel';
|
|
28
30
|
export type { ClubOffer, ClubOfferItem, ClubOfferLineItem, ClubOfferSummary, UseClubOffersOptions, UseClubOffersResult } from './react/hooks/useClubOffers';
|
|
29
31
|
export type { UseCreditsOptions, UseCreditsResult } from './react/hooks/useCredits';
|
|
30
32
|
export type { UseLoginOptions, UseLoginResult } from './react/hooks/useLogin';
|
package/dist/v2/index.js
CHANGED
|
@@ -15,4 +15,4 @@ export * from './core/utils/products';
|
|
|
15
15
|
export * from './core/pathRemapping';
|
|
16
16
|
export { FunnelActionType } from './core/resources/funnel';
|
|
17
17
|
// React exports (hooks and components only, types are exported above)
|
|
18
|
-
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCredits, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useLogin,
|
|
18
|
+
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCredits, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useFunnelLegacy, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffer, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useRemappableParams, useShippingRates, useSimpleFunnel, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers } from './react';
|
|
@@ -77,6 +77,8 @@ export const DebugDrawer = ({ isOpen, onClose }) => {
|
|
|
77
77
|
const context = useTagadaContext();
|
|
78
78
|
const pluginConfig = usePluginConfig();
|
|
79
79
|
const [activeTab, setActiveTab] = useState('overview');
|
|
80
|
+
const [runningScripts, setRunningScripts] = useState(new Set());
|
|
81
|
+
const [scriptResults, setScriptResults] = useState({});
|
|
80
82
|
// Handler to jump to a specific step using direct_navigation
|
|
81
83
|
const handleJumpToStep = async (stepId, stepName) => {
|
|
82
84
|
// Try to get sessionId from debug data or context
|
|
@@ -168,7 +170,49 @@ export const DebugDrawer = ({ isOpen, onClose }) => {
|
|
|
168
170
|
const itemsTab = context.debugCheckout.isActive && context.debugCheckout.data?.checkout?.summary
|
|
169
171
|
? [{ id: 'items', label: 'Items' }]
|
|
170
172
|
: [];
|
|
171
|
-
|
|
173
|
+
// Add scripts tab if debug scripts are available
|
|
174
|
+
const scriptsTab = context.debugScripts && context.debugScripts.length > 0
|
|
175
|
+
? [{ id: 'scripts', label: `Scripts (${context.debugScripts.length})` }]
|
|
176
|
+
: [];
|
|
177
|
+
const tabs = [
|
|
178
|
+
...baseTabs,
|
|
179
|
+
...funnelTab,
|
|
180
|
+
...checkoutTab,
|
|
181
|
+
...itemsTab,
|
|
182
|
+
...scriptsTab,
|
|
183
|
+
{ id: 'raw', label: 'Raw Data' },
|
|
184
|
+
];
|
|
185
|
+
// Handler to run a debug script
|
|
186
|
+
const handleRunScript = async (scriptId) => {
|
|
187
|
+
const script = context.debugScripts?.find((s) => s.id === scriptId);
|
|
188
|
+
if (!script)
|
|
189
|
+
return;
|
|
190
|
+
setRunningScripts((prev) => new Set(prev).add(scriptId));
|
|
191
|
+
setScriptResults((prev) => ({ ...prev, [scriptId]: undefined }));
|
|
192
|
+
try {
|
|
193
|
+
await script.run(context);
|
|
194
|
+
setScriptResults((prev) => ({
|
|
195
|
+
...prev,
|
|
196
|
+
[scriptId]: { success: true, message: 'Script executed successfully' },
|
|
197
|
+
}));
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
setScriptResults((prev) => ({
|
|
201
|
+
...prev,
|
|
202
|
+
[scriptId]: {
|
|
203
|
+
success: false,
|
|
204
|
+
message: error instanceof Error ? error.message : 'Script failed',
|
|
205
|
+
},
|
|
206
|
+
}));
|
|
207
|
+
}
|
|
208
|
+
finally {
|
|
209
|
+
setRunningScripts((prev) => {
|
|
210
|
+
const next = new Set(prev);
|
|
211
|
+
next.delete(scriptId);
|
|
212
|
+
return next;
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
};
|
|
172
216
|
return (_jsxs(_Fragment, { children: [_jsx("div", { style: {
|
|
173
217
|
position: 'fixed',
|
|
174
218
|
top: 0,
|
|
@@ -681,6 +725,59 @@ export const DebugDrawer = ({ isOpen, onClose }) => {
|
|
|
681
725
|
fontSize: '11px',
|
|
682
726
|
margin: 0,
|
|
683
727
|
whiteSpace: 'pre-wrap',
|
|
684
|
-
}, children: context.debugCheckout.error.stack }))] })] })), _jsxs("div", { children: [_jsx("h4", { style: { margin: '0 0 12px 0', color: '#60a5fa' }, children: "Full Checkout Data" }), _jsx(TreeView, { data: context.debugCheckout.data, name: "checkoutData" })] })] })) : (_jsx("p", { style: { color: '#6b7280' }, children: "No checkout hook active" }))] })), activeTab === '
|
|
728
|
+
}, children: context.debugCheckout.error.stack }))] })] })), _jsxs("div", { children: [_jsx("h4", { style: { margin: '0 0 12px 0', color: '#60a5fa' }, children: "Full Checkout Data" }), _jsx(TreeView, { data: context.debugCheckout.data, name: "checkoutData" })] })] })) : (_jsx("p", { style: { color: '#6b7280' }, children: "No checkout hook active" }))] })), activeTab === 'scripts' && (_jsxs("div", { children: [_jsx("h3", { style: { margin: '0 0 12px 0', color: '#60a5fa', fontSize: '14px' }, children: "\uD83D\uDEE0\uFE0F Debug Scripts" }), _jsx("p", { style: { margin: '0 0 16px 0', fontSize: '11px', color: '#9ca3af' }, children: "Template-provided scripts for debugging and testing. Click a script to run it." }), context.debugScripts && context.debugScripts.length > 0 ? (_jsx("div", { style: { display: 'grid', gap: '10px' }, children: (() => {
|
|
729
|
+
const grouped = context.debugScripts.reduce((acc, script) => {
|
|
730
|
+
const category = script.category || 'General';
|
|
731
|
+
if (!acc[category])
|
|
732
|
+
acc[category] = [];
|
|
733
|
+
acc[category].push(script);
|
|
734
|
+
return acc;
|
|
735
|
+
}, {});
|
|
736
|
+
return Object.entries(grouped).map(([category, scripts]) => (_jsxs("div", { children: [_jsx("div", { style: {
|
|
737
|
+
fontSize: '11px',
|
|
738
|
+
color: '#9ca3af',
|
|
739
|
+
fontWeight: 'bold',
|
|
740
|
+
marginBottom: '8px',
|
|
741
|
+
textTransform: 'uppercase',
|
|
742
|
+
letterSpacing: '0.5px',
|
|
743
|
+
}, children: category }), _jsx("div", { style: { display: 'grid', gap: '8px' }, children: scripts.map((script) => {
|
|
744
|
+
const isRunning = runningScripts.has(script.id);
|
|
745
|
+
const result = scriptResults[script.id];
|
|
746
|
+
return (_jsxs("div", { style: {
|
|
747
|
+
border: '1px solid #374151',
|
|
748
|
+
borderRadius: '6px',
|
|
749
|
+
padding: '10px 12px',
|
|
750
|
+
backgroundColor: '#111827',
|
|
751
|
+
}, children: [_jsxs("div", { style: {
|
|
752
|
+
display: 'flex',
|
|
753
|
+
justifyContent: 'space-between',
|
|
754
|
+
alignItems: 'flex-start',
|
|
755
|
+
gap: '12px',
|
|
756
|
+
}, children: [_jsxs("div", { style: { flex: 1 }, children: [_jsx("div", { style: {
|
|
757
|
+
color: '#f9fafb',
|
|
758
|
+
fontWeight: 'bold',
|
|
759
|
+
fontSize: '12px',
|
|
760
|
+
marginBottom: '4px',
|
|
761
|
+
}, children: script.name }), script.description && (_jsx("div", { style: { fontSize: '11px', color: '#9ca3af' }, children: script.description }))] }), _jsx("button", { onClick: () => handleRunScript(script.id), disabled: isRunning, style: {
|
|
762
|
+
backgroundColor: isRunning ? '#374151' : '#3b82f6',
|
|
763
|
+
color: '#fff',
|
|
764
|
+
border: 'none',
|
|
765
|
+
borderRadius: '4px',
|
|
766
|
+
padding: '6px 12px',
|
|
767
|
+
fontSize: '11px',
|
|
768
|
+
fontWeight: 'bold',
|
|
769
|
+
cursor: isRunning ? 'not-allowed' : 'pointer',
|
|
770
|
+
transition: 'background-color 0.2s',
|
|
771
|
+
minWidth: '60px',
|
|
772
|
+
}, children: isRunning ? '⏳' : '▶ Run' })] }), result && (_jsxs("div", { style: {
|
|
773
|
+
marginTop: '8px',
|
|
774
|
+
padding: '6px 8px',
|
|
775
|
+
borderRadius: '4px',
|
|
776
|
+
fontSize: '10px',
|
|
777
|
+
backgroundColor: result.success ? '#065f46' : '#7f1d1d',
|
|
778
|
+
color: result.success ? '#6ee7b7' : '#fca5a5',
|
|
779
|
+
}, children: [result.success ? '✅' : '❌', " ", result.message] }))] }, script.id));
|
|
780
|
+
}) })] }, category)));
|
|
781
|
+
})() })) : (_jsx("p", { style: { color: '#6b7280' }, children: "No debug scripts available" }))] })), activeTab === 'raw' && (_jsxs("div", { children: [_jsx("h3", { style: { margin: '0 0 16px 0', color: '#60a5fa' }, children: "Raw Context Data" }), _jsx("div", { style: { fontSize: '12px' }, children: _jsx(TreeView, { data: context, name: "tagadaContext", maxLevel: 4 }) })] }))] })] })] }));
|
|
685
782
|
};
|
|
686
783
|
export default DebugDrawer;
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This example demonstrates how to access data from previous steps
|
|
5
5
|
* using the funnel context, including order, customer, and other resources.
|
|
6
|
+
*
|
|
7
|
+
* Note: Funnel initialization is now configured at the provider level:
|
|
8
|
+
* <TagadaProvider autoInitializeFunnel={true} funnelId="...">
|
|
6
9
|
*/
|
|
7
10
|
export declare function FunnelContextExample(): import("react/jsx-runtime").JSX.Element;
|
|
8
11
|
/**
|
|
@@ -4,12 +4,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
4
4
|
*
|
|
5
5
|
* This example demonstrates how to access data from previous steps
|
|
6
6
|
* using the funnel context, including order, customer, and other resources.
|
|
7
|
+
*
|
|
8
|
+
* Note: Funnel initialization is now configured at the provider level:
|
|
9
|
+
* <TagadaProvider autoInitializeFunnel={true} funnelId="...">
|
|
7
10
|
*/
|
|
8
11
|
import { useFunnel } from '../useFunnel';
|
|
9
12
|
export function FunnelContextExample() {
|
|
10
|
-
const { context, isLoading, isInitialized } = useFunnel(
|
|
11
|
-
autoInitialize: true,
|
|
12
|
-
});
|
|
13
|
+
const { context, isLoading, isInitialized } = useFunnel();
|
|
13
14
|
if (isLoading) {
|
|
14
15
|
return _jsx("div", { children: "Loading funnel session..." });
|
|
15
16
|
}
|
|
@@ -9,7 +9,7 @@ export interface ClubOfferItem {
|
|
|
9
9
|
variant: {
|
|
10
10
|
name: string;
|
|
11
11
|
description: string;
|
|
12
|
-
imageUrl: string;
|
|
12
|
+
imageUrl: string | null;
|
|
13
13
|
grams: number;
|
|
14
14
|
};
|
|
15
15
|
unitAmount: number;
|
|
@@ -31,7 +31,7 @@ export interface ClubOfferLineItem {
|
|
|
31
31
|
id: string;
|
|
32
32
|
name: string;
|
|
33
33
|
description: string | null;
|
|
34
|
-
imageUrl: string;
|
|
34
|
+
imageUrl: string | null;
|
|
35
35
|
grams: number;
|
|
36
36
|
product: {
|
|
37
37
|
id: string;
|
|
@@ -1,52 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* useFunnel Hook
|
|
2
|
+
* useFunnel Hook - Access funnel state and navigation methods
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* and
|
|
4
|
+
* This hook consumes the funnel state from TagadaProvider. All complex
|
|
5
|
+
* initialization and session management is handled at the provider level.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```tsx
|
|
9
|
+
* // In your root component or layout:
|
|
10
|
+
* <TagadaProvider funnelId="funnelv2_xxx" autoInitializeFunnel={true}>
|
|
11
|
+
* <YourApp />
|
|
12
|
+
* </TagadaProvider>
|
|
13
|
+
*
|
|
14
|
+
* // In any child component:
|
|
15
|
+
* const { context, next, isLoading } = useFunnel();
|
|
16
|
+
* ```
|
|
6
17
|
*/
|
|
7
18
|
import { FunnelAction, FunnelNavigationResult, SimpleFunnelContext } from '../../core/resources/funnel';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
currentStepId?: string;
|
|
11
|
-
onNavigate?: (result: FunnelNavigationResult) => void | boolean;
|
|
12
|
-
onError?: (error: Error) => void;
|
|
13
|
-
autoInitialize?: boolean;
|
|
14
|
-
enabled?: boolean;
|
|
15
|
-
}
|
|
16
|
-
export interface UseFunnelResult {
|
|
17
|
-
next: (event: FunnelAction) => Promise<any>;
|
|
18
|
-
goToStep: (stepId: string) => Promise<any>;
|
|
19
|
-
updateContext: (updates: Partial<SimpleFunnelContext>) => Promise<void>;
|
|
19
|
+
import { FunnelState } from '../../core/funnelClient';
|
|
20
|
+
export interface FunnelContextValue extends FunnelState {
|
|
20
21
|
currentStep: {
|
|
21
22
|
id: string;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
isNavigating: boolean;
|
|
23
|
+
} | null;
|
|
24
|
+
next: (event: FunnelAction) => Promise<FunnelNavigationResult>;
|
|
25
|
+
goToStep: (stepId: string) => Promise<FunnelNavigationResult>;
|
|
26
|
+
updateContext: (updates: Partial<SimpleFunnelContext>) => Promise<void>;
|
|
27
27
|
initializeSession: (entryStepId?: string) => Promise<void>;
|
|
28
28
|
endSession: () => Promise<void>;
|
|
29
29
|
retryInitialization: () => Promise<void>;
|
|
30
|
-
|
|
31
|
-
isSessionLoading: boolean;
|
|
32
|
-
sessionError: Error | null;
|
|
33
|
-
refetch: () => void;
|
|
30
|
+
refetch: () => Promise<void>;
|
|
34
31
|
}
|
|
35
32
|
/**
|
|
36
|
-
*
|
|
33
|
+
* Hook to access funnel state and methods
|
|
37
34
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Simplified funnel hook for basic step tracking (v2)
|
|
35
|
+
* This hook simply returns the funnel state from TagadaProvider.
|
|
36
|
+
* All complex logic is handled at the provider level.
|
|
37
|
+
*
|
|
38
|
+
* @returns FunnelContextValue with state and methods
|
|
44
39
|
*/
|
|
45
|
-
export declare function
|
|
46
|
-
currentStepId: string;
|
|
47
|
-
next: (event: FunnelAction) => Promise<any>;
|
|
48
|
-
goToStep: (stepId: string) => Promise<any>;
|
|
49
|
-
isLoading: boolean;
|
|
50
|
-
context: SimpleFunnelContext<{}> | null;
|
|
51
|
-
};
|
|
52
|
-
export type { FunnelAction as FunnelEvent, FunnelNavigationAction, FunnelNavigationResult, SimpleFunnelContext } from '../../core/resources/funnel';
|
|
40
|
+
export declare function useFunnel(): FunnelContextValue;
|