@tagadapay/plugin-sdk 1.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.
Files changed (63) hide show
  1. package/README.md +475 -0
  2. package/dist/data/currencies.json +2410 -0
  3. package/dist/index.d.ts +33 -0
  4. package/dist/index.js +37 -0
  5. package/dist/react/components/DebugDrawer.d.ts +7 -0
  6. package/dist/react/components/DebugDrawer.js +368 -0
  7. package/dist/react/components/OffersDemo.d.ts +1 -0
  8. package/dist/react/components/OffersDemo.js +50 -0
  9. package/dist/react/components/index.d.ts +1 -0
  10. package/dist/react/components/index.js +1 -0
  11. package/dist/react/config/environment.d.ts +22 -0
  12. package/dist/react/config/environment.js +132 -0
  13. package/dist/react/config/payment.d.ts +23 -0
  14. package/dist/react/config/payment.js +52 -0
  15. package/dist/react/hooks/useAuth.d.ts +4 -0
  16. package/dist/react/hooks/useAuth.js +12 -0
  17. package/dist/react/hooks/useCheckout.d.ts +262 -0
  18. package/dist/react/hooks/useCheckout.js +325 -0
  19. package/dist/react/hooks/useCurrency.d.ts +4 -0
  20. package/dist/react/hooks/useCurrency.js +640 -0
  21. package/dist/react/hooks/useCustomer.d.ts +7 -0
  22. package/dist/react/hooks/useCustomer.js +14 -0
  23. package/dist/react/hooks/useEnvironment.d.ts +7 -0
  24. package/dist/react/hooks/useEnvironment.js +18 -0
  25. package/dist/react/hooks/useLocale.d.ts +2 -0
  26. package/dist/react/hooks/useLocale.js +43 -0
  27. package/dist/react/hooks/useOffers.d.ts +99 -0
  28. package/dist/react/hooks/useOffers.js +115 -0
  29. package/dist/react/hooks/useOrder.d.ts +44 -0
  30. package/dist/react/hooks/useOrder.js +77 -0
  31. package/dist/react/hooks/usePayment.d.ts +60 -0
  32. package/dist/react/hooks/usePayment.js +343 -0
  33. package/dist/react/hooks/usePaymentPolling.d.ts +45 -0
  34. package/dist/react/hooks/usePaymentPolling.js +146 -0
  35. package/dist/react/hooks/useProducts.d.ts +95 -0
  36. package/dist/react/hooks/useProducts.js +120 -0
  37. package/dist/react/hooks/useSession.d.ts +10 -0
  38. package/dist/react/hooks/useSession.js +17 -0
  39. package/dist/react/hooks/useThreeds.d.ts +38 -0
  40. package/dist/react/hooks/useThreeds.js +162 -0
  41. package/dist/react/hooks/useThreedsModal.d.ts +16 -0
  42. package/dist/react/hooks/useThreedsModal.js +328 -0
  43. package/dist/react/index.d.ts +26 -0
  44. package/dist/react/index.js +27 -0
  45. package/dist/react/providers/TagadaProvider.d.ts +55 -0
  46. package/dist/react/providers/TagadaProvider.js +471 -0
  47. package/dist/react/services/apiService.d.ts +149 -0
  48. package/dist/react/services/apiService.js +168 -0
  49. package/dist/react/types.d.ts +151 -0
  50. package/dist/react/types.js +4 -0
  51. package/dist/react/utils/__tests__/urlUtils.test.d.ts +1 -0
  52. package/dist/react/utils/__tests__/urlUtils.test.js +189 -0
  53. package/dist/react/utils/deviceInfo.d.ts +39 -0
  54. package/dist/react/utils/deviceInfo.js +163 -0
  55. package/dist/react/utils/jwtDecoder.d.ts +14 -0
  56. package/dist/react/utils/jwtDecoder.js +86 -0
  57. package/dist/react/utils/money.d.ts +2273 -0
  58. package/dist/react/utils/money.js +104 -0
  59. package/dist/react/utils/tokenStorage.d.ts +16 -0
  60. package/dist/react/utils/tokenStorage.js +52 -0
  61. package/dist/react/utils/urlUtils.d.ts +239 -0
  62. package/dist/react/utils/urlUtils.js +449 -0
  63. package/package.json +64 -0
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Tagada Pay Plugin SDK
3
+ *
4
+ * Modern React SDK for building Tagada Pay plugins
5
+ *
6
+ * Usage:
7
+ * ```tsx
8
+ * import { TagadaProvider, useCustomer } from '@tagadapay/plugin-sdk/react';
9
+ *
10
+ * function App() {
11
+ * return (
12
+ * <TagadaProvider>
13
+ * <MyPlugin />
14
+ * </TagadaProvider>
15
+ * );
16
+ * }
17
+ *
18
+ * function MyPlugin() {
19
+ * const { customer, isAuthenticated } = useCustomer();
20
+ *
21
+ * return (
22
+ * <div>
23
+ * {isAuthenticated ? (
24
+ * <p>Welcome back, {customer.firstName}!</p>
25
+ * ) : (
26
+ * <p>Welcome, guest!</p>
27
+ * )}
28
+ * </div>
29
+ * );
30
+ * }
31
+ * ```
32
+ */
33
+ export * from './react';
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Tagada Pay Plugin SDK
3
+ *
4
+ * Modern React SDK for building Tagada Pay plugins
5
+ *
6
+ * Usage:
7
+ * ```tsx
8
+ * import { TagadaProvider, useCustomer } from '@tagadapay/plugin-sdk/react';
9
+ *
10
+ * function App() {
11
+ * return (
12
+ * <TagadaProvider>
13
+ * <MyPlugin />
14
+ * </TagadaProvider>
15
+ * );
16
+ * }
17
+ *
18
+ * function MyPlugin() {
19
+ * const { customer, isAuthenticated } = useCustomer();
20
+ *
21
+ * return (
22
+ * <div>
23
+ * {isAuthenticated ? (
24
+ * <p>Welcome back, {customer.firstName}!</p>
25
+ * ) : (
26
+ * <p>Welcome, guest!</p>
27
+ * )}
28
+ * </div>
29
+ * );
30
+ * }
31
+ * ```
32
+ */
33
+ // Export the new React SDK
34
+ export * from './react';
35
+ // Bridge functionality has been moved to separate imports to prevent SSR issues
36
+ // If you need the deprecated bridge, explicitly import from '@tagadapay/plugin-sdk/bridge'
37
+ // Example: import { initializePlugin } from '@tagadapay/plugin-sdk/bridge'
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ interface DebugDrawerProps {
3
+ isOpen: boolean;
4
+ onClose: () => void;
5
+ }
6
+ export declare const DebugDrawer: React.FC<DebugDrawerProps>;
7
+ export default DebugDrawer;
@@ -0,0 +1,368 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState, useEffect } from 'react';
4
+ import { useTagadaContext } from '../providers/TagadaProvider';
5
+ const safeStringify = (value) => {
6
+ if (value === null)
7
+ return 'null';
8
+ if (value === undefined)
9
+ return 'undefined';
10
+ if (typeof value === 'string')
11
+ return value;
12
+ if (typeof value === 'number' || typeof value === 'boolean')
13
+ return String(value);
14
+ try {
15
+ return JSON.stringify(value);
16
+ }
17
+ catch {
18
+ return '[object]';
19
+ }
20
+ };
21
+ const TreeView = ({ data, name, level = 0, maxLevel = 3 }) => {
22
+ const [isExpanded, setIsExpanded] = useState(level < 2);
23
+ if (level > maxLevel) {
24
+ return _jsx("span", { style: { color: '#666' }, children: "..." });
25
+ }
26
+ if (data === null) {
27
+ return _jsx("span", { style: { color: '#f59e0b' }, children: "null" });
28
+ }
29
+ if (data === undefined) {
30
+ return _jsx("span", { style: { color: '#6b7280' }, children: "undefined" });
31
+ }
32
+ if (typeof data === 'string') {
33
+ return _jsxs("span", { style: { color: '#10b981' }, children: ["\"", data, "\""] });
34
+ }
35
+ if (typeof data === 'number') {
36
+ return _jsx("span", { style: { color: '#3b82f6' }, children: data });
37
+ }
38
+ if (typeof data === 'boolean') {
39
+ return _jsx("span", { style: { color: '#8b5cf6' }, children: data.toString() });
40
+ }
41
+ if (Array.isArray(data)) {
42
+ if (data.length === 0) {
43
+ return _jsx("span", { style: { color: '#6b7280' }, children: "[]" });
44
+ }
45
+ return (_jsxs("div", { style: { marginLeft: level > 0 ? '16px' : '0' }, children: [_jsxs("button", { onClick: () => setIsExpanded(!isExpanded), style: {
46
+ background: 'none',
47
+ border: 'none',
48
+ color: '#6b7280',
49
+ cursor: 'pointer',
50
+ padding: '0',
51
+ fontSize: '14px',
52
+ }, children: [isExpanded ? '▼' : '▶', " ", name, " (", data.length, " items)"] }), isExpanded && (_jsxs("div", { style: { marginLeft: '16px' }, children: [data.slice(0, 10).map((item, index) => (_jsx(TreeView, { data: item, name: `[${index}]`, level: level + 1, maxLevel: maxLevel }, index))), data.length > 10 && (_jsxs("div", { style: { color: '#6b7280', fontSize: '12px' }, children: ["... and ", data.length - 10, " more items"] }))] }))] }));
53
+ }
54
+ if (typeof data === 'object' && data !== null) {
55
+ const keys = Object.keys(data);
56
+ if (keys.length === 0) {
57
+ return _jsx("span", { style: { color: '#6b7280' }, children: '{}' });
58
+ }
59
+ return (_jsxs("div", { style: { marginLeft: level > 0 ? '16px' : '0' }, children: [_jsxs("button", { onClick: () => setIsExpanded(!isExpanded), style: {
60
+ background: 'none',
61
+ border: 'none',
62
+ color: '#6b7280',
63
+ cursor: 'pointer',
64
+ padding: '0',
65
+ fontSize: '14px',
66
+ }, children: [isExpanded ? '▼' : '▶', " ", name, " (", keys.length, " properties)"] }), isExpanded && (_jsxs("div", { style: { marginLeft: '16px' }, children: [keys.slice(0, 20).map((key) => (_jsxs("div", { style: { marginBottom: '4px' }, children: [_jsxs("span", { style: { color: '#ef4444', fontWeight: 'bold' }, children: [key, ": "] }), _jsx(TreeView, { data: data[key], name: key, level: level + 1, maxLevel: maxLevel })] }, key))), keys.length > 20 && (_jsxs("div", { style: { color: '#6b7280', fontSize: '12px' }, children: ["... and ", keys.length - 20, " more properties"] }))] }))] }));
67
+ }
68
+ try {
69
+ return _jsx("span", { children: safeStringify(data) });
70
+ }
71
+ catch {
72
+ return _jsx("span", { children: "[object]" });
73
+ }
74
+ };
75
+ export const DebugDrawer = ({ isOpen, onClose }) => {
76
+ const context = useTagadaContext();
77
+ const [activeTab, setActiveTab] = useState('overview');
78
+ useEffect(() => {
79
+ const handleEscape = (e) => {
80
+ if (e.key === 'Escape' && isOpen) {
81
+ onClose();
82
+ }
83
+ };
84
+ document.addEventListener('keydown', handleEscape);
85
+ return () => document.removeEventListener('keydown', handleEscape);
86
+ }, [isOpen, onClose]);
87
+ if (!isOpen)
88
+ return null;
89
+ const baseTabs = [
90
+ { id: 'overview', label: 'Overview' },
91
+ { id: 'store', label: 'Store' },
92
+ { id: 'session', label: 'Session' },
93
+ { id: 'auth', label: 'Auth' },
94
+ ];
95
+ // Add checkout tab if checkout is active
96
+ const checkoutTab = context.debugCheckout.isActive ? [{ id: 'checkout', label: 'Checkout' }] : [];
97
+ // Add items tab if checkout has summary data
98
+ const itemsTab = context.debugCheckout.isActive && context.debugCheckout.data?.checkout?.summary
99
+ ? [{ id: 'items', label: 'Items' }]
100
+ : [];
101
+ const tabs = [...baseTabs, ...checkoutTab, ...itemsTab, { id: 'raw', label: 'Raw Data' }];
102
+ return (_jsxs(_Fragment, { children: [_jsx("div", { style: {
103
+ position: 'fixed',
104
+ top: 0,
105
+ left: 0,
106
+ right: 0,
107
+ bottom: 0,
108
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
109
+ zIndex: 999998,
110
+ }, onClick: onClose }), _jsxs("div", { style: {
111
+ position: 'fixed',
112
+ top: 0,
113
+ right: 0,
114
+ bottom: 0,
115
+ width: '50vw',
116
+ minWidth: '500px',
117
+ maxWidth: '800px',
118
+ backgroundColor: '#1f2937',
119
+ color: '#f9fafb',
120
+ boxShadow: '-4px 0 24px rgba(0, 0, 0, 0.3)',
121
+ zIndex: 999999,
122
+ display: 'flex',
123
+ flexDirection: 'column',
124
+ fontSize: '14px',
125
+ fontFamily: 'ui-monospace, SFMono-Regular, Consolas, monospace',
126
+ }, children: [_jsxs("div", { style: {
127
+ padding: '16px',
128
+ borderBottom: '1px solid #374151',
129
+ display: 'flex',
130
+ justifyContent: 'space-between',
131
+ alignItems: 'center',
132
+ backgroundColor: '#111827',
133
+ }, children: [_jsxs("div", { children: [_jsx("h2", { style: { margin: 0, fontSize: '18px', fontWeight: 'bold' }, children: "\uD83D\uDC1B TagadaPay SDK Debug" }), _jsx("p", { style: { margin: '4px 0 0 0', fontSize: '12px', color: '#9ca3af' }, children: "Real-time SDK state and data inspection" })] }), _jsx("button", { onClick: onClose, style: {
134
+ background: 'none',
135
+ border: 'none',
136
+ color: '#9ca3af',
137
+ cursor: 'pointer',
138
+ fontSize: '24px',
139
+ padding: '4px',
140
+ }, children: "\u00D7" })] }), _jsx("div", { style: {
141
+ padding: '0 16px',
142
+ borderBottom: '1px solid #374151',
143
+ backgroundColor: '#111827',
144
+ }, children: _jsx("div", { style: { display: 'flex', gap: '0' }, children: tabs.map((tab) => (_jsx("button", { onClick: () => setActiveTab(tab.id), style: {
145
+ background: 'none',
146
+ border: 'none',
147
+ color: activeTab === tab.id ? '#60a5fa' : '#9ca3af',
148
+ cursor: 'pointer',
149
+ padding: '12px 16px',
150
+ fontSize: '14px',
151
+ borderBottom: activeTab === tab.id ? '2px solid #60a5fa' : '2px solid transparent',
152
+ }, children: tab.label }, tab.id))) }) }), _jsxs("div", { style: {
153
+ flex: 1,
154
+ padding: '16px',
155
+ overflow: 'auto',
156
+ backgroundColor: '#1f2937',
157
+ }, children: [activeTab === 'overview' && (_jsxs("div", { children: [_jsx("h3", { style: { margin: '0 0 16px 0', color: '#60a5fa' }, children: "SDK Overview" }), _jsxs("div", { style: { display: 'grid', gap: '12px' }, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Initialized:" }), _jsx("span", { style: { color: context.isInitialized ? '#10b981' : '#ef4444' }, children: context.isInitialized ? '✅ Yes' : '❌ No' })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Loading:" }), _jsx("span", { style: { color: context.isLoading ? '#f59e0b' : '#10b981' }, children: context.isLoading ? '⏳ Yes' : '✅ No' })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Environment:" }), _jsx("span", { style: { color: '#60a5fa' }, children: context.environment.apiConfig.baseUrl.includes('dev') ? 'Development' : 'Production' })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "API Base URL:" }), _jsx("span", { style: { color: '#10b981' }, children: context.environment.apiConfig.baseUrl })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Store ID:" }), _jsx("span", { style: { color: '#60a5fa' }, children: context.store?.id || 'Not set' })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Customer ID:" }), _jsx("span", { style: { color: '#60a5fa' }, children: context.customer?.id || 'Not set' })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Authenticated:" }), _jsx("span", { style: { color: context.auth.isAuthenticated ? '#10b981' : '#ef4444' }, children: context.auth.isAuthenticated ? '✅ Yes' : '❌ No' })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Currency:" }), _jsxs("span", { style: { color: '#f59e0b' }, children: [context.currency.code, " (", context.currency.symbol, ")"] })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Locale:" }), _jsx("span", { style: { color: '#8b5cf6' }, children: context.locale.locale })] })] })] })), activeTab === 'store' && (_jsxs("div", { children: [_jsx("h3", { style: { margin: '0 0 16px 0', color: '#60a5fa' }, children: "Store Configuration" }), context.store ? (_jsx(TreeView, { data: context.store, name: "store" })) : (_jsx("p", { style: { color: '#6b7280' }, children: "No store data available" }))] })), activeTab === 'session' && (_jsxs("div", { children: [_jsx("h3", { style: { margin: '0 0 16px 0', color: '#60a5fa' }, children: "Session Data" }), context.session ? (_jsx(TreeView, { data: context.session, name: "session" })) : (_jsx("p", { style: { color: '#6b7280' }, children: "No session data available" }))] })), activeTab === 'auth' && (_jsxs("div", { children: [_jsx("h3", { style: { margin: '0 0 16px 0', color: '#60a5fa' }, children: "Authentication State" }), _jsx(TreeView, { data: context.auth, name: "auth" }), context.customer && (_jsxs(_Fragment, { children: [_jsx("h4", { style: { margin: '24px 0 12px 0', color: '#60a5fa' }, children: "Customer Data" }), _jsx(TreeView, { data: context.customer, name: "customer" })] }))] })), activeTab === 'items' && (_jsxs("div", { children: [_jsx("h3", { style: { margin: '0 0 16px 0', color: '#60a5fa' }, children: "Items & Discounts" }), context.debugCheckout.data?.checkout?.summary ? (_jsxs("div", { children: [_jsxs("div", { style: { marginBottom: '24px' }, children: [_jsx("h4", { style: { margin: '0 0 12px 0', color: '#60a5fa' }, children: "Summary" }), _jsxs("div", { style: { display: 'grid', gap: '8px' }, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Currency:" }), _jsx("span", { style: { color: '#f59e0b' }, children: context.debugCheckout.data.checkout.summary.currency })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Subtotal:" }), _jsx("span", { style: { color: '#9ca3af' }, children: (() => {
158
+ try {
159
+ return context.money.formatMoney(Number(context.debugCheckout.data.checkout.summary.subtotalAmount) || 0, String(context.debugCheckout.data.checkout.summary.currency) || 'USD', context.locale.locale);
160
+ }
161
+ catch {
162
+ return String(context.debugCheckout.data.checkout.summary.subtotalAmount);
163
+ }
164
+ })() })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Total Promotions:" }), _jsx("span", { style: { color: '#ef4444' }, children: (() => {
165
+ try {
166
+ return `-${context.money.formatMoney(Number(context.debugCheckout.data.checkout.summary.totalPromotionAmount) || 0, String(context.debugCheckout.data.checkout.summary.currency) || 'USD', context.locale.locale)}`;
167
+ }
168
+ catch {
169
+ return `-${String(context.debugCheckout.data.checkout.summary.totalPromotionAmount)}`;
170
+ }
171
+ })() })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Total Adjusted:" }), _jsx("span", { style: { color: '#10b981', fontWeight: 'bold' }, children: (() => {
172
+ try {
173
+ return context.money.formatMoney(Number(context.debugCheckout.data.checkout.summary.totalAdjustedAmount) || 0, String(context.debugCheckout.data.checkout.summary.currency) || 'USD', context.locale.locale);
174
+ }
175
+ catch {
176
+ return String(context.debugCheckout.data.checkout.summary.totalAdjustedAmount);
177
+ }
178
+ })() })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Shipping:" }), _jsx("span", { style: { color: '#9ca3af' }, children: (() => {
179
+ try {
180
+ const shipping = Number(context.debugCheckout.data.checkout.summary.shippingCost) || 0;
181
+ return shipping === 0
182
+ ? 'FREE'
183
+ : context.money.formatMoney(shipping, String(context.debugCheckout.data.checkout.summary.currency) || 'USD', context.locale.locale);
184
+ }
185
+ catch {
186
+ return String(context.debugCheckout.data.checkout.summary.shippingCost);
187
+ }
188
+ })() })] })] })] }), _jsxs("div", { style: { marginBottom: '24px' }, children: [_jsxs("h4", { style: { margin: '0 0 12px 0', color: '#60a5fa' }, children: ["Line Items (", context.debugCheckout.data.checkout.summary.items.length, ")"] }), _jsx("div", { style: { display: 'grid', gap: '16px' }, children: context.debugCheckout.data.checkout.summary.items.map((item, index) => (_jsx("div", { style: {
189
+ border: '1px solid #374151',
190
+ borderRadius: '8px',
191
+ padding: '12px',
192
+ backgroundColor: '#111827',
193
+ }, children: _jsxs("div", { style: { display: 'flex', gap: '12px', alignItems: 'flex-start' }, children: [(() => {
194
+ const imageUrl = item.variant?.imageUrl ||
195
+ item.orderLineItemVariant?.imageUrl ||
196
+ item.imageUrl ||
197
+ item.product?.image?.src ||
198
+ item.product?.images?.[0]?.src;
199
+ return imageUrl ? (_jsx("img", { src: imageUrl, alt: item.product?.name ||
200
+ item.orderLineItemProduct?.name ||
201
+ item.name ||
202
+ 'Product', style: {
203
+ width: '60px',
204
+ height: '60px',
205
+ objectFit: 'cover',
206
+ borderRadius: '4px',
207
+ backgroundColor: '#374151',
208
+ }, onError: (e) => {
209
+ e.target.style.display = 'none';
210
+ } })) : (_jsx("div", { style: {
211
+ width: '60px',
212
+ height: '60px',
213
+ backgroundColor: '#374151',
214
+ borderRadius: '4px',
215
+ display: 'flex',
216
+ alignItems: 'center',
217
+ justifyContent: 'center',
218
+ fontSize: '24px',
219
+ color: '#9ca3af',
220
+ }, children: "\uD83D\uDCE6" }));
221
+ })(), _jsxs("div", { style: { flex: 1 }, children: [_jsxs("div", { style: { marginBottom: '8px' }, children: [_jsxs("h5", { style: {
222
+ margin: '0 0 4px 0',
223
+ color: '#f9fafb',
224
+ fontSize: '14px',
225
+ fontWeight: 'bold',
226
+ }, children: [item.product?.name ||
227
+ item.orderLineItemProduct?.name ||
228
+ item.name ||
229
+ 'Unknown Product', item.isOrderBump && (_jsx("span", { style: {
230
+ marginLeft: '8px',
231
+ fontSize: '11px',
232
+ backgroundColor: '#f59e0b',
233
+ color: '#000',
234
+ padding: '2px 6px',
235
+ borderRadius: '4px',
236
+ }, children: "ORDER BUMP" }))] }), (item.variant?.name || item.orderLineItemVariant?.name) && (_jsxs("p", { style: { margin: '0 0 4px 0', fontSize: '12px', color: '#9ca3af' }, children: ["Variant: ", item.variant?.name || item.orderLineItemVariant?.name] })), (item.product?.description || item.description) && (_jsx("p", { style: { margin: '0', fontSize: '11px', color: '#6b7280' }, children: (() => {
237
+ const desc = item.product?.description || item.description;
238
+ // Strip HTML tags for display
239
+ const cleaned = desc.replace(/<[^>]*>/g, '');
240
+ return cleaned.length > 100
241
+ ? cleaned.substring(0, 100) + '...'
242
+ : cleaned;
243
+ })() }))] }), _jsxs("div", { style: {
244
+ display: 'grid',
245
+ gridTemplateColumns: '1fr 1fr',
246
+ gap: '8px',
247
+ fontSize: '12px',
248
+ marginBottom: '8px',
249
+ }, children: [_jsxs("div", { children: [_jsx("span", { style: { color: '#9ca3af' }, children: "Quantity: " }), _jsx("span", { style: { color: '#60a5fa', fontWeight: 'bold' }, children: item.quantity })] }), _jsxs("div", { children: [_jsx("span", { style: { color: '#9ca3af' }, children: "Unit Price: " }), _jsx("span", { style: { color: '#f9fafb' }, children: (() => {
250
+ try {
251
+ return context.money.formatMoney(Number(item.unitAmount) || 0, String(context.debugCheckout.data.checkout.summary.currency) ||
252
+ 'USD', context.locale.locale);
253
+ }
254
+ catch {
255
+ return String(item.unitAmount);
256
+ }
257
+ })() })] }), _jsxs("div", { children: [_jsx("span", { style: { color: '#9ca3af' }, children: "Original: " }), _jsx("span", { style: {
258
+ color: item.amount !== item.adjustedAmount ? '#9ca3af' : '#f9fafb',
259
+ textDecoration: item.amount !== item.adjustedAmount ? 'line-through' : 'none',
260
+ }, children: (() => {
261
+ try {
262
+ return context.money.formatMoney(Number(item.amount) || 0, String(context.debugCheckout.data.checkout.summary.currency) ||
263
+ 'USD', context.locale.locale);
264
+ }
265
+ catch {
266
+ return String(item.amount);
267
+ }
268
+ })() })] }), _jsxs("div", { children: [_jsx("span", { style: { color: '#9ca3af' }, children: "Final: " }), _jsx("span", { style: { color: '#10b981', fontWeight: 'bold' }, children: (() => {
269
+ try {
270
+ return context.money.formatMoney(Number(item.adjustedAmount) || 0, String(context.debugCheckout.data.checkout.summary.currency) ||
271
+ 'USD', context.locale.locale);
272
+ }
273
+ catch {
274
+ return String(item.adjustedAmount);
275
+ }
276
+ })() }), item.amount !== item.adjustedAmount && (_jsxs("span", { style: { color: '#ef4444', marginLeft: '4px' }, children: ["(", (() => {
277
+ try {
278
+ const discount = Number(item.amount) - Number(item.adjustedAmount);
279
+ return `-${context.money.formatMoney(discount, String(context.debugCheckout.data.checkout.summary.currency) ||
280
+ 'USD', context.locale.locale)}`;
281
+ }
282
+ catch {
283
+ return `-${item.amount - item.adjustedAmount}`;
284
+ }
285
+ })(), ")"] }))] })] }), item.adjustments && item.adjustments.length > 0 && (_jsxs("div", { style: {
286
+ backgroundColor: '#065f46',
287
+ padding: '8px',
288
+ borderRadius: '4px',
289
+ marginTop: '8px',
290
+ }, children: [_jsx("div", { style: {
291
+ fontSize: '11px',
292
+ fontWeight: 'bold',
293
+ marginBottom: '4px',
294
+ color: '#6ee7b7',
295
+ }, children: "\uD83D\uDCB0 Item Promotions Applied:" }), item.adjustments.map((adjustment, adjIndex) => (_jsxs("div", { style: { fontSize: '10px', marginBottom: '2px' }, children: [_jsx("div", { style: { color: '#6ee7b7', fontWeight: 'bold' }, children: adjustment.description }), _jsxs("div", { style: { color: '#a7f3d0' }, children: ["Amount:", ' ', (() => {
296
+ try {
297
+ return context.money.formatMoney(Math.abs(Number(adjustment.amount) || 0), String(adjustment.currency) ||
298
+ String(context.debugCheckout.data.checkout.summary.currency) ||
299
+ 'USD', context.locale.locale);
300
+ }
301
+ catch {
302
+ return String(Math.abs(Number(adjustment.amount) || 0));
303
+ }
304
+ })(), ' ', "\u2022 Type: ", adjustment.type, " \u2022 Level: ", adjustment.level, adjustment.sourceId && ` • ID: ${adjustment.sourceId}`] })] }, adjIndex)))] })), _jsxs("div", { style: { fontSize: '9px', color: '#6b7280', marginTop: '8px' }, children: ["Product ID: ", item.productId, " \u2022 Variant ID: ", item.variantId, " \u2022 Price ID:", ' ', item.priceId] })] })] }) }, item.id || index))) })] }), context.debugCheckout.data?.availablePromotions &&
305
+ context.debugCheckout.data.availablePromotions.length > 0 && (_jsxs("div", { style: { marginBottom: '24px' }, children: [_jsxs("h4", { style: { margin: '0 0 12px 0', color: '#60a5fa' }, children: ["Available Promotions (", context.debugCheckout.data.availablePromotions.length, ")"] }), _jsx("div", { style: { display: 'grid', gap: '12px' }, children: context.debugCheckout.data.availablePromotions.map((promotion, index) => (_jsxs("div", { style: {
306
+ border: '1px solid #374151',
307
+ borderRadius: '6px',
308
+ padding: '12px',
309
+ backgroundColor: '#111827',
310
+ }, children: [_jsxs("div", { style: { marginBottom: '8px' }, children: [_jsxs("div", { style: { color: '#f9fafb', fontWeight: 'bold', marginBottom: '4px' }, children: [promotion.name, promotion.automatic && (_jsx("span", { style: {
311
+ marginLeft: '8px',
312
+ fontSize: '10px',
313
+ backgroundColor: '#10b981',
314
+ color: '#000',
315
+ padding: '2px 6px',
316
+ borderRadius: '4px',
317
+ }, children: "AUTO" })), promotion.enabled && (_jsx("span", { style: {
318
+ marginLeft: '8px',
319
+ fontSize: '10px',
320
+ backgroundColor: '#3b82f6',
321
+ color: '#fff',
322
+ padding: '2px 6px',
323
+ borderRadius: '4px',
324
+ }, children: "ACTIVE" }))] }), _jsxs("div", { style: { fontSize: '11px', color: '#9ca3af' }, children: ["ID: ", promotion.id, " \u2022 Usage: ", promotion.usageCount || 0, promotion.usageLimit && ` / ${promotion.usageLimit}`] })] }), promotion.rules && promotion.rules.length > 0 && (_jsxs("div", { style: { marginBottom: '8px' }, children: [_jsx("div", { style: {
325
+ fontSize: '10px',
326
+ color: '#60a5fa',
327
+ fontWeight: 'bold',
328
+ marginBottom: '4px',
329
+ }, children: "Rules:" }), promotion.rules.map((rule, ruleIndex) => (_jsxs("div", { style: { fontSize: '9px', color: '#d1d5db', marginBottom: '2px' }, children: ["\u2022 ", rule.type, " ", rule.productId && `(Product: ${rule.productId})`, rule.minimumQuantity && ` - Min Qty: ${rule.minimumQuantity}`, rule.minimumAmount && ` - Min Amount: ${rule.minimumAmount}`, rule.variantIds &&
330
+ rule.variantIds.length > 0 &&
331
+ ` - Variants: ${rule.variantIds.length}`] }, ruleIndex)))] })), promotion.actions && promotion.actions.length > 0 && (_jsxs("div", { children: [_jsx("div", { style: {
332
+ fontSize: '10px',
333
+ color: '#10b981',
334
+ fontWeight: 'bold',
335
+ marginBottom: '4px',
336
+ }, children: "Actions:" }), promotion.actions.map((action, actionIndex) => (_jsxs("div", { style: { fontSize: '9px', color: '#d1d5db', marginBottom: '2px' }, children: ["\u2022 ", action.type, action.adjustmentPercentage &&
337
+ ` - ${action.adjustmentPercentage}% off`, action.adjustmentAmount && ` - ${action.adjustmentAmount} off`, action.freeShipping && ` - Free Shipping`, action.targetProductId && ` - Target: ${action.targetProductId}`, action.maxQuantityDiscounted &&
338
+ ` - Max Qty: ${action.maxQuantityDiscounted}`] }, actionIndex)))] }))] }, promotion.id || index))) })] })), context.debugCheckout.data.checkout.summary.adjustments &&
339
+ context.debugCheckout.data.checkout.summary.adjustments.length > 0 && (_jsxs("div", { style: { marginBottom: '24px' }, children: [_jsxs("h4", { style: { margin: '0 0 12px 0', color: '#60a5fa' }, children: ["Order Level Discounts (", context.debugCheckout.data.checkout.summary.adjustments.length, ")"] }), _jsx("div", { style: { display: 'grid', gap: '8px' }, children: context.debugCheckout.data.checkout.summary.adjustments.map((adjustment, index) => (_jsxs("div", { style: {
340
+ border: '1px solid #374151',
341
+ borderRadius: '6px',
342
+ padding: '10px',
343
+ backgroundColor: '#111827',
344
+ display: 'flex',
345
+ justifyContent: 'space-between',
346
+ alignItems: 'center',
347
+ }, children: [_jsxs("div", { children: [_jsx("div", { style: { color: '#f9fafb', fontWeight: 'bold', marginBottom: '2px' }, children: adjustment.description }), _jsxs("div", { style: { fontSize: '11px', color: '#9ca3af' }, children: [adjustment.type, " \u2022 Level: ", adjustment.level, adjustment.sourceId && ` • ID: ${adjustment.sourceId}`] })] }), _jsx("div", { style: { color: '#ef4444', fontWeight: 'bold' }, children: (() => {
348
+ try {
349
+ return context.money.formatMoney(Math.abs(Number(adjustment.amount)) || 0, String(adjustment.currency) ||
350
+ String(context.debugCheckout.data.checkout.summary.currency) ||
351
+ 'USD', context.locale.locale);
352
+ }
353
+ catch {
354
+ return String(Math.abs(Number(adjustment.amount)));
355
+ }
356
+ })() })] }, index))) })] }))] })) : (_jsx("p", { style: { color: '#6b7280' }, children: "No checkout summary data available" }))] })), activeTab === 'checkout' && (_jsxs("div", { children: [_jsx("h3", { style: { margin: '0 0 16px 0', color: '#60a5fa' }, children: "Checkout Debug" }), context.debugCheckout.isActive ? (_jsxs("div", { children: [_jsxs("div", { style: { marginBottom: '20px' }, children: [_jsx("h4", { style: { margin: '0 0 12px 0', color: '#60a5fa' }, children: "Status" }), _jsxs("div", { style: { display: 'grid', gap: '8px' }, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Hook Active:" }), _jsx("span", { style: { color: '#10b981' }, children: "\u2705 Yes" })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Loading:" }), _jsx("span", { style: { color: context.debugCheckout.isLoading ? '#f59e0b' : '#10b981' }, children: context.debugCheckout.isLoading ? '⏳ Yes' : '✅ No' })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Has Error:" }), _jsx("span", { style: { color: context.debugCheckout.error ? '#ef4444' : '#10b981' }, children: context.debugCheckout.error ? '❌ Yes' : '✅ No' })] }), _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx("span", { children: "Last Updated:" }), _jsx("span", { style: { color: '#9ca3af', fontSize: '12px' }, children: context.debugCheckout.lastUpdated?.toLocaleTimeString() || 'Never' })] })] })] }), context.debugCheckout.error && (_jsxs("div", { style: { marginBottom: '20px' }, children: [_jsx("h4", { style: { margin: '0 0 12px 0', color: '#ef4444' }, children: "Error Details" }), _jsxs("div", { style: {
357
+ backgroundColor: '#372c2c',
358
+ padding: '12px',
359
+ borderRadius: '4px',
360
+ border: '1px solid #ef4444',
361
+ }, children: [_jsxs("div", { style: { color: '#ef4444', fontWeight: 'bold', marginBottom: '8px' }, children: [context.debugCheckout.error.name, ": ", context.debugCheckout.error.message] }), context.debugCheckout.error.stack && (_jsx("pre", { style: {
362
+ color: '#9ca3af',
363
+ fontSize: '11px',
364
+ margin: 0,
365
+ whiteSpace: 'pre-wrap',
366
+ }, 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 === '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 }) })] }))] })] })] }));
367
+ };
368
+ export default DebugDrawer;
@@ -0,0 +1 @@
1
+ export declare function OffersDemo(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,50 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { useOffers } from '../hooks/useOffers';
4
+ import { useCurrency } from '../hooks/useCurrency';
5
+ import { useLocale } from '../hooks/useLocale';
6
+ export function OffersDemo() {
7
+ const [selectedOfferIds, setSelectedOfferIds] = useState([]);
8
+ const [inputValue, setInputValue] = useState('');
9
+ const { locale } = useLocale();
10
+ const { offers, isLoading, error, refetch, createCheckoutSession, payOffer, transformToCheckout, getOffer, getTotalValue, getTotalSavings, } = useOffers({
11
+ offerIds: selectedOfferIds,
12
+ returnUrl: window.location.origin,
13
+ });
14
+ const currency = useCurrency();
15
+ const formatCurrency = (amount) => {
16
+ return currency.format(amount / 100);
17
+ };
18
+ const handleAddOffer = () => {
19
+ if (inputValue.trim() && !selectedOfferIds.includes(inputValue.trim())) {
20
+ setSelectedOfferIds([...selectedOfferIds, inputValue.trim()]);
21
+ setInputValue('');
22
+ }
23
+ };
24
+ const handleRemoveOffer = (offerId) => {
25
+ setSelectedOfferIds(selectedOfferIds.filter((id) => id !== offerId));
26
+ };
27
+ const handleCheckout = async (offerId) => {
28
+ try {
29
+ const { checkoutUrl } = await createCheckoutSession(offerId);
30
+ if (checkoutUrl) {
31
+ window.location.href = checkoutUrl;
32
+ }
33
+ }
34
+ catch (error) {
35
+ console.error('Checkout failed:', error);
36
+ alert('Checkout failed. Please try again.');
37
+ }
38
+ };
39
+ const handlePayOffer = async (offerId) => {
40
+ try {
41
+ await payOffer(offerId);
42
+ alert('Payment successful!');
43
+ }
44
+ catch (error) {
45
+ console.error('Payment failed:', error);
46
+ alert('Payment failed. Please try again.');
47
+ }
48
+ };
49
+ return (_jsxs("div", { className: "offers-demo mx-auto max-w-4xl p-6", children: [_jsx("h1", { className: "mb-6 text-2xl font-bold", children: "Offers Demo" }), _jsx("div", { className: "mb-6", children: _jsxs("div", { className: "flex gap-2", children: [_jsx("input", { type: "text", value: inputValue, onChange: (e) => setInputValue(e.target.value), placeholder: "Enter offer ID...", className: "flex-1 rounded-md border border-gray-300 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" }), _jsx("button", { onClick: handleAddOffer, className: "rounded-md bg-blue-500 px-4 py-2 text-white hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500", children: "Add Offer" })] }) }), _jsxs("div", { className: "mb-6", children: [_jsxs("h2", { className: "mb-3 text-lg font-semibold", children: ["Selected Offers (", selectedOfferIds.length, ")"] }), selectedOfferIds.length === 0 ? (_jsx("p", { className: "text-gray-500", children: "No offers selected. Add some offer IDs above." })) : (_jsx("div", { className: "space-y-2", children: selectedOfferIds.map((offerId) => (_jsxs("div", { className: "flex items-center justify-between rounded-md bg-gray-100 px-3 py-2", children: [_jsx("span", { className: "font-mono text-sm", children: offerId }), _jsx("button", { onClick: () => handleRemoveOffer(offerId), className: "text-red-500 hover:text-red-700", children: "Remove" })] }, offerId))) }))] }), isLoading && (_jsx("div", { className: "mb-6 rounded-md border border-blue-200 bg-blue-50 p-4", children: _jsx("p", { className: "text-blue-800", children: "Loading offers..." }) })), error && (_jsxs("div", { className: "mb-6 rounded-md border border-red-200 bg-red-50 p-4", children: [_jsxs("p", { className: "text-red-800", children: ["Error: ", error.message] }), _jsx("button", { onClick: () => refetch(), className: "mt-2 rounded-md bg-red-500 px-3 py-1 text-sm text-white hover:bg-red-600", children: "Retry" })] })), offers.length > 0 && (_jsxs("div", { className: "mb-6 rounded-md border border-green-200 bg-green-50 p-4", children: [_jsx("h3", { className: "mb-2 text-lg font-semibold text-green-800", children: "Offers Summary" }), _jsxs("div", { className: "space-y-1 text-green-700", children: [_jsxs("p", { children: ["Total Offers: ", offers.length] }), _jsxs("p", { children: ["Total Value: ", formatCurrency(getTotalValue())] }), _jsxs("p", { children: ["Total Savings: ", formatCurrency(getTotalSavings())] })] })] })), _jsx("div", { className: "space-y-4", children: offers.map((offer) => (_jsxs("div", { className: "rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "mb-3 flex items-start justify-between", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold", children: offer.titleTrans.en || offer.titleTrans[Object.keys(offer.titleTrans)[0]] }), _jsxs("p", { className: "font-mono text-sm text-gray-500", children: ["ID: ", offer.id] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx("button", { onClick: () => handleCheckout(offer.id), className: "rounded-md bg-blue-500 px-3 py-1 text-sm text-white hover:bg-blue-600", children: "Checkout" }), _jsx("button", { onClick: () => handlePayOffer(offer.id), className: "rounded-md bg-green-500 px-3 py-1 text-sm text-white hover:bg-green-600", children: "Pay Now" })] })] }), offer.summaries.map((summary, index) => (_jsxs("div", { className: "mb-3 rounded-md bg-gray-50 p-3", children: [_jsxs("div", { className: "mb-2 flex items-center justify-between", children: [_jsxs("span", { className: "font-semibold", children: ["Summary ", index + 1] }), _jsxs("div", { className: "text-right", children: [_jsx("div", { className: "text-lg font-bold text-green-600", children: formatCurrency(summary.totalAdjustedAmount) }), summary.totalPromotionAmount > 0 && (_jsxs("div", { className: "text-sm text-gray-500", children: ["Save ", formatCurrency(summary.totalPromotionAmount)] }))] })] }), _jsx("div", { className: "space-y-2", children: summary.items.map((item) => (_jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 py-1 last:border-b-0", children: [_jsxs("div", { children: [_jsx("span", { className: "font-medium", children: item.product.name }), _jsxs("span", { className: "ml-2 text-sm text-gray-500", children: ["(", item.variant.name, ")"] }), _jsxs("span", { className: "ml-2 text-sm text-gray-500", children: ["\u00D7 ", item.quantity] })] }), _jsxs("div", { className: "text-right", children: [_jsx("div", { className: "font-medium", children: formatCurrency(item.adjustedAmount) }), item.adjustedAmount !== item.amount && (_jsx("div", { className: "text-sm text-gray-500 line-through", children: formatCurrency(item.amount) }))] })] }, item.id))) }), summary.adjustments.length > 0 && (_jsxs("div", { className: "mt-2 border-t border-gray-200 pt-2", children: [_jsx("h4", { className: "mb-1 text-sm font-semibold", children: "Promotions:" }), _jsx("div", { className: "space-y-1", children: summary.adjustments.map((adjustment, adjIndex) => (_jsxs("div", { className: "text-sm text-green-600", children: ["\u2022 ", adjustment.description] }, adjIndex))) })] }))] }, index)))] }, offer.id))) })] }));
50
+ }
@@ -0,0 +1 @@
1
+ export { default as DebugDrawer } from './DebugDrawer';
@@ -0,0 +1 @@
1
+ export { default as DebugDrawer } from './DebugDrawer';
@@ -0,0 +1,22 @@
1
+ import { Environment, ApiConfig, EnvironmentConfig } from '../types';
2
+ /**
3
+ * Environment configurations for different deployment environments
4
+ */
5
+ export declare const ENVIRONMENT_CONFIGS: Record<Environment, ApiConfig>;
6
+ /**
7
+ * Get the environment configuration based on the current environment
8
+ */
9
+ export declare function getEnvironmentConfig(environment?: Environment): EnvironmentConfig;
10
+ /**
11
+ * Build a complete API URL from environment config and endpoint path
12
+ */
13
+ export declare function buildApiUrl(config: EnvironmentConfig, endpointPath: string): string;
14
+ /**
15
+ * Get a specific endpoint URL
16
+ */
17
+ export declare function getEndpointUrl(config: EnvironmentConfig, category: keyof ApiConfig['endpoints'], endpoint: string): string;
18
+ /**
19
+ * Auto-detect environment based on hostname, URL patterns, and deployment context
20
+ * Works with any build tool or deployment system
21
+ */
22
+ export declare function detectEnvironment(): Environment;