Mongo-db
Frontend
Frontend Development
Add to this Path src/components/auth/AuthForm.tsx
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { signIn } from 'next-auth/react';
import { useRouter } from 'next/router';
const loginSchema = z.object({
email: z.string().email('Invalid email address'),
password: z.string().min(6, 'Password must be at least 6 characters')
});
const registerSchema = loginSchema.extend({
confirmPassword: z.string()
}).refine(data => data.password === data.confirmPassword, {
message: "Passwords don't match",
path: ["confirmPassword"]
});
type FormData = z.infer<typeof loginSchema | typeof registerSchema>;
export default function AuthForm({ mode }: { mode: 'login' | 'register' }) {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(mode === 'login' ? loginSchema : registerSchema)
});
const [error, setError] = useState<string>('');
const router = useRouter();
const onSubmit = async (data: FormData) => {
try {
if (mode === 'login') {
const result = await signIn('credentials', {
redirect: false,
email: data.email,
password: data.password
});
if (result?.error) {
setError('Invalid credentials');
} else {
router.push('/dashboard');
}
} else {
const response = await fetch('/api/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (response.ok) {
await signIn('credentials', {
email: data.email,
password: data.password,
redirect: false
});
router.push('/dashboard');
} else {
const errorData = await response.json();
setError(errorData.error || 'Registration failed');
}
}
} catch (err) {
setError('An unexpected error occurred');
}
};
return (
<div className="max-w-md mx-auto mt-8 p-6 bg-white rounded-lg shadow-md">
<h2 className="text-2xl font-bold mb-6 text-center">
{mode === 'login' ? 'Sign In' : 'Create Account'}
</h2>
{error && (
<div className="mb-4 p-2 bg-red-100 text-red-700 rounded">
{error}
</div>
)}
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
<div>
<label className="block text-sm font-medium mb-1">Email</label>
<input
{...register('email')}
type="email"
className="w-full px-3 py-2 border rounded-md"
/>
{errors.email && (
<p className="text-red-500 text-sm mt-1">{errors.email.message}</p>
)}
</div>
<div>
<label className="block text-sm font-medium mb-1">Password</label>
<input
{...register('password')}
type="password"
className="w-full px-3 py-2 border rounded-md"
/>
{errors.password && (
<p className="text-red-500 text-sm mt-1">{errors.password.message}</p>
)}
</div>
{mode === 'register' && (
<div>
<label className="block text-sm font-medium mb-1">Confirm Password</label>
<input
{...register('confirmPassword')}
type="password"
className="w-full px-3 py-2 border rounded-md"
/>
{errors.confirmPassword && (
<p className="text-red-500 text-sm mt-1">
{errors.confirmPassword.message}
</p>
)}
</div>
)}
<button
type="submit"
className="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700"
>
{mode === 'login' ? 'Sign In' : 'Register'}
</button>
</form>
</div>
);
}