tf-checkout-react 1.6.6 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) 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 +25 -1
  16. package/dist/components/common/DatePickerField.d.ts +7 -1
  17. package/dist/components/confirmationContainer/index.d.ts +4 -1
  18. package/dist/components/countdown/index.d.ts +1 -1
  19. package/dist/components/forgotPasswordModal/index.d.ts +2 -1
  20. package/dist/components/myTicketsContainer/index.d.ts +3 -2
  21. package/dist/components/orderDetailsContainer/index.d.ts +8 -1
  22. package/dist/components/paymentContainer/OrderDetails.d.ts +9 -0
  23. package/dist/components/paymentContainer/handlePayment.d.ts +15 -0
  24. package/dist/components/paymentContainer/index.d.ts +12 -6
  25. package/dist/components/preRegistration/FieldsSection.d.ts +7 -1
  26. package/dist/components/preRegistration/PreRegistrationComplete.d.ts +6 -0
  27. package/dist/components/preRegistration/constants.d.ts +2 -2
  28. package/dist/components/preRegistration/index.d.ts +6 -0
  29. package/dist/components/resetPasswordContainer/index.d.ts +2 -2
  30. package/dist/components/ticketsContainer/InfoIcon.d.ts +5 -0
  31. package/dist/components/ticketsContainer/TicketsSection.d.ts +3 -2
  32. package/dist/components/ticketsContainer/TimeSlotsSection.d.ts +25 -0
  33. package/dist/components/ticketsContainer/index.d.ts +29 -5
  34. package/dist/components/timerWidget/index.d.ts +2 -1
  35. package/dist/constants/index.d.ts +5 -0
  36. package/dist/index.d.ts +4 -1
  37. package/dist/tf-checkout-react.cjs.development.js +11231 -9563
  38. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  39. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  40. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  41. package/dist/tf-checkout-react.esm.js +11194 -9529
  42. package/dist/tf-checkout-react.esm.js.map +1 -1
  43. package/dist/tf-checkout-styles.css +1 -1
  44. package/dist/types/add_on.d.ts +1 -0
  45. package/dist/types/checkoutPageConfigs.d.ts +1 -1
  46. package/dist/types/order-data.d.ts +3 -1
  47. package/dist/utils/auth.d.ts +8 -0
  48. package/dist/utils/customFields.d.ts +11 -0
  49. package/dist/utils/getDomain.d.ts +1 -1
  50. package/dist/utils/index.d.ts +1 -1
  51. package/dist/utils/setConfigs.d.ts +1 -0
  52. package/package.json +14 -8
  53. package/src/adapters/customFields.ts +7 -1
  54. package/src/api/auth.ts +2 -1
  55. package/src/api/checkout.ts +9 -4
  56. package/src/api/common.ts +49 -2
  57. package/src/api/index.ts +1 -0
  58. package/src/api/interceptors.ts +7 -23
  59. package/src/api/preRegistrationComplete.ts +1 -1
  60. package/src/api/publicRequest.ts +10 -0
  61. package/src/components/addonsContainer/AddonComponent.tsx +96 -11
  62. package/src/components/addonsContainer/SimpleAddonsContainer.tsx +420 -0
  63. package/src/components/addonsContainer/index.tsx +198 -47
  64. package/src/components/billing-info-container/hooks/index.ts +3 -0
  65. package/src/components/billing-info-container/hooks/usePaymentContext.ts +22 -0
  66. package/src/components/billing-info-container/hooks/usePaymentRedirect.ts +147 -0
  67. package/src/components/billing-info-container/hooks/useStripePayment.ts +121 -0
  68. package/src/components/billing-info-container/index.tsx +827 -406
  69. package/src/components/billing-info-container/{utils.ts → utils.tsx} +119 -0
  70. package/src/components/common/CheckboxField/index.tsx +1 -1
  71. package/src/components/common/CustomField.tsx +38 -2
  72. package/src/components/common/DatePickerField.tsx +25 -10
  73. package/src/components/common/SnackbarAlert.tsx +32 -34
  74. package/src/components/confirmationContainer/config.ts +3 -3
  75. package/src/components/confirmationContainer/index.tsx +20 -1
  76. package/src/components/confirmationContainer/social-buttons.tsx +5 -3
  77. package/src/components/confirmationContainer/style.css +9 -5
  78. package/src/components/countdown/index.tsx +22 -22
  79. package/src/components/delegationsContainer/IssueComponent.tsx +2 -1
  80. package/src/components/forgotPasswordModal/index.tsx +44 -13
  81. package/src/components/loginForm/index.tsx +1 -1
  82. package/src/components/loginModal/index.tsx +19 -27
  83. package/src/components/loginModal/style.css +3 -1
  84. package/src/components/myTicketsContainer/index.tsx +13 -9
  85. package/src/components/orderDetailsContainer/index.tsx +206 -174
  86. package/src/components/paymentContainer/OrderDetails.tsx +257 -0
  87. package/src/components/paymentContainer/handlePayment.ts +86 -0
  88. package/src/components/paymentContainer/index.tsx +299 -259
  89. package/src/components/paymentContainer/style.css +141 -0
  90. package/src/components/preRegistration/FieldsSection.tsx +8 -0
  91. package/src/components/preRegistration/PreRegistrationComplete.tsx +128 -118
  92. package/src/components/preRegistration/PreRegistrationInformations.tsx +21 -15
  93. package/src/components/preRegistration/constants.tsx +10 -4
  94. package/src/components/preRegistration/index.tsx +194 -174
  95. package/src/components/registerForm/constants.tsx +3 -1
  96. package/src/components/registerForm/index.tsx +3 -3
  97. package/src/components/registerModal/index.tsx +47 -72
  98. package/src/components/resetPasswordContainer/index.tsx +20 -14
  99. package/src/components/seatMapContainer/TicketsSection.tsx +2 -2
  100. package/src/components/signupModal/index.tsx +13 -6
  101. package/src/components/ticketResale/index.tsx +7 -0
  102. package/src/components/ticketsContainer/InfoIcon.tsx +35 -0
  103. package/src/components/ticketsContainer/PromoCodeSection.tsx +34 -28
  104. package/src/components/ticketsContainer/TicketRow.tsx +1 -1
  105. package/src/components/ticketsContainer/TicketsSection.tsx +189 -57
  106. package/src/components/ticketsContainer/TimeSlotsSection.tsx +120 -0
  107. package/src/components/ticketsContainer/index.tsx +268 -106
  108. package/src/components/timerWidget/index.tsx +15 -3
  109. package/src/constants/index.ts +2 -0
  110. package/src/env.ts +14 -6
  111. package/src/hoc/CustomFields/index.tsx +9 -1
  112. package/src/index.ts +7 -2
  113. package/src/types/add_on.ts +1 -0
  114. package/src/types/api/cart.d.ts +8 -0
  115. package/src/types/api/checkout.d.ts +58 -7
  116. package/src/types/api/common.d.ts +30 -0
  117. package/src/types/api/orders.d.ts +19 -3
  118. package/src/types/api/payment.d.ts +6 -2
  119. package/src/types/api/preRegistrationComplete.d.ts +2 -2
  120. package/src/types/checkoutPageConfigs.ts +1 -1
  121. package/src/types/order-data.ts +3 -1
  122. package/src/types/pre-registration-complete.d.ts +6 -1
  123. package/src/utils/auth.ts +32 -0
  124. package/src/utils/cookies.ts +42 -11
  125. package/src/utils/customFields.ts +22 -0
  126. package/src/utils/getDomain.ts +10 -4
  127. package/src/utils/index.ts +1 -1
  128. package/src/utils/setConfigs.ts +3 -1
  129. package/dist/components/stripePayment/index.d.ts +0 -24
  130. package/src/components/stripePayment/index.tsx +0 -281
  131. 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'
