tf-checkout-react 1.6.6-beta.3 → 1.6.6-beta.31

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 (110) hide show
  1. package/README.md +61 -40
  2. package/dist/adapters/customFields.d.ts +1 -0
  3. package/dist/api/checkout.d.ts +1 -0
  4. package/dist/api/common.d.ts +1 -0
  5. package/dist/api/index.d.ts +1 -0
  6. package/dist/api/preRegistrationComplete.d.ts +1 -1
  7. package/dist/components/addonsContainer/AddonComponent.d.ts +5 -1
  8. package/dist/components/addonsContainer/SimpleAddonsContainer.d.ts +17 -0
  9. package/dist/components/addonsContainer/index.d.ts +5 -1
  10. package/dist/components/billing-info-container/index.d.ts +8 -1
  11. package/dist/components/billing-info-container/utils.d.ts +25 -1
  12. package/dist/components/common/DatePickerField.d.ts +7 -1
  13. package/dist/components/countdown/index.d.ts +1 -1
  14. package/dist/components/forgotPasswordModal/index.d.ts +2 -1
  15. package/dist/components/myTicketsContainer/index.d.ts +3 -2
  16. package/dist/components/orderDetailsContainer/index.d.ts +7 -1
  17. package/dist/components/paymentContainer/OrderDetails.d.ts +8 -0
  18. package/dist/components/paymentContainer/handlePayment.d.ts +15 -0
  19. package/dist/components/paymentContainer/index.d.ts +10 -5
  20. package/dist/components/preRegistration/FieldsSection.d.ts +7 -1
  21. package/dist/components/preRegistration/PreRegistrationComplete.d.ts +6 -0
  22. package/dist/components/preRegistration/constants.d.ts +2 -2
  23. package/dist/components/preRegistration/index.d.ts +6 -0
  24. package/dist/components/resetPasswordContainer/index.d.ts +2 -2
  25. package/dist/components/stripePayment/index.d.ts +18 -3
  26. package/dist/components/ticketsContainer/InfoIcon.d.ts +5 -0
  27. package/dist/components/ticketsContainer/TicketsSection.d.ts +3 -2
  28. package/dist/components/ticketsContainer/TimeSlotsSection.d.ts +25 -0
  29. package/dist/components/ticketsContainer/index.d.ts +18 -5
  30. package/dist/components/timerWidget/index.d.ts +2 -1
  31. package/dist/constants/index.d.ts +5 -0
  32. package/dist/index.d.ts +4 -1
  33. package/dist/tf-checkout-react.cjs.development.js +5196 -3599
  34. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  35. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  36. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  37. package/dist/tf-checkout-react.esm.js +5199 -3605
  38. package/dist/tf-checkout-react.esm.js.map +1 -1
  39. package/dist/tf-checkout-styles.css +1 -1
  40. package/dist/types/add_on.d.ts +1 -0
  41. package/dist/types/checkoutPageConfigs.d.ts +1 -1
  42. package/dist/types/order-data.d.ts +2 -1
  43. package/dist/utils/auth.d.ts +8 -0
  44. package/dist/utils/customFields.d.ts +11 -0
  45. package/dist/utils/getDomain.d.ts +1 -1
  46. package/dist/utils/index.d.ts +1 -1
  47. package/dist/utils/setConfigs.d.ts +1 -0
  48. package/package.json +3 -2
  49. package/src/adapters/customFields.ts +7 -1
  50. package/src/api/auth.ts +2 -1
  51. package/src/api/checkout.ts +8 -4
  52. package/src/api/common.ts +49 -2
  53. package/src/api/interceptors.ts +7 -23
  54. package/src/api/preRegistrationComplete.ts +1 -1
  55. package/src/api/publicRequest.ts +10 -0
  56. package/src/components/addonsContainer/AddonComponent.tsx +71 -11
  57. package/src/components/addonsContainer/SimpleAddonsContainer.tsx +388 -0
  58. package/src/components/addonsContainer/index.tsx +189 -58
  59. package/src/components/billing-info-container/index.tsx +704 -390
  60. package/src/components/billing-info-container/{utils.ts → utils.tsx} +119 -0
  61. package/src/components/common/CheckboxField/index.tsx +1 -1
  62. package/src/components/common/DatePickerField.tsx +25 -10
  63. package/src/components/common/SnackbarAlert.tsx +32 -34
  64. package/src/components/confirmationContainer/index.tsx +1 -1
  65. package/src/components/countdown/index.tsx +22 -22
  66. package/src/components/delegationsContainer/IssueComponent.tsx +2 -1
  67. package/src/components/forgotPasswordModal/index.tsx +44 -13
  68. package/src/components/loginForm/index.tsx +1 -1
  69. package/src/components/loginModal/index.tsx +2 -2
  70. package/src/components/loginModal/style.css +3 -1
  71. package/src/components/myTicketsContainer/index.tsx +13 -9
  72. package/src/components/orderDetailsContainer/index.tsx +188 -173
  73. package/src/components/paymentContainer/OrderDetails.tsx +170 -0
  74. package/src/components/paymentContainer/handlePayment.ts +86 -0
  75. package/src/components/paymentContainer/index.tsx +253 -226
  76. package/src/components/paymentContainer/style.css +113 -0
  77. package/src/components/preRegistration/FieldsSection.tsx +8 -0
  78. package/src/components/preRegistration/PreRegistrationComplete.tsx +128 -118
  79. package/src/components/preRegistration/PreRegistrationInformations.tsx +21 -15
  80. package/src/components/preRegistration/constants.tsx +10 -4
  81. package/src/components/preRegistration/index.tsx +194 -174
  82. package/src/components/registerForm/constants.tsx +3 -1
  83. package/src/components/registerForm/index.tsx +3 -3
  84. package/src/components/resetPasswordContainer/index.tsx +12 -13
  85. package/src/components/seatMapContainer/TicketsSection.tsx +2 -2
  86. package/src/components/stripePayment/index.tsx +129 -24
  87. package/src/components/ticketsContainer/InfoIcon.tsx +35 -0
  88. package/src/components/ticketsContainer/PromoCodeSection.tsx +34 -28
  89. package/src/components/ticketsContainer/TicketRow.tsx +1 -1
  90. package/src/components/ticketsContainer/TicketsSection.tsx +178 -52
  91. package/src/components/ticketsContainer/TimeSlotsSection.tsx +120 -0
  92. package/src/components/ticketsContainer/index.tsx +209 -99
  93. package/src/components/timerWidget/index.tsx +15 -3
  94. package/src/constants/index.ts +2 -0
  95. package/src/hoc/CustomFields/index.tsx +9 -1
  96. package/src/index.ts +7 -2
  97. package/src/types/add_on.ts +1 -0
  98. package/src/types/api/common.d.ts +27 -0
  99. package/src/types/api/orders.d.ts +19 -3
  100. package/src/types/api/payment.d.ts +5 -2
  101. package/src/types/api/preRegistrationComplete.d.ts +2 -2
  102. package/src/types/checkoutPageConfigs.ts +1 -1
  103. package/src/types/order-data.ts +2 -1
  104. package/src/types/pre-registration-complete.d.ts +6 -1
  105. package/src/utils/auth.ts +32 -0
  106. package/src/utils/cookies.ts +42 -11
  107. package/src/utils/customFields.ts +22 -0
  108. package/src/utils/getDomain.ts +10 -4
  109. package/src/utils/index.ts +1 -1
  110. package/src/utils/setConfigs.ts +3 -1
