Skip to content

Commit 0adb1b4

Browse files
On signup, when user enter emails and it already exists then redirect to signin
1 parent 02942e5 commit 0adb1b4

File tree

3 files changed

+88
-52
lines changed

3 files changed

+88
-52
lines changed

client/packages/lowcoder-design/src/components/tacoInput.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,13 +331,14 @@ const FormInput = (props: {
331331
check: (value: string) => boolean;
332332
};
333333
formName?: string;
334+
onBlur?: () => void;
334335
onChange?: (value: string, valid: boolean) => void;
335336
className?: string;
336337
inputRef?: Ref<InputRef>;
337338
msg?: string;
338339
defaultValue?: string;
339340
}) => {
340-
const { mustFill, checkRule, label, placeholder, onChange, formName, className, inputRef, defaultValue } =
341+
const { mustFill, checkRule, label, placeholder, onBlur, onChange, formName, className, inputRef, defaultValue } =
341342
props;
342343
const [valueValid, setValueValid] = useState(true);
343344
return (
@@ -360,6 +361,7 @@ const FormInput = (props: {
360361
}
361362
onChange && onChange(e.target.value, valid);
362363
}}
364+
onBlur={() => onBlur?.()}
363365
/>
364366
</FormInputFiled>
365367
);

client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export default function FormLoginSteps(props: FormLoginProps) {
127127
const fetchOrgsByEmail = () => {
128128
// if user is invited or using org's login url then avoid fetching workspaces
129129
// and skip workspace selection step
130-
if (organizationId) {
130+
if (Boolean(organizationId)) {
131131
setSkipWorkspaceStep(true);
132132
dispatch(fetchConfigAction(organizationId));
133133
setCurrentStep(CurrentStepEnum.AUTH_PROVIDERS);
@@ -148,6 +148,7 @@ export default function FormLoginSteps(props: FormLoginProps) {
148148
}
149149
if (resp.data.data.length === 1) {
150150
setOrganizationId(resp.data.data[0].orgId);
151+
dispatch(fetchConfigAction(resp.data.data[0].orgId));
151152
setCurrentStep(CurrentStepEnum.AUTH_PROVIDERS);
152153
return;
153154
}

client/packages/lowcoder/src/pages/userAuth/register.tsx

Lines changed: 83 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
StyledRouteLinkLogin,
88
TermsAndPrivacyInfo,
99
} from "pages/userAuth/authComponents";
10-
import { FormInput, PasswordInput } from "lowcoder-design";
10+
import { CustomModal, FormInput, messageInstance, PasswordInput } from "lowcoder-design";
1111
import { AUTH_LOGIN_URL, ORG_AUTH_LOGIN_URL } from "constants/routesURL";
1212
import UserApi from "api/userApi";
1313
import { useRedirectUrl } from "util/hooks";
@@ -21,6 +21,11 @@ import { AuthContext, checkPassWithMsg, useAuthSubmit } from "pages/userAuth/aut
2121
import { ThirdPartyAuth } from "pages/userAuth/thirdParty/thirdPartyAuth";
2222
import { useParams } from "react-router-dom";
2323
import { Divider } from "antd";
24+
import { OrgApi } from "@lowcoder-ee/api/orgApi";
25+
import { validateResponse } from "@lowcoder-ee/api/apiUtils";
26+
import history from "util/history";
27+
import LoadingOutlined from "@ant-design/icons/LoadingOutlined";
28+
import Spin from "antd/es/spin";
2429

2530
const StyledFormInput = styled(FormInput)`
2631
margin-bottom: 16px;
@@ -44,6 +49,8 @@ function UserRegister() {
4449
return email ?? '';
4550
});
4651
const [password, setPassword] = useState("");
52+
const [orgLoading, setOrgLoading] = useState(false);
53+
const [lastEmailChecked, setLastEmailChecked] = useState("");
4754
const redirectUrl = useRedirectUrl();
4855
const { systemConfig, inviteInfo, fetchUserAfterAuthSuccess } = useContext(AuthContext);
4956
const invitationId = inviteInfo?.invitationId;
@@ -74,60 +81,86 @@ function UserRegister() {
7481
fetchUserAfterAuthSuccess,
7582
);
7683

84+
const checkEmailExist = () => {
85+
if (!Boolean(account.length) || lastEmailChecked === account) return;
86+
87+
setOrgLoading(true);
88+
OrgApi.fetchOrgsByEmail(account)
89+
.then((resp) => {
90+
if (validateResponse(resp)) {
91+
const orgList = resp.data.data;
92+
if (orgList.length) {
93+
messageInstance.error('Email is already registered');
94+
history.push(
95+
AUTH_LOGIN_URL,
96+
{...location.state || {}, email: account},
97+
)
98+
}
99+
}
100+
})
101+
.finally(() => {
102+
setLastEmailChecked(account)
103+
setOrgLoading(false);
104+
});
105+
}
106+
77107
const registerHeading = trans("userAuth.register")
78108
const registerSubHeading = trans("userAuth.poweredByLowcoder");
79109

80110
return (
81-
<AuthContainer
82-
heading={registerHeading}
83-
subHeading={registerSubHeading}
84-
type="large"
85-
>
86-
<RegisterContent>
87-
<StyledFormInput
88-
className="form-input"
89-
label={trans("userAuth.email")}
90-
defaultValue={account}
91-
onChange={(value, valid) => setAccount(valid ? value : "")}
92-
placeholder={trans("userAuth.inputEmail")}
93-
checkRule={{
94-
check: checkEmailValid,
95-
errorMsg: trans("userAuth.inputValidEmail"),
96-
}}
97-
/>
98-
<StyledPasswordInput
99-
className="form-input"
100-
passInputConf={{label:trans("password.label"), placeholder: trans("password.placeholder")}}
101-
confirmPassConf={{label:trans("password.conformLabel"), placeholder: trans("password.conformPlaceholder")}}
102-
valueCheck={checkPassWithMsg}
103-
onChange={(value, valid) => setPassword(valid ? value : "")}
104-
doubleCheck
105-
/>
106-
<ConfirmButton
107-
disabled={!account || !password || submitBtnDisable}
108-
onClick={onSubmit}
109-
loading={loading}
110-
>
111-
{trans("userAuth.register")}
112-
</ConfirmButton>
113-
<TermsAndPrivacyInfo onCheckChange={(e) => setSubmitBtnDisable(!e.target.checked)} />
114-
{organizationId && (
115-
<ThirdPartyAuth
116-
invitationId={invitationId}
117-
invitedOrganizationId={organizationId}
118-
authGoal="register"
111+
<Spin indicator={<LoadingOutlined style={{ fontSize: 30 }} />} spinning={orgLoading}>
112+
<AuthContainer
113+
heading={registerHeading}
114+
subHeading={registerSubHeading}
115+
type="large"
116+
>
117+
<RegisterContent>
118+
<StyledFormInput
119+
className="form-input"
120+
label={trans("userAuth.email")}
121+
defaultValue={account}
122+
onChange={(value, valid) => setAccount(valid ? value : "")}
123+
onBlur={checkEmailExist}
124+
placeholder={trans("userAuth.inputEmail")}
125+
checkRule={{
126+
check: checkEmailValid,
127+
errorMsg: trans("userAuth.inputValidEmail"),
128+
}}
129+
/>
130+
<StyledPasswordInput
131+
className="form-input"
132+
passInputConf={{label:trans("password.label"), placeholder: trans("password.placeholder")}}
133+
confirmPassConf={{label:trans("password.conformLabel"), placeholder: trans("password.conformPlaceholder")}}
134+
valueCheck={checkPassWithMsg}
135+
onChange={(value, valid) => setPassword(valid ? value : "")}
136+
doubleCheck
119137
/>
120-
)}
121-
</RegisterContent>
122-
<Divider/>
123-
<StyledRouteLinkLogin to={{
124-
pathname: orgId
125-
? ORG_AUTH_LOGIN_URL.replace(':orgId', orgId)
126-
: AUTH_LOGIN_URL,
127-
state: location.state
128-
}}>{trans("userAuth.userLogin")}
129-
</StyledRouteLinkLogin>
130-
</AuthContainer>
138+
<ConfirmButton
139+
disabled={!account || !password || submitBtnDisable}
140+
onClick={onSubmit}
141+
loading={loading}
142+
>
143+
{trans("userAuth.register")}
144+
</ConfirmButton>
145+
<TermsAndPrivacyInfo onCheckChange={(e) => setSubmitBtnDisable(!e.target.checked)} />
146+
{organizationId && (
147+
<ThirdPartyAuth
148+
invitationId={invitationId}
149+
invitedOrganizationId={organizationId}
150+
authGoal="register"
151+
/>
152+
)}
153+
</RegisterContent>
154+
<Divider/>
155+
<StyledRouteLinkLogin to={{
156+
pathname: orgId
157+
? ORG_AUTH_LOGIN_URL.replace(':orgId', orgId)
158+
: AUTH_LOGIN_URL,
159+
state: location.state
160+
}}>{trans("userAuth.userLogin")}
161+
</StyledRouteLinkLogin>
162+
</AuthContainer>
163+
</Spin>
131164
);
132165
}
133166

0 commit comments

Comments
 (0)