Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | 14x 14x 58x 58x 58x 58x 58x 58x 58x 58x 1x 1x 58x 58x 2x 58x 102x 104x 156x 100x | import React from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import { z } from "zod";
import { PageHeader } from "~app/components/page-header";
import { NavigationContext } from "~app/contexts/navigation-context";
import { useBooleanState } from "~app/hooks/use-boolean-state";
import { useTrpcMutationOptions } from "~app/hooks/use-trpc-mutation-options";
import { useAppForm } from "~app/utils/forms";
import { noBatchContext, useTRPC } from "~app/utils/trpc";
import { emailSchema, passwordSchema } from "~app/utils/validation";
import { Button } from "~components/button";
import { Input } from "~components/input";
import { options as authLoginOptions } from "~mutations/auth/login";
import { ResetPasswordModal } from "./reset-password-modal";
const formSchema = z.object({ email: emailSchema, password: passwordSchema });
type Form = z.infer<typeof formSchema>;
export const LoginScreen = () => {
const { usePush, useSearchParams } = React.use(NavigationContext);
const { redirect: redirectUrl } = useSearchParams("__root__");
const { t } = useTranslation("login");
const trpc = useTRPC();
const push = usePush();
const queryClient = useQueryClient();
const [modalOpen, { switchValue: switchModalOpen, setTrue: openModal }] =
useBooleanState();
const loginMutation = useMutation(
trpc.auth.login.mutationOptions(
useTrpcMutationOptions(authLoginOptions, {
onSuccess: () => {
void queryClient.resetQueries();
push(redirectUrl);
},
trpc: { context: noBatchContext },
}),
),
);
const defaultValues: Partial<Form> = {};
const form = useAppForm({
defaultValues: defaultValues as Form,
validators: {
onMount: formSchema,
onChange: formSchema,
onSubmit: formSchema,
},
onSubmit: ({ value }) => loginMutation.mutate(value),
});
return (
<>
<PageHeader>{t("header")}</PageHeader>
<form.AppForm>
<form.Form className="flex flex-col gap-4">
<form.AppField name="email">
{(field) => (
<Input
value={field.state.value}
onValueChange={field.setValue}
label={t("form.email.label")}
fieldError={
field.state.meta.isDirty ? field.state.meta.errors : undefined
}
mutation={loginMutation}
type="email"
/>
)}
</form.AppField>
<form.AppField name="password">
{(field) => (
<Input
value={field.state.value}
onValueChange={field.setValue}
label={t("form.password.label")}
fieldError={
field.state.meta.isDirty ? field.state.meta.errors : undefined
}
mutation={loginMutation}
type="password"
/>
)}
</form.AppField>
<form.Subscribe selector={(state) => state.canSubmit}>
{(canSubmit) => (
<Button
className="mt-4"
color="primary"
isDisabled={!canSubmit || loginMutation.isPending}
isLoading={loginMutation.isPending}
type="submit"
>
{t("form.submit")}
</Button>
)}
</form.Subscribe>
</form.Form>
</form.AppForm>
<Button
color="primary"
isDisabled={loginMutation.isPending}
onPress={openModal}
>
{t("forgotPassword.button")}
</Button>
<ResetPasswordModal
isModalOpen={modalOpen}
switchModalOpen={switchModalOpen}
/>
</>
);
};
|