@@ -288,3 +289,121 @@ export const getFieldComponent = (element: IGroupItem) => {
288
289
  const fieldComponent = _get(fieldComponentConfigs, type, CustomField)
289
290
  return fieldComponent
290
291
  }
292
+
293
+ /**
294
+ * Renders a React component with the provided props
295
+ * @param Component - The React component to render
296
+ * @param props - The props to apply to the component
297
+ * @returns JSX element with applied props
298
+ */
299
+ export const renderComponentWithProps = <T extends Record<string, any>>(
300
+ Component: React.ComponentType<T>,
301
+ props: T
302
+ ): React.ReactElement<T> => <Component {...props} />
303
+
304
+ export const filterBillingInfoFields = (
305
+ fields: IGroupItem[],
306
+ options: {
307
+ showDOB: boolean;
308
+ hideTtfOptIn: boolean;
309
+ hidePhoneField: boolean;
310
+ flagRequirePhone: boolean;
311
+ collectMandatoryWalletAddress: boolean;
312
+ collectMandatoryJobTitle: boolean;
313
+ collectMandatoryBusinessCategory: boolean;
314
+ collectMandatoryCompany: boolean;
315
+ collectMandatoryInstagram: boolean;
316
+ flagFreeTicket: boolean;
317
+ hideWalletAddressField: boolean;
318
+ hideJobTitleField: boolean;
319
+ hideBusinessCategoryField: boolean;
320
+ hideCompanyField: boolean;
321
+ hideInstagramField: boolean;
322
+ }
323
+ ) => {
324
+ const {
325
+ showDOB,
326
+ hideTtfOptIn,
327
+ hidePhoneField,
328
+ flagRequirePhone,
329
+ collectMandatoryWalletAddress,
330
+ collectMandatoryJobTitle,
331
+ collectMandatoryBusinessCategory,
332
+ collectMandatoryCompany,
333
+ collectMandatoryInstagram,
334
+ flagFreeTicket,
335
+ hideWalletAddressField,
336
+ hideJobTitleField,
337
+ hideBusinessCategoryField,
338
+ hideCompanyField,
339
+ hideInstagramField,
340
+ } = options
341
+ return fields.filter(el => {
342
+ if (el.name === 'holderAge' && !showDOB) {
343
+ return false
344
+ }
345
+ if (el.name === 'ttf_opt_in' && hideTtfOptIn) {
346
+ return false
347
+ }
348
+ if (el.name === 'phone') {
349
+ if (!hidePhoneField) {
350
+ el.required = flagRequirePhone
351
+ } else {
352
+ return false
353
+ }
354
+ }
355
+ if (el.name === 'data_capture[wallet_address]') {
356
+ if (collectMandatoryWalletAddress) {
357
+ el.required = true
358
+ }
359
+ }
360
+ if (el.name === 'data_capture[jobTitle]') {
361
+ if (collectMandatoryJobTitle) {
362
+ el.required = true
363
+ }
364
+ }
365
+ if (el.name === 'data_capture[businessCategory]') {
366
+ if (collectMandatoryBusinessCategory) {
367
+ el.required = true
368
+ }
369
+ }
370
+ if (el.name === 'data_capture[company]') {
371
+ if (collectMandatoryCompany) {
372
+ el.required = true
373
+ }
374
+ }
375
+ if (el.name === 'data_capture[instagram]') {
376
+ if (collectMandatoryInstagram) {
377
+ el.required = true
378
+ }
379
+ }
380
+ if (['street_address', 'country', 'state', 'city'].includes(el.name)) {
381
+ if (flagFreeTicket) {
382
+ el.required = false
383
+ return false
384
+ }
385
+ }
386
+ if (
387
+ hideWalletAddressField &&
388
+ (el.name === 'wallet-address-info' || el.name === 'data_capture[wallet_address]')
389
+ ) {
390
+ return false
391
+ }
392
+ if (hideJobTitleField && el.name === 'data_capture[jobTitle]') {
393
+ return false
394
+ }
395
+ if (hideBusinessCategoryField && el.name === 'data_capture[businessCategory]') {
396
+ return false
397
+ }
398
+ if (hideCompanyField && el.name === 'data_capture[company]') {
399
+ return false
400
+ }
401
+ if (
402
+ hideInstagramField &&
403
+ (el.name === 'data_capture[instagram]' || el.name === 'instagram-info')
404
+ ) {
405
+ return false
406
+ }
407
+ return true
408
+ })
409
+ }
@@ -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}
@@ -94,7 +130,7 @@ export const CustomField = ({
94
130
  sx: customTheme?.input,
95
131
  shrink: 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 || ''}
@@ -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
  }
@@ -1,4 +1,5 @@
1
1
  import axios, { AxiosError } from 'axios'
2
+ import _get from 'lodash/get'
2
3
  import _identity from 'lodash/identity'
3
4
  import _map from 'lodash/map'
4
5
  import React, { useEffect, useState } from 'react'
@@ -123,7 +124,7 @@ const IssueComponent = ({
123
124
  resetForm()
124
125
  } catch (e) {
125
126
  if (axios.isAxiosError(e)) {
126
- const error = e?.response?.data?.message || 'Error'
127
+ const error = _get(e, 'response.data.message') || 'Error'
127
128
  setError(error)
128
129
  } else if (e instanceof Error) {
129
130
  setError(e?.message || 'Error')