Files
portabase/src/features/auth/reset-password-form.tsx
T

97 lines
3.3 KiB
TypeScript
Raw Normal View History

2025-12-21 16:55:12 +01:00
"use client";
import {useMutation} from "@tanstack/react-query";
import {toast} from "sonner";
import {FormControl, FormField, FormItem, FormLabel, useZodForm} from "@/components/ui/form";
import {Form} from "@/components/ui/form";
2026-05-24 17:09:12 +02:00
import {ButtonWithLoading} from "@/components/common/button-with-loading";
2025-12-21 16:55:12 +01:00
import Link from "next/link";
import {ResetPasswordSchema, ResetPasswordType} from "./reset-password-form.schema";
import {PasswordStrengthInput} from "@/components/ui/password-input-indicator";
import {useRouter, useSearchParams} from "next/navigation";
import {ArrowLeft} from "lucide-react";
import {authClient} from "@/lib/auth/auth-client";
import {BetterAuthError} from "@/types/auth";
import {PasswordInput} from "@/components/ui/password-input";
export type ResetPasswordFormProps = {
defaultValues?: ResetPasswordType;
};
export const ResetPasswordForm = (props: ResetPasswordFormProps) => {
const searchParams = useSearchParams();
const form = useZodForm({
schema: ResetPasswordSchema,
});
const router = useRouter();
const mutation = useMutation({
mutationFn: async (values: ResetPasswordType) => {
const {data, error} = await authClient.resetPassword({
newPassword: values.password,
token: searchParams.get("token") || "",
});
if (error) throw error;
},
onSuccess: () => {
toast.success("Password successfully reset!");
setTimeout(() => router.push("/"), 1400);
},
onError: (error: BetterAuthError) => {
toast.error("An error occurred while resetting password");
},
});
return (
<Form
form={form}
className="flex flex-col gap-4 mb-1"
onSubmit={async (values) => {
await mutation.mutateAsync(values);
}}
>
<FormField
control={form.control}
name="password"
defaultValue=""
render={({field}) => (
<FormItem>
<PasswordStrengthInput label={"New password"} field={field}/>
</FormItem>
)}
/>
<FormField
control={form.control}
name="confirmPassword"
defaultValue=""
render={({field}) => (
<FormItem>
<FormLabel>Confirmation password</FormLabel>
<FormControl>
<PasswordInput placeholder={"Enter your conformation password"} {...field} />
</FormControl>
</FormItem>
)}
/>
<div className="flex flex-col items-center gap-y-6 w-full">
2026-02-12 15:48:51 +01:00
<ButtonWithLoading className="mt-2 w-full h-11" isPending={mutation.isPending}>
2025-12-21 16:55:12 +01:00
Reset
</ButtonWithLoading>
<Link href="/login" className="group flex items-center text-sm hover:underline">
<ArrowLeft
className="mr-1 size-4 text-muted-foreground transition-transform group-hover:-translate-x-1"/>
Back to login
</Link>
</div>
</Form>
);
};