@akinon/next 1.13.0 → 1.14.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.
Files changed (133) hide show
  1. package/.editorconfig +7 -0
  2. package/.eslintrc.js +40 -40
  3. package/.prettierrc +13 -13
  4. package/CHANGELOG.md +19 -0
  5. package/api/auth.ts +231 -231
  6. package/api/cache.ts +44 -44
  7. package/api/client.ts +174 -174
  8. package/api/logout.ts +42 -42
  9. package/assets/styles/index.scss +28 -28
  10. package/bin/pz-check-dependencies.js +98 -98
  11. package/bin/pz-install-plugins.js +33 -33
  12. package/bin/pz-install-theme.js +58 -58
  13. package/bin/pz-postbuild.js +1 -1
  14. package/bin/pz-postdev.js +1 -1
  15. package/bin/pz-postinstall.js +6 -6
  16. package/bin/pz-poststart.js +1 -1
  17. package/bin/pz-prebuild.js +4 -4
  18. package/bin/pz-predev.js +4 -4
  19. package/bin/pz-prestart.js +1 -1
  20. package/bin/run-script.js +44 -44
  21. package/components/accordion.tsx +52 -0
  22. package/components/button.tsx +46 -0
  23. package/components/client-root.tsx +19 -19
  24. package/components/icon.tsx +18 -18
  25. package/components/image.tsx +133 -133
  26. package/components/index.ts +17 -1
  27. package/components/input.tsx +110 -0
  28. package/components/lazy-component.tsx +33 -33
  29. package/components/loader-spinner.tsx +23 -23
  30. package/components/mobile-app-toggler.tsx +26 -26
  31. package/components/oauth-login.tsx +24 -24
  32. package/components/plugin-module.tsx +11 -8
  33. package/components/price.tsx +55 -0
  34. package/components/pz-providers.tsx +24 -24
  35. package/components/pz-root.tsx +21 -21
  36. package/components/radio.tsx +18 -18
  37. package/components/react-portal.tsx +45 -45
  38. package/components/redirect-three-d/content/index.tsx +74 -74
  39. package/components/redirect-three-d/index.tsx +17 -17
  40. package/components/selected-payment-option-view.tsx +7 -0
  41. package/components/trans.tsx +39 -39
  42. package/data/client/account.ts +208 -208
  43. package/data/client/address.ts +107 -107
  44. package/data/client/api.ts +85 -84
  45. package/data/client/b2b.ts +106 -106
  46. package/data/client/basket.ts +82 -82
  47. package/data/client/checkout.ts +516 -479
  48. package/data/client/misc.ts +101 -101
  49. package/data/client/product.ts +89 -89
  50. package/data/client/user.ts +99 -99
  51. package/data/client/wishlist.ts +118 -88
  52. package/data/server/category.ts +132 -128
  53. package/data/server/flatpage.ts +21 -21
  54. package/data/server/form.ts +22 -22
  55. package/data/server/index.ts +10 -10
  56. package/data/server/landingpage.ts +24 -24
  57. package/data/server/list.ts +67 -62
  58. package/data/server/menu.ts +35 -35
  59. package/data/server/product.ts +86 -86
  60. package/data/server/seo.ts +48 -48
  61. package/data/server/special-page.ts +47 -47
  62. package/data/server/widget.ts +27 -27
  63. package/data/urls.ts +221 -210
  64. package/hocs/client/index.ts +1 -1
  65. package/hocs/client/with-segment-defaults.tsx +25 -25
  66. package/hocs/server/index.ts +1 -1
  67. package/hocs/server/with-segment-defaults.tsx +85 -85
  68. package/hooks/index.ts +10 -10
  69. package/hooks/use-captcha.tsx +76 -76
  70. package/hooks/use-common-product-attributes.ts +36 -36
  71. package/hooks/use-debounce.ts +20 -20
  72. package/hooks/use-localization.ts +78 -78
  73. package/hooks/use-media-query.ts +36 -36
  74. package/hooks/use-mobile-iframe-handler.ts +23 -23
  75. package/hooks/use-on-click-outside.tsx +28 -28
  76. package/hooks/use-payment-options.ts +12 -16
  77. package/hooks/use-router.ts +45 -45
  78. package/hooks/use-translation.ts +14 -14
  79. package/lib/cache.ts +215 -215
  80. package/localization/index.ts +5 -5
  81. package/localization/provider.tsx +58 -58
  82. package/middlewares/currency.ts +100 -100
  83. package/middlewares/default.ts +256 -256
  84. package/middlewares/index.ts +29 -29
  85. package/middlewares/locale.ts +68 -68
  86. package/middlewares/oauth-login.ts +79 -79
  87. package/middlewares/pretty-url.ts +104 -104
  88. package/middlewares/redirection-payment.ts +160 -160
  89. package/middlewares/three-d-redirection.ts +159 -159
  90. package/middlewares/url-redirection.ts +65 -65
  91. package/package.json +2 -2
  92. package/plugins.js +2 -1
  93. package/redux/hooks.ts +7 -7
  94. package/redux/middlewares/checkout.ts +265 -260
  95. package/redux/middlewares/index.ts +50 -50
  96. package/redux/reducers/checkout.ts +184 -171
  97. package/redux/reducers/config.ts +28 -28
  98. package/redux/reducers/header.ts +59 -59
  99. package/redux/reducers/index.ts +14 -14
  100. package/redux/reducers/root.ts +61 -61
  101. package/sentry/index.ts +27 -27
  102. package/tailwind/rtl.js +137 -137
  103. package/types/commerce/account.ts +64 -64
  104. package/types/commerce/address.ts +94 -94
  105. package/types/commerce/b2b.ts +117 -117
  106. package/types/commerce/basket.ts +43 -43
  107. package/types/commerce/category.ts +114 -114
  108. package/types/commerce/checkout.ts +143 -136
  109. package/types/commerce/flatpage.ts +7 -7
  110. package/types/commerce/form.ts +66 -66
  111. package/types/commerce/index.ts +12 -12
  112. package/types/commerce/landingpage.ts +7 -7
  113. package/types/commerce/misc.ts +127 -127
  114. package/types/commerce/order.ts +119 -119
  115. package/types/commerce/product.ts +109 -109
  116. package/types/commerce/widget.ts +28 -28
  117. package/types/gtm.ts +16 -16
  118. package/types/index.ts +274 -237
  119. package/types/metadata.ts +7 -7
  120. package/types/next-auth.d.ts +24 -24
  121. package/utils/app-fetch.ts +69 -69
  122. package/utils/deep-merge.js +24 -24
  123. package/utils/generate-commerce-search-params.ts +22 -22
  124. package/utils/get-currency.ts +29 -29
  125. package/utils/image-loader.ts +31 -31
  126. package/utils/index.ts +150 -150
  127. package/utils/localization.ts +29 -29
  128. package/utils/log.ts +138 -138
  129. package/utils/menu-generator.ts +27 -27
  130. package/utils/mobile-3d-iframe.ts +77 -77
  131. package/utils/server-translation.ts +57 -57
  132. package/utils/server-variables.ts +9 -9
  133. package/with-pz-config.js +94 -94
