Files
threadnet-call/src/auth/LoginPage.tsx
T

145 lines
4.9 KiB
TypeScript
Raw Normal View History

2021-08-20 16:23:12 -07:00
/*
Copyright 2021-2024 New Vector Ltd.
2021-08-20 16:23:12 -07:00
SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
2021-08-20 16:23:12 -07:00
*/
import { FC, FormEvent, useCallback, useRef, useState } from "react";
2021-08-20 16:23:12 -07:00
import { useHistory, useLocation, Link } from "react-router-dom";
2022-10-10 09:19:10 -04:00
import { Trans, useTranslation } from "react-i18next";
import { Button } from "@vector-im/compound-web";
2022-05-27 10:00:14 -04:00
2023-09-27 19:06:10 -04:00
import Logo from "../icons/LogoLarge.svg?react";
import { useClient } from "../ClientContext";
2022-01-05 17:27:01 -08:00
import { FieldRow, InputField, ErrorMessage } from "../input/Input";
2021-12-10 12:46:18 -08:00
import styles from "./LoginPage.module.css";
2022-01-05 16:47:53 -08:00
import { useInteractiveLogin } from "./useInteractiveLogin";
2022-02-02 15:02:40 -08:00
import { usePageTitle } from "../usePageTitle";
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
2022-12-20 17:26:45 +00:00
import { Config } from "../config/Config";
2021-08-20 16:23:12 -07:00
2022-05-27 10:00:14 -04:00
export const LoginPage: FC = () => {
2022-10-10 09:19:10 -04:00
const { t } = useTranslation();
2023-11-20 13:00:43 +00:00
usePageTitle(t("login_title"));
2022-02-02 15:02:40 -08:00
const { client, setClient } = useClient();
const login = useInteractiveLogin(client);
2022-12-20 17:26:45 +00:00
const homeserver = Config.defaultHomeserverUrl(); // TODO: Make this configurable
2023-06-30 16:43:28 +01:00
const usernameRef = useRef<HTMLInputElement>(null);
const passwordRef = useRef<HTMLInputElement>(null);
2021-08-20 16:23:12 -07:00
const history = useHistory();
const location = useLocation();
2021-11-17 15:12:54 -08:00
const [loading, setLoading] = useState(false);
2022-05-27 10:00:14 -04:00
const [error, setError] = useState<Error>();
2021-08-20 16:23:12 -07:00
2021-12-09 12:58:30 -08:00
// TODO: Handle hitting login page with authenticated client
2021-08-20 16:23:12 -07:00
const onSubmitLoginForm = useCallback(
2022-05-27 10:00:14 -04:00
(e: FormEvent<HTMLFormElement>) => {
2021-08-20 16:23:12 -07:00
e.preventDefault();
2021-11-17 15:12:54 -08:00
setLoading(true);
2023-06-30 16:43:28 +01:00
if (!homeserver || !usernameRef.current || !passwordRef.current) {
setError(Error("Login parameters are undefined"));
setLoading(false);
return;
}
2021-12-09 12:58:30 -08:00
login(homeserver, usernameRef.current.value, passwordRef.current.value)
.then(([client, session]) => {
2023-06-30 16:43:28 +01:00
if (!setClient) {
return;
}
2023-06-30 16:43:28 +01:00
setClient({ client, session });
const locationState = location.state;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
if (locationState && locationState.from) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
history.push(locationState.from);
2021-08-20 16:23:12 -07:00
} else {
2021-12-09 12:58:30 -08:00
history.push("/");
2021-08-20 16:23:12 -07:00
}
PosthogAnalytics.instance.eventLogin.track();
2021-09-10 12:20:17 -07:00
})
2021-11-17 15:12:54 -08:00
.catch((error) => {
setError(error);
setLoading(false);
});
2021-08-20 16:23:12 -07:00
},
2023-10-11 10:42:04 -04:00
[login, location, history, homeserver, setClient],
2021-08-20 16:23:12 -07:00
);
// we need to limit the length of the homserver name to not cover the whole loginview input with the string.
let shortendHomeserverName = Config.defaultServerName()?.slice(0, 25);
shortendHomeserverName =
shortendHomeserverName?.length !== Config.defaultServerName()?.length
? shortendHomeserverName + "..."
: shortendHomeserverName;
2021-08-20 16:23:12 -07:00
return (
<>
2021-12-10 12:46:18 -08:00
<div className={styles.container}>
<div className={styles.content}>
<div className={styles.formContainer}>
<Logo width="auto" height="auto" className={styles.logo} />
2023-11-22 20:07:15 +00:00
<h2>{t("log_in")}</h2>
<h4>{t("login_subheading")}</h4>
2021-12-10 12:46:18 -08:00
<form onSubmit={onSubmitLoginForm}>
<FieldRow>
<InputField
type="text"
ref={usernameRef}
placeholder={t("common.username")}
label={t("common.username")}
2021-12-10 12:46:18 -08:00
autoCorrect="off"
autoCapitalize="none"
2021-12-15 10:54:01 -08:00
prefix="@"
suffix={`:${shortendHomeserverName}`}
data-testid="login_username"
2021-12-10 12:46:18 -08:00
/>
</FieldRow>
<FieldRow>
<InputField
type="password"
ref={passwordRef}
placeholder={t("common.password")}
label={t("common.password")}
data-testid="login_password"
2021-12-10 12:46:18 -08:00
/>
</FieldRow>
{error && (
2021-08-20 16:23:12 -07:00
<FieldRow>
2022-10-10 09:19:10 -04:00
<ErrorMessage error={error} />
2021-08-20 16:23:12 -07:00
</FieldRow>
2021-12-10 12:46:18 -08:00
)}
<FieldRow>
<Button
type="submit"
disabled={loading}
data-testid="login_login"
>
2023-11-20 13:00:43 +00:00
{loading ? t("logging_in") : t("login_title")}
2021-12-10 12:46:18 -08:00
</Button>
</FieldRow>
</form>
</div>
<div className={styles.authLinks}>
2023-11-22 20:07:15 +00:00
<p>{t("login_auth_links_prompt")}</p>
2021-12-10 12:46:18 -08:00
<p>
2023-11-20 13:00:43 +00:00
<Trans i18nKey="login_auth_links">
2022-10-10 09:19:10 -04:00
<Link to="/register">Create an account</Link>
{" Or "}
<Link to="/">Access as a guest</Link>
</Trans>
2021-12-10 12:46:18 -08:00
</p>
</div>
</div>
</div>
2021-08-20 16:23:12 -07:00
</>
);
2022-05-27 10:00:14 -04:00
};