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.
- package/README.md +462 -229
- package/dist/api/guestTicketDelegation.d.ts +47 -0
- package/dist/api/index.d.ts +2 -2
- package/dist/components/common/CustomField.d.ts +1 -1
- package/dist/components/common/FieldSection/index.d.ts +19 -0
- package/dist/components/common/FieldSection/utils/index.d.ts +8 -0
- package/dist/components/common/index.d.ts +2 -2
- package/dist/components/confirmModal/index.d.ts +2 -2
- package/dist/components/delegationsContainer/IssueComponent.d.ts +10 -0
- package/dist/components/delegationsContainer/IssueTicketForm.d.ts +9 -0
- package/dist/components/delegationsContainer/TicketsAssignedTable.d.ts +11 -0
- package/dist/components/delegationsContainer/TicketsAvailableTable.d.ts +11 -0
- package/dist/components/delegationsContainer/index.d.ts +10 -0
- package/dist/components/idVerificationContainer/constants.d.ts +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/loginForm/index.d.ts +45 -0
- package/dist/components/registerForm/adapters/index.d.ts +4 -0
- package/dist/components/registerForm/constants.d.ts +1 -0
- package/dist/components/registerForm/index.d.ts +16 -0
- package/dist/index.d.ts +3 -1
- package/dist/tf-checkout-react.cjs.development.js +1413 -283
- package/dist/tf-checkout-react.cjs.development.js.map +1 -1
- package/dist/tf-checkout-react.cjs.production.min.js +1 -1
- package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
- package/dist/tf-checkout-react.esm.js +1416 -288
- package/dist/tf-checkout-react.esm.js.map +1 -1
- package/dist/utils/form.d.ts +3 -0
- package/dist/utils/index.d.ts +3 -1
- package/dist/utils/replaceVarInString.d.ts +1 -0
- package/package.json +1 -1
- package/src/api/guestTicketDelegation.ts +79 -0
- package/src/api/index.ts +3 -2
- package/src/components/billing-info-container/utils.ts +1 -1
- package/src/components/common/CustomField.tsx +2 -0
- package/src/components/common/FieldSection/index.tsx +141 -0
- package/src/components/common/FieldSection/utils/index.tsx +92 -0
- package/src/components/common/SelectField/index.tsx +1 -1
- package/src/components/common/index.tsx +2 -2
- package/src/components/confirmModal/index.tsx +2 -2
- package/src/components/delegationsContainer/IssueComponent.tsx +155 -0
- package/src/components/delegationsContainer/IssueTicketForm.tsx +109 -0
- package/src/components/delegationsContainer/TicketsAssignedTable.tsx +55 -0
- package/src/components/delegationsContainer/TicketsAvailableTable.tsx +54 -0
- package/src/components/delegationsContainer/index.tsx +83 -0
- package/src/components/forgotPasswordModal/index.tsx +3 -9
- package/src/components/idVerificationContainer/constants.ts +5 -2
- package/src/components/index.ts +1 -0
- package/src/components/loginForm/index.tsx +195 -0
- package/src/components/registerForm/adapters/index.tsx +10 -0
- package/src/components/registerForm/constants.tsx +96 -0
- package/src/components/registerForm/index.tsx +192 -0
- package/src/index.ts +3 -4
- package/src/types/api/auth.d.ts +55 -0
- package/src/types/api/guestTicketDelegation.d.ts +18 -0
- package/src/types/formFields.d.ts +29 -0
- package/src/utils/form.ts +34 -0
- package/src/utils/index.ts +3 -1
- package/src/utils/replaceVarInString.ts +9 -0
- package/src/validators/index.ts +2 -2
package/dist/utils/index.d.ts
CHANGED
|
@@ -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
|
@@ -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) =>
|
|
@@ -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
|
|
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'
|
|
@@ -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
|