@akinon/next 1.58.0 → 1.59.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 +652 -0
- package/api/client.ts +23 -2
- 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/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 +37 -0
- 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/lib/cache-handler.mjs +33 -0
- package/lib/cache.ts +8 -6
- package/middlewares/default.ts +46 -2
- package/middlewares/pretty-url.ts +11 -1
- package/middlewares/url-redirection.ts +4 -0
- package/package.json +4 -3
- package/plugins.d.ts +1 -0
- package/redux/middlewares/checkout.ts +71 -11
- package/redux/reducers/checkout.ts +23 -3
- package/routes/pretty-url.tsx +192 -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 +17 -2
- package/utils/app-fetch.ts +16 -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/with-pz-config.js +13 -2
package/api/client.ts
CHANGED
|
@@ -4,6 +4,7 @@ import settings from 'settings';
|
|
|
4
4
|
import logger from '../utils/log';
|
|
5
5
|
import formatCookieString from '../utils/format-cookie-string';
|
|
6
6
|
import cookieParser from 'set-cookie-parser';
|
|
7
|
+
import { cookies } from 'next/headers';
|
|
7
8
|
|
|
8
9
|
interface RouteParams {
|
|
9
10
|
params: {
|
|
@@ -80,11 +81,27 @@ async function proxyRequest(...args) {
|
|
|
80
81
|
}
|
|
81
82
|
} as RequestInit;
|
|
82
83
|
|
|
84
|
+
const nextCookies = cookies();
|
|
85
|
+
const segment = nextCookies.get('pz-segment')?.value;
|
|
86
|
+
const currency = nextCookies.get('pz-external-currency')?.value;
|
|
87
|
+
|
|
88
|
+
if (segment) {
|
|
89
|
+
fetchOptions.headers['X-Segment-Id'] = segment;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (currency) {
|
|
93
|
+
fetchOptions.headers = Object.assign({}, fetchOptions.headers, {
|
|
94
|
+
'x-currency': currency
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
83
98
|
if (options.contentType) {
|
|
84
99
|
fetchOptions.headers['Content-Type'] = options.contentType;
|
|
85
100
|
}
|
|
86
101
|
|
|
87
|
-
const isMultipartFormData = req.headers
|
|
102
|
+
const isMultipartFormData = req.headers
|
|
103
|
+
.get('content-type')
|
|
104
|
+
?.includes('multipart/form-data;');
|
|
88
105
|
|
|
89
106
|
if (req.method !== 'GET') {
|
|
90
107
|
let body: Record<string, any> | FormData = {};
|
|
@@ -108,7 +125,11 @@ async function proxyRequest(...args) {
|
|
|
108
125
|
|
|
109
126
|
Object.keys(body ?? {}).forEach((key) => {
|
|
110
127
|
if (body[key]) {
|
|
111
|
-
|
|
128
|
+
if (typeof body[key] === 'object' && body[key] !== null) {
|
|
129
|
+
formData.append(key, JSON.stringify(body[key]));
|
|
130
|
+
} else {
|
|
131
|
+
formData.append(key, body[key]);
|
|
132
|
+
}
|
|
112
133
|
}
|
|
113
134
|
});
|
|
114
135
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
.checkout-payment-iframe-wrapper {
|
|
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
|
+
}
|
|
11
|
+
.checkout-payment-iframe-wrapper iframe {
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: 100%;
|
|
14
|
+
border: none;
|
|
15
|
+
background-color: white;
|
|
16
|
+
}
|
|
17
|
+
.checkout-payment-iframe-wrapper .close-button {
|
|
18
|
+
position: fixed;
|
|
19
|
+
top: 16px;
|
|
20
|
+
right: 16px;
|
|
21
|
+
width: 32px;
|
|
22
|
+
height: 32px;
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
z-index: 1001;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.checkout-payment-redirection-iframe-wrapper {
|
|
30
|
+
width: 100%;
|
|
31
|
+
position: relative;
|
|
32
|
+
}
|
|
33
|
+
.checkout-payment-redirection-iframe-wrapper iframe {
|
|
34
|
+
width: 100%;
|
|
35
|
+
height: 100%;
|
|
36
|
+
border: none;
|
|
37
|
+
background-color: white;
|
|
38
|
+
}
|
|
39
|
+
.checkout-payment-redirection-iframe-wrapper .close-button {
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: 16px;
|
|
42
|
+
right: 16px;
|
|
43
|
+
width: 32px;
|
|
44
|
+
height: 32px;
|
|
45
|
+
display: flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
justify-content: center;
|
|
48
|
+
z-index: 1001;
|
|
49
|
+
}/*# sourceMappingURL=index.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["index.scss","index.css"],"names":[],"mappings":"AAAA;EACE,eAAA;EACA,MAAA;EACA,OAAA;EACA,WAAA;EACA,YAAA;EACA,YAAA;EACA,aAAA;EACA,uBAAA;ACCF;ADCE;EACE,WAAA;EACA,YAAA;EACA,YAAA;EACA,uBAAA;ACCJ;ADEE;EACE,eAAA;EACA,SAAA;EACA,WAAA;EACA,WAAA;EACA,YAAA;EACA,aAAA;EACA,mBAAA;EACA,uBAAA;EACA,aAAA;ACAJ;;ADIA;EACE,WAAA;EACA,kBAAA;ACDF;ADGE;EACE,WAAA;EACA,YAAA;EACA,YAAA;EACA,uBAAA;ACDJ;ADIE;EACE,kBAAA;EACA,SAAA;EACA,WAAA;EACA,WAAA;EACA,YAAA;EACA,aAAA;EACA,mBAAA;EACA,uBAAA;EACA,aAAA;ACFJ","file":"index.css"}
|
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 />
|
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
|
@@ -380,6 +380,22 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
380
380
|
dispatch(setShippingStepBusy(false));
|
|
381
381
|
}
|
|
382
382
|
}),
|
|
383
|
+
setDataSourceShippingOptions: build.mutation<CheckoutResponse, number[]>({
|
|
384
|
+
query: (pks) => ({
|
|
385
|
+
url: buildClientRequestUrl(checkout.setDataSourceShippingOption, {
|
|
386
|
+
useFormData: true
|
|
387
|
+
}),
|
|
388
|
+
method: 'POST',
|
|
389
|
+
body: {
|
|
390
|
+
data_source_shipping_options: JSON.stringify(pks)
|
|
391
|
+
}
|
|
392
|
+
}),
|
|
393
|
+
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
394
|
+
dispatch(setShippingStepBusy(true));
|
|
395
|
+
await queryFulfilled;
|
|
396
|
+
dispatch(setShippingStepBusy(false));
|
|
397
|
+
}
|
|
398
|
+
}),
|
|
383
399
|
setRetailStore: build.mutation<CheckoutResponse, SetRetailStoreParams>({
|
|
384
400
|
query: ({ retailStorePk, billingAddressPk }) => ({
|
|
385
401
|
url: buildClientRequestUrl(
|
|
@@ -681,6 +697,25 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
681
697
|
};
|
|
682
698
|
}
|
|
683
699
|
}),
|
|
700
|
+
setAttributeBasedShippingOptions: build.mutation<
|
|
701
|
+
CheckoutResponse,
|
|
702
|
+
Record<string, number>
|
|
703
|
+
>({
|
|
704
|
+
query: (options) => ({
|
|
705
|
+
url: buildClientRequestUrl(checkout.setAttributeBasedShippingOption, {
|
|
706
|
+
useFormData: true
|
|
707
|
+
}),
|
|
708
|
+
method: 'POST',
|
|
709
|
+
body: {
|
|
710
|
+
attribute_based_shipping_options: JSON.stringify(options)
|
|
711
|
+
}
|
|
712
|
+
}),
|
|
713
|
+
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
714
|
+
dispatch(setShippingStepBusy(true));
|
|
715
|
+
await queryFulfilled;
|
|
716
|
+
dispatch(setShippingStepBusy(false));
|
|
717
|
+
}
|
|
718
|
+
}),
|
|
684
719
|
setOrderSelectionPage: build.mutation<
|
|
685
720
|
CheckoutResponse,
|
|
686
721
|
{ extra_field: ExtraField }
|
|
@@ -712,6 +747,7 @@ export const {
|
|
|
712
747
|
useSetDeliveryOptionMutation,
|
|
713
748
|
useSetAddressesMutation,
|
|
714
749
|
useSetShippingOptionMutation,
|
|
750
|
+
useSetDataSourceShippingOptionsMutation,
|
|
715
751
|
useSetPaymentOptionMutation,
|
|
716
752
|
useSetBinNumberMutation,
|
|
717
753
|
useSetInstallmentOptionMutation,
|
|
@@ -730,5 +766,6 @@ export const {
|
|
|
730
766
|
usePayWithLoyaltyBalanceMutation,
|
|
731
767
|
useSetOrderNoteMutation,
|
|
732
768
|
useSetDeliveryBagsMutation,
|
|
769
|
+
useSetAttributeBasedShippingOptionsMutation,
|
|
733
770
|
useSetOrderSelectionPageMutation
|
|
734
771
|
} = 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,
|