diff --git a/web/src/ResetModal.js b/web/src/ResetModal.js
index e83e6fe8..4d35f8ec 100644
--- a/web/src/ResetModal.js
+++ b/web/src/ResetModal.js
@@ -17,12 +17,11 @@ import i18next from "i18next";
import React from "react";
import * as Setting from "./Setting"
import * as UserBackend from "./backend/UserBackend"
+import {CountDownInput} from "./reusable/CountDownInput";
export const ResetModal = (props) => {
const [visible, setVisible] = React.useState(false);
const [confirmLoading, setConfirmLoading] = React.useState(false);
- const [sendButtonText, setSendButtonText] = React.useState(i18next.t("user:Send Code"));
- const [sendCodeCoolDown, setCoolDown] = React.useState(false);
const [dest, setDest] = React.useState("");
const [code, setCode] = React.useState("");
const {buttonText, destType, coolDownTime, org} = props;
@@ -56,18 +55,7 @@ export const ResetModal = (props) => {
})
}
- const countDown = (second) => {
- if (second <= 0) {
- setSendButtonText(i18next.t("user:Send Code"));
- setCoolDown(false);
- return;
- }
- setSendButtonText(second);
- setTimeout(() => countDown(second - 1), 1000);
- }
-
const sendCode = () => {
- if (sendCodeCoolDown) return;
if (dest === "") {
Setting.showMessage("error", i18next.t("user:Empty " + destType));
return;
@@ -76,8 +64,6 @@ export const ResetModal = (props) => {
UserBackend.sendCode(dest, destType, orgId).then(res => {
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("user:Code Sent"));
- setCoolDown(true);
- countDown(coolDownTime);
} else {
Setting.showMessage("error", i18next.t("user:" + res.msg));
}
@@ -105,13 +91,21 @@ export const ResetModal = (props) => {
>
- setDest(e.target.value)}
- addonAfter={}
+ setDest(e.target.value)}
/>
-
- setCode(e.target.value)}/>
+
diff --git a/web/src/auth/SignupPage.js b/web/src/auth/SignupPage.js
index c8e46f64..16f0dc65 100644
--- a/web/src/auth/SignupPage.js
+++ b/web/src/auth/SignupPage.js
@@ -22,6 +22,7 @@ import * as Util from "./Util";
import {authConfig} from "./Auth";
import * as ApplicationBackend from "../backend/ApplicationBackend";
import * as UserBackend from "../backend/UserBackend";
+import {CountDownInput} from "../reusable/CountDownInput";
const formItemLayout = {
labelCol: {
@@ -63,7 +64,9 @@ class SignupPage extends React.Component {
applicationName: props.match.params.applicationName !== undefined ? props.match.params.applicationName : authConfig.appName,
application: null,
email: "",
- phone: ""
+ phone: "",
+ emailCode: "",
+ phoneCode: ""
};
this.form = React.createRef();
@@ -250,7 +253,11 @@ class SignupPage extends React.Component {
message: i18next.t("signup:Please input your verification code!"),
}]}
>
- this.sendCode("email")} style={{backgroundColor: "#fafafa", border: "none"}}>{i18next.t("signup:send code")}} />
+ this.sendCode("email")}
+ coolDownTime={60}
+ />
- this.sendCode("phone")} style={{border: "none", backgroundColor: "#fafafa"}}>{i18next.t("signup:send code")}}/>
+ this.sendCode("phone")}
+ coolDownTime={60}
+ />
diff --git a/web/src/reusable/CountDownInput.js b/web/src/reusable/CountDownInput.js
new file mode 100644
index 00000000..b9ac41f4
--- /dev/null
+++ b/web/src/reusable/CountDownInput.js
@@ -0,0 +1,48 @@
+// Copyright 2021 The casbin Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { Input } from "antd";
+import React from "react";
+import * as Setting from "../Setting";
+import i18next from "i18next";
+
+export const CountDownInput = (props) => {
+ const {defaultButtonText, textBefore, placeHolder, onChange, onButtonClick, coolDownTime} = props;
+ const [buttonText, setButtonText] = React.useState(defaultButtonText);
+ let coolDown = false;
+
+ const countDown = (leftTime) => {
+ if (leftTime === 0) {
+ coolDown = false;
+ setButtonText(defaultButtonText);
+ return;
+ }
+ setButtonText(`${leftTime} s`);
+ setTimeout(() => countDown(leftTime - 1), 1000);
+ }
+
+ const clickButton = () => {
+ if (coolDown) {
+ Setting.showMessage("error", i18next.t("general:Cooling down"));
+ return;
+ }
+ onButtonClick();
+ coolDown = true;
+ countDown(coolDownTime);
+ }
+
+ return (
+ onChange(e.target.value)} addonAfter={}/>
+ );
+}
\ No newline at end of file