mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Create a simple login page
This commit is contained in:
parent
e9622edee9
commit
304951e463
@ -32,16 +32,17 @@ import { KyooErrors } from "./kyoo-errors";
|
||||
import { Page, Paged } from "./page";
|
||||
import { Platform } from "react-native";
|
||||
|
||||
export const kyooUrl =
|
||||
Platform.OS !== "web"
|
||||
? process.env.PUBLIC_BACK_URL
|
||||
: typeof window === "undefined"
|
||||
? process.env.KYOO_URL ?? "http://localhost:5000"
|
||||
: "/api";
|
||||
|
||||
const queryFn = async <Data,>(
|
||||
type: z.ZodType<Data>,
|
||||
context: QueryFunctionContext,
|
||||
): Promise<Data> => {
|
||||
const kyooUrl =
|
||||
Platform.OS !== "web"
|
||||
? process.env.PUBLIC_BACK_URL
|
||||
: typeof window === "undefined"
|
||||
? process.env.KYOO_URL ?? "http://localhost:5000"
|
||||
: "/api";
|
||||
if (!kyooUrl) console.error("Kyoo's url is not defined.");
|
||||
|
||||
let resp;
|
||||
|
@ -19,11 +19,108 @@
|
||||
*/
|
||||
|
||||
import { QueryPage } from "@kyoo/models";
|
||||
import { View } from "react-native";
|
||||
import { Button, P, Input, ts, H1, A, IconButton } from "@kyoo/primitives";
|
||||
import { ComponentProps, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ImageBackground, ImageProps, Platform, View } from "react-native";
|
||||
import { Trans } from "react-i18next";
|
||||
import { max, min, percent, px, useYoshiki, vh, vw } from "yoshiki/native";
|
||||
import Visibility from "@material-symbols/svg-400/rounded/visibility-fill.svg";
|
||||
import VisibilityOff from "@material-symbols/svg-400/rounded/visibility_off-fill.svg";
|
||||
import { DefaultLayout } from "../layout";
|
||||
|
||||
const PasswordInput = (props: ComponentProps<typeof Input>) => {
|
||||
const { css } = useYoshiki();
|
||||
const [show, setVisibility] = useState(false);
|
||||
console.log(show);
|
||||
|
||||
return (
|
||||
<Input
|
||||
secureTextEntry={!show}
|
||||
right={
|
||||
<IconButton
|
||||
icon={show ? VisibilityOff : Visibility}
|
||||
size={19}
|
||||
onPress={() => setVisibility(!show)}
|
||||
{...css({ width: px(19), height: px(19), m: 0, p: 0 })}
|
||||
/>
|
||||
}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const LoginPage: QueryPage = () => {
|
||||
return <View />;
|
||||
const { t } = useTranslation();
|
||||
const { css } = useYoshiki();
|
||||
|
||||
// TODO: Replace the hardcoded 1 to a random show/movie thumbnail.
|
||||
const src = `/api/shows/1/thumbnail`;
|
||||
const nativeProps = Platform.select<ImageProps>({
|
||||
web: {
|
||||
defaultSource: typeof src === "string" ? { uri: src! } : Array.isArray(src) ? src[0] : src!,
|
||||
},
|
||||
default: {},
|
||||
});
|
||||
|
||||
// TODO: Replace the borderRadius 99999 with an svg shape
|
||||
|
||||
return (
|
||||
<ImageBackground
|
||||
source={{ uri: src }}
|
||||
{...nativeProps}
|
||||
{...css({
|
||||
flexDirection: "row",
|
||||
flexGrow: 1,
|
||||
backgroundColor: (theme) => theme.dark.background,
|
||||
})}
|
||||
>
|
||||
<View
|
||||
{...css({
|
||||
width: min(vh(175), px(2400)),
|
||||
height: min(vh(175), px(2400)),
|
||||
transform: [{ translateX: percent(-50) }, { translateY: percent(-50) }],
|
||||
bg: (theme) => theme.background,
|
||||
paddingHorizontal: ts(1),
|
||||
borderRadius: 99999999999999999999999999999,
|
||||
justifyContent: "flex-end",
|
||||
alignItems: "flex-end",
|
||||
})}
|
||||
>
|
||||
<View {...css({ width: percent(50), height: percent(50), justifyContent: "center" })}>
|
||||
<View
|
||||
{...css({
|
||||
width: percent(75),
|
||||
maxWidth: vw(100),
|
||||
paddingHorizontal: ts(3),
|
||||
marginBottom: ts(16),
|
||||
})}
|
||||
>
|
||||
<H1>{t("login.login")}</H1>
|
||||
<P {...css({ paddingLeft: ts(1) })}>{t("login.email")}</P>
|
||||
<Input autoComplete="email" variant="big" />
|
||||
<P {...css({ paddingLeft: ts(1) })}>{t("login.password")}</P>
|
||||
<PasswordInput autoComplete="password" variant="big" />
|
||||
<Button
|
||||
text={t("login.login")}
|
||||
{...css({
|
||||
m: ts(1),
|
||||
width: px(250),
|
||||
maxWidth: percent(100),
|
||||
alignSelf: "center",
|
||||
mY: ts(3),
|
||||
})}
|
||||
/>
|
||||
<P>
|
||||
<Trans i18nKey="login.or-register">
|
||||
Don’t have an account? <A href="/register">Register</A>.
|
||||
</Trans>
|
||||
</P>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</ImageBackground>
|
||||
);
|
||||
};
|
||||
|
||||
LoginPage.getLayout = DefaultLayout;
|
||||
|
@ -66,8 +66,8 @@ const SearchBar = forwardRef<
|
||||
<Input
|
||||
ref={ref}
|
||||
value={query}
|
||||
onBlur={onBlur}
|
||||
onChange={(q) => {
|
||||
onBlur={() => onBlur?.call(null, query)}
|
||||
onChangeText={(q) => {
|
||||
if (Platform.OS === "web") {
|
||||
const action = window.location.pathname.startsWith("/search") ? replace : push;
|
||||
if (q) action(`/search?q=${q}`, undefined, { shallow: true });
|
||||
|
@ -49,5 +49,12 @@
|
||||
},
|
||||
"search": {
|
||||
"empty": "No result found. Try a different query."
|
||||
},
|
||||
"login": {
|
||||
"login": "Login",
|
||||
"register": "Register",
|
||||
"email": "Email",
|
||||
"password": "Password",
|
||||
"or-register": "Don’t have an account? <1>Register</1>."
|
||||
}
|
||||
}
|
||||
|
@ -49,5 +49,12 @@
|
||||
},
|
||||
"search": {
|
||||
"empty": "Aucun résultat trouvé. Essayer avec une autre recherche."
|
||||
},
|
||||
"login": {
|
||||
"login": "Connexion",
|
||||
"register": "Créer un compte",
|
||||
"email": "Email",
|
||||
"password": "Mot de passe",
|
||||
"or-register": "Vous n'avez pas de compte ? <1>Inscrivez-vous</1>."
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user