@instockng/storefront-ui 1.0.31 → 1.0.33

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 (276) hide show
  1. package/dist/components/Checkout.d.ts.map +1 -1
  2. package/dist/contexts/CartContext.d.ts.map +1 -1
  3. package/dist/hooks/usePaystackPayment.d.ts +2 -1
  4. package/dist/hooks/usePaystackPayment.d.ts.map +1 -1
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.mjs +99 -96
  8. package/dist/index10.mjs +85 -162
  9. package/dist/index100.mjs +210 -17
  10. package/dist/index101.mjs +174 -17
  11. package/dist/index102.mjs +14 -25
  12. package/dist/index103.mjs +17 -150
  13. package/dist/index104.mjs +26 -13
  14. package/dist/index105.mjs +149 -24
  15. package/dist/index106.mjs +13 -77
  16. package/dist/index107.mjs +20 -27
  17. package/dist/index108.mjs +76 -137
  18. package/dist/index109.mjs +33 -50
  19. package/dist/index11.mjs +171 -94
  20. package/dist/index110.mjs +141 -19
  21. package/dist/index111.mjs +50 -22
  22. package/dist/index112.mjs +14 -14
  23. package/dist/index113.mjs +20 -18
  24. package/dist/index114.mjs +16 -14
  25. package/dist/index115.mjs +17 -14
  26. package/dist/index116.mjs +12 -12
  27. package/dist/index117.mjs +15 -58
  28. package/dist/index118.mjs +14 -11
  29. package/dist/index119.mjs +56 -30
  30. package/dist/index12.mjs +82 -658
  31. package/dist/index120.mjs +9 -15
  32. package/dist/index121.mjs +31 -26
  33. package/dist/index122.mjs +13 -16
  34. package/dist/index123.mjs +26 -11
  35. package/dist/index124.mjs +18 -12
  36. package/dist/index125.mjs +12 -40
  37. package/dist/index126.mjs +14 -16
  38. package/dist/index127.mjs +42 -263
  39. package/dist/index128.mjs +15 -62
  40. package/dist/index129.mjs +267 -7
  41. package/dist/index13.mjs +668 -53
  42. package/dist/index130.mjs +70 -2
  43. package/dist/index131.mjs +8 -2
  44. package/dist/index132.mjs +2 -33
  45. package/dist/index133.mjs +2 -2
  46. package/dist/index134.mjs +32 -20
  47. package/dist/index135.mjs +2 -56
  48. package/dist/index136.mjs +18 -26
  49. package/dist/index137.mjs +55 -6
  50. package/dist/index138.mjs +28 -51
  51. package/dist/index139.mjs +7 -6
  52. package/dist/index14.mjs +58 -60
  53. package/dist/index140.mjs +51 -11
  54. package/dist/index141.mjs +5 -6
  55. package/dist/index142.mjs +12 -28
  56. package/dist/index143.mjs +7 -2
  57. package/dist/index144.mjs +27 -69
  58. package/dist/index145.mjs +2 -167
  59. package/dist/index146.mjs +70 -2
  60. package/dist/index147.mjs +167 -2
  61. package/dist/index149.mjs +2 -2
  62. package/dist/index15.mjs +60 -22
  63. package/dist/index150.mjs +2 -18
  64. package/dist/index151.mjs +11 -25
  65. package/dist/index152.mjs +26 -32
  66. package/dist/index153.mjs +32 -12
  67. package/dist/index154.mjs +9 -9
  68. package/dist/index155.mjs +18 -2
  69. package/dist/index156.mjs +2 -20
  70. package/dist/index157.mjs +13 -39
  71. package/dist/index158.mjs +46 -2
  72. package/dist/index159.mjs +2 -30
  73. package/dist/index16.mjs +22 -113
  74. package/dist/index160.mjs +24 -12
  75. package/dist/index161.mjs +18 -2
  76. package/dist/index162.mjs +2 -2
  77. package/dist/index163.mjs +2 -2
  78. package/dist/index164.mjs +2 -2
  79. package/dist/index165.mjs +2 -72
  80. package/dist/index166.mjs +72 -2
  81. package/dist/index167.mjs +2 -53
  82. package/dist/index168.mjs +53 -2
  83. package/dist/index169.mjs +2 -36
  84. package/dist/index17.mjs +111 -38
  85. package/dist/index170.mjs +30 -146
  86. package/dist/index171.mjs +152 -2
  87. package/dist/index172.mjs +2 -2
  88. package/dist/index173.mjs +2 -19
  89. package/dist/index174.mjs +19 -2
  90. package/dist/index175.mjs +2 -2
  91. package/dist/index176.mjs +2 -26
  92. package/dist/index177.mjs +26 -2
  93. package/dist/index178.mjs +2 -2
  94. package/dist/index179.mjs +2 -24
  95. package/dist/index18.mjs +37 -37
  96. package/dist/index180.mjs +17 -16
  97. package/dist/index181.mjs +23 -2
  98. package/dist/index183.mjs +2 -2
  99. package/dist/index184.mjs +2 -23
  100. package/dist/index185.mjs +23 -2
  101. package/dist/index186.mjs +2 -23
  102. package/dist/index187.mjs +23 -2
  103. package/dist/index188.mjs +2 -2
  104. package/dist/index19.mjs +42 -55
  105. package/dist/index190.mjs +2 -23
  106. package/dist/index191.mjs +23 -2
  107. package/dist/index192.mjs +2 -23
  108. package/dist/index193.mjs +23 -2
  109. package/dist/index194.mjs +2 -2
  110. package/dist/index195.mjs +2 -2
  111. package/dist/index197.mjs +2 -2
  112. package/dist/index198.mjs +2 -2
  113. package/dist/index199.mjs +2 -2
  114. package/dist/index2.mjs +14 -13
  115. package/dist/index20.mjs +53 -30
  116. package/dist/index200.mjs +2 -2
  117. package/dist/index201.mjs +2 -127
  118. package/dist/index202.mjs +127 -2
  119. package/dist/index203.mjs +2 -74
  120. package/dist/index204.mjs +60 -60
  121. package/dist/index205.mjs +73 -30
  122. package/dist/index206.mjs +2 -11
  123. package/dist/index207.mjs +30 -3
  124. package/dist/index208.mjs +10 -3
  125. package/dist/index209.mjs +4 -13
  126. package/dist/index21.mjs +29 -6
  127. package/dist/index210.mjs +4 -7
  128. package/dist/index211.mjs +13 -12
  129. package/dist/index212.mjs +7 -5
  130. package/dist/index213.mjs +12 -33
  131. package/dist/index214.mjs +5 -31
  132. package/dist/index215.mjs +32 -27
  133. package/dist/index216.mjs +28 -58
  134. package/dist/index217.mjs +28 -2
  135. package/dist/index218.mjs +61 -2
  136. package/dist/index219.mjs +2 -2
  137. package/dist/index22.mjs +8 -21
  138. package/dist/index220.mjs +2 -2
  139. package/dist/index221.mjs +2 -2
  140. package/dist/index222.mjs +2 -2
  141. package/dist/index223.mjs +2 -2
  142. package/dist/index224.mjs +2 -244
  143. package/dist/index226.mjs +2 -33
  144. package/dist/index227.mjs +28 -56
  145. package/dist/index228.mjs +2 -25
  146. package/dist/index229.mjs +2 -2
  147. package/dist/index23.mjs +19 -30
  148. package/dist/index230.mjs +243 -36
  149. package/dist/index232.mjs +33 -2
  150. package/dist/index233.mjs +65 -2
  151. package/dist/index234.mjs +25 -2
  152. package/dist/index235.mjs +2 -2
  153. package/dist/index236.mjs +108 -2
  154. package/dist/index237.mjs +2 -2
  155. package/dist/index238.mjs +2 -108
  156. package/dist/index239.mjs +2 -2
  157. package/dist/index24.mjs +31 -18
  158. package/dist/index241.mjs +2 -2
  159. package/dist/index242.mjs +2 -2
  160. package/dist/index244.mjs +2 -2
  161. package/dist/index245.mjs +2 -4
  162. package/dist/index246.mjs +2 -2
  163. package/dist/index247.mjs +4 -2
  164. package/dist/index248.mjs +2 -2
  165. package/dist/index249.mjs +2 -18
  166. package/dist/index25.mjs +12 -85
  167. package/dist/index250.mjs +3 -47
  168. package/dist/index251.mjs +2 -2
  169. package/dist/index252.mjs +2 -2
  170. package/dist/index253.mjs +17 -2
  171. package/dist/index254.mjs +13 -2
  172. package/dist/index255.mjs +6 -91
  173. package/dist/index256.mjs +30 -2
  174. package/dist/index257.mjs +2 -2
  175. package/dist/index258.mjs +18 -3
  176. package/dist/index259.mjs +47 -2
  177. package/dist/index26.mjs +85 -12
  178. package/dist/index260.mjs +2 -2
  179. package/dist/index261.mjs +2 -17
  180. package/dist/index262.mjs +2 -13
  181. package/dist/index263.mjs +2 -6
  182. package/dist/index264.mjs +91 -30
  183. package/dist/index265.mjs +2 -2
  184. package/dist/index266.mjs +2 -2
  185. package/dist/index268.mjs +5 -0
  186. package/dist/index269.mjs +5 -0
  187. package/dist/index27.mjs +18 -9
  188. package/dist/index28.mjs +9 -9
  189. package/dist/index29.mjs +11 -101
  190. package/dist/index3.mjs +104 -103
  191. package/dist/index30.mjs +101 -20
  192. package/dist/index31.mjs +20 -65
  193. package/dist/index32.mjs +66 -96
  194. package/dist/index33.mjs +93 -16
  195. package/dist/index34.mjs +13 -13
  196. package/dist/index35.mjs +17 -9
  197. package/dist/index36.mjs +9 -9
  198. package/dist/index37.mjs +10 -122
  199. package/dist/index38.mjs +116 -18
  200. package/dist/index39.mjs +342 -1386
  201. package/dist/index4.mjs +1 -1
  202. package/dist/index40.mjs +25 -2
  203. package/dist/index41.mjs +1425 -49
  204. package/dist/index42.mjs +2 -51
  205. package/dist/index43.mjs +60 -33
  206. package/dist/index44.mjs +49 -13
  207. package/dist/index45.mjs +32 -2262
  208. package/dist/index46.mjs +15 -36
  209. package/dist/index47.mjs +2261 -42
  210. package/dist/index48.mjs +36 -99
  211. package/dist/index49.mjs +43 -96
  212. package/dist/index5.mjs +110 -15
  213. package/dist/index50.mjs +99 -81
  214. package/dist/index51.mjs +93 -57
  215. package/dist/index52.mjs +54 -68
  216. package/dist/index53.mjs +58 -62
  217. package/dist/index54.mjs +74 -58
  218. package/dist/index55.mjs +77 -15
  219. package/dist/index56.mjs +75 -14
  220. package/dist/index57.mjs +15 -59
  221. package/dist/index58.mjs +11 -118
  222. package/dist/index59.mjs +46 -112
  223. package/dist/index6.mjs +15 -195
  224. package/dist/index60.mjs +124 -23
  225. package/dist/index61.mjs +129 -2
  226. package/dist/index62.mjs +4 -22
  227. package/dist/index63.mjs +19 -149
  228. package/dist/index64.mjs +20 -71
  229. package/dist/index65.mjs +153 -15
  230. package/dist/index66.mjs +2 -63
  231. package/dist/index67.mjs +74 -4
  232. package/dist/index68.mjs +15 -2
  233. package/dist/index69.mjs +62 -5
  234. package/dist/index7.mjs +188 -101
  235. package/dist/index70.mjs +230 -1129
  236. package/dist/index71.mjs +5 -19
  237. package/dist/index72.mjs +127 -48
  238. package/dist/index73.mjs +67 -32
  239. package/dist/index74.mjs +87 -2
  240. package/dist/index75.mjs +29 -2
  241. package/dist/index76.mjs +9 -235
  242. package/dist/index77.mjs +74 -5
  243. package/dist/index78.mjs +3 -133
  244. package/dist/index79.mjs +2 -68
  245. package/dist/index8.mjs +103 -73
  246. package/dist/index80.mjs +79 -83
  247. package/dist/index81.mjs +52 -27
  248. package/dist/index82.mjs +5 -8
  249. package/dist/index83.mjs +4 -74
  250. package/dist/index84.mjs +178 -3
  251. package/dist/index85.mjs +53 -2
  252. package/dist/index86.mjs +68 -82
  253. package/dist/index87.mjs +2 -54
  254. package/dist/index88.mjs +5 -5
  255. package/dist/index89.mjs +1133 -4
  256. package/dist/index9.mjs +72 -90
  257. package/dist/index90.mjs +18 -177
  258. package/dist/index91.mjs +52 -50
  259. package/dist/index92.mjs +33 -69
  260. package/dist/index93.mjs +2 -34
  261. package/dist/index94.mjs +31 -40
  262. package/dist/index95.mjs +43 -2
  263. package/dist/index96.mjs +2 -28
  264. package/dist/index97.mjs +2 -18
  265. package/dist/index98.mjs +26 -213
  266. package/dist/index99.mjs +13 -175
  267. package/dist/providers/StorefrontProvider.d.ts.map +1 -1
  268. package/dist/providers/TikTokPixelProvider.d.ts +22 -0
  269. package/dist/providers/TikTokPixelProvider.d.ts.map +1 -0
  270. package/package.json +3 -2
  271. package/src/components/Checkout.tsx +1 -0
  272. package/src/contexts/CartContext.tsx +17 -6
  273. package/src/hooks/usePaystackPayment.ts +8 -1
  274. package/src/index.ts +5 -0
  275. package/src/providers/StorefrontProvider.tsx +11 -8
  276. package/src/providers/TikTokPixelProvider.tsx +226 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instockng/storefront-ui",
