tf-checkout-react 1.0.56 → 1.0.60

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 (40) hide show
  1. package/dist/api/index.d.ts +2 -0
  2. package/dist/components/confirmationContainer/index.d.ts +1 -1
  3. package/dist/components/index.d.ts +2 -0
  4. package/dist/components/myTicketsContainer/index.d.ts +9 -0
  5. package/dist/components/myTicketsContainer/row.d.ts +15 -0
  6. package/dist/components/myTicketsContainer/tableConfig.d.ts +5 -0
  7. package/dist/components/orderDetailsContainer/index.d.ts +8 -0
  8. package/dist/components/orderDetailsContainer/ticketsTable.d.ts +6 -0
  9. package/dist/components/ticketsContainer/index.d.ts +2 -1
  10. package/dist/env.d.ts +2 -2
  11. package/{src/components/billing-info-container → dist/images}/logo-ttf.png +0 -0
  12. package/dist/tf-checkout-react.cjs.development.js +43 -16
  13. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  14. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  15. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  16. package/dist/tf-checkout-react.esm.js +48 -67
  17. package/dist/tf-checkout-react.esm.js.map +1 -1
  18. package/dist/tf-checkout-styles.css +1 -0
  19. package/dist/utils/getImage.d.ts +1 -0
  20. package/package.json +2 -5
  21. package/src/.d.ts +2 -0
  22. package/src/api/index.ts +6 -1
  23. package/src/assets/images/logo-ttf.png +0 -0
  24. package/src/components/billing-info-container/index.tsx +4 -3
  25. package/src/components/confirmationContainer/index.tsx +3 -2
  26. package/src/components/index.ts +2 -0
  27. package/src/components/loginModal/index.tsx +1 -0
  28. package/src/components/myTicketsContainer/index.tsx +125 -0
  29. package/src/components/myTicketsContainer/row.tsx +41 -0
  30. package/src/components/myTicketsContainer/style.css +40 -0
  31. package/src/components/myTicketsContainer/tableConfig.tsx +34 -0
  32. package/src/components/orderDetailsContainer/index.tsx +120 -0
  33. package/src/components/orderDetailsContainer/style.css +53 -0
  34. package/src/components/orderDetailsContainer/ticketsTable.tsx +86 -0
  35. package/src/components/ticketsContainer/index.tsx +3 -1
  36. package/src/components/waitingList/index.tsx +1 -1
  37. package/src/components/waitingList/style.css +1 -0
  38. package/src/env.ts +2 -2
  39. package/src/utils/getImage.ts +14 -0
  40. package/dist/tf-checkout-react.cjs.development.css +0 -8
