tf-checkout-react 1.0.58 → 1.0.59

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 (28) hide show
  1. package/dist/api/index.d.ts +2 -0
  2. package/dist/components/index.d.ts +2 -0
  3. package/dist/components/myTicketsContainer/index.d.ts +9 -0
  4. package/dist/components/myTicketsContainer/row.d.ts +15 -0
  5. package/dist/components/myTicketsContainer/tableConfig.d.ts +5 -0
  6. package/dist/components/orderDetailsContainer/index.d.ts +8 -0
  7. package/dist/components/orderDetailsContainer/ticketsTable.d.ts +6 -0
  8. package/dist/components/ticketsContainer/index.d.ts +2 -1
  9. package/dist/tf-checkout-react.cjs.development.css +1 -1
  10. package/dist/tf-checkout-react.cjs.development.js +8 -6
  11. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  12. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  13. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  14. package/dist/tf-checkout-react.esm.js +9 -7
  15. package/dist/tf-checkout-react.esm.js.map +1 -1
  16. package/package.json +1 -1
  17. package/src/api/index.ts +6 -1
  18. package/src/components/index.ts +2 -0
  19. package/src/components/myTicketsContainer/index.tsx +125 -0
  20. package/src/components/myTicketsContainer/row.tsx +41 -0
  21. package/src/components/myTicketsContainer/style.css +40 -0
  22. package/src/components/myTicketsContainer/tableConfig.tsx +34 -0
  23. package/src/components/orderDetailsContainer/index.tsx +120 -0
  24. package/src/components/orderDetailsContainer/style.css +53 -0
  25. package/src/components/orderDetailsContainer/ticketsTable.tsx +86 -0
  26. package/src/components/ticketsContainer/index.tsx +3 -1
  27. package/src/components/waitingList/index.tsx +1 -1
  28. package/src/components/waitingList/style.css +1 -0
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.58",
2
+ "version": "1.0.59",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
package/src/api/index.ts CHANGED
@@ -215,7 +215,12 @@ export const getCountries = () => publicRequest.get('/countries/')
215
215
 
216
216
  export const getConfirmationData = (orderHash: string) => publicRequest.get(`/v1/order/${orderHash}/payment/complete`)
217
217
 
218
- export const getStates = (countryId: string) => publicRequest.get(`/countries/${countryId}/states/`)
218
+ export const getStates = (countryId: string) => publicRequest.get(`/countries/${countryId}/states/`)
219
+
220
+ export const getOrders = (page: number, limit: number, eventSlug: string) =>
221
+ publicRequest.get(`/v1/account/orders/?page=${page}&limit=${limit}&filter[event]=${eventSlug}`)
222
+
223
+ export const getOrderDetails = (orderId: string) => publicRequest.get(`/v1/account/order/${orderId}`)
219
224
 
220
225
  export const addToWaitingList = (id: number, data: any) => publicRequest.post(`/v1/event/${id}/add_to_waiting_list`, data)
221
226
 
@@ -2,3 +2,5 @@ export { BillingInfoContainer } from './billing-info-container'
2
2
  export { ConfirmationContainer } from './confirmationContainer'
3
3
  export { PaymentContainer } from './paymentContainer'
4
4
  export { TicketsContainer } from './ticketsContainer'
