tf-checkout-react 1.3.31 → 1.3.33

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.
@@ -1,10 +1,10 @@
1
- import React from 'react'
2
- import FormGroup from '@mui/material/FormGroup'
3
- import FormControlLabel from '@mui/material/FormControlLabel'
1
+ import { FormControl, FormHelperText } from '@mui/material'
4
2
  import Checkbox from '@mui/material/Checkbox'
5
- import { FieldInputProps } from 'formik'
3
+ import FormControlLabel from '@mui/material/FormControlLabel'
4
+ import FormGroup from '@mui/material/FormGroup'
6
5
  import { useTheme } from '@mui/styles'
7
- import { FormControl, FormHelperText } from '@mui/material'
6
+ import { FieldInputProps } from 'formik'
7
+ import React from 'react'
8
8
 
9
9
  export interface ICheckboxField {
10
10
  label: string | number | JSX.Element;
@@ -23,21 +23,28 @@ export const CheckboxField = ({
23
23
  setFieldValue,
24
24
  disableDropdown,
25
25
  setPhoneValidationIsLoading,
26
+ defaultCountry,
27
+ dateFormat,
28
+ datePlaceholder,
26
29
  ...rest
27
30
  }: ICheckboxField & IOtherProps) => {
28
31
  const customTheme: any = useTheme()
29
32
  return (
30
- <FormControl error={!!(rest?.form?.errors && rest.form.errors[field?.name ?? ""])}>
33
+ <FormControl
34
+ error={!!(rest?.form?.errors && rest.form.errors[field?.name ?? ''])}
35
+ >
31
36
  <FormGroup>
32
37
  <FormControlLabel
33
38
  control={<Checkbox {...field} {...rest} />}
34
39
  label={label}
35
40
  componentsProps={{
36
- typography: customTheme?.checkbox
41
+ typography: customTheme?.checkbox,
37
42
  }}
38
43
  />
39
44
  </FormGroup>
40
- {!!(rest?.form?.errors && rest.form.errors[field?.name ?? ""]) ? <FormHelperText>Required</FormHelperText> : null}
45
+ {!!(rest?.form?.errors && rest.form.errors[field?.name ?? '']) ? (
46
+ <FormHelperText>Required</FormHelperText>
47
+ ) : null}
41
48
  </FormControl>
42
49
  )
43
50
  }
@@ -1,8 +1,8 @@
1
- import React from 'react'
1
+ import { useTheme } from '@mui/styles'
2
2
  import { FieldInputProps } from 'formik'
3
- import MuiPhoneNumber from 'material-ui-phone-number'
4
3
  import _get from 'lodash/get'
5
- import { useTheme } from '@mui/styles'
4
+ import MuiPhoneNumber from 'material-ui-phone-number'
5
+ import React from 'react'
6
6
 
7
7
  export interface INumberInField {
8
8
  label: string | number | JSX.Element;
@@ -28,24 +28,24 @@ export const FormikPhoneNumberField = ({
28
28
 
29
29
  return (
30
30
  <MuiPhoneNumber
31
- name='phone'
31
+ name="phone"
32
32
  value={values.phone}
33
- onChange={(e: any) => setFieldValue("phone", e)}
34
- variant="outlined"
35
- defaultCountry='us'
33
+ onChange={(e: any) => setFieldValue('phone', e)}
34
+ variant="outlined"
35
+ defaultCountry="us"
36
36
  disableDropdown={true}
37
37
  label={label}
38
38
  error={!!error && isTouched}
39
39
  helperText={isTouched && error}
40
40
  fullWidth
41
41
  InputLabelProps={{
42
- sx: customTheme?.input
42
+ sx: customTheme?.input,
43
43
  }}
44
44
  InputProps={{
45
- sx: customTheme?.input
45
+ sx: customTheme?.input,
46
46
  }}
47
47
  autoFormat={false}
48
- {...rest}
48
+ {...rest}
49
49
  />
50
50
  )
51
- }
51
+ }
@@ -0,0 +1,71 @@
1
+ import FormControl from '@mui/material/FormControl'
2
+ import FormControlLabel from '@mui/material/FormControlLabel'
3
+ import FormHelperText from '@mui/material/FormHelperText'
4
+ import FormLabel from '@mui/material/FormLabel'
5
+ import Radio from '@mui/material/Radio'
6
+ import RadioGroup from '@mui/material/RadioGroup'
7
+ import { FieldInputProps, FormikProps } from 'formik'
8
+ import _get from 'lodash/get'
9
+ import _identity from 'lodash/identity'
10
+ import React from 'react'
11
+
12
+ interface IRadio {
13
+ id: string | number;
14
+ name: string | number;
15
+ value: string | number;
16
+ [key: string]: any;
17
+ }
18
+
19
+ interface IRadioGroupField {
20
+ label?: string;
21
+ field: FieldInputProps<any>;
22
+ form: FormikProps<any>;
23
+ radios: IRadio[];
24
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
25
+ }
26
+
27
+ export const RadioGroupField = ({
28
+ label,
29
+ field,
30
+ radios,
31
+ form: { errors, setFieldValue },
32
+ onChange = _identity,
33
+ }: IRadioGroupField) => {
34
+ const radioId = `radio-${field.name}`
35
+ const error = _get(errors, field.name)
36
+
37
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
38
+ const { value } = e.target as HTMLInputElement
39
+ setFieldValue(field.name, value)
40
+ onChange(e)
41
+ }
42
+
43
+ return (
44
+ <FormControl>
45
+ {error ? (
46
+ <FormHelperText className="radio-error" error>
47
+ {error}
48
+ </FormHelperText>
49
+ ) : null}
50
+ {label && <FormLabel id={radioId}>{label}</FormLabel>}
51
+ <RadioGroup
52
+ aria-labelledby={radioId}
53
+ name={field.name}
54
+ value={field.value}
55
+ onChange={handleChange}
56
+ >
57
+ {radios.map(radio => {
58
+ const { id, name, value } = radio
59
+ return (
60
+ <FormControlLabel
61
+ key={id}
62
+ label={name}
63
+ value={value}
64
+ control={<Radio />}
65
+ />
66
+ )
67
+ })}
68
+ </RadioGroup>
69
+ </FormControl>
70
+ )
71
+ }
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (_) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ exports.__esModule = true;
50
+ exports.PhoneNumberField = void 0;
51
+ var TextField_1 = require("@mui/material/TextField");
52
+ var debounce_1 = require("lodash/debounce");
53
+ var get_1 = require("lodash/get");
54
+ var react_1 = require("react");
55
+ var api_1 = require("../../api");
56
+ exports.PhoneNumberField = function (_a) {
57
+ var label = _a.label, _b = _a.type, type = _b === void 0 ? 'text' : _b, field = _a.field, _c = _a.form, errors = _c.errors, setFieldError = _c.setFieldError, setStatus = _c.setStatus;
58
+ var error = get_1["default"](errors, field.name);
59
+ // eslint-disable-next-line react-hooks/exhaustive-deps
60
+ var debounceCb = react_1.useCallback(debounce_1["default"](function (cb) { return void cb(); }, 1000), []);
61
+ react_1.useEffect(function () {
62
+ var _a;
63
+ if (field.value) {
64
+ setStatus((_a = {}, _a[field.name] = true, _a));
65
+ }
66
+ debounceCb(function () { return __awaiter(void 0, void 0, void 0, function () {
67
+ var error_1, message;
68
+ var _a;
69
+ return __generator(this, function (_b) {
70
+ switch (_b.label) {
71
+ case 0:
72
+ _b.trys.push([0, 3, 4, 5]);
73
+ if (!field.value) return [3 /*break*/, 2];
74
+ return [4 /*yield*/, api_1.validatePhoneNumber(field.value)];
75
+ case 1:
76
+ _b.sent();
77
+ _b.label = 2;
78
+ case 2:
79
+ setFieldError(field.name, '');
80
+ return [3 /*break*/, 5];
81
+ case 3:
82
+ error_1 = _b.sent();
83
+ message = get_1["default"](error_1, 'response.data.message', 'Invalid phone number');
84
+ setFieldError(field.name, message);
85
+ return [3 /*break*/, 5];
86
+ case 4:
87
+ setStatus((_a = {}, _a[field.name] = false, _a));
88
+ return [7 /*endfinally*/];
89
+ case 5: return [2 /*return*/];
90
+ }
91
+ });
92
+ }); });
93
+ // eslint-disable-next-line
94
+ }, [field.value]);
95
+ return (react_1["default"].createElement(TextField_1["default"], __assign({}, field, { id: field.name, label: label, type: type, fullWidth: true, error: !!error, helperText: error, value: field.value || '', inputProps: { pattern: '[+0-9]/d+' } })));
96
+ };
@@ -3,4 +3,5 @@ export { CustomField } from './CustomField'
3
3
  export { FormikPhoneNumberField } from './FormikPhoneNumberField'
4
4
  export { PhoneNumberField } from './PhoneNumberField'
5
5
  export { Loader } from './Loader'
6
- export { SelectField } from './SelectField'
6
+ export { SelectField } from './SelectField'
7
+ export { RadioGroupField } from './RadioGroupField'
@@ -19,15 +19,19 @@ import {
19
19
  addToCart,
20
20
  getCheckoutPageConfigs,
21
21
  getEvent,
22
+ getProfileData,
22
23
  getTickets,
23
24
  logout,
24
25
  postOnCheckout,
25
26
  } from '../../api'
27
+ import { X_TF_ECOMMERCE } from '../../constants'
28
+ import { useCookieListener } from '../../hooks/useCookieListener'
26
29
  import {
27
30
  createCheckoutDataBodyWithDefaultHolder,
28
31
  deleteCookieByName,
29
32
  getCookieByName,
30
33
  getQueryVariable,
34
+ setLoggedUserData,
31
35
  } from '../../utils'
32
36
  import { Loader } from '../common/index'
33
37
  import ConfirmModal from '../confirmModal'
@@ -64,6 +68,8 @@ export interface IGetTickets {
64
68
  onGetTicketsError: (e: AxiosError) => void;
65
69
  onLogoutSuccess: () => void;
66
70
  onLogoutError: (e: AxiosError) => void;
71
+ onGetProfileDataSuccess: (response: any) => void;
72
+ onGetProfileDataError: (e: AxiosError) => void;
67
73
  onLoginSuccess: () => void;
68
74
  handleNotInvitedModalClose: () => void;
69
75
  handleInvalidLinkModalClose: () => void;
@@ -113,6 +119,8 @@ export const TicketsContainer = ({
113
119
  onGetTicketsError = _identity,
114
120
  onLogoutSuccess = _identity,
115
121
  onLogoutError = _identity,
122
+ onGetProfileDataSuccess = _identity,
123
+ onGetProfileDataError = _identity,
116
124
  theme = 'light',
117
125
  queryPromoCode = '',
118
126
  isPromotionsEnabled = true,
@@ -136,10 +144,8 @@ export const TicketsContainer = ({
136
144
  }: IGetTickets) => {
137
145
  const [selectedTickets, setSelectedTickets] = useState({} as ISelectedTickets)
138
146
  const isWindowDefined = typeof window !== 'undefined'
139
- const xtfCookie = getCookieByName('X-TF-ECOMMERCE')
140
147
  const [isLogged, setIsLogged] = useState(
141
- (isWindowDefined ? !!window.localStorage.getItem('access_token') : false) ||
142
- !!xtfCookie
148
+ Boolean(getCookieByName(X_TF_ECOMMERCE))
143
149
  )
144
150
  const [showLoginModal, setShowLoginModal] = useState(false)
145
151
  const [tickets, setTickets] = useState([] as ITicket[])
@@ -164,6 +170,8 @@ export const TicketsContainer = ({
164
170
 
165
171
  const ticketsContainerRef = useRef<HTMLDivElement>(null)
166
172
 
173
+ useCookieListener(X_TF_ECOMMERCE, value => setIsLogged(Boolean(value)))
174
+
167
175
  useEffect(() => {
168
176
  if (typeof window !== 'undefined') {
169
177
  const access_token = window.localStorage.getItem('access_token')
@@ -181,6 +189,21 @@ export const TicketsContainer = ({
181
189
  !!eventId && getTicketsApi()
182
190
  }, [eventId])
183
191
 
192
+ useEffect(() => {
193
+ if (isLogged) {
194
+ fetchUserData()
195
+ .then(res => {
196
+ window.localStorage.setItem('user_data', JSON.stringify(res))
197
+ onGetProfileDataSuccess(res)
198
+ })
199
+ .catch(e => {
200
+ if (axios.isAxiosError(e)) {
201
+ onGetProfileDataError(e)
202
+ }
203
+ })
204
+ }
205
+ }, [isLogged])
206
+
184
207
  const handleLogout = async () => {
185
208
  try {
186
209
  await logout()
@@ -201,9 +224,11 @@ export const TicketsContainer = ({
201
224
  const handleExternalLogin = () => {
202
225
  setIsLogged(true)
203
226
  }
227
+
204
228
  const handleOnClose = () => {
205
229
  setShowLoginModal(false)
206
230
  }
231
+
207
232
  const handleOnLogin = () => {
208
233
  setShowLoginModal(false)
209
234
  setIsLogged(true)
@@ -232,6 +257,10 @@ export const TicketsContainer = ({
232
257
  if (eventResponse.data.success) {
233
258
  const event = _get(eventResponse, 'data.data.attributes')
234
259
  setEvent(event)
260
+
261
+ if (event.country && isWindowDefined) {
262
+ window.localStorage.setItem('eventCountry', event.country)
263
+ }
235
264
  }
236
265
  } catch (e) {
237
266
  if (axios.isAxiosError(e)) {
@@ -297,7 +326,10 @@ export const TicketsContainer = ({
297
326
  const result = await addToCart(eventId, data)
298
327
  const pageConfigsDataResponse = enableAddOns
299
328
  ? await getCheckoutPageConfigs()
300
- : { status: 200, data: { attributes: _get(result, 'data.data.attributes') } }
329
+ : {
330
+ status: 200,
331
+ data: { attributes: _get(result, 'data.data.attributes') },
332
+ }
301
333
 
302
334
  if (result.status === 200 && pageConfigsDataResponse.status === 200) {
303
335
  const pageConfigsData =
@@ -310,8 +342,10 @@ export const TicketsContainer = ({
310
342
  const hidePhoneField = pageConfigsData.hide_phone_field ?? false
311
343
  const hasAddOn = pageConfigsData.has_add_on ?? false
312
344
  const freeTicket = pageConfigsData.free_ticket ?? false
313
- const collectOptionalWalletAddress = pageConfigsData.collect_optional_wallet_address ?? false
314
- const collectMandatoryWalletAddress = pageConfigsData.collect_mandatory_wallet_address ?? false
345
+ const collectOptionalWalletAddress =
346
+ pageConfigsData.collect_optional_wallet_address ?? false
347
+ const collectMandatoryWalletAddress =
348
+ pageConfigsData.collect_mandatory_wallet_address ?? false
315
349
 
316
350
  let hash = ''
317
351
  let total = ''
@@ -389,6 +423,17 @@ export const TicketsContainer = ({
389
423
  getTicketsApi(isUpdateingCode, type)
390
424
  }
391
425
 
426
+ const fetchUserData = async () => {
427
+ try {
428
+ const userDataResponse = await getProfileData()
429
+ const profileData = _get(userDataResponse, 'data.data')
430
+ const profileDataObj = setLoggedUserData(profileData)
431
+ return profileDataObj
432
+ } catch (e) {
433
+ throw new Error(e)
434
+ }
435
+ }
436
+
392
437
  const isTicketOnSale = _some(
393
438
  tickets,
394
439
  item => item.salesStarted && !item.salesEnded && !item.soldOut
@@ -471,6 +516,7 @@ export const TicketsContainer = ({
471
516
 
472
517
  return false
473
518
  }
519
+
474
520
  const onClose = (value: string) => {
475
521
  if (value === 'notInvited') {
476
522
  handleNotInvitedModalClose()
@@ -480,6 +526,7 @@ export const TicketsContainer = ({
480
526
  setIsNotInvitedError('')
481
527
  setIsInvalidLinkError('')
482
528
  }
529
+
483
530
  return (
484
531
  <ThemeProvider theme={themeMui}>
485
532
  {!isLoading && <ReferralLogic eventId={eventId} />}
@@ -0,0 +1 @@
1
+ export const X_TF_ECOMMERCE = 'X-TF-ECOMMERCE'
@@ -0,0 +1,32 @@
1
+ import { useEffect, useRef, useState } from 'react'
2
+
3
+ import { getCookieByName } from '../utils'
4
+
5
+ export const useCookieListener = (
6
+ key: string,
7
+ handler: (value: string | null) => void
8
+ ) => {
9
+ const getCookie = () => getCookieByName(key)
10
+ const [intervalValue, setIntervalValue] = useState<NodeJS.Timeout>()
11
+ const cookieRef = useRef<string>(getCookie())
12
+
13
+ const handleCookieChange = () => {
14
+ const currentCookie = getCookie()
15
+ const prevCookie = cookieRef.current
16
+
17
+ if (currentCookie !== prevCookie) {
18
+ cookieRef.current = getCookie()
19
+ handler(cookieRef.current)
20
+ }
21
+ }
22
+
23
+ useEffect(() => {
24
+ const interval = setInterval(handleCookieChange, 500)
25
+ setIntervalValue(interval)
26
+
27
+ return () => {
28
+ intervalValue && clearInterval(intervalValue)
29
+ }
30
+ // eslint-disable-next-line react-hooks/exhaustive-deps
31
+ }, [])
32
+ }
@@ -0,0 +1,15 @@
1
+ interface IUserData {
2
+ id: string;
3
+ firstName: string;
4
+ lastName: string;
5
+ email: string;
6
+ city?: string;
7
+ country?: string;
8
+ countryId?: string;
9
+ phone?: string;
10
+ streetAddress?: string;
11
+ state?: string;
12
+ zip?: string;
13
+ zipCode?: string;
14
+ stateId?: string;
15
+ }
@@ -0,0 +1,13 @@
1
+ export const setLoggedUserData = (data: IUserData) => ({
2
+ id: data.id,
3
+ first_name: data.firstName,
4
+ last_name: data.lastName,
5
+ email: data.email,
6
+ confirmEmail: data.email,
7
+ city: data?.city || '',
8
+ country: data?.countryId || data?.country || '',
9
+ phone: data?.phone || '',
10
+ street_address: data?.streetAddress || '',
11
+ state: data?.stateId || '',
12
+ zip: data?.zip || data?.zipCode || '',
13
+ })
@@ -6,3 +6,4 @@ 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 { setLoggedUserData } from './auth'