@akinon/pz-otp 2.0.0-beta.1 → 2.0.0-beta.11
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 +41 -0
- package/package.json +1 -1
- package/readme.md +104 -4
- package/src/views/Otp.tsx +41 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @akinon/pz-otp
|
|
2
2
|
|
|
3
|
+
## 2.0.0-beta.11
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ac783d6: ZERO-3482: Update tailwindcss to version 4.1.11 and enhance button cursor styles
|
|
8
|
+
|
|
9
|
+
## 2.0.0-beta.10
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 2806320: ZERO-3390: Update version tailwindcss, autoprefixer, tailwind-merge, postcss
|
|
14
|
+
|
|
15
|
+
## 2.0.0-beta.9
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- 0fe7711: ZERO-3387: Upgrade nextjs, eslint-config-next
|
|
20
|
+
|
|
21
|
+
## 2.0.0-beta.8
|
|
22
|
+
|
|
23
|
+
## 2.0.0-beta.7
|
|
24
|
+
|
|
25
|
+
## 2.0.0-beta.6
|
|
26
|
+
|
|
27
|
+
### Minor Changes
|
|
28
|
+
|
|
29
|
+
- 8f05f9b: ZERO-3250: Beta branch synchronized with Main branch
|
|
30
|
+
|
|
31
|
+
## 2.0.0-beta.5
|
|
32
|
+
|
|
33
|
+
## 2.0.0-beta.4
|
|
34
|
+
|
|
35
|
+
## 2.0.0-beta.3
|
|
36
|
+
|
|
37
|
+
## 2.0.0-beta.2
|
|
38
|
+
|
|
39
|
+
### Minor Changes
|
|
40
|
+
|
|
41
|
+
- a006015: ZERO-3116: Add not-found page and update default middleware.
|
|
42
|
+
- 1eeb3d8: ZERO-3116: Add not found page
|
|
43
|
+
|
|
3
44
|
## 2.0.0-beta.1
|
|
4
45
|
|
|
5
46
|
### Minor Changes
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -1,11 +1,111 @@
|
|
|
1
1
|
# @akinon/pz-otp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Installation method
|
|
4
|
+
|
|
5
|
+
You can use the following command to install the extension with the latest plugins:
|
|
4
6
|
|
|
5
7
|
```bash
|
|
6
|
-
# For latest version
|
|
7
|
-
yarn add @akinon/pz-otp
|
|
8
8
|
|
|
9
|
-
# Preferred installation method
|
|
10
9
|
npx @akinon/projectzero@latest --plugins
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Props
|
|
14
|
+
|
|
15
|
+
| Property | Type | Description |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| `customUIRender` | `React.ReactNode` | Optional function to fully customize the otp. Receives closeHandler, resendHandler, otp, setOtp, hasError, error, canResend, time, codeLength, setHasError and onSubmit props. |
|
|
18
|
+
|
|
19
|
+
### Customizing OTP
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
import PluginModule, { Component } from '@akinon/next/components/plugin-module';
|
|
23
|
+
|
|
24
|
+
<PluginModule
|
|
25
|
+
component={Component.Otp}
|
|
26
|
+
props={{
|
|
27
|
+
data: getValues(),
|
|
28
|
+
submitAction: registerHandler,
|
|
29
|
+
customUIRender: ({
|
|
30
|
+
closeHandler,
|
|
31
|
+
resendHandler,
|
|
32
|
+
onSubmit,
|
|
33
|
+
otp,
|
|
34
|
+
setOtp,
|
|
35
|
+
hasError,
|
|
36
|
+
error,
|
|
37
|
+
canResend,
|
|
38
|
+
time,
|
|
39
|
+
codeLength,
|
|
40
|
+
setHasError
|
|
41
|
+
}) => {
|
|
42
|
+
return (
|
|
43
|
+
<div className="fixed left-0 top-0 z-50 flex h-screen w-screen items-end md:items-center md:justify-center md:bg-black/10">
|
|
44
|
+
<div className="h-[calc(100vh-48px)] w-screen flex md:h-auto md:max-w-lg flex-col items-center rounded-sm bg-white p-8 shadow-xl">
|
|
45
|
+
<div className="w-full flex items-center justify-end">
|
|
46
|
+
<div className="cursor-pointer" onClick={closeHandler}>
|
|
47
|
+
<svg
|
|
48
|
+
width="14"
|
|
49
|
+
height="14"
|
|
50
|
+
viewBox="0 0 14 14"
|
|
51
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
52
|
+
>
|
|
53
|
+
<g fill="#000" fillRule="nonzero">
|
|
54
|
+
<path d="M.684 14A.684.684 0 0 1 .2 12.833L12.833.2a.684.684 0 1 1 .967.967L1.167 13.8a.682.682 0 0 1-.483.2z" />
|
|
55
|
+
<path d="M13.316 14a.682.682 0 0 1-.483-.2L.2 1.167A.684.684 0 0 1 1.167.2L13.8 12.833A.684.684 0 0 1 13.316 14z" />
|
|
56
|
+
</g>
|
|
57
|
+
</svg>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
<div className="flex flex-col items-center px-14 mt-5">
|
|
61
|
+
<div className="text-2xl font-medium">OTP Verification</div>
|
|
62
|
+
<div className={twMerge('mt-2.5 text-center text-gray-700')}>
|
|
63
|
+
{`Please enter the ${codeLength}-digit sms code sent to your registered number and email address`}
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
<form
|
|
67
|
+
onSubmit={onSubmit}
|
|
68
|
+
className="flex flex-col items-center w-full"
|
|
69
|
+
>
|
|
70
|
+
<OtpInput
|
|
71
|
+
value={otp}
|
|
72
|
+
onChange={(otp) => {
|
|
73
|
+
setOtp(otp);
|
|
74
|
+
setHasError(false);
|
|
75
|
+
}}
|
|
76
|
+
numInputs={codeLength}
|
|
77
|
+
containerStyle="mt-12 gap-2 flex-wrap"
|
|
78
|
+
inputStyle={twMerge(
|
|
79
|
+
'h-12 w-8 md:h-16 md:w-12 rounded-md border border-gray-600 text-center text-lg',
|
|
80
|
+
hasError && 'border-error'
|
|
81
|
+
)}
|
|
82
|
+
renderInput={({ ...props }) => <input {...props} />}
|
|
83
|
+
skipDefaultStyles={true}
|
|
84
|
+
/>
|
|
85
|
+
{error && <p className="text-xs text-error mt-2">{error}</p>}
|
|
86
|
+
<Button
|
|
87
|
+
type="submit"
|
|
88
|
+
className="mt-5 h-auto w-full py-4 text-lg font-medium uppercase"
|
|
89
|
+
>
|
|
90
|
+
Verify
|
|
91
|
+
</Button>
|
|
92
|
+
</form>
|
|
93
|
+
<div className="mt-6 flex flex-col items-center">
|
|
94
|
+
<span className="text-gray-700">I didn`t receive a code</span>
|
|
95
|
+
<div
|
|
96
|
+
className={twMerge(
|
|
97
|
+
' font-medium underline cursor-pointer',
|
|
98
|
+
!canResend && 'cursor-not-allowed text-gray-700'
|
|
99
|
+
)}
|
|
100
|
+
onClick={resendHandler}
|
|
101
|
+
>
|
|
102
|
+
RESEND
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
}}
|
|
110
|
+
/>;
|
|
11
111
|
```
|
package/src/views/Otp.tsx
CHANGED
|
@@ -30,7 +30,6 @@ type ComponentClasses = ComponentClassKey | ComponentWrapperClassKey;
|
|
|
30
30
|
type OtpProps = {
|
|
31
31
|
codeLength?: number;
|
|
32
32
|
timer?: number;
|
|
33
|
-
phone?: string;
|
|
34
33
|
submitAction: SubmitHandler<{
|
|
35
34
|
[key: string]: any;
|
|
36
35
|
}>;
|
|
@@ -44,6 +43,19 @@ type OtpProps = {
|
|
|
44
43
|
[c in ComponentClasses]?: string;
|
|
45
44
|
};
|
|
46
45
|
error?: string;
|
|
46
|
+
customUIRender?: (props: {
|
|
47
|
+
closeHandler?: () => void;
|
|
48
|
+
resendHandler?: () => void;
|
|
49
|
+
onSubmit?: (event: FormEvent<HTMLFormElement>) => Promise<void>;
|
|
50
|
+
otp?: string;
|
|
51
|
+
setOtp?: (otp: string) => void;
|
|
52
|
+
hasError?: boolean;
|
|
53
|
+
error?: string;
|
|
54
|
+
canResend?: boolean;
|
|
55
|
+
time?: number;
|
|
56
|
+
codeLength?: number;
|
|
57
|
+
setHasError?: (hasError: boolean) => void;
|
|
58
|
+
}) => ReactNode;
|
|
47
59
|
};
|
|
48
60
|
|
|
49
61
|
export const Otp = ({
|
|
@@ -54,14 +66,15 @@ export const Otp = ({
|
|
|
54
66
|
texts,
|
|
55
67
|
classes,
|
|
56
68
|
error,
|
|
57
|
-
|
|
69
|
+
customUIRender
|
|
58
70
|
}: OtpProps) => {
|
|
71
|
+
const { phone } = data;
|
|
59
72
|
const [otp, setOtp] = useState('');
|
|
60
73
|
const [canResend, setCanResend] = useState(false);
|
|
61
74
|
const [time, setTime] = useState(timer);
|
|
62
75
|
const [hasError, setHasError] = useState(false);
|
|
63
76
|
const dispatch = useAppDispatch();
|
|
64
|
-
const
|
|
77
|
+
const { isPopupVisible } = useAppSelector((state) => state.otp);
|
|
65
78
|
|
|
66
79
|
const resetTimer = () => {
|
|
67
80
|
setTime(timer);
|
|
@@ -118,19 +131,37 @@ export const Otp = ({
|
|
|
118
131
|
}, [time, onTimerEnd]);
|
|
119
132
|
|
|
120
133
|
useEffect(() => {
|
|
121
|
-
|
|
122
|
-
|
|
134
|
+
if (isPopupVisible) {
|
|
135
|
+
document.body.style.overflow = 'hidden';
|
|
136
|
+
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
123
137
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
138
|
+
return () => {
|
|
139
|
+
document.body.style.overflow = 'auto';
|
|
140
|
+
};
|
|
141
|
+
}
|
|
127
142
|
}, []);
|
|
128
143
|
|
|
129
|
-
if (!
|
|
144
|
+
if (!isPopupVisible) return null;
|
|
145
|
+
|
|
146
|
+
if (customUIRender) {
|
|
147
|
+
return customUIRender({
|
|
148
|
+
closeHandler,
|
|
149
|
+
resendHandler,
|
|
150
|
+
onSubmit,
|
|
151
|
+
otp,
|
|
152
|
+
setOtp,
|
|
153
|
+
hasError,
|
|
154
|
+
error,
|
|
155
|
+
canResend,
|
|
156
|
+
time,
|
|
157
|
+
codeLength,
|
|
158
|
+
setHasError
|
|
159
|
+
});
|
|
160
|
+
}
|
|
130
161
|
|
|
131
162
|
return (
|
|
132
163
|
<div className="fixed left-0 top-0 z-50 flex h-screen w-screen items-end md:items-center md:justify-center md:bg-black/10">
|
|
133
|
-
<div className="h-[calc(100vh-48px)] w-screen flex md:h-auto md:max-w-lg flex-col items-center rounded-
|
|
164
|
+
<div className="h-[calc(100vh-48px)] w-screen flex md:h-auto md:max-w-lg flex-col items-center rounded-xs bg-white p-8 shadow-xl">
|
|
134
165
|
<div className="w-full flex items-center justify-end">
|
|
135
166
|
<div className="cursor-pointer" onClick={closeHandler}>
|
|
136
167
|
<svg
|