tf-checkout-react 1.5.9 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/adapters/customFields.d.ts +11 -0
  2. package/dist/adapters/index.d.ts +1 -0
  3. package/dist/api/index.d.ts +6 -0
  4. package/dist/components/billing-info-container/index.d.ts +5 -2
  5. package/dist/components/billing-info-container/utils.d.ts +7 -5
  6. package/dist/components/common/Checkbox.d.ts +11 -0
  7. package/dist/components/common/CheckboxField/index.d.ts +9 -0
  8. package/dist/components/common/index.d.ts +1 -0
  9. package/dist/components/idVerificationContainer/constants.d.ts +4 -0
  10. package/dist/components/idVerificationContainer/index.d.ts +1 -1
  11. package/dist/components/orderDetailsContainer/CustomFieldsForm.d.ts +12 -0
  12. package/dist/components/orderDetailsContainer/TicketHolderCustomFields.d.ts +10 -0
  13. package/dist/components/orderDetailsContainer/index.d.ts +29 -1
  14. package/dist/components/orderDetailsContainer/ticketsTable.d.ts +4 -1
  15. package/dist/components/orderDetailsContainer/utils/index.d.ts +6 -0
  16. package/dist/components/ticketsContainer/index.d.ts +2 -1
  17. package/dist/hoc/CustomFields/index.d.ts +3 -0
  18. package/dist/hoc/index.d.ts +1 -0
  19. package/dist/images/edit.svg +10 -0
  20. package/dist/tf-checkout-react.cjs.development.js +1080 -307
  21. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  22. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  23. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  24. package/dist/tf-checkout-react.esm.js +1082 -309
  25. package/dist/tf-checkout-react.esm.js.map +1 -1
  26. package/dist/types/billing-info-data.d.ts +2 -2
  27. package/dist/types/verification.d.ts +2 -1
  28. package/dist/utils/createCheckoutDataBodyWithDefaultHolder.d.ts +3 -0
  29. package/dist/utils/customFields.d.ts +24 -0
  30. package/dist/utils/index.d.ts +1 -0
  31. package/package.json +1 -1
  32. package/src/adapters/customFields.ts +79 -0
  33. package/src/adapters/index.ts +1 -0
  34. package/src/api/index.ts +43 -0
  35. package/src/assets/images/edit.svg +10 -0
  36. package/src/components/billing-info-container/index.tsx +106 -60
  37. package/src/components/billing-info-container/utils.ts +29 -5
  38. package/src/components/common/{CheckboxField.tsx → Checkbox.tsx} +3 -3
  39. package/src/components/common/CheckboxField/index.tsx +41 -0
  40. package/src/components/common/CustomField.tsx +1 -1
  41. package/src/components/common/RadioGroupField/index.tsx +1 -1
  42. package/src/components/common/SelectField/index.tsx +1 -1
  43. package/src/components/common/index.tsx +1 -0
  44. package/src/components/idVerificationContainer/constants.ts +5 -0
  45. package/src/components/idVerificationContainer/index.tsx +81 -29
  46. package/src/components/orderDetailsContainer/CustomFieldsForm.tsx +75 -0
  47. package/src/components/orderDetailsContainer/TicketHolderCustomFields.tsx +100 -0
  48. package/src/components/orderDetailsContainer/index.tsx +175 -20
  49. package/src/components/orderDetailsContainer/ticketsTable.tsx +55 -33
  50. package/src/components/orderDetailsContainer/utils/index.tsx +55 -0
  51. package/src/components/paymentContainer/PaymentPlanSection.tsx +52 -35
  52. package/src/components/paymentContainer/index.tsx +2 -2
  53. package/src/components/stripePayment/index.tsx +2 -2
  54. package/src/components/ticketResale/index.tsx +4 -1
  55. package/src/components/ticketsContainer/index.tsx +4 -0
  56. package/src/hoc/CustomFields/index.tsx +77 -0
  57. package/src/hoc/index.ts +1 -0
  58. package/src/types/billing-info-data.ts +2 -2
  59. package/src/types/verification.ts +2 -1
  60. package/src/utils/createCheckoutDataBodyWithDefaultHolder.ts +3 -0
  61. package/src/utils/customFields.ts +58 -0
  62. package/src/utils/index.ts +1 -0
  63. package/dist/components/common/CheckboxField.d.ts +0 -11
