tf-checkout-react 1.7.3 → 1.7.5

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 (29) hide show
  1. package/dist/components/common/PhoneNumberField.d.ts +1 -2
  2. package/dist/components/confirmationContainer/index.d.ts +5 -1
  3. package/dist/components/loginModal/SignUpForm.d.ts +10 -0
  4. package/dist/components/loginModal/constants.d.ts +39 -0
  5. package/dist/components/preRegistration/PreRegistrationComplete.d.ts +1 -1
  6. package/dist/components/seatMapContainer/addToCart.d.ts +2 -2
  7. package/dist/components/ticketsContainer/TimeSlotTicketRow.d.ts +19 -0
  8. package/dist/tf-checkout-react.cjs.development.js +817 -85
  9. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  10. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  11. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  12. package/dist/tf-checkout-react.esm.js +818 -86
  13. package/dist/tf-checkout-react.esm.js.map +1 -1
  14. package/dist/tf-checkout-styles.css +1 -1
  15. package/package.json +4 -3
  16. package/src/api/publicRequest.ts +1 -0
  17. package/src/components/billing-info-container/index.tsx +1 -1
  18. package/src/components/common/CustomField.tsx +16 -5
  19. package/src/components/common/PhoneNumberField.tsx +7 -10
  20. package/src/components/confirmationContainer/index.tsx +29 -4
  21. package/src/components/loginModal/SignUpForm.tsx +329 -0
  22. package/src/components/loginModal/constants.ts +46 -0
  23. package/src/components/loginModal/index.tsx +94 -26
  24. package/src/components/loginModal/style.css +38 -0
  25. package/src/components/myTicketsContainer/index.tsx +2 -0
  26. package/src/components/preRegistration/PreRegistrationComplete.tsx +3 -1
  27. package/src/components/ticketsContainer/TimeSlotTicketRow.tsx +224 -0
  28. package/src/components/ticketsContainer/TimeSlotsSection.tsx +98 -24
  29. package/src/components/ticketsContainer/index.tsx +1 -1
@@ -1,4 +1,4 @@
1
- import { CircularProgress, Modal as Modal$1, FormControl, FormHelperText, InputLabel, Snackbar, Alert, Box as Box$1, Button as Button$1, TextField as TextField$1, Backdrop as Backdrop$1, Select as Select$1 } from '@mui/material';
1
+ import { CircularProgress, Modal as Modal$1, FormControl, FormHelperText, InputLabel, Snackbar, Alert, Box as Box$1, Grid, Button as Button$1, TextField as TextField$1, Backdrop as Backdrop$1, Select as Select$1 } from '@mui/material';
2
2
  import Backdrop from '@mui/material/Backdrop';
3
3
  import Button from '@mui/material/Button';
4
4
  import { ThemeProvider, createTheme } from '@mui/material/styles';
@@ -31,15 +31,16 @@ import Visibility from '@mui/icons-material/Visibility';
31
31
  import VisibilityOff from '@mui/icons-material/VisibilityOff';
32
32
  import IconButton from '@mui/material/IconButton';
33
33
  import InputAdornment from '@mui/material/InputAdornment';
34
+ import MenuItem from '@mui/material/MenuItem';
34
35
  import TextField from '@mui/material/TextField';
35
36
  import _includes from 'lodash-es/includes';
36
37
  import _isFunction from 'lodash-es/isFunction';
37
38
  import _isObject from 'lodash-es/isObject';
38
- import MuiPhoneNumber from 'material-ui-phone-number';
39
+ import 'material-ui-phone-number';
39
40
  import _debounce from 'lodash-es/debounce';
41
+ import { MuiTelInput } from 'mui-tel-input';
40
42
  import FormHelperText$1 from '@mui/material/FormHelperText';
41
43
  import ListItemText from '@mui/material/ListItemText';
42
- import MenuItem from '@mui/material/MenuItem';
43
44
  import OutlinedInput from '@mui/material/OutlinedInput';
44
45
  import Select from '@mui/material/Select';
45
46
  import Modal$2 from '@mui/material/Modal';
@@ -53,6 +54,9 @@ import RadioGroup from '@mui/material/RadioGroup';
53
54
  import _reverse from 'lodash-es/reverse';
54
55
  import _sortBy from 'lodash-es/sortBy';
55
56
  import { object, string, ref, boolean } from 'yup';
57
+ import Tab from '@mui/material/Tab';
58
+ import Tabs from '@mui/material/Tabs';
59
+ import useMediaQuery from '@mui/material/useMediaQuery';
56
60
  import Alert$1 from '@mui/material/Alert';
57
61
  import Container from '@mui/material/Container';
58
62
  import { Elements, useStripe, useElements, PaymentElement } from '@stripe/react-stripe-js';
@@ -496,7 +500,8 @@ if (isWindowDefined && authGuestToken) {
496
500
  }
497
501
  var publicRequest = /*#__PURE__*/axios.create({
498
502
  baseURL: 'https://www.ticketfairy.com/api',
499
- headers: headers
503
+ headers: headers,
504
+ withCredentials: true
500
505
  });
