tf-checkout-react 1.6.6 → 1.7.2

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 (137) hide show
  1. package/README.md +401 -59
  2. package/dist/adapters/customFields.d.ts +1 -0
  3. package/dist/api/checkout.d.ts +2 -0
  4. package/dist/api/common.d.ts +1 -0
  5. package/dist/api/index.d.ts +2 -0
  6. package/dist/api/preRegistrationComplete.d.ts +1 -1
  7. package/dist/components/addonsContainer/AddonComponent.d.ts +6 -1
  8. package/dist/components/addonsContainer/SimpleAddonsContainer.d.ts +17 -0
  9. package/dist/components/addonsContainer/index.d.ts +6 -1
  10. package/dist/components/billing-info-container/hooks/index.d.ts +3 -0
  11. package/dist/components/billing-info-container/hooks/usePaymentContext.d.ts +5 -0
  12. package/dist/components/billing-info-container/hooks/usePaymentRedirect.d.ts +14 -0
  13. package/dist/components/billing-info-container/hooks/useStripePayment.d.ts +18 -0
  14. package/dist/components/billing-info-container/index.d.ts +13 -2
  15. package/dist/components/billing-info-container/utils.d.ts +26 -1
  16. package/dist/components/common/DatePickerField.d.ts +7 -1
  17. package/dist/components/common/PhoneNumberField.d.ts +1 -1
  18. package/dist/components/confirmationContainer/index.d.ts +4 -1
  19. package/dist/components/countdown/index.d.ts +1 -1
  20. package/dist/components/forgotPasswordModal/index.d.ts +2 -1
  21. package/dist/components/myTicketsContainer/index.d.ts +3 -2
  22. package/dist/components/orderDetailsContainer/index.d.ts +8 -1
  23. package/dist/components/paymentContainer/OrderDetails.d.ts +9 -0
  24. package/dist/components/paymentContainer/handlePayment.d.ts +15 -0
  25. package/dist/components/paymentContainer/index.d.ts +12 -6
  26. package/dist/components/preRegistration/FieldsSection.d.ts +7 -1
  27. package/dist/components/preRegistration/PreRegistrationComplete.d.ts +8 -0
  28. package/dist/components/preRegistration/constants.d.ts +2 -2
  29. package/dist/components/preRegistration/index.d.ts +6 -0
  30. package/dist/components/resetPasswordContainer/index.d.ts +2 -2
  31. package/dist/components/ticketsContainer/InfoIcon.d.ts +5 -0
  32. package/dist/components/ticketsContainer/TicketsSection.d.ts +3 -2
  33. package/dist/components/ticketsContainer/TimeSlotsSection.d.ts +25 -0
  34. package/dist/components/ticketsContainer/index.d.ts +29 -5
  35. package/dist/components/timerWidget/index.d.ts +2 -1
  36. package/dist/constants/index.d.ts +5 -0
  37. package/dist/index.d.ts +4 -1
  38. package/dist/tf-checkout-react.cjs.development.js +11284 -9565
  39. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  40. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  41. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  42. package/dist/tf-checkout-react.esm.js +11293 -9577
  43. package/dist/tf-checkout-react.esm.js.map +1 -1
  44. package/dist/tf-checkout-styles.css +1 -1
  45. package/dist/types/add_on.d.ts +1 -0
  46. package/dist/types/checkoutPageConfigs.d.ts +1 -1
  47. package/dist/types/order-data.d.ts +3 -1
  48. package/dist/utils/auth.d.ts +8 -0
  49. package/dist/utils/createCheckoutDataBodyWithDefaultHolder.d.ts +1 -0
  50. package/dist/utils/customFields.d.ts +11 -0
  51. package/dist/utils/getDomain.d.ts +1 -1
  52. package/dist/utils/index.d.ts +1 -1
  53. package/dist/utils/setConfigs.d.ts +1 -0
  54. package/package.json +14 -8
  55. package/src/adapters/customFields.ts +7 -1
  56. package/src/api/auth.ts +2 -1
  57. package/src/api/checkout.ts +9 -4
  58. package/src/api/common.ts +49 -2
  59. package/src/api/index.ts +1 -0
  60. package/src/api/interceptors.ts +7 -23
  61. package/src/api/preRegistrationComplete.ts +1 -1
  62. package/src/api/publicRequest.ts +10 -0
  63. package/src/components/addonsContainer/AddonComponent.tsx +96 -11
  64. package/src/components/addonsContainer/SimpleAddonsContainer.tsx +420 -0
  65. package/src/components/addonsContainer/index.tsx +198 -47
  66. package/src/components/billing-info-container/hooks/index.ts +3 -0
  67. package/src/components/billing-info-container/hooks/usePaymentContext.ts +22 -0
  68. package/src/components/billing-info-container/hooks/usePaymentRedirect.ts +147 -0
  69. package/src/components/billing-info-container/hooks/useStripePayment.ts +121 -0
  70. package/src/components/billing-info-container/index.tsx +859 -418
  71. package/src/components/billing-info-container/{utils.ts → utils.tsx} +124 -1
  72. package/src/components/common/CheckboxField/index.tsx +1 -1
  73. package/src/components/common/CustomField.tsx +39 -3
  74. package/src/components/common/DatePickerField.tsx +25 -10
  75. package/src/components/common/PhoneNumberField.tsx +4 -2
  76. package/src/components/common/SnackbarAlert.tsx +32 -34
  77. package/src/components/confirmationContainer/config.ts +3 -3
  78. package/src/components/confirmationContainer/index.tsx +20 -1
  79. package/src/components/confirmationContainer/social-buttons.tsx +5 -3
  80. package/src/components/confirmationContainer/style.css +9 -5
  81. package/src/components/countdown/index.tsx +22 -22
  82. package/src/components/delegationsContainer/IssueComponent.tsx +2 -1
  83. package/src/components/forgotPasswordModal/index.tsx +44 -13
  84. package/src/components/loginForm/index.tsx +1 -1
  85. package/src/components/loginModal/index.tsx +19 -27
  86. package/src/components/loginModal/style.css +3 -1
  87. package/src/components/myTicketsContainer/index.tsx +13 -9
  88. package/src/components/orderDetailsContainer/index.tsx +206 -174
  89. package/src/components/paymentContainer/OrderDetails.tsx +257 -0
  90. package/src/components/paymentContainer/handlePayment.ts +86 -0
  91. package/src/components/paymentContainer/index.tsx +299 -259
  92. package/src/components/paymentContainer/style.css +141 -0
  93. package/src/components/preRegistration/FieldsSection.tsx +8 -0
  94. package/src/components/preRegistration/PreRegistrationComplete.tsx +138 -118
  95. package/src/components/preRegistration/PreRegistrationInformations.tsx +21 -15
  96. package/src/components/preRegistration/constants.tsx +10 -4
  97. package/src/components/preRegistration/index.tsx +233 -179
  98. package/src/components/preRegistration/style.css +3 -0
  99. package/src/components/registerForm/constants.tsx +3 -1
  100. package/src/components/registerForm/index.tsx +3 -3
  101. package/src/components/registerModal/index.tsx +47 -72
  102. package/src/components/resetPasswordContainer/index.tsx +20 -14
  103. package/src/components/seatMapContainer/TicketsSection.tsx +2 -2
  104. package/src/components/signupModal/index.tsx +13 -6
  105. package/src/components/ticketResale/index.tsx +7 -0
  106. package/src/components/ticketsContainer/InfoIcon.tsx +35 -0
  107. package/src/components/ticketsContainer/PromoCodeSection.tsx +34 -28
  108. package/src/components/ticketsContainer/TicketRow.tsx +1 -1
  109. package/src/components/ticketsContainer/TicketsSection.tsx +189 -57
  110. package/src/components/ticketsContainer/TimeSlotsSection.tsx +120 -0
  111. package/src/components/ticketsContainer/index.tsx +268 -106
  112. package/src/components/timerWidget/index.tsx +15 -3
  113. package/src/components/timerWidget/style.css +2 -1
  114. package/src/constants/index.ts +2 -0
  115. package/src/env.ts +14 -6
  116. package/src/hoc/CustomFields/index.tsx +9 -1
  117. package/src/index.ts +7 -2
  118. package/src/types/add_on.ts +1 -0
  119. package/src/types/api/cart.d.ts +8 -0
  120. package/src/types/api/checkout.d.ts +58 -7
  121. package/src/types/api/common.d.ts +30 -0
  122. package/src/types/api/orders.d.ts +19 -3
  123. package/src/types/api/payment.d.ts +6 -2
  124. package/src/types/api/preRegistrationComplete.d.ts +2 -2
  125. package/src/types/checkoutPageConfigs.ts +1 -1
  126. package/src/types/order-data.ts +3 -1
  127. package/src/types/pre-registration-complete.d.ts +6 -1
  128. package/src/utils/auth.ts +32 -0
  129. package/src/utils/cookies.ts +42 -11
  130. package/src/utils/createCheckoutDataBodyWithDefaultHolder.ts +3 -1
  131. package/src/utils/customFields.ts +22 -0
  132. package/src/utils/getDomain.ts +10 -4
  133. package/src/utils/index.ts +1 -1
  134. package/src/utils/setConfigs.ts +3 -1
  135. package/dist/components/stripePayment/index.d.ts +0 -24
  136. package/src/components/stripePayment/index.tsx +0 -281
  137. package/src/components/stripePayment/style.css +0 -60
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
2
  import { FormikErrors, FormikValues } from 'formik'
