Files
AthenaFE/app/(auth)/forgot-password.tsx
2025-11-05 20:11:34 +01:00

119 lines
3.6 KiB
TypeScript

import { useRouter } from "expo-router";
import { useState } from "react";
import { View, Text, TouchableOpacity } from "react-native";
import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { AuthLayout } from "@/components/auth/AuthLayout";
import { AuthHeader } from "@/components/auth/AuthHeader";
import { AuthCard } from "@/components/auth/AuthCard";
import { FormInput } from "@/components/auth/FormInput";
import { getApiUrl } from "@/store/api/baseApi";
import { AuthButton } from "@/components/auth/AuthButton";
import { MessageDisplay } from "@/components/auth/MessageDisplay";
const schema = z.object({
email: z.email("Enter a valid email"),
});
type FormValues = z.infer<typeof schema>;
const ForgotPasswordScreen = () => {
const router = useRouter();
const [submitting, setSubmitting] = useState(false);
const [message, setMessage] = useState("");
const [error, setError] = useState("");
const {
handleSubmit,
setValue,
watch,
formState: { errors },
} = useForm<FormValues>({
resolver: zodResolver(schema),
mode: "onSubmit",
reValidateMode: "onChange",
shouldUnregister: false,
defaultValues: { email: "" },
});
const email = watch("email");
const onSubmit = async (values: FormValues) => {
setSubmitting(true);
setError("");
setMessage("");
try {
const res = await fetch(
`${getApiUrl()?.replace(/\/$/, "")}/auth/password/forgot`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email: values.email }),
}
);
const data = await res.json();
if (!res.ok) {
throw new Error(data?.error || "Failed to request reset");
}
setMessage("If an account exists for this email, a reset link was sent");
} catch (error: unknown) {
if (error instanceof Error) {
setError(error.message);
} else {
setError("Failed to request reset");
}
} finally {
setSubmitting(false);
}
};
return (
<AuthLayout>
<AuthHeader title="Bird Eye View" />
<AuthCard title="Forgot Password" subtitle="We'll email you a reset link">
{error ? <MessageDisplay message={error} type="error" /> : null}
{message ? <MessageDisplay message={message} type="success" /> : null}
<FormInput
label="Email"
value={email}
onChangeText={(t) => setValue("email", t, { shouldValidate: true })}
icon="email"
disabled={submitting}
onSubmitEditing={handleSubmit(onSubmit)}
returnKeyType="send"
submitBehavior="blurAndSubmit"
/>
{errors.email?.message ? (
<Text style={{ color: "#F83434", marginTop: -4, marginBottom: 8 }}>
{errors.email.message}
</Text>
) : null}
<AuthButton
onPress={handleSubmit(onSubmit)}
loading={submitting}
disabled={submitting}
>
{submitting ? "Sending..." : "Send Reset Link"}
</AuthButton>
<View style={{ alignItems: "center", marginTop: 16 }}>
<Text>Remembered your password?</Text>
<TouchableOpacity
onPress={() => router.push("/sign-in")}
disabled={submitting}
>
<Text className="text-primaryPurpleDark font-bold mt-4">
Sign in
</Text>
</TouchableOpacity>
</View>
</AuthCard>
</AuthLayout>
);
};
export default ForgotPasswordScreen;