tf-checkout-react 1.0.100 → 1.0.104

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 (84) hide show
  1. package/dist/components/billing-info-container/index.d.ts +3 -1
  2. package/dist/components/common/RedirectModal.d.ts +7 -0
  3. package/dist/components/common/SnackbarAlert.d.ts +13 -0
  4. package/dist/components/confirmationContainer/index.d.ts +2 -1
  5. package/dist/components/ticketsContainer/index.d.ts +2 -1
  6. package/dist/env.d.ts +1 -0
  7. package/dist/images/done.svg +3 -3
  8. package/dist/index.d.ts +1 -0
  9. package/dist/tf-checkout-react.cjs.development.js +317 -136
  10. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  11. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  12. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  13. package/dist/tf-checkout-react.esm.js +318 -138
  14. package/dist/tf-checkout-react.esm.js.map +1 -1
  15. package/dist/tf-checkout-styles.css +1 -1
  16. package/package.json +89 -89
  17. package/src/.DS_Store +0 -0
  18. package/src/.d.ts +2 -2
  19. package/src/api/index.ts +293 -278
  20. package/src/assets/images/done.svg +3 -3
  21. package/src/components/.DS_Store +0 -0
  22. package/src/components/billing-info-container/index.tsx +796 -777
  23. package/src/components/billing-info-container/style.css +105 -105
  24. package/src/components/billing-info-container/utils.ts +224 -224
  25. package/src/components/common/CheckboxField.tsx +41 -41
  26. package/src/components/common/CustomField.tsx +84 -84
  27. package/src/components/common/FormikPhoneNumberField.tsx +51 -51
  28. package/src/components/common/Loader.tsx +9 -9
  29. package/src/components/common/RadioField.tsx +35 -35
  30. package/src/components/common/RedirectModal.tsx +43 -0
  31. package/src/components/common/SelectField.tsx +80 -80
  32. package/src/components/common/SnackbarAlert.tsx +54 -0
  33. package/src/components/common/index.tsx +4 -4
  34. package/src/components/confirmModal/index.tsx +51 -51
  35. package/src/components/confirmModal/style.css +21 -21
  36. package/src/components/confirmationContainer/config.ts +72 -72
  37. package/src/components/confirmationContainer/index.tsx +197 -194
  38. package/src/components/confirmationContainer/social-buttons.tsx +94 -94
  39. package/src/components/confirmationContainer/style.css +202 -202
  40. package/src/components/countdown/index.tsx +89 -89
  41. package/src/components/countdown/style.css +9 -9
  42. package/src/components/index.ts +7 -7
  43. package/src/components/loginModal/index.tsx +209 -209
  44. package/src/components/loginModal/style.css +71 -71
  45. package/src/components/myTicketsContainer/index.tsx +196 -137
  46. package/src/components/myTicketsContainer/row.tsx +41 -41
  47. package/src/components/myTicketsContainer/style.css +39 -39
  48. package/src/components/myTicketsContainer/tableConfig.tsx +34 -34
  49. package/src/components/orderDetailsContainer/index.tsx +249 -249
  50. package/src/components/orderDetailsContainer/style.css +72 -72
  51. package/src/components/orderDetailsContainer/ticketsTable.tsx +124 -124
  52. package/src/components/paymentContainer/index.tsx +284 -284
  53. package/src/components/registerModal/index.tsx +190 -190
  54. package/src/components/stripePayment/index.tsx +253 -253
  55. package/src/components/stripePayment/style.css +59 -59
  56. package/src/components/ticketResale/index.tsx +56 -56
  57. package/src/components/ticketResaleModal/index.tsx +210 -210
  58. package/src/components/ticketResaleModal/style.css +28 -28
  59. package/src/components/ticketsContainer/PromoCodeSection.tsx +99 -99
  60. package/src/components/ticketsContainer/ReferralLogic.tsx +33 -33
  61. package/src/components/ticketsContainer/TicketRow.tsx +83 -83
  62. package/src/components/ticketsContainer/TicketsSection.tsx +81 -81
  63. package/src/components/ticketsContainer/index.tsx +427 -409
  64. package/src/components/ticketsContainer/style.css +181 -181
  65. package/src/components/ticketsContainer/utils.ts +11 -11
  66. package/src/components/timerWidget/index.tsx +70 -70
  67. package/src/components/timerWidget/style.css +26 -26
  68. package/src/components/waitingList/index.tsx +178 -178
  69. package/src/components/waitingList/style.css +26 -26
  70. package/src/env.ts +20 -19
  71. package/src/index.ts +14 -13
  72. package/src/normalizers/index.ts +45 -45
  73. package/src/types/billing-info-data.ts +37 -37
  74. package/src/types/payment-field.ts +7 -7
  75. package/src/types/referral-promotion.ts +7 -7
  76. package/src/utils/createCheckoutDataBodyWithDefaultHolder.ts +59 -59
  77. package/src/utils/downloadPDF.tsx +30 -30
  78. package/src/utils/formikErrorFocus.ts +24 -24
  79. package/src/utils/getImage.ts +14 -14
  80. package/src/utils/getQueryVariable.ts +13 -13
  81. package/src/utils/index.ts +5 -5
  82. package/src/utils/setConfigs.ts +26 -26
  83. package/src/utils/showZero.tsx +10 -10
  84. package/src/validators/index.ts +20 -20