2
3
  import _flatMapDeep from 'lodash/flatMapDeep'
3
4
  import _forEach from 'lodash/forEach'
@@ -25,6 +26,7 @@ export interface ILoggedInValues {
25
26
  emailLogged?: string;
26
27
  firstNameLogged?: string;
27
28
  lastNameLogged?: string;
29
+ phoneLogged?: string;
28
30
  }
29
31
 
30
32
  export interface IValues {
@@ -74,6 +76,7 @@ export const getInitialValues = (
74
76
  initialValues['holderLastName-0'] =
75
77
  propsInitialValues.lastName || userValues.lastName || ''
76
78
  initialValues['holderEmail-0'] = propsInitialValues.email || userValues.email || ''
79
+ initialValues['holderPhone-0'] = propsInitialValues.phone || userValues.phone || ''
77
80
 
78
81
  return { ...initialValues, ...ticketHoldersCustomFieldsInitValues }
79
82
  }
@@ -153,7 +156,9 @@ export const createCheckoutDataBody = (
153
156
  last_name: !index
154
157
  ? item[`holderLastName-${index}`] || logedInValues.lastNameLogged || ''
155
158
  : item[`holderLastName-${index}`] || '',
156
- phone: item[`holderPhone-${index}`] || '',
159
+ phone: !index
160
+ ? item[`holderPhone-${index}`] || logedInValues.phoneLogged || ''
161
+ : item[`holderPhone-${index}`] || '',
157
162
  email: !index
158
163
  ? item[`holderEmail-${index}`] || logedInValues.emailLogged || ''
159
164
  : item[`holderEmail-${index}`] || '',
@@ -288,3 +293,121 @@ export const getFieldComponent = (element: IGroupItem) => {
288
293
  const fieldComponent = _get(fieldComponentConfigs, type, CustomField)
289
294
  return fieldComponent
290
295
  }
296
+
297
+ /**
298
+ * Renders a React component with the provided props
299
+ * @param Component - The React component to render
300
+ * @param props - The props to apply to the component
301
+ * @returns JSX element with applied props
302
+ */
303
+ export const renderComponentWithProps = <T extends Record<string, any>>(
304
+ Component: React.ComponentType<T>,
305
+ props: T
306
+ ): React.ReactElement<T> => <Component {...props} />
307
+
308
+ export const filterBillingInfoFields = (
309
+ fields: IGroupItem[],
310
+ options: {
311
+ showDOB: boolean;
312
+ hideTtfOptIn: boolean;
313
+ hidePhoneField: boolean;
314
+ flagRequirePhone: boolean;
315
+ collectMandatoryWalletAddress: boolean;
316
+ collectMandatoryJobTitle: boolean;
317
+ collectMandatoryBusinessCategory: boolean;
318
+ collectMandatoryCompany: boolean;
319
+ collectMandatoryInstagram: boolean;
320
+ flagFreeTicket: boolean;
321
+ hideWalletAddressField: boolean;
322
+ hideJobTitleField: boolean;
323
+ hideBusinessCategoryField: boolean;
324
+ hideCompanyField: boolean;
325
+ hideInstagramField: boolean;
326
+ }
327
+ ) => {
328
+ const {
329
+ showDOB,
330
+ hideTtfOptIn,
331
+ hidePhoneField,
332
+ flagRequirePhone,
333
+ collectMandatoryWalletAddress,
334
+ collectMandatoryJobTitle,
335
+ collectMandatoryBusinessCategory,
336
+ collectMandatoryCompany,
337
+ collectMandatoryInstagram,
338
+ flagFreeTicket,
339
+ hideWalletAddressField,
340
+ hideJobTitleField,
341
+ hideBusinessCategoryField,
342
+ hideCompanyField,
343
+ hideInstagramField,
344
+ } = options
345
+ return fields.filter(el => {
346
+ if (el.name === 'holderAge' && !showDOB) {
347
+ return false
348
+ }
349
+ if (el.name === 'ttf_opt_in' && hideTtfOptIn) {
350
+ return false
351
+ }
352
+ if (el.name === 'phone') {
353
+ if (!hidePhoneField) {
354
+ el.required = flagRequirePhone
355
+ } else {
356
+ return false
357
+ }
358
+ }
359
+ if (el.name === 'data_capture[wallet_address]') {
360
+ if (collectMandatoryWalletAddress) {
361
+ el.required = true
362
+ }
363
+ }
364
+ if (el.name === 'data_capture[jobTitle]') {
365
+ if (collectMandatoryJobTitle) {
366
+ el.required = true
367
+ }
368
+ }
369
+ if (el.name === 'data_capture[businessCategory]') {
370
+ if (collectMandatoryBusinessCategory) {
371
+ el.required = true
372
+ }
373
+ }
374
+ if (el.name === 'data_capture[company]') {
375
+ if (collectMandatoryCompany) {
376
+ el.required = true
377
+ }
378
+ }
379
+ if (el.name === 'data_capture[instagram]') {
380
+ if (collectMandatoryInstagram) {
381
+ el.required = true
382
+ }
383
+ }
384
+ if (['street_address', 'country', 'state', 'city'].includes(el.name)) {
385
+ if (flagFreeTicket) {
386
+ el.required = false
387
+ return false
388
+ }
389
+ }
390
+ if (
391
+ hideWalletAddressField &&
392
+ (el.name === 'wallet-address-info' || el.name === 'data_capture[wallet_address]')
393
+ ) {
394
+ return false
395
+ }
396
+ if (hideJobTitleField && el.name === 'data_capture[jobTitle]') {
397
+ return false
398
+ }
399
+ if (hideBusinessCategoryField && el.name === 'data_capture[businessCategory]') {
400
+ return false
401
+ }
402
+ if (hideCompanyField && el.name === 'data_capture[company]') {
403
+ return false
404
+ }
405
+ if (
406
+ hideInstagramField &&
407
+ (el.name === 'data_capture[instagram]' || el.name === 'instagram-info')
408
+ ) {
409
+ return false
410
+ }
411
+ return true
412
+ })
413
+ }
@@ -30,7 +30,7 @@ export const CheckboxField = ({
30
30
  >
31
31
  <FormGroup>
32
32
  <FormControlLabel
33
- control={<Checkbox {...field} checked={field.value} />}
33
+ control={<Checkbox {...field} checked={Boolean(field.value)} />}
34
34
  label={label}
35
35
  componentsProps={{ typography: customTheme?.checkbox }}
36
36
  />
@@ -1,4 +1,9 @@
1
1
  /* eslint-disable no-underscore-dangle */
2
+ /* eslint-disable import/no-unresolved */
3
+ import Visibility from '@mui/icons-material/Visibility'
4
+ import VisibilityOff from '@mui/icons-material/VisibilityOff'
5
+ import IconButton from '@mui/material/IconButton'
6
+ import InputAdornment from '@mui/material/InputAdornment'
2
7
  import TextField from '@mui/material/TextField'
3
8
  import { useTheme } from '@mui/styles'
4
9
  import { FieldInputProps, FormikProps } from 'formik'
@@ -31,6 +36,7 @@ export interface ICustomField {
31
36
  minRows?: string | number;
32
37
  maxRows?: string | number;
33
38
  }
39
+
34
40
  export interface IOtherProps {
35
41
  [key: string]: any;
36
42
  }
@@ -52,9 +58,11 @@ export const CustomField = ({
52
58
  disabled,
53
59
  }: ICustomField & IOtherProps) => {
54
60
  const [isShrinked, setIsShrinked] = useState(Boolean(field.value))
61
+ const [showPassword, setShowPassword] = useState(false)
55
62
  const _ref = useRef<HTMLInputElement>(null)
56
63
  const isAutoFilled = _ref.current?.matches(':-webkit-autofill')
57
64
  const isSelectField = type === 'select'
65
+ const isPasswordField = type === 'password'
58
66
  const error = _get(errors, field.name)
59
67
  const isTouched =
60
68
  Boolean(_get(touched, field.name)) ||
@@ -63,6 +71,34 @@ export const CustomField = ({
63
71
  const customTheme: any = useTheme()
64
72
  const inputProps: any = { sx: customTheme?.input }
65
73
 
74
+ const handleClickShowPassword = () => {
75
+ setShowPassword(!showPassword)
76
+ }
77
+
78
+ const handleMouseDownPassword = (event: React.MouseEvent<HTMLButtonElement>) => {
79
+ event.preventDefault()
80
+ }
81
+
82
+ const finalInputProps = isPasswordField
83
+ ? {
84
+ ...InputProps,
85
+ endAdornment: (
86
+ <InputAdornment position="end">
87
+ <IconButton
88
+ aria-label="toggle password visibility"
89
+ onClick={handleClickShowPassword}
90
+ onMouseDown={handleMouseDownPassword}
91
+ edge="end"
92
+ size="small"
93
+ sx={{ color: customTheme?.input?.color || 'inherit' }}
94
+ >
95
+ {showPassword ? <VisibilityOff /> : <Visibility />}
96
+ </IconButton>
97
+ </InputAdornment>
98
+ ),
99
+ }
100
+ : InputProps
101
+
66
102
  useEffect(() => {
67
103
  if (_isFunction(inputRef)) {
68
104
  inputRef(_ref.current)
@@ -77,7 +113,7 @@ export const CustomField = ({
77
113
  placeholder=""
78
114
  id={field.name}
79
115
  label={label}
80
- type={type}
116
+ type={isPasswordField ? (showPassword ? 'text' : 'password') : type}
81
117
  select={isSelectField}
82
118
  fullWidth={true}
83
119
  error={!!error && isTouched}
@@ -92,9 +128,9 @@ export const CustomField = ({
92
128
  }}
93
129
  InputLabelProps={{
94
130
  sx: customTheme?.input,
95
- shrink: isShrinked || Boolean(field.value) || isAutoFilled,
131
+ shrink: isSelectField || isShrinked || Boolean(field.value) || isAutoFilled,
96
132
  }}
97
- InputProps={InputProps}
133
+ InputProps={finalInputProps}
98
134
  inputProps={{ ...inputProps, ...pInputProps }}
99
135
  inputRef={_ref}
100
136
  multiline={multiline}
@@ -1,4 +1,6 @@
1
+ import { ThemeOptions } from '@mui/material'
1
2
  import { createTheme, ThemeProvider } from '@mui/material/styles'
3
+ import { CSSProperties } from '@mui/styles'
2
4
  import { DatePicker } from '@mui/x-date-pickers'
3
5
  import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment'
4
6
  import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'
@@ -40,15 +42,23 @@ const compactStyles = {
40
42
  },
41
43
  }
42
44
 
43
- const compactStyleTheme = createTheme({
44
- components: {
45
- MuiPaper: {
46
- defaultProps: {
47
- sx: compactStyles,
48
- },
49
- },
50
- },
51
- })
45
+ const getTheme = (isCompact: boolean, baseThemeOptions?: object | null) => {
46
+ if (isCompact) {
47
+ return createTheme(
48
+ Object.assign(baseThemeOptions ?? {}, {
49
+ components: {
50
+ MuiPaper: {
51
+ defaultProps: {
52
+ sx: compactStyles,
53
+ },
54
+ },
55
+ },
56
+ })
57
+ )
58
+ }
59
+
60
+ return createTheme(baseThemeOptions ?? {})
61
+ }
52
62
 
53
63
  export interface IDatePickerFieldProps {
54
64
  label: string;
@@ -56,6 +66,10 @@ export interface IDatePickerFieldProps {
56
66
  field: FieldInputProps<any>;
57
67
  form: FormikProps<any>;
58
68
  theme: 'dark' | 'light';
69
+ themeOptions?: ThemeOptions & {
70
+ input?: CSSProperties;
71
+ checkbox?: CSSProperties;
72
+ };
59
73
 
60
74
  useCompact?: boolean;
61
75
  }
@@ -70,10 +84,11 @@ export const DatePickerField = ({
70
84
  form,
71
85
  theme,
72
86
  useCompact = true,
87
+ themeOptions,
73
88
  dateFormat = 'DD/MM/YYYY',
74
89
  placeholder = 'dd/mm/yyyy',
75
90
  }: IDatePickerFieldProps & IOtherProps) => (
76
- <ThemeProvider theme={useCompact ? compactStyleTheme : {}}>
91
+ <ThemeProvider theme={getTheme(useCompact, themeOptions ?? null)}>
77
92
  <LocalizationProvider dateAdapter={AdapterMoment}>
78
93
  <DatePicker
79
94
  value={field.value || ''}
@@ -32,6 +32,7 @@ export const PhoneNumberField = ({
32
32
  setFieldValue,
33
33
  setFieldTouched,
34
34
  setErrors,
35
+ submitCount,
35
36
  },
36
37
  disableDropdown = true,
37
38
  defaultCountry = 'us',
@@ -41,6 +42,7 @@ export const PhoneNumberField = ({
41
42
  }: IPhoneNumberField) => {
42
43
  const error = _get(errors, field.name)
43
44
  const isTouched = Boolean(_get(touched, field.name))
45
+ const isSubmitAttempted = Boolean(submitCount && submitCount > 0)
44
46
 
45
47
  // eslint-disable-next-line react-hooks/exhaustive-deps
46
48
  const debounceCb = useCallback(
@@ -103,8 +105,8 @@ export const PhoneNumberField = ({
103
105
  defaultCountry={defaultCountry}
104
106
  disableDropdown={disableDropdown}
105
107
  label={label}
106
- error={!!error && (isTouched || fill)}
107
- helperText={(isTouched || fill) && error}
108
+ error={!!error && (isTouched || fill || isSubmitAttempted)}
109
+ helperText={(isTouched || fill || isSubmitAttempted) && error}
108
110
  fullWidth
109
111
  autoFormat={false}
110
112
  disableAreaCodes={true}
@@ -1,15 +1,15 @@
1
- import React from 'react'
2
1
  import { Alert, AlertColor, Snackbar, SnackbarOrigin } from '@mui/material'
2
+ import React from 'react'
3
3
 
4
4
  interface ISnackbarAlertProps {
5
- isOpen: boolean
6
- message: string
7
- type: AlertColor
8
- position?: SnackbarOrigin
9
- autoHideDuration?: number
10
- variant?: 'filled' | 'standard' | 'outlined'
5
+ isOpen: boolean;
6
+ message: string;
7
+ type: AlertColor;
8
+ position?: SnackbarOrigin;
9
+ autoHideDuration?: number;
10
+ variant?: 'filled' | 'standard' | 'outlined';
11
11
 
12
- onClose: () => void
12
+ onClose: () => void;
13
13
  }
14
14
 
15
15
  const SnackbarAlert = ({
@@ -20,35 +20,33 @@ const SnackbarAlert = ({
20
20
  autoHideDuration = 3000,
21
21
  variant,
22
22
  onClose,
23
- }: ISnackbarAlertProps) => {
24
- return (
25
- <div className="snackbar-alert-container">
26
- <Snackbar
27
- autoHideDuration={autoHideDuration}
28
- open={isOpen}
29
- anchorOrigin={position || { vertical: 'top', horizontal: 'center' }}
23
+ }: ISnackbarAlertProps) => (
24
+ <div className="snackbar-alert-container">
25
+ <Snackbar
26
+ autoHideDuration={autoHideDuration}
27
+ open={isOpen}
28
+ anchorOrigin={position || { vertical: 'top', horizontal: 'center' }}
29
+ onClose={onClose}
30
+ classes={{
31
+ root: 'snackbar-alert-snackbar-root',
32
+ }}
33
+ >
34
+ <Alert
35
+ severity={type}
30
36
  onClose={onClose}
37
+ variant={variant || 'filled'}
31
38
  classes={{
32
- root: 'snackbar-alert-snackbar-root',
39
+ icon: 'snackbar-alert-icon',
40
+ root: 'snackbar-alert-alert-root',
41
+ action: 'snackbar-alert-action',
42
+ message: 'snackbar-alert-message',
43
+ filled: 'snackbar-alert-filled',
33
44
  }}
34
45
  >
35
- <Alert
36
- severity={type}
37
- onClose={onClose}
38
- variant={variant || 'filled'}
39
- classes={{
40
- icon: 'snackbar-alert-icon',
41
- root: 'snackbar-alert-alert-root',
42
- action: 'snackbar-alert-action',
43
- message: 'snackbar-alert-message',
44
- filled: 'snackbar-alert-filled',
45
- }}
46
- >
47
- {message}
48
- </Alert>
49
- </Snackbar>
50
- </div>
51
- )
52
- }
46
+ {message}
47
+ </Alert>
48
+ </Snackbar>
49
+ </div>
50
+ )
53
51
 
54
52
  export default SnackbarAlert
@@ -29,7 +29,6 @@ import {
29
29
  TelegramShareButton,
30
30
  TumblrIcon,
31
31
  TumblrShareButton,
32
- TwitterIcon,
33
32
  TwitterShareButton,
34
33
  ViberIcon,
35
34
  ViberShareButton,
@@ -41,6 +40,7 @@ import {
41
40
  WhatsappShareButton,
42
41
  WorkplaceIcon,
43
42
  WorkplaceShareButton,
43
+ XIcon,
44
44
  } from 'react-share'
45
45
 
46
46
  import { InstagramIcon, SocialButton, SpotifyIcon } from '../common/socials'
@@ -51,7 +51,7 @@ const config: any = {
51
51
  component: FacebookMessengerShareButton,
52
52
  icon: FacebookMessengerIcon,
53
53
  },
54
- twitter: { component: TwitterShareButton, icon: TwitterIcon },
54
+ twitter: { component: TwitterShareButton, icon: XIcon },
55
55
  linkedin: { component: LinkedinShareButton, icon: LinkedinIcon },
56
56
  pinterest: { component: PinterestShareButton, icon: PinterestIcon },
57
57
  vk: { component: VKShareButton, icon: VKIcon },
@@ -74,6 +74,6 @@ const config: any = {
74
74
  spotify: { component: SocialButton, icon: SpotifyIcon },
75
75
  }
76
76
 
77
- export default function(key: string) {
77
+ export default function (key: string) {
78
78
  return config[key]
79
79
  }
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable max-len */
2
2
  import './style.css'
3
3
 
4
+ import { Button } from '@mui/material'
4
5
  import axios, { AxiosError } from 'axios'
5
6
  import _get from 'lodash/get'
6
7
  import _identity from 'lodash/identity'
@@ -24,6 +25,7 @@ export interface IShareButton {
24
25
  eventActionId?: string;
25
26
  oneTimeAction?: boolean;
26
27
  alreadyApplied?: boolean;
28
+ btnClassName?: string;
27
29
  }
28
30
 
29
31
  export interface IConfirmationLabels {
@@ -50,6 +52,8 @@ export interface IConfirmationPage {
50
52
  showReferralsInfoText?: boolean;
51
53
  showCopyInfoModal?: boolean;
52
54
  showPricingNoteSection?: boolean;
55
+ showOrderDetailsBtn?: boolean;
56
+ onOrderDetailsClick?: (data: ICheckoutCompleteData) => void;
53
57
  }
54
58
 
55
59
  export const ConfirmationContainer = ({
@@ -67,6 +71,8 @@ export const ConfirmationContainer = ({
67
71
  showReferralsInfoText = false,
68
72
  showCopyInfoModal = false,
69
73
  showPricingNoteSection = false,
74
+ showOrderDetailsBtn = false,
75
+ onOrderDetailsClick = _identity,
70
76
  }: IConfirmationPage) => {
71
77
  const inputRef = useRef(null)
72
78
  const [data, setData] = useState<ICheckoutCompleteData | null>(null)
@@ -195,6 +201,19 @@ export const ConfirmationContainer = ({
195
201
  dangerouslySetInnerHTML={createMarkup(data.custom_confirmation_page_text)}
196
202
  />
197
203
  ) : null}
204
+ {showOrderDetailsBtn && (
205
+ <div className="order-details-button-container">
206
+ <Button
207
+ className="view-order-button"
208
+ variant="contained"
209
+ onClick={() => {
210
+ onOrderDetailsClick(data)
211
+ }}
212
+ >
213
+ View Order
214
+ </Button>
215
+ </div>
216
+ )}
198
217
  {data.disable_referral === false && isReferralEnabled && (
199
218
  <>
200
219
  <div className="referral_text_image_section">
@@ -239,7 +258,7 @@ export const ConfirmationContainer = ({
239
258
  className="share-by-link-copy-icon"
240
259
  onClick={() => {
241
260
  navigator.clipboard.writeText(
242
- _get(inputRef, 'current.value')
261
+ _get(inputRef, 'current.value') || ''
243
262
  )
244
263
  setShowCopyModal(true)
245
264
  onLinkCopied()
@@ -14,6 +14,7 @@ const SocialComponent = ({
14
14
  onAfterShare,
15
15
  alreadyApplied,
16
16
  oneTimeAction,
17
+ btnClassName = '',
17
18
  }: IShareButton) => {
18
19
  const Component = config(platform)?.component
19
20
  const Icon = config(platform)?.icon
@@ -21,7 +22,7 @@ const SocialComponent = ({
21
22
  return (
22
23
  <>
23
24
  {Component && (
24
- <Component {...shareData} disabled={isActionDisabled}>
25
+ <Component {...shareData} disabled={isActionDisabled} className={btnClassName}>
25
26
  <div
26
27
  onKeyDown={_identity}
27
28
  onClick={!isActionDisabled ? onAfterShare : _identity}
@@ -91,13 +92,14 @@ const SocialButtons = ({
91
92
  }}
92
93
  />
93
94
  <SocialComponent
94
- mainLabel="Tweet to your"
95
- subLabel="Followers"
95
+ mainLabel="Post on"
96
+ subLabel="X"
96
97
  platform="twitter"
97
98
  shareData={{
98
99
  title: name,
99
100
  url: shareLink,
100
101
  }}
102
+ btnClassName="twitter-btn"
101
103
  />
102
104
  <SocialComponent
103
105
  mainLabel="Message friends on"
@@ -26,14 +26,14 @@
26
26
  .confirmation-page .main {
27
27
  font-weight: 700;
28
28
  font-size: 15px;
29
- font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
30
- Ubuntu, Cantarell, Open Sans, Helvetica Neue, Icons16, sans-serif;
29
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu,
30
+ Cantarell, Open Sans, Helvetica Neue, Icons16, sans-serif;
31
31
  }
32
32
  .confirmation-page .helper {
33
33
  font-size: 14px;
34
34
  margin-top: 5px;
35
- font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
36
- Ubuntu, Cantarell, Open Sans, Helvetica Neue, Icons16, sans-serif;
35
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu,
36
+ Cantarell, Open Sans, Helvetica Neue, Icons16, sans-serif;
37
37
  }
38
38
  .confirmation-page .referral_text_image_section {
39
39
  display: flex;
@@ -89,7 +89,7 @@
89
89
  .confirmation-page .social-media-btns {
90
90
  display: grid;
91
91
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
92
- grid-gap: 5px
92
+ grid-gap: 5px;
93
93
  }
94
94
  .confirmation-page .sharing-btn {
95
95
  min-width: 130px;
@@ -200,3 +200,7 @@
200
200
  width: 250px;
201
201
  }
202
202
  }
203
+
204
+ .twitter-btn {
205
+ background-color: #000 !important;
206
+ }
@@ -1,7 +1,8 @@
1
- import React, { useEffect, useState } from 'react'
2
- import moment from 'moment-timezone'
3
1
  import './style.css'
4
2
 
3
+ import moment from 'moment-timezone'
4
+ import React, { useEffect, useState } from 'react'
5
+
5
6
  interface CountdownTypes {
6
7
  startDate: string;
7
8
  timezone?: string;
@@ -13,9 +14,8 @@ interface CountdownTypes {
13
14
  isLoggedIn?: boolean;
14
15
  }
15
16
 
16
- const isTimeExpired = (startDate: string, timezone: string) => {
17
- return !moment(startDate).isAfter(moment.tz(moment(), timezone).format('YYYY-MM-DD HH:mm:ss'))
18
- }
17
+ const isTimeExpired = (startDate: string, timezone: string) =>
18
+ !moment(startDate).isAfter(moment.tz(moment(), timezone).format('YYYY-MM-DD HH:mm:ss'))
19
19
 
20
20
  function Countdown({
21
21
  startDate,
@@ -25,7 +25,7 @@ function Countdown({
25
25
  showMessage = false,
26
26
  disableLeadingZero = false,
27
27
  callback = () => {},
28
- isLoggedIn
28
+ isLoggedIn,
29
29
  }: CountdownTypes) {
30
30
  const [duration, setDuration] = useState('')
31
31
  const [timeExpired, setTimeExpired] = useState(false)
@@ -35,11 +35,11 @@ function Countdown({
35
35
  }, [])
36
36
 
37
37
  useEffect(() => {
38
- let timer: any;
38
+ let timer: any
39
39
 
40
- if(!timeExpired) {
40
+ if (!timeExpired) {
41
41
  timer = setInterval(() => {
42
- if(isTimeExpired(startDate, timezone)) {
42
+ if (isTimeExpired(startDate, timezone)) {
43
43
  clearInterval(timer)
44
44
  setTimeExpired(true)
45
45
  callback()
@@ -58,8 +58,8 @@ function Countdown({
58
58
  second: duration.seconds(),
59
59
  }
60
60
  let timeLeft = ''
61
-
62
- for(let date in dateArr) {
61
+
62
+ for (const date in dateArr) {
63
63
  const unit = dateArr[date] === 1 ? date : date + 's'
64
64
  let val = dateArr[date]
65
65
 
@@ -67,13 +67,13 @@ function Countdown({
67
67
  val = '0' + dateArr[date]
68
68
  }
69
69
 
70
- if(timeLeft) {
70
+ if (timeLeft) {
71
71
  timeLeft += `, ${val} ${unit}`
72
- } else if(dateArr[date]) {
72
+ } else if (dateArr[date]) {
73
73
  timeLeft += `${val} ${unit}`
74
74
  }
75
75
  }
76
-
76
+
77
77
  setDuration(timeLeft)
78
78
  }, 1000)
79
79
  }
@@ -84,15 +84,15 @@ function Countdown({
84
84
 
85
85
  return (
86
86
  <>
87
- {!timeExpired && duration && (
88
- <div className={`countdown ${!isLoggedIn ? 'countdown-on-bottom' : ''}`}>
89
- <div>
90
- <p className='title'>{title}</p>
91
- <p>{duration}</p>
87
+ {!timeExpired && duration && (
88
+ <div className={`countdown ${!isLoggedIn ? 'countdown-on-bottom' : ''}`}>
89
+ <div>
90
+ <p className="title">{title}</p>
91
+ <p>{duration}</p>
92
+ </div>
93
+ {showMessage && <p className="message">{message}</p>}
92
94
  </div>
93
- {showMessage && <p className='message'>{message}</p>}
94
- </div>
95
- )}
95
+ )}
96
96
  </>
97
97
  )
98
98
  }