Files
AthenaFE/components/auth/SignInForm.tsx
T
2025-11-02 10:08:56 +01:00

124 lines
3.3 KiB
TypeScript

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>
</>
);
};