140 lines
4.5 KiB
TypeScript
140 lines
4.5 KiB
TypeScript
'use client';
|
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
import { Button } from '@repo/shadcn/button';
|
|
import {
|
|
Form,
|
|
FormControl,
|
|
FormField,
|
|
FormItem,
|
|
FormLabel,
|
|
FormMessage,
|
|
} from '@repo/shadcn/form';
|
|
import { Input } from '@repo/shadcn/input';
|
|
import { signIn } from 'next-auth/react';
|
|
import { useRouter, useSearchParams } from 'next/navigation';
|
|
import { useState, useTransition } from 'react';
|
|
import { useForm } from 'react-hook-form';
|
|
import { toast } from 'sonner';
|
|
import { UserFormValue, formSchema } from '../schemas/login';
|
|
|
|
export default function UserAuthForm() {
|
|
const router = useRouter();
|
|
const searchParams = useSearchParams();
|
|
const callbackUrl = searchParams.get('callbackUrl');
|
|
const [loading, startTransition] = useTransition();
|
|
const [error, SetError] = useState<string | null>(null);
|
|
const defaultValues = {
|
|
username: '',
|
|
password: '',
|
|
};
|
|
const form = useForm<UserFormValue>({
|
|
resolver: zodResolver(formSchema),
|
|
defaultValues,
|
|
});
|
|
|
|
const onSubmit = async (data: UserFormValue) => {
|
|
SetError(null); // Limpia cualquier error previo al intentar iniciar sesión
|
|
startTransition(async () => {
|
|
try {
|
|
const login = await signIn('credentials', {
|
|
username: data.username,
|
|
password: data.password,
|
|
redirect: false, // No queremos una redirección automática aquí
|
|
});
|
|
|
|
|
|
|
|
if (login?.error) {
|
|
const errorMessage =
|
|
login.error === 'CredentialsSignin'
|
|
? 'Usuario o contraseña incorrectos'
|
|
: 'Contacte al Administrador';
|
|
SetError(errorMessage);
|
|
toast.error(errorMessage);
|
|
}
|
|
|
|
// Si la autenticación es exitosa y `redirect: false`, necesitamos redirigir manualmente
|
|
if (login?.ok && !login?.error) {
|
|
toast.success('Ingreso Exitoso!');
|
|
router.push(callbackUrl ?? '/dashboard');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error durante el inicio de sesión:', error);
|
|
toast.error('Hubo un error inesperado');
|
|
}
|
|
});
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Form {...form}>
|
|
|
|
<form className="p-6 md:p-8" onSubmit={form.handleSubmit(onSubmit)}>
|
|
<div className="flex flex-col gap-6">
|
|
<div className="flex flex-col items-center text-center">
|
|
<h1 className="text-2xl font-bold">Sistema Integral Fondemi</h1>
|
|
<p className="text-balance text-muted-foreground">
|
|
Ingresa tus datos
|
|
</p>
|
|
</div>
|
|
<div className="grid gap-2">
|
|
<FormField
|
|
control={form.control}
|
|
name="username"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>Usuario</FormLabel>
|
|
<FormControl>
|
|
<Input
|
|
type="text"
|
|
placeholder="ingrese su usuario..."
|
|
disabled={loading}
|
|
{...field}
|
|
/>
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
</div>
|
|
<div className="grid gap-2">
|
|
|
|
<FormField
|
|
control={form.control}
|
|
name="password"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>Contraseña</FormLabel>
|
|
<FormControl>
|
|
<Input
|
|
type="password"
|
|
placeholder="*************"
|
|
disabled={loading}
|
|
{...field}
|
|
/>
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
|
|
</div>
|
|
{error && (
|
|
<FormMessage className="text-red-500">{error}</FormMessage>
|
|
)}{' '}
|
|
<Button disabled={loading} type="submit" className="w-full">
|
|
Ingresar
|
|
</Button>
|
|
<div className="text-center text-sm">
|
|
No tienes una cuenta?{" "}
|
|
<a href="/register" className="underline underline-offset-4">
|
|
Registrate
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</Form>
|
|
</>
|
|
);
|
|
}
|