custom sign-in page
This commit is contained in:
105
pages/auth/signin.tsx
Normal file
105
pages/auth/signin.tsx
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// pages/auth/signin.js
|
||||||
|
import { getCsrfToken, signIn } from 'next-auth/react';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import Layout from '../../components/layout';
|
||||||
|
|
||||||
|
export default function SignIn({ csrfToken }) {
|
||||||
|
const [email, setEmail] = useState('');
|
||||||
|
const [password, setPassword] = useState('');
|
||||||
|
const [error, setError] = useState('');
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Perform client-side validation if needed
|
||||||
|
if (!email || !password) {
|
||||||
|
setError('All fields are required');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear any existing errors
|
||||||
|
setError('');
|
||||||
|
|
||||||
|
// Attempt to sign in
|
||||||
|
const result = await signIn('credentials', {
|
||||||
|
redirect: false,
|
||||||
|
username: email,
|
||||||
|
password,
|
||||||
|
callbackUrl: '/',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check if there was an error
|
||||||
|
if (result.error) {
|
||||||
|
setError(result.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect to the home page or callbackUrl on success
|
||||||
|
if (result.ok && result.url) {
|
||||||
|
router.push(result.url);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout>
|
||||||
|
<div className="page">
|
||||||
|
<div className="signin">
|
||||||
|
<div className="min-h-screen flex items-center justify-center">
|
||||||
|
<div className="provider">
|
||||||
|
{/* Button to sign in with Google */}
|
||||||
|
<button onClick={() => signIn('google', { callbackUrl: '/dash' })}>
|
||||||
|
<img loading="lazy" height="24" width="24" id="provider-logo" src="https://authjs.dev/img/providers/google.svg" alt="Google Logo" />
|
||||||
|
Sign in with Google
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="provider">
|
||||||
|
<form onSubmit={handleSubmit} className="w-full max-w-xs">
|
||||||
|
<input name="csrfToken" type="hidden" defaultValue={csrfToken} />
|
||||||
|
<div>
|
||||||
|
<label htmlFor="email">Email</label>
|
||||||
|
<input
|
||||||
|
id="email"
|
||||||
|
type="email"
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
className="border p-2 w-full"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="password">Password</label>
|
||||||
|
<input
|
||||||
|
id="password"
|
||||||
|
type="password"
|
||||||
|
value={password}
|
||||||
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
|
className="border p-2 w-full"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{error && <div className="text-red-500">{error}</div>}
|
||||||
|
<button type="submit" className="bg-blue-500 text-white p-2 mt-4">
|
||||||
|
Sign in
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="text-blue-500 p-2 mt-4"
|
||||||
|
onClick={() => router.push('/auth/reset-password')}>
|
||||||
|
Forgot password?
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This gets called on every request
|
||||||
|
export async function getServerSideProps(context) {
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
csrfToken: await getCsrfToken(context),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
Reference in New Issue
Block a user