@@ -1,12 +1,16 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
2
  import './style.css'
2
3
 
4
+ import { ThemeOptions } from '@mui/material'
3
5
  import Paper from '@mui/material/Paper'
6
+ import { createTheme, ThemeProvider } from '@mui/material/styles'
4
7
  import Table from '@mui/material/Table'
5
8
  import TableBody from '@mui/material/TableBody'
6
9
  import TableCell from '@mui/material/TableCell'
7
10
  import TableContainer from '@mui/material/TableContainer'
8
11
  import TableHead from '@mui/material/TableHead'
9
12
  import TableRow from '@mui/material/TableRow'
13
+ import { CSSProperties } from '@mui/styles'
10
14
  import _find from 'lodash/find'
11
15
  import _get from 'lodash/get'
12
16
  import _has from 'lodash/has'
@@ -61,6 +65,10 @@ interface OrderDetailsTypes {
61
65
  personalLinkIcon?: string;
62
66
  displayColumnNameInRow?: boolean;
63
67
  canSellTicket?: boolean;
68
+ themeOptions?: ThemeOptions & {
69
+ input?: CSSProperties;
70
+ checkbox?: CSSProperties;
71
+ };
64
72
  ticketsTableColumns?: Array<{
65
73
  id?: string | number;
66
74
  key: keyof ITicketTypes & keyof IActionColumns;
@@ -130,6 +138,7 @@ export const OrderDetailsContainer = ({
130
138
  referralTitle = '',
131
139
  itemsTitle = '',
132
140
  ticketsTitle = 'Your Tickets',
141
+ themeOptions,
133
142
  }: OrderDetailsTypes) => {
134
143
  const [data, setData] = useState<any>({})
135
144
  const [removeFromResaleLoading, setRemoveFromResaleLoading] = useState(false)
@@ -352,194 +361,200 @@ export const OrderDetailsContainer = ({
352
361
  }
353
362
  }
354
363
 
364
+ const theme = createTheme(themeOptions ?? {})
365
+
355
366
  return (
356
- <div className="order-details">
357
- <div className="layout-block">
358
- <h1 className="layout-title">Order Details</h1>
359
- {!_isEmpty(orderUpdatableCustomFields) && (
360
- <SVG src={EditSvg} onClick={() => setShowOrderCustomFieldsSection(true)} />
361
- )}
362
- </div>
363
- <div className="order-summary-box">
364
- <div className="summary-block">
365
- <div className="summary-item">
366
- <h6 className="sub-title">Order Summary</h6>
367
- <p className="order-summary-date">{orderSummery}</p>
368
- </div>
369
- <div className="summary-item">
370
- <div className="return-button-container">
371
- <button
372
- type="button"
373
- className="return-button"
374
- onClick={() => {
375
- if (isBrowser) {
376
- window.location.assign(ordersPath ?? '/orders')
377
- }
378
- }}
379
- >
380
- Back to Orders
381
- </button>
382
- </div>
383
- </div>
367
+ <ThemeProvider theme={theme}>
368
+ <div className="order-details">
369
+ <div className="layout-block">
370
+ <h1 className="layout-title">Order Details</h1>
371
+ {!_isEmpty(orderUpdatableCustomFields) && (
372
+ <SVG src={EditSvg} onClick={() => setShowOrderCustomFieldsSection(true)} />
373
+ )}
384
374
  </div>
385
- {!_isEmpty(orderCustomFields) && (
386
- <>
387
- <div className="custom-field-value-container">
388
- {orderCustomFields.map((customField: CustomFieldTypes) => (
389
- <div className="info-item" key={customField.id}>
390
- <b>{customField.label} :</b> {renderCustomFieldValue(customField)}
391
- </div>
392
- ))}
375
+ <div className="order-summary-box">
376
+ <div className="summary-block">
377
+ <div className="summary-item">
378
+ <h6 className="sub-title">Order Summary</h6>
379
+ <p className="order-summary-date">{orderSummery}</p>
393
380
  </div>
394
- {!_isEmpty(orderUpdatableCustomFields) && (
395
- <div
396
- className={`custom-fields-block ${
397
- showOrderCustomFieldsSection ? 'show' : ''
398
- }`}
399
- >
400
- <p className="title">Aditional Information Request</p>
401
- <CustomFieldsForm
402
- initialValues={orderEditableFieldsFormInitialValues}
403
- fields={orderUpdatableCustomFields}
404
- handleFormSubmit={handleOrderCustomFieldsUpdate}
405
- handleFormClose={() => setShowOrderCustomFieldsSection(false)}
406
- />
381
+ <div className="summary-item">
382
+ <div className="return-button-container">
383
+ <button
384
+ type="button"
385
+ className="return-button"
386
+ onClick={() => {
387
+ if (isBrowser) {
388
+ window.location.assign(ordersPath ?? '/orders')
389
+ }
390
+ }}
391
+ >
392
+ Back to Orders
393
+ </button>
407
394
  </div>
408
- )}
409
- </>
410
- )}
411
- {!data?.disable_referral && (
412
- <>
413
- {referralTitle && (
414
- <h4 className="referral-title sub-title">{referralTitle}</h4>
415
- )}
416
- <div className="personal-link">
417
- <div className="link-item">
418
- <span>Personal Share Link: </span>
419
- <a href={data?.personal_share_link} target="_blank" rel="noreferrer">
420
- {Boolean(personalLinkIcon) && <img src={personalLinkIcon} alt="Icon" />}
421
- {data?.personal_share_link}
422
- </a>
395
+ </div>
396
+ </div>
397
+ {!_isEmpty(orderCustomFields) && (
398
+ <>
399
+ <div className="custom-field-value-container">
400
+ {orderCustomFields.map((customField: CustomFieldTypes) => (
401
+ <div className="info-item" key={customField.id}>
402
+ <b>{customField.label} :</b> {renderCustomFieldValue(customField)}
403
+ </div>
404
+ ))}
423
405
  </div>
424
- {data?.sales_referred ? (
406
+ {!_isEmpty(orderUpdatableCustomFields) && (
407
+ <div
408
+ className={`custom-fields-block ${
409
+ showOrderCustomFieldsSection ? 'show' : ''
410
+ }`}
411
+ >
412
+ <p className="title">Aditional Information Request</p>
413
+ <CustomFieldsForm
414
+ initialValues={orderEditableFieldsFormInitialValues}
415
+ fields={orderUpdatableCustomFields}
416
+ handleFormSubmit={handleOrderCustomFieldsUpdate}
417
+ handleFormClose={() => setShowOrderCustomFieldsSection(false)}
418
+ />
419
+ </div>
420
+ )}
421
+ </>
422
+ )}
423
+ {!data?.disable_referral && (
424
+ <>
425
+ {referralTitle && (
426
+ <h4 className="referral-title sub-title">{referralTitle}</h4>
427
+ )}
428
+ <div className="personal-link">
425
429
  <div className="link-item">
426
- <p className="total-referrer">{`So far, you’ve referred ${data.sales_referred} tickets`}</p>
430
+ <span>Personal Share Link: </span>
431
+ <a href={data?.personal_share_link} target="_blank" rel="noreferrer">
432
+ {Boolean(personalLinkIcon) && (
433
+ <img src={personalLinkIcon} alt="Icon" />
434
+ )}
435
+ {data?.personal_share_link}
436
+ </a>
427
437
  </div>
428
- ) : null}
429
- </div>
430
- </>
431
- )}
432
- {itemsTitle && <h4 className="items-title sub-title">{itemsTitle}</h4>}
433
- <TableContainer component={Paper}>
434
- <Table className="tt-type" aria-label="collapsible table">
435
- <TableHead>
436
- <TableRow>
437
- {_map(columnsProps, item => (
438
- <TableCell>{item.label || ''}</TableCell>
439
- ))}
440
- </TableRow>
441
- </TableHead>
442
- <TableBody>
443
- {data?.items?.ticket_types?.map((ticket: TicketTypes, index: number) =>
444
- data?.tickets && !data?.tickets[0].is_table ? (
438
+ {data?.sales_referred ? (
439
+ <div className="link-item">
440
+ <p className="total-referrer">{`So far, you’ve referred ${data.sales_referred} tickets`}</p>
441
+ </div>
442
+ ) : null}
443
+ </div>
444
+ </>
445
+ )}
446
+ {itemsTitle && <h4 className="items-title sub-title">{itemsTitle}</h4>}
447
+ <TableContainer component={Paper}>
448
+ <Table className="tt-type" aria-label="collapsible table">
449
+ <TableHead>
450
+ <TableRow>
451
+ {_map(columnsProps, item => (
452
+ <TableCell>{item.label || ''}</TableCell>
453
+ ))}
454
+ </TableRow>
455
+ </TableHead>
456
+ <TableBody>
457
+ {data?.items?.ticket_types?.map((ticket: TicketTypes, index: number) =>
458
+ data?.tickets && !data?.tickets[0].is_table ? (
459
+ <TableRow key={index}>
460
+ <TableCell>
461
+ <b>Ticket Type:</b> {ticket.name}
462
+ </TableCell>
463
+ <TableCell>{ticket.currency + ticket.price}</TableCell>
464
+ <TableCell>{ticket.quantity}</TableCell>
465
+ <TableCell>{ticket.currency + ticket.total}</TableCell>
466
+ </TableRow>
467
+ ) : (
468
+ <TableRow key={index}>
469
+ <TableCell>
470
+ <b>Ticket Type:</b> {ticket.name}
471
+ </TableCell>
472
+ <TableCell>{ticket.currency + ticket.price}</TableCell>
473
+ <TableCell>{ticket.guests_count}</TableCell>
474
+ <TableCell>{ticket.deposit_paid}</TableCell>
475
+ <TableCell>{ticket.remaining}</TableCell>
476
+ </TableRow>
477
+ )
478
+ )}
479
+ {data?.items?.add_ons?.map((ticket: TicketTypes, index: number) => (
445
480
  <TableRow key={index}>
446
481
  <TableCell>
447
- <b>Ticket Type:</b> {ticket.name}
482
+ <div>
483
+ <b>Add-On</b>
484
+ <div>
485
+ {ticket.groupName && `${ticket.groupName}: `} {ticket.name}
486
+ </div>
487
+ </div>
448
488
  </TableCell>
449
489
  <TableCell>{ticket.currency + ticket.price}</TableCell>
450
490
  <TableCell>{ticket.quantity}</TableCell>
451
491
  <TableCell>{ticket.currency + ticket.total}</TableCell>
452
492
  </TableRow>
453
- ) : (
454
- <TableRow key={index}>
455
- <TableCell>
456
- <b>Ticket Type:</b> {ticket.name}
457
- </TableCell>
458
- <TableCell>{ticket.currency + ticket.price}</TableCell>
459
- <TableCell>{ticket.guests_count}</TableCell>
460
- <TableCell>{ticket.deposit_paid}</TableCell>
461
- <TableCell>{ticket.remaining}</TableCell>
462
- </TableRow>
463
- )
464
- )}
465
- {data?.items?.add_ons?.map((ticket: TicketTypes, index: number) => (
466
- <TableRow key={index}>
467
- <TableCell>
468
- <div>
469
- <b>Add-On</b>
470
- <div>
471
- {ticket.groupName && `${ticket.groupName}: `} {ticket.name}
472
- </div>
473
- </div>
474
- </TableCell>
475
- <TableCell>{ticket.currency + ticket.price}</TableCell>
476
- <TableCell>{ticket.quantity}</TableCell>
477
- <TableCell>{ticket.currency + ticket.total}</TableCell>
493
+ ))}
494
+ <TableRow className="total-row">
495
+ <TableCell />
496
+ <TableCell />
497
+ <TableCell>Total</TableCell>
498
+ <TableCell>{getTotal(data)}</TableCell>
478
499
  </TableRow>
479
- ))}
480
- <TableRow className="total-row">
481
- <TableCell />
482
- <TableCell />
483
- <TableCell>Total</TableCell>
484
- <TableCell>{getTotal(data)}</TableCell>
485
- </TableRow>
486
- </TableBody>
487
- </Table>
488
- </TableContainer>
489
- </div>
490
- <TicketsTable
491
- ticketsTitle={ticketsTitle}
492
- tickets={data.tickets}
493
- columns={
494
- ticketsTableColumns?.length
495
- ? ticketsTableColumns
496
- : [
497
- { key: 'hash' as never, label: 'Ticket ID' },
498
- { key: 'ticket_type' as never, label: 'Ticket Type' },
499
- { key: 'holder_name' as never, label: 'Ticket Holder' },
500
- { key: 'status' as never, label: 'Status' },
501
- { key: 'download' as never, label: '' },
502
- { key: 'sell_ticket' as never, label: '' },
503
- ]
504
- }
505
- handleSellTicket={handleSellTicket}
506
- handleRemoveFromResale={handleRemoveFromResale}
507
- displayColumnNameInRow={displayColumnNameInRow}
508
- canSellTicket={canSellTicket}
509
- ticketHoldersCustomFields={ticketHoldersCustomFields}
510
- handleTicketHoldersUpdate={handleTicketHoldersUpdate}
511
- />
512
- <div className="return-button-container">
513
- <button
514
- type="button"
515
- className="return-button"
516
- onClick={() => {
517
- if (onReturnButtonClick) {
518
- onReturnButtonClick(data)
519
- } else if (isBrowser) {
520
- window.location.assign(ordersPath ?? '/orders')
521
- }
522
- }}
523
- >
524
- Return to Order History
525
- </button>
526
- </div>
527
- {showResaleModal && (
528
- <TicketResaleModal
529
- ticket={activeTicket}
530
- onClose={handleOnClose}
531
- onSubmit={handleOnSubmit}
532
- loading={resaleTicketLoading}
533
- />
534
- )}
535
- {showRemoveResaleModal && (
536
- <ConfirmModal
537
- message="Are you sure you want to withdraw your ticket from resale?"
538
- onClose={onCloseRemoveResale}
539
- onConfirm={onConfirmRemoveResale}
540
- loading={removeFromResaleLoading}
500
+ </TableBody>
501
+ </Table>
502
+ </TableContainer>
503
+ </div>
504
+ <TicketsTable
505
+ ticketsTitle={ticketsTitle}
506
+ tickets={data.tickets}
507
+ columns={
508
+ ticketsTableColumns?.length
509
+ ? ticketsTableColumns
510
+ : [
511
+ { key: 'hash' as never, label: 'Ticket ID' },
512
+ { key: 'ticket_type' as never, label: 'Ticket Type' },
513
+ { key: 'holder_name' as never, label: 'Ticket Holder' },
514
+ { key: 'status' as never, label: 'Status' },
515
+ { key: 'download' as never, label: '' },
516
+ { key: 'sell_ticket' as never, label: '' },
517
+ ]
518
+ }
519
+ handleSellTicket={handleSellTicket}
520
+ handleRemoveFromResale={handleRemoveFromResale}
521
+ displayColumnNameInRow={displayColumnNameInRow}
522
+ canSellTicket={canSellTicket}
523
+ ticketHoldersCustomFields={ticketHoldersCustomFields}
524
+ handleTicketHoldersUpdate={handleTicketHoldersUpdate}
541
525
  />
542
- )}
543
- </div>
526
+ <div className="return-button-container">
527
+ <button
528
+ type="button"
529
+ className="return-button"
530
+ onClick={() => {
531
+ if (onReturnButtonClick) {
532
+ onReturnButtonClick(data)
533
+ } else if (isBrowser) {
534
+ window.location.assign(ordersPath ?? '/orders')
535
+ }
536
+ }}
537
+ >
538
+ Return to Order History
539
+ </button>
540
+ </div>
541
+ {showResaleModal && (
542
+ <TicketResaleModal
543
+ ticket={activeTicket}
544
+ onClose={handleOnClose}
545
+ onSubmit={handleOnSubmit}
546
+ loading={resaleTicketLoading}
547
+ />
548
+ )}
549
+ {showRemoveResaleModal && (
550
+ <ConfirmModal
551
+ message="Are you sure you want to withdraw your ticket from resale?"
552
+ onClose={onCloseRemoveResale}
553
+ onConfirm={onConfirmRemoveResale}
554
+ loading={removeFromResaleLoading}
555
+ />
556
+ )}
557
+ </div>
558
+ </ThemeProvider>
544
559
  )
545
560
  }
@@ -0,0 +1,170 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import _identity from 'lodash/identity'
3
+ import _isEmpty from 'lodash/isEmpty'
4
+ import _map from 'lodash/map'
5
+ import React, { useState } from 'react'
6
+
7
+ import { FEES_STYLES } from '../../constants'
8
+ import { createFixedFloatNormalizer, currencyNormalizerCreator } from '../../normalizers'
9
+ import { IOrderData } from '../../types'
10
+ import { CONFIGS } from '../../utils'
11
+
12
+ interface OrderDetailsProps {
13
+ orderData: any;
14
+ paymentFieldsData: any[];
15
+ customMobileText?: string;
16
+ }
17
+
18
+ export const OrderDetails = ({
19
+ orderData = {},
20
+ paymentFieldsData = [],
21
+ customMobileText = 'Your order total',
22
+ }: OrderDetailsProps) => {
23
+ const { currency, guest_count } = orderData
24
+ const hasTableTypes = Boolean(Number(guest_count))
25
+ const [isExpanded, setIsExpanded] = useState(false)
26
+
27
+ // Find the total field to display in the mobile view
28
+ const totalField = paymentFieldsData.find(field => field.id === 'total')
29
+ const totalValue =
30
+ totalField && orderData.total
31
+ ? totalField.normalizer
32
+ ? totalField.normalizer(orderData.total, currency, orderData)
33
+ : orderData.total
34
+ : ''
35
+
36
+ const toggleExpand = () => {
37
+ setIsExpanded(!isExpanded)
38
+ }
39
+
40
+ return (
41
+ <div className="payment_page payment_page_single">
42
+ {/* Mobile view summary */}
43
+ <div className="mobile-order-summary">
44
+ <div className="mobile-order-summary-content" onClick={toggleExpand}>
45
+ <div className="mobile-order-info">
46
+ <div
47
+ className={`mobile-order-info-container order-info-container-left ${
48
+ isExpanded ? 'open' : ''
49
+ }`}
50
+ >
51
+ <div className="mobile-order-text">{customMobileText}</div>
52
+ </div>
53
+ {!isExpanded && (
54
+ <div className="mobile-order-info-container order-info-container-right">
55
+ <div className="mobile-order-total">{totalValue}</div>
56
+ </div>
57
+ )}
58
+ </div>
59
+ </div>
60
+ </div>
61
+
62
+ {/* Original content - will be hidden on mobile when collapsed */}
63
+ <div
64
+ className={`order_info_section ${isExpanded ? 'expanded' : 'collapsed'}`}
65
+ style={{ display: hasTableTypes ? 'block' : 'grid' }}
66
+ >
67
+ {_map(paymentFieldsData, field => {
68
+ const { id, label, className = '', normalizer = _identity } = field
69
+ const value = orderData[id as keyof IOrderData] || ''
70
+ let component = null
71
+
72
+ if (field.id === 'add_ons' && _isEmpty(value)) {
73
+ return false
74
+ }
75
+
76
+ if (field.id === 'tableTypes') {
77
+ const valueArray = value as Array<any>
78
+
79
+ component = (
80
+ <div
81
+ key={id}
82
+ className="order_info_block"
83
+ style={{
84
+ display: 'flex',
85
+ flexDirection: 'column',
86
+ }}
87
+ >
88
+ {_map(valueArray, tableTypeItem => (
89
+ <div
90
+ key={tableTypeItem.id}
91
+ style={{
92
+ display: 'grid',
93
+ gridTemplateColumns: '33% 33% 33%',
94
+ gridColumnGap: '10%',
95
+ }}
96
+ >
97
+ <div className="order_info_block">
98
+ <div className="order_info_title">Table Type</div>
99
+ <div className={`${className} order_info_text`}>
100
+ {tableTypeItem.ticketType}
101
+ </div>
102
+ </div>
103
+ <div className="order_info_block">
104
+ <div className="order_info_title">Number of Tables</div>
105
+ <div className={`${className} order_info_text`}>
106
+ {tableTypeItem.count}
107
+ </div>
108
+ </div>
109
+ <div className="order_info_block">
110
+ <div className="order_info_title">Guest Count</div>
111
+ <div className={`${className} order_info_text`}>
112
+ {tableTypeItem.quantity}
113
+ </div>
114
+ </div>
115
+ </div>
116
+ ))}
117
+ </div>
118
+ )
119
+ }
120
+
121
+ return (
122
+ component || (
123
+ <div key={id} className={`order_info_block ${className}`}>
124
+ <div className="order_info_title">{label}</div>
125
+ <div className={`${className} order_info_text`}>
126
+ {typeof value === 'string' || typeof value === 'number'
127
+ ? normalizer(value, currency, orderData)
128
+ : _map(value, item => (
129
+ <div>
130
+ <div key={item.id} className="add-on-container">
131
+ <span>{item.quantity}</span>
132
+ <span className="add-on-x">{' x '}</span>
133
+ <span>{item.groupName ? item.groupName + ' - ' : ''}</span>
134
+ <span>{item.name}</span>
135
+ <span>{' - '}</span>
136
+ <span>
137
+ {CONFIGS.FEES_STYLE === FEES_STYLES.TRADITIONAL &&
138
+ currencyNormalizerCreator(
139
+ createFixedFloatNormalizer(2)(parseFloat(item.price)),
140
+ currency
141
+ ) + ' (incl. fees)'}
142
+ {CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH &&
143
+ currencyNormalizerCreator(
144
+ createFixedFloatNormalizer(2)(parseFloat(item.cost)),
145
+ currency
146
+ )}
147
+ </span>
148
+ <span className="add-on-each">{' each'}</span>
149
+ </div>
150
+ {CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH && (
151
+ <p className="fees">
152
+ {`(${currencyNormalizerCreator(
153
+ createFixedFloatNormalizer(2)(
154
+ parseFloat(String(item.price))
155
+ ),
156
+ currency
157
+ )} with fees)`}
158
+ </p>
159
+ )}
160
+ </div>
161
+ ))}
162
+ </div>
163
+ </div>
164
+ )
165
+ )
166
+ })}
167
+ </div>
168
+ </div>
169
+ )
170
+ }
@@ -0,0 +1,86 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { AxiosError } from 'axios'
3
+ import _get from 'lodash/get'
4
+
5
+ import { createPaymentPlan, handleFreeSuccess, handlePaymentSuccess } from '../../api'
6
+
7
+ interface Options {
8
+ reviewData: any;
9
+ isFreeTickets: boolean;
10
+ paymentPlanIsAvailable: boolean;
11
+ showPaymentPlanSection: boolean;
12
+ handlePayment: any;
13
+ setPaymentIsLoading: any;
14
+ setError: any;
15
+ orderData: any;
16
+ eventId: any;
17
+ isBrowser: boolean;
18
+ onPaymentError: any;
19
+ }
20
+
21
+ export const handlePaymentMiddleWare = async (
22
+ error: any,
23
+ data: object,
24
+ {
25
+ reviewData,
26
+ isFreeTickets,
27
+ paymentPlanIsAvailable,
28
+ showPaymentPlanSection,
29
+ handlePayment,
30
+ setPaymentIsLoading,
31
+ setError,
32
+ orderData,
33
+ eventId,
34
+ isBrowser,
35
+ onPaymentError,
36
+ }: Options
37
+ ) => {
38
+ try {
39
+ if (error) {
40
+ throw error
41
+ }
42
+ const {
43
+ order_details: { order_hash },
44
+ } = reviewData
45
+
46
+ let paymentSuccessResponse
47
+
48
+ if (isFreeTickets) {
49
+ paymentSuccessResponse = await handleFreeSuccess(order_hash)
50
+ } else if (paymentPlanIsAvailable && showPaymentPlanSection) {
51
+ paymentSuccessResponse = await createPaymentPlan(
52
+ order_hash,
53
+ _get(data, 'paymentMethodId', '')
54
+ )
55
+ } else {
56
+ paymentSuccessResponse = await handlePaymentSuccess(order_hash)
57
+ }
58
+
59
+ if (paymentSuccessResponse.status === 200) {
60
+ handlePayment(paymentSuccessResponse)
61
+ setPaymentIsLoading(false)
62
+
63
+ // clear seat-map related data from localStorage
64
+ localStorage.removeItem('reservationData')
65
+ localStorage.removeItem(`reservationStart-${eventId}`)
66
+ localStorage.removeItem('ownReservations')
67
+ localStorage.removeItem('tierId')
68
+
69
+ if (isBrowser) {
70
+ (window as any)?.dataLayer?.push({
71
+ event: 'Purchase',
72
+ orderValue: orderData.total,
73
+ orderCurrency: orderData.currency,
74
+ orderId: orderData.id,
75
+ })
76
+ }
77
+ }
78
+ } catch (e) {
79
+ setError(_get(e, 'response.data.message', null))
80
+ setPaymentIsLoading(false)
81
+ onPaymentError(
82
+ ((e as Record<string, unknown>).response as AxiosError) || e,
83
+ reviewData.event_details.slug
84
+ )
85
+ }
86
+ }