@@ -0,0 +1 @@
1
+ .button-container{display:flex;justify-content:center;padding:20px}.billing-info-container{margin:0 auto;max-width:800px}.billing-info-container .is-half{width:49%}.billing-info-container p{color:#000}.billing-info-container .main-header{font-size:2rem;font-weight:600}.billing-info-container__twoFields{display:flex;justify-content:space-between;margin-top:15px}.billing-info-container__singleField{margin-top:15px}.account-actions-block{color:#182026;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,Icons16,sans-serif;margin-top:10px}.login-register-button,.MuiButtonBase-root.MuiButton-root,.MuiButtonBase-root.MuiButton-root:hover{background-color:#212529;border:#f28051;border-radius:5px;color:#fff;cursor:pointer;display:block;font-family:Inter-Bold;font-size:26px;font-weight:700;line-height:1.15;margin-top:10px;min-height:46px;outline:none;overflow:hidden;padding:14px 12px 12px;position:relative;text-align:center;text-overflow:ellipsis;text-transform:uppercase;width:49%}.logo-image-container{margin-top:5px;text-align:center;width:49%}.logo-image-container img{height:30px}.login-block{align-items:center;display:flex;flex-direction:column}.login-register-button:hover{background-color:#505050!important;border-color:#505050!important}.login-register-block{display:flex;justify-content:space-between}@media only screen and (max-width:820px){.billing-info-container{width:90%}.billing-info-container .main-header{font-size:1.5rem}}.email-checking{margin-bottom:15px}.modal-title{align-items:center;background-color:#fff;display:flex;font-family:Inter;font-size:18px;font-weight:700;height:49px;line-height:22px;padding-left:25px;position:relative}.login-modal-body{padding:15px 25px}.login-modal-body input{background:#fff!important}.login-modal-body__email,.login-modal-body__password{margin-bottom:20px}.login-action-button button{background-color:#212529;border:none;border-radius:0;color:#fff;cursor:pointer;font-size:26px;font-weight:600;height:45px;line-height:18px;margin:10px 0;outline:none;padding:10px;width:100%}.login-action-button button:hover{background-color:#505050;border-color:#505050}.server_auth__error{color:red;font-family:Inter;font-size:12px;font-style:normal;padding-left:25px;padding-top:15px}.info-text-for-login{font-size:14px;margin-bottom:4px;padding-left:10px}.register-container{margin:0 auto;max-width:800px}.register-container .is-half{width:49%}.register-container__twoFields{display:flex;justify-content:space-between;margin-top:15px}.register-container__singleField{margin-top:15px}button{margin-top:10px}.payment_page{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,Icons16,sans-serif}.payment_page .order_info_section{padding:15px 0}.payment_page .order_info_section .order_info_block{padding-bottom:15px;padding-top:15px}.payment_page .order_info_section .order_info_block .field-underline{border-bottom:1px solid #000;padding-bottom:15px}.payment_page .order_info_section .order_info_block .order_info_title{font-size:14px;font-weight:700;padding-bottom:3px}.payment_page .order_info_section .order_info_block .order_info_text{font-size:16px;line-height:1.15;outline:none}.payment_page .MuiBox-root{margin-left:auto;margin-right:auto;padding:20px;text-align:center}.payment_page .payment_info_label{padding:20px 0;text-align:center}.payment_page .payment_form{color:#fff;padding:20px}.payment_page .payment_form input,.payment_page .payment_form label{color:#fff}.payment_page .payment_button{padding-top:20px;text-align:center}.card_form_inner{background:#232323;border-radius:8px;margin:0 auto 20px;min-width:325px;padding:15px;width:50%}.card_form_inner .card_label_text{color:#fff}.card_form_inner .StripeElement{margin:5px 0 10px}.card_label_text{color:#fff}.payment_button{padding-top:15px;text-align:center}.payment_button button{background-color:#212529;border-radius:8px;color:#fff;cursor:pointer;font-size:26px;padding:15px 30px;transition:opacity .5s;width:200px}.payment_button button:hover{opacity:.7}.disabled-payment-button button{opacity:.3;pointer-events:none;user-select:none}.checkout_error_block{color:#e53935;font-weight:600;padding:15px 0}.zip_element p{margin-bottom:0}.zip_element input{background-color:#232323;border:none;color:#fff;font-size:18px;margin-top:5px;outline:none;width:100%}.confirmation-page{margin:0 auto;max-width:1024px}.confirmation-page .strong-text{font-weight:700}.confirmation-page .title{color:#333;font-size:24px;font-weight:600}.confirmation-page .share-message-section{background:#dff0d8;border:1px solid #d6e9c6;border-radius:5px;color:#2c7221;display:flex;flex-direction:column;margin:20px 0;padding:15px}.confirmation-page .main{font-size:15px;font-weight:700}.confirmation-page .helper,.confirmation-page .main{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,Icons16,sans-serif}.confirmation-page .helper{font-size:14px;margin-top:5px}.confirmation-page .referral_text_image_section{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between;margin:20px -10px}.confirmation-page .referral_text_image_section .referral_text_section{margin:10px}.confirmation-page .referral_text_image_section .referral_title_text{color:#f08057;font-size:28px;padding-bottom:10px}.confirmation-page .referral_text_image_section .referral_text{font-size:18px}.confirmation-page .referral_text_image_section img{margin:10px;max-width:200px}.confirmation-page .share_wrapper{column-gap:5rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));margin:10px}.confirmation-page .share_wrapper .invitation_title{font-size:22px;padding-bottom:12px;padding-top:12px}.confirmation-page .share_wrapper .share_section{display:flex;flex-wrap:wrap;justify-content:space-between;margin:0 -10px}.confirmation-page .share_wrapper .share_section .invitation_section{flex:1 1;padding:0 5px}.confirmation-page .share_wrapper .share_section .invitation_section .share_buttons{display:grid;flex-wrap:wrap;margin:0 -7px}.confirmation-page .share_wrapper .share_section .invitation_section .share_buttons .social-media-btns{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}.confirmation-page .share_wrapper .share_section .invitation_section .share_buttons .social-media-btns .sharing-btn{min-width:130px}.confirmation-page .share_wrapper .share_section .invitation_section .share-btn-inner.share-by-link-copy{padding:0;text-align:left}.confirmation-page .share_wrapper .share_section .invitation_section .sharing-button{flex:1 1}.confirmation-page .share_wrapper .share_section .invitation_section .convenient_buttons.sharing-btn{display:inline}.confirmation-page .share_wrapper .share_section .invitation_section .share-by-link{background:#000;color:#fff;padding:0}.confirmation-page .share_wrapper .share_section .invitation_section .share-by-link.label{margin:0;padding:0;text-align:left}.confirmation-page .share_wrapper .share_section .invitation_section .sharing-btn{flex:1 1;padding:7px;text-align:center}.confirmation-page .share_wrapper .share_section .invitation_section .share-btn-inner{background:#000;color:#fff;padding:10px}.confirmation-page .share_wrapper .share_section .invitation_section .share-btn-inner .svg_wrapper{display:inline}.confirmation-page .share_wrapper .share_section .invitation_section .share-btn-inner .share-input{background-color:#fff;text-align:left;width:300px}.confirmation-page .share_wrapper .share_section .invitation_section .share-text{display:block;font-size:13px;font-weight:600;padding-top:8px;width:100%}.confirmation-page .share_wrapper .pricing-section_wrapper{background:#e3e3e3;border:1px solid #dcdcdc;display:grid;grid-template-columns:1fr 1fr;margin:10px 0;padding:15px}.confirmation-page .share_wrapper .pricing-section_wrapper.free_price{background:#e9835b;border:1px solid #eb7b4a;color:#fff}.confirmation-page .share_wrapper .pricing-section_label{font-weight:600}.confirmation-page .share_wrapper .pricing-section_sublabel{font-size:14px;font-weight:100}.confirmation-page .share_wrapper .pricing-section_price{font-weight:600;text-align:right}body{margin:0;padding:0}.get-tickets-page{width:100%}.event-detail__tier{background-color:#fff;padding:17px 35px 20px}.event-detail__tier-name{color:#000;font-family:Inter-Bold;font-family:Bebas Neue;font-size:.85rem;font-weight:700;letter-spacing:.2em;line-height:1.3;margin-bottom:8px;margin-top:16px;padding-right:20%;text-transform:uppercase}.event-detail__tier-status{align-items:center;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;margin-top:8px;width:100%}.event-detail__tier-status.ticket-button{background-color:#212529;border:3px solid #000;border-radius:0;color:#fff;cursor:pointer;font-weight:700;letter-spacing:.2em;line-height:1.5;margin-bottom:10px;width:200px}.event-tickets-container{align-items:center;display:flex;justify-content:space-between}.event-detail__tier-status.ticket-button.true{background-color:#c1c3c6;border-color:#afb0b1}.event-detail__tier-price{color:#000;font-family:Inter-Bold;font-size:1.5rem;font-weight:700;line-height:1;text-align:center}.event-detail__tier-price p{margin:0}.event-detail__tier-price .fees{font-size:14px;font-weight:400;margin-top:4px;text-align:left}.event-detail__tier-price .old-price{color:red;font-size:1.3rem;margin-bottom:5px;text-decoration:line-through}.alert-info{background-color:#d9edf7;border:1px solid #bce8f1;border-radius:4px;color:#3a87ad;font-size:1em;margin:0 35px;padding:8px 15px;text-align:center;text-shadow:0 1px 0 hsla(0,0%,100%,.5)}.event-detail__tier-state{color:#30bc9d;font-family:Inter-Bold;font-size:.75rem;font-weight:300;line-height:1;text-align:right;text-transform:uppercase}.promo-code-block input{font-size:14px;padding:1px 8px}.book-button{background-color:#212529;border:3px solid #000;border-radius:0;color:#fff;cursor:pointer;display:block;font-size:26px;font-weight:700;height:50px;letter-spacing:.2em;line-height:1.5;margin:25px auto 10px;text-align:center;width:100%}.book-button:hover{background-color:#505050;border-color:#505050}.loader-container{align-items:center;display:flex;height:100%;justify-content:center;width:100%}.get-tickets-paper::-webkit-scrollbar{width:5px}.get-tickets-paper::-webkit-scrollbar-track{background:#f1f1f1}.get-tickets-paper::-webkit-scrollbar-thumb{background:#888}.get-tickets-paper::-webkit-scrollbar-thumb:hover{background:#555}.get-tickets .get-tickets__selectbox{width:100%}.disabled{pointer-events:none;user-select:none}.hidden{display:none}.waiting-list{padding:17px 35px 20px}.waiting-list .field-item{margin-bottom:30px}.waiting-list .waiting-list-button{width:100%!important}.waiting-list .waiting-list-button:hover{background-color:#505050}.waiting-list .success-message h3{margin:10px 0}.waiting-list .success-message p{margin:0}.waiting-list .no-tickets-text{font-weight:700;text-align:center}.waiting-list .added-success-message{font-size:22px}
@@ -0,0 +1 @@
1
+ export declare const getImage: (name?: string) => any;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.56",
2
+ "version": "1.0.60",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -56,8 +56,7 @@
56
56
  "react": "^17.0.2",
57
57
  "react-dom": "^17.0.2",
58
58
  "rollup-plugin-postcss": "^4.0.1",
59
- "rollup-plugin-scss": "^3.0.0",
60
- "sass": "^1.43.4",
59
+ "rollup-plugin-static-files": "^0.2.0",
61
60
  "size-limit": "^6.0.4",
62
61
  "tsdx": "^0.14.1",
63
62
  "tslib": "^2.3.1",
@@ -71,9 +70,7 @@
71
70
  "@mui/styles": "^5.1.1",
72
71
  "@stripe/react-stripe-js": "^1.6.0",
73
72
  "@stripe/stripe-js": "^1.21.1",
74
- "autoprefixer": "^10.4.0",
75
73
  "axios": "^0.24.0",
76
- "cssnano": "^5.0.10",
77
74
  "formik": "^2.2.9",
78
75
  "jwt-decode": "^3.1.2",
79
76
  "lodash": "^4.17.21",
package/src/.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ declare module '*.css';
2
+ declare module '*.png';
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
 
Binary file
@@ -45,8 +45,9 @@ import { nanoid } from 'nanoid'
45
45
  import { getQueryVariable } from '../../utils/getQueryVariable'
46
46
  import { SelectField } from '../common/SelectField'
47
47
  import { ErrorFocus } from '../../utils/formikErrorFocus'
48
+ import { getImage } from '../../utils/getImage'
48
49
 
49
- // const TTFLOGO = require('./logo-ttf.png')
50
+ const TTFLOGO = getImage('logo-ttf.png')
50
51
 
51
52
  export interface IBillingInfoPage {
52
53
  data?: IBillingInfoData[];
@@ -507,9 +508,9 @@ export const BillingInfoContainer = ({
507
508
  >
508
509
  Login
509
510
  </button>
510
- {/* <div className="logo-image-container">
511
+ <div className="logo-image-container">
511
512
  <img src={TTFLOGO} alt="nodata" />
512
- </div> */}
513
+ </div>
513
514
  </div>
514
515
  </div>
515
516
  )}
@@ -35,6 +35,7 @@ const defaultSvg =
35
35
  'https://img.icons8.com/ios-filled/50/000000/facebook-new.svg'
36
36
 
37
37
  export const ConfirmationContainer = ({
38
+ isReferralEnabled,
38
39
  referralPromotions = [],
39
40
  shareButtons = [],
40
41
  shareLink = '',
@@ -68,7 +69,7 @@ export const ConfirmationContainer = ({
68
69
  }
69
70
  })()
70
71
  }, [])
71
-
72
+
72
73
  return (
73
74
  <div className="confirmation-page">
74
75
  <p className="title">Your Tickets are Confirmed!</p>
@@ -76,7 +77,7 @@ export const ConfirmationContainer = ({
76
77
  <span className="main">Your tickets have been emailed to you</span>
77
78
  <span className="helper">Please bring them with you to the event</span>
78
79
  </div>
79
- {data.disable_referral === false && (
80
+ { data.disable_referral === false && isReferralEnabled && (
80
81
  <>
81
82
  <div className="referral_text_image_section">
82
83
  <div className="referral_text_section">
@@ -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'
@@ -136,6 +136,7 @@ export const LoginModal: FC<Props> = ({
136
136
  {props => (
137
137
  <Form onSubmit={props.handleSubmit}>
138
138
  <div className="modal-title">Login</div>
139
+ <img className="login-logo-tff" src="https://www.ticketfairy.com/resources/images/logo-ttf-black.svg" alt=""/>
139
140
  <div className="server_auth__error">{error}</div>
140
141
  {alreadyHasUser && (
141
142
  <p className="info-text-for-login">
@@ -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