From eb1451c7554c8fff3e2477ec1d14ae6e902168ba Mon Sep 17 00:00:00 2001 From: William Tanardi Date: Wed, 24 May 2023 15:54:35 +0700 Subject: [PATCH] fixed login and register page --- prisma/schema.prisma | 7 +- src/app/(auth)/login/page.tsx | 74 +++++++++++++++ src/app/{ => (auth)}/register/form.tsx | 0 src/app/(auth)/register/page.tsx | 121 ++++++++++++++++++++++++ src/app/api/auth/[...nextauth]/route.ts | 1 + src/app/api/login.ts | 23 ----- src/app/api/register/route.ts | 7 +- src/app/register/page.tsx | 19 ---- src/lib/auth.ts | 19 ++-- 9 files changed, 217 insertions(+), 54 deletions(-) create mode 100644 src/app/(auth)/login/page.tsx rename src/app/{ => (auth)}/register/form.tsx (100%) create mode 100644 src/app/(auth)/register/page.tsx delete mode 100644 src/app/api/login.ts delete mode 100644 src/app/register/page.tsx diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 5e47b35..228f540 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -65,11 +65,12 @@ model Menu { } model User { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) name String - email String @unique + email String @unique password String - Order Order[] + isAdmin Boolean + orders Order[] } model Order { diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx new file mode 100644 index 0000000..7106b5a --- /dev/null +++ b/src/app/(auth)/login/page.tsx @@ -0,0 +1,74 @@ +"use client"; +import React, { useRef } from "react"; +import Header from "@/components/Header"; +import Link from "next/link"; +import { signIn } from "next-auth/react"; + +const Login = () => { + const email = useRef(""); + const pass = useRef(""); + + const onSubmit = async () => { + const result = await signIn("credentials", { + email: email.current, + password: pass.current, + redirect: true, + callbackUrl: "/dashboard/user", + }); + }; + + return ( + <> +
+
+

Login

+
+
+ + (email.current = e.target.value)} + /> +
+
+ + (pass.current = e.target.value)} + /> +
+ + +
+

+ Not Registered? + + +   Sign up + + +

+
+ + ); +}; + +export default Login; diff --git a/src/app/register/form.tsx b/src/app/(auth)/register/form.tsx similarity index 100% rename from src/app/register/form.tsx rename to src/app/(auth)/register/form.tsx diff --git a/src/app/(auth)/register/page.tsx b/src/app/(auth)/register/page.tsx new file mode 100644 index 0000000..4fda113 --- /dev/null +++ b/src/app/(auth)/register/page.tsx @@ -0,0 +1,121 @@ +"use client"; +import Header from "@/components/Header"; +import Link from "next/link"; +import { signIn } from "next-auth/react"; +import { ChangeEvent, useState } from "react"; + +export default function RegisterPage() { + let [loading, setLoading] = useState(false); + let [formValues, setFormValues] = useState({ + name: "", + email: "", + password: "", + }); + + const onSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setLoading(true); + + try { + const res = await fetch("/api/register", { + method: "POST", + body: JSON.stringify(formValues), + headers: { + "Content-Type": "application/json", + }, + }); + + setLoading(false); + if (!res.ok) { + alert((await res.json()).message); + return; + } + + signIn(undefined, { callbackUrl: "/" }); + } catch (error: any) { + setLoading(false); + console.error(error); + alert(error.message); + } + }; + + const handleChange = (event: ChangeEvent) => { + const { name, value } = event.target; + setFormValues({ ...formValues, [name]: value }); + }; + return ( + <> +
+
+

Create Account

+
+
+ + +
+
+ + +
+
+ + +
+ +
+

+ Already have an account? + + + Sign in + + +

+
+ + ); +} diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts index 3ad333e..721d9ec 100644 --- a/src/app/api/auth/[...nextauth]/route.ts +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -3,3 +3,4 @@ import NextAuth from "next-auth"; const handler = NextAuth(authOptions); export { handler as GET, handler as POST }; + diff --git a/src/app/api/login.ts b/src/app/api/login.ts deleted file mode 100644 index 352b828..0000000 --- a/src/app/api/login.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { NextApiRequest, NextApiResponse } from "next"; - -const loginHandler = (req: NextApiRequest, res: NextApiResponse) => { - if (req.method === "POST") { - // Perform authentication logic here - // Validate user credentials, generate tokens, etc. - // Example authentication logic: - const { email, password } = req.body; - - if (email === "user@example.com" && password === "password") { - // Authentication successful - res.status(200).json({ message: "Login successful" }); - } else { - // Authentication failed - res.status(401).json({ message: "Invalid email or password" }); - } - } else { - // Only accept POST requests - res.status(405).end(); - } -}; - -export default loginHandler; diff --git a/src/app/api/register/route.ts b/src/app/api/register/route.ts index 5edac65..7777a3e 100644 --- a/src/app/api/register/route.ts +++ b/src/app/api/register/route.ts @@ -8,6 +8,7 @@ export async function POST(req: Request) { name: string; email: string; password: string; + isAdmin: boolean; }; const hashed_password = await hash(password, 12); @@ -16,13 +17,15 @@ export async function POST(req: Request) { name, email: email.toLowerCase(), password: hashed_password, + isAdmin: false, }, }); - + return NextResponse.json({ user: { name: user.name, email: user.email, + isAdmin: user.isAdmin, }, }); } catch (error: any) { @@ -34,4 +37,4 @@ export async function POST(req: Request) { { status: 500 } ); } -} +} \ No newline at end of file diff --git a/src/app/register/page.tsx b/src/app/register/page.tsx deleted file mode 100644 index 0f364de..0000000 --- a/src/app/register/page.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { RegisterForm } from "./form"; - -export default function RegisterPage() { - return ( -
-
-

Register

- -
-
- ); -} diff --git a/src/lib/auth.ts b/src/lib/auth.ts index dc5787b..5029681 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -1,6 +1,6 @@ import { prisma } from "@/lib/prisma"; import { compare } from "bcrypt"; -import type { NextAuthOptions } from "next-auth"; +import type { NextAuthOptions, User } from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; export const authOptions: NextAuthOptions = { @@ -17,29 +17,30 @@ export const authOptions: NextAuthOptions = { placeholder: "example@example.com", }, password: { label: "Password", type: "password" }, + }, - async authorize(credentials) { + async authorize(credentials, req) { if (!credentials?.email || !credentials.password) { return null; } - + const user = await prisma.user.findUnique({ where: { email: credentials.email, }, }); - + if (!user || !(await compare(credentials.password, user.password))) { return null; } - + return { id: user.id, email: user.email, name: user.name, randomKey: "Hey cool", - }; - }, + } as unknown as User; // Cast the return value to the User type + } }), ], callbacks: { @@ -67,4 +68,8 @@ export const authOptions: NextAuthOptions = { return token; }, }, + pages: { + signIn: "/login", + signOut: "/register", + } };