@@ -1,99 +1,99 @@
1
- import React from 'react'
2
- import Button from 'react-bootstrap/Button'
3
- import SVG from 'react-inlinesvg'
4
- import { getImage } from '../../utils/getImage'
5
- import { Loader } from '../common/index'
6
-
7
- export interface IPromoCodeSectionProps {
8
- promoCode: string;
9
- promoCodeIsApplied: boolean;
10
- showPromoInput: boolean;
11
- isPromotionsEnabled: boolean;
12
- isAllTicketsSoldOut: boolean;
13
- isAccessCodeEnabled?: boolean;
14
- isPromoLoading?: boolean;
15
- setPromoCode: (value: string) => void;
16
- setPromoCodeUpdated: (value: string) => void;
17
- setShowPromoInput: (value: boolean) => void;
18
- }
19
-
20
- export const PromoCodeSection = ({
21
- promoCode,
22
- promoCodeIsApplied,
23
- showPromoInput,
24
- isPromotionsEnabled,
25
- setPromoCode,
26
- setPromoCodeUpdated,
27
- setShowPromoInput,
28
- isAccessCodeEnabled,
29
- isPromoLoading,
30
- }: IPromoCodeSectionProps) => {
31
- const isPromoCodeHasValue = !!promoCode.trim()
32
-
33
- const renderInputField = () => {
34
- return (
35
- <div className="promo-code-block">
36
- <div className="promo-code-block">
37
- <p className="promo-code-text">
38
- { isAccessCodeEnabled ? 'Access code required' : 'Promo code'}
39
- </p>
40
-
41
- </div>
42
- <input
43
- className="promo-code-input"
44
- placeholder=""
45
- onChange={e => {
46
- setPromoCode(e.target.value)
47
- }}
48
- onKeyPress={event => {
49
- if (event.key === 'Enter' && isPromoCodeHasValue) {
50
- setPromoCodeUpdated(promoCode)
51
- setShowPromoInput(false)
52
- }
53
- }}
54
- />
55
- <Button
56
- className="promo-submit-button"
57
- onClick={() => {
58
- if (isPromoCodeHasValue) {
59
- setPromoCodeUpdated(promoCode)
60
- setShowPromoInput(false)
61
- }
62
- }}
63
- >
64
- {isAccessCodeEnabled ? 'ENTER' : 'APPLY'}
65
- </Button>
66
- </div>
67
- )
68
- }
69
-
70
- return isPromoLoading ? <Loader /> : (
71
- <div >
72
- {promoCodeIsApplied ? (
73
- <div className="alert-info">
74
- <SVG
75
- src={getImage('done.svg')}
76
- preProcessor={(code) => code.replace(/fill=".*?"/g, 'fill="currentColor"')}
77
- />
78
- <p className="promo-code-success">PROMO CODE APPLIED SUCCESSFULLY</p>
79
- </div>
80
- ) : null}
81
- {showPromoInput && (
82
- renderInputField()
83
- )}
84
- {isPromotionsEnabled && !showPromoInput && !isAccessCodeEnabled ? (
85
- <Button
86
- className="promo-code-button"
87
- placeholder="Promo Codes"
88
- onClick={() => {
89
- setShowPromoInput(true)
90
- }}
91
- >
92
- Got a promo code? Click here
93
- </Button>
94
- ) : !isPromotionsEnabled && !showPromoInput && isAccessCodeEnabled && !promoCodeIsApplied ? renderInputField() :
95
- null
96
- }
97
- </div>
98
- )
99
- }
1
+ import React from 'react'
2
+ import Button from 'react-bootstrap/Button'
3
+ import SVG from 'react-inlinesvg'
4
+ import { getImage } from '../../utils/getImage'
5
+ import { Loader } from '../common/index'
6
+
7
+ export interface IPromoCodeSectionProps {
8
+ promoCode: string;
9
+ promoCodeIsApplied: boolean;
10
+ showPromoInput: boolean;
11
+ isPromotionsEnabled: boolean;
12
+ isAllTicketsSoldOut: boolean;
13
+ isAccessCodeEnabled?: boolean;
14
+ isPromoLoading?: boolean;
15
+ setPromoCode: (value: string) => void;
16
+ setPromoCodeUpdated: (value: string) => void;
17
+ setShowPromoInput: (value: boolean) => void;
18
+ }
19
+
20
+ export const PromoCodeSection = ({
21
+ promoCode,
22
+ promoCodeIsApplied,
23
+ showPromoInput,
24
+ isPromotionsEnabled,
25
+ setPromoCode,
26
+ setPromoCodeUpdated,
27
+ setShowPromoInput,
28
+ isAccessCodeEnabled,
29
+ isPromoLoading,
30
+ }: IPromoCodeSectionProps) => {
31
+ const isPromoCodeHasValue = !!promoCode.trim()
32
+
33
+ const renderInputField = () => {
34
+ return (
35
+ <div className="promo-code-block">
36
+ <div className="promo-code-block">
37
+ <p className="promo-code-text">
38
+ { isAccessCodeEnabled ? 'Access code required' : 'Promo code'}
39
+ </p>
40
+
41
+ </div>
42
+ <input
43
+ className="promo-code-input"
44
+ placeholder=""
45
+ onChange={e => {
46
+ setPromoCode(e.target.value)
47
+ }}
48
+ onKeyPress={event => {
49
+ if (event.key === 'Enter' && isPromoCodeHasValue) {
50
+ setPromoCodeUpdated(promoCode)
51
+ setShowPromoInput(false)
52
+ }
53
+ }}
54
+ />
55
+ <Button
56
+ className="promo-submit-button"
57
+ onClick={() => {
58
+ if (isPromoCodeHasValue) {
59
+ setPromoCodeUpdated(promoCode)
60
+ setShowPromoInput(false)
61
+ }
62
+ }}
63
+ >
64
+ {isAccessCodeEnabled ? 'ENTER' : 'APPLY'}
65
+ </Button>
66
+ </div>
67
+ )
68
+ }
69
+
70
+ return isPromoLoading ? <Loader /> : (
71
+ <div >
72
+ {promoCodeIsApplied ? (
73
+ <div className="alert-info">
74
+ <SVG
75
+ src={getImage('done.svg')}
76
+ preProcessor={(code) => code.replace(/fill=".*?"/g, 'fill="currentColor"')}
77
+ />
78
+ <p className="promo-code-success">PROMO CODE APPLIED SUCCESSFULLY</p>
79
+ </div>
80
+ ) : null}
81
+ {showPromoInput && (
82
+ renderInputField()
83
+ )}
84
+ {isPromotionsEnabled && !showPromoInput && !isAccessCodeEnabled ? (
85
+ <Button
86
+ className="promo-code-button"
87
+ placeholder="Promo Codes"
88
+ onClick={() => {
89
+ setShowPromoInput(true)
90
+ }}
91
+ >
92
+ Got a promo code? Click here
93
+ </Button>
94
+ ) : !isPromotionsEnabled && !showPromoInput && isAccessCodeEnabled && !promoCodeIsApplied ? renderInputField() :
95
+ null
96
+ }
97
+ </div>
98
+ )
99
+ }
@@ -1,33 +1,33 @@
1
- import { useEffect } from 'react'
2
- import { postReferralVisits } from '../../api'
3
-
4
- interface IReferralLogicProps {
5
- eventId: string | number;
6
- }
7
-
8
- export const ReferralLogic = (props: IReferralLogicProps) => {
9
- const { eventId } = props
10
- const isWindowDefined = typeof window !== 'undefined'
11
-
12
- useEffect(() => {
13
- if (isWindowDefined) {
14
- const params: URLSearchParams = new URL(`${window.location}`).searchParams
15
- const referralId = params.get('ttf_r') || ''
16
- const isAlreadyCounted = !!localStorage.getItem('referral_key')
17
-
18
- if (referralId && eventId && !isAlreadyCounted) {
19
- (async () => {
20
- try {
21
- await postReferralVisits(`${eventId}`, referralId)
22
- localStorage.setItem(
23
- 'referral_key',
24
- [eventId, '.', referralId].join('')
25
- )
26
- } catch (error) {}
27
- })()
28
- }
29
- }
30
- }, [])
31
-
32
- return null
33
- }
1
+ import { useEffect } from 'react'
2
+ import { postReferralVisits } from '../../api'
3
+
4
+ interface IReferralLogicProps {
5
+ eventId: string | number;
6
+ }
7
+
8
+ export const ReferralLogic = (props: IReferralLogicProps) => {
9
+ const { eventId } = props
10
+ const isWindowDefined = typeof window !== 'undefined'
11
+
12
+ useEffect(() => {
13
+ if (isWindowDefined) {
14
+ const params: URLSearchParams = new URL(`${window.location}`).searchParams
15
+ const referralId = params.get('ttf_r') || ''
16
+ const isAlreadyCounted = !!localStorage.getItem('referral_key')
17
+
18
+ if (referralId && eventId && !isAlreadyCounted) {
19
+ (async () => {
20
+ try {
21
+ await postReferralVisits(`${eventId}`, referralId)
22
+ localStorage.setItem(
23
+ 'referral_key',
24
+ [eventId, '.', referralId].join('')
25
+ )
26
+ } catch (error) {}
27
+ })()
28
+ }
29
+ }
30
+ }, [])
31
+
32
+ return null
33
+ }
@@ -1,83 +1,83 @@
1
- import React from 'react'
2
- import './style.css'
3
- import _has from 'lodash/has'
4
- import _get from 'lodash/get'
5
- import Box from '@mui/material/Box'
6
- import FormControl from '@mui/material/FormControl'
7
- import MenuItem from '@mui/material/MenuItem'
8
- import Select from '@mui/material/Select'
9
-
10
- import { getTicketSelectOptions } from './utils'
11
-
12
- interface ITicketRowProps {
13
- ticketTier: any;
14
- prevTicketTier: any;
15
- selectedTickets: any;
16
- handleTicketSelect: any;
17
- }
18
-
19
- export const TicketRow = ({
20
- ticketTier,
21
- prevTicketTier,
22
- selectedTickets,
23
- handleTicketSelect,
24
- }: ITicketRowProps) => {
25
- const soldOutMessage = ticketTier.soldOutMessage
26
- ? `${ticketTier.soldOutMessage}`.toUpperCase()
27
- : 'SOLD OUT'
28
- const isSalesClosed = !ticketTier.salesStarted || ticketTier.salesEnded
29
- const options = getTicketSelectOptions(
30
- ticketTier.maxQuantity,
31
- ticketTier.minQuantity,
32
- ticketTier.multiplier
33
- )
34
- const ticketsClosedMessage = !ticketTier.salesStarted ? 'Sales not started' : 'Sales Ended'
35
-
36
- const onSaleContent = isSalesClosed ? ticketsClosedMessage : (
37
- <div className="get-tickets">
38
- <Box className="get-tickets__selectbox">
39
- <FormControl fullWidth>
40
- <Select
41
- sx={{
42
- borderRadius: 0,
43
- }}
44
- value={
45
- selectedTickets[ticketTier.id]
46
- ? selectedTickets[ticketTier.id]
47
- : 0
48
- }
49
- onChange={handleTicketSelect}
50
- displayEmpty
51
- inputProps={{ 'aria-label': 'Without label' }}
52
- MenuProps={{
53
- PaperProps: {
54
- sx: { maxHeight: 150 },
55
- className: 'get-tickets-paper',
56
- },
57
- }}
58
- >
59
- {options.map((option, index) => (
60
- <MenuItem key={index} value={option.value}>
61
- {option.value}
62
- </MenuItem>
63
- ))}
64
- </Select>
65
- </FormControl>
66
- </Box>
67
- </div>
68
- )
69
-
70
- let returnValue: any = ''
71
-
72
- if (ticketTier.sold_out || !ticketTier.displayTicket || ticketTier.soldOut) {
73
- returnValue = soldOutMessage
74
- }
75
- if (ticketTier.displayTicket) {
76
- returnValue = onSaleContent
77
- }
78
- if (_get(prevTicketTier, 'in_stock')) {
79
- returnValue = 'SOON'
80
- }
81
-
82
- return <>{returnValue} </>
83
- }
1
+ import React from 'react'
2
+ import './style.css'
3
+ import _has from 'lodash/has'
4
+ import _get from 'lodash/get'
5
+ import Box from '@mui/material/Box'
6
+ import FormControl from '@mui/material/FormControl'
7
+ import MenuItem from '@mui/material/MenuItem'
8
+ import Select from '@mui/material/Select'
9
+
10
+ import { getTicketSelectOptions } from './utils'
11
+
12
+ interface ITicketRowProps {
13
+ ticketTier: any;
14
+ prevTicketTier: any;
15
+ selectedTickets: any;
16
+ handleTicketSelect: any;
17
+ }
18
+
19
+ export const TicketRow = ({
20
+ ticketTier,
21
+ prevTicketTier,
22
+ selectedTickets,
23
+ handleTicketSelect,
24
+ }: ITicketRowProps) => {
25
+ const soldOutMessage = ticketTier.soldOutMessage
26
+ ? `${ticketTier.soldOutMessage}`.toUpperCase()
27
+ : 'SOLD OUT'
28
+ const isSalesClosed = !ticketTier.salesStarted || ticketTier.salesEnded
29
+ const options = getTicketSelectOptions(
30
+ ticketTier.maxQuantity,
31
+ ticketTier.minQuantity,
32
+ ticketTier.multiplier
33
+ )
34
+ const ticketsClosedMessage = !ticketTier.salesStarted ? 'Sales not started' : 'Sales Ended'
35
+
36
+ const onSaleContent = isSalesClosed ? ticketsClosedMessage : (
37
+ <div className="get-tickets">
38
+ <Box className="get-tickets__selectbox">
39
+ <FormControl fullWidth>
40
+ <Select
41
+ sx={{
42
+ borderRadius: 0,
43
+ }}
44
+ value={
45
+ selectedTickets[ticketTier.id]
46
+ ? selectedTickets[ticketTier.id]
47
+ : 0
48
+ }
49
+ onChange={handleTicketSelect}
50
+ displayEmpty
51
+ inputProps={{ 'aria-label': 'Without label' }}
52
+ MenuProps={{
53
+ PaperProps: {
54
+ sx: { maxHeight: 150 },
55
+ className: 'get-tickets-paper',
56
+ },
57
+ }}
58
+ >
59
+ {options.map((option, index) => (
60
+ <MenuItem key={index} value={option.value}>
61
+ {option.value}
62
+ </MenuItem>
63
+ ))}
64
+ </Select>
65
+ </FormControl>
66
+ </Box>
67
+ </div>
68
+ )
69
+
70
+ let returnValue: any = ''
71
+
72
+ if (ticketTier.sold_out || !ticketTier.displayTicket || ticketTier.soldOut) {
73
+ returnValue = soldOutMessage
74
+ }
75
+ if (ticketTier.displayTicket) {
76
+ returnValue = onSaleContent
77
+ }
78
+ if (_get(prevTicketTier, 'in_stock')) {
79
+ returnValue = 'SOON'
80
+ }
81
+
82
+ return <>{returnValue} </>
83
+ }
@@ -1,81 +1,81 @@
1
- import React from 'react'
2
- import './style.css'
3
-
4
- import _sortBy from 'lodash/sortBy'
5
- import { TicketRow } from './TicketRow'
6
-
7
- interface ITicketsSectionProps {
8
- ticketsList: any;
9
- selectedTickets: any;
10
- handleTicketSelect: any;
11
- promoCodeIsApplied: boolean;
12
- }
13
-
14
- export const TicketsSection = ({
15
- ticketsList,
16
- selectedTickets,
17
- handleTicketSelect,
18
- promoCodeIsApplied,
19
- }: ITicketsSectionProps) => {
20
- const sortedTicketsList = _sortBy(ticketsList, 'sortOrder')
21
- return (
22
- <>
23
- {sortedTicketsList.map((ticket, i, arr) => {
24
- const isSoldOut =
25
- ticket.sold_out || !ticket.displayTicket || ticket.soldOut
26
- const ticketSelect = (event: any) => {
27
- const { value } = event.target
28
- handleTicketSelect(ticket.id, value)
29
- }
30
-
31
- let ticketIsDiscounted = false
32
- if (
33
- ticket.oldPrice &&
34
- promoCodeIsApplied &&
35
- !isSoldOut &&
36
- ticket.oldPrice !== ticket.price
37
- ) {
38
- ticketIsDiscounted = true
39
- }
40
-
41
- const ticketIsFree = (+ticket.cost || +ticket.price) === 0
42
- const ticketPrice = isSoldOut ? 'SOLD OUT' : ticketIsFree ? 'FREE' : `$ ${(+ticket.cost || +ticket.price).toFixed(2)}`
43
-
44
- return (
45
- <div
46
- key={ticket.id || ticket.name}
47
- className={`event-detail__tier ${isSoldOut ? 'disabled' : ''}`}
48
- >
49
- <div className="event-detail__tier-name">
50
- {ticket.displayName || ticket.name}
51
- </div>
52
- <div className="event-tickets-container">
53
- <div className="event-detail__tier-price">
54
- {ticketIsDiscounted && (
55
- <p className="old-price">$ {(+ticket.oldPrice).toFixed(2)}</p>
56
- )}
57
- <p>{ticketPrice}</p>
58
- {!isSoldOut && !ticketIsFree && (
59
- <p className="fees">
60
- {ticket.feeIncluded ? '(incl. Fees)' : '(excl. Fees)'}
61
- </p>
62
- )}
63
- </div>
64
- <div
65
- className="event-detail__tier-state"
66
- style={{ minWidth: 55 }}
67
- >
68
- <TicketRow
69
- ticketTier={ticket}
70
- prevTicketTier={arr[i - 1]}
71
- selectedTickets={selectedTickets}
72
- handleTicketSelect={ticketSelect}
73
- />
74
- </div>
75
- </div>
76
- </div>
77
- )
78
- })}
79
- </>
80
- )
81
- }
1
+ import React from 'react'
2
+ import './style.css'
3
+
4
+ import _sortBy from 'lodash/sortBy'
5
+ import { TicketRow } from './TicketRow'
6
+
7
+ interface ITicketsSectionProps {
8
+ ticketsList: any;
9
+ selectedTickets: any;
10
+ handleTicketSelect: any;
11
+ promoCodeIsApplied: boolean;
12
+ }
13
+
14
+ export const TicketsSection = ({
15
+ ticketsList,
16
+ selectedTickets,
17
+ handleTicketSelect,
18
+ promoCodeIsApplied,
19
+ }: ITicketsSectionProps) => {
20
+ const sortedTicketsList = _sortBy(ticketsList, 'sortOrder')
21
+ return (
22
+ <>
23
+ {sortedTicketsList.map((ticket, i, arr) => {
24
+ const isSoldOut =
25
+ ticket.sold_out || !ticket.displayTicket || ticket.soldOut
26
+ const ticketSelect = (event: any) => {
27
+ const { value } = event.target
28
+ handleTicketSelect(ticket.id, value)
29
+ }
30
+
31
+ let ticketIsDiscounted = false
32
+ if (
33
+ ticket.oldPrice &&
34
+ promoCodeIsApplied &&
35
+ !isSoldOut &&
36
+ ticket.oldPrice !== ticket.price
37
+ ) {
38
+ ticketIsDiscounted = true
39
+ }
40
+
41
+ const ticketIsFree = (+ticket.cost || +ticket.price) === 0
42
+ const ticketPrice = isSoldOut ? 'SOLD OUT' : ticketIsFree ? 'FREE' : `$ ${(+ticket.cost || +ticket.price).toFixed(2)}`
43
+
44
+ return (
45
+ <div
46
+ key={ticket.id || ticket.name}
47
+ className={`event-detail__tier ${isSoldOut ? 'disabled' : ''}`}
48
+ >
49
+ <div className="event-detail__tier-name">
50
+ {ticket.displayName || ticket.name}
51
+ </div>
52
+ <div className="event-tickets-container">
53
+ <div className="event-detail__tier-price">
54
+ {ticketIsDiscounted && (
55
+ <p className="old-price">$ {(+ticket.oldPrice).toFixed(2)}</p>
56
+ )}
57
+ <p>{ticketPrice}</p>
58
+ {!isSoldOut && !ticketIsFree && (
59
+ <p className="fees">
60
+ {ticket.feeIncluded ? '(incl. Fees)' : '(excl. Fees)'}
61
+ </p>
62
+ )}
63
+ </div>
64
+ <div
65
+ className="event-detail__tier-state"
66
+ style={{ minWidth: 55 }}
67
+ >
68
+ <TicketRow
69
+ ticketTier={ticket}
70
+ prevTicketTier={arr[i - 1]}
71
+ selectedTickets={selectedTickets}
72
+ handleTicketSelect={ticketSelect}
73
+ />
74
+ </div>
75
+ </div>
76
+ </div>
77
+ )
78
+ })}
79
+ </>
80
+ )
81
+ }