tf-checkout-react 1.3.35 → 1.3.37-beta

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/{src/components → dist}/.DS_Store +0 -0
  2. package/dist/components/common/{SelectField.d.ts → NativeSelectFeild/index.d.ts} +1 -1
  3. package/dist/components/common/SelectField/index.d.ts +18 -0
  4. package/dist/components/common/index.d.ts +2 -1
  5. package/dist/components/ticketsContainer/TicketsSection.d.ts +2 -1
  6. package/dist/components/waitingList/index.d.ts +2 -1
  7. package/dist/tf-checkout-react.cjs.development.js +97 -14
  8. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  9. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  10. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  11. package/dist/tf-checkout-react.esm.js +97 -14
  12. package/dist/tf-checkout-react.esm.js.map +1 -1
  13. package/dist/validators/index.d.ts +2 -1
  14. package/package.json +1 -1
  15. package/src/.DS_Store +0 -0
  16. package/src/assets/.DS_Store +0 -0
  17. package/src/components/addonsContainer/AddonComponent.tsx +2 -2
  18. package/src/components/billing-info-container/index.tsx +5 -1
  19. package/src/components/common/{SelectField.tsx → NativeSelectFeild/index.tsx} +1 -1
  20. package/src/components/common/SelectField/index.tsx +82 -0
  21. package/src/components/common/index.tsx +2 -1
  22. package/src/components/ticketsContainer/TicketsSection.tsx +31 -11
  23. package/src/components/ticketsContainer/index.tsx +2 -1
  24. package/src/components/waitingList/index.tsx +3 -2
  25. package/src/env.ts +2 -2
  26. package/src/normalizers/index.ts +8 -5
  27. package/src/validators/index.ts +25 -5
  28. package/src/components/common/dist/PhoneNumberField.js +0 -96
@@ -1,3 +1,4 @@
1
1
  export declare const combineValidators: (...validators: any) => (...value: any) => any;
2
- export declare const requiredValidator: (value?: string | number | undefined, message?: string | undefined) => string;
2
+ export declare function isFalsy(item: any): boolean;
3
+ export declare const requiredValidator: (value?: string | number | boolean | string[] | undefined, message?: string | undefined) => string;
3
4
  export declare const emailValidator: (email: string) => "" | "Please enter a valid email address";
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.35",
2
+ "version": "1.3.37-beta",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
package/src/.DS_Store CHANGED
Binary file
Binary file
@@ -3,7 +3,7 @@ import _identity from 'lodash/identity'
3
3
  import _isNull from 'lodash/isNull'
4
4
  import React from 'react'
5
5
 
6
- import { SelectField } from '../common'
6
+ import { NativeSelectField } from '../common'
7
7
 