501
506
  publicRequest.interceptors.request.use(function (config) {
502
507
  if (getCookieByName('X-TF-ECOMMERCE')) {
@@ -2506,6 +2511,12 @@ var passwordValidator = function passwordValidator(password) {
2506
2511
  }
2507
2512
  return '';
2508
2513
  };
2514
+ var confirmPasswordValidator = function confirmPasswordValidator(confirmPassword, password) {
2515
+ if (confirmPassword !== password) {
2516
+ return 'Passwords do not match.';
2517
+ }
2518
+ return '';
2519
+ };
2509
2520
 
2510
2521
  var currencyNormalizerCreator = function currencyNormalizerCreator(value, currency) {
2511
2522
  return !value ? '' : getCurrencySymbolByCurrency(currency) + " " + value;
@@ -2825,7 +2836,7 @@ var Checkbox = function Checkbox(_ref) {
2825
2836
  };
2826
2837
 
2827
2838
  var CustomField = function CustomField(_ref2) {
2828
- var _ref$current, _customTheme$input;
2839
+ var _ref$current, _ref$current2, _customTheme$input;
2829
2840
  var label = _ref2.label,
2830
2841
  _ref2$type = _ref2.type,
2831
2842
  type = _ref2$type === void 0 ? 'text' : _ref2$type,
@@ -2856,7 +2867,7 @@ var CustomField = function CustomField(_ref2) {
2856
2867
  showPassword = _useState2[0],
2857
2868
  setShowPassword = _useState2[1];
2858
2869
  var _ref = useRef(null);
2859
- var isAutoFilled = (_ref$current = _ref.current) == null ? void 0 : _ref$current.matches(':-webkit-autofill');
2870
+ var isAutoFilled = (_ref$current = _ref.current) != null && _ref$current.matches ? (_ref$current2 = _ref.current) == null ? void 0 : _ref$current2.matches(':-webkit-autofill') : false;
2860
2871
  var isSelectField = type === 'select';
2861
2872
  var isPasswordField = type === 'password';
2862
2873
  var error = _get(errors, field.name);
@@ -2906,10 +2917,18 @@ var CustomField = function CustomField(_ref2) {
2906
2917
  setIsShrinked(true);
2907
2918
  },
2908
2919
  SelectProps: {
2909
- "native": true,
2920
+ "native": false,
2910
2921
  className: theme,
2911
2922
  MenuProps: {
2912
- className: theme
2923
+ className: theme,
2924
+ PaperProps: {
2925
+ sx: {
2926
+ '& .MuiMenuItem-root': {
2927
+ paddingLeft: '16px',
2928
+ paddingRight: '16px'
2929
+ }
2930
+ }
2931
+ }
2913
2932
  }
2914
2933
  },
2915
2934
  InputLabelProps: {
@@ -2931,7 +2950,7 @@ var CustomField = function CustomField(_ref2) {
2931
2950
  },
2932
2951
  onChange: onChange != null ? onChange : field.onChange
2933
2952
  }), isSelectField ? _map(selectOptions, function (option) {
2934
- return React.createElement("option", {
2953
+ return React.createElement(MenuItem, {
2935
2954
  key: option.value,
2936
2955
  value: option.value,
2937
2956
  disabled: option.disabled
@@ -2958,8 +2977,7 @@ var PhoneNumberField = function PhoneNumberField(_ref) {
2958
2977
  defaultCountry = _ref$defaultCountry === void 0 ? 'us' : _ref$defaultCountry,
2959
2978
  _ref$fill = _ref.fill,
2960
2979
  fill = _ref$fill === void 0 ? false : _ref$fill,
2961
- setPhoneValidationIsLoading = _ref.setPhoneValidationIsLoading,
2962
- isCountryCodeEditable = _ref.isCountryCodeEditable;
2980
+ setPhoneValidationIsLoading = _ref.setPhoneValidationIsLoading;
2963
2981
  var error = _get(errors, field.name);
2964
2982
  var isTouched = Boolean(_get(touched, field.name));
2965
2983
  var isSubmitAttempted = Boolean(submitCount && submitCount > 0);
@@ -3019,11 +3037,11 @@ var PhoneNumberField = function PhoneNumberField(_ref) {
3019
3037
  })));
3020
3038
  // eslint-disable-next-line
3021
3039
  }, [field.value]);
3022
- return React.createElement(React.Fragment, null, React.createElement(MuiPhoneNumber, {
3040
+ return React.createElement(React.Fragment, null, React.createElement(MuiTelInput, {
3023
3041
  name: field.name,
3024
3042
  value: fill ? values[field.name] : initialValues[field.name],
3025
- onChange: function onChange(value, country) {
3026
- if ("+" + (country == null ? void 0 : country.dialCode) === value || value === '+') {
3043
+ onChange: function onChange(value) {
3044
+ if (!value || value.length <= 4) {
3027
3045
  setFieldValue(field.name, '');
3028
3046
  setFieldError(field.name, '');
3029
3047
  } else {
@@ -3032,15 +3050,14 @@ var PhoneNumberField = function PhoneNumberField(_ref) {
3032
3050
  }
3033
3051
  },
3034
3052
  variant: "outlined",
3035
- defaultCountry: defaultCountry,
3053
+ defaultCountry: defaultCountry.toUpperCase(),
3036
3054
  disableDropdown: disableDropdown,
3037
3055
  label: label,
3038
3056
  error: !!error && (isTouched || fill || isSubmitAttempted),
3039
3057
  helperText: (isTouched || fill || isSubmitAttempted) && error,
3040
3058
  fullWidth: true,
3041
- autoFormat: false,
3042
- disableAreaCodes: true,
3043
- countryCodeEditable: isCountryCodeEditable
3059
+ forceCallingCode: true,
3060
+ focusOnSelectCountry: true
3044
3061
  }));
3045
3062
  };
3046
3063
 
@@ -4827,16 +4844,441 @@ var ForgotPasswordModal = function ForgotPasswordModal(_ref) {
4827
4844
  }))));
4828
4845
  };
4829
4846
 
4847
+ // Theme colors
4848
+ var COLORS = {
4849
+ PRIMARY: '#212529',
4850
+ SECONDARY: '#666',
4851
+ BACKGROUND: '#fff',
4852
+ BORDER: 'white',
4853
+ INDICATOR: '#212529'
4854
+ };
4855
+ // Typography
4856
+ var TYPOGRAPHY = {
4857
+ FONT_FAMILY: 'Inter',
4858
+ FONT_WEIGHT: {
4859
+ SEMIBOLD: 600,
4860
+ BOLD: 700
4861
+ },
4862
+ FONT_SIZE: {
4863
+ TAB: '16px',
4864
+ TITLE: '18px'
4865
+ }
4866
+ };
4867
+ // Modal dimensions
4868
+ var MODAL_DIMENSIONS = {
4869
+ WIDTH: {
4870
+ DESKTOP: 480,
4871
+ MOBILE: 345
4872
+ }
4873
+ };
4874
+ // Tab configuration
4875
+ var TAB_STYLES = {
4876
+ BACKGROUND_COLOR: COLORS.BACKGROUND,
4877
+ MARGIN_BOTTOM: '30px',
4878
+ LABEL: {
4879
+ FONT_FAMILY: TYPOGRAPHY.FONT_FAMILY,
4880
+ FONT_WEIGHT: TYPOGRAPHY.FONT_WEIGHT.SEMIBOLD,
4881
+ FONT_SIZE: TYPOGRAPHY.FONT_SIZE.TAB,
4882
+ TEXT_TRANSFORM: 'none',
4883
+ COLOR: COLORS.SECONDARY,
4884
+ SELECTED_COLOR: COLORS.PRIMARY
4885
+ },
4886
+ INDICATOR: {
4887
+ BACKGROUND_COLOR: COLORS.INDICATOR
4888
+ }
4889
+ };
4890
+
4891
+ var SignUpForm = function SignUpForm(_ref) {
4892
+ var onSignUpSuccess = _ref.onSignUpSuccess,
4893
+ _ref$onGetProfileData = _ref.onGetProfileDataSuccess,
4894
+ onGetProfileDataSuccess = _ref$onGetProfileData === void 0 ? function () {} : _ref$onGetProfileData,
4895
+ _ref$onGetProfileData2 = _ref.onGetProfileDataError,
4896
+ onGetProfileDataError = _ref$onGetProfileData2 === void 0 ? function () {} : _ref$onGetProfileData2,
4897
+ logo = _ref.logo;
4898
+ var _useState = useState(''),
4899
+ error = _useState[0],
4900
+ setError = _useState[1];
4901
+ var _useState2 = useState(false),
4902
+ isSubmitting = _useState2[0],
4903
+ setIsSubmitting = _useState2[1];
4904
+ var _useState3 = useState([]),
4905
+ countries = _useState3[0],
4906
+ setCountries = _useState3[1];
4907
+ var _useState4 = useState([]),
4908
+ states = _useState4[0],
4909
+ setStates = _useState4[1];
4910
+ var _useState5 = useState(false),
4911
+ phoneValidationIsLoading = _useState5[0],
4912
+ setPhoneValidationIsLoading = _useState5[1];
4913
+ // Fetch countries on mount
4914
+ useEffect(function () {
4915
+ var fetchCountries = /*#__PURE__*/function () {
4916
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
4917
+ var res, mappedCountries;
4918
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
4919
+ while (1) switch (_context.prev = _context.next) {
4920
+ case 0:
4921
+ _context.prev = 0;
4922
+ _context.next = 3;
4923
+ return getCountries();
4924
+ case 3:
4925
+ res = _context.sent;
4926
+ mappedCountries = _map(res.data, function (item) {
4927
+ return {
4928
+ id: item.id,
4929
+ name: item.name,
4930
+ code: item.code
4931
+ };
4932
+ });
4933
+ setCountries(mappedCountries);
4934
+ _context.next = 11;
4935
+ break;
4936
+ case 8:
4937
+ _context.prev = 8;
4938
+ _context.t0 = _context["catch"](0);
4939
+ console.error('Error fetching countries:', _context.t0);
4940
+ case 11:
4941
+ case "end":
4942
+ return _context.stop();
4943
+ }
4944
+ }, _callee, null, [[0, 8]]);
4945
+ }));
4946
+ return function fetchCountries() {
4947
+ return _ref2.apply(this, arguments);
4948
+ };
4949
+ }();
4950
+ fetchCountries();
4951
+ }, []);
4952
+ return React.createElement(Formik, {
4953
+ enableReinitialize: true,
4954
+ initialValues: {
4955
+ firstName: '',
4956
+ lastName: '',
4957
+ email: '',
4958
+ password: '',
4959
+ passwordConfirmation: '',
4960
+ phone: '',
4961
+ country: '1',
4962
+ city: '',
4963
+ state: '',
4964
+ streetAddress: '',
4965
+ zip: ''
4966
+ },
4967
+ onSubmit: function () {
4968
+ var _onSubmit = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(values) {
4969
+ var formData, profileResponse, profileSpecifiedData, profileDataObj, event, errorData, errorMessages;
4970
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
4971
+ while (1) switch (_context2.prev = _context2.next) {
4972
+ case 0:
4973
+ setIsSubmitting(true);
4974
+ setError('');
4975
+ _context2.prev = 2;
4976
+ formData = new FormData();
4977
+ formData.append('first_name', values.firstName);
4978
+ formData.append('last_name', values.lastName);
4979
+ formData.append('email', values.email);
4980
+ formData.append('password', values.password);
4981
+ formData.append('password_confirmation', values.passwordConfirmation);
4982
+ formData.append('phone', values.phone);
4983
+ formData.append('country', values.country);
4984
+ formData.append('city', values.city);
4985
+ formData.append('state', values.state);
4986
+ formData.append('street_address', values.streetAddress);
4987
+ formData.append('zip', values.zip);
4988
+ formData.append('client_id', CONFIGS.CLIENT_ID || '');
4989
+ formData.append('client_secret', CONFIGS.CLIENT_SECRET || '');
4990
+ _context2.next = 19;
4991
+ return register(formData);
4992
+ case 19:
4993
+ _context2.prev = 19;
4994
+ _context2.next = 22;
4995
+ return getProfileData();
4996
+ case 22:
4997
+ profileResponse = _context2.sent;
4998
+ onGetProfileDataSuccess(profileResponse.data);
4999
+ profileSpecifiedData = profileResponse.data;
5000
+ profileDataObj = setLoggedUserData(profileSpecifiedData);
5001
+ if (isBrowser) {
5002
+ window.localStorage.setItem('user_data', JSON.stringify(profileDataObj));
5003
+ event = new window.CustomEvent('tf-login');
5004
+ window.document.dispatchEvent(event);
5005
+ }
5006
+ onSignUpSuccess(_get(profileResponse, 'data.data', {}));
5007
+ _context2.next = 34;
5008
+ break;
5009
+ case 30:
5010
+ _context2.prev = 30;
5011
+ _context2.t0 = _context2["catch"](19);
5012
+ if (_context2.t0.isAxiosError) {
5013
+ onGetProfileDataError(_context2.t0);
5014
+ }
5015
+ setError('Registration successful but failed to fetch profile data');
5016
+ case 34:
5017
+ _context2.next = 40;
5018
+ break;
5019
+ case 36:
5020
+ _context2.prev = 36;
5021
+ _context2.t1 = _context2["catch"](2);
5022
+ errorData = _get(_context2.t1, 'response.data.message', ''); // Check if error is an object with field-specific errors
5023
+ if (typeof errorData === 'object' && errorData !== null) {
5024
+ errorMessages = Object.entries(errorData).map(function (_ref3) {
5025
+ var field = _ref3[0],
5026
+ messages = _ref3[1];
5027
+ var fieldName = field.replace(/_/g, ' ').replace(/\b\w/g, function (l) {
5028
+ return l.toUpperCase();
5029
+ });
5030
+ var messageArray = Array.isArray(messages) ? messages : [messages];
5031
+ return fieldName + ": " + messageArray.join(', ');
5032
+ }).join('\n');
5033
+ setError(errorMessages || 'Registration failed. Please try again.');
5034
+ } else {
5035
+ setError(String(errorData) || 'Registration failed. Please try again.');
5036
+ }
5037
+ case 40:
5038
+ _context2.prev = 40;
5039
+ setIsSubmitting(false);
5040
+ return _context2.finish(40);
5041
+ case 43:
5042
+ case "end":
5043
+ return _context2.stop();
5044
+ }
5045
+ }, _callee2, null, [[2, 36, 40, 43], [19, 30]]);
5046
+ }));
5047
+ function onSubmit(_x) {
5048
+ return _onSubmit.apply(this, arguments);
5049
+ }
5050
+ return onSubmit;
5051
+ }()
5052
+ }, function (props) {
5053
+ return React.createElement(Form, {
5054
+ onSubmit: props.handleSubmit
5055
+ }, React.createElement("div", {
5056
+ className: "login-logo-container"
5057
+ }, React.createElement("img", {
5058
+ className: "login-logo-tff",
5059
+ src: logo || 'https://www.ticketfairy.com/resources/images/logo-ttf-black.svg',
5060
+ alt: "logo"
5061
+ })), error && React.createElement("div", {
5062
+ className: "server_auth__error",
5063
+ style: {
5064
+ whiteSpace: 'pre-line'
5065
+ }
5066
+ }, error), React.createElement(Grid, {
5067
+ container: true,
5068
+ spacing: 2,
5069
+ sx: {
5070
+ padding: '15px 25px',
5071
+ maxHeight: {
5072
+ xs: '40vh',
5073
+ sm: '60vh'
5074
+ },
5075
+ overflowY: 'auto'
5076
+ }
5077
+ }, React.createElement(Grid, {
5078
+ item: true,
5079
+ xs: 12,
5080
+ md: 6
5081
+ }, React.createElement(Field, {
5082
+ name: "firstName",
5083
+ label: "First Name",
5084
+ type: "text",
5085
+ component: CustomField,
5086
+ theme: "light",
5087
+ validate: requiredValidator
5088
+ })), React.createElement(Grid, {
5089
+ item: true,
5090
+ xs: 12,
5091
+ md: 6
5092
+ }, React.createElement(Field, {
5093
+ name: "lastName",
5094
+ label: "Last Name",
5095
+ type: "text",
5096
+ component: CustomField,
5097
+ theme: "light",
5098
+ validate: requiredValidator
5099
+ })), React.createElement(Grid, {
5100
+ item: true,
5101
+ xs: 12,
5102
+ md: 6
5103
+ }, React.createElement(Field, {
5104
+ name: "email",
5105
+ label: "Email",
5106
+ type: "email",
5107
+ component: CustomField,
5108
+ theme: "light",
5109
+ validate: function validate(value) {
5110
+ var required = requiredValidator(value);
5111
+ if (required) return required;
5112
+ return emailValidator(value);
5113
+ }
5114
+ })), React.createElement(Grid, {
5115
+ item: true,
5116
+ xs: 12,
5117
+ md: 6
5118
+ }, React.createElement(Field, {
5119
+ name: "streetAddress",
5120
+ label: "Street Address",
5121
+ type: "text",
5122
+ component: CustomField,
5123
+ theme: "light",
5124
+ validate: requiredValidator
5125
+ })), React.createElement(Grid, {
5126
+ item: true,
5127
+ xs: 12,
5128
+ md: 6
5129
+ }, React.createElement(Field, {
5130
+ name: "zip",
5131
+ label: "Zip / Postal Code",
5132
+ type: "text",
5133
+ component: CustomField,
5134
+ theme: "light",
5135
+ validate: requiredValidator
5136
+ })), React.createElement(Grid, {
5137
+ item: true,
5138
+ xs: 12,
5139
+ md: 6
5140
+ }, React.createElement(Field, {
5141
+ name: "country",
5142
+ label: "Country",
5143
+ type: "select",
5144
+ component: CustomField,
5145
+ theme: "light",
5146
+ validate: requiredValidator,
5147
+ selectOptions: _map(countries, function (item) {
5148
+ return {
5149
+ value: item.id,
5150
+ label: item.name
5151
+ };
5152
+ }),
5153
+ onChange: function onChange(e) {
5154
+ props.setFieldValue('country', e.target.value);
5155
+ props.setFieldValue('state', '');
5156
+ // Fetch states for selected country
5157
+ var fetchStatesForCountry = /*#__PURE__*/function () {
5158
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
5159
+ var res, mappedStates;
5160
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
5161
+ while (1) switch (_context3.prev = _context3.next) {
5162
+ case 0:
5163
+ _context3.prev = 0;
5164
+ _context3.next = 3;
5165
+ return getStates(e.target.value);
5166
+ case 3:
5167
+ res = _context3.sent;
5168
+ mappedStates = _map(res.data, function (item, key) {
5169
+ return {
5170
+ label: item,
5171
+ value: key
5172
+ };
5173
+ });
5174
+ setStates(mappedStates);
5175
+ _context3.next = 12;
5176
+ break;
5177
+ case 8:
5178
+ _context3.prev = 8;
5179
+ _context3.t0 = _context3["catch"](0);
5180
+ console.error('Error fetching states:', _context3.t0);
5181
+ setStates([]);
5182
+ case 12:
5183
+ case "end":
5184
+ return _context3.stop();
5185
+ }
5186
+ }, _callee3, null, [[0, 8]]);
5187
+ }));
5188
+ return function fetchStatesForCountry() {
5189
+ return _ref4.apply(this, arguments);
5190
+ };
5191
+ }();
5192
+ fetchStatesForCountry();
5193
+ }
5194
+ })), React.createElement(Grid, {
5195
+ item: true,
5196
+ xs: 12,
5197
+ md: 6
5198
+ }, React.createElement(Field, {
5199
+ name: "state",
5200
+ label: "State / Province",
5201
+ type: "select",
5202
+ component: CustomField,
5203
+ theme: "light",
5204
+ validate: requiredValidator,
5205
+ selectOptions: [{
5206
+ value: '',
5207
+ label: 'Select State/Province',
5208
+ disabled: true
5209
+ }].concat(states)
5210
+ })), React.createElement(Grid, {
5211
+ item: true,
5212
+ xs: 12,
5213
+ md: 6
5214
+ }, React.createElement(Field, {
5215
+ name: "city",
5216
+ label: "City",
5217
+ type: "text",
5218
+ component: CustomField,
5219
+ theme: "light",
5220
+ validate: requiredValidator
5221
+ })), React.createElement(Grid, {
5222
+ item: true,
5223
+ xs: 12
5224
+ }, React.createElement(Field, {
5225
+ name: "phone",
5226
+ label: "Phone",
5227
+ type: "phone",
5228
+ component: PhoneNumberField,
5229
+ fill: true,
5230
+ disableDropdown: false,
5231
+ setPhoneValidationIsLoading: setPhoneValidationIsLoading,
5232
+ defaultCountry: "us",
5233
+ isCountryCodeEditable: true
5234
+ })), React.createElement(Grid, {
5235
+ item: true,
5236
+ xs: 12,
5237
+ md: 6
5238
+ }, React.createElement(Field, {
5239
+ name: "password",
5240
+ label: "Password",
5241
+ type: "password",
5242
+ component: CustomField,
5243
+ theme: "light",
5244
+ validate: passwordValidator
5245
+ })), React.createElement(Grid, {
5246
+ item: true,
5247
+ xs: 12,
5248
+ md: 6
5249
+ }, React.createElement(Field, {
5250
+ name: "passwordConfirmation",
5251
+ label: "Confirm Password",
5252
+ type: "password",
5253
+ component: CustomField,
5254
+ theme: "light",
5255
+ validate: function validate(value) {
5256
+ return confirmPasswordValidator(value, props.values.password);
5257
+ }
5258
+ }))), React.createElement("div", {
5259
+ className: "login-modal-body"
5260
+ }, React.createElement("div", {
5261
+ className: "login-action-button"
5262
+ }, React.createElement("button", {
5263
+ type: "submit",
5264
+ disabled: isSubmitting || phoneValidationIsLoading
5265
+ }, isSubmitting ? 'Creating Account...' : 'Create Account'))));
5266
+ });
5267
+ };
5268
+
4830
5269
  var style$2 = {
4831
5270
  position: 'absolute',
4832
5271
  top: '50%',
4833
5272
  left: '50%',
4834
5273
  transform: 'translate(-50%, -50%)',
4835
- minWidth: 480,
5274
+ width: MODAL_DIMENSIONS.WIDTH.DESKTOP,
4836
5275
  backgroundColor: '#e3e3e3',
4837
- border: '1px solid white',
5276
+ border: "1px solid " + COLORS.BORDER,
4838
5277
  outline: 'none'
4839
5278
  };