3
- "version": "1.0.31",
3
+ "version": "1.0.33",
4
4
  "description": "Pre-built UI components for OMS e-commerce sites",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -45,11 +45,12 @@
45
45
  "author": "Ola Wale",
46
46
  "license": "MIT",
47
47
  "dependencies": {
48
- "@instockng/api-client": "^1.0.12",
48
+ "@instockng/api-client": "^1.0.16",
49
49
  "class-variance-authority": "^0.7.1",
50
50
  "clsx": "^2.1.0",
51
51
  "react-facebook-pixel": "^1.0.4",
52
52
  "tailwind-merge": "^2.2.0",
53
+ "tiktok-pixel": "^2.0.3",
53
54
  "yup": "^1.7.1"
54
55
  },
55
56
  "peerDependencies": {
@@ -153,6 +153,7 @@ export function Checkout({
153
153
 
154
154
  // Paystack payment integration
155
155
  const paystack = usePaystackPayment({
156
+ isOpen,
156
157
  publicKey: paystackPublicKey || '',
157
158
  onSuccess: async (response) => {
158
159
 
@@ -23,6 +23,7 @@ import {
23
23
  } from '@instockng/api-client';
24
24
  import { ShoppingCart } from '../components/ShoppingCart';
25
25
  import { useMetaPixel } from '../providers/MetaPixelProvider';
26
+ import { useTikTokPixel } from '../providers/TikTokPixelProvider';
26
27
  import { getFbCookies } from '../lib/utils';
27
28
 
28
29
  const CART_ID_KEY = 'oms_cart_id';
@@ -95,7 +96,10 @@ export function CartProvider({ children, brandSlug, initialCartId, shoppingCartP
95
96
  const isHandlingErrorRef = useRef(false);
96
97
 
97
98
  // Get Meta Pixel tracking methods
98
- const { trackAddToCart, trackInitiateCheckout } = useMetaPixel();
99
+ const { trackAddToCart: trackMetaAddToCart, trackInitiateCheckout: trackMetaInitiateCheckout } = useMetaPixel();
100
+
101
+ // Get TikTok Pixel tracking methods
102
+ const { trackAddToCart: trackTikTokAddToCart, trackInitiateCheckout: trackTikTokInitiateCheckout } = useTikTokPixel();
99
103
 
100
104
  // Set mounted flag on client
101
105
  useEffect(() => {
@@ -256,14 +260,18 @@ export function CartProvider({ children, brandSlug, initialCartId, shoppingCartP
256
260
  const eventID = `cart_${cartId}_item_${addedItem.id}`;
257
261
 
258
262
  // Track AddToCart event with Meta Pixel and matching event ID
259
- trackAddToCart(productSlug, productName, price, quantity, eventID);
263
+ trackMetaAddToCart(productSlug, productName, price, quantity, eventID);
264
+
265
+ // Track AddToCart event with TikTok Pixel and matching event ID
266
+ trackTikTokAddToCart(productSlug, productName, price, quantity, eventID);
260
267
  } else {
261
268
  // Fallback without event ID if item not found
262
- trackAddToCart(productSlug, productName, price, quantity);
269
+ trackMetaAddToCart(productSlug, productName, price, quantity);
270
+ trackTikTokAddToCart(productSlug, productName, price, quantity);
263
271
  }
264
272
  },
265
273
  // eslint-disable-next-line react-hooks/exhaustive-deps
266
- [cartId, trackAddToCart]
274
+ [cartId, trackMetaAddToCart, trackTikTokAddToCart]
267
275
  );
268
276
 
269
277
  const updateItem = useCallback(
@@ -335,8 +343,11 @@ export function CartProvider({ children, brandSlug, initialCartId, shoppingCartP
335
343
  const eventID = `cart_${cartId}_checkout`;
336
344
 
337
345
  // Track InitiateCheckout event with Meta Pixel
338
- trackInitiateCheckout(cartTotal, itemCount, eventID);
339
- }, [cart, cartId, trackInitiateCheckout]);
346
+ trackMetaInitiateCheckout(cartTotal, itemCount, eventID);
347
+
348
+ // Track InitiateCheckout event with TikTok Pixel
349
+ trackTikTokInitiateCheckout(cartTotal, itemCount, eventID);
350
+ }, [cart, cartId, trackMetaInitiateCheckout, trackTikTokInitiateCheckout]);
340
351
 
341
352
  const value: CartContextValue = {
342
353
  cart: cart || null,
@@ -48,12 +48,14 @@ export interface PaystackResponse {
48
48
  }
49
49
 
50
50
  export interface UsePaystackPaymentOptions {
51
+ isOpen: boolean;
51
52
  publicKey: string;
52
53
  onSuccess?: (response: PaystackResponse) => void;
53
54
  onClose?: () => void;
54
55
  }
55
56
 
56
57
  export function usePaystackPayment({
58
+ isOpen,
57
59
  publicKey,
58
60
  onSuccess,
59
61
  onClose,
@@ -64,6 +66,11 @@ export function usePaystackPayment({
64
66
 
65
67
  // Load Paystack Inline script
66
68
  useEffect(() => {
69
+
70
+ if (!isOpen) {
71
+ return;
72
+ }
73
+
67
74
  // Check if script is already loaded
68
75
  if (window.PaystackPop) {
69
76
  setIsLoaded(true);
@@ -93,7 +100,7 @@ export function usePaystackPayment({
93
100
  return () => {
94
101
  // Don't remove script on unmount as it can be reused
95
102
  };
96
- }, []);
103
+ }, [isOpen]);
97
104
 
98
105
  const initializePayment = useCallback(
99
106
  (config: Omit<PaystackConfig, 'key' | 'callback' | 'onClose'>) => {
package/src/index.ts CHANGED
@@ -14,6 +14,11 @@ export { CartProvider, useCart } from './contexts/CartContext';
14
14
  // Export Meta Pixel tracking
15
15
  export { useMetaPixel, MetaPixelProvider } from './providers/MetaPixelProvider';
16
16
  export type { MetaPixelProviderProps, PurchaseItem } from './providers/MetaPixelProvider';
17
+
18
+ // Export TikTok Pixel tracking
19
+ export { useTikTokPixel, TikTokPixelProvider } from './providers/TikTokPixelProvider';
20
+
21
+ // Export page tracking hook
17
22
  export { usePageTracking } from './hooks/usePageTracking';
18
23
 
19
24
  // Export main components
@@ -29,6 +29,7 @@ import { ReactNode } from 'react';
29
29
  import { ApiClientProvider, useGetBrand } from '@instockng/api-client';
30
30
  import { CartProvider, CartProviderProps } from '../contexts/CartContext';
31
31
  import { MetaPixelProvider } from './MetaPixelProvider';
32
+ import { TikTokPixelProvider } from './TikTokPixelProvider';
32
33
 
33
34
  export interface StorefrontProviderProps {
34
35
  /** Your children components */
@@ -44,7 +45,7 @@ export interface StorefrontProviderProps {
44
45
  }
45
46
 
46
47
  /**
47
- * Internal component that fetches brand config and wraps children with MetaPixelProvider
48
+ * Internal component that fetches brand config and wraps children with MetaPixelProvider and TikTokPixelProvider
48
49
  */
49
50
  function StorefrontProviderInner({
50
51
  children,
@@ -56,13 +57,15 @@ function StorefrontProviderInner({
56
57
 
57
58
  return (
58
59
  <MetaPixelProvider pixelId={brand?.metaPixelId}>
59
- <CartProvider
60
- brandSlug={brandSlug}
61
- initialCartId={initialCartId}
62
- shoppingCartProps={shoppingCartProps}
63
- >
64
- {children}
65
- </CartProvider>
60
+ <TikTokPixelProvider pixelId={brand?.tiktokPixelId}>
61
+ <CartProvider
62
+ brandSlug={brandSlug}
63
+ initialCartId={initialCartId}
64
+ shoppingCartProps={shoppingCartProps}
65
+ >
66
+ {children}
67
+ </CartProvider>
68
+ </TikTokPixelProvider>
66
69
  </MetaPixelProvider>
67
70
  );
68
71
  }
@@ -0,0 +1,226 @@
1
+ 'use client';
2
+
3
+ import React, {
4
+ createContext,
5
+ useContext,
6
+ useEffect,
7
+ useState,
8
+ type ReactNode,
9
+ } from 'react';
10
+
11
+ interface TikTokPixelContextType {
12
+ track: (event: string, data?: Record<string, unknown>, eventID?: string) => void;
13
+ trackPageView: () => void;
14
+ trackProductView: (
15
+ productId: string,
16
+ productName: string,
17
+ price: number,
18
+ eventID?: string
19
+ ) => void;
20
+ trackAddToCart: (
21
+ productId: string,
22
+ productName: string,
23
+ price: number,
24
+ quantity: number,
25
+ eventID?: string
26
+ ) => void;
27
+ trackInitiateCheckout: (cartTotal: number, itemCount: number, eventID?: string) => void;
28
+ trackPurchase: (
29
+ orderTotal: number,
30
+ currency: string,
31
+ orderId: string,
32
+ items: Array<{ id: string; quantity: number; item_price: number }>,
33
+ eventID?: string
34
+ ) => void;
35
+ }
36
+
37
+ const TikTokPixelContext = createContext<TikTokPixelContextType | undefined>(undefined);
38
+
39
+ interface TikTokPixelProviderProps {
40
+ children: ReactNode;
41
+ pixelId?: string;
42
+ debug?: boolean;
43
+ }
44
+
45
+ let ttqInstance: any = null;
46
+
47
+ export function TikTokPixelProvider({
48
+ children,
49
+ pixelId,
50
+ debug = false,
51
+ }: TikTokPixelProviderProps) {
52
+ const [isInitialized, setIsInitialized] = useState(false);
53
+
54
+ useEffect(() => {
55
+ // Only run on client side
56
+ if (typeof window === 'undefined') return;
57
+ if (!pixelId) {
58
+ if (debug) {
59
+ console.log('TikTok Pixel ID not provided. Tracking disabled.');
60
+ }
61
+ return;
62
+ }
63
+
64
+ // Initialize TikTok Pixel
65
+ const initTikTokPixel = async () => {
66
+ try {
67
+ // Dynamically import tiktok-pixel to avoid SSR issues
68
+ const TikTokPixel = (await import('tiktok-pixel')).default;
69
+
70
+ // Initialize pixel
71
+ TikTokPixel.init(pixelId, {}, { debug });
72
+
73
+ // Track initial page view
74
+ TikTokPixel.pageView();
75
+
76
+ ttqInstance = TikTokPixel;
77
+ setIsInitialized(true);
78
+
79
+ if (debug) {
80
+ console.log('TikTok Pixel initialized:', pixelId);
81
+ }
82
+ } catch (error) {
83
+ console.error('Failed to initialize TikTok Pixel:', error);
84
+ }
85
+ };
86
+
87
+ initTikTokPixel();
88
+ }, [pixelId, debug]);
89
+
90
+ const track = (event: string, data?: Record<string, unknown>, eventID?: string) => {
91
+ if (!isInitialized || !ttqInstance) {
92
+ if (debug) {
93
+ console.log('TikTok Pixel not initialized. Event not tracked:', event);
94
+ }
95
+ return;
96
+ }
97
+
98
+ try {
99
+ const eventData = eventID ? { ...data, event_id: eventID } : data;
100
+ ttqInstance.track(event, eventData);
101
+
102
+ if (debug) {
103
+ console.log('TikTok Pixel tracked event:', event, eventData);
104
+ }
105
+ } catch (error) {
106
+ console.error('Failed to track TikTok Pixel event:', error);
107
+ }
108
+ };
109
+
110
+ const trackPageView = () => {
111
+ if (!isInitialized || !ttqInstance) return;
112
+
113
+ try {
114
+ ttqInstance.pageView();
115
+
116
+ if (debug) {
117
+ console.log('TikTok Pixel tracked page view');
118
+ }
119
+ } catch (error) {
120
+ console.error('Failed to track TikTok Pixel page view:', error);
121
+ }
122
+ };
123
+
124
+ const trackProductView = (
125
+ productId: string,
126
+ productName: string,
127
+ price: number,
128
+ eventID?: string
129
+ ) => {
130
+ track(
131
+ 'ViewContent',
132
+ {
133
+ content_type: 'product',
134
+ content_id: productId,
135
+ content_name: productName,
136
+ price: price,
137
+ currency: 'NGN',
138
+ },
139
+ eventID
140
+ );
141
+ };
142
+
143
+ const trackAddToCart = (
144
+ productId: string,
145
+ productName: string,
146
+ price: number,
147
+ quantity: number,
148
+ eventID?: string
149
+ ) => {
150
+ track(
151
+ 'AddToCart',
152
+ {
153
+ content_type: 'product',
154
+ content_id: productId,
155
+ content_name: productName,
156
+ price: price,
157
+ quantity: quantity,
158
+ currency: 'NGN',
159
+ },
160
+ eventID
161
+ );
162
+ };
163
+
164
+ const trackInitiateCheckout = (
165
+ cartTotal: number,
166
+ itemCount: number,
167
+ eventID?: string
168
+ ) => {
169
+ track(
170
+ 'InitiateCheckout',
171
+ {
172
+ content_type: 'product',
173
+ value: cartTotal,
174
+ currency: 'NGN',
175
+ num_items: itemCount,
176
+ },
177
+ eventID
178
+ );
179
+ };
180
+
181
+ const trackPurchase = (
182
+ orderTotal: number,
183
+ currency: string,
184
+ orderId: string,
185
+ items: Array<{ id: string; quantity: number; item_price: number }>,
186
+ eventID?: string
187
+ ) => {
188
+ track(
189
+ 'CompletePayment',
190
+ {
191
+ content_type: 'product',
192
+ value: orderTotal,
193
+ currency: currency,
194
+ contents: items.map((item) => ({
195
+ content_id: item.id,
196
+ quantity: item.quantity,
197
+ price: item.item_price,
198
+ })),
199
+ },
200
+ eventID
201
+ );
202
+ };
203
+
204
+ const contextValue: TikTokPixelContextType = {
205
+ track,
206
+ trackPageView,
207
+ trackProductView,
208
+ trackAddToCart,
209
+ trackInitiateCheckout,
210
+ trackPurchase,
211
+ };
212
+
213
+ return (
214
+ <TikTokPixelContext.Provider value={contextValue}>
215
+ {children}
216
+ </TikTokPixelContext.Provider>
217
+ );
218
+ }
219
+
220
+ export function useTikTokPixel(): TikTokPixelContextType {
221
+ const context = useContext(TikTokPixelContext);
222
+ if (context === undefined) {
223
+ throw new Error('useTikTokPixel must be used within a TikTokPixelProvider');
224
+ }
225
+ return context;
226
+ }