8
8
  interface IAddonComponentProps {
9
9
  classNamePrefix: string;
@@ -32,7 +32,7 @@ const AddonComponent = ({
32
32
  <Field
33
33
  name={id}
34
34
  selectOptions={selectOptions}
35
- component={SelectField}
35
+ component={NativeSelectField}
36
36
  onChange={(e: any) => {
37
37
  const { value } = e.target
38
38
  handleAddonChange(id, value)
@@ -46,6 +46,7 @@ import { DatePickerField } from '../common/DatePickerField'
46
46
  import {
47
47
  CheckboxField,
48
48
  CustomField,
49
+ NativeSelectField,
49
50
  PhoneNumberField,
50
51
  RadioGroupField,
51
52
  SelectField,
@@ -887,13 +888,16 @@ export const BillingInfoContainer = React.memo(
887
888
  element.type === 'checkbox'
888
889
  ? CheckboxField
889
890
  : element.type === 'select'
890
- ? SelectField
891
+ ? NativeSelectField
891
892
  : element.type === 'phone'
892
893
  ? PhoneNumberField
893
894
  : element.type === 'date'
894
895
  ? DatePickerField
895
896
  : element.type === 'radio'
896
897
  ? RadioGroupField
898
+ : element.type ===
899
+ 'select_multi'
900
+ ? SelectField
897
901
  : CustomField
898
902
  }
899
903
  selectOptions={
@@ -29,7 +29,7 @@ interface IOtherProps {
29
29
  [key: string]: any;
30
30
  }
31
31
 
32
- export const SelectField = ({
32
+ export const NativeSelectField = ({
33
33
  label,
34
34
  type = 'text',
35
35
  field,
@@ -0,0 +1,82 @@
1
+ import { FormControl, InputLabel } from '@mui/material'
2
+ import Checkbox from '@mui/material/Checkbox'
3
+ import FormHelperText from '@mui/material/FormHelperText'
4
+ import ListItemText from '@mui/material/ListItemText'
5
+ import MenuItem from '@mui/material/MenuItem'
6
+ import OutlinedInput from '@mui/material/OutlinedInput'
7
+ import Select, { SelectChangeEvent } from '@mui/material/Select'
8
+ import { FieldInputProps, FormikProps } from 'formik'
9
+ import _get from 'lodash/get'
10
+ import _identity from 'lodash/identity'
11
+ import React from 'react'
12
+
13
+ interface ISelectOption {
14
+ id: string | number;
15
+ name: string | number;
16
+ value: string | number;
17
+ }
18
+
19
+ interface ISelectField {
20
+ field: FieldInputProps<any>;
21
+ form: FormikProps<any>;
22
+ options: ISelectOption[];
23
+
24
+ // optional
25
+ label?: string;
26
+ isMultiple?: boolean;
27
+ onChange?: (e: SelectChangeEvent<string[]>) => void;
28
+ }
29
+
30
+ function SelectField({
31
+ label,
32
+ isMultiple,
33
+ field,
34
+ form: { errors, setFieldValue },
35
+ options,
36
+ onChange = _identity,
37
+ }: ISelectField) {
38
+ const { name, value } = field
39
+ const selectId = `select-field-${name}`
40
+ const error = _get(errors, name)
41
+
42
+ const handleChange = (event: SelectChangeEvent<string[]>) => {
43
+ const {
44
+ target: { value },
45
+ } = event
46
+
47
+ setFieldValue(name, value)
48
+ onChange(event)
49
+ }
50
+
51
+ return (
52
+ <>
53
+ <FormControl fullWidth={true} error={Boolean(error)}>
54
+ {label && <InputLabel id={selectId}>{label}</InputLabel>}
55
+ <Select
56
+ id={name}
57
+ labelId={selectId}
58
+ multiple={isMultiple}
59
+ value={value}
60
+ onChange={handleChange}
61
+ input={<OutlinedInput label={label} />}
62
+ renderValue={selected =>
63
+ isMultiple ? selected.join(', ') : selected
64
+ }
65
+ sx={{ textAlign: 'start' }}
66
+ >
67
+ {options.map((option: ISelectOption) => (
68
+ <MenuItem key={option.name} value={option.value}>
69
+ {isMultiple && (
70
+ <Checkbox checked={value.indexOf(option.value) > -1} />
71
+ )}
72
+ <ListItemText primary={option.name} />
73
+ </MenuItem>
74
+ ))}
75
+ </Select>
76
+ {error ? <FormHelperText error>{error}</FormHelperText> : null}
77
+ </FormControl>
78
+ </>
79
+ )
80
+ }
81
+
82
+ export { SelectField }
@@ -3,5 +3,6 @@ export { CustomField } from './CustomField'
3
3
  export { FormikPhoneNumberField } from './FormikPhoneNumberField'
4
4
  export { PhoneNumberField } from './PhoneNumberField'
5
5
  export { Loader } from './Loader'
6
- export { SelectField } from './SelectField'
6
+ export { NativeSelectField } from './NativeSelectFeild'
7
7
  export { RadioGroupField } from './RadioGroupField'
8
+ export { SelectField } from './SelectField'
@@ -3,9 +3,12 @@ import './style.css'
3
3
  import _sortBy from 'lodash/sortBy'
4
4
  import React, { ReactNode } from 'react'
5
5
 
6
+ import { currencyNormalizerCreator } from '../../normalizers'
6
7
  import { TicketRow } from './TicketRow'
7
8
 
8
9
  interface ITicketsSectionProps {
10
+ event: any;
11
+
9
12
  ticketsList: any;
10
13
  selectedTickets: any;
11
14
  handleTicketSelect: any;
@@ -15,13 +18,17 @@ interface ITicketsSectionProps {
15
18
  }
16
19
 
17
20
  export const TicketsSection = ({
21
+ event = { currency: {} },
18
22
  ticketsList,
19
23
  selectedTickets,
20
24
  handleTicketSelect,
21
25
  sortBySoldOut,
22
26
  ticketsHeaderComponent,
23
- hideTicketsHeader
27
+ hideTicketsHeader,
24
28
  }: ITicketsSectionProps) => {
29
+ const {
30
+ currency: { currency },
31
+ } = event
25
32
  const sortedTicketsList = sortBySoldOut
26
33
  ? _sortBy(_sortBy(ticketsList, 'sortOrder'), 'soldOut')
27
34
  : _sortBy(ticketsList, 'sortOrder')
@@ -30,6 +37,15 @@ export const TicketsSection = ({
30
37
  <>
31
38
  {!hideTicketsHeader && ticketsHeaderComponent}
32
39
  {sortedTicketsList.map((ticket, i, arr) => {
40
+ const ticketPrice = currencyNormalizerCreator(
41
+ (+ticket.price).toFixed(2),
42
+ currency
43
+ )
44
+ const ticketOldPrice = currencyNormalizerCreator(
45
+ (+ticket.oldPrice).toFixed(2),
46
+ currency
47
+ )
48
+
33
49
  const isSoldOut =
34
50
  ticket.sold_out || !ticket.displayTicket || ticket.soldOut
35
51
  const ticketSelect = (event: any) => {
@@ -38,22 +54,24 @@ export const TicketsSection = ({
38
54
  }
39
55
 
40
56
  let ticketIsDiscounted = false
41
- if (
42
- ticket.oldPrice &&
43
- !isSoldOut &&
44
- ticket.oldPrice !== ticket.price
45
- ) {
57
+ if (ticket.oldPrice && !isSoldOut && ticket.oldPrice !== ticket.price) {
46
58
  ticketIsDiscounted = true
47
59
  }
48
60
 
49
61
  const ticketIsFree = +ticket.price === 0
50
- const ticketPrice = isSoldOut ? 'SOLD OUT' : ticketIsFree ? 'FREE' : `$ ${(+ticket.price).toFixed(2)}`
51
- const isNewGroupTicket = ticket?.groupName !== arr[i-1]?.groupName
62
+ const ticketPriceElem = isSoldOut
63
+ ? 'SOLD OUT'
64
+ : ticketIsFree
65
+ ? 'FREE'
66
+ : ticketPrice
67
+ const isNewGroupTicket = ticket?.groupName !== arr[i - 1]?.groupName
52
68
 
53
69
  return (
54
70
  <React.Fragment key={ticket.id || ticket.name}>
55
71
  {showGroup && isNewGroupTicket ? (
56
- <div className='event-detail__tier group-title'>{ticket.groupName || ''}</div>
72
+ <div className="event-detail__tier group-title">
73
+ {ticket.groupName || ''}
74
+ </div>
57
75
  ) : null}
58
76
  <div
59
77
  className={`event-detail__tier ${isSoldOut ? 'disabled' : ''}`}
@@ -64,9 +82,11 @@ export const TicketsSection = ({
64
82
  <div className="event-tickets-container">
65
83
  <div className="event-detail__tier-price">
66
84
  {ticketIsDiscounted && (
67
- <p className="old-price">$ {(+ticket.oldPrice).toFixed(2)}</p>
85
+ <p className="old-price">{ticketOldPrice}</p>
68
86
  )}
69
- <p className={isSoldOut ? 'sold-out' : ''}>{ticketPrice}</p>
87
+ <p className={isSoldOut ? 'sold-out' : ''}>
88
+ {ticketPriceElem}
89
+ </p>
70
90
  {!isSoldOut && !ticketIsFree && (
71
91
  <p className="fees">
72
92
  {ticket.feeIncluded ? '(incl. Fees)' : '(excl. Fees)'}
@@ -564,6 +564,7 @@ export const TicketsContainer = ({
564
564
  <div ref={ticketsContainerRef}>
565
565
  {!isSalesClosed && (
566
566
  <TicketsSection
567
+ event={event}
567
568
  ticketsList={tickets}
568
569
  selectedTickets={selectedTickets}
569
570
  handleTicketSelect={handleTicketSelect}
@@ -593,7 +594,7 @@ export const TicketsContainer = ({
593
594
  />
594
595
  ) : null}
595
596
  {showWaitingList && event.salesStarted && !hideWaitingList && (
596
- <WaitingList tickets={tickets} eventId={eventId} />
597
+ <WaitingList tickets={tickets} eventId={eventId} defaultMaxQuantity={event.waitingListMaxQuantity} />
597
598
  )}
598
599
  {codeIsLoading ? (
599
600
  <Loader />
@@ -16,6 +16,7 @@ import './style.css'
16
16
  interface WaitingListProps {
17
17
  tickets: any;
18
18
  eventId: number;
19
+ defaultMaxQuantity: number;
19
20
  }
20
21
 
21
22
  interface WaitingListFields {
@@ -34,7 +35,7 @@ const generateQuantity = (n: number) => {
34
35
  return quantityList
35
36
  }
36
37
 
37
- const WaitingList = ({ tickets = {}, eventId }: WaitingListProps) => {
38
+ const WaitingList = ({ tickets = {}, eventId, defaultMaxQuantity = 10 }: WaitingListProps) => {
38
39
  const isWindowDefined = typeof window !== 'undefined'
39
40
  const userData =
40
41
  isWindowDefined && window.localStorage.getItem('user_data')
@@ -117,7 +118,7 @@ const WaitingList = ({ tickets = {}, eventId }: WaitingListProps) => {
117
118
  value: '',
118
119
  disabled: true,
119
120
  },
120
- ...generateQuantity(10),
121
+ ...generateQuantity(defaultMaxQuantity ?? 10),
121
122
  ]}
122
123
  />
123
124
  </div>
package/src/env.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  // preview
2
2
  export const ENV = {
3
- EVENT_ID: 5106,
4
- BASE_URL: 'https://staging2.ttf.fluxtech.me',
3
+ EVENT_ID: 12927,
4
+ BASE_URL: 'https://test.ticketfairy.com',
5
5
  CLIENT_ID: 'e9d8f8922797b4621e562255afe90dbf',
6
6
  CLIENT_SECRET: 'b89c191eff22fdcf84ac9bfd88d005355a151ec2c83b26b9',
7
7
  STRIPE_PUBLISHABLE_KEY:
@@ -1,8 +1,11 @@
1
- export const currencyNormalizerCreator = (value: string | number, currency: string) =>
2
- !value ? '' : `${getCurrencySymbolByCurrency(currency)}${value}`
1
+ export const currencyNormalizerCreator = (
2
+ value: string | number,
3
+ currency: string
4
+ ) => (!value ? '' : `${getCurrencySymbolByCurrency(currency)} ${value}`)
3
5
 
4
- export const createFixedFloatNormalizer = (fixedValue: number) => (value: string | number) =>
5
- value || `${value}` === '0' ? (+value).toFixed(fixedValue) : ''
6
+ export const createFixedFloatNormalizer = (fixedValue: number) => (
7
+ value: string | number
8
+ ) => (value || `${value}` === '0' ? (+value).toFixed(fixedValue) : '')
6
9
 
7
10
  export const getCurrencySymbolByCurrency = (currency = '') => {
8
11
  switch (currency) {
@@ -43,4 +46,4 @@ export const getCurrencySymbolByCurrency = (currency = '') => {
43
46
  }
44
47
  }
45
48
 
46
- export const removePlusSign = (string = '') => string.replace('+', '')
49
+ export const removePlusSign = (string = '') => string.replace('+', '')
@@ -7,14 +7,34 @@ export const combineValidators = (...validators: any) => (...value: any) => {
7
7
  }
8
8
  }
9
9
 
10
- export const requiredValidator = (value?: string | number, message?: string): string => {
10
+ export function isFalsy(item: any) {
11
+ try {
12
+ if (
13
+ !item || // handles most, like false, 0, null, etc
14
+ (typeof item == 'object' &&
15
+ Object.keys(item).length === 0 && // for empty objects, like {}, []
16
+ !(typeof item.addEventListener == 'function')) // omit webpage elements
17
+ ) {
18
+ return true
19
+ }
20
+ } catch (err) {
21
+ return true
22
+ }
23
+
24
+ return false
25
+ }
26
+
27
+ export const requiredValidator = (
28
+ value?: string | number | Array<string> | boolean,
29
+ message?: string
30
+ ): string => {
11
31
  let errorMessage = ''
12
- if (!value) {
32
+
33
+ if (isFalsy(value)) {
13
34
  errorMessage = message || 'Required'
14
35
  }
15
36
  return errorMessage
16
37
  }
17
38
 
18
- export const emailValidator = (email: string) => {
19
- return !emailRegex.test(email) ? 'Please enter a valid email address' : ''
20
- }
39
+ export const emailValidator = (email: string) =>
40
+ !emailRegex.test(email) ? 'Please enter a valid email address' : ''
@@ -1,96 +0,0 @@
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
- };