tf-checkout-react 1.7.13 → 1.7.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.7.13",
2
+ "version": "1.7.14",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -3,36 +3,21 @@
3
3
 
4
4
  import { CircularProgress } from '@mui/material'
5
5
  import { Form, Formik } from 'formik'
6
- import _get from 'lodash/get'
7
6
  import _identity from 'lodash/identity'
8
7
  import _map from 'lodash/map'
9
- import React, { useEffect, useMemo, useState } from 'react'
8
+ import React, { useEffect, useState } from 'react'
10
9
  import { Tooltip } from 'react-tooltip'
11
10
 
12
- import { getAddons, getCart, getCheckoutPageConfigs, postOnCheckout } from '../../api'
13
11
  import { FEES_STYLES } from '../../constants'
14
12
  import { currencyNormalizerCreator } from '../../normalizers'
15
- import { ICheckoutPageConfigs } from '../../types'
16
- import {
17
- CONFIGS,
18
- createCheckoutDataBodyWithDefaultHolder,
19
- createMarkup,
20
- getQueryVariable,
21
- isBrowser,
22
- } from '../../utils'
13
+ import { CONFIGS, createMarkup, getQueryVariable, isBrowser } from '../../utils'
23
14
  import { VerificationPendingModal } from '../idVerificationContainer/VerificationPendingModal'
24
15
  import InfoIcon from '../ticketsContainer/InfoIcon'
25
16
  import TimerWidget from '../timerWidget'
26
- import { addonsWithGroupsAdapter, cartAdapter } from './adapters'
27
17
  import AddonComponent from './AddonComponent'
28
18
  import { getNormalizedPrice } from './normalizers'
29
- import {
30
- generateSelectOptions,
31
- getAddonSelectOptions,
32
- getSortedAddons,
33
- getTicketRelatedAddons,
34
- isAtLeastOneAddonSelected,
35
- } from './utils'
19
+ import { isAtLeastOneAddonSelected } from './utils'
20
+ import { useAddons } from './useAddons'
36
21
 
