tf-checkout-react 1.7.30 → 2.0.0-beta.0

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 (453) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +141 -1033
  3. package/dist/checkout.css +17 -0
  4. package/dist/index.d.mts +3930 -0
  5. package/dist/index.d.ts +3930 -30
  6. package/dist/index.esm.js +9123 -0
  7. package/dist/index.esm.js.map +1 -0
  8. package/dist/index.js +9277 -6
  9. package/dist/index.js.map +1 -0
  10. package/dist/styles/addons.css +75 -0
  11. package/dist/styles/auth.css +294 -0
  12. package/dist/styles/billing.css +98 -0
  13. package/dist/styles/confirmation.css +51 -0
  14. package/dist/styles/foundation.css +146 -0
  15. package/dist/styles/payment.css +179 -0
  16. package/dist/styles/primitives.css +356 -0
  17. package/dist/styles/seat-map.css +46 -0
  18. package/dist/styles/tickets.css +285 -0
  19. package/dist/styles/verification-confirmation.css +258 -0
  20. package/package.json +93 -78
  21. package/src/.d.ts +1 -1
  22. package/src/CardInput.tsx +374 -0
  23. package/src/EmbeddedCheckout.tsx +400 -0
  24. package/src/ResumedCheckout.tsx +132 -0
  25. package/src/auth/AuthModal.tsx +231 -0
  26. package/src/auth/ForgotPasswordForm.tsx +93 -0
  27. package/src/auth/LoginForm.tsx +104 -0
  28. package/src/auth/PasswordInput.tsx +33 -0
  29. package/src/auth/RegisterForm.tsx +333 -0
  30. package/src/auth/ResetPasswordForm.tsx +112 -0
  31. package/src/auth/index.ts +5 -0
  32. package/src/checkout.css +17 -0
  33. package/src/configure.ts +29 -0
  34. package/src/confirmer.ts +439 -0
  35. package/src/index.ts +41 -30
  36. package/src/instance.ts +21 -0
  37. package/src/sections/AddOns.tsx +241 -0
  38. package/src/sections/BillingInfo.tsx +743 -0
  39. package/src/sections/Confirmation.tsx +146 -0
  40. package/src/sections/IDVerification.tsx +76 -0
  41. package/src/sections/OrderConfirmation.tsx +277 -0
  42. package/src/sections/OrderIDVerification.tsx +117 -0
  43. package/src/sections/OrderSummary.tsx +84 -0
  44. package/src/sections/Payment.tsx +541 -0
  45. package/src/sections/SeatMap.tsx +512 -0
  46. package/src/sections/Tickets.tsx +573 -0
  47. package/src/sections/billing/BillingAddressFields.tsx +138 -0
  48. package/src/sections/billing/BuyerField.tsx +75 -0
  49. package/src/sections/billing/TicketHoldersCard.tsx +119 -0
  50. package/src/sections/billing/types.ts +10 -0
  51. package/src/sections/index.ts +15 -0
  52. package/src/sections/seatMap.utils.ts +105 -0
  53. package/src/styles/addons.css +75 -0
  54. package/src/styles/auth.css +294 -0
  55. package/src/styles/billing.css +98 -0
  56. package/src/styles/confirmation.css +51 -0
  57. package/src/styles/foundation.css +146 -0
  58. package/src/styles/payment.css +179 -0
  59. package/src/styles/primitives.css +356 -0
  60. package/src/styles/seat-map.css +46 -0
  61. package/src/styles/tickets.css +285 -0
  62. package/src/styles/verification-confirmation.css +258 -0
  63. package/src/typings.d.ts +2 -2
  64. package/src/ui/Button.tsx +38 -0
  65. package/src/ui/Card.tsx +54 -0
  66. package/src/ui/CheckoutProvider.tsx +172 -0
  67. package/src/ui/CustomFields.tsx +195 -0
  68. package/src/ui/Field.tsx +114 -0
  69. package/src/ui/I18nProvider.tsx +36 -0
  70. package/src/ui/InstallmentPicker.tsx +69 -0
  71. package/src/ui/Loader.tsx +12 -0
  72. package/src/ui/PaymentMethods.tsx +133 -0
  73. package/src/ui/PriceLine.tsx +24 -0
  74. package/src/ui/QuantitySelect.tsx +50 -0
  75. package/src/ui/Stepper.tsx +36 -0
  76. package/src/ui/Timer.tsx +34 -0
  77. package/src/ui/TimerBanner.tsx +55 -0
  78. package/src/ui/cx.ts +3 -0
  79. package/src/ui/index.ts +54 -0
  80. package/src/ui/theme.ts +83 -0
  81. package/src/useCheckout.ts +35 -0
  82. package/src/xendit.ts +438 -0
  83. package/dist/adapters/customFields.d.ts +0 -12
  84. package/dist/adapters/index.d.ts +0 -1
  85. package/dist/api/auth.d.ts +0 -27
  86. package/dist/api/cart.d.ts +0 -2
  87. package/dist/api/checkout.d.ts +0 -3
  88. package/dist/api/common.d.ts +0 -11
  89. package/dist/api/guestTicketDelegation.d.ts +0 -47
  90. package/dist/api/index.d.ts +0 -82
  91. package/dist/api/interceptors.d.ts +0 -1
  92. package/dist/api/orders.d.ts +0 -2
  93. package/dist/api/payment.d.ts +0 -5
  94. package/dist/api/preRegistrationComplete.d.ts +0 -3
  95. package/dist/api/publicRequest.d.ts +0 -9
  96. package/dist/api/resale.d.ts +0 -5
  97. package/dist/components/account-settings/index.d.ts +0 -3
  98. package/dist/components/addonsContainer/AddonComponent.d.ts +0 -18
  99. package/dist/components/addonsContainer/SimpleAddonsContainer.d.ts +0 -20
  100. package/dist/components/addonsContainer/adapters/index.d.ts +0 -12
  101. package/dist/components/addonsContainer/index.d.ts +0 -22
  102. package/dist/components/addonsContainer/normalizers/index.d.ts +0 -1
  103. package/dist/components/addonsContainer/useAddons.d.ts +0 -23
  104. package/dist/components/addonsContainer/utils/index.d.ts +0 -16
  105. package/dist/components/billing-info-container/hooks/index.d.ts +0 -3
  106. package/dist/components/billing-info-container/hooks/usePaymentContext.d.ts +0 -5
  107. package/dist/components/billing-info-container/hooks/usePaymentRedirect.d.ts +0 -14
  108. package/dist/components/billing-info-container/hooks/useStripePayment.d.ts +0 -18
  109. package/dist/components/billing-info-container/index.d.ts +0 -69
  110. package/dist/components/billing-info-container/utils.d.ts +0 -59
  111. package/dist/components/common/Checkbox.d.ts +0 -11
  112. package/dist/components/common/CheckboxField/index.d.ts +0 -9
  113. package/dist/components/common/CopyField.d.ts +0 -12
  114. package/dist/components/common/CopyMessageModal.d.ts +0 -7
  115. package/dist/components/common/CustomField.d.ts +0 -26
  116. package/dist/components/common/DatePickerField.d.ts +0 -20
  117. package/dist/components/common/FieldSection/index.d.ts +0 -19
  118. package/dist/components/common/FieldSection/utils/index.d.ts +0 -8
  119. package/dist/components/common/FormikPhoneNumberField.d.ts +0 -11
  120. package/dist/components/common/Loader.d.ts +0 -2
  121. package/dist/components/common/ModalComponent/index.d.ts +0 -16
  122. package/dist/components/common/NativeSelectFeild/index.d.ts +0 -21
  123. package/dist/components/common/PhoneNumberField.d.ts +0 -14
  124. package/dist/components/common/PoweredBy.d.ts +0 -2
  125. package/dist/components/common/RadioField.d.ts +0 -11
  126. package/dist/components/common/RadioGroupField/index.d.ts +0 -17
  127. package/dist/components/common/RedirectModal.d.ts +0 -7
  128. package/dist/components/common/SelectField/index.d.ts +0 -19
  129. package/dist/components/common/SnackbarAlert.d.ts +0 -13
  130. package/dist/components/common/index.d.ts +0 -11
  131. package/dist/components/common/socials.d.ts +0 -10
  132. package/dist/components/confirmModal/index.d.ts +0 -10
  133. package/dist/components/confirmationContainer/config.d.ts +0 -1
  134. package/dist/components/confirmationContainer/index.d.ts +0 -46
  135. package/dist/components/confirmationContainer/social-buttons.d.ts +0 -16
  136. package/dist/components/countdown/index.d.ts +0 -14
  137. package/dist/components/delegationsContainer/IssueComponent.d.ts +0 -10
  138. package/dist/components/delegationsContainer/IssueTicketForm.d.ts +0 -9
  139. package/dist/components/delegationsContainer/TicketsAssignedTable.d.ts +0 -11
  140. package/dist/components/delegationsContainer/TicketsAvailableTable.d.ts +0 -11
  141. package/dist/components/delegationsContainer/index.d.ts +0 -10
  142. package/dist/components/forgotPasswordModal/index.d.ts +0 -12
  143. package/dist/components/idVerificationContainer/VerificationPendingModal.d.ts +0 -10
  144. package/dist/components/idVerificationContainer/constants.d.ts +0 -21
  145. package/dist/components/idVerificationContainer/index.d.ts +0 -16
  146. package/dist/components/index.d.ts +0 -12
  147. package/dist/components/loginForm/index.d.ts +0 -31
  148. package/dist/components/loginModal/SignUpForm.d.ts +0 -10
  149. package/dist/components/loginModal/constants.d.ts +0 -39
  150. package/dist/components/loginModal/index.d.ts +0 -22
  151. package/dist/components/myTicketsContainer/index.d.ts +0 -16
  152. package/dist/components/myTicketsContainer/row.d.ts +0 -3
  153. package/dist/components/myTicketsContainer/tableConfig.d.ts +0 -5
  154. package/dist/components/orderDetailsContainer/CustomFieldsForm.d.ts +0 -12
  155. package/dist/components/orderDetailsContainer/TicketHolderCustomFields.d.ts +0 -10
  156. package/dist/components/orderDetailsContainer/index.d.ts +0 -66
  157. package/dist/components/orderDetailsContainer/ticketsTable.d.ts +0 -46
  158. package/dist/components/orderDetailsContainer/utils/index.d.ts +0 -6
  159. package/dist/components/paymentContainer/OrderDetails.d.ts +0 -9
  160. package/dist/components/paymentContainer/PaymentPlanSection.d.ts +0 -10
  161. package/dist/components/paymentContainer/handlePayment.d.ts +0 -15
  162. package/dist/components/paymentContainer/index.d.ts +0 -39
  163. package/dist/components/preRegistration/FieldsSection.d.ts +0 -19
  164. package/dist/components/preRegistration/Influancers.d.ts +0 -2
  165. package/dist/components/preRegistration/PreRegistrationComplete.d.ts +0 -13
  166. package/dist/components/preRegistration/PreRegistrationInformations.d.ts +0 -2
  167. package/dist/components/preRegistration/Prewards.d.ts +0 -2
  168. package/dist/components/preRegistration/ShareOptions.d.ts +0 -2
  169. package/dist/components/preRegistration/constants.d.ts +0 -2
  170. package/dist/components/preRegistration/index.d.ts +0 -23
  171. package/dist/components/preRegistration/utils.d.ts +0 -12
  172. package/dist/components/registerForm/adapters/index.d.ts +0 -4
  173. package/dist/components/registerForm/constants.d.ts +0 -1
  174. package/dist/components/registerForm/index.d.ts +0 -16
  175. package/dist/components/registerModal/index.d.ts +0 -12
  176. package/dist/components/resetPasswordContainer/index.d.ts +0 -10
  177. package/dist/components/rsvpContainer/index.d.ts +0 -7
  178. package/dist/components/seatMapContainer/SeatMapComponent.d.ts +0 -8
  179. package/dist/components/seatMapContainer/TicketsSection.d.ts +0 -9
  180. package/dist/components/seatMapContainer/addToCart.d.ts +0 -14
  181. package/dist/components/seatMapContainer/index.d.ts +0 -2
  182. package/dist/components/seatMapContainer/utils.d.ts +0 -6
  183. package/dist/components/signupModal/index.d.ts +0 -12
  184. package/dist/components/ticketResale/index.d.ts +0 -12
  185. package/dist/components/ticketResaleModal/index.d.ts +0 -19
  186. package/dist/components/ticketsContainer/AccessCodeSection.d.ts +0 -7
  187. package/dist/components/ticketsContainer/InfoIcon.d.ts +0 -5
  188. package/dist/components/ticketsContainer/PromoCodeSection.d.ts +0 -15
  189. package/dist/components/ticketsContainer/ReferralLogic.d.ts +0 -5
  190. package/dist/components/ticketsContainer/TicketRow.d.ts +0 -13
  191. package/dist/components/ticketsContainer/TicketsSection.d.ts +0 -20
  192. package/dist/components/ticketsContainer/TimeSlotTicketRow.d.ts +0 -19
  193. package/dist/components/ticketsContainer/TimeSlotsSection.d.ts +0 -25
  194. package/dist/components/ticketsContainer/index.d.ts +0 -93
  195. package/dist/components/ticketsContainer/utils.d.ts +0 -13
  196. package/dist/components/timerWidget/index.d.ts +0 -16
  197. package/dist/components/waitingList/index.d.ts +0 -9
  198. package/dist/constants/index.d.ts +0 -7
  199. package/dist/env.d.ts +0 -16
  200. package/dist/hoc/CustomFields/index.d.ts +0 -3
  201. package/dist/hoc/index.d.ts +0 -1
  202. package/dist/hooks/index.d.ts +0 -1
  203. package/dist/hooks/useCookieListener.d.ts +0 -1
  204. package/dist/hooks/useEventListener.d.ts +0 -1
  205. package/dist/hooks/useLocalStorageListener.d.ts +0 -1
  206. package/dist/hooks/useOnline.d.ts +0 -1
  207. package/dist/hooks/usePixel.d.ts +0 -6
  208. package/dist/images/Polygon.png +0 -0
  209. package/dist/images/cross.svg +0 -44
  210. package/dist/images/done.svg +0 -3
  211. package/dist/images/edit.svg +0 -10
  212. package/dist/images/email.svg +0 -1
  213. package/dist/images/instagram.svg +0 -5
  214. package/dist/images/logo-ttf.png +0 -0
  215. package/dist/images/spotify.svg +0 -6
  216. package/dist/images/user.svg +0 -1
  217. package/dist/images/xmark.svg +0 -92
  218. package/dist/normalizers/index.d.ts +0 -4
  219. package/dist/tf-checkout-react.cjs.development.js +0 -16149
  220. package/dist/tf-checkout-react.cjs.development.js.map +0 -1
  221. package/dist/tf-checkout-react.cjs.production.min.js +0 -2
  222. package/dist/tf-checkout-react.cjs.production.min.js.map +0 -1
  223. package/dist/tf-checkout-react.esm.js +0 -16116
  224. package/dist/tf-checkout-react.esm.js.map +0 -1
  225. package/dist/tf-checkout-styles.css +0 -1
  226. package/dist/types/add_on.d.ts +0 -8
  227. package/dist/types/billing-info-data.d.ts +0 -27
  228. package/dist/types/checkoutPageConfigs.d.ts +0 -13
  229. package/dist/types/index.d.ts +0 -6
  230. package/dist/types/order-data.d.ts +0 -15
  231. package/dist/types/payment-field.d.ts +0 -6
  232. package/dist/types/payment-plan-configuration.d.ts +0 -18
  233. package/dist/types/referral-promotion.d.ts +0 -6
  234. package/dist/types/verification.d.ts +0 -12
  235. package/dist/utils/adaptStripeErrors.d.ts +0 -8
  236. package/dist/utils/auth.d.ts +0 -21
  237. package/dist/utils/cookies.d.ts +0 -3
  238. package/dist/utils/createCheckoutDataBodyWithDefaultHolder.d.ts +0 -23
  239. package/dist/utils/createMarkup.d.ts +0 -3
  240. package/dist/utils/customFields.d.ts +0 -35
  241. package/dist/utils/downloadPDF.d.ts +0 -1
  242. package/dist/utils/form.d.ts +0 -3
  243. package/dist/utils/formikErrorFocus.d.ts +0 -2
  244. package/dist/utils/getDomain.d.ts +0 -1
  245. package/dist/utils/getImage.d.ts +0 -1
  246. package/dist/utils/getQueryVariable.d.ts +0 -1
  247. package/dist/utils/htmlNodeFromString.d.ts +0 -1
  248. package/dist/utils/index.d.ts +0 -15
  249. package/dist/utils/isBrowser.d.ts +0 -1
  250. package/dist/utils/isValidNumber.d.ts +0 -1
  251. package/dist/utils/jsonUtils.d.ts +0 -1
  252. package/dist/utils/replaceVarInString.d.ts +0 -1
  253. package/dist/utils/setConfigs.d.ts +0 -11
  254. package/dist/utils/showZero.d.ts +0 -1
  255. package/dist/validators/index.d.ts +0 -8
  256. package/src/adapters/customFields.ts +0 -85
  257. package/src/adapters/index.ts +0 -1
  258. package/src/api/auth.ts +0 -88
  259. package/src/api/cart.ts +0 -28
  260. package/src/api/checkout.ts +0 -28
  261. package/src/api/common.ts +0 -190
  262. package/src/api/guestTicketDelegation.ts +0 -79
  263. package/src/api/index.ts +0 -346
  264. package/src/api/interceptors.ts +0 -77
  265. package/src/api/orders.ts +0 -30
  266. package/src/api/payment.ts +0 -77
  267. package/src/api/preRegistrationComplete.ts +0 -37
  268. package/src/api/publicRequest.ts +0 -47
  269. package/src/api/resale.ts +0 -28
  270. package/src/assets/images/Polygon.png +0 -0
  271. package/src/assets/images/cross.svg +0 -44
  272. package/src/assets/images/done.svg +0 -3
  273. package/src/assets/images/edit.svg +0 -10
  274. package/src/assets/images/email.svg +0 -1
  275. package/src/assets/images/instagram.svg +0 -5
  276. package/src/assets/images/logo-ttf.png +0 -0
  277. package/src/assets/images/spotify.svg +0 -6
  278. package/src/assets/images/user.svg +0 -1
  279. package/src/assets/images/xmark.svg +0 -92
  280. package/src/components/account-settings/index.tsx +0 -161
  281. package/src/components/account-settings/style.css +0 -200
  282. package/src/components/addonsContainer/AddonComponent.tsx +0 -204
  283. package/src/components/addonsContainer/SimpleAddonsContainer.tsx +0 -459
  284. package/src/components/addonsContainer/adapters/index.tsx +0 -62
  285. package/src/components/addonsContainer/index.tsx +0 -353
  286. package/src/components/addonsContainer/normalizers/index.ts +0 -5
  287. package/src/components/addonsContainer/useAddons.ts +0 -248
  288. package/src/components/addonsContainer/utils/index.tsx +0 -231
  289. package/src/components/billing-info-container/hooks/index.ts +0 -3
  290. package/src/components/billing-info-container/hooks/usePaymentContext.ts +0 -22
  291. package/src/components/billing-info-container/hooks/usePaymentRedirect.ts +0 -145
  292. package/src/components/billing-info-container/hooks/useStripePayment.ts +0 -119
  293. package/src/components/billing-info-container/index.tsx +0 -1695
  294. package/src/components/billing-info-container/style.css +0 -150
  295. package/src/components/billing-info-container/utils.tsx +0 -413
  296. package/src/components/common/Checkbox.tsx +0 -51
  297. package/src/components/common/CheckboxField/index.tsx +0 -41
  298. package/src/components/common/CopyField.tsx +0 -53
  299. package/src/components/common/CopyMessageModal.tsx +0 -34
  300. package/src/components/common/CustomField.tsx +0 -168
  301. package/src/components/common/DatePickerField.tsx +0 -126
  302. package/src/components/common/FieldSection/index.tsx +0 -141
  303. package/src/components/common/FieldSection/utils/index.tsx +0 -92
  304. package/src/components/common/FormikPhoneNumberField.tsx +0 -51
  305. package/src/components/common/Loader.tsx +0 -8
  306. package/src/components/common/ModalComponent/index.tsx +0 -68
  307. package/src/components/common/NativeSelectFeild/index.tsx +0 -86
  308. package/src/components/common/PhoneNumberField.tsx +0 -117
  309. package/src/components/common/PoweredBy.tsx +0 -15
  310. package/src/components/common/RadioField.tsx +0 -36
  311. package/src/components/common/RadioGroupField/index.tsx +0 -76
  312. package/src/components/common/RedirectModal.tsx +0 -43
  313. package/src/components/common/SelectField/index.tsx +0 -104
  314. package/src/components/common/SnackbarAlert.tsx +0 -52
  315. package/src/components/common/index.tsx +0 -11
  316. package/src/components/common/socials.tsx +0 -33
  317. package/src/components/confirmModal/index.tsx +0 -60
  318. package/src/components/confirmationContainer/config.ts +0 -79
  319. package/src/components/confirmationContainer/index.tsx +0 -349
  320. package/src/components/confirmationContainer/social-buttons.tsx +0 -149
  321. package/src/components/confirmationContainer/style.css +0 -206
  322. package/src/components/countdown/index.tsx +0 -100
  323. package/src/components/countdown/style.css +0 -10
  324. package/src/components/delegationsContainer/IssueComponent.tsx +0 -156
  325. package/src/components/delegationsContainer/IssueTicketForm.tsx +0 -109
  326. package/src/components/delegationsContainer/TicketsAssignedTable.tsx +0 -55
  327. package/src/components/delegationsContainer/TicketsAvailableTable.tsx +0 -54
  328. package/src/components/delegationsContainer/index.tsx +0 -83
  329. package/src/components/forgotPasswordModal/index.tsx +0 -138
  330. package/src/components/forgotPasswordModal/style.css +0 -47
  331. package/src/components/idVerificationContainer/VerificationPendingModal.tsx +0 -47
  332. package/src/components/idVerificationContainer/constants.ts +0 -27
  333. package/src/components/idVerificationContainer/index.tsx +0 -323
  334. package/src/components/index.ts +0 -12
  335. package/src/components/loginForm/index.tsx +0 -202
  336. package/src/components/loginModal/SignUpForm.tsx +0 -329
  337. package/src/components/loginModal/constants.ts +0 -46
  338. package/src/components/loginModal/index.tsx +0 -263
  339. package/src/components/loginModal/style.css +0 -116
  340. package/src/components/myTicketsContainer/index.tsx +0 -228
  341. package/src/components/myTicketsContainer/row.tsx +0 -46
  342. package/src/components/myTicketsContainer/style.css +0 -40
  343. package/src/components/myTicketsContainer/tableConfig.tsx +0 -80
  344. package/src/components/myTicketsContainer/types.d.ts +0 -41
  345. package/src/components/orderDetailsContainer/CustomFieldsForm.tsx +0 -75
  346. package/src/components/orderDetailsContainer/TicketHolderCustomFields.tsx +0 -100
  347. package/src/components/orderDetailsContainer/index.tsx +0 -586
  348. package/src/components/orderDetailsContainer/style.css +0 -77
  349. package/src/components/orderDetailsContainer/ticketsTable.tsx +0 -246
  350. package/src/components/orderDetailsContainer/utils/index.tsx +0 -55
  351. package/src/components/paymentContainer/OrderDetails.tsx +0 -277
  352. package/src/components/paymentContainer/PaymentPlanSection.tsx +0 -169
  353. package/src/components/paymentContainer/handlePayment.ts +0 -86
  354. package/src/components/paymentContainer/index.tsx +0 -643
  355. package/src/components/paymentContainer/style.css +0 -196
  356. package/src/components/preRegistration/FieldsSection.tsx +0 -150
  357. package/src/components/preRegistration/Influancers.tsx +0 -34
  358. package/src/components/preRegistration/PreRegistrationComplete.tsx +0 -186
  359. package/src/components/preRegistration/PreRegistrationInformations.tsx +0 -60
  360. package/src/components/preRegistration/Prewards.tsx +0 -41
  361. package/src/components/preRegistration/ShareOptions.tsx +0 -77
  362. package/src/components/preRegistration/constants.tsx +0 -169
  363. package/src/components/preRegistration/index.tsx +0 -330
  364. package/src/components/preRegistration/style.css +0 -3
  365. package/src/components/preRegistration/utils.ts +0 -163
  366. package/src/components/registerForm/adapters/index.tsx +0 -10
  367. package/src/components/registerForm/constants.tsx +0 -98
  368. package/src/components/registerForm/index.tsx +0 -188
  369. package/src/components/registerModal/index.tsx +0 -154
  370. package/src/components/registerModal/style.css +0 -18
  371. package/src/components/resetPasswordContainer/index.tsx +0 -102
  372. package/src/components/resetPasswordContainer/style.css +0 -36
  373. package/src/components/rsvpContainer/index.tsx +0 -126
  374. package/src/components/seatMapContainer/SeatMapComponent.tsx +0 -77
  375. package/src/components/seatMapContainer/TicketsSection.tsx +0 -286
  376. package/src/components/seatMapContainer/addToCart.ts +0 -66
  377. package/src/components/seatMapContainer/index.tsx +0 -443
  378. package/src/components/seatMapContainer/utils.ts +0 -133
  379. package/src/components/signupModal/index.tsx +0 -178
  380. package/src/components/signupModal/style.css +0 -58
  381. package/src/components/ticketResale/index.tsx +0 -86
  382. package/src/components/ticketResaleModal/index.tsx +0 -224
  383. package/src/components/ticketResaleModal/style.css +0 -28
  384. package/src/components/ticketsContainer/AccessCodeSection.tsx +0 -50
  385. package/src/components/ticketsContainer/InfoIcon.tsx +0 -35
  386. package/src/components/ticketsContainer/PromoCodeSection.tsx +0 -116
  387. package/src/components/ticketsContainer/ReferralLogic.tsx +0 -33
  388. package/src/components/ticketsContainer/TicketRow.tsx +0 -107
  389. package/src/components/ticketsContainer/TicketsSection.tsx +0 -350
  390. package/src/components/ticketsContainer/TimeSlotTicketRow.tsx +0 -243
  391. package/src/components/ticketsContainer/TimeSlotsSection.tsx +0 -194
  392. package/src/components/ticketsContainer/index.tsx +0 -986
  393. package/src/components/ticketsContainer/style.css +0 -178
  394. package/src/components/ticketsContainer/utils.ts +0 -35
  395. package/src/components/timerWidget/index.tsx +0 -97
  396. package/src/components/timerWidget/style.css +0 -35
  397. package/src/components/waitingList/index.tsx +0 -190
  398. package/src/components/waitingList/style.css +0 -27
  399. package/src/constants/index.ts +0 -3
  400. package/src/env.ts +0 -29
  401. package/src/hoc/CustomFields/index.tsx +0 -85
  402. package/src/hoc/index.ts +0 -1
  403. package/src/hooks/index.ts +0 -1
  404. package/src/hooks/useCookieListener.ts +0 -32
  405. package/src/hooks/useEventListener.ts +0 -32
  406. package/src/hooks/useLocalStorageListener.ts +0 -32
  407. package/src/hooks/useOnline.ts +0 -21
  408. package/src/hooks/usePixel.ts +0 -88
  409. package/src/normalizers/index.ts +0 -49
  410. package/src/types/add_on.ts +0 -8
  411. package/src/types/api/auth.d.ts +0 -63
  412. package/src/types/api/axiosResponse.d.ts +0 -6
  413. package/src/types/api/cart.d.ts +0 -73
  414. package/src/types/api/checkout.d.ts +0 -92
  415. package/src/types/api/common.d.ts +0 -153
  416. package/src/types/api/guestTicketDelegation.d.ts +0 -18
  417. package/src/types/api/orders.d.ts +0 -116
  418. package/src/types/api/payment.d.ts +0 -180
  419. package/src/types/api/preRegistration.d.ts +0 -11
  420. package/src/types/api/preRegistrationComplete.d.ts +0 -95
  421. package/src/types/api/ticketResale.d.ts +0 -13
  422. package/src/types/billing-info-data.ts +0 -37
  423. package/src/types/checkoutPageConfigs.ts +0 -13
  424. package/src/types/formFields.d.ts +0 -29
  425. package/src/types/index.ts +0 -6
  426. package/src/types/order-data.ts +0 -16
  427. package/src/types/payment-field.ts +0 -7
  428. package/src/types/payment-plan-configuration.ts +0 -19
  429. package/src/types/pre-registration-complete.d.ts +0 -47
  430. package/src/types/referral-promotion.ts +0 -7
  431. package/src/types/seatMap.d.ts +0 -159
  432. package/src/types/verification.ts +0 -12
  433. package/src/utils/adaptStripeErrors.ts +0 -26
  434. package/src/utils/auth.ts +0 -45
  435. package/src/utils/cookies.ts +0 -73
  436. package/src/utils/createCheckoutDataBodyWithDefaultHolder.ts +0 -81
  437. package/src/utils/createMarkup.ts +0 -1
  438. package/src/utils/customFields.ts +0 -80
  439. package/src/utils/downloadPDF.tsx +0 -42
  440. package/src/utils/form.ts +0 -34
  441. package/src/utils/formikErrorFocus.ts +0 -24
  442. package/src/utils/getDomain.ts +0 -21
  443. package/src/utils/getImage.ts +0 -14
  444. package/src/utils/getQueryVariable.ts +0 -13
  445. package/src/utils/htmlNodeFromString.ts +0 -6
  446. package/src/utils/index.ts +0 -15
  447. package/src/utils/isBrowser.ts +0 -2
  448. package/src/utils/isValidNumber.ts +0 -8
  449. package/src/utils/jsonUtils.ts +0 -8
  450. package/src/utils/replaceVarInString.ts +0 -9
  451. package/src/utils/setConfigs.ts +0 -24
  452. package/src/utils/showZero.tsx +0 -10
  453. package/src/validators/index.ts +0 -61
