Skip to content

Commit 7d7a1c5

Browse files
palerdotzomars
andauthored
Fix login page CTA disabled state (#2832)
* fix(ui/login): better disabled state for login CTA The fix involves tracking the form submission with a dedicated state `submitInProgress` with React. `formState` from `react-hook-form` does not take time taken for the network call into account. For example, if the api takes 5 seconds to complete, we would expect the `formState.isSubmitting` to be true for `5` seconds. But, surprisingly this is not the case and `formState` from `react-hook-form` resolves immediately after it makes a successful connection to the endpoint. A dedicated state (with `useState`) is introduced that is enabled when the user clicks on the login CTA, and disabled when the api call is resolved, either successfully or with an error. * Update login.tsx * Update login.tsx * Fixes isSubmitting state Co-authored-by: zomars <zomars@me.com>
1 parent 53a7b1c commit 7d7a1c5

File tree

1 file changed

+17
-20
lines changed

1 file changed

+17
-20
lines changed

apps/web/pages/auth/login.tsx

+17-20
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export default function Login({
4545
const { t } = useLocale();
4646
const router = useRouter();
4747
const form = useForm<LoginValues>();
48+
const { formState } = form;
49+
const { isSubmitting } = formState;
4850

4951
const [twoFactorRequired, setTwoFactorRequired] = useState(false);
5052
const [errorMessage, setErrorMessage] = useState<string | null>(null);
@@ -97,26 +99,27 @@ export default function Login({
9799
<AuthContainer
98100
title={t("login")}
99101
description={t("login")}
100-
loading={form.formState.isSubmitting}
101102
showLogo
102103
heading={twoFactorRequired ? t("2fa_code") : t("sign_in_account")}
103104
footerText={twoFactorRequired ? TwoFactorFooter : LoginFooter}>
104105
<Form
105106
form={form}
106107
className="space-y-6"
107-
handleSubmit={(values) => {
108+
handleSubmit={async (values) => {
109+
setErrorMessage(null);
108110
telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.login, collectPageParameters()));
109-
signIn<"credentials">("credentials", { ...values, callbackUrl, redirect: false })
110-
.then((res) => {
111-
if (!res) setErrorMessage(errorMessages[ErrorCode.InternalServerError]);
112-
// we're logged in! let's do a hard refresh to the desired url
113-
else if (!res.error) router.push(callbackUrl);
114-
// reveal two factor input if required
115-
else if (res.error === ErrorCode.SecondFactorRequired) setTwoFactorRequired(true);
116-
// fallback if error not found
117-
else setErrorMessage(errorMessages[res.error] || t("something_went_wrong"));
118-
})
119-
.catch(() => setErrorMessage(errorMessages[ErrorCode.InternalServerError]));
111+
const res = await signIn<"credentials">("credentials", {
112+
...values,
113+
callbackUrl,
114+
redirect: false,
115+
});
116+
if (!res) setErrorMessage(errorMessages[ErrorCode.InternalServerError]);
117+
// we're logged in! let's do a hard refresh to the desired url
118+
else if (!res.error) router.push(callbackUrl);
119+
// reveal two factor input if required
120+
else if (res.error === ErrorCode.SecondFactorRequired) setTwoFactorRequired(true);
121+
// fallback if error not found
122+
else setErrorMessage(errorMessages[res.error] || t("something_went_wrong"));
120123
}}
121124
data-testid="login-form">
122125
<div>
@@ -157,13 +160,7 @@ export default function Login({
157160

158161
{errorMessage && <Alert severity="error" title={errorMessage} />}
159162
<div className="flex space-y-2">
160-
<Button
161-
className="flex w-full justify-center"
162-
type="submit"
163-
disabled={
164-
form.formState.isSubmitting ||
165-
(form.formState.isSubmitted && !twoFactorRequired && !errorMessage)
166-
}>
163+
<Button className="flex w-full justify-center" type="submit" disabled={isSubmitting}>
167164
{twoFactorRequired ? t("submit") : t("sign_in")}
168165
</Button>
169166
</div>

0 commit comments

Comments
 (0)