tf-checkout-react 1.4.20 → 1.4.21

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 (59) hide show
  1. package/README.md +462 -229
  2. package/dist/api/guestTicketDelegation.d.ts +47 -0
  3. package/dist/api/index.d.ts +2 -2
  4. package/dist/components/common/CustomField.d.ts +1 -1
  5. package/dist/components/common/FieldSection/index.d.ts +19 -0
  6. package/dist/components/common/FieldSection/utils/index.d.ts +8 -0
  7. package/dist/components/common/index.d.ts +2 -2
  8. package/dist/components/confirmModal/index.d.ts +2 -2
  9. package/dist/components/delegationsContainer/IssueComponent.d.ts +10 -0
  10. package/dist/components/delegationsContainer/IssueTicketForm.d.ts +9 -0
  11. package/dist/components/delegationsContainer/TicketsAssignedTable.d.ts +11 -0
  12. package/dist/components/delegationsContainer/TicketsAvailableTable.d.ts +11 -0
  13. package/dist/components/delegationsContainer/index.d.ts +10 -0
  14. package/dist/components/idVerificationContainer/constants.d.ts +1 -0
  15. package/dist/components/index.d.ts +1 -0
  16. package/dist/components/loginForm/index.d.ts +45 -0
  17. package/dist/components/registerForm/adapters/index.d.ts +4 -0
  18. package/dist/components/registerForm/constants.d.ts +1 -0
  19. package/dist/components/registerForm/index.d.ts +16 -0
  20. package/dist/index.d.ts +3 -1
  21. package/dist/tf-checkout-react.cjs.development.js +1413 -283
  22. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  23. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  24. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  25. package/dist/tf-checkout-react.esm.js +1416 -288
  26. package/dist/tf-checkout-react.esm.js.map +1 -1
  27. package/dist/utils/form.d.ts +3 -0
  28. package/dist/utils/index.d.ts +3 -1
  29. package/dist/utils/replaceVarInString.d.ts +1 -0
  30. package/package.json +1 -1
  31. package/src/api/guestTicketDelegation.ts +79 -0
  32. package/src/api/index.ts +3 -2
  33. package/src/components/billing-info-container/utils.ts +1 -1
  34. package/src/components/common/CustomField.tsx +2 -0
  35. package/src/components/common/FieldSection/index.tsx +141 -0
  36. package/src/components/common/FieldSection/utils/index.tsx +92 -0
  37. package/src/components/common/SelectField/index.tsx +1 -1
  38. package/src/components/common/index.tsx +2 -2
  39. package/src/components/confirmModal/index.tsx +2 -2
  40. package/src/components/delegationsContainer/IssueComponent.tsx +155 -0
  41. package/src/components/delegationsContainer/IssueTicketForm.tsx +109 -0
  42. package/src/components/delegationsContainer/TicketsAssignedTable.tsx +55 -0
  43. package/src/components/delegationsContainer/TicketsAvailableTable.tsx +54 -0
  44. package/src/components/delegationsContainer/index.tsx +83 -0
  45. package/src/components/forgotPasswordModal/index.tsx +3 -9
  46. package/src/components/idVerificationContainer/constants.ts +5 -2
  47. package/src/components/index.ts +1 -0
  48. package/src/components/loginForm/index.tsx +195 -0
  49. package/src/components/registerForm/adapters/index.tsx +10 -0
  50. package/src/components/registerForm/constants.tsx +96 -0
  51. package/src/components/registerForm/index.tsx +192 -0
  52. package/src/index.ts +3 -4
  53. package/src/types/api/auth.d.ts +55 -0
  54. package/src/types/api/guestTicketDelegation.d.ts +18 -0
  55. package/src/types/formFields.d.ts +29 -0
  56. package/src/utils/form.ts +34 -0
  57. package/src/utils/index.ts +3 -1
  58. package/src/utils/replaceVarInString.ts +9 -0
  59. package/src/validators/index.ts +2 -2
@@ -0,0 +1,3 @@
1
+ export declare const getFormInitialValues: (fieldsSections: IFormFieldsSection[]) => {
2
+ [key: string]: string | number | boolean;
3
+ };
@@ -6,7 +6,9 @@ export { createCheckoutDataBodyWithDefaultHolder } from './createCheckoutDataBod
6
6
  export { setCustomCookie, getCookieByName, deleteCookieByName } from './cookies';
