tf-checkout-react 1.3.51 → 1.4.0

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 (50) hide show
  1. package/dist/api/index.d.ts +6 -1
  2. package/dist/components/common/Loader.d.ts +1 -1
  3. package/dist/components/idVerificationContainer/constants.d.ts +2 -0
  4. package/dist/components/index.d.ts +1 -0
  5. package/dist/components/seatMapContainer/SeatMapComponent.d.ts +8 -0
  6. package/dist/components/seatMapContainer/TicketsSection.d.ts +9 -0
  7. package/dist/components/seatMapContainer/addToCart.d.ts +21 -0
  8. package/dist/components/seatMapContainer/index.d.ts +2 -0
  9. package/dist/components/seatMapContainer/utils.d.ts +14 -0
  10. package/dist/components/stripePayment/index.d.ts +2 -2
  11. package/dist/components/ticketsContainer/TicketRow.d.ts +3 -1
  12. package/dist/components/ticketsContainer/TicketsSection.d.ts +5 -1
  13. package/dist/components/ticketsContainer/index.d.ts +6 -2
  14. package/dist/index.d.ts +1 -0
  15. package/dist/tf-checkout-react.cjs.development.js +1435 -128
  16. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  17. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  18. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  19. package/dist/tf-checkout-react.esm.js +1436 -130
  20. package/dist/tf-checkout-react.esm.js.map +1 -1
  21. package/dist/tf-checkout-styles.css +1 -1
  22. package/dist/types/order-data.d.ts +3 -0
  23. package/dist/utils/createCheckoutDataBodyWithDefaultHolder.d.ts +9 -2
  24. package/package.json +12 -4
  25. package/src/.d.ts +4 -3
  26. package/src/api/index.ts +89 -6
  27. package/src/components/billing-info-container/index.tsx +111 -102
  28. package/src/components/common/Loader.tsx +6 -8
  29. package/src/components/common/dist/PhoneNumberField.js +96 -0
  30. package/src/components/confirmationContainer/index.tsx +11 -9
  31. package/src/components/idVerificationContainer/constants.ts +2 -0
  32. package/src/components/idVerificationContainer/index.tsx +54 -13
  33. package/src/components/index.ts +2 -1
  34. package/src/components/orderDetailsContainer/index.tsx +54 -23
  35. package/src/components/paymentContainer/index.tsx +167 -33
  36. package/src/components/seatMapContainer/SeatMapComponent.tsx +73 -0
  37. package/src/components/seatMapContainer/TicketsSection.tsx +254 -0
  38. package/src/components/seatMapContainer/addToCart.ts +82 -0
  39. package/src/components/seatMapContainer/index.tsx +408 -0
  40. package/src/components/seatMapContainer/utils.ts +138 -0
  41. package/src/components/stripePayment/index.tsx +23 -18
  42. package/src/components/ticketsContainer/TicketRow.tsx +28 -13
  43. package/src/components/ticketsContainer/TicketsSection.tsx +85 -2
  44. package/src/components/ticketsContainer/index.tsx +57 -12
  45. package/src/components/ticketsContainer/style.css +0 -3
  46. package/src/hooks/usePixel.ts +35 -1
  47. package/src/index.ts +2 -1
  48. package/src/types/order-data.ts +3 -0
  49. package/src/types/seatMap.d.ts +154 -0
  50. package/src/utils/createCheckoutDataBodyWithDefaultHolder.ts +6 -2
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (_) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ exports.__esModule = true;
50
+ exports.PhoneNumberField = void 0;
51
+ var TextField_1 = require("@mui/material/TextField");
52
+ var debounce_1 = require("lodash/debounce");
53
+ var get_1 = require("lodash/get");
54
+ var react_1 = require("react");
55
+ var api_1 = require("../../api");
56
+ exports.PhoneNumberField = function (_a) {
57
+ var label = _a.label, _b = _a.type, type = _b === void 0 ? 'text' : _b, field = _a.field, _c = _a.form, errors = _c.errors, setFieldError = _c.setFieldError, setStatus = _c.setStatus;
58
+ var error = get_1["default"](errors, field.name);
59
+ // eslint-disable-next-line react-hooks/exhaustive-deps
60
+ var debounceCb = react_1.useCallback(debounce_1["default"](function (cb) { return void cb(); }, 1000), []);
61
+ react_1.useEffect(function () {
62
+ var _a;
63
+ if (field.value) {
64
+ setStatus((_a = {}, _a[field.name] = true, _a));
65
+ }
66
+ debounceCb(function () { return __awaiter(void 0, void 0, void 0, function () {
67
+ var error_1, message;
68
+ var _a;
69
+ return __generator(this, function (_b) {
70
+ switch (_b.label) {
71
+ case 0:
72
+ _b.trys.push([0, 3, 4, 5]);
73
+ if (!field.value) return [3 /*break*/, 2];
74
+ return [4 /*yield*/, api_1.validatePhoneNumber(field.value)];
75
+ case 1:
76
+ _b.sent();
77
+ _b.label = 2;
78
+ case 2:
79
+ setFieldError(field.name, '');
80
+ return [3 /*break*/, 5];
81
+ case 3:
82
+ error_1 = _b.sent();
83
+ message = get_1["default"](error_1, 'response.data.message', 'Invalid phone number');
84
+ setFieldError(field.name, message);
85
+ return [3 /*break*/, 5];
86
+ case 4:
87
+ setStatus((_a = {}, _a[field.name] = false, _a));
88
+ return [7 /*endfinally*/];
89
+ case 5: return [2 /*return*/];
90
+ }
91
+ });
92
+ }); });
93
+ // eslint-disable-next-line
94
+ }, [field.value]);
95
+ return (react_1["default"].createElement(TextField_1["default"], __assign({}, field, { id: field.name, label: label, type: type, fullWidth: true, error: !!error, helperText: error, value: field.value || '', inputProps: { pattern: '[+0-9]/d+' } })));
96
+ };
@@ -4,6 +4,7 @@ import './style.css'
4
4
  import Modal from '@mui/material/Modal'