@@ -1,1695 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import './style.css'
3
-
4
- import { CircularProgress, ThemeOptions } from '@mui/material'
5
- import Backdrop from '@mui/material/Backdrop'
6
- import Button from '@mui/material/Button'
7
- import { createTheme, ThemeProvider } from '@mui/material/styles'
8
- import { CSSProperties } from '@mui/styles'
9
- import { Stripe, StripeElementsOptions } from '@stripe/stripe-js'
10
- import axios, { AxiosError } from 'axios'
11
- import { Field, Form, Formik, FormikHelpers, FormikProps, FormikValues } from 'formik'
12
- import _find from 'lodash/find'
13
- import _forEach from 'lodash/forEach'
14
- import _get from 'lodash/get'
15
- import _identity from 'lodash/identity'
16
- import _isEmpty from 'lodash/isEmpty'
17
- import _isEqual from 'lodash/isEqual'
18
- import _map from 'lodash/map'
19
- import { nanoid } from 'nanoid'
20
- import React, { FC, useCallback, useEffect, useRef, useState } from 'react'
21
-
22
- import {
23
- AttributesConfig,
24
- checkEmailExists,
25
- getCart,
26
- getCheckoutPageConfigs,
27
- getCountries,
28
- getPaymentData,
29
- getProfileData,
30
- getStates,
31
- postOnCheckout,
32
- setCustomHeader,
33
- } from '../../api'
34
- import { updateCheckout } from '../../api/checkout'
35
- import { withCustomFields } from '../../hoc'
36
- import { usePixel } from '../../hooks/usePixel'
37
- import { IBillingInfoData } from '../../types'
38
- import { ICheckoutResponseData } from '../../types/api/checkout'
39
- import {
40
- createCheckoutDataBodyWithDefaultHolder,
41
- deleteCookieByName,
42
- getCookieByName,
43
- isBrowser,
44
- setLoggedUserData,
45
- } from '../../utils'
46
- import { ErrorFocus } from '../../utils/formikErrorFocus'
47
- import { emailRegex } from '../../validators'
48
- import { AddonsContainter, IAddonContainterProps } from '../addonsContainer'
49
- import SimpleAddonsContainer from '../addonsContainer/SimpleAddonsContainer'
50
- import SnackbarAlert from '../common/SnackbarAlert'
51
- import { ForgotPasswordModal } from '../forgotPasswordModal'
52
- import { VerificationPendingModal } from '../idVerificationContainer/VerificationPendingModal'
53
- import { LoginModal } from '../loginModal'
54
- import { IPaymentPage, PaymentContainer } from '../paymentContainer'
55
- import { SignupModal } from '../signupModal'
56
- import TimerWidget from '../timerWidget'
57
- import { usePaymentRedirect, useStripePayment } from './hooks'
58
- import {
59
- assingUniqueIds,
60
- createCheckoutDataBody,
61
- filterBillingInfoFields,
62
- getFieldComponent,
63
- getFieldLabel,
64
- getInitialValues,
65
- getValidateFunctions,
66
- ICheckoutBody,
67
- renderComponentWithProps,
68
- } from './utils'
69
-
70
- export interface IBillingInfoPage {
71
- data?: IBillingInfoData[];
72
- ticketHoldersFields?: IBillingInfoData;
73
- handleSubmit?: (
74
- values: FormikValues,
75
- formikHelpers: FormikHelpers<FormikValues>,
76
- eventId: any,
77
- res: any,
78
- checkoutUpdateResponse?: any,
79
- paymentResponse?: any
80
- ) => void;
81
- onRegisterSuccess?: (value: any) => void;
82
- onRegisterError?: (e: AxiosError, email: string) => void;
83
- onSubmitError?: (e: AxiosError) => void;
84
- onGetCartSuccess?: (res: any) => void;
85
- onGetCartError?: (e: AxiosError) => void;
86
- onGetCountriesSuccess?: (res: any) => void;
87
- onGetCountriesError?: (e: AxiosError) => void;
88
- onGetStatesSuccess?: (res: any) => void;
89
- onGetStatesError?: (e: AxiosError) => void;
90
- onGetProfileDataSuccess?: (res: any) => void;
91
- onGetProfileDataError?: (e: AxiosError) => void;
92
- onGetCheckoutConfigsSuccess?: (res: any) => void;
93
- onGetCheckoutConfigsError?: (e: AxiosError) => void;
94
- onLogin?: () => void;
95
- onLoginSuccess?: () => void;
96
- onErrorClose?: () => void;
97
- onCheckoutUpdateSuccess?: (res: any) => void;
98
- onCheckoutUpdateError?: (e: AxiosError) => void;
99
- initialValues?: FormikValues;
100
- buttonName?: string;
101
- freeOrderButtonName?: string;
102
- theme?: 'light' | 'dark';
103
- isLoggedIn?: boolean;
104
- accountInfoTitle?: string | JSX.Element;
105
- hideLogo?: boolean;
106
- themeOptions?: ThemeOptions & {
107
- input?: CSSProperties;
108
- checkbox?: CSSProperties;
109
- };
110
- hideErrorsAlertSection?: boolean;
111
- onSkipBillingPage: (data: any) => void;
112
- skipPage?: boolean;
113
- canSkipHolderNames?: boolean;
114
- shouldFetchCountries?: boolean;
115
- onForgotPasswordSuccess?: (res: any) => void;
116
- onForgotPasswordError?: (e: AxiosError) => void;
117
- onCountdownFinish?: () => void;
118
- enableTimer?: boolean;
119
- logo?: string;
120
- showForgotPasswordButton?: boolean;
121
- showSignUpButton?: boolean;
122
- brandOptIn?: boolean;
123
- showPoweredByImage?: boolean;
124
- isCountryCodeEditable?: boolean;
125
- customFieldsOrderKeys?: string[];
126
- customFieldsTicketHolderKeys?: string[];
127
- onPendingVerification?: () => void;
128
- includeAddons?: boolean;
129
- addonsProps?: IAddonContainterProps;
130
- addOnDataWithCustomFields?: any;
131
- isSinglePageCheckout?: boolean;
132
- paymentProps?: Partial<IPaymentPage>;
133
- paymentSectionAddon?: React.ReactNode;
134
- }
135
-
136
- const LogicRunner: FC<{
137
- brandOptIn?: boolean;
138
- values: any;
139
- errors: any;
140
- setStates: React.Dispatch<any>;
141
- setFieldValue: any;
142
- setValues: any;
143
- setUserValues: any;
144
- onGetStatesSuccess: any;
145
- onGetStatesError: any;
146
- shouldFetchCountries: boolean;
147
- }> = ({
148
- values,
149
- setStates,
150
- setFieldValue,
151
- setValues,
152
- setUserValues,
153
- onGetStatesSuccess,
154
- onGetStatesError,
155
- shouldFetchCountries,
156
- brandOptIn,
157
- }) => {
158
- const prevCountry = useRef(values.country)
159
- const prevBuyerData = useRef({
160
- firstName: '',
161
- lastName: '',
162
- email: '',
163
- phone: '',
164
- })
165
- const hasLoadedUserData = useRef(false)
166
- useEffect(() => {
167
- const fetchStates = async () => {
168
- try {
169
- const res = await getStates(values.country)
170
- const mappedStates = _map(res.data, (item, key) => ({
171
- label: item,
172
- value: key,
173
- }))
174
- setStates(mappedStates)
175
- if (prevCountry.current !== values.country) {
176
- const stateExists = mappedStates.find(
177
- state => state.value === values.state
178
- )?.value
179
- setFieldValue('state', stateExists ?? mappedStates[0]?.value ?? '')
180
- prevCountry.current = values.country
181
- }
182
- onGetStatesSuccess(res.data)
183
- } catch (e) {
184
- if (axios.isAxiosError(e)) {
185
- onGetStatesError(e)
186
- }
187
- }
188
- }
189
- shouldFetchCountries && fetchStates()
190
- }, [values.country, setStates, setFieldValue])
191
-
192
- // Auto-fill first holder with buyer data
193
- useEffect(() => {
194
- const buyerFirstName = values.firstName || ''
195
- const buyerLastName = values.lastName || ''
196
- const buyerEmail = values.email || ''
197
- const buyerPhone = values.phone || ''
198
-
199
- // Check if any buyer data has changed
200
- const firstNameChanged = prevBuyerData.current.firstName !== buyerFirstName
201
- const lastNameChanged = prevBuyerData.current.lastName !== buyerLastName
202
- const emailChanged = prevBuyerData.current.email !== buyerEmail
203
- const phoneChanged = prevBuyerData.current.phone !== buyerPhone
204
-
205
- // Update holder fields individually based on what changed
206
- if (firstNameChanged) {
207
- setFieldValue('holderFirstName-0', buyerFirstName, false)
208
- prevBuyerData.current.firstName = buyerFirstName
209
- }
210
-
211
- if (lastNameChanged) {
212
- setFieldValue('holderLastName-0', buyerLastName, false)
213
- prevBuyerData.current.lastName = buyerLastName
214
- }
215
-
216
- if (emailChanged) {
217
- setFieldValue('holderEmail-0', buyerEmail, false)
218
- prevBuyerData.current.email = buyerEmail
219
- }
220
-
221
- if (phoneChanged) {
222
- setFieldValue('holderPhone-0', buyerPhone, false)
223
- prevBuyerData.current.phone = buyerPhone
224
- }
225
- }, [values.firstName, values.lastName, values.email, values.phone, setFieldValue])
226
-
227
- const userDataEncoded = isBrowser ? window.localStorage.getItem('user_data') : ''
228
- useEffect(() => {
229
- // set user data from local storage only on initial load
230
- const getStoredUserData = () => {
231
- if (isBrowser && userDataEncoded && !hasLoadedUserData.current) {
232
- try {
233
- const parsedData = JSON.parse(userDataEncoded)
234
- const mappedValues = {
235
- firstName: parsedData?.first_name || parsedData?.firstName || '',
236
- lastName: parsedData?.last_name || parsedData?.lastName || '',
237
- email: parsedData?.email || '',
238
- phone: parsedData?.phone || '',
239
- confirmEmail: parsedData?.email || '',
240
- state: parsedData?.state || '',
241
- street_address: parsedData?.street_address || '',
242
- country: parsedData?.country || '1',
243
- zip: parsedData?.zip || '',
244
- brand_opt_in: brandOptIn ? brandOptIn : parsedData?.brand_opt_in || false,
245
- city: parsedData?.city || '',
246
- confirmPassword: '',
247
- password: '',
248
- 'holderFirstName-0': parsedData?.first_name || parsedData?.firstName || '',
249
- 'holderLastName-0': parsedData?.last_name || parsedData?.lastName || '',
250
- 'holderEmail-0': parsedData?.email || '',
251
- 'holderPhone-0': parsedData?.phone || '',
252
- }
253
-
254
- const extraDataJSON = window.localStorage.getItem('extraData')
255
- const extraData = extraDataJSON ? JSON.parse(extraDataJSON) : null
256
-
257
- setValues({ ...values, ...mappedValues, ...(extraData ?? {}) })
258
- setUserValues(mappedValues)
259
- hasLoadedUserData.current = true
260
- } catch (e) {}
261
- }
262
- }
263
- getStoredUserData()
264
- // Only run on mount or when userDataEncoded first becomes available
265
- // eslint-disable-next-line react-hooks/exhaustive-deps
266
- }, [])
267
- return null
268
- }
269
-
270
- // Component to check if email exists
271
- /**
272
- * A utility component that checks if an email address already exists in the system.
273
- *
274
- * Performs debounced validation and existence checking for user email addresses.
275
- * Only checks when both email and confirmEmail match, are valid, and user is not logged in.
276
- *
277
- * @param email - The primary email address to check
278
- * @param confirmEmail - The confirmation email address (must match email)
279
- * @param isLoggedIn - Whether the user is currently logged in
280
- * @param setEmailExists - Callback function to update the email existence state
281
- *
282
- * @remarks
283
- * - Uses a 500ms debounce to avoid excessive API calls
284
- * - Validates email format using regex before checking existence
285
- * - Automatically returns false if user is logged in
286
- * - Returns null as it's a logic-only component with no UI
287
- */
288
- const EmailExistenceChecker: FC<{
289
- email: string;
290
- confirmEmail: string;
291
- isLoggedIn: boolean;
292
- setEmailExists: (exists: boolean) => void;
293
- }> = ({ email, confirmEmail, isLoggedIn, setEmailExists }) => {
294
- useEffect(() => {
295
- const checkEmail = async () => {
296
- // Don't check if user is logged in
297
- if (isLoggedIn) {
298
- setEmailExists(false)
299
- return
300
- }
301
-
302
- // Only check if both emails exist, match, and are valid
303
- if (!email || !confirmEmail || email !== confirmEmail || !emailRegex.test(email)) {
304
- setEmailExists(false)
305
- return
306
- }
307
-
308
- // Check if email exists
309
- try {
310
- const result = await checkEmailExists(email)
311
- setEmailExists(result.exists)
312
- } catch {
313
- setEmailExists(false)
314
- }
315
- }
316
-
317
- // Debounce the check
318
- const timeoutId = setTimeout(() => {
319
- checkEmail()
320
- }, 800)
321
-
322
- return () => clearTimeout(timeoutId)
323
- }, [email, confirmEmail, isLoggedIn, setEmailExists])
324
-
325
- return null
326
- }
327
-
328
- const BillingInfoContainer = React.memo(
329
- ({
330
- data = [],
331
- ticketHoldersFields = {
332
- id: 1,
333
- fields: [],
334
- },
335
- initialValues = {},
336
- buttonName = 'Submit',
337
- freeOrderButtonName = 'Complete Registration',
338
- handleSubmit = _identity,
339
- theme = 'light',
340
- onRegisterSuccess = _identity,
341
- onRegisterError = _identity,
342
- onSubmitError = _identity,
343
- onGetCartSuccess = _identity,
344
- onGetCartError = _identity,
345
- onGetCountriesSuccess = _identity,
346
- onGetCountriesError = _identity,
347
- onGetStatesSuccess = _identity,
348
- onGetStatesError = _identity,
349
- onGetProfileDataSuccess = _identity,
350
- onGetProfileDataError = _identity,
351
- onLogin,
352
- onLoginSuccess = _identity,
353
- onCheckoutUpdateSuccess = _identity,
354
- onCheckoutUpdateError = _identity,
355
- isLoggedIn: pIsLoggedIn = false,
356
- accountInfoTitle = '',
357
- hideLogo,
358
- themeOptions,
359
- onErrorClose = _identity,
360
- hideErrorsAlertSection = false,
361
- onSkipBillingPage = _identity,
362
- skipPage = false,
363
- canSkipHolderNames = false,
364
- onForgotPasswordSuccess = _identity,
365
- onForgotPasswordError = _identity,
366
- shouldFetchCountries = true,
367
- onCountdownFinish = _identity,
368
- enableTimer = false,
369
- logo,
370
- showForgotPasswordButton = true,
371
- showSignUpButton = false,
372
- brandOptIn = false,
373
- showPoweredByImage = false,
374
- customFieldsOrderKeys,
375
- customFieldsTicketHolderKeys,
376
- isCountryCodeEditable = true,
377
- onPendingVerification = _identity,
378
- onGetCheckoutConfigsSuccess = _identity,
379
- onGetCheckoutConfigsError = _identity,
380
- includeAddons = false,
381
- addonsProps,
382
- addOnDataWithCustomFields,
383
- isSinglePageCheckout = false,
384
- paymentProps = {},
385
- paymentSectionAddon,
386
- }: IBillingInfoPage) => {
387
- const [extraData, setExtraData] = useState(null)
388
- const [isConfigLoading, setIsConfigLoading] = useState(true)
389
- const [configs, setConfigs] = useState<null | AttributesConfig>(null)
390
- const isNewUser = false
391
- const themeMui = createTheme(themeOptions)
392
- const elementsRef = useRef<any>(null)
393
- const stripeRef = useRef<Stripe | null>(null)
394
-
395
- useEffect(() => {
396
- if (isBrowser) {
397
- const extraData = window.localStorage.getItem('extraData')
398
- if (extraData) {
399
- setExtraData(JSON.parse(extraData))
400
- }
401
- }
402
- getCheckoutPageConfigs()
403
- .then(data => {
404
- if (data?.data?.attributes) {
405
- setConfigs(data.data.attributes)
406
- setIsConfigLoading(false)
407
- }
408
- onGetCheckoutConfigsSuccess(data)
409
- })
410
- .catch(e => {
411
- setIsConfigLoading(false)
412
- onGetCheckoutConfigsError(e)
413
- })
414
- }, [isBrowser])
415
-
416
- const defaultCountry = isBrowser ? window.localStorage.getItem('eventCountry') : ''
417
- const userData =
418
- isBrowser && window.localStorage.getItem('user_data')
419
- ? JSON.parse(window.localStorage.getItem('user_data') || '{}')
420
- : {}
421
- const additionalConfigs =
422
- isBrowser && window.localStorage.getItem('checkoutAdditionalConfigs')
423
- ? JSON.parse(
424
- window.localStorage.getItem('checkoutAdditionalConfigs') ||
425
- '{"resale": false, "resaleWithAddons": false}'
426
- )
427
- : { resale: false, resaleWithAddons: false }
428
- const [dataWithUniqueIds, setDataWithUniqueIds] = useState<IBillingInfoData[]>(
429
- assingUniqueIds(data)
430
- )
431
- const xtfCookie = getCookieByName('X-TF-ECOMMERCE')
432
- const [isLoggedIn, setIsLoggedIn] = useState(!!(pIsLoggedIn || xtfCookie))
433
- const [cartInfoData, setCartInfo] = useState<any>({})
434
- const [countries, setCountries] = useState<any>([])
435
- const [states, setStates] = useState<any>([])
436
- const [showModalLogin, setShowModalLogin] = useState(false)
437
- const alreadyHasUser= false
438
- const [userExpired, setUserExpired] = useState(false)
439
- const [showModalSignup, setShowModalSignup] = useState(false)
440
- const [showModalForgotPassword, setShowModalForgotPassword] = useState(false)
441
- const [ticketsQuantity, setTicketsQuantity] = useState<string[]>([])
442
- const [userValues, setUserValues] = useState<any>({
443
- firstName: '',
444
- lastName: '',
445
- email: '',
446
- phone: '',
447
- confirmEmail: '',
448
- holderFirstName: '',
449
- holderLastName: '',
450
- holderAge: '',
451
- city: '',
452
- country: '',
453
- street_address: '',
454
- state: '',
455
- zip: '',
456
- })
457
- const [loading, setLoading] = useState(true)
458
- const [cardLoading, setCardLoading] = useState(false)
459
- const [isCountriesLoading, setIsCountriesLoading] = useState(true)
460
- const [error, setError] = useState<string | null>(null)
461
- const [phoneValidationIsLoading, setPhoneValidationIsLoading] = useState(false)
462
- const [emailExists, setEmailExists] = useState(false)
463
- const emailLogged = _get(userData, 'email', '') || _get(userValues, 'email', '')
464
- const firstNameLogged =
465
- _get(userData, 'first_name', '') || _get(userValues, 'first_name', '')
466
- const lastNameLogged =
467
- _get(userData, 'last_name', '') || _get(userValues, 'last_name', '')
468
- const phoneLogged = _get(userData, 'phone', '') || _get(userValues, 'phone', '')
469
- const showDOB = configs?.age_required
470
- const showTicketHolders = configs?.names_required
471
- const eventId = configs?.event_id
472
- const optedInFieldValue: boolean = brandOptIn
473
- ? brandOptIn
474
- : _get(cartInfoData, 'optedIn', false)
475
- const ttfOptIn = Boolean(_get(cartInfoData, 'ttfOptIn', false))
476
- const isTable = Boolean(_get(cartInfoData, 'is_table', false))
477
- const hideTtfOptIn: boolean = _get(cartInfoData, 'hide_ttf_opt_in', true)
478
- const expirationTime = _get(cartInfoData, 'expiresAt')
479
- const flagRequirePhone = configs?.phone_required
480
- const collectMandatoryWalletAddress = configs?.collect_mandatory_wallet_address
481
- const collectOptionalWalletAddress = configs?.collect_optional_wallet_address
482
- const flagFreeTicket = configs?.free_ticket
483
- const hidePhoneField = configs?.hide_phone_field
484
- const hideWalletAddressField =
485
- !collectOptionalWalletAddress && !collectMandatoryWalletAddress
486
- const collectMandatoryCompany = configs?.collect_mandatory_company
487
- const collectOptionalCompany = configs?.collect_optional_company
488
- const hideCompanyField = !collectOptionalCompany && !collectMandatoryCompany
489
- const collectMandatoryJobTitle = configs?.collect_mandatory_job_title
490
- const collectOptionalJobTitle = configs?.collect_optional_job_title
491
- const hideJobTitleField = !collectMandatoryJobTitle && !collectOptionalJobTitle
492
- const collectMandatoryInstagram = configs?.collect_mandatory_instagram
493
- const collectOptionalInstagram = configs?.collect_optional_instagram
494
- const hideInstagramField = !collectMandatoryInstagram && !collectOptionalInstagram
495
- const collectMandatoryBusinessCategory = configs?.collect_mandatory_business_category
496
- const collectOptionalBusinessCategory = configs?.collect_optional_business_category
497
- const eventHasAddons = configs?.has_add_on
498
- const addonMaxQuantityGroups = configs?.addon_max_quantity_groups ?? undefined
499
- const hideBusinessCategoryField =
500
- !collectMandatoryBusinessCategory && !collectOptionalBusinessCategory
501
-
502
- const [pendingVerificationMessage, setPendingVerificationMessage] = useState<string>()
503
- const [reviewData, setReviewData] = useState<any>({})
504
- const [checkoutData, setCheckoutData] = useState<any>({})
505
- const [checkoutUpdateData, setCheckoutUpdateData] =
506
- useState<ICheckoutResponseData | null>(null)
507
- const prevData = useRef(data)
508
-
509
- const addAddOnsInAttributes = useCallback((checkoutBody: any) => {
510
- const selectedAddOns = window.localStorage.getItem('add_ons') || '{}'
511
- const addOnDataCapture = window.localStorage.getItem('add_on_data_capture') || '{}'
512
-
513
- checkoutBody.attributes.add_ons = JSON.parse(selectedAddOns)
514
- checkoutBody.attributes.add_on_data_capture = JSON.parse(addOnDataCapture)
515
- }, [])
516
- const [singleCheckoutAddons, setSingleCheckoutAddOns] = useState<any>({})
517
-
518
- const orderIsFree = !Number(checkoutData?.total)
519
-
520
- useEffect(() => {
521
- const hasUniqueId = _get(data, '[0].uniqueId')
522
- const isEqualData = _isEqual(prevData.current, data)
523
- if (!hasUniqueId || !isEqualData) {
524
- setDataWithUniqueIds(assingUniqueIds(data))
525
- if (!isEqualData) {
526
- prevData.current = data
527
- }
528
- }
529
- }, [data])
530
-
531
- const getQuantity = useCallback((cart: any = []) => {
532
- let qty = 0
533
- cart.forEach((item: any) => {
534
- qty += +item.quantity
535
- })
536
- return qty
537
- }, [])
538
-
539
- useEffect(() => {
540
- if (pIsLoggedIn !== isLoggedIn || xtfCookie) {
541
- setIsLoggedIn(!!(pIsLoggedIn || xtfCookie))
542
- }
543
- }, [pIsLoggedIn, isLoggedIn, xtfCookie])
544
-
545
- //just once
546
- useEffect(() => {
547
- // fetch countries data
548
- const fetchCountries = async () => {
549
- try {
550
- const res = await getCountries()
551
- setCustomHeader(res)
552
- setCountries(res.data)
553
- setIsCountriesLoading(false)
554
- onGetCountriesSuccess(res.data)
555
- } catch (e) {
556
- if (axios.isAxiosError(e)) {
557
- onGetCountriesError(e)
558
- }
559
- setIsCountriesLoading(false)
560
- }
561
- }
562
- shouldFetchCountries && fetchCountries()
563
- fetchCart()
564
-
565
- // Initialize checkout with event_id on first load
566
- if (isSinglePageCheckout && eventId) {
567
- updateCheckoutWithAddOns()
568
- }
569
-
570
- return () => {
571
- isBrowser && localStorage.removeItem('selectedTicketsQuantity')
572
- }
573
- // eslint-disable-next-line react-hooks/exhaustive-deps
574
- }, [
575
- eventId,
576
- isSinglePageCheckout,
577
- shouldFetchCountries,
578
- onGetCountriesSuccess,
579
- onGetCountriesError,
580
- ])
581
-
582
- // fetch cart data
583
- const fetchCart = async () => {
584
- try {
585
- setCardLoading(true)
586
- const res = await getCart()
587
- setCustomHeader(res)
588
- const cartInfo = res.data.attributes
589
- setCartInfo(cartInfo)
590
- const { cart = [] } = cartInfo
591
- setTicketsQuantity(new Array(getQuantity(cart)).fill(null).map(() => nanoid()))
592
- onGetCartSuccess(res.data)
593
- } catch (e) {
594
- if (axios.isAxiosError(e)) {
595
- onGetCartError(e)
596
- }
597
- } finally {
598
- setCardLoading(false)
599
- }
600
- }
601
-
602
- // fetch user data
603
- const fetchUserData = async () => {
604
- try {
605
- if (isLoggedIn) {
606
- const userDataResponse = await getProfileData()
607
- const profileSpecifiedData = _get(userDataResponse, 'data')
608
- const profileDataObj = setLoggedUserData(profileSpecifiedData)
609
- setUserValues({
610
- ...profileDataObj,
611
- firstName: profileDataObj.first_name,
612
- lastName: profileDataObj.last_name,
613
- })
614
- window.localStorage.setItem('user_data', JSON.stringify(profileDataObj))
615
- onGetProfileDataSuccess(userDataResponse.data)
616
- }
617
- } catch (e) {
618
- if (axios.isAxiosError(e)) {
619
- onGetProfileDataError(e)
620
- }
621
- }
622
- }
623
-
624
- useEffect(() => {
625
- fetchUserData()
626
- fetchCart()
627
- }, [isLoggedIn])
628
-
629
- useEffect(() => {
630
- const fetchCheckoutUpdate = async () => {
631
- if (!eventId) return
632
-
633
- try {
634
- const checkoutUpdateResponse = await updateCheckout({
635
- attributes: {
636
- event_id: eventId,
637
- is_from_resale: additionalConfigs?.resale,
638
- },
639
- })
640
- if (checkoutUpdateResponse.success) {
641
- const checkoutAttributes = checkoutUpdateResponse.data.attributes
642
- const cartPriceBreakdown = _get(
643
- checkoutAttributes,
644
- 'cart_price_breakdown',
645
- {}
646
- )
647
- localStorage.setItem(
648
- 'checkoutData',
649
- JSON.stringify({ hash: '', total: _get(cartPriceBreakdown, 'total', 0) })
650
- )
651
- setCheckoutUpdateData(checkoutAttributes)
652
- onCheckoutUpdateSuccess({ expires_at: expirationTime, ...cartPriceBreakdown })
653
- }
654
- } catch (error) {
655
- console.error('Failed to fetch checkout update:', error)
656
- }
657
- }
658
-
659
- fetchCheckoutUpdate()
660
- }, [eventId, additionalConfigs?.resale])
661
-
662
- useEffect(() => {
663
- const collectPaymentData = async () => {
664
- if (
665
- skipPage &&
666
- !_isEmpty(ticketsQuantity) &&
667
- !showDOB &&
668
- !loading &&
669
- !isNewUser
670
- ) {
671
- setLoading(true)
672
- const checkoutBody = createCheckoutDataBodyWithDefaultHolder(
673
- ticketsQuantity.length,
674
- userData
675
- )
676
-
677
- try {
678
- if (isBrowser) {
679
- addAddOnsInAttributes(checkoutBody)
680
- }
681
-
682
- const checkoutResponse = await postOnCheckout(checkoutBody, flagFreeTicket)
683
- removeReferralKey()
684
- removeAdditionalConfigs()
685
- onSkipBillingPage(checkoutResponse.data.attributes)
686
- setLoading(false)
687
- } catch (e) {
688
- onSubmitError(e as AxiosError)
689
- if (_get(e, 'response.data.data.hasUnverifiedOrder')) {
690
- setPendingVerificationMessage(_get(e, 'response.data.message'))
691
- }
692
- }
693
- } else {
694
- setLoading(false)
695
- }
696
- }
697
- collectPaymentData()
698
- }, [skipPage, ticketsQuantity])
699
-
700
- const collectCheckoutBody = useCallback(
701
- (values: Record<string, any>, profileData?: any): Record<string, any> => {
702
- let checkoutBody = {} as ICheckoutBody
703
-
704
- // Auto collect ticket holders name when it was skipped optionally
705
- if (showDOB && !showTicketHolders && canSkipHolderNames) {
706
- checkoutBody = createCheckoutDataBodyWithDefaultHolder(
707
- ticketsQuantity.length,
708
- values,
709
- true,
710
- { emailLogged, firstNameLogged, lastNameLogged, phoneLogged }
711
- )
712
- } else {
713
- checkoutBody = createCheckoutDataBody(
714
- ticketsQuantity.length,
715
- values,
716
- {
717
- emailLogged: emailLogged || profileData.email,
718
- firstNameLogged:
719
- firstNameLogged || profileData.first_name || profileData.firstName,
720
- lastNameLogged:
721
- lastNameLogged || profileData.last_name || profileData.lastName,
722
- phoneLogged: phoneLogged || profileData.phone,
723
- },
724
- showDOB
725
- )
726
- }
727
-
728
- // Collect data_capture for Order Custom Fields
729
- const data_capture: Record<string, any> = {}
730
- _forEach(customFieldsOrderKeys, (key: string) => {
731
- data_capture[key] = values[key]
732
-
733
- // Delete from values list
734
- delete checkoutBody.attributes[key]
735
- })
736
-
737
- // Temp solution for hardcoded data capture values, to be deleted in the future
738
- const captureKeys = [
739
- 'businessCategory',
740
- 'company',
741
- 'instagram',
742
- 'jobTitle',
743
- 'wallet_address',
744
- ]
745
-
746
- captureKeys.forEach(key => {
747
- const path = `data_capture.${key}`
748
- const value = _get(values, path, '')
749
-
750
- if (value !== '') {
751
- data_capture[key] = value
752
- }
753
-
754
- const attributeKey = `data_capture[${key}]`
755
- delete checkoutBody.attributes?.[attributeKey]
756
- })
757
-
758
- // Collect data_capture for Ticket Holders Fields
759
- _forEach(checkoutBody.attributes.ticket_holders, (holder, holderIndex) => {
760
- const holderDataCapture: Record<string, any> = {}
761
-
762
- _forEach(customFieldsTicketHolderKeys, customFieldKey => {
763
- const customFieldHolderName = `${customFieldKey}-${holderIndex}`
764
- const customFieldHolderKey = values[customFieldHolderName] || ''
765
- holderDataCapture[customFieldKey] = customFieldHolderKey
766
-
767
- // Delete holder specific value from values list
768
- delete checkoutBody.attributes[customFieldHolderName]
769
- })
770
-
771
- // Assign Ticket Holder data_capture final value
772
- if (!_isEmpty(holderDataCapture)) {
773
- holder.ticket_data_capture = holderDataCapture
774
- }
775
- })
776
-
777
- // Collect add_on_data_capture for Add-on Custom Fields
778
- const add_on_data_capture: Record<string, any> = {}
779
- _forEach(values, (val: any, key: string) => {
780
- // Matches keys like: `${addonId}-${groupId}-${fieldKey}` created in AddonComponent
781
- const match = key.match(/^(\d+)-\d+-(.+)$/)
782
- if (match) {
783
- const addonId = match[1]
784
- const fieldKey = match[2]
785
-
786
- // Initialize addon bucket
787
- if (!add_on_data_capture[addonId]) {
788
- add_on_data_capture[addonId] = {}
789
- }
790
-
791
- add_on_data_capture[addonId][fieldKey] = val
792
-
793
- // Remove the raw form key from attributes to avoid leaking internals
794
- delete checkoutBody.attributes[key]
795
- }
796
- })
797
-
798
- // Also include add_on_data_capture from localStorage for single-page checkout
799
- if (isBrowser) {
800
- const storedAddOnDataCapture = localStorage.getItem('add_on_data_capture')
801
- if (storedAddOnDataCapture) {
802
- const parsed = JSON.parse(storedAddOnDataCapture)
803
- Object.keys(parsed).forEach(addonId => {
804
- if (!add_on_data_capture[addonId]) {
805
- add_on_data_capture[addonId] = {}
806
- }
807
- Object.keys(parsed[addonId]).forEach(fieldKey => {
808
- add_on_data_capture[addonId][fieldKey] = parsed[addonId][fieldKey]
809
- })
810
- })
811
- }
812
- }
813
-
814
- const mergedAttributes: Record<string, any> = {
815
- ...checkoutBody.attributes,
816
- data_capture,
817
- }
818
-
819
- if (!_isEmpty(add_on_data_capture)) {
820
- mergedAttributes.add_on_data_capture = add_on_data_capture
821
- }
822
-
823
- return { attributes: mergedAttributes }
824
- },
825
- [
826
- showDOB,
827
- showTicketHolders,
828
- canSkipHolderNames,
829
- customFieldsOrderKeys,
830
- ticketsQuantity.length,
831
- emailLogged,
832
- firstNameLogged,
833
- lastNameLogged,
834
- phoneLogged,
835
- customFieldsTicketHolderKeys,
836
- ]
837
- )
838
-
839
- const removeReferralKey = useCallback(() => {
840
- localStorage.removeItem('referral_key')
841
- }, [])
842
-
843
- const removeAdditionalConfigs = useCallback(() => {
844
- localStorage.removeItem('checkoutAdditionalConfigs')
845
- }, [])
846
-
847
- useEffect(() => {
848
- onCheckoutUpdateSuccess({ expires_at: expirationTime, ...checkoutData })
849
- }, [checkoutData, cartInfoData])
850
-
851
- // Initialize payment hooks
852
- usePaymentRedirect({
853
- stripeRef,
854
- setError,
855
- setLoading,
856
- removeReferralKey,
857
- removeAdditionalConfigs,
858
- handleSubmit,
859
- isBrowser,
860
- })
861
-
862
- const { processPayment } = useStripePayment({
863
- stripeRef,
864
- elementsRef,
865
- setError,
866
- isBrowser,
867
- })
868
-
869
- const updateCheckoutWithAddOns = useCallback(
870
- async (addOns: { [key: string]: number } = {}) => {
871
- if (!isSinglePageCheckout) return
872
-
873
- const mergedAddOns = { ...singleCheckoutAddons }
874
-
875
- // Update existing entries and add new ones
876
- Object.entries(addOns).forEach(([key, value]) => {
877
- const amount = Number(value)
878
- if (amount) {
879
- mergedAddOns[key] = amount
880
- } else {
881
- delete mergedAddOns[key]
882
- }
883
- })
884
-
885
- try {
886
- const checkoutUpdateData = {
887
- attributes: {
888
- event_id: eventId,
889
- add_ons: mergedAddOns,
890
- is_from_resale: additionalConfigs?.resale,
891
- },
892
- }
893
-
894
- const checkoutResponse = await updateCheckout(checkoutUpdateData)
895
-
896
- if (checkoutResponse.success) {
897
- const checkoutDataObj = _get(
898
- checkoutResponse,
899
- 'data.attributes.cart_price_breakdown',
900
- {}
901
- )
902
- setCheckoutData(checkoutDataObj)
903
- setSingleCheckoutAddOns(mergedAddOns)
904
- const updatedAttributes = _get(checkoutResponse, 'data.attributes', {})
905
- if (updatedAttributes.additional_payment_information) {
906
- setCheckoutUpdateData(updatedAttributes)
907
- }
908
- }
909
- } catch (error) {
910
- const errorMessage = _get(
911
- error,
912
- 'response.data.message',
913
- 'Failed to update add-ons'
914
- )
915
- setError(errorMessage)
916
- onCheckoutUpdateError(error as AxiosError)
917
- }
918
- },
919
- [eventId, isSinglePageCheckout, onCheckoutUpdateError, onCheckoutUpdateSuccess]
920
- )
921
-
922
- const handleAddOnSelect = useCallback(
923
- async (selectedAddOns: { [key: string]: number }) => {
924
- await updateCheckoutWithAddOns(selectedAddOns)
925
- },
926
- [updateCheckoutWithAddOns]
927
- )
928
-
929
- const onAddOnSelect = useCallback(
930
- (id: string, value: string, _addon: any, fieldUpdates: Record<string, any> = {}) => {
931
- const quantity = parseInt(value) || 0
932
- const addonId = id
933
-
934
- // Get current add-ons and their custom fields
935
- const currentAddOns = JSON.parse(localStorage.getItem('add_ons') || '{}')
936
- const currentDataCapture = JSON.parse(
937
- localStorage.getItem('add_on_data_capture') || '{}'
938
- )
939
-
940
- // Update quantities
941
- const updatedAddOns = { ...currentAddOns }
942
- updatedAddOns[addonId] = quantity
943
-
944
- // Update custom fields if any
945
- const updatedDataCapture = { ...currentDataCapture }
946
- if (Object.keys(fieldUpdates).length > 0) {
947
- updatedDataCapture[addonId] = {
948
- ...(updatedDataCapture[addonId] || {}),
949
- ...fieldUpdates,
950
- }
951
- }
952
-
953
- if (quantity === 0 && updatedDataCapture[addonId]) {
954
- delete updatedDataCapture[addonId]
955
- }
956
- // Save to localStorage
957
- localStorage.setItem('add_ons', JSON.stringify(updatedAddOns))
958
- localStorage.setItem('add_on_data_capture', JSON.stringify(updatedDataCapture))
959
-
960
- // Call handleAddOnSelect with the updated addons object
961
- handleAddOnSelect(updatedAddOns)
962
- },
963
- [handleAddOnSelect]
964
- )
965
- if (loading || (enableTimer && !expirationTime && isBrowser)) {
966
- if (expirationTime === 0) {
967
- // Redirect to homepage (countdown finished and browser reloaded case)
968
- window.location.href = '/'
969
- }
970
- }
971
-
972
- const selectedCountry =
973
- _find(countries, item => item.code.toLowerCase() === defaultCountry) || {}
974
- const initialCountry = selectedCountry.id || _get(userData, 'countryId', '') || '1'
975
-
976
- const pageUrl = isBrowser ? window.location.href.split('?')[0] : ''
977
- usePixel(eventId || cartInfoData?.eventId, { page: 'billing', pageUrl })
978
- if (isTable) {
979
- dataWithUniqueIds[0].label = 'Get Your Tables'
980
- }
981
-
982
- const stripePublishableKey =
983
- reviewData?.payment_method?.stripe_publishable_key ||
984
- checkoutUpdateData?.additional_payment_information?.basic_config?.apiKey
985
- const stripeAccountId =
986
- reviewData?.payment_method?.stripe_connected_account ||
987
- checkoutUpdateData?.additional_payment_information?.basic_config?.accountId
988
- const addOnsIncludedOnInvitation =
989
- additionalConfigs.resale && additionalConfigs.resaleWithAddons
990
-
991
- const elementsOptions: StripeElementsOptions = {
992
- ...checkoutUpdateData?.additional_payment_information?.elements_config,
993
- }
994
-
995
- if (loading || cardLoading || isCountriesLoading || isConfigLoading || !eventId) {
996
- return (
997
- <Backdrop
998
- sx={{ color: '#fff', backgroundColor: '#000000bd', zIndex: 1205 }}
999
- open={true}
1000
- >
1001
- <CircularProgress color="inherit" />
1002
- </Backdrop>
1003
- )
1004
- }
1005
-
1006
- return (
1007
- <ThemeProvider theme={themeMui}>
1008
- {!!expirationTime && enableTimer && (
1009
- <TimerWidget
1010
- expires_at={expirationTime}
1011
- onCountdownFinish={onCountdownFinish}
1012
- container={isSinglePageCheckout ? 'body' : ''}
1013
- />
1014
- )}
1015
- {!isCountriesLoading && !isConfigLoading && (
1016
- <Formik
1017
- initialValues={getInitialValues(
1018
- dataWithUniqueIds,
1019
- {
1020
- country: initialCountry,
1021
- state:
1022
- _get(userData, 'stateId', '') || _get(userData, 'state', '') || '1',
1023
- brand_opt_in: Boolean(optedInFieldValue),
1024
- ttf_opt_in: ttfOptIn,
1025
- data_capture: {
1026
- instagram: _get(extraData, 'data_capture.instagram', ''),
1027
- company: _get(extraData, 'data_capture.company', ''),
1028
- businessCategory: _get(extraData, 'data_capture.businessCategory', ''),
1029
- jobTitle: _get(extraData, 'data_capture.jobTitle', ''),
1030
- },
1031
- ...initialValues,
1032
- },
1033
- userValues,
1034
- ticketHoldersFields,
1035
- ticketsQuantity
1036
- )}
1037
- enableReinitialize={false}
1038
- onSubmit={async (values, formikHelpers) => {
1039
- try {
1040
- // Validation: if phone is required for ticket holders, mark errors and stop submit
1041
- const flagRequirePhoneLocal = Boolean(configs?.phone_required)
1042
- if (flagRequirePhoneLocal) {
1043
- const holdersCount = ticketsQuantity.length
1044
- let hasHolderPhoneError = false
1045
- for (let i = 0; i < holdersCount; i++) {
1046
- const fieldName = `holderPhone-${i}`
1047
- const value = _get(values, fieldName, '')
1048
- if (!value) {
1049
- hasHolderPhoneError = true
1050
- formikHelpers.setFieldTouched(fieldName, true, false)
1051
- formikHelpers.setFieldError(fieldName, 'This field is required')
1052
- }
1053
- }
1054
- if (hasHolderPhoneError) {
1055
- // Do not proceed with submit; Formik will show errors and our PhoneNumberField now shows errors when submitCount > 0
1056
- return
1057
- }
1058
- }
1059
-
1060
- if ((!elementsRef.current || !stripeRef.current) && !orderIsFree) {
1061
- setError('Fill in the payment details')
1062
- return
1063
- }
1064
-
1065
- if (isSinglePageCheckout && !orderIsFree) {
1066
- // For PaymentElement, we'll use confirmPayment directly
1067
- // No need to create payment method separately
1068
- }
1069
-
1070
- if (isBrowser) {
1071
- window.localStorage.setItem(
1072
- 'extraData',
1073
- JSON.stringify({
1074
- data_capture: {
1075
- instagram: _get(values, 'data_capture.instagram', ''),
1076
- company: _get(values, 'data_capture.company', ''),
1077
- businessCategory: _get(
1078
- values,
1079
- 'data_capture.businessCategory',
1080
- ''
1081
- ),
1082
- jobTitle: _get(values, 'data_capture.jobTitle', ''),
1083
- },
1084
- })
1085
- )
1086
- }
1087
-
1088
- // Guest checkout: no need to register, just get profile if logged in
1089
- let userDataObj = userData
1090
- if (isLoggedIn) {
1091
- try {
1092
- const profileData = await getProfileData()
1093
- const profileSpecifiedData = _get(profileData, 'data')
1094
- userDataObj = setLoggedUserData(profileSpecifiedData)
1095
- } catch (e) {
1096
- // If profile fetch fails, use values from form
1097
- userDataObj = {
1098
- email: values.email,
1099
- first_name: values.firstName,
1100
- last_name: values.lastName,
1101
- phone: values.phone,
1102
- }
1103
- }
1104
- } else {
1105
- // For guest checkout, use form values
1106
- userDataObj = {
1107
- email: values.email,
1108
- first_name: values.firstName,
1109
- last_name: values.lastName,
1110
- phone: values.phone,
1111
- }
1112
- }
1113
-
1114
- if (isBrowser) {
1115
- window.localStorage.setItem('user_data', JSON.stringify(userDataObj))
1116
- }
1117
-
1118
- const checkoutBody = collectCheckoutBody(values, userDataObj)
1119
-
1120
- if (isBrowser && !isSinglePageCheckout) {
1121
- addAddOnsInAttributes(checkoutBody)
1122
- }
1123
-
1124
- if (isSinglePageCheckout) {
1125
- checkoutBody.attributes.add_ons = singleCheckoutAddons
1126
- // Include add_on_data_capture for single-page checkout
1127
- const storedAddOnDataCapture =
1128
- localStorage.getItem('add_on_data_capture')
1129
- if (storedAddOnDataCapture) {
1130
- checkoutBody.attributes.add_on_data_capture =
1131
- JSON.parse(storedAddOnDataCapture)
1132
- }
1133
- }
1134
-
1135
- const checkoutResponse = await postOnCheckout(
1136
- checkoutBody,
1137
- flagFreeTicket
1138
- )
1139
-
1140
- const checkoutUpdateResponse = await updateCheckout({
1141
- attributes: {
1142
- event_id: eventId,
1143
- add_ons: checkoutBody?.attributes?.add_ons ?? [],
1144
- is_from_resale: additionalConfigs?.resale,
1145
- },
1146
- })
1147
- setCheckoutUpdateData(checkoutUpdateResponse.data.attributes)
1148
-
1149
- let paymentResponse = null
1150
-
1151
- if (isSinglePageCheckout) {
1152
- const { hash, total } = checkoutResponse.data.attributes
1153
- localStorage.setItem('checkoutData', JSON.stringify({ hash, total }))
1154
-
1155
- const paymentDataResponse = await getPaymentData(String(hash))
1156
-
1157
- if (paymentDataResponse.success) {
1158
- const { attributes } = paymentDataResponse.data
1159
- setReviewData(attributes)
1160
-
1161
- const { order_details, cart } = attributes
1162
- const {
1163
- tickets: [ticket],
1164
- } = order_details
1165
-
1166
- const updatedOrderData = {
1167
- add_ons: order_details.add_ons || [],
1168
- total: order_details.total,
1169
- subtotal: order_details.subtotal,
1170
- fees: order_details.fees,
1171
- pay_now: order_details.pay_now || '',
1172
-
1173
- id: order_details?.id,
1174
- product_name: cart[0]?.product_name,
1175
- ticketType: ticket?.name,
1176
- quantity: ticket?.quantity,
1177
- price: ticket?.price,
1178
- currency: order_details?.currency,
1179
- guest_count: order_details?.guest_count || '',
1180
- debt: order_details?.debt || null,
1181
- cost: ticket?.cost,
1182
- }
1183
-
1184
- const isFreeTickets =
1185
- (!Number(total) && !Number(updatedOrderData.total)) ||
1186
- !Number(updatedOrderData?.pay_now || 0)
1187
- // Process payment using the hook
1188
- paymentResponse = await processPayment(
1189
- paymentDataResponse,
1190
- values,
1191
- formikHelpers,
1192
- checkoutResponse,
1193
- checkoutUpdateResponse,
1194
- {
1195
- attributes,
1196
- isFreeTickets,
1197
- updatedOrderData,
1198
- eventId,
1199
- }
1200
- )
1201
-
1202
- if (!paymentResponse && !isFreeTickets) {
1203
- // Payment failed or redirected, don't continue
1204
- return
1205
- }
1206
- }
1207
- }
1208
-
1209
- removeReferralKey()
1210
- removeAdditionalConfigs()
1211
- handleSubmit(
1212
- values,
1213
- formikHelpers as FormikHelpers<any>,
1214
- eventId,
1215
- checkoutResponse,
1216
- checkoutUpdateResponse,
1217
- paymentResponse
1218
- )
1219
- } catch (e) {
1220
- setLoading(false)
1221
- onSubmitError(e as AxiosError)
1222
- const hasUnverifiedOrder = _get(
1223
- e,
1224
- 'response.data.data.hasUnverifiedOrder'
1225
- )
1226
- const message = _get(e, 'response.data.message', {}) as
1227
- | { password?: string | null, email?: string | null }
1228
- | string
1229
-
1230
- if (hasUnverifiedOrder && typeof message === 'string') {
1231
- setPendingVerificationMessage(message)
1232
- } else if (axios.isAxiosError(e)) {
1233
- if (
1234
- (e as any).response?.status === 401 ||
1235
- _get(e, 'response.data.error') === 'invalid_token'
1236
- ) {
1237
- if (isBrowser) {
1238
- window.localStorage.removeItem('user_data')
1239
- setUserExpired(true)
1240
- setShowModalLogin(true)
1241
- setIsLoggedIn(false)
1242
- setShowModalSignup(false)
1243
- setShowModalForgotPassword(false)
1244
- const event = new window.CustomEvent('tf-logout')
1245
- deleteCookieByName('X-TF-ECOMMERCE')
1246
- window.document.dispatchEvent(event)
1247
- }
1248
- }
1249
- if (message && !hideErrorsAlertSection && typeof message === 'string') {
1250
- setError(message)
1251
- }
1252
- onSubmitError(e)
1253
- }
1254
-
1255
- // Keep form values intact - don't reset
1256
- formikHelpers.setSubmitting(false)
1257
- } finally {
1258
- setLoading(false)
1259
- }
1260
- }}
1261
- >
1262
- {(props: FormikProps<any>) => (
1263
- <Form onSubmit={props.handleSubmit}>
1264
- <ErrorFocus />
1265
- <LogicRunner
1266
- brandOptIn={brandOptIn}
1267
- values={props.values}
1268
- errors={props.errors}
1269
- setStates={setStates}
1270
- setFieldValue={props.setFieldValue}
1271
- setValues={props.setValues}
1272
- setUserValues={setUserValues}
1273
- onGetStatesSuccess={onGetStatesSuccess}
1274
- onGetStatesError={onGetStatesError}
1275
- shouldFetchCountries={shouldFetchCountries}
1276
- />
1277
- <EmailExistenceChecker
1278
- email={props.values.email || ''}
1279
- confirmEmail={props.values.confirmEmail || ''}
1280
- isLoggedIn={isLoggedIn}
1281
- setEmailExists={setEmailExists}
1282
- />
1283
- <div className={`billing-info-container ${theme}`}>
1284
- {!!error && (
1285
- <SnackbarAlert
1286
- type="error"
1287
- isOpen={!!error}
1288
- message={error || ''}
1289
- onClose={() => {
1290
- setError(null)
1291
- onErrorClose()
1292
- }}
1293
- />
1294
- )}
1295
- {!isLoggedIn && !isSinglePageCheckout && (
1296
- <div className="account-actions-block">
1297
- <div className="action-item">
1298
- <div>{accountInfoTitle}</div>
1299
- <div>Login & skip ahead:</div>
1300
- </div>
1301
- <div className="action-item login-block">
1302
- <button
1303
- className="login-register-button"
1304
- type="button"
1305
- onClick={() => {
1306
- // If outside login needed to skip package login functionallity
1307
- if (onLogin) {
1308
- onLogin()
1309
- } else {
1310
- setShowModalLogin(true)
1311
- }
1312
- }}
1313
- >
1314
- Login
1315
- </button>
1316
- {!hideLogo && (
1317
- <div className="logo-image-container">
1318
- <img
1319
- src={
1320
- theme === 'dark'
1321
- ? 'https://www.ticketfairy.com/resources/images/logo-ttf.svg'
1322
- : 'https://www.ticketfairy.com/resources/images/logo-ttf-black.svg'
1323
- }
1324
- alt="nodata"
1325
- />
1326
- </div>
1327
- )}
1328
- </div>
1329
- </div>
1330
- )}
1331
- {isSinglePageCheckout &&
1332
- !addOnsIncludedOnInvitation &&
1333
- eventHasAddons &&
1334
- eventId ? (
1335
- <SimpleAddonsContainer
1336
- {...(addonsProps ?? {})}
1337
- eventId={eventId}
1338
- addOnDataWithCustomFields={addOnDataWithCustomFields}
1339
- configs={configs}
1340
- onAddOnSelect={onAddOnSelect}
1341
- addonMaxQuantityGroups={addonMaxQuantityGroups}
1342
- />
1343
- ) : !addOnsIncludedOnInvitation &&
1344
- includeAddons &&
1345
- !isSinglePageCheckout ? (
1346
- <AddonsContainter
1347
- {...(addonsProps ?? {})}
1348
- addOnDataWithCustomFields={addOnDataWithCustomFields}
1349
- configs={configs}
1350
- onAddOnSelect={onAddOnSelect}
1351
- />
1352
- ) : null}
1353
- {!cardLoading &&
1354
- _map(dataWithUniqueIds, item => {
1355
- const { label, labelClassName, fields } = item
1356
- return (
1357
- <div key={item.uniqueId} className="billing-info-fields">
1358
- <p className={labelClassName}>{label}</p>
1359
- {_map(fields, group => {
1360
- const { groupClassname, groupItems } = group
1361
- const filteredGroupItems = filterBillingInfoFields(
1362
- groupItems,
1363
- {
1364
- showDOB: Boolean(showDOB),
1365
- hideTtfOptIn: Boolean(hideTtfOptIn),
1366
- hidePhoneField: Boolean(hidePhoneField),
1367
- flagRequirePhone: Boolean(flagRequirePhone),
1368
- collectMandatoryWalletAddress: Boolean(
1369
- collectMandatoryWalletAddress
1370
- ),
1371
- collectMandatoryJobTitle: Boolean(
1372
- collectMandatoryJobTitle
1373
- ),
1374
- collectMandatoryBusinessCategory: Boolean(
1375
- collectMandatoryBusinessCategory
1376
- ),
1377
- collectMandatoryCompany: Boolean(collectMandatoryCompany),
1378
- collectMandatoryInstagram: Boolean(
1379
- collectMandatoryInstagram
1380
- ),
1381
- flagFreeTicket: Boolean(flagFreeTicket),
1382
- hideWalletAddressField: Boolean(hideWalletAddressField),
1383
- hideJobTitleField: Boolean(hideJobTitleField),
1384
- hideBusinessCategoryField: Boolean(
1385
- hideBusinessCategoryField
1386
- ),
1387
- hideCompanyField: Boolean(hideCompanyField),
1388
- hideInstagramField,
1389
- }
1390
- )
1391
- return (
1392
- <React.Fragment key={group.uniqueId}>
1393
- <div className={groupClassname}>
1394
- {_map(filteredGroupItems, element => {
1395
- // Hide password fields in single-page checkout or when user is logged in
1396
- const shouldHidePasswordFields =
1397
- ['password', 'confirmPassword', 'password-info'].includes(
1398
- element.name
1399
- ) &&
1400
- (isLoggedIn || isSinglePageCheckout)
1401
-
1402
- return shouldHidePasswordFields ? null : (
1403
- <React.Fragment key={element.uniqueId}>
1404
- <div
1405
- className={`${element.className} ${
1406
- props?.errors[element.name] || ''
1407
- }`}
1408
- >
1409
- {element.component ? (
1410
- typeof element.component === 'function' ? (
1411
- renderComponentWithProps(
1412
- element.component as React.ComponentType<any>,
1413
- element.name === 'payment_info'
1414
- ? { reviewData }
1415
- : {}
1416
- )
1417
- ) : (
1418
- element.component
1419
- )
1420
- ) : (
1421
- <Field
1422
- {...element}
1423
- type={
1424
- element.type === 'radio' ||
1425
- element.type === 'checkbox'
1426
- ? undefined
1427
- : element.type
1428
- }
1429
- setPhoneValidationIsLoading={
1430
- element.type === 'phone'
1431
- ? setPhoneValidationIsLoading
1432
- : undefined
1433
- }
1434
- fill={element.type === 'phone' ? true : undefined}
1435
- label={getFieldLabel(element, configs)}
1436
- validate={getValidateFunctions(
1437
- element,
1438
- states,
1439
- props.values,
1440
- props.errors
1441
- )}
1442
- setFieldValue={props.setFieldValue}
1443
- onBlur={props.handleBlur}
1444
- component={getFieldComponent(element)}
1445
- selectOptions={
1446
- element.name === 'country'
1447
- ? _map(countries, item => ({
1448
- value: item.id,
1449
- label: item.name,
1450
- }))
1451
- : element.name === 'state'
1452
- ? [
1453
- {
1454
- label: element.label,
1455
- value: '',
1456
- disabled: true,
1457
- },
1458
- ...states,
1459
- ]
1460
- : element.selectOptions || []
1461
- }
1462
- theme={theme}
1463
- defaultCountry={
1464
- defaultCountry || element.defaultCountry
1465
- }
1466
- dateFormat={element.format}
1467
- isCountryCodeEditable={
1468
- isCountryCodeEditable
1469
- }
1470
- />
1471
- )}
1472
- </div>
1473
- </React.Fragment>
1474
- )
1475
- })}
1476
- </div>
1477
- {/* Show login suggestion if email is registered */}
1478
- {group.groupItems.some(el => el.name === 'confirmEmail') &&
1479
- emailExists &&
1480
- !isLoggedIn && (
1481
- <div className="email-registered-message">
1482
- <p className="email-registered-text">
1483
- ✓ This email is already registered. Log in to
1484
- auto-fill your information
1485
- </p>
1486
- <Button
1487
- type="button"
1488
- variant="contained"
1489
- className="email-login-button"
1490
- onClick={() => {
1491
- if (onLogin) {
1492
- onLogin()
1493
- } else {
1494
- setShowModalLogin(true)
1495
- }
1496
- }}
1497
- >
1498
- Log in
1499
- </Button>
1500
- </div>
1501
- )}
1502
- </React.Fragment>
1503
- )
1504
- })}
1505
- </div>
1506
- )
1507
- })}
1508
- {!_isEmpty(ticketHoldersFields.fields) && (
1509
- <div className="ticket-holders-fields">
1510
- <h2>{ticketHoldersFields.label}</h2>
1511
- {_map(ticketsQuantity, (_item, index) => (
1512
- <div key={_item}>
1513
- <h5>Ticket {index + 1}</h5>
1514
- {_map(ticketHoldersFields.fields, group => {
1515
- const { id, groupClassname, groupItems } = group
1516
- return (
1517
- <div key={id}>
1518
- <div className={groupClassname}>
1519
- {_map(groupItems, element => (
1520
- <div className={element.className} key={element.name}>
1521
- <Field
1522
- {...element}
1523
- type={
1524
- element.type === 'radio' ||
1525
- element.type === 'checkbox'
1526
- ? undefined
1527
- : element.type
1528
- }
1529
- name={`${element.name}-${index}`}
1530
- label={getFieldLabel(element, configs)}
1531
- component={getFieldComponent(element)}
1532
- validate={getValidateFunctions(
1533
- element,
1534
- states,
1535
- props.values,
1536
- props.errors
1537
- )}
1538
- setPhoneValidationIsLoading={
1539
- setPhoneValidationIsLoading
1540
- }
1541
- fill={element.type === 'phone' ? true : undefined}
1542
- defaultCountry={
1543
- defaultCountry || element.defaultCountry
1544
- }
1545
- isCountryCodeEditable={isCountryCodeEditable}
1546
- />
1547
- </div>
1548
- ))}
1549
- </div>
1550
- </div>
1551
- )
1552
- })}
1553
- </div>
1554
- ))}
1555
- </div>
1556
- )}
1557
- <div className="payment-section">
1558
- {isSinglePageCheckout && !orderIsFree && stripePublishableKey && (
1559
- <PaymentContainer
1560
- stripePublishableKey={stripePublishableKey}
1561
- stripeAccountId={stripeAccountId}
1562
- formTitle="Payment Information"
1563
- orderInfoLabel=""
1564
- enableTimer={false}
1565
- checkoutData={checkoutData}
1566
- elementsOptions={elementsOptions}
1567
- paymentElementOptions={{
1568
- fields: { billingDetails: { phone: 'never' } },
1569
- wallets: {
1570
- applePay:
1571
- checkoutUpdateData?.additional_payment_information
1572
- ?.stripe_wallets?.applePay || 'never',
1573
- googlePay:
1574
- checkoutUpdateData?.additional_payment_information
1575
- ?.stripe_wallets?.googlePay || 'never',
1576
- },
1577
- }}
1578
- onStripeReady={(stripe, elements) => {
1579
- stripeRef.current = stripe
1580
- elementsRef.current = elements
1581
- }}
1582
- paymentFields={paymentProps.paymentFields || []}
1583
- onPaymentError={paymentProps.onPaymentError || _identity}
1584
- handlePayment={paymentProps.handlePayment || _identity}
1585
- onGetPaymentDataSuccess={
1586
- paymentProps.onGetPaymentDataSuccess || _identity
1587
- }
1588
- onGetPaymentDataError={
1589
- paymentProps.onGetPaymentDataError || _identity
1590
- }
1591
- themeOptions={themeOptions}
1592
- paymentInfoLabel=""
1593
- displayPaymentButton={false}
1594
- hidePaymentForm={false}
1595
- hideFieldsBlock={true}
1596
- isSinglePageCheckout={true}
1597
- />
1598
- )}
1599
- {paymentSectionAddon}
1600
- </div>
1601
- <div className="button-container">
1602
- <Button
1603
- type="submit"
1604
- variant="contained"
1605
- className="login-register-button"
1606
- disabled={props.isSubmitting || phoneValidationIsLoading}
1607
- >
1608
- {props.isSubmitting ? (
1609
- <CircularProgress size={26} />
1610
- ) : orderIsFree ? (
1611
- freeOrderButtonName
1612
- ) : (
1613
- buttonName
1614
- )}
1615
- </Button>
1616
- </div>
1617
- </div>
1618
- </Form>
1619
- )}
1620
- </Formik>
1621
- )}
1622
- {showModalLogin && (
1623
- <LoginModal
1624
- logo={logo}
1625
- onClose={() => {
1626
- setShowModalLogin(false)
1627
- }}
1628
- onLogin={() => {
1629
- setShowModalLogin(false)
1630
- setUserExpired(false)
1631
- onLoginSuccess()
1632
- }}
1633
- alreadyHasUser={alreadyHasUser}
1634
- userExpired={userExpired}
1635
- onGetProfileDataSuccess={(data: any) => {
1636
- fetchCart()
1637
- onGetProfileDataSuccess(data)
1638
- }}
1639
- onGetProfileDataError={onGetProfileDataError}
1640
- showSignUpButton={showSignUpButton}
1641
- showForgotPasswordButton={showForgotPasswordButton}
1642
- onForgotPassword={() => {
1643
- setShowModalLogin(false)
1644
- setShowModalForgotPassword(true)
1645
- }}
1646
- onSignup={() => {
1647
- setShowModalLogin(false)
1648
- setShowModalSignup(true)
1649
- }}
1650
- showPoweredByImage={showPoweredByImage}
1651
- />
1652
- )}
1653
- {showModalSignup && (
1654
- <SignupModal
1655
- onClose={() => {
1656
- setShowModalSignup(false)
1657
- }}
1658
- onLogin={() => {
1659
- setShowModalSignup(false)
1660
- setShowModalLogin(true)
1661
- }}
1662
- onRegisterSuccess={onRegisterSuccess}
1663
- onRegisterError={onRegisterError}
1664
- showPoweredByImage={showPoweredByImage}
1665
- />
1666
- )}
1667
- {showModalForgotPassword && (
1668
- <ForgotPasswordModal
1669
- onClose={() => {
1670
- setShowModalForgotPassword(false)
1671
- }}
1672
- onLoginButtonClick={() => {
1673
- setShowModalForgotPassword(false)
1674
- setShowModalLogin(true)
1675
- }}
1676
- onForgotPasswordSuccess={onForgotPasswordSuccess}
1677
- onForgotPasswordError={onForgotPasswordError}
1678
- showPoweredByImage={showPoweredByImage}
1679
- displaySuccessMessage
1680
- />
1681
- )}
1682
- <VerificationPendingModal
1683
- message={pendingVerificationMessage}
1684
- onClose={() => {
1685
- onPendingVerification()
1686
- }}
1687
- />
1688
- </ThemeProvider>
1689
- )
1690
- }
1691
- )
1692
-
1693
- const WithCustomFieldsBillingInfoContainer = withCustomFields(BillingInfoContainer)
1694
-
1695
- export { WithCustomFieldsBillingInfoContainer as BillingInfoContainer }