5279
+ var mobileStyle = /*#__PURE__*/_extends({}, style$2, {
5280
+ width: MODAL_DIMENSIONS.WIDTH.MOBILE
5281
+ });
4840
5282
  var LoginModal = function LoginModal(_ref) {
4841
5283
  var onClose = _ref.onClose,
4842
5284
  onLogin = _ref.onLogin,
@@ -4860,12 +5302,19 @@ var LoginModal = function LoginModal(_ref) {
4860
5302
  _ref$showSignUpButton = _ref.showSignUpButton,
4861
5303
  showSignUpButton = _ref$showSignUpButton === void 0 ? false : _ref$showSignUpButton,
4862
5304
  _ref$showPoweredByIma = _ref.showPoweredByImage,
4863
- showPoweredByImage = _ref$showPoweredByIma === void 0 ? false : _ref$showPoweredByIma,
4864
- _ref$registerUrl = _ref.registerUrl,
4865
- registerUrl = _ref$registerUrl === void 0 ? 'https://www.ticketfairy.com/register' : _ref$registerUrl;
5305
+ showPoweredByImage = _ref$showPoweredByIma === void 0 ? false : _ref$showPoweredByIma;
4866
5306
  var _useState = useState(''),
4867
5307
  error = _useState[0],
4868
5308
  setError = _useState[1];
5309
+ var _useState2 = useState('login'),
5310
+ activeTab = _useState2[0],
5311
+ setActiveTab = _useState2[1];
5312
+ var isMobile = useMediaQuery('(max-width:600px)');
5313
+ // If onSignup is provided (custom callback), use old behavior
5314
+ var useCustomSignup = onSignup !== _identity;
5315
+ var handleTabChange = function handleTabChange(_event, newValue) {
5316
+ setActiveTab(newValue);
5317
+ };
4869
5318
  return React.createElement(Modal$2, {
4870
5319
  open: true,
4871
5320
  onClose: onClose,
@@ -4873,8 +5322,51 @@ var LoginModal = function LoginModal(_ref) {
4873
5322
  "aria-describedby": "modal-modal-description",
4874
5323
  className: "login-modal " + modalClassname
4875
5324
  }, React.createElement(Box, {
4876
- style: style$2
4877
- }, React.createElement("div", null, React.createElement(Formik, {
5325
+ style: isMobile ? mobileStyle : style$2,
5326
+ sx: {
5327
+ '@media screen and (orientation:landscape)': {
5328
+ maxHeight: '80vh',
5329
+ overflowY: 'auto'
5330
+ }
5331
+ }
5332
+ }, React.createElement("div", null, showSignUpButton && !useCustomSignup && React.createElement(Tabs, {
5333
+ value: activeTab,
5334
+ onChange: handleTabChange,
5335
+ variant: "fullWidth",
5336
+ sx: {
5337
+ backgroundColor: TAB_STYLES.BACKGROUND_COLOR,
5338
+ marginBottom: TAB_STYLES.MARGIN_BOTTOM,
5339
+ '& .MuiTabs-indicator': {
5340
+ backgroundColor: TAB_STYLES.INDICATOR.BACKGROUND_COLOR
5341
+ }
5342
+ }
5343
+ }, React.createElement(Tab, {
5344
+ label: "Login",
5345
+ value: "login",
5346
+ sx: {
5347
+ fontFamily: TAB_STYLES.LABEL.FONT_FAMILY,
5348
+ fontWeight: TAB_STYLES.LABEL.FONT_WEIGHT,
5349
+ fontSize: TAB_STYLES.LABEL.FONT_SIZE,
5350
+ textTransform: TAB_STYLES.LABEL.TEXT_TRANSFORM,
5351
+ color: TAB_STYLES.LABEL.COLOR,
5352
+ '&.Mui-selected': {
5353
+ color: TAB_STYLES.LABEL.SELECTED_COLOR
5354
+ }
5355
+ }
5356
+ }), React.createElement(Tab, {
5357
+ label: "Sign Up",
5358
+ value: "signup",
5359
+ sx: {
5360
+ fontFamily: TAB_STYLES.LABEL.FONT_FAMILY,
5361
+ fontWeight: TAB_STYLES.LABEL.FONT_WEIGHT,
5362
+ fontSize: TAB_STYLES.LABEL.FONT_SIZE,
5363
+ textTransform: TAB_STYLES.LABEL.TEXT_TRANSFORM,
5364
+ color: TAB_STYLES.LABEL.COLOR,
5365
+ '&.Mui-selected': {
5366
+ color: TAB_STYLES.LABEL.SELECTED_COLOR
5367
+ }
5368
+ }
5369
+ })), activeTab === 'login' ? React.createElement(Formik, {
4878
5370
  initialValues: {
4879
5371
  email: '',
4880
5372
  password: ''
@@ -4946,8 +5438,6 @@ var LoginModal = function LoginModal(_ref) {
4946
5438
  return React.createElement(Form, {
4947
5439
  onSubmit: props.handleSubmit
4948
5440
  }, React.createElement("div", {
4949
- className: "modal-title"
4950
- }, "Login"), React.createElement("div", {
4951
5441
  className: "login-logo-container"
4952
5442
  }, React.createElement("img", {
4953
5443
  className: "login-logo-tff",
@@ -4988,19 +5478,20 @@ var LoginModal = function LoginModal(_ref) {
4988
5478
  }, React.createElement("span", {
4989
5479
  "aria-hidden": "true",
4990
5480
  onClick: onForgotPassword
4991
- }, "Forgot password?")), showSignUpButton && React.createElement("div", {
5481
+ }, "Forgot password?")), showSignUpButton && useCustomSignup && React.createElement("div", {
4992
5482
  className: "forgot-password"
4993
- }, onSignup !== _identity ? React.createElement("span", {
5483
+ }, React.createElement("span", {
4994
5484
  "aria-hidden": "true",
4995
5485
  onClick: onSignup,
4996
5486
  style: {
4997
5487
  cursor: 'pointer'
4998
5488
  }
4999
- }, "Sign up") : React.createElement("a", {
5000
- href: registerUrl,
5001
- target: "_blank",
5002
- rel: "noopener noreferrer"
5003
5489
  }, "Sign up")), showPoweredByImage ? React.createElement(PoweredBy, null) : null));
5490
+ }) : React.createElement(SignUpForm, {
5491
+ onSignUpSuccess: onLogin,
5492
+ onGetProfileDataSuccess: onGetProfileDataSuccess,
5493
+ onGetProfileDataError: onGetProfileDataError,
5494
+ logo: logo
5004
5495
  }))));
5005
5496
  };
5006
5497
 
@@ -6330,7 +6821,7 @@ var BillingInfoContainer = /*#__PURE__*/React.memo(function (_ref6) {
6330
6821
  enableTimer = _ref6$enableTimer === void 0 ? false : _ref6$enableTimer,
6331
6822
  logo = _ref6.logo,
6332
6823
  _ref6$showForgotPassw = _ref6.showForgotPasswordButton,
6333
- showForgotPasswordButton = _ref6$showForgotPassw === void 0 ? false : _ref6$showForgotPassw,
6824
+ showForgotPasswordButton = _ref6$showForgotPassw === void 0 ? true : _ref6$showForgotPassw,
6334
6825
  _ref6$showSignUpButto = _ref6.showSignUpButton,
6335
6826
  showSignUpButton = _ref6$showSignUpButto === void 0 ? false : _ref6$showSignUpButto,
6336
6827
  _ref6$brandOptIn = _ref6.brandOptIn,
@@ -7846,7 +8337,12 @@ var ConfirmationContainer = function ConfirmationContainer(_ref) {
7846
8337
  _ref$showOrderDetails = _ref.showOrderDetailsBtn,
7847
8338
  showOrderDetailsBtn = _ref$showOrderDetails === void 0 ? false : _ref$showOrderDetails,
7848
8339
  _ref$onOrderDetailsCl = _ref.onOrderDetailsClick,
7849
- onOrderDetailsClick = _ref$onOrderDetailsCl === void 0 ? _identity : _ref$onOrderDetailsCl;
8340
+ onOrderDetailsClick = _ref$onOrderDetailsCl === void 0 ? _identity : _ref$onOrderDetailsCl,
8341
+ _ref$showProductImage = _ref.showProductImage,
8342
+ showProductImage = _ref$showProductImage === void 0 ? true : _ref$showProductImage,
8343
+ eventTitle = _ref.eventTitle,
8344
+ eventDate = _ref.eventDate,
8345
+ eventLocation = _ref.eventLocation;
7850
8346
  var inputRef = useRef(null);
7851
8347
  var _useState = useState(null),
7852
8348
  data = _useState[0],
@@ -7859,12 +8355,12 @@ var ConfirmationContainer = function ConfirmationContainer(_ref) {
7859
8355
  var eventId = (data == null ? void 0 : data.product_id) || '';
7860
8356
  useEffect(function () {
7861
8357
  _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
7862
- var _data$product_price, confirmationDataResponse, _data;
8358
+ var _data$product_price, confirmationDataResponse, _data, isLoggedIn;
7863
8359
  return _regeneratorRuntime().wrap(function _callee$(_context) {
7864
8360
  while (1) switch (_context.prev = _context.next) {
7865
8361
  case 0:
7866
8362
  if (!hash) {
7867
- _context.next = 16;
8363
+ _context.next = 17;
7868
8364
  break;
7869
8365
  }
7870
8366
  _context.prev = 1;
@@ -7897,17 +8393,24 @@ var ConfirmationContainer = function ConfirmationContainer(_ref) {
7897
8393
  }
7898
8394
  setData(_data);
7899
8395
  onGetConfirmationDataSuccess(confirmationDataResponse.data.attributes);
7900
- _context.next = 16;
8396
+ // Clear user_data for non-logged-in users after successful purchase
8397
+ if (isBrowser) {
8398
+ isLoggedIn = Boolean(getCookieByName('X-TF-ECOMMERCE'));
8399
+ if (!isLoggedIn) {
8400
+ window.localStorage.removeItem('user_data');
8401
+ }
8402
+ }
8403
+ _context.next = 17;
7901
8404
  break;
7902
- case 13:
7903
- _context.prev = 13;
8405
+ case 14:
8406
+ _context.prev = 14;
7904
8407
  _context.t0 = _context["catch"](1);
7905
8408
  if (axios.isAxiosError(_context.t0)) onGetConfirmationDataError(_context.t0);
7906
- case 16:
8409
+ case 17:
7907
8410
  case "end":
7908
8411
  return _context.stop();
7909
8412
  }
7910
- }, _callee, null, [[1, 13]]);
8413
+ }, _callee, null, [[1, 14]]);
7911
8414
  }))();
7912
8415
  }, [hash]);
7913
8416
  var _useState2 = useState(false),
@@ -7947,7 +8450,7 @@ var ConfirmationContainer = function ConfirmationContainer(_ref) {
7947
8450
  showCopyModal: showCopyModal
7948
8451
  }), data && React.createElement(React.Fragment, null, React.createElement("div", {
7949
8452
  className: "header-container"
7950
- }, React.createElement("div", {
8453
+ }, showProductImage && React.createElement("div", {
7951
8454
  className: "header-product-image"
7952
8455
  }, React.createElement("img", {
7953
8456
  alt: "",
@@ -7957,7 +8460,15 @@ var ConfirmationContainer = function ConfirmationContainer(_ref) {
7957
8460
  className: "header-product-text"
7958
8461
  }, React.createElement("p", {
7959
8462
  className: "title"
7960
- }, data.is_payment_plan ? paymentPlanConfirmationTitle : confirmationTitle), React.createElement("div", {
8463
+ }, data.is_payment_plan ? paymentPlanConfirmationTitle : confirmationTitle), (eventTitle || eventDate || eventLocation) && React.createElement("div", {
8464
+ className: "event-details"
8465
+ }, eventTitle && React.createElement("div", {
8466
+ className: "event-title"
8467
+ }, eventTitle), eventDate && React.createElement("div", {
8468
+ className: "event-date"
8469
+ }, eventDate), eventLocation && React.createElement("div", {
8470
+ className: "event-location"
8471
+ }, eventLocation)), React.createElement("div", {
7961
8472
  className: "share-message-section",
7962
8473
  dangerouslySetInnerHTML: data.custom_confirmation_page_text && data.custom_confirmation_page_text_full_replacement ? createMarkup(data.custom_confirmation_page_text) : undefined
7963
8474
  }, data.custom_confirmation_page_text && data.custom_confirmation_page_text_full_replacement ? undefined : React.createElement(React.Fragment, null, Boolean(data.is_payment_plan) && React.createElement(React.Fragment, null, React.createElement("span", {
@@ -8978,7 +9489,8 @@ var PreRegistrationComplete = function PreRegistrationComplete(_ref) {
8978
9489
  onLogin: function onLogin(res) {
8979
9490
  setShowModalLogin(false);
8980
9491
  onLoginSuccess(res);
8981
- }
9492
+ },
9493
+ showForgotPasswordButton: true
8982
9494
  }), !_isEmpty(error) && React.createElement(ConfirmModal, {
8983
9495
  hideCancelBtn: true,
8984
9496
  message: error.message,
@@ -9912,6 +10424,168 @@ var TicketsSection = function TicketsSection(_ref) {
9912
10424
  }));
9913
10425
  };
9914
10426
 
10427
+ /* eslint-disable @typescript-eslint/no-explicit-any */
10428
+ function decodeHTML$1(html) {
10429
+ var textArea = document.createElement('textarea');
10430
+ textArea.innerHTML = html;
10431
+ return textArea.value;
10432
+ }
10433
+ var TimeSlotTicketRow = function TimeSlotTicketRow(_ref) {
10434
+ var _availableTimeSlots$f;
10435
+ var ticketKey = _ref.ticketKey,
10436
+ ticket = _ref.ticket,
10437
+ availableTimeSlots = _ref.availableTimeSlots,
10438
+ selectedTickets = _ref.selectedTickets,
10439
+ selectedTimeSlots = _ref.selectedTimeSlots,
10440
+ handleTicketSelect = _ref.handleTicketSelect,
10441
+ handleTimeSlotSelect = _ref.handleTimeSlotSelect,
10442
+ priceSymbol = _ref.priceSymbol,
10443
+ isSoldOut = _ref.isSoldOut;
10444
+ var _useState = useState(false),
10445
+ visibleDescription = _useState[0],
10446
+ setVisibleDescription = _useState[1];
10447
+ var currentSelectedTimeKey = selectedTimeSlots[ticketKey] || '';
10448
+ var currentTicketInstance = (_availableTimeSlots$f = availableTimeSlots.find(function (slot) {
10449
+ return slot.timeKey === currentSelectedTimeKey;
10450
+ })) == null ? void 0 : _availableTimeSlots$f.ticketInstance;
10451
+ var currentSelectedQuantity = currentTicketInstance ? selectedTickets[currentTicketInstance.id] || 0 : 0;
10452
+ var maxCount = ticket.maxQuantity;
10453
+ var minCount = ticket.minQuantity;
10454
+ var multiplier = ticket.multiplier;
10455
+ var options = getTicketSelectOptions(maxCount, minCount, multiplier);
10456
+ var ticketPriceWithoutFees = priceSymbol + " " + (+ticket.cost).toFixed(2);
10457
+ var ticketPriceWithFees = priceSymbol + " " + (+ticket.basePrice).toFixed(2);
10458
+ var ticketOldPriceWithFees = priceSymbol + " " + (+ticket.oldBasePrice).toFixed(2);
10459
+ var ticketOldPriceWithoutFees = priceSymbol + " " + (+ticket.oldCost).toFixed(2);
10460
+ var ticketIsDiscounted = false;
10461
+ if (ticket.oldPrice && !isSoldOut && ticket.oldPrice !== ticket.price) {
10462
+ ticketIsDiscounted = true;
10463
+ }
10464
+ var ticketIsFree = +ticket.price === 0;
10465
+ var discountTicketPriceElem = CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH || !ticket.feeIncluded ? ticketOldPriceWithoutFees : ticketOldPriceWithFees;
10466
+ var ticketPriceElem = isSoldOut ? 'SOLD OUT' : ticketIsFree ? 'FREE' : CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH || !ticket.feeIncluded ? ticketPriceWithoutFees : ticketPriceWithFees;
10467
+ var handleTimeChange = function handleTimeChange(event) {
10468
+ var selectedTimeKey = event.target.value;
10469
+ var selectedOption = availableTimeSlots.find(function (slot) {
10470
+ return slot.timeKey === selectedTimeKey;
10471
+ });
10472
+ if (selectedOption) {
10473
+ handleTimeSlotSelect(ticketKey, selectedOption.timeKey, selectedOption.ticketInstance);
10474
+ }
10475
+ };
10476
+ var handleQuantityChange = function handleQuantityChange(event) {
10477
+ var value = event.target.value;
10478
+ // Only allow quantity selection if a time slot is selected
10479
+ if (!currentSelectedTimeKey && value > 0) {
10480
+ return;
10481
+ }
10482
+ if (currentTicketInstance) {
10483
+ handleTicketSelect(ticketKey, value, currentTicketInstance);
10484
+ }
10485
+ };
10486
+ var handleDescriptionToggle = function handleDescriptionToggle() {
10487
+ setVisibleDescription(function (current) {
10488
+ return !current;
10489
+ });
10490
+ };
10491
+ return React.createElement(React.Fragment, null, React.createElement("div", {
10492
+ className: "event-detail__tier " + (isSoldOut ? 'disabled' : ''),
10493
+ id: ticketKey
10494
+ }, React.createElement("div", {
10495
+ className: "event-detail__tier-name"
10496
+ }, ticket.displayName || ticket.name, ticket.descriptionRich && React.createElement(React.Fragment, null, React.createElement("span", {
10497
+ "aria-hidden": true,
10498
+ className: "info-icon",
10499
+ onClick: handleDescriptionToggle,
10500
+ "data-tooltip-id": "tooltip-" + ticketKey,
10501
+ "data-tooltip-content": "View ticket info",
10502
+ style: {
10503
+ marginLeft: 8,
10504
+ cursor: 'pointer',
10505
+ display: 'flex'
10506
+ }
10507
+ }, React.createElement(InfoIcon, null)), React.createElement(Tooltip, {
10508
+ id: "tooltip-" + ticketKey,
10509
+ place: "top"
10510
+ }, ticket.description || 'No description available'))), React.createElement("div", {
10511
+ className: "event-tickets-container"
10512
+ }, React.createElement("div", {
10513
+ className: "event-detail__tier-price"
10514
+ }, ticketIsDiscounted && React.createElement("p", {
10515
+ className: "old-price"
10516
+ }, discountTicketPriceElem), React.createElement("p", {
10517
+ className: isSoldOut ? 'sold-out' : ''
10518
+ }, ticketPriceElem), !isSoldOut && !ticketIsFree && React.createElement("p", {
10519
+ className: "fees"
10520
+ }, CONFIGS.FEES_STYLE === FEES_STYLES.TRADITIONAL && (ticket.feeIncluded ? '(incl. Fees)' : '(excl. Fees)'), CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH && "(" + ticketPriceWithFees + " with fees)")), !isSoldOut && React.createElement("div", {
10521
+ className: "event-detail__tier-state time-slot-selectors-container"
10522
+ }, React.createElement(Box, {
10523
+ sx: {
10524
+ display: 'flex',
10525
+ flexDirection: 'row',
10526
+ alignItems: 'center',
10527
+ justifyContent: 'space-between',
10528
+ gap: 2,
10529
+ marginTop: 2
10530
+ }
10531
+ }, React.createElement(FormControl$1, null, React.createElement(Select, {
10532
+ sx: {
10533
+ borderRadius: 0,
10534
+ minWidth: 120
10535
+ },
10536
+ value: currentSelectedTimeKey,
10537
+ onChange: handleTimeChange,
10538
+ displayEmpty: true,
10539
+ inputProps: {
10540
+ 'aria-label': 'Select time slot'
10541
+ },
10542
+ MenuProps: {
10543
+ PaperProps: {
10544
+ className: 'get-tickets-paper'
10545
+ }
10546
+ }
10547
+ }, React.createElement(MenuItem, {
10548
+ value: "",
10549
+ disabled: true
10550
+ }, "Time"), availableTimeSlots.map(function (slot, index) {
10551
+ return React.createElement(MenuItem, {
10552
+ key: index,
10553
+ value: slot.timeKey
10554
+ }, moment(slot.ticketInstance.slotStartDate).format('hh:mm A'));
10555
+ }))), React.createElement(FormControl$1, null, React.createElement(Select, {
10556
+ sx: {
10557
+ borderRadius: 0,
10558
+ minWidth: 60
10559
+ },
10560
+ value: currentSelectedQuantity,
10561
+ onChange: handleQuantityChange,
10562
+ displayEmpty: true,
10563
+ disabled: !currentSelectedTimeKey,
10564
+ inputProps: {
10565
+ 'aria-label': 'Select quantity'
10566
+ },
10567
+ MenuProps: {
10568
+ PaperProps: {
10569
+ sx: {
10570
+ maxHeight: 150
10571
+ },
10572
+ className: 'get-tickets-paper'
10573
+ }
10574
+ }
10575
+ }, options.map(function (option, index) {
10576
+ return React.createElement(MenuItem, {
10577
+ key: index,
10578
+ value: option.value
10579
+ }, option.value);
10580
+ })))))), visibleDescription && ticket.descriptionRich && React.createElement("div", {
10581
+ className: "ticket-description"
10582
+ }, React.createElement("div", {
10583
+ dangerouslySetInnerHTML: {
10584
+ __html: decodeHTML$1(ticket.descriptionRich)
10585
+ }
10586
+ }))));
10587
+ };
10588
+
9915
10589
  var TimeSlotsSection = function TimeSlotsSection(_ref) {
9916
10590
  var event = _ref.event,
9917
10591
  availableDates = _ref.availableDates,
@@ -9924,42 +10598,44 @@ var TimeSlotsSection = function TimeSlotsSection(_ref) {
9924
10598
  sortBySoldOut = _ref.sortBySoldOut,
9925
10599
  hideTicketsHeader = _ref.hideTicketsHeader,
9926
10600
  ticketsHeaderComponent = _ref.ticketsHeaderComponent,
9927
- showGroupNameBlock = _ref.showGroupNameBlock,
9928
- currencySymbol = _ref.currencySymbol,
9929
- isSeatMapAllowed = _ref.isSeatMapAllowed;
10601
+ currencySymbol = _ref.currencySymbol;
9930
10602
  var _useState = useState(false),
9931
10603
  loading = _useState[0],
9932
10604
  setLoading = _useState[1];
10605
+ var _useState2 = useState({}),
10606
+ selectedTimeSlots = _useState2[0],
10607
+ setSelectedTimeSlots = _useState2[1];
9933
10608
  var handleDateChange = /*#__PURE__*/function () {
9934
10609
  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(date) {
9935
10610
  return _regeneratorRuntime().wrap(function _callee$(_context) {
9936
10611
  while (1) switch (_context.prev = _context.next) {
9937
10612
  case 0:
9938
10613
  setSelectedDate(date);
10614
+ setSelectedTimeSlots({}); // Reset time slot selections when date changes
9939
10615
  if (!date) {
9940
- _context.next = 14;
10616
+ _context.next = 15;
9941
10617
  break;
9942
10618
  }
9943
10619
  setLoading(true);
9944
- _context.prev = 3;
9945
- _context.next = 6;
10620
+ _context.prev = 4;
10621
+ _context.next = 7;
9946
10622
  return getTimeSlots(date);
9947
- case 6:
9948
- _context.next = 11;
10623
+ case 7:
10624
+ _context.next = 12;
9949
10625
  break;
9950
- case 8:
9951
- _context.prev = 8;
9952
- _context.t0 = _context["catch"](3);
10626
+ case 9:
10627
+ _context.prev = 9;
10628
+ _context.t0 = _context["catch"](4);
9953
10629
  console.error('Error fetching time slots:', _context.t0);
9954
- case 11:
9955
- _context.prev = 11;
10630
+ case 12:
10631
+ _context.prev = 12;
9956
10632
  setLoading(false);
9957
- return _context.finish(11);
9958
- case 14:
10633
+ return _context.finish(12);
10634
+ case 15:
9959
10635
  case "end":
9960
10636
  return _context.stop();
9961
10637
  }
9962
- }, _callee, null, [[3, 8, 11, 14]]);
10638
+ }, _callee, null, [[4, 9, 12, 15]]);
9963
10639
  }));
9964
10640
  return function handleDateChange(_x) {
9965
10641
  return _ref2.apply(this, arguments);
@@ -9969,6 +10645,64 @@ var TimeSlotsSection = function TimeSlotsSection(_ref) {
9969
10645
  var formattedDate = moment(date).format('YYYY-MM-DD');
9970
10646
  return !availableDates.includes(formattedDate);
9971
10647
  };
10648
+ // Group tickets by unique ticket type using displayName + price
10649
+ var uniqueTickets = useMemo(function () {
10650
+ var ticketMap = {};
10651
+ // Iterate through all time slots
10652
+ _map(timeSlotGroups, function (tickets, timeKey) {
10653
+ tickets.forEach(function (ticket) {
10654
+ // Use displayName + price as the unique identifier for ticket types
10655
+ // This handles cases where multiple ticket types share the same optionName
10656
+ var ticketKey = (ticket.displayName || ticket.name) + "_" + ticket.price;
10657
+ if (!ticketMap[ticketKey]) {
10658
+ ticketMap[ticketKey] = {
10659
+ ticket: _extends({}, ticket),
10660
+ availableTimeSlots: []
10661
+ };
10662
+ }
10663
+ // Store both the time key and the ticket instance for this slot
10664
+ if (!ticketMap[ticketKey].availableTimeSlots.find(function (slot) {
10665
+ return slot.timeKey === timeKey;
10666
+ })) {
10667
+ ticketMap[ticketKey].availableTimeSlots.push({
10668
+ timeKey: timeKey,
10669
+ ticketInstance: ticket
10670
+ });
10671
+ }
10672
+ });
10673
+ });
10674
+ // Convert to array and sort
10675
+ var ticketsArray = Object.values(ticketMap);
10676
+ return sortBySoldOut ? _sortBy(_sortBy(ticketsArray, function (t) {
10677
+ return t.ticket.sortOrder;
10678
+ }), function (t) {
10679
+ return t.ticket.soldOut;
10680
+ }) : _sortBy(ticketsArray, function (t) {
10681
+ return t.ticket.sortOrder;
10682
+ });
10683
+ }, [timeSlotGroups, sortBySoldOut]);
10684
+ var handleTimeSlotSelect = function handleTimeSlotSelect(ticketKey, timeKey, ticketInstance) {
10685
+ setSelectedTimeSlots(function (prev) {
10686
+ var _extends2;
10687
+ return _extends({}, prev, (_extends2 = {}, _extends2[ticketKey] = timeKey, _extends2));
10688
+ });
10689
+ // Reset quantity when time slot changes
10690
+ if (selectedTickets[ticketInstance.id]) {
10691
+ handleTicketSelect(ticketInstance.id, 0);
10692
+ }
10693
+ };
10694
+ var handleTicketSelectWithTimeSlot = function handleTicketSelectWithTimeSlot(ticketKey, quantity, ticketInstance) {
10695
+ var timeSlot = selectedTimeSlots[ticketKey];
10696
+ if (!timeSlot && quantity > 0) {
10697
+ return; // Don't allow quantity selection without time slot
10698
+ }
10699
+
10700
+ if (ticketInstance) {
10701
+ handleTicketSelect(ticketInstance.id, quantity);
10702
+ }
10703
+ };
10704
+ var symbol = _get(event, 'currency.symbol');
10705
+ var priceSymbol = currencySymbol || symbol;
9972
10706
  return React.createElement(Box$1, {
9973
10707
  sx: {
9974
10708
  display: 'flex',
@@ -10000,30 +10734,25 @@ var TimeSlotsSection = function TimeSlotsSection(_ref) {
10000
10734
  marginTop: 2,
10001
10735
  width: '100%',
10002
10736
  display: 'flex',
10003
- flexDirection: 'column',
10004
- gap: 2
10737
+ flexDirection: 'column'
10005
10738
  }
10006
- }, _map(Object.keys(timeSlotGroups).sort(), function (timeKey) {
10007
- return React.createElement("div", {
10008
- key: timeKey,
10009
- className: "time-slot-block"
10010
- }, React.createElement("div", {
10011
- className: "time-slot-date"
10012
- }, moment(timeKey).format('hh:mm A')), React.createElement(TicketsSection, {
10013
- event: event,
10014
- ticketsList: timeSlotGroups[timeKey],
10015
- tableTickets: [],
10739
+ }, !hideTicketsHeader && ticketsHeaderComponent, uniqueTickets.map(function (_ref3) {
10740
+ var ticket = _ref3.ticket,
10741
+ availableTimeSlots = _ref3.availableTimeSlots;
10742
+ var ticketKey = (ticket.displayName || ticket.name) + "_" + ticket.price;
10743
+ var isSoldOut = ticket.sold_out || !(ticket.displayTicket || ticket.slotGroupId) || ticket.soldOut;
10744
+ return React.createElement(TimeSlotTicketRow, {
10745
+ key: ticketKey,
10746
+ ticketKey: ticketKey,
10747
+ ticket: ticket,
10748
+ availableTimeSlots: availableTimeSlots,
10016
10749
  selectedTickets: selectedTickets,
10017
- handleTicketSelect: handleTicketSelect,
10018
- sortBySoldOut: sortBySoldOut,
10019
- ticketsHeaderComponent: ticketsHeaderComponent,
10020
- tableTicketsHeaderComponent: null,
10021
- hideTableTicketsHeader: true,
10022
- hideTicketsHeader: hideTicketsHeader || _isEmpty(timeSlotGroups[timeKey]),
10023
- showGroupNameBlock: showGroupNameBlock,
10024
- currencySymbol: currencySymbol,
10025
- isSeatMapAllowed: isSeatMapAllowed
10026
- }));
10750
+ selectedTimeSlots: selectedTimeSlots,
10751
+ handleTicketSelect: handleTicketSelectWithTimeSlot,
10752
+ handleTimeSlotSelect: handleTimeSlotSelect,
10753
+ priceSymbol: priceSymbol,
10754
+ isSoldOut: isSoldOut
10755
+ });
10027
10756
  })));
10028
10757
  };
10029
10758
 
@@ -10900,7 +11629,8 @@ var TicketsContainer = function TicketsContainer(_ref) {
10900
11629
  onClick: handleLogout
10901
11630
  }, "Log out"))) : ''), showLoginModal ? React.createElement(LoginModal, {
10902
11631
  onClose: handleOnClose,
10903
- onLogin: handleOnLogin
11632
+ onLogin: handleOnLogin,
11633
+ showForgotPasswordButton: true
10904
11634
  }) : null), showPoweredByImage ? React.createElement(PoweredBy, null) : null, enableInfluencersSection && !hideTopInfluencers && influencers.length ? React.createElement("div", {
10905
11635
  className: "event-influencers"
10906
11636
  }, React.createElement("h3", null, React.createElement("span", null, "TOP"), " INFLUENCERS"), React.createElement("ol", {
@@ -11168,7 +11898,8 @@ var MyTicketsContainer = function MyTicketsContainer(_ref) {
11168
11898
  setIsLogged(true);
11169
11899
  },
11170
11900
  userExpired: userExpired,
11171
- logo: logo
11901
+ logo: logo,
11902
+ showForgotPasswordButton: true
11172
11903
  }) : null), data != null && (_data$orders = data.orders) != null && _data$orders.length ? React.createElement(React.Fragment, null, React.createElement("h2", null, "My Ticket Orders"), React.createElement(Autocomplete, {
11173
11904
  disablePortal: true,
11174
11905
  id: "combo-box-demo",
@@ -11221,7 +11952,8 @@ var MyTicketsContainer = function MyTicketsContainer(_ref) {
11221
11952
  setUserExpired(false);
11222
11953
  setIsLogged(true);
11223
11954
  },
11224
- userExpired: userExpired
11955
+ userExpired: userExpired,
11956
+ showForgotPasswordButton: true
11225
11957
  })));
11226
11958
  };
11227
11959