project setup
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import { Text } from "react-native";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
import { FormInput } from "@/components/auth/FormInput";
|
||||
import { PasswordInput } from "@/components/auth/PasswordInput";
|
||||
import { MessageDisplay } from "@/components/auth/MessageDisplay";
|
||||
import { AuthButton } from "@/components/auth/AuthButton";
|
||||
|
||||
const signInSchema = z.object({
|
||||
emailAddress: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, "Email is required")
|
||||
.pipe(z.email("Enter a valid email address")),
|
||||
password: z
|
||||
.string()
|
||||
.min(1, "Password is required")
|
||||
.max(128, "Password is too long"),
|
||||
});
|
||||
|
||||
type SignInValues = z.infer<typeof signInSchema>;
|
||||
|
||||
interface SignInFormProps {
|
||||
errorMessage: string;
|
||||
successMessage: string;
|
||||
isLoading: boolean;
|
||||
onSignInSubmit: (values: {
|
||||
emailAddress: string;
|
||||
password: string;
|
||||
}) => void | Promise<void>;
|
||||
}
|
||||
|
||||
export const SignInForm = ({
|
||||
errorMessage,
|
||||
successMessage,
|
||||
isLoading,
|
||||
onSignInSubmit,
|
||||
}: SignInFormProps) => {
|
||||
const { control, handleSubmit } = useForm<SignInValues>({
|
||||
resolver: zodResolver(signInSchema),
|
||||
defaultValues: { emailAddress: "", password: "" },
|
||||
mode: "onBlur",
|
||||
reValidateMode: "onBlur",
|
||||
shouldUnregister: false,
|
||||
});
|
||||
|
||||
const submit = (vals: SignInValues) =>
|
||||
onSignInSubmit({
|
||||
emailAddress: vals.emailAddress.trim().toLowerCase(),
|
||||
password: vals.password,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<Controller
|
||||
control={control}
|
||||
name="emailAddress"
|
||||
render={({ field: { onChange, onBlur, value }, fieldState: { error } }) => (
|
||||
<>
|
||||
<FormInput
|
||||
label="Email"
|
||||
value={value}
|
||||
onChangeText={onChange}
|
||||
onBlur={onBlur}
|
||||
icon="email"
|
||||
keyboardType="email-address"
|
||||
disabled={isLoading}
|
||||
style={{ marginBottom: 8 }}
|
||||
returnKeyType="next"
|
||||
/>
|
||||
{error ? (
|
||||
<Text style={{ color: "#F83434", marginBottom: 8 }}>
|
||||
{error.message}
|
||||
</Text>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
control={control}
|
||||
name="password"
|
||||
render={({ field: { onChange, onBlur, value }, fieldState: { error } }) => (
|
||||
<>
|
||||
<PasswordInput
|
||||
label="Password"
|
||||
value={value}
|
||||
onChangeText={onChange}
|
||||
onBlur={onBlur}
|
||||
disabled={isLoading}
|
||||
style={{ marginBottom: 8 }}
|
||||
returnKeyType="done"
|
||||
submitBehavior="blurAndSubmit"
|
||||
onSubmitEditing={() => handleSubmit(submit)()}
|
||||
/>
|
||||
{error ? (
|
||||
<Text style={{ color: "#F83434", marginBottom: 8 }}>
|
||||
{error.message}
|
||||
</Text>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
|
||||
{errorMessage ? (
|
||||
<MessageDisplay message={errorMessage} type="error" />
|
||||
) : null}
|
||||
{successMessage ? (
|
||||
<MessageDisplay message={successMessage} type="success" />
|
||||
) : null}
|
||||
|
||||
<AuthButton
|
||||
onPress={handleSubmit(submit)}
|
||||
loading={isLoading}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? "Signing in..." : "Sign In"}
|
||||
</AuthButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user