@@ -1,85 +1,85 @@
1
- import settings from 'settings';
2
- import { LayoutProps, PageProps, RootLayoutProps } from '../../types';
3
- import { redirect } from 'next/navigation';
4
- import { ServerVariables } from '../../utils/server-variables';
5
- import { getTranslations } from '../../utils/server-translation';
6
- import { ROUTES } from 'routes';
7
- import logger from '../../utils/log';
8
-
9
- type SegmentType = 'root-layout' | 'layout' | 'page';
10
-
11
- interface SegmentDefaultsOptions {
12
- segmentType: SegmentType;
13
- }
14
-
15
- export const withSegmentDefaults =
16
- <T extends PageProps | LayoutProps | RootLayoutProps>(
17
- Component: (
18
- props?: T
19
- ) => null | JSX.Element | Promise<JSX.Element> | Promise<JSX.Element[]>,
20
- options: SegmentDefaultsOptions
21
- ) =>
22
- async (props: T) => {
23
- let componentProps = { ...props };
24
-
25
- if (options.segmentType === 'root-layout') {
26
- componentProps = (await addRootLayoutProps(
27
- componentProps as RootLayoutProps
28
- )) as T;
29
-
30
- checkRedisVariables();
31
- }
32
-
33
- ServerVariables.locale = props.params.locale;
34
- ServerVariables.currency = props.params.currency;
35
-
36
- return await (
37
- <>
38
- <Component {...componentProps} />
39
- </>
40
- );
41
- };
42
-
43
- const addRootLayoutProps = async (componentProps: RootLayoutProps) => {
44
- const params = componentProps.params;
45
-
46
- if (
47
- params.commerce !== encodeURIComponent(decodeURI(settings.commerceUrl)) ||
48
- !settings.localization.locales.find((l) => l.value === params.locale)
49
- ) {
50
- return redirect(ROUTES.HOME);
51
- }
52
-
53
- const translations = await getTranslations(params.locale);
54
- componentProps.translations = translations;
55
-
56
- const locale = settings.localization.locales.find(
57
- (l) => l.value === params.locale
58
- );
59
- const [isoCode] = locale.value.split('-');
60
-
61
- componentProps.locale = {
62
- ...locale,
63
- isoCode
64
- };
65
-
66
- return componentProps;
67
- };
68
-
69
- const checkRedisVariables = () => {
70
- const requiredVariableValues = [
71
- process.env.CACHE_HOST,
72
- process.env.CACHE_PORT,
73
- process.env.CACHE_SECRET
74
- ];
75
-
76
- if (
77
- !requiredVariableValues.every((v) => v) &&
78
- process.env.NODE_ENV === 'production'
79
- ) {
80
- logger.warn('Redis cache variables are not set', {
81
- requiredVariables: ['CACHE_HOST', 'CACHE_PORT', 'CACHE_SECRET'],
82
- values: requiredVariableValues
83
- });
84
- }
85
- };
1
+ import settings from 'settings';
2
+ import { LayoutProps, PageProps, RootLayoutProps } from '../../types';
3
+ import { redirect } from 'next/navigation';
4
+ import { ServerVariables } from '../../utils/server-variables';
5
+ import { getTranslations } from '../../utils/server-translation';
6
+ import { ROUTES } from 'routes';
7
+ import logger from '../../utils/log';
8
+
9
+ type SegmentType = 'root-layout' | 'layout' | 'page';
10
+
11
+ interface SegmentDefaultsOptions {
12
+ segmentType: SegmentType;
13
+ }
14
+
15
+ export const withSegmentDefaults =
16
+ <T extends PageProps | LayoutProps | RootLayoutProps>(
17
+ Component: (
18
+ props?: T
19
+ ) => null | JSX.Element | Promise<JSX.Element> | Promise<JSX.Element[]>,
20
+ options: SegmentDefaultsOptions
21
+ ) =>
22
+ async (props: T) => {
23
+ let componentProps = { ...props };
24
+
25
+ if (options.segmentType === 'root-layout') {
26
+ componentProps = (await addRootLayoutProps(
27
+ componentProps as RootLayoutProps
28
+ )) as T;
29
+
30
+ checkRedisVariables();
31
+ }
32
+
33
+ ServerVariables.locale = props.params.locale;
34
+ ServerVariables.currency = props.params.currency;
35
+
36
+ return await (
37
+ <>
38
+ <Component {...componentProps} />
39
+ </>
40
+ );
41
+ };
42
+
43
+ const addRootLayoutProps = async (componentProps: RootLayoutProps) => {
44
+ const params = componentProps.params;
45
+
46
+ if (
47
+ params.commerce !== encodeURIComponent(decodeURI(settings.commerceUrl)) ||
48
+ !settings.localization.locales.find((l) => l.value === params.locale)
49
+ ) {
50
+ return redirect(ROUTES.HOME);
51
+ }
52
+
53
+ const translations = await getTranslations(params.locale);
54
+ componentProps.translations = translations;
55
+
56
+ const locale = settings.localization.locales.find(
57
+ (l) => l.value === params.locale
58
+ );
59
+ const [isoCode] = locale.value.split('-');
60
+
61
+ componentProps.locale = {
62
+ ...locale,
63
+ isoCode
64
+ };
65
+
66
+ return componentProps;
67
+ };
68
+
69
+ const checkRedisVariables = () => {
70
+ const requiredVariableValues = [
71
+ process.env.CACHE_HOST,
72
+ process.env.CACHE_PORT,
73
+ process.env.CACHE_SECRET
74
+ ];
75
+
76
+ if (
77
+ !requiredVariableValues.every((v) => v) &&
78
+ process.env.NODE_ENV === 'production'
79
+ ) {
80
+ logger.warn('Redis cache variables are not set', {
81
+ requiredVariables: ['CACHE_HOST', 'CACHE_PORT', 'CACHE_SECRET'],
82
+ values: requiredVariableValues
83
+ });
84
+ }
85
+ };
package/hooks/index.ts CHANGED
@@ -1,10 +1,10 @@
1
- export * from './use-router';
2
- export * from './use-localization';
3
- export * from './use-translation';
4
- export * from './use-captcha';
5
- export * from './use-common-product-attributes';
6
- export * from './use-debounce';
7
- export * from './use-media-query';
8
- export * from './use-on-click-outside';
9
- export * from './use-mobile-iframe-handler';
10
- export * from './use-payment-options';
1
+ export * from './use-router';
2
+ export * from './use-localization';
3
+ export * from './use-translation';
4
+ export * from './use-captcha';
5
+ export * from './use-common-product-attributes';
6
+ export * from './use-debounce';
7
+ export * from './use-media-query';
8
+ export * from './use-on-click-outside';
9
+ export * from './use-mobile-iframe-handler';
10
+ export * from './use-payment-options';
@@ -1,76 +1,76 @@
1
- 'use client';
2
-
3
- import { useCallback, useEffect, useMemo, useState } from 'react';
4
- import ReCAPTCHA from 'react-google-recaptcha';
5
- import {
6
- useGetCaptchaQuery,
7
- useValidateCaptchaMutation
8
- } from '../data/client/user';
9
- import { setCookie } from '../utils';
10
-
11
- interface CaptchaViewProps {
12
- className?: string;
13
- }
14
-
15
- export const useCaptcha = () => {
16
- const { data } = useGetCaptchaQuery();
17
- const { siteKey, csrfToken } = data ?? {};
18
- const [validateCaptchaMutation] = useValidateCaptchaMutation();
19
- const [validated, setValidated] = useState<boolean>(false);
20
- const [isVisible, setIsVisible] = useState<boolean>(false);
21
- const [captchaResponse, setCaptchaResponse] = useState<string>(null);
22
-
23
- const validate = async () => {
24
- if (!captchaResponse) {
25
- setIsVisible(true);
26
- return false;
27
- }
28
-
29
- setValidated(false);
30
-
31
- const response = await validateCaptchaMutation({
32
- captchaResponse,
33
- csrfToken
34
- }).unwrap();
35
-
36
- setValidated(response.success);
37
-
38
- return response.success;
39
- };
40
-
41
- if (csrfToken) {
42
- setCookie('csrftoken', csrfToken);
43
- }
44
-
45
- const onCaptchaChange = useCallback(async (response) => {
46
- setTimeout(() => {
47
- setCaptchaResponse(response);
48
- }, 500);
49
- }, []);
50
-
51
- useEffect(() => {
52
- if (captchaResponse) {
53
- validate();
54
- }
55
- }, [captchaResponse]);
56
-
57
- const CaptchaView = useMemo(() => {
58
- const View = (props: CaptchaViewProps) =>
59
- isVisible && !captchaResponse ? (
60
- <ReCAPTCHA
61
- sitekey={siteKey}
62
- onChange={onCaptchaChange}
63
- className={props.className}
64
- />
65
- ) : null;
66
-
67
- return View;
68
- }, [siteKey, onCaptchaChange, isVisible, captchaResponse]);
69
-
70
- return {
71
- CaptchaView,
72
- validated,
73
- isVisible,
74
- validate
75
- };
76
- };
1
+ 'use client';
2
+
3
+ import { useCallback, useEffect, useMemo, useState } from 'react';
4
+ import ReCAPTCHA from 'react-google-recaptcha';
5
+ import {
6
+ useGetCaptchaQuery,
7
+ useValidateCaptchaMutation
8
+ } from '../data/client/user';
9
+ import { setCookie } from '../utils';
10
+
11
+ interface CaptchaViewProps {
12
+ className?: string;
13
+ }
14
+
15
+ export const useCaptcha = () => {
16
+ const { data } = useGetCaptchaQuery();
17
+ const { siteKey, csrfToken } = data ?? {};
18
+ const [validateCaptchaMutation] = useValidateCaptchaMutation();
19
+ const [validated, setValidated] = useState<boolean>(false);
20
+ const [isVisible, setIsVisible] = useState<boolean>(false);
21
+ const [captchaResponse, setCaptchaResponse] = useState<string>(null);
22
+
23
+ const validate = async () => {
24
+ if (!captchaResponse) {
25
+ setIsVisible(true);
26
+ return false;
27
+ }
28
+
29
+ setValidated(false);
30
+
31
+ const response = await validateCaptchaMutation({
32
+ captchaResponse,
33
+ csrfToken
34
+ }).unwrap();
35
+
36
+ setValidated(response.success);
37
+
38
+ return response.success;
39
+ };
40
+
41
+ if (csrfToken) {
42
+ setCookie('csrftoken', csrfToken);
43
+ }
44
+
45
+ const onCaptchaChange = useCallback(async (response) => {
46
+ setTimeout(() => {
47
+ setCaptchaResponse(response);
48
+ }, 500);
49
+ }, []);
50
+
51
+ useEffect(() => {
52
+ if (captchaResponse) {
53
+ validate();
54
+ }
55
+ }, [captchaResponse]);
56
+
57
+ const CaptchaView = useMemo(() => {
58
+ const View = (props: CaptchaViewProps) =>
59
+ isVisible && !captchaResponse ? (
60
+ <ReCAPTCHA
61
+ sitekey={siteKey}
62
+ onChange={onCaptchaChange}
63
+ className={props.className}
64
+ />
65
+ ) : null;
66
+
67
+ return View;
68
+ }, [siteKey, onCaptchaChange, isVisible, captchaResponse]);
69
+
70
+ return {
71
+ CaptchaView,
72
+ validated,
73
+ isVisible,
74
+ validate
75
+ };
76
+ };
@@ -1,36 +1,36 @@
1
- 'use client';
2
-
3
- import Settings from 'settings';
4
- import { useLocalization } from './use-localization';
5
-
6
- type UseCommonProductAttributesArgs = {
7
- attributes: { [key: string]: { value: string } };
8
- };
9
-
10
- type CommonProductAttributes = { name: string; value: string }[];
11
-
12
- export const useCommonProductAttributes = (
13
- args: UseCommonProductAttributesArgs
14
- ) => {
15
- const { attributes } = args;
16
- const commonProductAttributes: CommonProductAttributes = [];
17
- const { t } = useLocalization();
18
-
19
- Settings.commonProductAttributes.forEach((commonProductAttribute) => {
20
- const attribute = Object.entries(attributes).find(
21
- // Object.entries gives us an array of [key, value] pairs.
22
- ([key]) => key === commonProductAttribute.key
23
- )?.[1]; // We only want the value, so we get the second item in the array.
24
-
25
- if (attribute) {
26
- commonProductAttributes.push({
27
- name: t(
28
- `common.common_product_attributes.${commonProductAttribute.translationKey}`
29
- ),
30
- value: attribute.value
31
- });
32
- }
33
- });
34
-
35
- return commonProductAttributes;
36
- };
1
+ 'use client';
2
+
3
+ import Settings from 'settings';
4
+ import { useLocalization } from './use-localization';
5
+
6
+ type UseCommonProductAttributesArgs = {
7
+ attributes: { [key: string]: { value: string } };
8
+ };
9
+
10
+ type CommonProductAttributes = { name: string; value: string }[];
11
+
12
+ export const useCommonProductAttributes = (
13
+ args: UseCommonProductAttributesArgs
14
+ ) => {
15
+ const { attributes } = args;
16
+ const commonProductAttributes: CommonProductAttributes = [];
17
+ const { t } = useLocalization();
18
+
19
+ Settings.commonProductAttributes.forEach((commonProductAttribute) => {
20
+ const attribute = Object.entries(attributes).find(
21
+ // Object.entries gives us an array of [key, value] pairs.
22
+ ([key]) => key === commonProductAttribute.key
23
+ )?.[1]; // We only want the value, so we get the second item in the array.
24
+
25
+ if (attribute) {
26
+ commonProductAttributes.push({
27
+ name: t(
28
+ `common.common_product_attributes.${commonProductAttribute.translationKey}`
29
+ ),
30
+ value: attribute.value
31
+ });
32
+ }
33
+ });
34
+
35
+ return commonProductAttributes;
36
+ };
@@ -1,20 +1,20 @@
1
- // https://usehooks.com/useDebounce/
2
- 'use client';
3
-
4
- import { useEffect, useState } from 'react';
5
-
6
- export function useDebounce<T>(value: T, delay: number): T {
7
- const [debouncedValue, setDebouncedValue] = useState<T>(value);
8
-
9
- useEffect(() => {
10
- const handler = setTimeout(() => {
11
- setDebouncedValue(value);
12
- }, delay);
13
-
14
- return () => {
15
- clearTimeout(handler);
16
- };
17
- }, [value, delay]);
18
-
19
- return debouncedValue;
20
- }
1
+ // https://usehooks.com/useDebounce/
2
+ 'use client';
3
+
4
+ import { useEffect, useState } from 'react';
5
+
6
+ export function useDebounce<T>(value: T, delay: number): T {
7
+ const [debouncedValue, setDebouncedValue] = useState<T>(value);
8
+
9
+ useEffect(() => {
10
+ const handler = setTimeout(() => {
11
+ setDebouncedValue(value);
12
+ }, delay);
13
+
14
+ return () => {
15
+ clearTimeout(handler);
16
+ };
17
+ }, [value, delay]);
18
+
19
+ return debouncedValue;
20
+ }
@@ -1,78 +1,78 @@
1
- 'use client';
2
-
3
- import { LocalizationContext } from '../localization/provider';
4
- import { useContext } from 'react';
5
- import { setCookie, urlLocaleMatcherRegex } from '../utils';
6
- import { LocaleUrlStrategy } from '../localization';
7
- import { useRouter } from 'next/navigation';
8
-
9
- export const useLocalization = () => {
10
- const {
11
- translate,
12
- locale,
13
- currency,
14
- locales,
15
- currencies,
16
- defaultLocaleValue,
17
- defaultCurrencyCode,
18
- localeUrlStrategy
19
- } = useContext(LocalizationContext);
20
-
21
- const router = useRouter();
22
-
23
- /**
24
- * Sets the locale in the URL.
25
- * @param locale Locale value defined in the settings.
26
- */
27
- const setLocale = (locale: string) => {
28
- const localePath =
29
- locale === defaultLocaleValue &&
30
- localeUrlStrategy !== LocaleUrlStrategy.ShowAllLocales
31
- ? ''
32
- : `/${locale}`;
33
-
34
- const pathnameWithoutLocale = location.pathname.replace(
35
- urlLocaleMatcherRegex,
36
- ''
37
- );
38
-
39
- // router.push is not used because reloading the page also clears the client side cache.
40
- location.href = `${localePath}${pathnameWithoutLocale}${location.search}`;
41
- };
42
-
43
- /**
44
- * Sets the currency.
45
- *
46
- * If the currency is linked to the locale by using `getActiveCurrencyCode` function in the settings,
47
- * you need to use `setLocale` instead of this.
48
- * @param currency Currency code defined in the settings.
49
- */
50
- const setCurrency = (currency: string) => {
51
- // It is a temp cookie to set currency in `currency` middleware.
52
- setCookie('pz-set-currency', currency);
53
- location.reload();
54
- };
55
-
56
- return {
57
- /**
58
- * Translate function
59
- * @param path
60
- * Path of the translation.
61
- * It is a dot separated string e.g. "common.header.title".
62
- * "common" is the file name in the translations folder.
63
- * "header" is the key in the file.
64
- * "title" is the value of the key.
65
- * @returns {string} Translated value
66
- */
67
- t: (path: string) => translate(path),
68
- setLocale,
69
- setCurrency,
70
- locale,
71
- currency,
72
- locales,
73
- currencies,
74
- defaultLocaleValue,
75
- defaultCurrencyCode,
76
- localeUrlStrategy
77
- };
78
- };
1
+ 'use client';
2
+
3
+ import { LocalizationContext } from '../localization/provider';
4
+ import { useContext } from 'react';
5
+ import { setCookie, urlLocaleMatcherRegex } from '../utils';
6
+ import { LocaleUrlStrategy } from '../localization';
7
+ import { useRouter } from 'next/navigation';
8
+
9
+ export const useLocalization = () => {
10
+ const {
11
+ translate,
12
+ locale,
13
+ currency,
14
+ locales,
15
+ currencies,
16
+ defaultLocaleValue,
17
+ defaultCurrencyCode,
18
+ localeUrlStrategy
19
+ } = useContext(LocalizationContext);
20
+
21
+ const router = useRouter();
22
+
23
+ /**
24
+ * Sets the locale in the URL.
25
+ * @param locale Locale value defined in the settings.
26
+ */
27
+ const setLocale = (locale: string) => {
28
+ const localePath =
29
+ locale === defaultLocaleValue &&
30
+ localeUrlStrategy !== LocaleUrlStrategy.ShowAllLocales
31
+ ? ''
32
+ : `/${locale}`;
33
+
34
+ const pathnameWithoutLocale = location.pathname.replace(
35
+ urlLocaleMatcherRegex,
36
+ ''
37
+ );
38
+
39
+ // router.push is not used because reloading the page also clears the client side cache.
40
+ location.href = `${localePath}${pathnameWithoutLocale}${location.search}`;
41
+ };
42
+
43
+ /**
44
+ * Sets the currency.
45
+ *
46
+ * If the currency is linked to the locale by using `getActiveCurrencyCode` function in the settings,
47
+ * you need to use `setLocale` instead of this.
48
+ * @param currency Currency code defined in the settings.
49
+ */
50
+ const setCurrency = (currency: string) => {
51
+ // It is a temp cookie to set currency in `currency` middleware.
52
+ setCookie('pz-set-currency', currency);
53
+ location.reload();
54
+ };
55
+
56
+ return {
57
+ /**
58
+ * Translate function
59
+ * @param path
60
+ * Path of the translation.
61
+ * It is a dot separated string e.g. "common.header.title".
62
+ * "common" is the file name in the translations folder.
63
+ * "header" is the key in the file.
64
+ * "title" is the value of the key.
65
+ * @returns {string} Translated value
66
+ */
67
+ t: (path: string) => translate(path),
68
+ setLocale,
69
+ setCurrency,
70
+ locale,
71
+ currency,
72
+ locales,
73
+ currencies,
74
+ defaultLocaleValue,
75
+ defaultCurrencyCode,
76
+ localeUrlStrategy
77
+ };
78
+ };