@eventlook/sdk 1.5.0-beta.6 → 1.5.0-beta.7
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.
- package/.claude/settings.local.json +2 -1
- package/.env.example +1 -0
- package/README.md +18 -16
- package/dist/cjs/{index-DvUR1fp8.js → index-BAfaeq84.js} +3230 -554
- package/dist/cjs/index-BAfaeq84.js.map +1 -0
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/{index.umd-6SU6nkkJ.js → index.umd-Bpwd9vUs.js} +9 -19
- package/dist/cjs/index.umd-Bpwd9vUs.js.map +1 -0
- package/dist/esm/{index-BlTqx0jm.js → index-CJ_gPli9.js} +3217 -540
- package/dist/esm/index-CJ_gPli9.js.map +1 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/{index.umd-Dn0hjh7E.js → index.umd-ewNTELOK.js} +9 -19
- package/dist/esm/index.umd-ewNTELOK.js.map +1 -0
- package/dist/types/components/hook-form/FormProvider.d.ts +2 -1
- package/dist/types/form/PaymentOverviewBox.d.ts +2 -0
- package/dist/types/form/PaymentOverviewDrawer.d.ts +10 -0
- package/dist/types/form/TicketForm.d.ts +1 -0
- package/dist/types/form/index.d.ts +2 -1
- package/dist/types/form/merchandise/MerchandiseSelection.d.ts +9 -0
- package/dist/types/form/merchandise/MerchandiseSlider.d.ts +10 -0
- package/dist/types/form/payment/PaymentOverviewCheckbox.d.ts +0 -4
- package/dist/types/form/product/ProductVariantsDialog.d.ts +2 -1
- package/dist/types/form/services/index.d.ts +7 -0
- package/dist/types/form/style.d.ts +1 -0
- package/dist/types/form/tickets/ReleaseDescription.d.ts +10 -0
- package/dist/types/form/tickets/ReleaseWithMerchandise.d.ts +12 -0
- package/dist/types/form/tickets/TicketQuantityControl.d.ts +13 -0
- package/dist/types/form/tickets/TicketSelectionMobile.d.ts +17 -0
- package/dist/types/hooks/useScrollToFirstError.d.ts +4 -0
- package/dist/types/locales/cs.d.ts +22 -0
- package/dist/types/locales/en.d.ts +22 -0
- package/dist/types/locales/es.d.ts +22 -0
- package/dist/types/locales/pl.d.ts +22 -0
- package/dist/types/locales/sk.d.ts +22 -0
- package/dist/types/locales/uk.d.ts +22 -0
- package/dist/types/utils/data/global.d.ts +1 -0
- package/package.json +10 -4
- package/rollup.config.mjs +7 -12
- package/src/components/hook-form/FormProvider.tsx +5 -2
- package/src/form/ChildEventDialog.tsx +3 -3
- package/src/form/ContactPerson.tsx +1 -1
- package/src/form/PaymentOverviewBox.tsx +96 -123
- package/src/form/PaymentOverviewDrawer.tsx +446 -0
- package/src/form/PaymentPending.tsx +19 -4
- package/src/form/ReleaseWithMerchandise.tsx +4 -4
- package/src/form/Shipping.tsx +91 -74
- package/src/form/TicketForm.tsx +144 -41
- package/src/form/index.tsx +3 -1
- package/src/form/merchandise/MerchandiseSelection.tsx +24 -0
- package/src/form/merchandise/MerchandiseSlider.tsx +62 -0
- package/src/form/payment/FeeBox.tsx +4 -31
- package/src/form/payment/PaymentOverviewCheckbox.tsx +57 -56
- package/src/form/product/ProductCard.tsx +255 -59
- package/src/form/product/ProductVariantsDialog.tsx +271 -141
- package/src/form/services/index.tsx +263 -0
- package/src/form/style.ts +16 -4
- package/src/form/tickets/ReleaseDescription.tsx +46 -0
- package/src/form/tickets/ReleaseWithMerchandise.tsx +231 -0
- package/src/form/tickets/TicketQuantityControl.tsx +100 -0
- package/src/form/{TicketSelection.tsx → tickets/TicketSelection.tsx} +24 -128
- package/src/form/{TicketSelectionMap.tsx → tickets/TicketSelectionMap.tsx} +9 -1
- package/src/form/tickets/TicketSelectionMobile.tsx +177 -0
- package/src/form/{TicketWithMerchandiseSelection.tsx → tickets/TicketWithMerchandiseSelection.tsx} +3 -7
- package/src/hooks/useScrollToFirstError.ts +99 -0
- package/src/locales/cs.tsx +25 -3
- package/src/locales/en.tsx +23 -1
- package/src/locales/es.tsx +23 -1
- package/src/locales/pl.tsx +23 -1
- package/src/locales/sk.tsx +24 -2
- package/src/locales/uk.tsx +23 -1
- package/src/utils/data/global.ts +1 -0
- package/tsconfig.json +1 -1
- package/README +0 -1
- package/dist/cjs/index-DvUR1fp8.js.map +0 -1
- package/dist/cjs/index.umd-6SU6nkkJ.js.map +0 -1
- package/dist/esm/index-BlTqx0jm.js.map +0 -1
- package/dist/esm/index.umd-Dn0hjh7E.js.map +0 -1
- /package/dist/types/form/{TicketSelection.d.ts → tickets/TicketSelection.d.ts} +0 -0
- /package/dist/types/form/{TicketSelectionMap.d.ts → tickets/TicketSelectionMap.d.ts} +0 -0
- /package/dist/types/form/{TicketWithMerchandiseSelection.d.ts → tickets/TicketWithMerchandiseSelection.d.ts} +0 -0
package/src/form/Shipping.tsx
CHANGED
|
@@ -46,7 +46,6 @@ const Shipping: React.FC<Props> = ({ event }) => {
|
|
|
46
46
|
[products]
|
|
47
47
|
);
|
|
48
48
|
const shippingMethodId = watch('shipping.shippingMethodId');
|
|
49
|
-
const branchId = watch('shipping.branchId');
|
|
50
49
|
const [displayBranchName, setDisplayBranchName] = useState<string | null>(null);
|
|
51
50
|
const [firstRender, setFirstRender] = useState<boolean>(true);
|
|
52
51
|
const filteredShippingMethods = useMemo(
|
|
@@ -83,9 +82,21 @@ const Shipping: React.FC<Props> = ({ event }) => {
|
|
|
83
82
|
}
|
|
84
83
|
};
|
|
85
84
|
|
|
85
|
+
const openPacketaWidget = () => {
|
|
86
|
+
const interval = setInterval(() => {
|
|
87
|
+
if (window.Packeta && window.Packeta.Widget) {
|
|
88
|
+
clearInterval(interval);
|
|
89
|
+
window.Packeta.Widget.pick(options?.packetaApiKey, onSelectBranch, {
|
|
90
|
+
language: lang,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}, 100);
|
|
94
|
+
};
|
|
95
|
+
|
|
86
96
|
const handleChangeBranch = () => {
|
|
87
97
|
setValue('shipping.branchId', null);
|
|
88
98
|
setDisplayBranchName(null);
|
|
99
|
+
openPacketaWidget();
|
|
89
100
|
};
|
|
90
101
|
|
|
91
102
|
useEffect(() => {
|
|
@@ -103,25 +114,14 @@ const Shipping: React.FC<Props> = ({ event }) => {
|
|
|
103
114
|
if (selectedShippingMethod) {
|
|
104
115
|
setValue('shipping.price', selectedShippingMethod.price);
|
|
105
116
|
|
|
106
|
-
if (selectedShippingMethod.type
|
|
107
|
-
if (!branchId) {
|
|
108
|
-
const interval = setInterval(() => {
|
|
109
|
-
if (window.Packeta && window.Packeta.Widget) {
|
|
110
|
-
clearInterval(interval);
|
|
111
|
-
window.Packeta.Widget.pick(options?.packetaApiKey, onSelectBranch, {
|
|
112
|
-
language: lang,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
}, 100);
|
|
116
|
-
}
|
|
117
|
-
} else {
|
|
117
|
+
if (selectedShippingMethod.type !== ShippingTypes.PACKETA) {
|
|
118
118
|
setValue('shipping.branchId', null);
|
|
119
119
|
setDisplayBranchName(null);
|
|
120
120
|
}
|
|
121
121
|
} else {
|
|
122
122
|
setValue('shipping.price', 0);
|
|
123
123
|
}
|
|
124
|
-
}, [shippingMethodId, shippingMethods
|
|
124
|
+
}, [shippingMethodId, shippingMethods]);
|
|
125
125
|
|
|
126
126
|
return (
|
|
127
127
|
<>
|
|
@@ -136,36 +136,54 @@ const Shipping: React.FC<Props> = ({ event }) => {
|
|
|
136
136
|
{t('event.tickets.stepper.5.error')}
|
|
137
137
|
</Typography>
|
|
138
138
|
) : (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
<
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
139
|
+
<>
|
|
140
|
+
<Controller
|
|
141
|
+
name="shipping.shippingMethodId"
|
|
142
|
+
control={control}
|
|
143
|
+
render={({ field, fieldState: { error } }) => (
|
|
144
|
+
<FormControl component="fieldset" sx={{ width: '100%' }}>
|
|
145
|
+
<RadioGroup
|
|
146
|
+
{...field}
|
|
147
|
+
onChange={(event, value) => {
|
|
148
|
+
field.onChange(event);
|
|
149
|
+
const selectedShippingMethod = filteredShippingMethods.find(
|
|
150
|
+
(method) => method.id === Number(value)
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
if (selectedShippingMethod?.type === ShippingTypes.PACKETA) {
|
|
154
|
+
openPacketaWidget();
|
|
155
|
+
}
|
|
156
|
+
}}
|
|
157
|
+
>
|
|
158
|
+
{filteredShippingMethods.map((shippingMethod) => (
|
|
159
|
+
<ShippingMethodItem
|
|
160
|
+
key={shippingMethod.id}
|
|
161
|
+
active={Number(shippingMethodId) === shippingMethod.id}
|
|
162
|
+
hasError={!!error}
|
|
163
|
+
sx={{
|
|
164
|
+
'& .MuiFormControlLabel-labelPlacementEnd': {
|
|
165
|
+
mr: 0,
|
|
166
|
+
width: '100%',
|
|
167
|
+
},
|
|
168
|
+
}}
|
|
169
|
+
>
|
|
170
|
+
<FormControlLabel
|
|
171
|
+
value={shippingMethod.id}
|
|
172
|
+
control={<Radio />}
|
|
173
|
+
label={
|
|
174
|
+
<Stack
|
|
175
|
+
direction="row"
|
|
176
|
+
justifyContent="space-between"
|
|
177
|
+
alignItems="center"
|
|
178
|
+
width="100%"
|
|
179
|
+
>
|
|
180
|
+
<Stack direction="column">
|
|
181
|
+
<Stack direction="row" alignItems="center" spacing={1}>
|
|
182
|
+
<Typography sx={{ lineHeight: 1.2 }}>
|
|
183
|
+
{t(`shipping_method.types.${shippingMethod.type}`)}
|
|
184
|
+
</Typography>
|
|
185
|
+
{paymentImages[shippingMethod.type]}
|
|
186
|
+
</Stack>
|
|
169
187
|
{displayBranchName &&
|
|
170
188
|
shippingMethod.type === ShippingTypes.PACKETA &&
|
|
171
189
|
shippingMethod.id === Number(shippingMethodId) && (
|
|
@@ -173,37 +191,35 @@ const Shipping: React.FC<Props> = ({ event }) => {
|
|
|
173
191
|
{displayBranchName}
|
|
174
192
|
</Typography>
|
|
175
193
|
)}
|
|
176
|
-
</
|
|
177
|
-
{
|
|
194
|
+
</Stack>
|
|
195
|
+
{shippingMethod.type === ShippingTypes.PACKETA &&
|
|
196
|
+
shippingMethod.id === Number(shippingMethodId) && (
|
|
197
|
+
<Box>
|
|
198
|
+
<Button
|
|
199
|
+
onClick={handleChangeBranch}
|
|
200
|
+
variant="outlined"
|
|
201
|
+
size="small"
|
|
202
|
+
sx={{ px: 1, whiteSpace: 'nowrap' }}
|
|
203
|
+
>
|
|
204
|
+
{t('event.tickets.shipping.choose_address')}
|
|
205
|
+
</Button>
|
|
206
|
+
</Box>
|
|
207
|
+
)}
|
|
178
208
|
</Stack>
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
sx={{
|
|
195
|
-
'&:not(:last-of-type)': {
|
|
196
|
-
mb: 0,
|
|
197
|
-
},
|
|
198
|
-
'& .MuiFormControlLabel-label': {
|
|
199
|
-
width: '100%',
|
|
200
|
-
mr: 0,
|
|
201
|
-
},
|
|
202
|
-
}}
|
|
203
|
-
/>
|
|
204
|
-
</ShippingMethodItem>
|
|
205
|
-
))}
|
|
206
|
-
</RadioGroup>
|
|
209
|
+
}
|
|
210
|
+
sx={{
|
|
211
|
+
'&:not(:last-of-type)': {
|
|
212
|
+
mb: 0,
|
|
213
|
+
},
|
|
214
|
+
'& .MuiFormControlLabel-label': {
|
|
215
|
+
width: '100%',
|
|
216
|
+
mr: 0,
|
|
217
|
+
},
|
|
218
|
+
}}
|
|
219
|
+
/>
|
|
220
|
+
</ShippingMethodItem>
|
|
221
|
+
))}
|
|
222
|
+
</RadioGroup>
|
|
207
223
|
|
|
208
224
|
{!!error && (
|
|
209
225
|
<FormHelperText error={!!error} sx={{ mx: 0 }}>
|
|
@@ -213,6 +229,7 @@ const Shipping: React.FC<Props> = ({ event }) => {
|
|
|
213
229
|
</FormControl>
|
|
214
230
|
)}
|
|
215
231
|
/>
|
|
232
|
+
</>
|
|
216
233
|
)}
|
|
217
234
|
</>
|
|
218
235
|
)}
|
package/src/form/TicketForm.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import PaymentSuccess from '@form/PaymentSuccess';
|
|
|
3
3
|
import FormProvider, { RHFCheckbox } from '@components/hook-form';
|
|
4
4
|
import {
|
|
5
5
|
Box,
|
|
6
|
+
Divider,
|
|
6
7
|
Grid,
|
|
7
8
|
Link,
|
|
8
9
|
LinkProps,
|
|
@@ -14,7 +15,7 @@ import {
|
|
|
14
15
|
Typography,
|
|
15
16
|
} from '@mui/material';
|
|
16
17
|
import dayjs from 'dayjs';
|
|
17
|
-
import TicketSelection from '@form/TicketSelection';
|
|
18
|
+
import TicketSelection from '@form/tickets/TicketSelection';
|
|
18
19
|
import ContactPerson from '@form/ContactPerson';
|
|
19
20
|
import Payment from '@form/Payment';
|
|
20
21
|
import EmailConfirmation from '@form/EmailConfirmation';
|
|
@@ -44,18 +45,22 @@ import {
|
|
|
44
45
|
import ReleaseCountdown from '@form/ReleaseCountdown';
|
|
45
46
|
import { cloneObject } from '@utils/global';
|
|
46
47
|
import PaymentPending from '@form/PaymentPending';
|
|
47
|
-
import MerchandiseSelection from '@form/MerchandiseSelection';
|
|
48
|
-
import TicketWithMerchandiseSelection from '@form/TicketWithMerchandiseSelection';
|
|
48
|
+
import MerchandiseSelection from '@form/merchandise/MerchandiseSelection';
|
|
49
|
+
import TicketWithMerchandiseSelection from '@form/tickets/TicketWithMerchandiseSelection';
|
|
49
50
|
import useActiveEventProducts from '@hooks/data/useActiveEventProducts';
|
|
50
51
|
import Shipping from '@form/Shipping';
|
|
51
52
|
import useErrors from '@hooks/useErrors';
|
|
52
53
|
import { EventType } from '@utils/data/event';
|
|
53
54
|
import TimeslotSelection from '@form/TimeslotSelection';
|
|
54
55
|
import useGlobal from '@hooks/useGlobal';
|
|
56
|
+
import useScrollToFirstError from '@hooks/useScrollToFirstError';
|
|
55
57
|
import { Trans } from '@components/Trans';
|
|
56
|
-
import { EVENTLOOK_ORDER_FORM_ID } from '@utils/data/global';
|
|
58
|
+
import { EVENTLOOK_ORDER_FORM_ID, EVENTLOOK_ORDER_FORM_CONTAINER_ID } from '@utils/data/global';
|
|
57
59
|
import ChildEventSection from './ChildEvents';
|
|
58
|
-
import TicketSelectionMap from '@form/TicketSelectionMap';
|
|
60
|
+
import TicketSelectionMap from '@form/tickets/TicketSelectionMap';
|
|
61
|
+
import PaymentOverviewDrawer from './PaymentOverviewDrawer';
|
|
62
|
+
import { getPlaceAsString } from '@utils/place';
|
|
63
|
+
import Services from '@form/services';
|
|
59
64
|
|
|
60
65
|
interface Props {
|
|
61
66
|
event: IEvent;
|
|
@@ -63,14 +68,33 @@ interface Props {
|
|
|
63
68
|
selectedReleaseId?: number;
|
|
64
69
|
isIframe?: boolean;
|
|
65
70
|
isInline?: boolean;
|
|
71
|
+
headerSlot?: React.ReactNode;
|
|
66
72
|
}
|
|
67
73
|
|
|
74
|
+
const getCartUniqueItemCount = (formValues: ITicketForm) => {
|
|
75
|
+
const flatTickets = Object.values(formValues.tickets ?? {}).flat();
|
|
76
|
+
const ticketsCount = flatTickets.reduce(
|
|
77
|
+
(sum, ticket) => sum + (Number(ticket.quantity) > 0 ? 1 : 0),
|
|
78
|
+
0
|
|
79
|
+
);
|
|
80
|
+
const ticketsWithProductsCount = flatTickets.reduce(
|
|
81
|
+
(sum, ticket) => sum + ((ticket.products?.length ?? 0) > 0 ? 1 : 0),
|
|
82
|
+
0
|
|
83
|
+
);
|
|
84
|
+
const productsCount = Object.values(formValues.products ?? {})
|
|
85
|
+
.flat()
|
|
86
|
+
.reduce((sum, product) => sum + (Number(product.quantity) || 0), 0);
|
|
87
|
+
|
|
88
|
+
return ticketsCount + ticketsWithProductsCount + productsCount;
|
|
89
|
+
};
|
|
90
|
+
|
|
68
91
|
const TicketForm: React.FC<Props> = ({
|
|
69
92
|
event,
|
|
70
93
|
hasGopayIdSsr,
|
|
71
94
|
selectedReleaseId,
|
|
72
95
|
isIframe,
|
|
73
96
|
isInline,
|
|
97
|
+
headerSlot,
|
|
74
98
|
}) => {
|
|
75
99
|
const { t, setGlobal, callbacks, links, user, options, showSnackbar, content, seatingIframeUrl } =
|
|
76
100
|
useGlobal();
|
|
@@ -80,6 +104,7 @@ const TicketForm: React.FC<Props> = ({
|
|
|
80
104
|
const [hasGopayId, setHasGopayId] = useState<boolean>(hasGopayIdSsr);
|
|
81
105
|
const [isPaying, setIsPaying] = useState<boolean>(false);
|
|
82
106
|
const [formStep, setFormStep] = useState<number>(1);
|
|
107
|
+
const [isPaymentOverviewDrawerOpen, setIsPaymentOverviewDrawerOpen] = useState<boolean>(false);
|
|
83
108
|
const [showReleaseDate, setShowReleaseDate] = useState(
|
|
84
109
|
dayjs(event.releaseDate).diff(dayjs()) > 0
|
|
85
110
|
);
|
|
@@ -88,6 +113,8 @@ const TicketForm: React.FC<Props> = ({
|
|
|
88
113
|
const hasFiredViewCart = useRef(false);
|
|
89
114
|
const hasFiredBeginCheckout = useRef(false);
|
|
90
115
|
const hasFiredPaymentMethod = useRef(false);
|
|
116
|
+
const termsAndConditionsRef = useRef<HTMLDivElement | null>(null);
|
|
117
|
+
|
|
91
118
|
const item: IEcommerce = {
|
|
92
119
|
currency: event.currency,
|
|
93
120
|
items: [
|
|
@@ -274,11 +301,36 @@ const TicketForm: React.FC<Props> = ({
|
|
|
274
301
|
// }
|
|
275
302
|
// return true;
|
|
276
303
|
// }),
|
|
277
|
-
shipping: Yup.object()
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
304
|
+
shipping: Yup.object()
|
|
305
|
+
.shape({
|
|
306
|
+
shippingMethodId: Yup.number().nullable(),
|
|
307
|
+
branchId: Yup.string().nullable(),
|
|
308
|
+
price: Yup.number(),
|
|
309
|
+
})
|
|
310
|
+
.test('shipping-method-required', t('form.validation.required'), function (value) {
|
|
311
|
+
if (!event.hasMerchandise) {
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const formValues = this.parent as ITicketForm;
|
|
316
|
+
const hasProducts = Object.values(formValues.products ?? {}).some((arr) => arr.length > 0);
|
|
317
|
+
const allTickets = Object.values(formValues.tickets ?? {}).flat();
|
|
318
|
+
const hasTicketProducts = allTickets.some((ticket) => (ticket.products?.length ?? 0) > 0);
|
|
319
|
+
const requiresShipping = hasProducts || hasTicketProducts;
|
|
320
|
+
|
|
321
|
+
if (!requiresShipping) {
|
|
322
|
+
return true;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (value?.shippingMethodId !== null && value?.shippingMethodId !== undefined) {
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return this.createError({
|
|
330
|
+
path: 'shipping.shippingMethodId',
|
|
331
|
+
message: t('form.validation.required'),
|
|
332
|
+
});
|
|
333
|
+
}),
|
|
282
334
|
paymentMethodId: Yup.number().nullable().required(t('form.validation.required')),
|
|
283
335
|
paymentMethodOptionId: Yup.number().nullable(),
|
|
284
336
|
termsAndConditions: Yup.boolean().isTrue(t('form.validation.terms_and_conditions')),
|
|
@@ -306,15 +358,11 @@ const TicketForm: React.FC<Props> = ({
|
|
|
306
358
|
defaultValues,
|
|
307
359
|
});
|
|
308
360
|
const values = methods.watch();
|
|
361
|
+
const cartItemCount = getCartUniqueItemCount(values);
|
|
362
|
+
const onInvalid = useScrollToFirstError(methods);
|
|
309
363
|
|
|
310
364
|
const onSubmit = async (values: ITicketForm) => {
|
|
311
|
-
|
|
312
|
-
if (
|
|
313
|
-
allTickets.length === 1 &&
|
|
314
|
-
!allTickets[0].releaseId &&
|
|
315
|
-
!allTickets[0].quantity &&
|
|
316
|
-
!values.products.length
|
|
317
|
-
) {
|
|
365
|
+
if (cartItemCount <= 0) {
|
|
318
366
|
showSnackbar(t('form.validation.count_tickets_or_products'), {
|
|
319
367
|
variant: 'error',
|
|
320
368
|
});
|
|
@@ -444,7 +492,7 @@ const TicketForm: React.FC<Props> = ({
|
|
|
444
492
|
}, [window.location.search]);
|
|
445
493
|
|
|
446
494
|
useEffect(() => {
|
|
447
|
-
const subscription = methods.watch((value
|
|
495
|
+
const subscription = methods.watch((value) => {
|
|
448
496
|
if (
|
|
449
497
|
JSON.stringify(defaultValues) !== JSON.stringify(value) &&
|
|
450
498
|
!hasFiredBeginCheckout.current
|
|
@@ -471,7 +519,7 @@ const TicketForm: React.FC<Props> = ({
|
|
|
471
519
|
useEffect(() => {
|
|
472
520
|
if (hasGopayId || isPaying || paymentRedirect) {
|
|
473
521
|
if (options?.autoscrollAfterViewChange) {
|
|
474
|
-
const orderForm = document.getElementById(
|
|
522
|
+
const orderForm = document.getElementById(EVENTLOOK_ORDER_FORM_CONTAINER_ID);
|
|
475
523
|
if (orderForm) {
|
|
476
524
|
orderForm.scrollIntoView({ behavior: 'smooth' });
|
|
477
525
|
}
|
|
@@ -483,7 +531,7 @@ const TicketForm: React.FC<Props> = ({
|
|
|
483
531
|
return <ReleaseCountdown event={event} setShowReleaseDate={setShowReleaseDate} />;
|
|
484
532
|
|
|
485
533
|
return (
|
|
486
|
-
<Box id={
|
|
534
|
+
<Box id={EVENTLOOK_ORDER_FORM_CONTAINER_ID}>
|
|
487
535
|
{hasGopayId ? (
|
|
488
536
|
<PaymentSuccess setIsPaying={setIsPaying} isIframe={isIframe} pixels={pixels} />
|
|
489
537
|
) : isPaying ? (
|
|
@@ -496,32 +544,65 @@ const TicketForm: React.FC<Props> = ({
|
|
|
496
544
|
isInline={isInline}
|
|
497
545
|
/>
|
|
498
546
|
) : (
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
547
|
+
<FormProvider
|
|
548
|
+
methods={methods}
|
|
549
|
+
// @ts-ignore
|
|
550
|
+
onSubmit={methods.handleSubmit(onSubmit, onInvalid)}
|
|
551
|
+
formId={EVENTLOOK_ORDER_FORM_ID}
|
|
552
|
+
>
|
|
553
|
+
<Stack
|
|
502
554
|
className="overview-card__event-info"
|
|
503
555
|
display={{ md: 'none' }}
|
|
504
|
-
variant="h4"
|
|
505
556
|
sx={{
|
|
506
557
|
mb: 2,
|
|
507
558
|
}}
|
|
508
559
|
>
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
560
|
+
<Typography variant="h3" component="h1">
|
|
561
|
+
{event.name}
|
|
562
|
+
</Typography>
|
|
563
|
+
<Typography variant="h5" component="h2">
|
|
564
|
+
{dayjs(event.startDate).format('DD.MM.YYYY HH:mm')}
|
|
565
|
+
</Typography>
|
|
566
|
+
<Typography variant="body2" mt={1}>
|
|
567
|
+
{getPlaceAsString(event.place)}
|
|
568
|
+
</Typography>
|
|
569
|
+
{headerSlot ? <>{headerSlot}</> : null}
|
|
570
|
+
</Stack>
|
|
571
|
+
<Grid
|
|
572
|
+
container
|
|
573
|
+
spacing={2}
|
|
574
|
+
sx={{
|
|
575
|
+
pb: {
|
|
576
|
+
xs: isPaymentOverviewDrawerOpen ? cartItemCount * 4 + 18 : 0,
|
|
577
|
+
md: 0,
|
|
578
|
+
},
|
|
579
|
+
}}
|
|
580
|
+
>
|
|
512
581
|
<Grid size={{ xs: 12, md: 8 }}>
|
|
513
|
-
<Stepper
|
|
582
|
+
<Stepper
|
|
583
|
+
orientation="vertical"
|
|
584
|
+
sx={(theme) => ({
|
|
585
|
+
[theme.breakpoints.down('sm')]: {
|
|
586
|
+
'& .MuiStepContent-root': {
|
|
587
|
+
borderLeftWidth: 0,
|
|
588
|
+
paddingLeft: 0,
|
|
589
|
+
marginLeft: 0,
|
|
590
|
+
},
|
|
591
|
+
'& .MuiStepConnector-line': { borderLeftWidth: 0 },
|
|
592
|
+
},
|
|
593
|
+
})}
|
|
594
|
+
>
|
|
514
595
|
{event.type === EventType.RECURRING && (
|
|
515
596
|
<Step active>
|
|
516
597
|
<StepLabel>{t('event.tickets.stepper.6.title')}</StepLabel>
|
|
517
|
-
<StepContent>
|
|
598
|
+
<StepContent sx={{ pr: { xs: 0 } }}>
|
|
518
599
|
<TimeslotSelection event={event} />
|
|
519
600
|
</StepContent>
|
|
520
601
|
</Step>
|
|
521
602
|
)}
|
|
522
603
|
<Step active>
|
|
523
604
|
<StepLabel>{t('event.tickets.stepper.1.title')}</StepLabel>
|
|
524
|
-
<StepContent>
|
|
605
|
+
<StepContent sx={{ pr: { xs: 0 } }}>
|
|
525
606
|
{event.mapId && seatingIframeUrl ? (
|
|
526
607
|
<TicketSelectionMap event={event} />
|
|
527
608
|
) : event.hasMerchandise ? (
|
|
@@ -534,7 +615,7 @@ const TicketForm: React.FC<Props> = ({
|
|
|
534
615
|
{event.hasMerchandise && eventProducts.length && (
|
|
535
616
|
<Step active>
|
|
536
617
|
<StepLabel>{t('event.tickets.stepper.4.title')}</StepLabel>
|
|
537
|
-
<StepContent>
|
|
618
|
+
<StepContent sx={{ pr: { xs: 0 } }}>
|
|
538
619
|
<MerchandiseSelection
|
|
539
620
|
eventProducts={eventProducts}
|
|
540
621
|
eventId={event.id}
|
|
@@ -543,24 +624,30 @@ const TicketForm: React.FC<Props> = ({
|
|
|
543
624
|
</StepContent>
|
|
544
625
|
</Step>
|
|
545
626
|
)}
|
|
627
|
+
<Step active>
|
|
628
|
+
<StepLabel>{t('event.tickets.stepper.8.title')}</StepLabel>
|
|
629
|
+
<StepContent sx={{ pr: { xs: 0 } }}>
|
|
630
|
+
<Services event={event} />
|
|
631
|
+
</StepContent>
|
|
632
|
+
</Step>
|
|
546
633
|
{event.children.length && (
|
|
547
634
|
<Step active>
|
|
548
635
|
<StepLabel>{t('event.tickets.stepper.7.title')}</StepLabel>
|
|
549
|
-
<StepContent>
|
|
636
|
+
<StepContent sx={{ pr: { xs: 0 } }}>
|
|
550
637
|
<ChildEventSection events={event.children} />
|
|
551
638
|
</StepContent>
|
|
552
639
|
</Step>
|
|
553
640
|
)}
|
|
554
641
|
<Step active>
|
|
555
642
|
<StepLabel>{t('event.tickets.stepper.2.title')}</StepLabel>
|
|
556
|
-
<StepContent>
|
|
643
|
+
<StepContent sx={{ pr: { xs: 0 } }}>
|
|
557
644
|
<ContactPerson event={event} />
|
|
558
645
|
</StepContent>
|
|
559
646
|
</Step>
|
|
560
647
|
{event.hasMerchandise && showShippingMethods() && (
|
|
561
648
|
<Step active>
|
|
562
649
|
<StepLabel>{t('event.tickets.stepper.5.title')}</StepLabel>
|
|
563
|
-
<StepContent>
|
|
650
|
+
<StepContent sx={{ pr: { xs: 0 } }}>
|
|
564
651
|
<Shipping event={event} />
|
|
565
652
|
</StepContent>
|
|
566
653
|
</Step>
|
|
@@ -571,12 +658,17 @@ const TicketForm: React.FC<Props> = ({
|
|
|
571
658
|
`event.tickets.stepper.3.${values.isPaymentVerify ? 'title_verify' : 'title'}`
|
|
572
659
|
)}
|
|
573
660
|
</StepLabel>
|
|
574
|
-
<StepContent>
|
|
661
|
+
<StepContent sx={{ pr: { xs: 0 } }}>
|
|
575
662
|
<Payment event={event} />
|
|
576
663
|
</StepContent>
|
|
577
664
|
</Step>
|
|
578
665
|
</Stepper>
|
|
579
|
-
<Stack
|
|
666
|
+
<Stack
|
|
667
|
+
ref={termsAndConditionsRef}
|
|
668
|
+
mt={2}
|
|
669
|
+
ml={{ xs: 1, md: 4 }}
|
|
670
|
+
sx={{ scrollMarginBottom: { xs: 220, md: 0 } }}
|
|
671
|
+
>
|
|
580
672
|
<RHFCheckbox
|
|
581
673
|
name="termsAndConditions"
|
|
582
674
|
label={
|
|
@@ -596,15 +688,26 @@ const TicketForm: React.FC<Props> = ({
|
|
|
596
688
|
/>
|
|
597
689
|
</Stack>
|
|
598
690
|
</Grid>
|
|
599
|
-
<Grid size={{ xs:
|
|
600
|
-
<
|
|
691
|
+
<Grid size={12} sx={{ display: { xs: 'block', md: 'none' } }}>
|
|
692
|
+
<Divider sx={{ borderStyle: 'dashed' }} />
|
|
693
|
+
</Grid>
|
|
694
|
+
<Grid size={{ xs: 12, md: 4 }} sx={{ mt: { xs: 0, md: 0 } }}>
|
|
695
|
+
<PaymentOverviewBox event={event} withoutPadding />
|
|
601
696
|
</Grid>
|
|
602
697
|
</Grid>
|
|
698
|
+
|
|
699
|
+
<PaymentOverviewDrawer
|
|
700
|
+
event={event}
|
|
701
|
+
totalPrice={values.total}
|
|
702
|
+
termsAndConditionsRef={termsAndConditionsRef}
|
|
703
|
+
onOpenChange={setIsPaymentOverviewDrawerOpen}
|
|
704
|
+
/>
|
|
705
|
+
|
|
603
706
|
<EmailConfirmation
|
|
604
707
|
open={formStep === 2 && !isIframe}
|
|
605
708
|
onClose={() => setFormStep(1)}
|
|
606
|
-
// @ts-ignore
|
|
607
|
-
onConfirm={methods.handleSubmit(onSubmit)}
|
|
709
|
+
// @ts-ignore
|
|
710
|
+
onConfirm={methods.handleSubmit(onSubmit, onInvalid)}
|
|
608
711
|
/>
|
|
609
712
|
</FormProvider>
|
|
610
713
|
)}
|
|
@@ -613,7 +716,7 @@ const TicketForm: React.FC<Props> = ({
|
|
|
613
716
|
};
|
|
614
717
|
|
|
615
718
|
const CustomLink: React.FC<PropsWithChildren<LinkProps>> = ({ href = '', children, ...other }) => (
|
|
616
|
-
<Link href={href} {...other}>
|
|
719
|
+
<Link href={href} {...other} sx={{ color: 'inherit', textDecoration: 'underline' }}>
|
|
617
720
|
{children}
|
|
618
721
|
</Link>
|
|
619
722
|
);
|
package/src/form/index.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import 'dayjs/locale/es';
|
|
|
5
5
|
import 'dayjs/locale/uk';
|
|
6
6
|
import 'dayjs/locale/sk';
|
|
7
7
|
|
|
8
|
-
import React, { useEffect } from 'react';
|
|
8
|
+
import React, { useEffect, ReactNode } from 'react';
|
|
9
9
|
import TicketForm from '@form/TicketForm';
|
|
10
10
|
import { GlobalProvider } from '@context/GlobalContext';
|
|
11
11
|
import api from '@utils/axios';
|
|
@@ -33,6 +33,7 @@ export interface OrderFormProps {
|
|
|
33
33
|
lang?: Languages;
|
|
34
34
|
slots?: {
|
|
35
35
|
showSnackbar: IGlobalContext['showSnackbar'];
|
|
36
|
+
headerSlot?: ReactNode;
|
|
36
37
|
};
|
|
37
38
|
user?: IUser;
|
|
38
39
|
selectedReleaseId?: number;
|
|
@@ -112,6 +113,7 @@ const ClientRender: React.FC<OrderFormProps> = ({
|
|
|
112
113
|
hasGopayIdSsr={options?.hasGopayId || false}
|
|
113
114
|
isIframe={options?.isIframe}
|
|
114
115
|
selectedReleaseId={selectedReleaseId}
|
|
116
|
+
headerSlot={slots?.headerSlot}
|
|
115
117
|
/>
|
|
116
118
|
)}
|
|
117
119
|
</GlobalProvider>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Grid } from '@mui/material';
|
|
3
|
+
import { IEventProduct } from '@utils/types/event-product.type';
|
|
4
|
+
import CustomSkeleton from '@components/CustomSkeleton';
|
|
5
|
+
import MerchandiseSlider from './MerchandiseSlider';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
eventProducts: IEventProduct[];
|
|
9
|
+
eventId: number;
|
|
10
|
+
isLoading?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const MerchandiseSelection: React.FC<Props> = ({ eventProducts, eventId, isLoading }) =>
|
|
14
|
+
isLoading ? (
|
|
15
|
+
[...Array(3)].map((item) => (
|
|
16
|
+
<Grid key={item} size={{ xs: 12, md: 4 }}>
|
|
17
|
+
<CustomSkeleton height={334} />
|
|
18
|
+
</Grid>
|
|
19
|
+
))
|
|
20
|
+
) : (
|
|
21
|
+
<MerchandiseSlider eventProducts={eventProducts} eventId={eventId} />
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export default MerchandiseSelection;
|