7
7
  export { getDomain } from './getDomain';
8
8
  export { createMarkup } from './createMarkup';
9
+ export { replaceVarInString } from './replaceVarInString';
10
+ export { isBrowser } from './isBrowser';
11
+ export { getFormInitialValues } from './form';
9
12
  export { setLoggedUserData } from './auth';
10
13
  export { createElementFromHTML } from './htmlNodeFromString';
11
- export { isBrowser } from './isBrowser';
12
14
  export { isJson } from './jsonUtils';
@@ -0,0 +1 @@
1
+ export declare const replaceVarInString: (message: string | undefined, varArray: Array<string>) => string;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.4.20",
2
+ "version": "1.4.21",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -0,0 +1,79 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios'
2
+
3
+ import { publicRequest } from '../utils/setConfigs'
4
+
5
+ export const getCustomerExistsData = async (
6
+ accessHash: string
7
+ ): Promise<ICheckCustomerExistsData> => {
8
+ const response: AxiosResponse<ICheckCustomerExistsData, AxiosRequestConfig> =
9
+ await publicRequest.get(`/v1/delegation-access/${accessHash}/customer-exists`)
10
+ return response.data
11
+ }
12
+
13
+ interface IDelegationTicketType {
14
+ delegationMaxQuantity: number | string;
15
+ }
16
+
17
+ interface IIssueTicketResponseData {
18
+ delegationName: string;
19
+ eventImage: string;
20
+ eventName: string;
21
+ ticketTypes: {
22
+ [key: number]: IDelegationTicketType;
23
+ };
24
+ }
25
+
26
+ interface IIssueTicketResponse {
27
+ data: {
28
+ attributes: IIssueTicketResponseData;
29
+ relationships: Array<any>;
30
+ type: string;
31
+ message: string;
32
+ };
33
+ }
34
+
35
+ export interface IDelegationsTicketType {
36
+ [key: number]: {
37
+ delegationMaxQuantity: string | number;
38
+ delegationQuantityIssued: string | number;
39
+ matrixRecordId: string | number;
40
+ optionValue: string | number;
41
+ };
42
+ }
43
+ export interface IDelegationsData {
44
+ delegationName: string;
45
+ eventImage: string;
46
+ eventName: string;
47
+ ticketTypes: IDelegationsTicketType;
48
+ tickets: Array<any>;
49
+ }
50
+
51
+ interface IDelegationsResponse {
52
+ data: {
53
+ data: {
54
+ attributes: IDelegationsData;
55
+ relationships: Array<any>;
56
+ type: string;
57
+ };
58
+ };
59
+ }
60
+
61
+ export const getDelegationTickets = (
62
+ accessHash: string
63
+ ): Promise<IDelegationsResponse> => {
64
+ const res = publicRequest.get(`v1/delegation-access/${accessHash}/consumer-page-info`)
65
+ return res
66
+ }
67
+
68
+ export const issueTicket = async (
69
+ accessHash: string,
70
+ data: ITicketIssueData
71
+ ): Promise<IIssueTicketResponse> => {
72
+ const response: AxiosResponse<IIssueTicketResponse, AxiosRequestConfig> =
73
+ await publicRequest.post(`v1/delegation-access/${accessHash}/issue-ticket`, {
74
+ data: {
75
+ attributes: data,
76
+ },
77
+ })
78
+ return response.data
79
+ }
package/src/api/index.ts CHANGED
@@ -128,6 +128,8 @@ publicRequest.setBaseUrl = (baseUrl: string) =>
128
128
  publicRequest.setAccessToken = token =>
129
129
  (publicRequest.defaults.headers.common.Authorization = token)
130
130
 
