@akinon/next 1.55.0 → 1.56.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +482 -0
- package/api/client.ts +50 -17
- package/assets/styles/index.css +49 -0
- package/assets/styles/index.css.map +1 -0
- package/assets/styles/index.scss +50 -26
- package/bin/pz-generate-translations.js +41 -0
- package/bin/pz-prebuild.js +1 -0
- package/bin/pz-predev.js +1 -0
- package/components/file-input.tsx +8 -0
- package/components/index.ts +1 -0
- package/components/input.tsx +21 -7
- package/components/link.tsx +17 -13
- package/components/price.tsx +11 -4
- package/components/pz-root.tsx +15 -3
- package/components/selected-payment-option-view.tsx +26 -38
- package/data/client/account.ts +10 -9
- package/data/client/api.ts +1 -1
- package/data/client/b2b.ts +35 -2
- package/data/client/basket.ts +6 -5
- package/data/client/checkout.ts +38 -1
- package/data/client/user.ts +3 -2
- package/data/server/category.ts +43 -19
- package/data/server/flatpage.ts +29 -7
- package/data/server/form.ts +29 -11
- package/data/server/landingpage.ts +26 -7
- package/data/server/list.ts +16 -6
- package/data/server/menu.ts +15 -2
- package/data/server/product.ts +33 -13
- package/data/server/seo.ts +17 -24
- package/data/server/special-page.ts +15 -5
- package/data/server/widget.ts +14 -7
- package/data/urls.ts +8 -1
- package/hocs/server/with-segment-defaults.tsx +4 -1
- package/hooks/index.ts +2 -1
- package/hooks/use-message-listener.ts +24 -0
- package/hooks/use-pagination.ts +2 -2
- package/hooks/use-payment-options.ts +2 -1
- package/lib/cache-handler.mjs +33 -0
- package/lib/cache.ts +8 -6
- package/middlewares/default.ts +87 -8
- package/middlewares/pretty-url.ts +11 -1
- package/middlewares/url-redirection.ts +4 -0
- package/package.json +4 -3
- package/redux/middlewares/checkout.ts +69 -10
- package/redux/reducers/checkout.ts +23 -3
- package/routes/pretty-url.tsx +192 -0
- package/types/commerce/account.ts +1 -0
- package/types/commerce/address.ts +1 -1
- package/types/commerce/b2b.ts +12 -2
- package/types/commerce/checkout.ts +30 -0
- package/types/commerce/order.ts +1 -0
- package/types/index.ts +18 -2
- package/utils/app-fetch.ts +17 -8
- package/utils/generate-commerce-search-params.ts +3 -1
- package/utils/index.ts +27 -6
- package/utils/redirection-iframe.ts +85 -0
- package/utils/server-translation.ts +11 -1
- package/utils/server-variables.ts +2 -1
- package/with-pz-config.js +13 -2
package/assets/styles/index.scss
CHANGED
|
@@ -1,29 +1,53 @@
|
|
|
1
1
|
.checkout-payment-iframe-wrapper {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
position: fixed;
|
|
3
|
+
top: 0;
|
|
4
|
+
left: 0;
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
border: none;
|
|
8
|
+
z-index: 1000;
|
|
9
|
+
background-color: white;
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
iframe {
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: 100%;
|
|
14
|
+
border: none;
|
|
15
|
+
background-color: white;
|
|
16
|
+
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
18
|
+
.close-button {
|
|
19
|
+
position: fixed;
|
|
20
|
+
top: 16px;
|
|
21
|
+
right: 16px;
|
|
22
|
+
width: 32px;
|
|
23
|
+
height: 32px;
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
z-index: 1001;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.checkout-payment-redirection-iframe-wrapper {
|
|
32
|
+
width: 100%;
|
|
33
|
+
position: relative;
|
|
34
|
+
|
|
35
|
+
iframe {
|
|
36
|
+
width: 100%;
|
|
37
|
+
height: 100%;
|
|
38
|
+
border: none;
|
|
39
|
+
background-color: white;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.close-button {
|
|
43
|
+
position: absolute;
|
|
44
|
+
top: 16px;
|
|
45
|
+
right: 16px;
|
|
46
|
+
width: 32px;
|
|
47
|
+
height: 32px;
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
justify-content: center;
|
|
51
|
+
z-index: 1001;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const localesPath = path.resolve(`public/locales/`);
|
|
6
|
+
|
|
7
|
+
async function generateTranslationIndex(locale_) {
|
|
8
|
+
let translations = {};
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
const localeDirPath = path.resolve(`public/locales/${locale_}`);
|
|
12
|
+
const fileNames = fs.readdirSync(localeDirPath);
|
|
13
|
+
|
|
14
|
+
for await (const fileName of fileNames) {
|
|
15
|
+
if (fileName === 'index.json') {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const data = fs.readFileSync(
|
|
20
|
+
path.join(localeDirPath, `/${fileName}`),
|
|
21
|
+
'utf-8'
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
translations[fileName.substring(0, fileName.lastIndexOf('.'))] =
|
|
25
|
+
JSON.parse(data);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
fs.writeFileSync(
|
|
29
|
+
path.resolve(`public/locales/${locale_}/index.json`),
|
|
30
|
+
JSON.stringify(translations)
|
|
31
|
+
);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error(error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const localePaths = fs.readdirSync(localesPath);
|
|
38
|
+
|
|
39
|
+
localePaths.forEach((localePath) => {
|
|
40
|
+
generateTranslationIndex(localePath);
|
|
41
|
+
});
|
package/bin/pz-prebuild.js
CHANGED
package/bin/pz-predev.js
CHANGED
package/components/index.ts
CHANGED
package/components/input.tsx
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
|
-
import { forwardRef, FocusEvent, useState } from 'react';
|
|
2
|
+
import { forwardRef, FocusEvent, useState, Ref } from 'react';
|
|
3
3
|
import { Controller } from 'react-hook-form';
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
import { PatternFormat, PatternFormatProps } from 'react-number-format';
|
|
5
7
|
import { InputProps } from '../types';
|
|
6
8
|
import { twMerge } from 'tailwind-merge';
|
|
7
9
|
|
|
10
|
+
const PatternFormatWithRef = forwardRef(
|
|
11
|
+
(props: PatternFormatProps, ref: Ref<HTMLInputElement>) => {
|
|
12
|
+
return <PatternFormat {...props} getInputRef={ref} />;
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
PatternFormatWithRef.displayName = 'PatternFormatWithRef';
|
|
16
|
+
|
|
8
17
|
export const Input = forwardRef<
|
|
9
18
|
HTMLInputElement,
|
|
10
19
|
InputProps &
|
|
11
20
|
Pick<
|
|
12
|
-
|
|
13
|
-
'
|
|
14
|
-
>
|
|
21
|
+
PatternFormatProps,
|
|
22
|
+
'mask' | 'allowEmptyFormatting' | 'onValueChange'
|
|
23
|
+
> & {
|
|
24
|
+
format?: string;
|
|
25
|
+
defaultValue?: string;
|
|
26
|
+
type?: string;
|
|
27
|
+
}
|
|
15
28
|
>((props, ref) => {
|
|
16
29
|
const [focused, setFocused] = useState(false);
|
|
17
30
|
const [hasValue, setHasValue] = useState(false);
|
|
@@ -37,6 +50,7 @@ export const Input = forwardRef<
|
|
|
37
50
|
),
|
|
38
51
|
props.className
|
|
39
52
|
);
|
|
53
|
+
|
|
40
54
|
const inputProps: any = {
|
|
41
55
|
id,
|
|
42
56
|
ref,
|
|
@@ -79,14 +93,14 @@ export const Input = forwardRef<
|
|
|
79
93
|
<Controller
|
|
80
94
|
name={props.name ?? ''}
|
|
81
95
|
control={props.control}
|
|
82
|
-
defaultValue={false}
|
|
83
96
|
render={({ field }) => (
|
|
84
|
-
<
|
|
97
|
+
<PatternFormatWithRef
|
|
85
98
|
format={format}
|
|
86
99
|
mask={mask ?? ''}
|
|
87
100
|
{...rest}
|
|
88
101
|
{...field}
|
|
89
102
|
{...inputProps}
|
|
103
|
+
type={props.type as 'text' | 'password' | 'tel'}
|
|
90
104
|
/>
|
|
91
105
|
)}
|
|
92
106
|
/>
|
package/components/link.tsx
CHANGED
|
@@ -10,28 +10,32 @@ type LinkProps = Omit<
|
|
|
10
10
|
React.AnchorHTMLAttributes<HTMLAnchorElement>,
|
|
11
11
|
keyof NextLinkProps
|
|
12
12
|
> &
|
|
13
|
-
NextLinkProps
|
|
13
|
+
NextLinkProps & {
|
|
14
|
+
href: string;
|
|
15
|
+
};
|
|
14
16
|
|
|
15
17
|
export const Link = ({ children, href, ...rest }: LinkProps) => {
|
|
16
18
|
const { locale, defaultLocaleValue, localeUrlStrategy } = useLocalization();
|
|
17
19
|
const formattedHref = useMemo(() => {
|
|
18
|
-
if (
|
|
19
|
-
return
|
|
20
|
+
if (!href) {
|
|
21
|
+
return '#';
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
if (typeof href === 'string' && !href.startsWith('http')) {
|
|
25
|
+
const pathnameWithoutLocale = href.replace(urlLocaleMatcherRegex, '');
|
|
26
|
+
const hrefWithLocale = `/${locale}${pathnameWithoutLocale}`;
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
if (localeUrlStrategy === LocaleUrlStrategy.ShowAllLocales) {
|
|
29
|
+
return hrefWithLocale;
|
|
30
|
+
} else if (
|
|
31
|
+
localeUrlStrategy === LocaleUrlStrategy.HideDefaultLocale &&
|
|
32
|
+
locale !== defaultLocaleValue
|
|
33
|
+
) {
|
|
34
|
+
return hrefWithLocale;
|
|
35
|
+
}
|
|
32
36
|
}
|
|
33
37
|
|
|
34
|
-
return href
|
|
38
|
+
return href;
|
|
35
39
|
}, [href, defaultLocaleValue, locale, localeUrlStrategy]);
|
|
36
40
|
|
|
37
41
|
return (
|
package/components/price.tsx
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import { NumericFormat, NumericFormatProps } from 'react-number-format';
|
|
3
5
|
import { getCurrency } from '@akinon/next/utils';
|
|
4
6
|
|
|
5
7
|
import { useLocalization } from '@akinon/next/hooks';
|
|
6
8
|
import { PriceProps } from '../types';
|
|
9
|
+
import Settings from 'settings';
|
|
7
10
|
|
|
8
|
-
export const Price = (props:
|
|
11
|
+
export const Price = (props: NumericFormatProps & PriceProps) => {
|
|
9
12
|
const {
|
|
10
13
|
value,
|
|
11
14
|
currencyCode,
|
|
@@ -27,6 +30,10 @@ export const Price = (props: NumberFormatProps & PriceProps) => {
|
|
|
27
30
|
// TODO: This is very bad practice. It broke decimalScale.
|
|
28
31
|
const _value = value?.toString().replace('.', ',');
|
|
29
32
|
|
|
33
|
+
const currentCurrencyDecimalScale = Settings.localization.currencies.find(
|
|
34
|
+
(currency) => currency.code === currencyCode_
|
|
35
|
+
).decimalScale;
|
|
36
|
+
|
|
30
37
|
const currency = useMemo(
|
|
31
38
|
() =>
|
|
32
39
|
getCurrency({
|
|
@@ -39,14 +46,14 @@ export const Price = (props: NumberFormatProps & PriceProps) => {
|
|
|
39
46
|
);
|
|
40
47
|
|
|
41
48
|
return (
|
|
42
|
-
<
|
|
49
|
+
<NumericFormat
|
|
43
50
|
value={useNegative ? `-${useNegativeSpace}${_value}` : _value}
|
|
44
51
|
{...{
|
|
45
52
|
[useCurrencyAfterPrice ? 'suffix' : 'prefix']: currency
|
|
46
53
|
}}
|
|
47
54
|
displayType={displayType}
|
|
48
55
|
thousandSeparator={thousandSeparator}
|
|
49
|
-
decimalScale={decimalScale}
|
|
56
|
+
decimalScale={currentCurrencyDecimalScale ?? decimalScale}
|
|
50
57
|
decimalSeparator={decimalSeparator}
|
|
51
58
|
fixedDecimalScale={fixedDecimalScale}
|
|
52
59
|
{...rest}
|
package/components/pz-root.tsx
CHANGED
|
@@ -3,17 +3,29 @@ import ClientRoot from './client-root';
|
|
|
3
3
|
import { cookies } from 'next/headers';
|
|
4
4
|
import PzProviders from './pz-providers';
|
|
5
5
|
import { WebVitals } from './web-vitals';
|
|
6
|
+
import settings from 'settings';
|
|
6
7
|
|
|
7
|
-
export default function PzRoot({
|
|
8
|
+
export default async function PzRoot({
|
|
8
9
|
translations,
|
|
9
|
-
children
|
|
10
|
+
children,
|
|
11
|
+
locale
|
|
10
12
|
}: {
|
|
11
|
-
translations
|
|
13
|
+
translations?: any;
|
|
12
14
|
children: React.ReactNode;
|
|
15
|
+
locale?: string;
|
|
13
16
|
}) {
|
|
14
17
|
const nextCookies = cookies();
|
|
15
18
|
const sessionid = nextCookies.get('osessionid')?.value;
|
|
16
19
|
|
|
20
|
+
if (!translations) {
|
|
21
|
+
const { getTranslations } =
|
|
22
|
+
settings.useOptimizedTranslations && locale
|
|
23
|
+
? require('translations')
|
|
24
|
+
: require('../utils/server-translation');
|
|
25
|
+
|
|
26
|
+
translations = await getTranslations(locale);
|
|
27
|
+
}
|
|
28
|
+
|
|
17
29
|
return (
|
|
18
30
|
<PzProviders translations={translations}>
|
|
19
31
|
<WebVitals />
|
|
@@ -6,6 +6,21 @@ import dynamic from 'next/dynamic';
|
|
|
6
6
|
import { PaymentOptionViews } from 'views/checkout/steps/payment';
|
|
7
7
|
import { useMemo } from 'react';
|
|
8
8
|
|
|
9
|
+
const fallbackView = () => <div />;
|
|
10
|
+
|
|
11
|
+
const paymentTypeToView = {
|
|
12
|
+
bkm_express: 'bkm',
|
|
13
|
+
credit_card: 'credit-card',
|
|
14
|
+
credit_payment: 'credit-payment',
|
|
15
|
+
funds_transfer: 'funds-transfer',
|
|
16
|
+
gpay: 'gpay',
|
|
17
|
+
loyalty_money: 'loyalty',
|
|
18
|
+
masterpass: 'credit-card',
|
|
19
|
+
pay_on_delivery: 'pay-on-delivery',
|
|
20
|
+
redirection: 'redirection'
|
|
21
|
+
// Add other mappings as needed
|
|
22
|
+
};
|
|
23
|
+
|
|
9
24
|
export default function SelectedPaymentOptionView() {
|
|
10
25
|
const { payment_option } = useAppSelector(
|
|
11
26
|
(state: RootState) => state.checkout.preOrder
|
|
@@ -14,7 +29,7 @@ export default function SelectedPaymentOptionView() {
|
|
|
14
29
|
const Component = useMemo(
|
|
15
30
|
() =>
|
|
16
31
|
dynamic(
|
|
17
|
-
() => {
|
|
32
|
+
async () => {
|
|
18
33
|
const customOption = PaymentOptionViews.find(
|
|
19
34
|
(opt) => opt.slug === payment_option.slug
|
|
20
35
|
);
|
|
@@ -29,46 +44,19 @@ export default function SelectedPaymentOptionView() {
|
|
|
29
44
|
});
|
|
30
45
|
}
|
|
31
46
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
`views/checkout/steps/payment/options/credit-card`
|
|
38
|
-
);
|
|
39
|
-
} else if (payment_option.payment_type === 'funds_transfer') {
|
|
40
|
-
promise = import(
|
|
41
|
-
`views/checkout/steps/payment/options/funds-transfer`
|
|
42
|
-
);
|
|
43
|
-
} else if (payment_option.payment_type === 'redirection') {
|
|
44
|
-
promise = import(
|
|
45
|
-
`views/checkout/steps/payment/options/redirection`
|
|
46
|
-
);
|
|
47
|
-
} else if (payment_option.payment_type === 'pay_on_delivery') {
|
|
48
|
-
promise = import(
|
|
49
|
-
`views/checkout/steps/payment/options/pay-on-delivery`
|
|
50
|
-
);
|
|
51
|
-
} else if (payment_option.payment_type === 'loyalty_money') {
|
|
52
|
-
promise = import(`views/checkout/steps/payment/options/loyalty`);
|
|
53
|
-
} else if (payment_option.payment_type === 'masterpass') {
|
|
54
|
-
promise = import(
|
|
55
|
-
`views/checkout/steps/payment/options/credit-card`
|
|
47
|
+
const view = paymentTypeToView[payment_option.payment_type];
|
|
48
|
+
if (view) {
|
|
49
|
+
try {
|
|
50
|
+
const mod = await import(
|
|
51
|
+
`views/checkout/steps/payment/options/${view}`
|
|
56
52
|
);
|
|
53
|
+
return mod.default || fallbackView;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
return fallbackView;
|
|
57
56
|
}
|
|
58
|
-
|
|
59
|
-
// promise = import(`views/checkout/steps/payment/options/credit-payment`);
|
|
60
|
-
// }
|
|
61
|
-
// else if (payment_option.payment_type === 'gpay') {
|
|
62
|
-
// promise = import(`views/checkout/steps/payment/options/gpay`);
|
|
63
|
-
// }
|
|
64
|
-
// else if (payment_option.payment_type === 'bkm_express') {
|
|
65
|
-
// promise = import(`views/checkout/steps/payment/options/bkm`);
|
|
66
|
-
// }
|
|
67
|
-
} catch (error) {}
|
|
57
|
+
}
|
|
68
58
|
|
|
69
|
-
return
|
|
70
|
-
? promise.then((mod) => mod.default).catch(() => () => null)
|
|
71
|
-
: new Promise<any>((resolve) => resolve(() => null));
|
|
59
|
+
return fallbackView;
|
|
72
60
|
},
|
|
73
61
|
{ ssr: false }
|
|
74
62
|
),
|
package/data/client/account.ts
CHANGED
|
@@ -123,15 +123,16 @@ const accountApi = api.injectEndpoints({
|
|
|
123
123
|
query: ({ page, status, limit }) =>
|
|
124
124
|
buildClientRequestUrl(account.getQuotations(page, status, limit))
|
|
125
125
|
}),
|
|
126
|
-
sendContact: builder.mutation<void,
|
|
127
|
-
query: (body) =>
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
126
|
+
sendContact: builder.mutation<void, FormData>({
|
|
127
|
+
query: (body) => {
|
|
128
|
+
return {
|
|
129
|
+
url: buildClientRequestUrl(account.sendContact, {
|
|
130
|
+
useFormData: true
|
|
131
|
+
}),
|
|
132
|
+
method: 'POST',
|
|
133
|
+
body
|
|
134
|
+
};
|
|
135
|
+
}
|
|
135
136
|
}),
|
|
136
137
|
cancelOrder: builder.mutation<void, AccountOrderCancellation>({
|
|
137
138
|
query: ({ id, ...body }) => ({
|
package/data/client/api.ts
CHANGED
package/data/client/b2b.ts
CHANGED
|
@@ -12,7 +12,9 @@ import {
|
|
|
12
12
|
SaveBasketParams,
|
|
13
13
|
UpdateProductParams,
|
|
14
14
|
DeleteProductParams,
|
|
15
|
-
CreateQuotationParams
|
|
15
|
+
CreateQuotationParams,
|
|
16
|
+
BasketStatusResponse,
|
|
17
|
+
ExportBasketResponse
|
|
16
18
|
} from '../../types';
|
|
17
19
|
|
|
18
20
|
const b2bApi = api.injectEndpoints({
|
|
@@ -89,6 +91,34 @@ const b2bApi = api.injectEndpoints({
|
|
|
89
91
|
}),
|
|
90
92
|
invalidatesTags: ['BasketB2b', 'DraftsB2b']
|
|
91
93
|
}),
|
|
94
|
+
exportBasket: build.mutation<ExportBasketResponse, string>({
|
|
95
|
+
query: (queryString) => {
|
|
96
|
+
return {
|
|
97
|
+
url: buildClientRequestUrl(b2b.basketExport(queryString)),
|
|
98
|
+
method: 'GET'
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}),
|
|
102
|
+
getBasketStatus: build.mutation<BasketStatusResponse, string>({
|
|
103
|
+
query: (cacheKey) => {
|
|
104
|
+
return {
|
|
105
|
+
url: buildClientRequestUrl(b2b.statusBasket(cacheKey)),
|
|
106
|
+
method: 'GET'
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}),
|
|
110
|
+
uploadFile: build.mutation<void, FormData>({
|
|
111
|
+
query: (body) => {
|
|
112
|
+
return {
|
|
113
|
+
url: buildClientRequestUrl(b2b.basketImport, {
|
|
114
|
+
useFormData: true
|
|
115
|
+
}),
|
|
116
|
+
method: 'POST',
|
|
117
|
+
body
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
invalidatesTags: ['BasketB2b']
|
|
121
|
+
})
|
|
92
122
|
}),
|
|
93
123
|
overrideExisting: true
|
|
94
124
|
});
|
|
@@ -102,5 +132,8 @@ export const {
|
|
|
102
132
|
useLoadBasketMutation,
|
|
103
133
|
useUpdateProductMutation,
|
|
104
134
|
useDeleteProductMutation,
|
|
105
|
-
useCreateQuotationMutation
|
|
135
|
+
useCreateQuotationMutation,
|
|
136
|
+
useGetBasketStatusMutation,
|
|
137
|
+
useExportBasketMutation,
|
|
138
|
+
useUploadFileMutation
|
|
106
139
|
} = b2bApi;
|
package/data/client/basket.ts
CHANGED
|
@@ -28,7 +28,7 @@ export const basketApi = api.injectEndpoints({
|
|
|
28
28
|
query: ({ namespace }) =>
|
|
29
29
|
buildClientRequestUrl(basket.getBasketDetail(namespace)),
|
|
30
30
|
transformResponse: (response: { basket: Basket }) => response.basket,
|
|
31
|
-
providesTags: ['
|
|
31
|
+
providesTags: ['MultiBasket']
|
|
32
32
|
}),
|
|
33
33
|
getAllBaskets: build.query<Basket[], void>({
|
|
34
34
|
query: () =>
|
|
@@ -36,7 +36,7 @@ export const basketApi = api.injectEndpoints({
|
|
|
36
36
|
contentType: 'application/json'
|
|
37
37
|
}),
|
|
38
38
|
transformResponse: (response: { baskets: Basket[] }) => response.baskets,
|
|
39
|
-
providesTags: ['
|
|
39
|
+
providesTags: ['MultiBasket']
|
|
40
40
|
}),
|
|
41
41
|
removeBasket: build.mutation<Basket, { pk: number }>({
|
|
42
42
|
query: ({ pk }) => ({
|
|
@@ -46,7 +46,7 @@ export const basketApi = api.injectEndpoints({
|
|
|
46
46
|
method: 'DELETE',
|
|
47
47
|
body: { pk }
|
|
48
48
|
}),
|
|
49
|
-
invalidatesTags: ['
|
|
49
|
+
invalidatesTags: ['MultiBasket', 'Basket']
|
|
50
50
|
}),
|
|
51
51
|
selectMainBasket: build.mutation<Basket, { pk: number }>({
|
|
52
52
|
query: ({ pk }) => ({
|
|
@@ -57,7 +57,7 @@ export const basketApi = api.injectEndpoints({
|
|
|
57
57
|
body: { pk }
|
|
58
58
|
}),
|
|
59
59
|
transformResponse: (response: { baskets: Basket }) => response.baskets,
|
|
60
|
-
invalidatesTags: ['
|
|
60
|
+
invalidatesTags: ['MultiBasket', 'Basket']
|
|
61
61
|
}),
|
|
62
62
|
updateQuantity: build.mutation<
|
|
63
63
|
UpdateQuantityResponse,
|
|
@@ -69,7 +69,8 @@ export const basketApi = api.injectEndpoints({
|
|
|
69
69
|
}),
|
|
70
70
|
method: 'PUT',
|
|
71
71
|
body
|
|
72
|
-
})
|
|
72
|
+
}),
|
|
73
|
+
invalidatesTags: ['MultiBasket', 'Basket']
|
|
73
74
|
}),
|
|
74
75
|
clearBasket: build.mutation<Basket, void>({
|
|
75
76
|
query: (body) => ({
|
package/data/client/checkout.ts
CHANGED
|
@@ -379,6 +379,22 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
379
379
|
dispatch(setShippingStepBusy(false));
|
|
380
380
|
}
|
|
381
381
|
}),
|
|
382
|
+
setDataSourceShippingOptions: build.mutation<CheckoutResponse, number[]>({
|
|
383
|
+
query: (pks) => ({
|
|
384
|
+
url: buildClientRequestUrl(checkout.setDataSourceShippingOption, {
|
|
385
|
+
useFormData: true
|
|
386
|
+
}),
|
|
387
|
+
method: 'POST',
|
|
388
|
+
body: {
|
|
389
|
+
data_source_shipping_options: JSON.stringify(pks)
|
|
390
|
+
}
|
|
391
|
+
}),
|
|
392
|
+
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
393
|
+
dispatch(setShippingStepBusy(true));
|
|
394
|
+
await queryFulfilled;
|
|
395
|
+
dispatch(setShippingStepBusy(false));
|
|
396
|
+
}
|
|
397
|
+
}),
|
|
382
398
|
setRetailStore: build.mutation<CheckoutResponse, SetRetailStoreParams>({
|
|
383
399
|
query: ({ retailStorePk, billingAddressPk }) => ({
|
|
384
400
|
url: buildClientRequestUrl(
|
|
@@ -679,6 +695,25 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
679
695
|
body
|
|
680
696
|
};
|
|
681
697
|
}
|
|
698
|
+
}),
|
|
699
|
+
setAttributeBasedShippingOptions: build.mutation<
|
|
700
|
+
CheckoutResponse,
|
|
701
|
+
Record<string, number>
|
|
702
|
+
>({
|
|
703
|
+
query: (options) => ({
|
|
704
|
+
url: buildClientRequestUrl(checkout.setAttributeBasedShippingOption, {
|
|
705
|
+
useFormData: true
|
|
706
|
+
}),
|
|
707
|
+
method: 'POST',
|
|
708
|
+
body: {
|
|
709
|
+
attribute_based_shipping_options: JSON.stringify(options)
|
|
710
|
+
}
|
|
711
|
+
}),
|
|
712
|
+
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
713
|
+
dispatch(setShippingStepBusy(true));
|
|
714
|
+
await queryFulfilled;
|
|
715
|
+
dispatch(setShippingStepBusy(false));
|
|
716
|
+
}
|
|
682
717
|
})
|
|
683
718
|
}),
|
|
684
719
|
overrideExisting: false
|
|
@@ -697,6 +732,7 @@ export const {
|
|
|
697
732
|
useSetDeliveryOptionMutation,
|
|
698
733
|
useSetAddressesMutation,
|
|
699
734
|
useSetShippingOptionMutation,
|
|
735
|
+
useSetDataSourceShippingOptionsMutation,
|
|
700
736
|
useSetPaymentOptionMutation,
|
|
701
737
|
useSetBinNumberMutation,
|
|
702
738
|
useSetInstallmentOptionMutation,
|
|
@@ -714,5 +750,6 @@ export const {
|
|
|
714
750
|
useGetCheckoutLoyaltyBalanceQuery,
|
|
715
751
|
usePayWithLoyaltyBalanceMutation,
|
|
716
752
|
useSetOrderNoteMutation,
|
|
717
|
-
useSetDeliveryBagsMutation
|
|
753
|
+
useSetDeliveryBagsMutation,
|
|
754
|
+
useSetAttributeBasedShippingOptionsMutation
|
|
718
755
|
} = checkoutApi;
|
package/data/client/user.ts
CHANGED
|
@@ -22,11 +22,12 @@ const userApi = api.injectEndpoints({
|
|
|
22
22
|
getCaptcha: build.query<GetCaptchaResponse, void>({
|
|
23
23
|
query: () => buildClientRequestUrl(user.captcha),
|
|
24
24
|
transformResponse: (response: { html: string }) => {
|
|
25
|
-
const
|
|
25
|
+
const siteKey = response.html.match(/data-sitekey="([^"]+)"/i)[1];
|
|
26
|
+
|
|
26
27
|
const csrfTokenMatch = response.html.match(
|
|
27
28
|
/name=['|"]csrfmiddlewaretoken['|"] value=['|"][^'"]+/gi
|
|
28
29
|
);
|
|
29
|
-
|
|
30
|
+
|
|
30
31
|
const csrfToken =
|
|
31
32
|
csrfTokenMatch?.[0].replace(
|
|
32
33
|
/name=['|"]csrfmiddlewaretoken['|"] value=['|"]/gi,
|