37
22
  export interface IAddonContainterProps {
38
23
  classNamePrefix?: string;
@@ -54,9 +39,6 @@ export interface IAddonContainterProps {
54
39
  onAddOnSelect?: (id: string, value: string, addon: any) => void;
55
40
  }
56
41
 
57
- export interface ObjectLiteral {
58
- [key: string]: any;
59
- }
60
42
 
61
43
  export const AddonsContainter = ({
62
44
  classNamePrefix = 'add_on',
@@ -76,15 +58,28 @@ export const AddonsContainter = ({
76
58
  configs,
77
59
  onAddOnSelect = _identity,
78
60
  }: IAddonContainterProps) => {
79
- const eventId = getQueryVariable('event_id')
80
- const [addons, setAddons] = useState<any>([])
81
- const [addonsOptions, setAddonsOptions] = useState<any>({})
82
- const [groupsWithSelectedVariants, setGroupsWithSelectedVariants] = useState<any>({})
83
- const [groupsWithInitialVariantsValues, setGroupsWithInitialVariantsValues] =
84
- useState<any>({})
85
- const [loading, setLoading] = useState(true)
86
- const [cartExpirationTime, setCartExpirationTime] = useState(0)
87
- const [pendingVerificationMessage, setPendingVerificationMessage] = useState()
61
+ const eventId = getQueryVariable('event_id') || null
62
+
63
+ const {
64
+ addons,
65
+ addonsOptions,
66
+ loading,
67
+ cartExpirationTime,
68
+ pendingVerificationMessage,
69
+ initialValues,
70
+ onFieldChange,
71
+ handleConfirm,
72
+ handleClearAddons,
73
+ } = useAddons(eventId, {
74
+ enableBillingInfoAutoCreate,
75
+ addOnDataWithCustomFields,
76
+ onGetAddonsPageInfoSuccess,
77
+ onGetAddonsPageInfoError,
78
+ onPostCheckoutSuccess,
79
+ onPostCheckoutError,
80
+ onConfirmSelectionSuccess,
81
+ onConfirmSelectionError,
82
+ })
88
83
 
89
84
  const [visibleDescription, setVisibleDescription] = useState<string | null>(null)
90
85
 
@@ -96,207 +91,8 @@ export const AddonsContainter = ({
96
91
  if (samePage) {
97
92
  window.localStorage.removeItem('add_ons')
98
93
  }
99
- const getAddonsPageInfo = async () => {
100
- try {
101
- if (eventId) {
102
- setLoading(true)
103
-
104
- // Get choosed ticket info (id, count) from Cart request for addons options calculations
105
- const cart = await getCart()
106
- const { id: choosedTicketID, quantity, expiresAt } = cartAdapter(cart)
107
- const choosedTicketCount = Number(quantity)
108
- setCartExpirationTime(expiresAt)
109
-
110
- // Get and collect addons data
111
- const addonsData = await getAddons(eventId)
112
- const adaptedAddons = addonsWithGroupsAdapter(addonsData)
113
- const ticketRelatedAddons = getTicketRelatedAddons(
114
- adaptedAddons,
115
- choosedTicketID
116
- )
117
- const sortedTicketAddons = getSortedAddons(ticketRelatedAddons)
118
-
119
- setAddons(sortedTicketAddons)
120
-
121
- // Collect addons and addon group options
122
- const {
123
- addonsWithOptions,
124
- groupsWithSelectedVariantsInfo,
125
- groupsWithVariants,
126
- } = getAddonSelectOptions(adaptedAddons, choosedTicketCount)
127
-
128
- setAddonsOptions(addonsWithOptions)
129
- setGroupsWithSelectedVariants(groupsWithSelectedVariantsInfo)
130
- setGroupsWithInitialVariantsValues(groupsWithVariants)
131
-
132
- // Success callback props
133
- onGetAddonsPageInfoSuccess(addonsData)
134
- }
135
- } catch (e) {
136
- // Callback error props
137
- onGetAddonsPageInfoError(e)
138
- } finally {
139
- setLoading(false)
140
- }
141
- }
142
-
143
- getAddonsPageInfo()
144
94
  }, [])
145
95
 
146
- const recreateGroupVariantsSelectOptions = (groupId: any, changedGroupd: any) => {
147
- const { choosedVariants, limit, selectedCount } = changedGroupd
148
- const remainingGroupStock = limit - selectedCount
149
- const recreatedVariantsOptions: ObjectLiteral = {}
150
-
151
- // Regenerate variants allowed stock counts
152
- for (const variant in choosedVariants) {
153
- const variantId = variant
154
- const variantCurrSelectedValue = choosedVariants[variant]
155
- let allowedOptionCount
156
-
157
- // Formula for regenerating
158
- if (
159
- remainingGroupStock >=
160
- groupsWithInitialVariantsValues[groupId][variantId] - variantCurrSelectedValue
161
- ) {
162
- allowedOptionCount = groupsWithInitialVariantsValues[groupId][variantId]
163
- } else {
164
- allowedOptionCount = remainingGroupStock + variantCurrSelectedValue
165
- }
166
-
167
- recreatedVariantsOptions[variantId] = generateSelectOptions(0, allowedOptionCount)
168
- }
169
-
170
- setAddonsOptions((prevState: any) =>
171
- Object.assign({}, prevState, recreatedVariantsOptions)
172
- )
173
- }
174
-
175
- const onFieldChange = (id: any, value: any, addon: any) => {
176
- // If changeableGroup exsists it means that group with limitation variant was changed
177
- const changeableGroup = groupsWithSelectedVariants[addon.id]
178
-
179
- if (changeableGroup) {
180
- const currGroupId = addon.id
181
- const currSelectedVariantId = id
182
- const currSelectedVariantCount = Number(value)
183
- const currSelectedVariantPrevCount =
184
- groupsWithSelectedVariants[currGroupId].choosedVariants[currSelectedVariantId]
185
-
186
- const currSelectedGroupCount =
187
- changeableGroup.selectedCount +
188
- (currSelectedVariantCount - currSelectedVariantPrevCount)
189
-
190
- // Update Group info
191
- const updatedGroupsWithSelectedVariants = {
192
- ...groupsWithSelectedVariants,
193
- [currGroupId]: {
194
- ...groupsWithSelectedVariants[currGroupId],
195
- selectedCount: currSelectedGroupCount,
196
- choosedVariants: {
197
- ...groupsWithSelectedVariants[currGroupId].choosedVariants,
198
- [currSelectedVariantId]: currSelectedVariantCount,
199
- },
200
- },
201
- }
202
- setGroupsWithSelectedVariants(updatedGroupsWithSelectedVariants)
203
-
204
- // Recreate Select Options for Addon Group Variants
205
- recreateGroupVariantsSelectOptions(
206
- currGroupId,
207
- updatedGroupsWithSelectedVariants[currGroupId]
208
- )
209
- }
210
- }
211
-
212
- const handleConfirm = async (values: any, skipAddonPage?: boolean) => {
213
- try {
214
- const pageConfigsDataResponse = await getCheckoutPageConfigs()
215
- const pageConfigsData: ICheckoutPageConfigs =
216
- _get(pageConfigsDataResponse, 'data.attributes') || {}
217
-
218
- const skipBillingPage = pageConfigsData.skip_billing_page ?? false
219
-
220
- if (skipBillingPage && enableBillingInfoAutoCreate) {
221
- const ticketsQuantity = window.localStorage.getItem('quantity')
222
- const userData = JSON.parse(window.localStorage.getItem('user_data') || '{}')
223
-
224
- const checkoutBody = createCheckoutDataBodyWithDefaultHolder(
225
- Number(ticketsQuantity) || 0,
226
- userData
227
- )
228
-
229
- try {
230
- const checkoutResponse = await postOnCheckout({
231
- ...checkoutBody,
232
- attributes: {
233
- ...checkoutBody.attributes,
234
- ...(!skipAddonPage && { add_ons: values }),
235
- },
236
- })
237
- const hash = checkoutResponse?.data?.attributes?.hash || ''
238
- const total = checkoutResponse?.data?.attributes?.total || ''
239
-
240
- isBrowser && window.localStorage.removeItem('quantity')
241
- isBrowser && window.localStorage.removeItem('add_ons')
242
-
243
- onPostCheckoutSuccess(checkoutResponse?.data.attributes)
244
- onConfirmSelectionSuccess({
245
- skip_billing_page: skipBillingPage,
246
- event_id: String(eventId),
247
- hash,
248
- total,
249
- })
250
- } catch (error) {
251
- if ((error as any).response?.data?.data?.hasUnverifiedOrder) {
252
- setPendingVerificationMessage((error as any).response?.data?.message)
253
- } else {
254
- onPostCheckoutError(error)
255
- onConfirmSelectionError(error)
256
- }
257
- }
258
- } else {
259
- if (isBrowser) {
260
- if (!skipAddonPage) {
261
- window.localStorage.setItem('add_ons', JSON.stringify(values))
262
- }
263
-
264
- onConfirmSelectionSuccess({
265
- skip_billing_page: skipBillingPage && enableBillingInfoAutoCreate,
266
- event_id: String(eventId),
267
- })
268
- } else {
269
- onConfirmSelectionError({
270
- error: true,
271
- message: 'Window is not defined',
272
- })
273
- }
274
- }
275
- } catch (e) {
276
- onConfirmSelectionError(e)
277
- }
278
- }
279
-
280
- const handleClearAddons = () => {
281
- window.localStorage.removeItem('add_ons')
282
- }
283
-
284
- const initialValues = useMemo(() => {
285
- const addOnsData: any = {}
286
- if (addons?.length > 0 && addOnDataWithCustomFields?.fields?.length > 0) {
287
- _map(addons, addon => {
288
- _map(addOnDataWithCustomFields.fields, field => {
289
- const { id, groupItems } = field
290
- _map(groupItems, item => {
291
- addOnsData[`${addon.id}-${id}-${item.name}`] = item.value
292
- })
293
- })
294
- })
295
- }
296
-
297
- return addOnsData
298
- }, [addons, addOnDataWithCustomFields])
299
-
300
96
  if (loading) {
301
97
  return (
302
98
  <div className={`${classNamePrefix}_loader`}>
@@ -0,0 +1,248 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import _get from 'lodash/get'
3
+ import _identity from 'lodash/identity'
4
+ import _map from 'lodash/map'
5
+ import { useEffect, useMemo, useState } from 'react'
6
+
7
+ import { getAddons, getCart, getCheckoutPageConfigs, postOnCheckout } from '../../api'
8
+ import { ICheckoutPageConfigs } from '../../types'
9
+ import { createCheckoutDataBodyWithDefaultHolder, isBrowser } from '../../utils'
10
+ import { addonsWithGroupsAdapter, cartAdapter } from './adapters'
11
+ import {
12
+ generateSelectOptions,
13
+ getAddonSelectOptions,
14
+ getSortedAddons,
15
+ getTicketRelatedAddons,
16
+ } from './utils'
17
+
18
+ interface ObjectLiteral {
19
+ [key: string]: any;
20
+ }
21
+
22
+ export interface IUseAddonsOptions {
23
+ enableBillingInfoAutoCreate?: boolean;
24
+ addOnDataWithCustomFields?: any;
25
+ onGetAddonsPageInfoSuccess?: (res: any) => void;
26
+ onGetAddonsPageInfoError?: (error: any) => void;
27
+ onPostCheckoutSuccess?: (res: any) => void;
28
+ onPostCheckoutError?: (error: any) => void;
29
+ onConfirmSelectionSuccess?: (res: any) => void;
30
+ onConfirmSelectionError?: (error: any) => void;
31
+ }
32
+
33
+ export const useAddons = (eventId: string | null, options: IUseAddonsOptions = {}) => {
34
+ const {
35
+ enableBillingInfoAutoCreate = true,
36
+ addOnDataWithCustomFields,
37
+ onGetAddonsPageInfoSuccess = _identity,
38
+ onGetAddonsPageInfoError = _identity,
39
+ onPostCheckoutSuccess = _identity,
40
+ onPostCheckoutError = _identity,
41
+ onConfirmSelectionSuccess = _identity,
42
+ onConfirmSelectionError = _identity,
43
+ } = options
44
+
45
+ const [addons, setAddons] = useState<any>([])
46
+ const [addonsOptions, setAddonsOptions] = useState<any>({})
47
+ const [groupsWithSelectedVariants, setGroupsWithSelectedVariants] = useState<any>({})
48
+ const [groupsWithInitialVariantsValues, setGroupsWithInitialVariantsValues] = useState<any>({})
49
+ const [loading, setLoading] = useState(true)
50
+ const [cartExpirationTime, setCartExpirationTime] = useState(0)
51
+ const [pendingVerificationMessage, setPendingVerificationMessage] = useState<any>()
52
+
53
+ useEffect(() => {
54
+ const getAddonsPageInfo = async () => {
55
+ try {
56
+ if (eventId) {
57
+ setLoading(true)
58
+
59
+ const cart = await getCart()
60
+ const { id: choosedTicketID, quantity, expiresAt } = cartAdapter(cart)
61
+ const choosedTicketCount = Number(quantity)
62
+ setCartExpirationTime(expiresAt)
63
+
64
+ const addonsData = await getAddons(eventId)
65
+ const adaptedAddons = addonsWithGroupsAdapter(addonsData)
66
+ const ticketRelatedAddons = getTicketRelatedAddons(adaptedAddons, choosedTicketID)
67
+ const sortedTicketAddons = getSortedAddons(ticketRelatedAddons)
68
+
69
+ setAddons(sortedTicketAddons)
70
+
71
+ const {
72
+ addonsWithOptions,
73
+ groupsWithSelectedVariantsInfo,
74
+ groupsWithVariants,
75
+ } = getAddonSelectOptions(adaptedAddons, choosedTicketCount)
76
+
77
+ setAddonsOptions(addonsWithOptions)
78
+ setGroupsWithSelectedVariants(groupsWithSelectedVariantsInfo)
79
+ setGroupsWithInitialVariantsValues(groupsWithVariants)
80
+
81
+ onGetAddonsPageInfoSuccess(addonsData)
82
+ }
83
+ } catch (e) {
84
+ onGetAddonsPageInfoError(e)
85
+ } finally {
86
+ setLoading(false)
87
+ }
88
+ }
89
+
90
+ getAddonsPageInfo()
91
+ }, [eventId])
92
+
93
+ const recreateGroupVariantsSelectOptions = (groupId: any, changedGroup: any) => {
94
+ const { choosedVariants, limit, selectedCount } = changedGroup
95
+ const remainingGroupStock = limit - selectedCount
96
+ const recreatedVariantsOptions: ObjectLiteral = {}
97
+
98
+ for (const variant in choosedVariants) {
99
+ const variantId = variant
100
+ const variantCurrSelectedValue = choosedVariants[variant]
101
+ let allowedOptionCount
102
+
103
+ if (
104
+ remainingGroupStock >=
105
+ groupsWithInitialVariantsValues[groupId][variantId] - variantCurrSelectedValue
106
+ ) {
107
+ allowedOptionCount = groupsWithInitialVariantsValues[groupId][variantId]
108
+ } else {
109
+ allowedOptionCount = remainingGroupStock + variantCurrSelectedValue
110
+ }
111
+
112
+ recreatedVariantsOptions[variantId] = generateSelectOptions(0, allowedOptionCount)
113
+ }
114
+
115
+ setAddonsOptions((prevState: any) => Object.assign({}, prevState, recreatedVariantsOptions))
116
+ }
117
+
118
+ const onFieldChange = (id: any, value: any, addon: any) => {
119
+ const changeableGroup = groupsWithSelectedVariants[addon.id]
120
+
121
+ if (changeableGroup) {
122
+ const currGroupId = addon.id
123
+ const currSelectedVariantId = id
124
+ const currSelectedVariantCount = Number(value)
125
+ const currSelectedVariantPrevCount =
126
+ groupsWithSelectedVariants[currGroupId].choosedVariants[currSelectedVariantId]
127
+
128
+ const currSelectedGroupCount =
129
+ changeableGroup.selectedCount +
130
+ (currSelectedVariantCount - currSelectedVariantPrevCount)
131
+
132
+ const updatedGroupsWithSelectedVariants = {
133
+ ...groupsWithSelectedVariants,
134
+ [currGroupId]: {
135
+ ...groupsWithSelectedVariants[currGroupId],
136
+ selectedCount: currSelectedGroupCount,
137
+ choosedVariants: {
138
+ ...groupsWithSelectedVariants[currGroupId].choosedVariants,
139
+ [currSelectedVariantId]: currSelectedVariantCount,
140
+ },
141
+ },
142
+ }
143
+ setGroupsWithSelectedVariants(updatedGroupsWithSelectedVariants)
144
+
145
+ recreateGroupVariantsSelectOptions(
146
+ currGroupId,
147
+ updatedGroupsWithSelectedVariants[currGroupId]
148
+ )
149
+ }
150
+ }
151
+
152
+ const handleConfirm = async (values: any, skipAddonPage?: boolean) => {
153
+ try {
154
+ const pageConfigsDataResponse = await getCheckoutPageConfigs()
155
+ const pageConfigsData: ICheckoutPageConfigs =
156
+ _get(pageConfigsDataResponse, 'data.attributes') || {}
157
+
158
+ const skipBillingPage = pageConfigsData.skip_billing_page ?? false
159
+
160
+ if (skipBillingPage && enableBillingInfoAutoCreate) {
161
+ const ticketsQuantity = window.localStorage.getItem('quantity')
162
+ const userData = JSON.parse(window.localStorage.getItem('user_data') || '{}')
163
+
164
+ const checkoutBody = createCheckoutDataBodyWithDefaultHolder(
165
+ Number(ticketsQuantity) || 0,
166
+ userData
167
+ )
168
+
169
+ try {
170
+ const checkoutResponse = await postOnCheckout({
171
+ ...checkoutBody,
172
+ attributes: {
173
+ ...checkoutBody.attributes,
174
+ ...(!skipAddonPage && { add_ons: values }),
175
+ },
176
+ })
177
+ const hash = checkoutResponse?.data?.attributes?.hash || ''
178
+ const total = checkoutResponse?.data?.attributes?.total || ''
179
+
180
+ isBrowser && window.localStorage.removeItem('quantity')
181
+ isBrowser && window.localStorage.removeItem('add_ons')
182
+
183
+ onPostCheckoutSuccess(checkoutResponse?.data.attributes)
184
+ onConfirmSelectionSuccess({
185
+ skip_billing_page: skipBillingPage,
186
+ event_id: String(eventId),
187
+ hash,
188
+ total,
189
+ })
190
+ } catch (error) {
191
+ if ((error as any).response?.data?.data?.hasUnverifiedOrder) {
192
+ setPendingVerificationMessage((error as any).response?.data?.message)
193
+ } else {
194
+ onPostCheckoutError(error)
195
+ onConfirmSelectionError(error)
196
+ }
197
+ }
198
+ } else {
199
+ if (isBrowser) {
200
+ if (!skipAddonPage) {
201
+ window.localStorage.setItem('add_ons', JSON.stringify(values))
202
+ }
203
+
204
+ onConfirmSelectionSuccess({
205
+ skip_billing_page: skipBillingPage && enableBillingInfoAutoCreate,
206
+ event_id: String(eventId),
207
+ })
208
+ } else {
209
+ onConfirmSelectionError({ error: true, message: 'Window is not defined' })
210
+ }
211
+ }
212
+ } catch (e) {
213
+ onConfirmSelectionError(e)
214
+ }
215
+ }
216
+
217
+ const handleClearAddons = () => {
218
+ window.localStorage.removeItem('add_ons')
219
+ }
220
+
221
+ const initialValues = useMemo(() => {
222
+ const addOnsData: any = {}
223
+ if (addons?.length > 0 && addOnDataWithCustomFields?.fields?.length > 0) {
224
+ _map(addons, addon => {
225
+ _map(addOnDataWithCustomFields.fields, field => {
226
+ const { id, groupItems } = field
227
+ _map(groupItems, item => {
228
+ addOnsData[`${addon.id}-${id}-${item.name}`] = item.value
229
+ })
230
+ })
231
+ })
232
+ }
233
+ return addOnsData
234
+ }, [addons, addOnDataWithCustomFields])
235
+
236
+ return {
237
+ addons,
238
+ addonsOptions,
239
+ loading,
240
+ cartExpirationTime,
241
+ pendingVerificationMessage,
242
+ setPendingVerificationMessage,
243
+ initialValues,
244
+ onFieldChange,
245
+ handleConfirm,
246
+ handleClearAddons,
247
+ }
248
+ }
package/src/index.ts CHANGED
@@ -13,6 +13,9 @@ export { RsvpContainer } from './components/rsvpContainer'
13
13
  export { ResetPasswordContainer } from './components/resetPasswordContainer'
14
14
  export { ForgotPasswordModal } from './components/forgotPasswordModal'
15
15
  export { AddonsContainter } from './components/addonsContainer'
16
+ export { useAddons } from './components/addonsContainer/useAddons'
17
+ export { default as TimerWidget } from './components/timerWidget'
18
+ export { VerificationPendingModal } from './components/idVerificationContainer/VerificationPendingModal'
16
19
  export { PreRegistration } from './components/preRegistration'
17
20
  export { PreRegistrationComplete } from './components/preRegistration/PreRegistrationComplete'
18
21
  export { PreRegistrationInformations } from './components/preRegistration/PreRegistrationInformations'