131
+ export { issueTicket, getDelegationTickets } from './guestTicketDelegation'
132
+
131
133
  export const setCustomHeader = (response: any) => {
132
134
  const guestHeaderResponseValue = _get(response, 'headers.authorization-guest')
133
135
  const guestHeaderExistingValue = _get(response, 'config.headers[Authorization-Guest]')
@@ -232,7 +234,6 @@ export const postOnCheckout = (data: any, accessToken?: string, freeTicket = fal
232
234
  delete data.attributes.city
233
235
  delete data.attributes.country
234
236
  delete data.attributes.state
235
- delete data.attributes.zip
236
237
  delete data.attributes.street_address
237
238
  }
238
239
  const res = publicRequest.post(
@@ -338,7 +339,7 @@ export const getCountries = () => publicRequest.get('/countries/list')
338
339
  export const getConfirmationData = (orderHash: string) =>
339
340
  publicRequest.get(`v1/order/${orderHash}/payment/complete`)
340
341
 
341
- export const getStates = (countryId: string) =>
342
+ export const getStates = (countryId: string | number) =>
342
343
  publicRequest.get(`/countries/${countryId}/states/`)
343
344
 
344
345
  export const getOrders = (page: number, limit: number, eventSlug: string) =>
@@ -84,7 +84,7 @@ export const createRegisterFormData = (
84
84
  if (
85
85
  !(
86
86
  flagFreeTicket &&
87
- ['country', 'state', 'city', 'street_address', 'zip'].includes(key)
87
+ ['country', 'state', 'city', 'street_address'].includes(key)
88
88
  )
89
89
  ) {
90
90
  bodyFormData.append(key, item)
@@ -47,6 +47,7 @@ export const CustomField = ({
47
47
  multiline = false,
48
48
  minRows,
49
49
  maxRows,
50
+ disabled,
50
51
  }: ICustomField & IOtherProps) => {
51
52
  const [isShrinked, setIsShrinked] = useState(Boolean(field.value))
52
53
  const _ref = useRef<HTMLInputElement>(null)
@@ -70,6 +71,7 @@ export const CustomField = ({
70
71
 
71
72
  return (
72
73
  <TextField
74
+ disabled={disabled}
73
75
  placeholder=""
74
76
  id={field.name}
75
77
  label={label}
@@ -0,0 +1,141 @@
1
+ import { Field, FormikValues } from 'formik'
2
+ import _identity from 'lodash/identity'
3
+ import _map from 'lodash/map'
4
+ import React, { FC } from 'react'
5
+
6
+ import { replaceVarInString } from '../../../utils'
7
+ import {
8
+ CheckboxField,
9
+ CustomField,
10
+ DatePickerField,
11
+ PhoneNumberField,
12
+ SelectField,
13
+ } from '../index'
14
+ import { getFieldClassNames, getValidateFunctions, insertHTML } from './utils'
15
+
16
+ export interface IFieldsSectionProps {
17
+ formFields?: IFormFieldsSection[];
18
+ values: FormikValues;
19
+ setFieldValue: (
20
+ field: string,
21
+ value: FormikValues | string | number,
22
+ shouldValidate?: boolean | undefined
23
+ ) => void;
24
+ disableField?: string;
25
+ countries?: { [key: string]: string | number }[];
26
+ states?: { [key: string]: string | number }[];
27
+ theme?: 'dark' | 'light';
28
+ containerClass?: string;
29
+ setPhoneValidationIsLoading?: (isLoading: boolean) => void;
30
+ onFieldChange?: (name: string, value: string | number) => void;
31
+ }
32
+
33
+ const SectionContainer: FC<{ className: string }> = ({
34
+ children,
35
+ className,
36
+ }) => <div className={className}>{children}</div>
37
+
38
+ export const FieldsSection = ({
39
+ formFields = [],
40
+ countries = [],
41
+ states = [],
42
+ values,
43
+ setFieldValue,
44
+ theme,
45
+ containerClass = '',
46
+ setPhoneValidationIsLoading = _identity,
47
+ onFieldChange = _identity,
48
+ disableField,
49
+ }: IFieldsSectionProps) => (
50
+ <>
51
+ {_map(formFields, (item, index) => {
52
+ const {
53
+ name,
54
+ groupLabel,
55
+ groupLabelVars = [],
56
+ groupLabelClassName,
57
+ groupClassName = '',
58
+ fields,
59
+ } = item
60
+ return (
61
+ <SectionContainer key={name} className={groupClassName}>
62
+ <span id={`group_label_${index}`} className={groupLabelClassName}>
63
+ {typeof groupLabel === 'string'
64
+ ? insertHTML(
65
+ `group_label_${index}`,
66
+ replaceVarInString(groupLabel, groupLabelVars)
67
+ )
68
+ : groupLabel}
69
+ </span>
70
+ <div className={`fields-container ${groupClassName}`}>
71
+ {_map(fields, (fieldData, fieldIndex) => {
72
+ const {
73
+ name,
74
+ label,
75
+ className = 'full-width',
76
+ type,
77
+ component,
78
+ options = [],
79
+ required,
80
+ } = fieldData
81
+ const id = `${name}-${fieldIndex}`
82
+ const classNames = `${containerClass}-container__field ${className}`
83
+ return (
84
+ component || (
85
+ <div
86
+ key={name}
87
+ id={id}
88
+ className={getFieldClassNames(id, classNames)}
89
+ >
90
+ <Field
91
+ disabled={name === disableField || name === 'state' && !states.length}
92
+ name={name}
93
+ label={`${label}${required ? '' : ' (optional)'}`}
94
+ type={type}
95
+ validate={name === 'state' && !states.length ? false : getValidateFunctions({
96
+ element: fieldData,
97
+ values,
98
+ })}
99
+ setFieldValue={setFieldValue}
100
+ component={
101
+ type === 'checkbox'
102
+ ? CheckboxField
103
+ : type === 'select'
104
+ ? SelectField
105
+ : type === 'phone'
106
+ ? PhoneNumberField
107
+ : type === 'date'
108
+ ? DatePickerField
109
+ : CustomField
110
+ }
111
+ options={
112
+ name === 'country'
113
+ ? countries
114
+ : name === 'state'
115
+ ? states
116
+ : options
117
+ }
118
+ theme={theme}
119
+ setPhoneValidationIsLoading={
120
+ type === 'phone'
121
+ ? setPhoneValidationIsLoading
122
+ : undefined
123
+ }
124
+ onChange={(e: React.FormEvent<EventTarget>) => {
125
+ const element = e.target as HTMLInputElement
126
+ const { value } = element
127
+ setFieldValue(name, value)
128
+ onFieldChange(name, value)
129
+ }}
130
+ disableDropdown={fieldData.disableDropdown}
131
+ />
132
+ </div>
133
+ )
134
+ )
135
+ })}
136
+ </div>
137
+ </SectionContainer>
138
+ )
139
+ })}
140
+ </>
141
+ )
@@ -0,0 +1,92 @@
1
+ import { FormikValues } from 'formik'
2
+ import _isEmpty from 'lodash/isEmpty'
3
+ import _map from 'lodash/map'
4
+
5
+ import { isBrowser } from '../../../../utils'
6
+ import { combineValidators, requiredValidator } from '../../../../validators'
7
+
8
+ export const getValidateFunctions = ({
9
+ element,
10
+ values,
11
+ }: {
12
+ element: IFormField;
13
+ values: FormikValues;
14
+ }) => {
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ const validationFunctions: any[] = []
17
+ if (element.required) {
18
+ validationFunctions.push(requiredValidator)
19
+ }
20
+
21
+ if (element.onValidate) {
22
+ validationFunctions.push(element.onValidate)
23
+ }
24
+
25
+ if (element.name === 'confirmEmail') {
26
+ const isSameEmail = (confirmEmail?: string) =>
27
+ values.email !== confirmEmail
28
+ ? 'Please confirm your email address correctly'
29
+ : null
30
+ validationFunctions.push(isSameEmail)
31
+ }
32
+
33
+ if (element.name === 'confirmPassword') {
34
+ const isSame = (confirmPassword?: string) =>
35
+ values.password !== confirmPassword
36
+ ? 'Password confirmation does not match'
37
+ : null
38
+
39
+ validationFunctions.push(isSame)
40
+ }
41
+
42
+ return combineValidators(...validationFunctions)
43
+ }
44
+
45
+ export const updateFormFieldsAttributes = (
46
+ formFields: IFormFieldsSection[],
47
+ attributes?: IFieldAttribute
48
+ ) => {
49
+ if (attributes && !_isEmpty(attributes)) {
50
+ const updatedFormFields = _map(formFields, fieldSection => {
51
+ const fieldSectionAttributes = attributes[fieldSection.name] || {}
52
+
53
+ const updatedFields = _map(fieldSection.fields, fieldItem => {
54
+ const fieldItemAttributes = attributes[fieldItem.name] || {}
55
+ return { ...fieldItem, ...fieldItemAttributes }
56
+ })
57
+
58
+ return {
59
+ ...fieldSection,
60
+ ...fieldSectionAttributes,
61
+ fields: updatedFields,
62
+ }
63
+ })
64
+
65
+ return updatedFormFields
66
+ }
67
+ return formFields
68
+ }
69
+
70
+ export const getFieldClassNames = (id: string, existingClassNames: string) => {
71
+ if (isBrowser) {
72
+ const elem = document && document.getElementById(id)
73
+
74
+ if ((elem?.parentElement?.clientWidth || 0) < 375) {
75
+ return existingClassNames + ' full-width'
76
+ }
77
+ }
78
+
79
+ return existingClassNames
80
+ }
81
+
82
+ export const insertHTML = (elementId: string, text = '') => {
83
+ if (isBrowser) {
84
+ const elem = document && document.getElementById(elementId)
85
+
86
+ if (!elem?.childNodes.length) {
87
+ elem?.insertAdjacentHTML('afterbegin', text)
88
+ }
89
+ }
90
+
91
+ return null
92
+ }
@@ -86,7 +86,7 @@ function SelectField({
86
86
  }}
87
87
  sx={{ textAlign: 'start' }}
88
88
  >
89
- {options.map((option: ISelectOption) => (
89
+ {options?.map((option: ISelectOption) => (
90
90
  <MenuItem key={option.label} value={option.value}>
91
91
  {isMultiple && (
92
92
  <Checkbox checked={value.indexOf(option.value) > -1} />
@@ -3,7 +3,7 @@ export { CustomField } from './CustomField'
3
3
  export { FormikPhoneNumberField } from './FormikPhoneNumberField'
4
4
  export { PhoneNumberField } from './PhoneNumberField'
5
5
  export { Loader } from './Loader'
6
- export { NativeSelectField } from './NativeSelectFeild'
7
- export { RadioGroupField } from './RadioGroupField'
8
6
  export { SelectField } from './SelectField'
9
7
  export { DatePickerField } from './DatePickerField'
8
+ export { NativeSelectField } from './NativeSelectFeild'
9
+ export { RadioGroupField } from './RadioGroupField'
@@ -9,8 +9,8 @@ interface Props {
9
9
  message: string;
10
10
  loading?: boolean;
11
11
  hideCancelBtn?: boolean;
12
- onClose: () => void;
13
- onConfirm: () => void;
12
+ onClose?: () => void;
13
+ onConfirm?: () => void;
14
14
  }
15
15
 
16
16
  const style: React.CSSProperties = {
@@ -0,0 +1,155 @@
1
+ import axios, { AxiosError } from 'axios'
2
+ import _identity from 'lodash/identity'
3
+ import _map from 'lodash/map'
4
+ import React, { useEffect, useState } from 'react'
5
+
6
+ import { IDelegationsData, IDelegationsTicketType } from '../../api/guestTicketDelegation'
7
+ import { getDelegationTickets, issueTicket } from '../../api/index'
8
+ import { CONFIGS, getQueryVariable } from '../../utils'
9
+ import { Loader } from '../common'
10
+ import ConfirmModal from '../confirmModal'
11
+ import { DELEGATION_ACCESS_ERROR } from '../idVerificationContainer/constants'
12
+ import IssueTicketForm from './IssueTicketForm'
13
+ import TicketsAssignedTable from './TicketsAssignedTable'
14
+ import TicketsAvailableTable from './TicketsAvailableTable'
15
+
16
+ export interface IssueTicketData {
17
+ headTitle?: string;
18
+ classNamePrefix?: string;
19
+ onGetIssuePageDataSuccess?: () => void;
20
+ onGetIssuePageDataError?: (e: AxiosError) => void;
21
+ }
22
+
23
+ const IssueComponent = ({
24
+ classNamePrefix = 'delegations',
25
+ headTitle = 'Manage Your Guest Tickets',
26
+ onGetIssuePageDataSuccess = _identity,
27
+ onGetIssuePageDataError = _identity,
28
+ }: IssueTicketData) => {
29
+ const [loading, setLoading] = useState(true)
30
+ const [showMaxQtyModal, setShowMaxQtyModal] = useState(false)
31
+ const [showSuccessModal, setShowSuccessModal] = useState(false)
32
+ const [error, setError] = useState('')
33
+ const accessHash = getQueryVariable('hash') || ''
34
+ const [issuePageData, setIssuePageData] = useState<IDelegationsData>(
35
+ {} as IDelegationsData
36
+ )
37
+
38
+ useEffect(() => {
39
+ const fetchDelegationTickets = async () => {
40
+ try {
41
+ const res = await getDelegationTickets(accessHash)
42
+ setLoading(false)
43
+ setIssuePageData(res?.data?.data?.attributes || {})
44
+ onGetIssuePageDataSuccess()
45
+ } catch (e) {
46
+ setLoading(false)
47
+ if (axios.isAxiosError(e)) {
48
+ onGetIssuePageDataError(e)
49
+ }
50
+ }
51
+ }
52
+ fetchDelegationTickets()
53
+ }, [showSuccessModal])
54
+ const selectTicketTypeOptions = _map(
55
+ issuePageData.ticketTypes || ({} as IDelegationsTicketType),
56
+ (val, key) => ({
57
+ value: key,
58
+ label: val.optionValue,
59
+ })
60
+ )
61
+ return (
62
+ <div className={`${classNamePrefix}-container`}>
63
+ {loading ? (
64
+ <Loader />
65
+ ) : (
66
+ <>
67
+ {showMaxQtyModal && (
68
+ <ConfirmModal
69
+ hideCancelBtn={true}
70
+ message={error}
71
+ onClose={() =>
72
+ error === DELEGATION_ACCESS_ERROR
73
+ ? (window.location.href = '/')
74
+ : setShowMaxQtyModal(false)
75
+ }
76
+ onConfirm={() =>
77
+ error === DELEGATION_ACCESS_ERROR
78
+ ? (window.location.href = '/')
79
+ : setShowMaxQtyModal(false)
80
+ }
81
+ />
82
+ )}
83
+ {showSuccessModal && (
84
+ <ConfirmModal
85
+ hideCancelBtn={true}
86
+ message="Your ticket successfully issued."
87
+ onClose={() => setShowSuccessModal(false)}
88
+ onConfirm={() => setShowSuccessModal(false)}
89
+ />
90
+ )}
91
+ <div className={`${classNamePrefix}-head-title`}>{headTitle}</div>
92
+ <div className={`${classNamePrefix}-inner-blocks`}>
93
+ <div className={`${classNamePrefix}-image-block`}>
94
+ <img
95
+ src={`${CONFIGS.BASE_URL}${issuePageData?.eventImage}`}
96
+ alt="main_event_img"
97
+ title=""
98
+ />
99
+ </div>
100
+ <div className={`${classNamePrefix}-tables`}>
101
+ <TicketsAvailableTable
102
+ tableTitle="Tickets available"
103
+ issuePageData={issuePageData}
104
+ classNamePrefix="delegations"
105
+ />
106
+ <TicketsAssignedTable
107
+ tableTitle="Tickets assigned"
108
+ issuePageData={issuePageData}
109
+ classNamePrefix="delegations"
110
+ />
111
+ <div className={`${classNamePrefix}-issue-block`}>
112
+ <div className={`${classNamePrefix}-issue-title`}>Issue New Tickets</div>
113
+ <div className={`${classNamePrefix}-issue-subtitle`}>
114
+ Please select the type of tickets and enter recipient details:
115
+ </div>
116
+ </div>
117
+ <IssueTicketForm
118
+ classNamePrefix={'delegations'}
119
+ handleSubmit={async (values: any, { resetForm, setSubmitting }) => {
120
+ try {
121
+ await issueTicket(accessHash, values)
122
+ setShowSuccessModal(true)
123
+ resetForm()
124
+ } catch (e) {
125
+ if (axios.isAxiosError(e)) {
126
+ const error = e?.response?.data?.message || 'Error'
127
+ setError(error)
128
+ } else if (e instanceof Error) {
129
+ setError(e?.message || 'Error')
130
+ }
131
+ setShowMaxQtyModal(true)
132
+ } finally {
133
+ setLoading(false)
134
+ setSubmitting(false)
135
+ }
136
+ }}
137
+ selectTicketTypeOptions={selectTicketTypeOptions}
138
+ initialValues={{
139
+ ticketTypeId: '',
140
+ firstName: '',
141
+ lastName: '',
142
+ email: '',
143
+ confirmEmail: '',
144
+ confirm: false,
145
+ }}
146
+ />
147
+ </div>
148
+ </div>
149
+ </>
150
+ )}
151
+ </div>
152
+ )
153
+ }
154
+
155
+ export default IssueComponent
@@ -0,0 +1,109 @@
1
+ import { CircularProgress } from '@mui/material'
2
+ import { Field, Form, Formik } from 'formik'
3
+ import _identity from 'lodash/identity'
4
+ import React from 'react'
5
+
6
+ import { requiredValidator } from '../../validators'
7
+ import { CheckboxField, SelectField } from '../common'
8
+ import { CustomField } from '../common/CustomField'
9
+ import { getValidateFunctions } from '../common/FieldSection/utils'
10
+
11
+ export interface IIssueTicketForm {
12
+ classNamePrefix?: string;
13
+ handleSubmit: (values: any, resetForm: any) => void;
14
+ selectTicketTypeOptions: Array<any>;
15
+ initialValues?: any;
16
+ }
17
+
18
+ const IssueTicketForm = ({
19
+ classNamePrefix = 'delegations',
20
+ handleSubmit = _identity,
21
+ selectTicketTypeOptions,
22
+ initialValues,
23
+ }: IIssueTicketForm) => (
24
+ <div className={`${classNamePrefix}-issue-form`}>
25
+ <Formik
26
+ initialValues={initialValues}
27
+ onSubmit={(values, { resetForm, setSubmitting }) => {
28
+ delete values.confirm
29
+ handleSubmit(values, { resetForm, setSubmitting })
30
+ }}
31
+ >
32
+ {({ isValid, values, isSubmitting }) => (
33
+ <Form>
34
+ <div className="body">
35
+ <div className="field-item">
36
+ <div className="field_label">Ticket Type</div>
37
+ <Field
38
+ name="ticketTypeId"
39
+ label="Ticket Type"
40
+ component={SelectField}
41
+ validate={requiredValidator}
42
+ options={selectTicketTypeOptions}
43
+ />
44
+ </div>
45
+ <div className="field-item">
46
+ <div className="field_label">Name</div>
47
+ <Field
48
+ name="firstName"
49
+ label="Name"
50
+ component={CustomField}
51
+ validate={requiredValidator}
52
+ />
53
+ </div>
54
+ <div className="field-item">
55
+ <div className="field_label">Last Name</div>
56
+ <Field
57
+ name="lastName"
58
+ label="Last Name"
59
+ component={CustomField}
60
+ validate={requiredValidator}
61
+ />
62
+ </div>
63
+ <div className="field-item">
64
+ <div className="field_label">Email</div>
65
+ <Field
66
+ name="email"
67
+ label="Email"
68
+ component={CustomField}
69
+ validate={requiredValidator}
70
+ />
71
+ </div>
72
+ <div className="field-item">
73
+ <div className="field_label">Confirm Email</div>
74
+ <Field
75
+ name="confirmEmail"
76
+ label="Confirm Email"
77
+ component={CustomField}
78
+ validate={getValidateFunctions({
79
+ element: {
80
+ name: 'confirmEmail',
81
+ label: 'Confirm Email',
82
+ required: true,
83
+ },
84
+ values,
85
+ })}
86
+ />
87
+ </div>
88
+ </div>
89
+ <div className="field-item checkbox_item">
90
+ <Field
91
+ name="confirm"
92
+ label="I agree to ManaCommon's privacy policy"
93
+ type="checkbox"
94
+ validate={requiredValidator}
95
+ component={CheckboxField}
96
+ />
97
+ </div>
98
+ <div className="action-button">
99
+ <button type="submit" disabled={!isValid}>
100
+ {isSubmitting ? <CircularProgress size="22px" /> : 'Issue Ticket'}
101
+ </button>
102
+ </div>
103
+ </Form>
104
+ )}
105
+ </Formik>
106
+ </div>
107
+ )
108
+
109
+ export default IssueTicketForm