@akinon/next 1.14.0 → 1.15.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/.editorconfig +7 -7
- package/.eslintrc.js +40 -40
- package/.gitattributes +15 -0
- package/.prettierrc +13 -13
- package/CHANGELOG.md +14 -0
- package/api/auth.ts +231 -231
- package/api/cache.ts +44 -44
- package/api/client.ts +174 -174
- package/api/logout.ts +42 -42
- package/bin/pz-check-dependencies.js +98 -98
- package/bin/pz-install-plugins.js +33 -33
- package/bin/pz-install-theme.js +58 -58
- package/bin/pz-postbuild.js +1 -1
- package/bin/pz-postdev.js +1 -1
- package/bin/pz-postinstall.js +6 -6
- package/bin/pz-poststart.js +1 -1
- package/bin/pz-prebuild.js +4 -4
- package/bin/pz-predev.js +4 -4
- package/bin/pz-prestart.js +1 -1
- package/bin/run-script.js +44 -44
- package/components/accordion.tsx +52 -52
- package/components/button.tsx +46 -46
- package/components/client-root.tsx +19 -19
- package/components/icon.tsx +18 -18
- package/components/image.tsx +133 -133
- package/components/index.ts +1 -0
- package/components/input.tsx +110 -110
- package/components/lazy-component.tsx +33 -33
- package/components/loader-spinner.tsx +23 -23
- package/components/mobile-app-toggler.tsx +26 -26
- package/components/modal.tsx +66 -0
- package/components/oauth-login.tsx +24 -24
- package/components/plugin-module.tsx +5 -0
- package/components/price.tsx +55 -55
- package/components/pz-providers.tsx +24 -24
- package/components/pz-root.tsx +21 -21
- package/components/radio.tsx +18 -18
- package/components/react-portal.tsx +45 -45
- package/components/redirect-three-d/content/index.tsx +74 -74
- package/components/redirect-three-d/index.tsx +17 -17
- package/components/selected-payment-option-view.tsx +1 -1
- package/components/trans.tsx +39 -39
- package/data/client/account.ts +208 -208
- package/data/client/api.ts +85 -85
- package/data/client/basket.ts +82 -82
- package/data/client/misc.ts +101 -101
- package/data/client/product.ts +89 -89
- package/data/client/user.ts +99 -99
- package/data/client/wishlist.ts +118 -118
- package/data/server/category.ts +132 -132
- package/data/server/flatpage.ts +21 -21
- package/data/server/form.ts +22 -22
- package/data/server/index.ts +10 -10
- package/data/server/landingpage.ts +24 -24
- package/data/server/list.ts +67 -67
- package/data/server/menu.ts +35 -35
- package/data/server/product.ts +86 -86
- package/data/server/seo.ts +48 -48
- package/data/server/special-page.ts +47 -47
- package/data/server/widget.ts +27 -27
- package/data/urls.ts +221 -221
- package/hocs/client/index.ts +1 -1
- package/hocs/client/with-segment-defaults.tsx +25 -25
- package/hocs/server/index.ts +1 -1
- package/hocs/server/with-segment-defaults.tsx +85 -85
- package/hooks/index.ts +10 -10
- package/hooks/use-captcha.tsx +76 -76
- package/hooks/use-common-product-attributes.ts +36 -36
- package/hooks/use-debounce.ts +20 -20
- package/hooks/use-localization.ts +78 -78
- package/hooks/use-media-query.ts +36 -36
- package/hooks/use-mobile-iframe-handler.ts +23 -23
- package/hooks/use-on-click-outside.tsx +28 -28
- package/hooks/use-payment-options.ts +3 -1
- package/hooks/use-router.ts +45 -45
- package/hooks/use-translation.ts +14 -14
- package/lib/cache.ts +215 -215
- package/localization/index.ts +5 -5
- package/localization/provider.tsx +58 -58
- package/middlewares/complete-gpay.ts +159 -0
- package/middlewares/currency.ts +100 -100
- package/middlewares/default.ts +259 -256
- package/middlewares/index.ts +31 -29
- package/middlewares/locale.ts +68 -68
- package/middlewares/oauth-login.ts +79 -79
- package/middlewares/pretty-url.ts +104 -104
- package/middlewares/redirection-payment.ts +160 -160
- package/middlewares/three-d-redirection.ts +159 -159
- package/middlewares/url-redirection.ts +65 -65
- package/package.json +2 -2
- package/plugins.js +1 -0
- package/redux/hooks.ts +7 -7
- package/redux/middlewares/index.ts +50 -50
- package/redux/reducers/checkout.ts +184 -184
- package/redux/reducers/config.ts +28 -28
- package/redux/reducers/header.ts +59 -59
- package/redux/reducers/root.ts +61 -61
- package/sentry/index.ts +27 -27
- package/tailwind/rtl.js +137 -137
- package/types/commerce/account.ts +64 -64
- package/types/commerce/address.ts +94 -94
- package/types/commerce/basket.ts +43 -43
- package/types/commerce/category.ts +114 -114
- package/types/commerce/checkout.ts +143 -143
- package/types/commerce/flatpage.ts +7 -7
- package/types/commerce/form.ts +66 -66
- package/types/commerce/index.ts +12 -12
- package/types/commerce/landingpage.ts +7 -7
- package/types/commerce/misc.ts +127 -127
- package/types/commerce/order.ts +119 -119
- package/types/commerce/product.ts +109 -109
- package/types/commerce/widget.ts +28 -28
- package/types/gtm.ts +16 -16
- package/types/index.ts +274 -274
- package/types/metadata.ts +7 -7
- package/types/next-auth.d.ts +24 -24
- package/utils/app-fetch.ts +69 -69
- package/utils/deep-merge.js +24 -24
- package/utils/image-loader.ts +31 -31
- package/utils/index.ts +150 -150
- package/utils/localization.ts +29 -29
- package/utils/log.ts +138 -138
- package/utils/menu-generator.ts +27 -27
- package/utils/mobile-3d-iframe.ts +77 -77
- package/utils/server-translation.ts +57 -57
- package/utils/server-variables.ts +9 -9
- package/with-pz-config.js +94 -94
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import clsx from 'clsx';
|
|
4
|
-
import { useEffect, useState } from 'react';
|
|
5
|
-
import { useInView } from 'react-intersection-observer';
|
|
6
|
-
|
|
7
|
-
interface LazyComponentProps {
|
|
8
|
-
children: React.ReactNode;
|
|
9
|
-
className?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export default function LazyComponent({
|
|
13
|
-
children,
|
|
14
|
-
className
|
|
15
|
-
}: LazyComponentProps) {
|
|
16
|
-
const [isInView, setIsInView] = useState(false);
|
|
17
|
-
|
|
18
|
-
const { ref, inView } = useInView({
|
|
19
|
-
threshold: 0
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
if (inView) {
|
|
24
|
-
setIsInView(true);
|
|
25
|
-
}
|
|
26
|
-
}, [inView]);
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<div ref={ref} className={clsx(className)}>
|
|
30
|
-
{isInView ? <>{children}</> : null}
|
|
31
|
-
</div>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import clsx from 'clsx';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
import { useInView } from 'react-intersection-observer';
|
|
6
|
+
|
|
7
|
+
interface LazyComponentProps {
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default function LazyComponent({
|
|
13
|
+
children,
|
|
14
|
+
className
|
|
15
|
+
}: LazyComponentProps) {
|
|
16
|
+
const [isInView, setIsInView] = useState(false);
|
|
17
|
+
|
|
18
|
+
const { ref, inView } = useInView({
|
|
19
|
+
threshold: 0
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (inView) {
|
|
24
|
+
setIsInView(true);
|
|
25
|
+
}
|
|
26
|
+
}, [inView]);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div ref={ref} className={clsx(className)}>
|
|
30
|
+
{isInView ? <>{children}</> : null}
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { twMerge } from 'tailwind-merge';
|
|
2
|
-
|
|
3
|
-
type LoaderSpinnerProps = {
|
|
4
|
-
className?: string;
|
|
5
|
-
borderType?: 'solid' | 'dotted' | 'dashed';
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export const LoaderSpinner: React.FC<LoaderSpinnerProps> = ({
|
|
9
|
-
borderType = 'solid',
|
|
10
|
-
className
|
|
11
|
-
}) => {
|
|
12
|
-
return (
|
|
13
|
-
<div className="w-full h-full flex justify-center items-center">
|
|
14
|
-
<div
|
|
15
|
-
className={twMerge(
|
|
16
|
-
'w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin',
|
|
17
|
-
`border-${borderType}`,
|
|
18
|
-
className
|
|
19
|
-
)}
|
|
20
|
-
/>
|
|
21
|
-
</div>
|
|
22
|
-
);
|
|
23
|
-
};
|
|
1
|
+
import { twMerge } from 'tailwind-merge';
|
|
2
|
+
|
|
3
|
+
type LoaderSpinnerProps = {
|
|
4
|
+
className?: string;
|
|
5
|
+
borderType?: 'solid' | 'dotted' | 'dashed';
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const LoaderSpinner: React.FC<LoaderSpinnerProps> = ({
|
|
9
|
+
borderType = 'solid',
|
|
10
|
+
className
|
|
11
|
+
}) => {
|
|
12
|
+
return (
|
|
13
|
+
<div className="w-full h-full flex justify-center items-center">
|
|
14
|
+
<div
|
|
15
|
+
className={twMerge(
|
|
16
|
+
'w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin',
|
|
17
|
+
`border-${borderType}`,
|
|
18
|
+
className
|
|
19
|
+
)}
|
|
20
|
+
/>
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { useAppSelector } from '../redux/hooks';
|
|
4
|
-
import { useState, useEffect } from 'react';
|
|
5
|
-
import { useSearchParams } from 'next/navigation';
|
|
6
|
-
|
|
7
|
-
export default function MobileAppToggler({
|
|
8
|
-
children
|
|
9
|
-
}: {
|
|
10
|
-
children: React.ReactNode;
|
|
11
|
-
}) {
|
|
12
|
-
const searchParams = useSearchParams();
|
|
13
|
-
const { isMobileApp } = useAppSelector((state) => state.root);
|
|
14
|
-
const [isInIframe, setIsInIframe] = useState(false);
|
|
15
|
-
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
if (window.frameElement) {
|
|
18
|
-
setIsInIframe(true);
|
|
19
|
-
}
|
|
20
|
-
}, []);
|
|
21
|
-
|
|
22
|
-
if (isMobileApp || isInIframe || searchParams.get('iframe') === 'true')
|
|
23
|
-
return null;
|
|
24
|
-
|
|
25
|
-
return <>{children}</>;
|
|
26
|
-
}
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useAppSelector } from '../redux/hooks';
|
|
4
|
+
import { useState, useEffect } from 'react';
|
|
5
|
+
import { useSearchParams } from 'next/navigation';
|
|
6
|
+
|
|
7
|
+
export default function MobileAppToggler({
|
|
8
|
+
children
|
|
9
|
+
}: {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
}) {
|
|
12
|
+
const searchParams = useSearchParams();
|
|
13
|
+
const { isMobileApp } = useAppSelector((state) => state.root);
|
|
14
|
+
const [isInIframe, setIsInIframe] = useState(false);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (window.frameElement) {
|
|
18
|
+
setIsInIframe(true);
|
|
19
|
+
}
|
|
20
|
+
}, []);
|
|
21
|
+
|
|
22
|
+
if (isMobileApp || isInIframe || searchParams.get('iframe') === 'true')
|
|
23
|
+
return null;
|
|
24
|
+
|
|
25
|
+
return <>{children}</>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { ReactPortal } from './react-portal';
|
|
4
|
+
|
|
5
|
+
import { Icon } from './icon';
|
|
6
|
+
import { twMerge } from 'tailwind-merge';
|
|
7
|
+
import { useEffect } from 'react';
|
|
8
|
+
export interface ModalProps {
|
|
9
|
+
portalId: string;
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
open?: boolean;
|
|
12
|
+
setOpen?: (open: boolean) => void;
|
|
13
|
+
title?: React.ReactNode;
|
|
14
|
+
showCloseButton?: React.ReactNode;
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const Modal = (props: ModalProps) => {
|
|
19
|
+
const {
|
|
20
|
+
children,
|
|
21
|
+
portalId,
|
|
22
|
+
open,
|
|
23
|
+
setOpen,
|
|
24
|
+
title = '',
|
|
25
|
+
showCloseButton = true,
|
|
26
|
+
className
|
|
27
|
+
} = props;
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (open) {
|
|
31
|
+
document.body.style.overflow = 'hidden';
|
|
32
|
+
} else {
|
|
33
|
+
document.body.style.overflow = 'auto';
|
|
34
|
+
}
|
|
35
|
+
}, [open]);
|
|
36
|
+
|
|
37
|
+
if (!open) return null;
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<ReactPortal wrapperId={portalId}>
|
|
41
|
+
<div className="fixed top-0 left-0 w-screen h-screen bg-primary bg-opacity-60 z-50" />
|
|
42
|
+
<section
|
|
43
|
+
className={twMerge(
|
|
44
|
+
'fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-50 bg-white',
|
|
45
|
+
className
|
|
46
|
+
)}
|
|
47
|
+
>
|
|
48
|
+
{(showCloseButton || title) && (
|
|
49
|
+
<div className="flex px-6 py-4 border-b border-gray-400">
|
|
50
|
+
{title && <h3 className="text-lg font-light">{title}</h3>}
|
|
51
|
+
{showCloseButton && (
|
|
52
|
+
<button
|
|
53
|
+
type="button"
|
|
54
|
+
onClick={() => setOpen(false)}
|
|
55
|
+
className="ml-auto"
|
|
56
|
+
>
|
|
57
|
+
<Icon name="close" size={16} />
|
|
58
|
+
</button>
|
|
59
|
+
)}
|
|
60
|
+
</div>
|
|
61
|
+
)}
|
|
62
|
+
{children}
|
|
63
|
+
</section>
|
|
64
|
+
</ReactPortal>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { signIn, useSession } from 'next-auth/react';
|
|
4
|
-
import { useEffect } from 'react';
|
|
5
|
-
import { useSearchParams } from 'next/navigation';
|
|
6
|
-
|
|
7
|
-
export default function OauthLogin() {
|
|
8
|
-
const { status } = useSession();
|
|
9
|
-
const searchParams = useSearchParams();
|
|
10
|
-
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
if (!searchParams) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (status === 'unauthenticated') {
|
|
17
|
-
signIn('oauth', {
|
|
18
|
-
callbackUrl: searchParams.get('next') ?? '/'
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
}, [status, searchParams]);
|
|
22
|
-
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { signIn, useSession } from 'next-auth/react';
|
|
4
|
+
import { useEffect } from 'react';
|
|
5
|
+
import { useSearchParams } from 'next/navigation';
|
|
6
|
+
|
|
7
|
+
export default function OauthLogin() {
|
|
8
|
+
const { status } = useSession();
|
|
9
|
+
const searchParams = useSearchParams();
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!searchParams) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (status === 'unauthenticated') {
|
|
17
|
+
signIn('oauth', {
|
|
18
|
+
callbackUrl: searchParams.get('next') ?? '/'
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}, [status, searchParams]);
|
|
22
|
+
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
@@ -12,6 +12,7 @@ enum Plugin {
|
|
|
12
12
|
GPay = 'pz-gpay',
|
|
13
13
|
Otp = 'pz-otp',
|
|
14
14
|
BKMExpress = 'pz-bkm',
|
|
15
|
+
CreditPayment = 'pz-credit-payment',
|
|
15
16
|
Masterpass = 'pz-masterpass'
|
|
16
17
|
}
|
|
17
18
|
|
|
@@ -24,6 +25,7 @@ export enum Component {
|
|
|
24
25
|
GPay = 'GPayOption',
|
|
25
26
|
Otp = 'Otp',
|
|
26
27
|
BKMExpress = 'BKMOption',
|
|
28
|
+
CreditPayment = 'CreditPayment',
|
|
27
29
|
MasterpassCardList = 'MasterpassCardList'
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -36,6 +38,7 @@ const PluginComponents = new Map([
|
|
|
36
38
|
[Plugin.GPay, [Component.GPay]],
|
|
37
39
|
[Plugin.Otp, [Component.Otp]],
|
|
38
40
|
[Plugin.BKMExpress, [Component.BKMExpress]],
|
|
41
|
+
[Plugin.CreditPayment, [Component.CreditPayment]],
|
|
39
42
|
[Plugin.Masterpass, [Component.MasterpassCardList]]
|
|
40
43
|
]);
|
|
41
44
|
|
|
@@ -79,6 +82,8 @@ export default function PluginModule({
|
|
|
79
82
|
promise = import(`${'pz-otp'}`);
|
|
80
83
|
} else if (plugin === Plugin.BKMExpress) {
|
|
81
84
|
promise = import(`${'pz-bkm'}`);
|
|
85
|
+
} else if (plugin === Plugin.CreditPayment) {
|
|
86
|
+
promise = import(`${'pz-credit-payment'}`);
|
|
82
87
|
}
|
|
83
88
|
} catch (error) {
|
|
84
89
|
logger.error(error);
|
package/components/price.tsx
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import NumberFormat, { NumberFormatProps } from 'react-number-format';
|
|
3
|
-
import { getCurrency } from '@akinon/next/utils';
|
|
4
|
-
|
|
5
|
-
import { useLocalization } from '@akinon/next/hooks';
|
|
6
|
-
import { PriceProps } from '../types';
|
|
7
|
-
|
|
8
|
-
export const Price = (props: NumberFormatProps & PriceProps) => {
|
|
9
|
-
const {
|
|
10
|
-
value,
|
|
11
|
-
currencyCode,
|
|
12
|
-
displayType = 'text',
|
|
13
|
-
useCurrencySymbol = false,
|
|
14
|
-
useCurrencyAfterPrice = true,
|
|
15
|
-
useCurrencySpace = true,
|
|
16
|
-
useNegative = false,
|
|
17
|
-
useNegativeSpace = true,
|
|
18
|
-
thousandSeparator = '.',
|
|
19
|
-
decimalScale = 2,
|
|
20
|
-
decimalSeparator = ',',
|
|
21
|
-
fixedDecimalScale = true,
|
|
22
|
-
...rest
|
|
23
|
-
} = props;
|
|
24
|
-
const { currency: selectedCurrencyCode } = useLocalization();
|
|
25
|
-
const currencyCode_ = currencyCode || selectedCurrencyCode;
|
|
26
|
-
|
|
27
|
-
// TODO: This is very bad practice. It broke decimalScale.
|
|
28
|
-
const _value = value?.toString().replace('.', ',');
|
|
29
|
-
|
|
30
|
-
const currency = useMemo(
|
|
31
|
-
() =>
|
|
32
|
-
getCurrency({
|
|
33
|
-
currencyCode: currencyCode_,
|
|
34
|
-
useCurrencySymbol,
|
|
35
|
-
useCurrencyAfterPrice,
|
|
36
|
-
useCurrencySpace
|
|
37
|
-
}),
|
|
38
|
-
[currencyCode_, useCurrencySymbol, useCurrencyAfterPrice, useCurrencySpace]
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
return (
|
|
42
|
-
<NumberFormat
|
|
43
|
-
value={useNegative ? `-${useNegativeSpace}${_value}` : _value}
|
|
44
|
-
{...{
|
|
45
|
-
[useCurrencyAfterPrice ? 'suffix' : 'prefix']: currency
|
|
46
|
-
}}
|
|
47
|
-
displayType={displayType}
|
|
48
|
-
thousandSeparator={thousandSeparator}
|
|
49
|
-
decimalScale={decimalScale}
|
|
50
|
-
decimalSeparator={decimalSeparator}
|
|
51
|
-
fixedDecimalScale={fixedDecimalScale}
|
|
52
|
-
{...rest}
|
|
53
|
-
/>
|
|
54
|
-
);
|
|
55
|
-
};
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import NumberFormat, { NumberFormatProps } from 'react-number-format';
|
|
3
|
+
import { getCurrency } from '@akinon/next/utils';
|
|
4
|
+
|
|
5
|
+
import { useLocalization } from '@akinon/next/hooks';
|
|
6
|
+
import { PriceProps } from '../types';
|
|
7
|
+
|
|
8
|
+
export const Price = (props: NumberFormatProps & PriceProps) => {
|
|
9
|
+
const {
|
|
10
|
+
value,
|
|
11
|
+
currencyCode,
|
|
12
|
+
displayType = 'text',
|
|
13
|
+
useCurrencySymbol = false,
|
|
14
|
+
useCurrencyAfterPrice = true,
|
|
15
|
+
useCurrencySpace = true,
|
|
16
|
+
useNegative = false,
|
|
17
|
+
useNegativeSpace = true,
|
|
18
|
+
thousandSeparator = '.',
|
|
19
|
+
decimalScale = 2,
|
|
20
|
+
decimalSeparator = ',',
|
|
21
|
+
fixedDecimalScale = true,
|
|
22
|
+
...rest
|
|
23
|
+
} = props;
|
|
24
|
+
const { currency: selectedCurrencyCode } = useLocalization();
|
|
25
|
+
const currencyCode_ = currencyCode || selectedCurrencyCode;
|
|
26
|
+
|
|
27
|
+
// TODO: This is very bad practice. It broke decimalScale.
|
|
28
|
+
const _value = value?.toString().replace('.', ',');
|
|
29
|
+
|
|
30
|
+
const currency = useMemo(
|
|
31
|
+
() =>
|
|
32
|
+
getCurrency({
|
|
33
|
+
currencyCode: currencyCode_,
|
|
34
|
+
useCurrencySymbol,
|
|
35
|
+
useCurrencyAfterPrice,
|
|
36
|
+
useCurrencySpace
|
|
37
|
+
}),
|
|
38
|
+
[currencyCode_, useCurrencySymbol, useCurrencyAfterPrice, useCurrencySpace]
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<NumberFormat
|
|
43
|
+
value={useNegative ? `-${useNegativeSpace}${_value}` : _value}
|
|
44
|
+
{...{
|
|
45
|
+
[useCurrencyAfterPrice ? 'suffix' : 'prefix']: currency
|
|
46
|
+
}}
|
|
47
|
+
displayType={displayType}
|
|
48
|
+
thousandSeparator={thousandSeparator}
|
|
49
|
+
decimalScale={decimalScale}
|
|
50
|
+
decimalSeparator={decimalSeparator}
|
|
51
|
+
fixedDecimalScale={fixedDecimalScale}
|
|
52
|
+
{...rest}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import LocalizationProvider from '@akinon/next/localization/provider';
|
|
4
|
-
import { SessionProvider } from 'next-auth/react';
|
|
5
|
-
import { Provider } from 'react-redux';
|
|
6
|
-
import { store } from 'redux/store';
|
|
7
|
-
|
|
8
|
-
export default function PzProviders({
|
|
9
|
-
translations,
|
|
10
|
-
children
|
|
11
|
-
}: {
|
|
12
|
-
translations: any;
|
|
13
|
-
children: React.ReactNode;
|
|
14
|
-
}) {
|
|
15
|
-
return (
|
|
16
|
-
<Provider store={store}>
|
|
17
|
-
<SessionProvider refetchOnWindowFocus={false}>
|
|
18
|
-
<LocalizationProvider translations={translations}>
|
|
19
|
-
{children}
|
|
20
|
-
</LocalizationProvider>
|
|
21
|
-
</SessionProvider>
|
|
22
|
-
</Provider>
|
|
23
|
-
);
|
|
24
|
-
}
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import LocalizationProvider from '@akinon/next/localization/provider';
|
|
4
|
+
import { SessionProvider } from 'next-auth/react';
|
|
5
|
+
import { Provider } from 'react-redux';
|
|
6
|
+
import { store } from 'redux/store';
|
|
7
|
+
|
|
8
|
+
export default function PzProviders({
|
|
9
|
+
translations,
|
|
10
|
+
children
|
|
11
|
+
}: {
|
|
12
|
+
translations: any;
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
}) {
|
|
15
|
+
return (
|
|
16
|
+
<Provider store={store}>
|
|
17
|
+
<SessionProvider refetchOnWindowFocus={false}>
|
|
18
|
+
<LocalizationProvider translations={translations}>
|
|
19
|
+
{children}
|
|
20
|
+
</LocalizationProvider>
|
|
21
|
+
</SessionProvider>
|
|
22
|
+
</Provider>
|
|
23
|
+
);
|
|
24
|
+
}
|
package/components/pz-root.tsx
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import 'server-only';
|
|
2
|
-
import ClientRoot from './client-root';
|
|
3
|
-
import { cookies } from 'next/headers';
|
|
4
|
-
import PzProviders from './pz-providers';
|
|
5
|
-
|
|
6
|
-
export default function PzRoot({
|
|
7
|
-
translations,
|
|
8
|
-
children
|
|
9
|
-
}: {
|
|
10
|
-
translations: any;
|
|
11
|
-
children: React.ReactNode;
|
|
12
|
-
}) {
|
|
13
|
-
const nextCookies = cookies();
|
|
14
|
-
const sessionid = nextCookies.get('osessionid')?.value;
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<PzProviders translations={translations}>
|
|
18
|
-
<ClientRoot sessionId={sessionid}>{children}</ClientRoot>
|
|
19
|
-
</PzProviders>
|
|
20
|
-
);
|
|
21
|
-
}
|
|
1
|
+
import 'server-only';
|
|
2
|
+
import ClientRoot from './client-root';
|
|
3
|
+
import { cookies } from 'next/headers';
|
|
4
|
+
import PzProviders from './pz-providers';
|
|
5
|
+
|
|
6
|
+
export default function PzRoot({
|
|
7
|
+
translations,
|
|
8
|
+
children
|
|
9
|
+
}: {
|
|
10
|
+
translations: any;
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}) {
|
|
13
|
+
const nextCookies = cookies();
|
|
14
|
+
const sessionid = nextCookies.get('osessionid')?.value;
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<PzProviders translations={translations}>
|
|
18
|
+
<ClientRoot sessionId={sessionid}>{children}</ClientRoot>
|
|
19
|
+
</PzProviders>
|
|
20
|
+
);
|
|
21
|
+
}
|
package/components/radio.tsx
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { forwardRef } from 'react';
|
|
2
|
-
import { RadioProps } from '../types/index';
|
|
3
|
-
import { twMerge } from 'tailwind-merge';
|
|
4
|
-
|
|
5
|
-
const Radio = forwardRef<HTMLInputElement, RadioProps>((props, ref) => {
|
|
6
|
-
const { children, ...rest } = props;
|
|
7
|
-
|
|
8
|
-
return (
|
|
9
|
-
<label className={twMerge('flex items-center text-xs', props.className)}>
|
|
10
|
-
<input type="radio" {...rest} ref={ref} className="w-4 h-4" />
|
|
11
|
-
{children && <span className="text-xs ml-2">{children}</span>}
|
|
12
|
-
</label>
|
|
13
|
-
);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
Radio.displayName = 'Radio';
|
|
17
|
-
|
|
18
|
-
export { Radio };
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
import { RadioProps } from '../types/index';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
|
|
5
|
+
const Radio = forwardRef<HTMLInputElement, RadioProps>((props, ref) => {
|
|
6
|
+
const { children, ...rest } = props;
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<label className={twMerge('flex items-center text-xs', props.className)}>
|
|
10
|
+
<input type="radio" {...rest} ref={ref} className="w-4 h-4" />
|
|
11
|
+
{children && <span className="text-xs ml-2">{children}</span>}
|
|
12
|
+
</label>
|
|
13
|
+
);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
Radio.displayName = 'Radio';
|
|
17
|
+
|
|
18
|
+
export { Radio };
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react';
|
|
2
|
-
import { createPortal } from 'react-dom';
|
|
3
|
-
|
|
4
|
-
function createWrapperAndAppendToBody(wrapperId: string) {
|
|
5
|
-
const wrapperElement = document.createElement('div');
|
|
6
|
-
wrapperElement.setAttribute('id', wrapperId);
|
|
7
|
-
document.body.appendChild(wrapperElement);
|
|
8
|
-
return wrapperElement;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
type Props = {
|
|
12
|
-
children: React.ReactNode;
|
|
13
|
-
wrapperId: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const ReactPortal: React.FC<Props> = ({
|
|
17
|
-
children,
|
|
18
|
-
wrapperId = 'react-portal-wrapper'
|
|
19
|
-
}) => {
|
|
20
|
-
const [wrapperElement, setWrapperElement] = useState<HTMLElement | null>(
|
|
21
|
-
null
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
let element = document.getElementById(wrapperId) as HTMLElement;
|
|
26
|
-
let modalCreated = false;
|
|
27
|
-
|
|
28
|
-
if (!element) {
|
|
29
|
-
modalCreated = true;
|
|
30
|
-
element = createWrapperAndAppendToBody(wrapperId);
|
|
31
|
-
}
|
|
32
|
-
setWrapperElement(element);
|
|
33
|
-
|
|
34
|
-
return () => {
|
|
35
|
-
// delete the programatically created element if it was created
|
|
36
|
-
if (modalCreated && element.parentNode) {
|
|
37
|
-
element.parentNode.removeChild(element);
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
}, [wrapperId]);
|
|
41
|
-
|
|
42
|
-
if (wrapperElement === null) return null;
|
|
43
|
-
|
|
44
|
-
return createPortal(children, wrapperElement);
|
|
45
|
-
};
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
import { createPortal } from 'react-dom';
|
|
3
|
+
|
|
4
|
+
function createWrapperAndAppendToBody(wrapperId: string) {
|
|
5
|
+
const wrapperElement = document.createElement('div');
|
|
6
|
+
wrapperElement.setAttribute('id', wrapperId);
|
|
7
|
+
document.body.appendChild(wrapperElement);
|
|
8
|
+
return wrapperElement;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type Props = {
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
wrapperId: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const ReactPortal: React.FC<Props> = ({
|
|
17
|
+
children,
|
|
18
|
+
wrapperId = 'react-portal-wrapper'
|
|
19
|
+
}) => {
|
|
20
|
+
const [wrapperElement, setWrapperElement] = useState<HTMLElement | null>(
|
|
21
|
+
null
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
let element = document.getElementById(wrapperId) as HTMLElement;
|
|
26
|
+
let modalCreated = false;
|
|
27
|
+
|
|
28
|
+
if (!element) {
|
|
29
|
+
modalCreated = true;
|
|
30
|
+
element = createWrapperAndAppendToBody(wrapperId);
|
|
31
|
+
}
|
|
32
|
+
setWrapperElement(element);
|
|
33
|
+
|
|
34
|
+
return () => {
|
|
35
|
+
// delete the programatically created element if it was created
|
|
36
|
+
if (modalCreated && element.parentNode) {
|
|
37
|
+
element.parentNode.removeChild(element);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}, [wrapperId]);
|
|
41
|
+
|
|
42
|
+
if (wrapperElement === null) return null;
|
|
43
|
+
|
|
44
|
+
return createPortal(children, wrapperElement);
|
|
45
|
+
};
|