5
5
  import { AxiosError } from 'axios'
6
6
  import _get from 'lodash/get'
7
+ import _identity from 'lodash/identity'
7
8
  import _map from 'lodash/map'
8
9
  import React, { useEffect, useRef, useState } from 'react'
9
10
 
@@ -50,10 +51,10 @@ export const ConfirmationContainer = ({
50
51
  showDefaultShareButtons,
51
52
  messengerAppId = '',
52
53
  shareButtons = [],
53
- onGetConfirmationDataSuccess = () => {},
54
- onGetConfirmationDataError = () => {},
54
+ onGetConfirmationDataSuccess = _identity,
55
+ onGetConfirmationDataError = _identity,
55
56
  orderHash,
56
- onLinkCopied = () => {},
57
+ onLinkCopied = _identity,
57
58
  clientLabel,
58
59
  showReferralsInfoText = false,
59
60
  showCopyInfoModal = false,
@@ -61,12 +62,13 @@ export const ConfirmationContainer = ({
61
62
  }: IConfirmationPage) => {
62
63
  const inputRef = useRef(null)
63
64
  const [data, setData] = useState<any>(null)
64
-
65
- const dataEncoded = (isBrowser && window.localStorage.getItem('checkoutData')) || ''
66
- const dataDecoded = dataEncoded ? JSON.parse(dataEncoded): { hash: orderHash }
65
+ const dataEncoded =
66
+ (isBrowser && window.localStorage.getItem('checkoutData')) || ''
67
+ const dataDecoded = dataEncoded
68
+ ? JSON.parse(dataEncoded)
69
+ : { hash: orderHash }
67
70
  const { hash } = dataDecoded
68
-
69
- // 1. get payment complete data ---> v1/order/${orderHash}/payment/complete/
71
+ const eventId = data?.product_id || ''
70
72
 
71
73
  useEffect(() => {
72
74
  (async () => {
@@ -120,7 +122,6 @@ export const ConfirmationContainer = ({
120
122
  confirmationHelper = 'Please bring them with you to the event',
121
123
  } = confirmationLabels
122
124
 
123
- const eventId = data?.product_id || ''
124
125
  const pageUrl = isBrowser ? window.location.href.split('?')[0] : ''
125
126
  usePixel(eventId, { page: 'complete', pageUrl, orderHash: hash })
126
127
 
@@ -240,6 +241,7 @@ export const ConfirmationContainer = ({
240
241
  onChange={onChangeShareLink}
241
242
  />
242
243
  <div
244
+ aria-hidden={true}
243
245
  className="share-by-link-copy-icon"
244
246
  onClick={() => {
245
247
  navigator.clipboard.writeText(
@@ -3,6 +3,7 @@ export const VERIFICATION_STATUSES = {
3
3
  PENDING: 'PENDING',
4
4
  APPROVED: 'APPROVED_VERIFIED',
5
5
  FAILED: 'FAILED',
6
+ WRONG_CUSTOMER: 'WRONG_CUSTOMER',
6
7
  }
7
8
 
8
9
  export const TRANSACTION_STATUSES = {
@@ -14,4 +15,5 @@ export const VERIFICATION_MESSAGES = {
14
15
  PENDING: 'Your ID verification is currently being processed. We will notify you as soon as it is completed. Thank you for your patience.',
15
16
  APPROVED: 'Your ID verification is approved!',
16
17
  FAILED: 'Unfortunately your ID verification has failed. Please try again.',
18
+ WRONG_CUSTOMER: 'The order does not belong to the customer.'
17
19
  }
@@ -5,11 +5,15 @@ import _isEmpty from 'lodash/isEmpty'
5
5
  import React, { useEffect, useState } from 'react'
6
6
 
7
7
  import {
8
+ checkCustomerOrder,
8
9
  checkVerificationStatus,
9
10
  getNetverifyUrl,
10
11
  updateVerificationStatus,
11
12
  } from '../../api'
12
- import { GetNetverifyUrlResponseData, VerificationStatusResponseData } from '../../types/verification'
13
+ import {
14
+ GetNetverifyUrlResponseData,
15
+ VerificationStatusResponseData,
16
+ } from '../../types/verification'
13
17
  import { getQueryVariable, isJson } from '../../utils'
14
18
  import Modal from '../common/ModalComponent'
15
19
  import { VERIFICATION_MESSAGES, VERIFICATION_STATUSES } from './constants'
@@ -56,8 +60,9 @@ export const IDVerification = (props: IDVerificationProps) => {
56
60
  })
57
61
 
58
62
  const isAccountVerifiedOrPending =
59
- verificationStatus === VERIFICATION_STATUSES.APPROVED ||
60
- verificationStatus === VERIFICATION_STATUSES.PENDING
63
+ (verificationStatus === VERIFICATION_STATUSES.APPROVED ||
64
+ verificationStatus === VERIFICATION_STATUSES.PENDING) &&
65
+ verificationStatus !== VERIFICATION_STATUSES.WRONG_CUSTOMER
61
66
 
62
67
  const handleClose = () => {
63
68
  setModalData({
@@ -103,6 +108,9 @@ export const IDVerification = (props: IDVerificationProps) => {
103
108
  }, [])
104
109
 
105
110
  useEffect(() => {
111
+ let intervalId: any = null
112
+ const orderHash = getQueryVariable('order_hash') || ''
113
+
106
114
  const getUrl = async () => {
107
115
  try {
108
116
  const urlResponse = await getNetverifyUrl()
@@ -141,17 +149,46 @@ export const IDVerification = (props: IDVerificationProps) => {
141
149
  }
142
150
  }
143
151
 
144
- getUrl()
145
- getVerificationStatus()
152
+ const getCustomerOrderStatus = async () => {
153
+ try {
154
+ const customerOrderResponse = await checkCustomerOrder(orderHash)
155
+ return customerOrderResponse
156
+ } catch (error) {
157
+ throw error
158
+ }
159
+ }
146
160
 
147
- // Check the verification status every 30 seconds
148
- const intervalId = setInterval(() => {
149
- getVerificationStatus()
150
- }, 10000)
161
+ const makeRequests = async () => {
162
+ try {
163
+ if (orderHash) {
164
+ await getCustomerOrderStatus()
165
+ }
166
+ getUrl()
167
+ getVerificationStatus()
168
+
169
+ // Check the verification status every 30 seconds
170
+ intervalId = setInterval(() => {
171
+ getVerificationStatus()
172
+ }, 10000)
173
+ } catch (error) {
174
+ if (
175
+ error.response?.data?.message === VERIFICATION_MESSAGES.WRONG_CUSTOMER
176
+ ) {
177
+ setVerificationStatus(VERIFICATION_STATUSES.WRONG_CUSTOMER)
178
+ setModalData({
179
+ displaModal: true,
180
+ hideCancelBtn: true,
181
+ message: VERIFICATION_MESSAGES.WRONG_CUSTOMER,
182
+ })
183
+ }
184
+ }
185
+ }
186
+
187
+ makeRequests()
151
188
 
152
189
  // Clear the interval when the component unmounts
153
190
  return () => clearInterval(intervalId)
154
- }, [verificationStatus])
191
+ }, [])
155
192
 
156
193
  const iframe = (netverifyUrl: string) => {
157
194
  // eslint-disable-next-line max-len
@@ -166,14 +203,18 @@ export const IDVerification = (props: IDVerificationProps) => {
166
203
  const orderHash = getQueryVariable('order_hash')
167
204
 
168
205
  if (isWindowDefined) {
169
- const checkoutData = JSON.parse(window.localStorage.getItem('checkoutData') || '{}')
206
+ const checkoutData = JSON.parse(
207
+ window.localStorage.getItem('checkoutData') || '{}'
208
+ )
170
209
  if (_isEmpty(checkoutData) && orderHash) {
171
- window.localStorage.setItem('checkoutData', JSON.stringify({ hash: orderHash }))
210
+ window.localStorage.setItem(
211
+ 'checkoutData',
212
+ JSON.stringify({ hash: orderHash })
213
+ )
172
214
  }
173
215
  }
174
216
  }, [])
175
217
 
176
-
177
218
  return (
178
219
  <div>
179
220
  <h2 className="page-header">Account Verification</h2>
@@ -7,4 +7,5 @@ export { OrderDetailsContainer } from './orderDetailsContainer'
7
7
  export { ResetPasswordContainer } from './resetPasswordContainer'
8
8
  export { TicketResaleContainer } from './ticketResale'
9
9
  export { AddonsContainter } from './addonsContainer'
10
- export { IDVerification } from './idVerificationContainer'
10
+ export { SeatMapContainer } from './seatMapContainer'
11
+ export { IDVerification } from './idVerificationContainer'
@@ -28,6 +28,9 @@ interface TicketTypes {
28
28
  price: string;
29
29
  quantity: string;
30
30
  total: string;
31
+ guests_count: string;
32
+ deposit_paid: string;
33
+ remaining: string;
31
34
  }
32
35
 
33
36
  interface OrderDetailsTypes {
@@ -50,7 +53,8 @@ interface OrderDetailsTypes {
50
53
  }
51
54
 
52
55
  const getTotal = (data: any) => {
53
- if (data?.total && data?.tickets && data.tickets[0]?.currency) return data.tickets[0].currency + data.total
56
+ if (data?.total && data?.tickets && data.tickets[0]?.currency)
57
+ return data.tickets[0].currency + data.total
54
58
  if (!data?.total || !_has(data, 'items.ticket_types.length')) return ''
55
59
 
56
60
  return data.items.ticket_types[0].currency + data.total
@@ -206,6 +210,16 @@ export const OrderDetailsContainer = ({
206
210
  orderSummery += ` ${date}`
207
211
  }
208
212
 
213
+ const columnsProps =
214
+ data.tickets && data.tickets[0].is_table
215
+ ? [
216
+ { label: 'Items' },
217
+ { label: 'Price' },
218
+ { label: 'Guests count' },
219
+ { label: 'Deposit paid' },
220
+ { label: 'Remaining' },
221
+ ]
222
+ : columns
209
223
  return (
210
224
  <div className="order-details">
211
225
  {loading ? (
@@ -237,49 +251,66 @@ export const OrderDetailsContainer = ({
237
251
  </div>
238
252
  </div>
239
253
  </div>
240
- {!data?.disable_referral &&
241
- (<div className="personal-link">
254
+ {!data?.disable_referral && (
255
+ <div className="personal-link">
242
256
  <div className="link-item">
243
257
  <span>Personal Share Link: </span>
244
258
  <a
245
- href={data?.personal_share_link}
246
- target="_blank"
247
- rel="noreferrer"
259
+ href={data?.personal_share_link}
260
+ target="_blank"
261
+ rel="noreferrer"
248
262
  >
249
263
  {Boolean(personalLinkIcon) && (
250
- <img src={personalLinkIcon} alt="Icon"/>
264
+ <img src={personalLinkIcon} alt="Icon" />
251
265
  )}
252
266
  {data?.personal_share_link}
253
267
  </a>
254
268
  </div>
255
269
  {data?.sales_referred ? (
256
- <div className="link-item">
257
- <p className="total-referrer">{`So far, you’ve referred ${data.sales_referred} tickets`}</p>
258
- </div>
270
+ <div className="link-item">
271
+ <p className="total-referrer">{`So far, you’ve referred ${data.sales_referred} tickets`}</p>
272
+ </div>
259
273
  ) : null}
260
- </div>)
261
- }
274
+ </div>
275
+ )}
262
276
  <TableContainer component={Paper}>
263
277
  <Table className="tt-type" aria-label="collapsible table">
264
278
  <TableHead>
265
279
  <TableRow>
266
- {_map(columns, item => (
280
+ {_map(columnsProps, item => (
267
281
  <TableCell>{item.label || ''}</TableCell>
268
282
  ))}
269
283
  </TableRow>
270
284
  </TableHead>
271
285
  <TableBody>
272
286
  {data?.items?.ticket_types?.map(
273
- (ticket: TicketTypes, index: number) => (
274
- <TableRow key={index}>
275
- <TableCell>
276
- <b>Ticket Type:</b> {ticket.name}
277
- </TableCell>
278
- <TableCell>{ticket.currency + ticket.price}</TableCell>
279
- <TableCell>{ticket.quantity}</TableCell>
280
- <TableCell>{ticket.currency + ticket.total}</TableCell>
281
- </TableRow>
282
- )
287
+ (ticket: TicketTypes, index: number) =>
288
+ data?.tickets && !data?.tickets[0].is_table ? (
289
+ <TableRow key={index}>
290
+ <TableCell>
291
+ <b>Ticket Type:</b> {ticket.name}
292
+ </TableCell>
293
+ <TableCell>
294
+ {ticket.currency + ticket.price}
295
+ </TableCell>
296
+ <TableCell>{ticket.quantity}</TableCell>
297
+ <TableCell>
298
+ {ticket.currency + ticket.total}
299
+ </TableCell>
300
+ </TableRow>
301
+ ) : (
302
+ <TableRow key={index}>
303
+ <TableCell>
304
+ <b>Ticket Type:</b> {ticket.name}
305
+ </TableCell>
306
+ <TableCell>
307
+ {ticket.currency + ticket.price}
308
+ </TableCell>
309
+ <TableCell>{ticket.guests_count}</TableCell>
310
+ <TableCell>{ticket.deposit_paid}</TableCell>
311
+ <TableCell>{ticket.remaining}</TableCell>
312
+ </TableRow>
313
+ )
283
314
  )}
284
315
  {data?.items?.add_ons?.map(
285
316
  (ticket: TicketTypes, index: number) => (