5
+ export { MyTicketsContainer } from './myTicketsContainer'
6
+ export { OrderDetailsContainer } from './orderDetailsContainer'
@@ -0,0 +1,125 @@
1
+ import React, { useEffect, useState } from 'react'
2
+ import './style.css'
3
+
4
+ import Table from '@mui/material/Table'
5
+ import TableBody from '@mui/material/TableBody'
6
+ import TableCell from '@mui/material/TableCell'
7
+ import TableContainer from '@mui/material/TableContainer'
8
+ import TableHead from '@mui/material/TableHead'
9
+ import TableRow from '@mui/material/TableRow'
10
+ import Paper from '@mui/material/Paper'
11
+ import TablePagination from '@mui/material/TablePagination'
12
+ import CircularProgress from '@mui/material/CircularProgress'
13
+ import TextField from '@mui/material/TextField'
14
+ import Autocomplete from '@mui/material/Autocomplete'
15
+ import _get from 'lodash/get'
16
+ import MyTicketsRow, { RowItems } from './row'
17
+ import tableConfig from './tableConfig'
18
+ import { getOrders } from '../../api'
19
+
20
+ interface MyTicketsTypes {
21
+ handleDetailsInfo: (id: string) => void;
22
+ onGetOrdersSuccess: (res: any) => void;
23
+ onGetOrdersError: (err: any) => void;
24
+ }
25
+
26
+ interface EventFilter {
27
+ event_name: string;
28
+ url_name: string;
29
+ }
30
+
31
+ export const MyTicketsContainer = ({
32
+ handleDetailsInfo = () => {},
33
+ onGetOrdersSuccess = () => {},
34
+ onGetOrdersError = () => {}
35
+ }: MyTicketsTypes) => {
36
+ const [data, setData] = useState<any>(null)
37
+ const [loading, setLoading] = useState(true)
38
+ const [limit, setLimit] = useState(10)
39
+ const [filter, setFilter] = useState('')
40
+
41
+ //just once
42
+ useEffect(() => {
43
+ fetchData(1, limit, filter)
44
+ }, [])
45
+
46
+ const fetchData = async (page: number, limit: number, filter: string) => {
47
+ try {
48
+ setLoading(true)
49
+ const response = await getOrders(page, limit, filter)
50
+ onGetOrdersSuccess(response)
51
+
52
+ const data = _get(response, 'data.data.attributes')
53
+ data.page -= 1
54
+
55
+ setData(data)
56
+ } catch (error) {
57
+ onGetOrdersError(error)
58
+ } finally {
59
+ setLoading(false)
60
+ }
61
+ }
62
+
63
+ const handleChangePage = (_event: any, newPage: number) => {
64
+ fetchData(newPage + 1, limit, filter)
65
+ }
66
+
67
+ const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
68
+ fetchData(1, +event.target.value, filter)
69
+ setLimit(+event.target.value)
70
+ }
71
+
72
+ const onChange = (_event: React.SyntheticEvent<Element, Event>, eventFilter: EventFilter | null) => {
73
+ fetchData(1, limit, eventFilter?.url_name || '' )
74
+ setFilter(eventFilter?.url_name || '')
75
+ }
76
+
77
+ return (
78
+ <div className='my-ticket'>
79
+ {loading && (
80
+ <div className='loading'>
81
+ <CircularProgress />
82
+ </div>
83
+ )}
84
+ {data && (
85
+ <>
86
+ <Autocomplete
87
+ disablePortal
88
+ id="combo-box-demo"
89
+ getOptionLabel={(option: EventFilter) => option.event_name}
90
+ onChange={onChange}
91
+ options={data.purchased_events}
92
+ sx={{ width: 300 }}
93
+ renderInput={(params) => <TextField {...params} label="Events" />}
94
+ />
95
+ <TableContainer component={Paper} className='my-ticket-table'>
96
+ <Table aria-label="collapsible table">
97
+ <TableHead>
98
+ <TableRow>
99
+ {tableConfig().header.map((column: string, index: number) => (
100
+ <TableCell key={index}>{column}</TableCell>
101
+ ))}
102
+ <TableCell />
103
+ </TableRow>
104
+ </TableHead>
105
+ <TableBody>
106
+ {data.orders?.map((row: RowItems) => (
107
+ <MyTicketsRow key={row.id} row={row} handleDetailsInfo={handleDetailsInfo} />
108
+ ))}
109
+ </TableBody>
110
+ </Table>
111
+ </TableContainer>
112
+ <TablePagination
113
+ rowsPerPageOptions={[10, 25, 100]}
114
+ component="div"
115
+ count={data.total_count}
116
+ rowsPerPage={limit}
117
+ page={data.page}
118
+ onPageChange={handleChangePage}
119
+ onRowsPerPageChange={handleChangeRowsPerPage}
120
+ />
121
+ </>
122
+ )}
123
+ </div>
124
+ )
125
+ }
@@ -0,0 +1,41 @@
1
+ import React from 'react'
2
+ import TableRow from '@mui/material/TableRow'
3
+ import TableCell from '@mui/material/TableCell'
4
+ import tableConfig from './tableConfig'
5
+
6
+ export interface RowItems {
7
+ id: string;
8
+ date: string;
9
+ image: string;
10
+ eventName: string;
11
+ amount: string;
12
+ currency: string;
13
+ }
14
+
15
+ interface RowPropsTypes {
16
+ row: RowItems;
17
+ handleDetailsInfo: (id: string) => void;
18
+ }
19
+
20
+ const Row = ({ row, handleDetailsInfo }: RowPropsTypes) => {
21
+ return (
22
+ <TableRow sx={{ '& > *': { borderBottom: 'unset' } }}>
23
+ {tableConfig().body.map((column: any, index: number) => (
24
+ <TableCell component="th" scope="row" key={index}>
25
+ {column(row)}
26
+ </TableCell>
27
+ ))}
28
+ <TableCell component="th" scope="row">
29
+ <button
30
+ type='button'
31
+ className="order-details-button"
32
+ onClick={() => handleDetailsInfo(row.id)}
33
+ >
34
+ Details
35
+ </button>
36
+ </TableCell>
37
+ </TableRow>
38
+ );
39
+ }
40
+
41
+ export default Row
@@ -0,0 +1,40 @@
1
+ .my-ticket {
2
+ padding: 30px;
3
+ }
4
+ .my-ticket-table {
5
+ margin-top: 30px;
6
+ }
7
+ .my-ticket .loading {
8
+ width: 100%;
9
+ display: flex;
10
+ justify-content: center;
11
+ align-items: center;
12
+ height: 100vh;
13
+ position: fixed;
14
+ top: 0;
15
+ left: 0;
16
+ background-color: rgba(0, 0, 0, .4);
17
+ }
18
+ .my-ticket .event-info {
19
+ display: flex;
20
+ align-items: center;
21
+ }
22
+ .my-ticket thead th {
23
+ font-weight: 700;
24
+ }
25
+ .my-ticket .event-info img {
26
+ width: 50px;
27
+ margin-right: 10px;
28
+ }
29
+ .my-ticket .order-details-button {
30
+ border: none;
31
+ border-radius: 4px;
32
+ color: #fff;
33
+ background-color: #32325d;
34
+ transition: all 150ms ease;
35
+ cursor: pointer;
36
+ padding: 10px 14px;
37
+ }
38
+ .my-ticket .order-details-button:hover {
39
+ background-color: #505050;
40
+ }
@@ -0,0 +1,34 @@
1
+ import React from 'react'
2
+
3
+ interface EventInfoTypes {
4
+ image: string;
5
+ name: string;
6
+ }
7
+
8
+ const EventInfoItem = ({ image, name }: EventInfoTypes) => {
9
+ return (
10
+ <div className='event-info'>
11
+ <img src={image} alt="event" />
12
+ {name}
13
+ </div>
14
+ )
15
+ }
16
+
17
+ const tableConfig = (key?: string) => {
18
+ let config;
19
+ switch (key) {
20
+ default:
21
+ config = {
22
+ header: ['Order No.', 'Date', 'Event', 'Total'],
23
+ body: [
24
+ (row: any) => row.id,
25
+ (row: any) => row.date,
26
+ (row: any) => <EventInfoItem image={row.image} name={row.eventName} />,
27
+ (row: any) => row.currency + row.amount
28
+ ],
29
+ }
30
+ }
31
+ return config
32
+ }
33
+
34
+ export default tableConfig
@@ -0,0 +1,120 @@
1
+ import React, { useState, useEffect } from 'react'
2
+ import './style.css'
3
+
4
+ import Table from '@mui/material/Table'
5
+ import TableBody from '@mui/material/TableBody'
6
+ import TableCell from '@mui/material/TableCell'
7
+ import TableContainer from '@mui/material/TableContainer'
8
+ import TableHead from '@mui/material/TableHead'
9
+ import TableRow from '@mui/material/TableRow'
10
+ import Paper from '@mui/material/Paper'
11
+ import CircularProgress from '@mui/material/CircularProgress'
12
+ import _get from 'lodash/get'
13
+ import _has from 'lodash/has'
14
+ import { getOrderDetails } from '../../api'
15
+ import TicketsTable from './ticketsTable'
16
+
17
+ interface TicketTypes {
18
+ currency: string;
19
+ discount: string;
20
+ name: string;
21
+ price: string;
22
+ quantity: string;
23
+ total: string;
24
+ }
25
+
26
+ interface OrderDetailsTypes {
27
+ onGetOrdersSuccess: (res: any) => void;
28
+ onGetOrdersError: (err: any) => void;
29
+ }
30
+
31
+ const getTotal = (data: any) => {
32
+ if(!data?.total || !_has(data, 'items.ticket_types.length')) return ''
33
+
34
+ return data.items.ticket_types[0].currency + data.total
35
+ }
36
+
37
+ export const OrderDetailsContainer = ({
38
+ onGetOrdersSuccess = () => {},
39
+ onGetOrdersError = () => {}
40
+ }: OrderDetailsTypes) => {
41
+ const [data, setData] = useState<any>(null)
42
+ const [loading, setLoading] = useState(true)
43
+
44
+ useEffect(() => {
45
+ (async () => {
46
+ try {
47
+ setLoading(true)
48
+ const orderId = window.location.href.split('/').slice(-1)[0]
49
+ const response = await getOrderDetails(orderId)
50
+ onGetOrdersSuccess(response)
51
+
52
+ const data = _get(response, 'data.data.attributes')
53
+
54
+ setData(data)
55
+ } catch (error) {
56
+ onGetOrdersError(error)
57
+ } finally {
58
+ setLoading(false)
59
+ }
60
+ })()
61
+ }, [])
62
+
63
+ return (
64
+ <div className="order-details">
65
+ {loading ? (
66
+ <div className='loading'>
67
+ <CircularProgress />
68
+ </div>
69
+ ) : (
70
+ <>
71
+ <h1 className='layout-title'>Order Details</h1>
72
+ <div className='order-summary-box'>
73
+ <h4 className='sub-title'>Order Summary</h4>
74
+ <div>
75
+ <b>Your personal share link for this event is:{" "}</b>
76
+ <a href={data?.personal_share_link} target='_blank' rel='noreferrer'>{data?.personal_share_link}</a>
77
+ </div>
78
+ <TableContainer component={Paper}>
79
+ <Table aria-label="collapsible table">
80
+ <TableHead>
81
+ <TableRow>
82
+ <TableCell>Items</TableCell>
83
+ <TableCell>Price</TableCell>
84
+ <TableCell>Quantity</TableCell>
85
+ <TableCell>Total</TableCell>
86
+ </TableRow>
87
+ </TableHead>
88
+ <TableBody>
89
+ {data?.items.ticket_types?.map((ticket: TicketTypes, index: number) => (
90
+ <TableRow key={index}>
91
+ <TableCell><b>Ticket Type: </b>{ticket.name}</TableCell>
92
+ <TableCell>{ticket.currency + ticket.price}</TableCell>
93
+ <TableCell>{ticket.quantity}</TableCell>
94
+ <TableCell>{ticket.currency + ticket.total}</TableCell>
95
+ </TableRow>
96
+ ))}
97
+ {data?.items.add_ons?.map((ticket: TicketTypes, index: number) => (
98
+ <TableRow key={index}>
99
+ <TableCell><b>Add-On: </b>{ticket.name}</TableCell>
100
+ <TableCell>{ticket.currency + ticket.price}</TableCell>
101
+ <TableCell>{ticket.quantity}</TableCell>
102
+ <TableCell>{ticket.currency + ticket.total}</TableCell>
103
+ </TableRow>
104
+ ))}
105
+ <TableRow className='total-row'>
106
+ <TableCell />
107
+ <TableCell />
108
+ <TableCell>Total</TableCell>
109
+ <TableCell>{getTotal(data)}</TableCell>
110
+ </TableRow>
111
+ </TableBody>
112
+ </Table>
113
+ </TableContainer>
114
+ </div>
115
+ <TicketsTable tickets={data.tickets} />
116
+ </>
117
+ )}
118
+ </div>
119
+ )
120
+ }
@@ -0,0 +1,53 @@
1
+ .order-details {
2
+ max-width: 940px;
3
+ margin: 0 auto;
4
+ }
5
+ .order-details .loading {
6
+ width: 100%;
7
+ display: flex;
8
+ justify-content: center;
9
+ align-items: center;
10
+ height: 100vh;
11
+ position: fixed;
12
+ top: 0;
13
+ left: 0;
14
+ background-color: rgba(0, 0, 0, .4);
15
+ }
16
+ .order-details .layout-title {
17
+ font-size: 24px;
18
+ font-weight: 400;
19
+ }
20
+ .order-details .sub-title {
21
+ font-size: 18px;
22
+ font-weight: 400;
23
+ margin: 10px 0;
24
+ }
25
+ .order-details .order-summary-box {
26
+ margin-top: 30px;
27
+ }
28
+ .order-details .total-row td {
29
+ font-weight: 700;
30
+ }
31
+ .order-details th {
32
+ font-weight: 700;
33
+ }
34
+ .order-details .tickets-box {
35
+ margin-top: 30px;
36
+ }
37
+ .order-details .ticket-add-on-table {
38
+ background-color: #fcf8e3;;
39
+ }
40
+ .order-details .download-button {
41
+ border: none;
42
+ border-radius: 4px;
43
+ text-decoration: none;
44
+ color: #fff;
45
+ background-color: #32325d;
46
+ font-size: 12px;
47
+ font-weight: 400;
48
+ transition: all 150ms ease;
49
+ padding: 8px 14px;
50
+ }
51
+ .order-details .download-button:hover {
52
+ background-color: #505050;
53
+ }
@@ -0,0 +1,86 @@
1
+ import React, { Fragment } from 'react'
2
+ import Table from '@mui/material/Table'
3
+ import TableBody from '@mui/material/TableBody'
4
+ import TableCell from '@mui/material/TableCell'
5
+ import TableContainer from '@mui/material/TableContainer'
6
+ import TableHead from '@mui/material/TableHead'
7
+ import TableRow from '@mui/material/TableRow'
8
+ import Paper from '@mui/material/Paper'
9
+
10
+ interface TicketsTableTypes {
11
+ tickets: any[];
12
+ }
13
+
14
+ interface TicketTypes {
15
+ add_ons: any[];
16
+ hash: string;
17
+ ticket_type: string;
18
+ holder_name: string;
19
+ status: string;
20
+ pdf_link: string;
21
+ }
22
+
23
+ interface AddOnTypes {
24
+ name: string;
25
+ status: string;
26
+ }
27
+
28
+ const TicketsTable = ({ tickets = [] }: TicketsTableTypes) => {
29
+ return (
30
+ <div className='tickets-box'>
31
+ <h4 className='sub-title'>Your Tickets</h4>
32
+ <TableContainer component={Paper}>
33
+ <Table aria-label="collapsible table">
34
+ <TableHead>
35
+ <TableRow>
36
+ <TableCell>Ticket ID</TableCell>
37
+ <TableCell>Ticket Type</TableCell>
38
+ <TableCell>Ticket Holder Name</TableCell>
39
+ <TableCell>Status</TableCell>
40
+ <TableCell>Download</TableCell>
41
+ </TableRow>
42
+ </TableHead>
43
+ <TableBody>
44
+ {tickets.map((ticket: TicketTypes, index: number) => (
45
+ <Fragment key={index}>
46
+ <TableRow>
47
+ <TableCell>{ticket.hash}</TableCell>
48
+ <TableCell>{ticket.ticket_type}</TableCell>
49
+ <TableCell>{ticket.holder_name}</TableCell>
50
+ <TableCell>{ticket.status}</TableCell>
51
+ <TableCell>
52
+ <a className='download-button' href={ticket.pdf_link} download>Download</a>
53
+ </TableCell>
54
+ </TableRow>
55
+ {!!ticket.add_ons?.length && (
56
+ <TableRow>
57
+ <TableCell colSpan={5}>
58
+ <Table className='ticket-add-on-table'>
59
+ <TableHead>
60
+ <TableRow>
61
+ <TableCell>Add-On</TableCell>
62
+ <TableCell>Status</TableCell>
63
+ </TableRow>
64
+ </TableHead>
65
+ <TableBody>
66
+ {ticket.add_ons.map((add_on: AddOnTypes, index: number) => (
67
+ <TableRow key={index}>
68
+ <TableCell>{add_on.name}</TableCell>
69
+ <TableCell>{add_on.status}</TableCell>
70
+ </TableRow>
71
+ ))}
72
+ </TableBody>
73
+ </Table>
74
+ </TableCell>
75
+ </TableRow>
76
+ )}
77
+ </Fragment>
78
+ ))}
79
+ </TableBody>
80
+ </Table>
81
+ </TableContainer>
82
+ </div>
83
+ )
84
+ }
85
+
86
+ export default TicketsTable
@@ -40,6 +40,7 @@ export interface IGetTickets {
40
40
  onGetTicketsError: (e: AxiosError) => void;
41
41
 
42
42
  theme?: 'light' | 'dark';
43
+ queryPromoCode?: string;
43
44
  }