@@ -15,12 +15,12 @@ export interface IFieldData {
15
15
  groupClassname?: string;
16
16
  groupLabel?: string | JSX.Element | HTMLElement;
17
17
  groupLabelClassName?: string;
18
- id: number;
18
+ id?: number;
19
19
  uniqueId?: string;
20
20
  }
21
21
  export interface IBillingInfoData {
22
- id: number | string;
23
22
  fields: IFieldData[];
23
+ id?: number | string;
24
24
  label?: string | JSX.Element;
25
25
  labelClassName?: string;
26
26
  uniqueId?: string;
@@ -1,5 +1,6 @@
1
1
  export interface GetNetverifyUrlResponseData {
2
- netverifyUrl: string;
2
+ netverifyUrl: string | null;
3
+ provider: string | null;
3
4
  }
4
5
  export interface VerificationStatusResponseData {
5
6
  attributes: {
@@ -3,6 +3,9 @@ interface ICheckoutBody {
3
3
  attributes: {
4
4
  [key: string]: Type1 | Record<string | number, Type1> | Array<Type1 | IticketHolder>;
5
5
  };
6
+ data_capture?: {
7
+ [key: string]: any;
8
+ };
6
9
  }
7
10
  interface IticketHolder {
8
11
  first_name?: string;
@@ -0,0 +1,24 @@
1
+ /// <reference types="react" />
2
+ import { IBillingInfoData } from '../types';
3
+ export declare const getDataWithCustomFields: (initialData: IBillingInfoData[], ticketHoldersFields: IBillingInfoData, customFields: any) => {
4
+ dataWithCustomFields: {
5
+ fields: import("../types").IFieldData[];
6
+ id?: string | number | undefined;
7
+ label?: string | JSX.Element | undefined;
8
+ labelClassName?: string | undefined;
9
+ uniqueId?: string | undefined;
10
+ }[];
11
+ ticketHoldersWithCustomFields: {
12
+ fields: (import("../types").IFieldData | {
13
+ id: number;
14
+ customFields: boolean;
15
+ groupClassname: string;
16
+ groupItems: any[];
17
+ })[];
18
+ id?: string | number | undefined;
19
+ label?: string | JSX.Element | undefined;
20
+ labelClassName?: string | undefined;
21
+ uniqueId?: string | undefined;
22
+ };
23
+ };
24
+ export declare const getFieldsKeys: (customFields: any) => any[];
@@ -10,5 +10,6 @@ export { replaceVarInString } from './replaceVarInString';
10
10
  export { isBrowser } from './isBrowser';
11
11
  export { getFormInitialValues } from './form';
12
12
  export { setLoggedUserData } from './auth';
13
+ export { getDataWithCustomFields, getFieldsKeys } from './customFields';
13
14
  export { createElementFromHTML } from './htmlNodeFromString';
14
15
  export { isJson } from './jsonUtils';
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.5.9",
2
+ "version": "1.6.1",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -0,0 +1,79 @@
1
+ import _forEach from 'lodash/forEach'
2
+ import _get from 'lodash/get'
3
+ import _map from 'lodash/map'
4
+
5
+ import { IGroupItem } from '../types'
6
+
7
+ export const optionsAdapter = (options: any) => {
8
+ const adaptedOptions = _map(options, option => ({
9
+ id: option.id,
10
+ label: option.name,
11
+ value: option.value,
12
+ }))
13
+ return adaptedOptions
14
+ }
15
+
16
+ export const fieldDataAdapter = (field: IGroupItem) => {
17
+ const {
18
+ name,
19
+ label,
20
+ required,
21
+ description,
22
+ type,
23
+ options,
24
+ ...restValues
25
+ } = field
26
+
27
+ const adaptedField: IGroupItem = {
28
+ name,
29
+ label,
30
+ required,
31
+ description,
32
+ type,
33
+ className: _get(restValues, 'settings.className', ''),
34
+ value: _get(restValues, 'defaultValue'),
35
+ }
36
+
37
+ switch (type) {
38
+ case 'textarea':
39
+ adaptedField.type = 'text'
40
+ adaptedField.multiline = true
41
+ break
42
+ case 'radio':
43
+ adaptedField.radios = optionsAdapter(options)
44
+ break
45
+ case 'select_multi':
46
+ adaptedField.isMultiple = true
47
+ adaptedField.options = optionsAdapter(options)
48
+ break
49
+ case 'select':
50
+ adaptedField.type = 'select_multi'
51
+ adaptedField.isMultiple = false
52
+ adaptedField.options = optionsAdapter(options)
53
+ break
54
+ default:
55
+ break
56
+ }
57
+
58
+ return adaptedField
59
+ }
60
+
61
+ export const customFieldsDataAdapter = (data: any) => {
62
+ const adaptedTicketFields: Array<IGroupItem> = []
63
+ const adaptedOrderFields: Array<IGroupItem> = []
64
+
65
+ _forEach(data, field => {
66
+ const ticketFields = _get(field, 'ticket.group.fields')
67
+ const orderFields = _get(field, 'order.group.fields')
68
+
69
+ _forEach(ticketFields, ticketField => {
70
+ adaptedTicketFields.push(fieldDataAdapter(ticketField))
71
+ })
72
+
73
+ _forEach(orderFields, orderField => {
74
+ adaptedOrderFields.push(fieldDataAdapter(orderField))
75
+ })
76
+ })
77
+
78
+ return { ticketsFields: adaptedTicketFields, orderFields: adaptedOrderFields }
79
+ }
@@ -0,0 +1 @@
1
+ export { customFieldsDataAdapter } from './customFields'
package/src/api/index.ts CHANGED
@@ -3,6 +3,7 @@ import './interceptors'
3
3
  import { AxiosRequestConfig, AxiosResponse } from 'axios'
4
4
  import _get from 'lodash/get'
5
5
 
6
+ import { customFieldsDataAdapter } from '../adapters'
6
7
  import {
7
8
  GetNetverifyUrlResponseData,
8
9
  UpdateVerificationStatusResponseData,
@@ -152,6 +153,48 @@ export const getCheckoutPageConfigs = async (): Promise<ResponseConfigs> => {
152
153
  return response.data
153
154
  }
154
155
 
156
+
157
+ export const getCustomFields = async (eventId: string) => {
158
+ const response = await publicRequest.get(`/v1/event/${eventId}/custom_fields`)
159
+ const customFields = _get(response, 'data.data.attributes', [])
160
+ const adaptedResponse = customFieldsDataAdapter(customFields)
161
+ return adaptedResponse
162
+ }
163
+
164
+ export const updateOrderCustomFields = async (
165
+ eventId: string,
166
+ orderId: string,
167
+ customFieldsData: Record<string, any>
168
+ ) => {
169
+ const response = await publicRequest.put(`v1/event/${eventId}/order-data-capture`, {
170
+ data: {
171
+ attributes: {
172
+ order_id: orderId,
173
+ data_capture: customFieldsData,
174
+ },
175
+ },
176
+ })
177
+ return response
178
+ }
179
+
180
+ export const updateTicketHoldersCustomFields = async (
181
+ eventId: string,
182
+ customFieldsData: Record<string, any>,
183
+ ticketHash: string
184
+ ) => {
185
+ const response = await publicRequest.put(`v1/event/${eventId}/ticket-data-capture`, {
186
+ data: {
187
+ attributes: {
188
+ ticket_hash: ticketHash,
189
+ ticket_data_capture: {
190
+ [ticketHash]: customFieldsData,
191
+ },
192
+ },
193
+ },
194
+ })
195
+ return response
196
+ }
197
+
155
198
  export const confirmPreRegistration = async (
156
199
  eventId: string | number,
157
200
  data: IConfirmPreRegistrationRequestData
@@ -0,0 +1,10 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g clip-path="url(#clip0_996_11495)">
3
+ <path d="M6.162 12.6667L5 13.6667L2 14.0001V11.1714L8.6 4.57139L11.428 7.40072L6.16133 12.6667H6.162ZM9.542 3.62939L10.9567 2.21472C11.0817 2.08974 11.2512 2.01953 11.428 2.01953C11.6048 2.01953 11.7743 2.08974 11.8993 2.21472L13.7853 4.10072C13.9103 4.22574 13.9805 4.39528 13.9805 4.57206C13.9805 4.74883 13.9103 4.91837 13.7853 5.04339L12.3707 6.45739L9.54267 3.62939H9.542Z" fill="#03053D"/>
4
+ </g>
5
+ <defs>
6
+ <clipPath id="clip0_996_11495">
7
+ <rect width="16" height="16" fill="white"/>
8
+ </clipPath>
9
+ </defs>
10
+ </svg>
@@ -8,6 +8,7 @@ import { CSSProperties } from '@mui/styles'
8
8
  import axios, { AxiosError } from 'axios'
9
9
  import { Field, Form, Formik, FormikHelpers, FormikProps, FormikValues } from 'formik'
10
10
  import _find from 'lodash/find'
11
+ import _forEach from 'lodash/forEach'
11
12
  import _get from 'lodash/get'
12
13
  import _identity from 'lodash/identity'
13
14
  import _includes from 'lodash/includes'
@@ -28,6 +29,7 @@ import {
28
29
  register,
29
30
  setCustomHeader,
30
31
  } from '../../api'
32
+ import { withCustomFields } from '../../hoc'
31
33
  import { usePixel } from '../../hooks/usePixel'
32
34
  import { IBillingInfoData } from '../../types'
33
35
  import {
@@ -38,7 +40,6 @@ import {
38
40
  setLoggedUserData,
39
41
  } from '../../utils'
40
42
  import { ErrorFocus } from '../../utils/formikErrorFocus'
41
- import { combineValidators, requiredValidator } from '../../validators'
42
43
  import SnackbarAlert from '../common/SnackbarAlert'
43
44
  import { ForgotPasswordModal } from '../forgotPasswordModal'
44
45
  import { VerificationPendingModal } from '../idVerificationContainer/VerificationPendingModal'
@@ -53,6 +54,7 @@ import {
53
54
  getFieldLabel,
54
55
  getInitialValues,
55
56
  getValidateFunctions,
57
+ ICheckoutBody,
56
58
  } from './utils'
57
59
 
58
60
  export interface IBillingInfoPage {
@@ -105,7 +107,8 @@ export interface IBillingInfoPage {
105
107
  brandOptIn?: boolean;
106
108
  showPoweredByImage?: boolean;
107
109
  isCountryCodeEditable?: boolean;
108
-
110
+ customFieldsOrderKeys?: string[];
111
+ customFieldsTicketHolderKeys?: string[];
109
112
  onPendingVerification?: () => void;
110
113
  }
111
114
 
@@ -197,7 +200,7 @@ const LogicRunner: FC<{
197
200
  return null
198
201
  }
199
202
 
200
- export const BillingInfoContainer = React.memo(
203
+ const BillingInfoContainer = React.memo(
201
204
  ({
202
205
  data = [],
203
206
  ticketHoldersFields = {
@@ -240,6 +243,8 @@ export const BillingInfoContainer = React.memo(
240
243
  showSignUpButton = false,
241
244
  brandOptIn = false,
242
245
  showPoweredByImage = false,
246
+ customFieldsOrderKeys,
247
+ customFieldsTicketHolderKeys,
243
248
  isCountryCodeEditable = true,
244
249
  onPendingVerification = _identity,
245
250
  onGetCheckoutConfigsSuccess = _identity,
@@ -381,6 +386,7 @@ export const BillingInfoContainer = React.memo(
381
386
  setIsLoggedIn(!!(pIsLoggedIn || xtfCookie))
382
387
  }
383
388
  }, [pIsLoggedIn, isLoggedIn, xtfCookie])
389
+
384
390
  //just once
385
391
  useEffect(() => {
386
392
  // fetch countries data
@@ -400,6 +406,10 @@ export const BillingInfoContainer = React.memo(
400
406
  }
401
407
  shouldFetchCountries && fetchCountries()
402
408
  fetchCart()
409
+
410
+ return () => {
411
+ isBrowser && localStorage.removeItem('selectedTicketsQuantity')
412
+ }
403
413
  }, [])
404
414
 
405
415
  // fetch cart data
@@ -421,6 +431,7 @@ export const BillingInfoContainer = React.memo(
421
431
  setCardLoading(false)
422
432
  }
423
433
  }
434
+
424
435
  // fetch user data
425
436
  const fetchUserData = async () => {
426
437
  try {
@@ -468,10 +479,7 @@ export const BillingInfoContainer = React.memo(
468
479
  addAddOnsInAttributes(checkoutBody)
469
480
  }
470
481
 
471
- const checkoutResponse = await postOnCheckout(
472
- checkoutBody,
473
- flagFreeTicket
474
- )
482
+ const checkoutResponse = await postOnCheckout(checkoutBody, flagFreeTicket)
475
483
  removeReferralKey()
476
484
  onSkipBillingPage(checkoutResponse.data.attributes)
477
485
  setLoading(false)
@@ -492,7 +500,7 @@ export const BillingInfoContainer = React.memo(
492
500
  values: Record<string, any>,
493
501
  profileData?: any
494
502
  ): Record<string, any> => {
495
- let checkoutBody = {}
503
+ let checkoutBody = {} as ICheckoutBody
496
504
 
497
505
  // Auto collect ticket holders name when it was skipped optionally
498
506
  if (showDOB && !showTicketHolders && canSkipHolderNames) {
@@ -517,7 +525,56 @@ export const BillingInfoContainer = React.memo(
517
525
  )
518
526
  }
519
527
 
520
- return checkoutBody
528
+ // Collect data_capture for Order Custom Fields
529
+ const data_capture: Record<string, any> = {}
530
+ _forEach(customFieldsOrderKeys, (key: string) => {
531
+ data_capture[key] = values[key]
532
+
533
+ // Delete from values list
534
+ delete checkoutBody.attributes[key]
535
+ })
536
+
537
+ // Temp solution for hardcoded data capture values, to be deleted in the future
538
+ const captureKeys = [
539
+ 'businessCategory',
540
+ 'company',
541
+ 'instagram',
542
+ 'jobTitle',
543
+ 'wallet_address',
544
+ ]
545
+
546
+ captureKeys.forEach(key => {
547
+ const path = `data_capture.${key}`
548
+ const value = _get(values, path, '')
549
+
550
+ if (value !== '') {
551
+ data_capture[key] = value
552
+ }
553
+
554
+ const attributeKey = `data_capture[${key}]`
555
+ delete checkoutBody.attributes?.[attributeKey]
556
+ })
557
+
558
+ // Collect data_capture for Ticket Holders Fields
559
+ _forEach(checkoutBody.attributes.ticket_holders, (holder, holderIndex) => {
560
+ const holderDataCapture: Record<string, any> = {}
561
+
562
+ _forEach(customFieldsTicketHolderKeys, customFieldKey => {
563
+ const customFieldHolderName = `${customFieldKey}-${holderIndex}`
564
+ const customFieldHolderKey = values[customFieldHolderName] || ''
565
+ holderDataCapture[customFieldKey] = customFieldHolderKey
566
+
567
+ // Delete holder specific value from values list
568
+ delete checkoutBody.attributes[customFieldHolderName]
569
+ })
570
+
571
+ // Assign Ticket Holder data_capture final value
572
+ if (!_isEmpty(holderDataCapture)) {
573
+ holder.ticket_data_capture = holderDataCapture
574
+ }
575
+ })
576
+
577
+ return { attributes: { ...checkoutBody.attributes, data_capture } }
521
578
  }
522
579
 
523
580
  const removeReferralKey = () => {
@@ -573,7 +630,9 @@ export const BillingInfoContainer = React.memo(
573
630
  },
574
631
  ...initialValues,
575
632
  },
576
- userValues
633
+ userValues,
634
+ ticketHoldersFields,
635
+ ticketsQuantity
577
636
  )}
578
637
  enableReinitialize={false}
579
638
  onSubmit={async (values, formikHelpers) => {
@@ -912,7 +971,8 @@ export const BillingInfoContainer = React.memo(
912
971
  <Field
913
972
  {...element}
914
973
  type={
915
- element.type === 'radio'
974
+ element.type === 'radio' ||
975
+ element.type === 'checkbox'
916
976
  ? undefined
917
977
  : element.type
918
978
  }
@@ -976,57 +1036,39 @@ export const BillingInfoContainer = React.memo(
976
1036
  <div key={_item}>
977
1037
  <h5>Ticket {index + 1}</h5>
978
1038
  {_map(ticketHoldersFields.fields, group => {
979
- const { groupClassname, groupItems } = group
1039
+ const { id, groupClassname, groupItems } = group
980
1040
  return (
981
- <div key={group.id}>
1041
+ <div key={id}>
982
1042
  <div className={groupClassname}>
983
- {_map(groupItems, element => {
984
- if (
985
- _includes(
986
- ['holderFirstName', 'holderLastName'],
987
- element.name
988
- )
989
- ) {
990
- element.required = showTicketHolders
991
- }
992
- return (
993
- <div
994
- className={element.className}
995
- key={element.name}
996
- >
997
- <Field
998
- {...element}
999
- type={
1000
- element.type === 'radio'
1001
- ? undefined
1002
- : element.type
1003
- }
1004
- name={`${element.name}-${index}`}
1005
- label={getFieldLabel(element, configs)}
1006
- component={getFieldComponent(element)}
1007
- validate={combineValidators(
1008
- element.required
1009
- ? requiredValidator
1010
- : () =>
1011
- props.errors[
1012
- `${element.name}-${index}`
1013
- ],
1014
- element.onValidate
1015
- ? element.onValidate
1016
- : () =>
1017
- props.errors[`${element.name}-${index}`]
1018
- )}
1019
- setPhoneValidationIsLoading={
1020
- setPhoneValidationIsLoading
1021
- }
1022
- defaultCountry={
1023
- defaultCountry || element.defaultCountry
1024
- }
1025
- isCountryCodeEditable={isCountryCodeEditable}
1026
- />
1027
- </div>
1028
- )
1029
- })}
1043
+ {_map(groupItems, element => (
1044
+ <div className={element.className} key={element.name}>
1045
+ <Field
1046
+ {...element}
1047
+ type={
1048
+ element.type === 'radio' ||
1049
+ element.type === 'checkbox'
1050
+ ? undefined
1051
+ : element.type
1052
+ }
1053
+ name={`${element.name}-${index}`}
1054
+ label={getFieldLabel(element, configs)}
1055
+ component={getFieldComponent(element)}
1056
+ validate={getValidateFunctions(
1057
+ element,
1058
+ states,
1059
+ props.values,
1060
+ props.errors
1061
+ )}
1062
+ setPhoneValidationIsLoading={
1063
+ setPhoneValidationIsLoading
1064
+ }
1065
+ defaultCountry={
1066
+ defaultCountry || element.defaultCountry
1067
+ }
1068
+ isCountryCodeEditable={isCountryCodeEditable}
1069
+ />
1070
+ </div>
1071
+ ))}
1030
1072
  </div>
1031
1073
  </div>
1032
1074
  )
@@ -1119,3 +1161,7 @@ export const BillingInfoContainer = React.memo(
1119
1161
  )
1120
1162
  }
1121
1163
  )
1164
+
1165
+ const WithCustomFieldsBillingInfoContainer = withCustomFields(BillingInfoContainer)
1166
+
1167
+ export { WithCustomFieldsBillingInfoContainer as BillingInfoContainer }
@@ -3,6 +3,7 @@ import _flatMapDeep from 'lodash/flatMapDeep'
3
3
  import _forEach from 'lodash/forEach'
4
4
  import _get from 'lodash/get'
5
5
  import _isArray from 'lodash/isArray'
6
+ import _isEmpty from 'lodash/isEmpty'
6
7
  import _map from 'lodash/map'
7
8
  import { nanoid } from 'nanoid'
8
9
  import React from 'react'
@@ -33,7 +34,9 @@ export interface IValues {
33
34
  export const getInitialValues = (
34
35
  data: any = [],
35
36
  propsInitialValues: IValues = {},
36
- userValues: any = {}
37
+ userValues: any = {},
38
+ ticketHoldersFields: any = {},
39
+ ticketsQuantity: any = []
37
40
  ): IValues => {
38
41
  const results = _flatMapDeep(data, ({ fields }) =>
39
42
  _map(fields, ({ groupItems }) =>
@@ -41,6 +44,24 @@ export const getInitialValues = (
41
44
  )
42
45
  )
43
46
 
47
+ // Add Ticket Holder default values for custom fields
48
+ const ticketHoldersCustomFields =
49
+ ticketHoldersFields?.fields?.find((groupItem: any) => groupItem.customFields)
50
+ ?.groupItems || []
51
+ const ticketHoldersCustomFieldsInitValues = {} as IValues
52
+ const selectedTicketsCount =
53
+ ticketsQuantity.length || localStorage.getItem('selectedTicketsQuantity') || 0
54
+
55
+ if (!_isEmpty(ticketHoldersCustomFields)) {
56
+ for (const customField of ticketHoldersCustomFields) {
57
+ for (let i = 0; i < selectedTicketsCount; i++) {
58
+ const fieldName = `${customField.name}-${i}`
59
+ const fieldValue = customField.value
60
+ ticketHoldersCustomFieldsInitValues[fieldName] = fieldValue
61
+ }
62
+ }
63
+ }
64
+
44
65
  const initialValues: IValues = {}
45
66
  _forEach(results, groupItem => {
46
67
  const { name, value } = groupItem
@@ -54,7 +75,7 @@ export const getInitialValues = (
54
75
  propsInitialValues.lastName || userValues.lastName || ''
55
76
  initialValues['holderEmail-0'] = propsInitialValues.email || userValues.email || ''
56
77
 
57
- return initialValues
78
+ return { ...initialValues, ...ticketHoldersCustomFieldsInitValues }
58
79
  }
59
80
 
60
81
  export const createRegisterFormData = (
@@ -89,10 +110,13 @@ export const createRegisterFormData = (
89
110
  return bodyFormData
90
111
  }
91
112
 
92
- interface ICheckoutBody {
113
+ export interface ICheckoutBody {
93
114
  attributes: {
94
115
  [key: string]: any;
95
116
  };
117
+ data_capture?: {
118
+ [key: string]: any;
119
+ };
96
120
  }
97
121
 
98
122
  interface IticketHolder {
@@ -219,7 +243,7 @@ export const assingUniqueIds = (data: any): any => {
219
243
 
220
244
  export const isRequiredField = (
221
245
  element: IGroupItem,
222
- configs: null | AttributesConfig
246
+ configs?: null | AttributesConfig
223
247
  ) => {
224
248
  const { name, required } = element
225
249
  const flagRequirePhone = _get(configs, 'phone_required', false)
@@ -240,7 +264,7 @@ export const isRequiredField = (
240
264
  return false
241
265
  }
242
266
 
243
- export const getFieldLabel = (element: IGroupItem, configs: null | AttributesConfig) => {
267
+ export const getFieldLabel = (element: IGroupItem, configs?: null | AttributesConfig) => {
244
268
  if (isRequiredField(element, configs) || React.isValidElement(element.label)) {
245
269
  return element.label
246
270
  }
@@ -1,5 +1,5 @@
1
1
  import { FormControl, FormHelperText } from '@mui/material'
2
- import Checkbox from '@mui/material/Checkbox'
2
+ import CheckboxMaterial from '@mui/material/Checkbox'
3
3
  import FormControlLabel from '@mui/material/FormControlLabel'
4
4
  import FormGroup from '@mui/material/FormGroup'
5
5
  import { useTheme } from '@mui/styles'
@@ -15,7 +15,7 @@ interface IOtherProps {
15
15
  [key: string]: any;
16
16
  }
17
17
 
18
- export const CheckboxField = ({
18
+ export const Checkbox = ({
19
19
  label,
20
20
  field,
21
21
  selectOptions,
@@ -36,7 +36,7 @@ export const CheckboxField = ({
36
36
  <FormControl error={!!(rest?.form?.errors && rest.form.errors[field?.name ?? ''])}>
37
37
  <FormGroup>
38
38
  <FormControlLabel
39
- control={<Checkbox {...field} {...rest} />}
39
+ control={<CheckboxMaterial {...field} {...rest} />}
40
40
  label={label}
41
41
  componentsProps={{
42
42
  typography: customTheme?.checkbox,
@@ -0,0 +1,41 @@
1
+ import { FormControl, FormHelperText } from '@mui/material'
2
+ import Checkbox from '@mui/material/Checkbox'
3
+ import FormControlLabel from '@mui/material/FormControlLabel'
4
+ import FormGroup from '@mui/material/FormGroup'
5
+ import { useTheme } from '@mui/styles'
6
+ import { FieldInputProps, FormikProps } from 'formik'
7
+ import _get from 'lodash/get'
8
+ import React from 'react'
9
+
10
+ interface ICheckboxField {
11
+ label: string | number | JSX.Element;
12
+ field: FieldInputProps<any>;
13
+ form: FormikProps<any>;
14
+ }
15
+
16
+ export const CheckboxField = ({
17
+ label,
18
+ field,
19
+ form: { touched, errors },
20
+ }: ICheckboxField) => {
21
+ const isTouched = Boolean(_get(touched, field.name, false))
22
+ const errorText = _get(errors, field.name)
23
+ const hasError = isTouched && Boolean(errorText)
24
+ const customTheme: any = useTheme()
25
+
26
+ return (
27
+ <FormControl
28
+ className={`checkbox-field ${hasError ? 'required-checkbox-field' : ''}`}
29
+ error={hasError}
30
+ >
31
+ <FormGroup>
32
+ <FormControlLabel
33
+ control={<Checkbox {...field} checked={field.value} />}
34
+ label={label}
35
+ componentsProps={{ typography: customTheme?.checkbox }}
36
+ />
37
+ </FormGroup>
38
+ {hasError && <FormHelperText>Required</FormHelperText>}
39
+ </FormControl>
40
+ )
41
+ }
@@ -47,7 +47,7 @@ export const CustomField = ({
47
47
  inputRef,
48
48
  onChange,
49
49
  multiline = false,
50
- minRows,
50
+ minRows = 3,
51
51
  maxRows,
52
52
  disabled,
53
53
  }: ICustomField & IOtherProps) => {
@@ -28,7 +28,7 @@ export interface IRadioGroupField {
28
28
  export const RadioGroupField = ({
29
29
  label,
30
30
  field,
31
- radios,
31
+ radios = [],
32
32
  disabled,
33
33
  form: { touched, errors, setFieldValue },
34
34
  onChange = _identity,