mirror of
https://github.com/zoriya/Kyoo.git
synced 2026-01-01 09:40:28 -05:00
103 lines
3.2 KiB
TypeScript
103 lines
3.2 KiB
TypeScript
import { type QueryPage, login } from "@kyoo/models";
|
|
import { A, Button, H1, Input, P, ts } from "@kyoo/primitives";
|
|
import { useEffect, useState } from "react";
|
|
import { Trans, useTranslation } from "react-i18next";
|
|
import { Platform } from "react-native";
|
|
import { useRouter } from "solito/router";
|
|
import { percent, px, useYoshiki } from "yoshiki/native";
|
|
import { DefaultLayout } from "../../../packages/ui/src/layout";
|
|
import { FormPage } from "./form";
|
|
import { OidcLogin } from "./oidc";
|
|
import { PasswordInput } from "./password-input";
|
|
|
|
export const RegisterPage: QueryPage<{ apiUrl?: string }> = ({ apiUrl }) => {
|
|
const { data } = useFetch({
|
|
path: ["info"],
|
|
parser: ServerInfoP,
|
|
});
|
|
|
|
const [email, setEmail] = useState("");
|
|
const [username, setUsername] = useState("");
|
|
const [password, setPassword] = useState("");
|
|
const [confirm, setConfirm] = useState("");
|
|
const [error, setError] = useState<string | undefined>(undefined);
|
|
|
|
const router = useRouter();
|
|
const { t } = useTranslation();
|
|
const { css } = useYoshiki();
|
|
|
|
useEffect(() => {
|
|
if (!apiUrl && Platform.OS !== "web")
|
|
router.replace("/server-url", undefined, {
|
|
experimental: { nativeBehavior: "stack-replace", isNestedNavigator: false },
|
|
});
|
|
}, [apiUrl, router]);
|
|
|
|
return (
|
|
<FormPage apiUrl={apiUrl}>
|
|
<H1>{t("login.register")}</H1>
|
|
<OidcLogin apiUrl={apiUrl} hideOr={!data?.passwordLoginEnabled} />
|
|
{data?.registrationEnabled && (
|
|
<>
|
|
<P {...css({ paddingLeft: ts(1) })}>{t("login.username")}</P>
|
|
<Input
|
|
autoComplete="username"
|
|
variant="big"
|
|
onChangeText={(value) => setUsername(value)}
|
|
/>
|
|
|
|
<P {...css({ paddingLeft: ts(1) })}>{t("login.email")}</P>
|
|
<Input autoComplete="email" variant="big" onChangeText={(value) => setEmail(value)} />
|
|
|
|
<P {...css({ paddingLeft: ts(1) })}>{t("login.password")}</P>
|
|
<PasswordInput
|
|
autoComplete="password-new"
|
|
variant="big"
|
|
onChangeText={(value) => setPassword(value)}
|
|
/>
|
|
|
|
<P {...css({ paddingLeft: ts(1) })}>{t("login.confirm")}</P>
|
|
<PasswordInput
|
|
autoComplete="password-new"
|
|
variant="big"
|
|
onChangeText={(value) => setConfirm(value)}
|
|
/>
|
|
|
|
{password !== confirm && (
|
|
<P {...css({ color: (theme) => theme.colors.red })}>{t("login.password-no-match")}</P>
|
|
)}
|
|
{error && <P {...css({ color: (theme) => theme.colors.red })}>{error}</P>}
|
|
<Button
|
|
text={t("login.register")}
|
|
disabled={password !== confirm}
|
|
onPress={async () => {
|
|
const { error } = await login("register", { email, username, password, apiUrl });
|
|
setError(error);
|
|
if (error) return;
|
|
router.replace("/", undefined, {
|
|
experimental: { nativeBehavior: "stack-replace", isNestedNavigator: false },
|
|
});
|
|
}}
|
|
{...css({
|
|
m: ts(1),
|
|
width: px(250),
|
|
maxWidth: percent(100),
|
|
alignSelf: "center",
|
|
mY: ts(3),
|
|
})}
|
|
/>
|
|
</>
|
|
)}
|
|
<P>
|
|
<Trans i18nKey="login.or-login">
|
|
Have an account already? <A href={{ pathname: "/login", query: { apiUrl } }}>Log in</A>.
|
|
</Trans>
|
|
</P>
|
|
</FormPage>
|
|
);
|
|
};
|
|
|
|
RegisterPage.getFetchUrls = () => [OidcLogin.query()];
|
|
RegisterPage.isPublic = true;
|
|
RegisterPage.getLayout = DefaultLayout;
|