44
45
 
45
46
  export interface ITicket {
@@ -60,6 +61,7 @@ export const TicketsContainer = ({
60
61
  onGetTicketsSuccess = () => {},
61
62
  onGetTicketsError = () => {},
62
63
  theme = 'light',
64
+ queryPromoCode = ''
63
65
  }: IGetTickets) => {
64
66
  const [selectedTickets, setSelectedTickets] = useState(
65
67
  {} as ISelectedTickets
@@ -69,7 +71,7 @@ export const TicketsContainer = ({
69
71
  const [isLoading, setIsLoading] = useState(false)
70
72
  const [handleBookIsLoading, setHandleBookIsLoading] = useState(false)
71
73
  const [promoCode, setPromoCode] = useState('')
72
- const [promoCodeUpdated, setPromoCodeUpdated] = useState('')
74
+ const [promoCodeUpdated, setPromoCodeUpdated] = useState(queryPromoCode)
73
75
  const [showPromoInput, setShowPromoInput] = useState(false)
74
76
  const [promoCodeIsApplied, setPromoCodeIsApplied] = useState(false)
75
77
 
@@ -66,7 +66,6 @@ const WaitingList = ({ tickets = {} }: WaitingListProps) => {
66
66
 
67
67
  return (
68
68
  <div className="waiting-list">
69
- <p className="no-tickets-text">No tickets are currently available for this event.</p>
70
69
  {showSuccessMessage ? (
71
70
  <div className="success-message">
72
71
  <p className="added-success-message">{`You've been added to the waiting list!`}</p>
@@ -74,6 +73,7 @@ const WaitingList = ({ tickets = {} }: WaitingListProps) => {
74
73
  </div>
75
74
  ) : (
76
75
  <>
76
+ <p className="no-tickets-text">No tickets are currently available for this event.</p>
77
77
  <h2>WAITING LIST</h2>
78
78
  <Formik
79
79
  initialValues={{
@@ -18,6 +18,7 @@
18
18
  }
19
19
  .waiting-list .no-tickets-text {
20
20
  text-align: center;
21
+ font-weight: bold;
21
22
  }
22
23
  .waiting-list .added-success-message {
23
24
  font-size: 22px;