Skip to content

Commit b39dff9

Browse files
author
Harshit Yadav
committed
feat: added register page,and its functionality; setup schema of neon db and prisma
1 parent e8cf13b commit b39dff9

33 files changed

+2193
-321
lines changed

.env

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
3+
# This was inserted by `prisma init`:
4+
# Environment variables declared in this file are automatically made available to Prisma.
5+
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
6+
7+
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
8+
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
9+
10+
DATABASE_URL="postgresql://CodeMaster17:qc8Qn7kBDrGb@ep-falling-pine-75509530-pooler.us-east-2.aws.neon.tech/auth?sslmode=require&pgbouncer=true"
11+
DIRECT_URL="postgresql://CodeMaster17:qc8Qn7kBDrGb@ep-falling-pine-75509530.us-east-2.aws.neon.tech/auth?sslmode=require"

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ yarn-debug.log*
2626
yarn-error.log*
2727

2828
# local env files
29-
.env*.local
3029

3130
# vercel
3231
.vercel

README.md

Lines changed: 124 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,138 @@
1-
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
1+
# NextJs V5 Authentication
22

3-
## Getting Started
3+
7. Create Register page UI
4+
8. Install prisma
5+
`npm i -D prisma`
6+
9. install prisma client
7+
`npm i @prisma/client`
8+
10. Go to `database.connection.ts` and add following code
49

5-
First, run the development server:
10+
```
11+
import { PrismaClient } from "@prisma/client";
12+
declare global {
13+
var prisma: PrismaClient | undefined;
14+
}
15+
export const db = globalThis.prisma || new PrismaClient();
16+
17+
if (process.env.NODE_ENV !== "production") globalThis.prisma = db
18+
19+
```
20+
21+
11. Run command
22+
`npx prisma init`
23+
12. We used `Neon DB` as our database
24+
13. Got to `Neon DB ` to create a new database
25+
14. Paste connection string in `schema.prisma` and `.env` file
26+
15. Start creating schema in `schema.prisma` file
27+
16. With help of `db` in `database.connection.ts` file we can access our models
28+
17. Create `User` model in `schema.prisma` file
29+
18. Should also run following command to access `User` model in `database.connection.ts` file
30+
`npx prisma generate`
31+
19. To psuh your schema to database
32+
`npx prisma db push`
33+
34+
20. Move to `Auth JS site`
35+
21. Select database adapter as `Prisma`
36+
22. Install `@auth/prisma-adapter`
37+
23. Comand to install `@auth/prisma-adapter`
38+
`npm i @auth/prisma-adapter`
39+
24. Copy model `User` and paste in `schema.prisma` file
40+
25. Copy model `Account` and paste in `schema.prisma` file ( We are not using session model from `Auth JS site`)
41+
26. Push again to database
42+
`npx prisma generate` and `npx prisma db push`
43+
27. Auth does not use `password` field in `User` model. So we need to add it to user model as optional because google aut h providers do not require password in `schema.prisma` file.
44+
28. Add the code below to validate fields in `register.ts`
45+
46+
```
47+
"use server";
48+
49+
import { RegisterSchema } from "@/schema";
50+
import * as z from "zod";
51+
52+
export const register = async (values: z.infer<typeof RegisterSchema>) => {
53+
const validatedFields = RegisterSchema.safeParse(values); // safeParse returns a ZodResult object, and it is used to validate the input values
54+
if (!validatedFields.success) {
55+
return { error: "Invalid fields!" };
56+
}
57+
return { success: "Email sent!" };
58+
};
59+
60+
```
61+
62+
29. Install `bcrypt` to hash password
63+
`npm i bcrypt` and `npm i -D @types/bcrypt`
64+
30. Create register function
665

7-
```bash
8-
npm run dev
9-
# or
10-
yarn dev
11-
# or
12-
pnpm dev
13-
# or
14-
bun dev
1566
```
67+
export const register = async (values: z.infer<typeof RegisterSchema>) => {
68+
69+
// * check and store user in database
70+
71+
const validatedFields = RegisterSchema.safeParse(values); // safeParse returns a ZodResult object, and it is used to validate the input values
72+
if (!validatedFields.success) {
73+
return { error: "Invalid fields!" };
74+
}
75+
76+
const { email, password, name } = validatedFields.data;
77+
const hashedPassword = await bcrypt.hash(password, 10); // 10 is the number of salt rounds
78+
79+
//finding the email in database
80+
const exisitingUser = await db.user.findUnique({
81+
where: {
82+
email,
83+
},
84+
});
85+
86+
// if user already exists, return error
87+
if (exisitingUser) {
88+
return { error: "Email already exists!" };
89+
}
1690
17-
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
91+
// if not, create and save it in database
92+
await db.user.create({
93+
data: {
94+
name,
95+
email,
96+
password: hashedPassword,
97+
},
98+
});
1899
19-
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
100+
// TODO: send verification email
20101
21-
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
102+
return { success: "Email sent!" };
103+
};
22104
23-
## Learn More
105+
```
106+
107+
31. Create user actions in `user.action.ts` file, to get user by email and id
24108

25-
To learn more about Next.js, take a look at the following resources:
109+
```
110+
export const getUserByEmail = async (email: string) => {
111+
try {
112+
const user = await db.user.findUnique({ where: { email } });
113+
return user;
114+
} catch {
115+
return null;
116+
}
117+
};
26118
27-
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28-
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
119+
export const getUserById = async (id: string) => {
120+
try {
121+
const user = await db.user.findUnique({ where: { id } });
122+
return user;
123+
} catch {
124+
return null;
125+
}
126+
};
29127
30-
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
128+
```
31129

32-
## Deploy on Vercel
130+
32. Use it in `register.ts` function
33131

34-
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
132+
```
133+
//finding the email in database
134+
const exisitingUser = await getUserByEmail(email)
35135
36-
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
136+
```
137+
33. Now, for `login` we have to install nextauth v5
138+
`npm i next-auth@beta`

actions/auth/login.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"use server"; // necessary in every auth action
2+
3+
export const Login = (values: any) => {
4+
console.log(values);
5+
};

actions/auth/register.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"use server";
2+
3+
import { RegisterSchema } from "@/schema";
4+
import * as z from "zod";
5+
import bcrypt from "bcrypt";
6+
import { db } from "@/lib/database.connection";
7+
import { getUserByEmail } from "@/lib/actions/user.action";
8+
9+
export const register = async (values: z.infer<typeof RegisterSchema>) => {
10+
11+
// * check and store user in database
12+
13+
const validatedFields = RegisterSchema.safeParse(values); // safeParse returns a ZodResult object, and it is used to validate the input values
14+
if (!validatedFields.success) {
15+
return { error: "Invalid fields!" };
16+
}
17+
18+
const { email, password, name } = validatedFields.data;
19+
const hashedPassword = await bcrypt.hash(password, 10); // 10 is the number of salt rounds
20+
21+
//finding the email in database
22+
const exisitingUser = await getUserByEmail(email)
23+
24+
// if user already exists, return error
25+
if (exisitingUser) {
26+
return { error: "Email already exists!" };
27+
}
28+
29+
// if not, create and save it in database
30+
await db.user.create({
31+
data: {
32+
name,
33+
email,
34+
password: hashedPassword,
35+
},
36+
});
37+
38+
// TODO: send verification email
39+
40+
return { success: "Email sent!" };
41+
};

app/auth/layout.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from 'react'
2+
3+
const AuthLayout = ({ children }: { children: React.ReactNode }) => {
4+
return (
5+
<div className="h-full flex items-center justify-center bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-sky-400 to-blue-800">
6+
{children}
7+
</div>
8+
)
9+
}
10+
11+
export default AuthLayout

app/auth/login/page.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import LoginForm from '@/components/auth/login-form'
2+
import React from 'react'
3+
4+
const LoginPage = () => {
5+
return (
6+
<div >
7+
<LoginForm />
8+
</div>
9+
)
10+
}
11+
12+
export default LoginPage

app/auth/register/page.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import RegisterForm from '@/components/auth/register-form'
2+
import React from 'react'
3+
4+
const Register = () => {
5+
return (
6+
<>
7+
8+
<RegisterForm />
9+
</>
10+
11+
)
12+
}
13+
14+
export default Register

app/globals.css

Lines changed: 72 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,82 @@
22
@tailwind components;
33
@tailwind utilities;
44

5+
html,
6+
body,
57
:root {
6-
--foreground-rgb: 0, 0, 0;
7-
--background-start-rgb: 214, 219, 220;
8-
--background-end-rgb: 255, 255, 255;
8+
height: 100%;
99
}
1010

11-
@media (prefers-color-scheme: dark) {
11+
@layer base {
1212
:root {
13-
--foreground-rgb: 255, 255, 255;
14-
--background-start-rgb: 0, 0, 0;
15-
--background-end-rgb: 0, 0, 0;
13+
--background: 0 0% 100%;
14+
--foreground: 222.2 84% 4.9%;
15+
16+
--card: 0 0% 100%;
17+
--card-foreground: 222.2 84% 4.9%;
18+
19+
--popover: 0 0% 100%;
20+
--popover-foreground: 222.2 84% 4.9%;
21+
22+
--primary: 222.2 47.4% 11.2%;
23+
--primary-foreground: 210 40% 98%;
24+
25+
--secondary: 210 40% 96.1%;
26+
--secondary-foreground: 222.2 47.4% 11.2%;
27+
28+
--muted: 210 40% 96.1%;
29+
--muted-foreground: 215.4 16.3% 46.9%;
30+
31+
--accent: 210 40% 96.1%;
32+
--accent-foreground: 222.2 47.4% 11.2%;
33+
34+
--destructive: 0 84.2% 60.2%;
35+
--destructive-foreground: 210 40% 98%;
36+
37+
--border: 214.3 31.8% 91.4%;
38+
--input: 214.3 31.8% 91.4%;
39+
--ring: 222.2 84% 4.9%;
40+
41+
--radius: 0.5rem;
1642
}
17-
}
1843

19-
body {
20-
color: rgb(var(--foreground-rgb));
21-
background: linear-gradient(
22-
to bottom,
23-
transparent,
24-
rgb(var(--background-end-rgb))
25-
)
26-
rgb(var(--background-start-rgb));
44+
.dark {
45+
--background: 222.2 84% 4.9%;
46+
--foreground: 210 40% 98%;
47+
48+
--card: 222.2 84% 4.9%;
49+
--card-foreground: 210 40% 98%;
50+
51+
--popover: 222.2 84% 4.9%;
52+
--popover-foreground: 210 40% 98%;
53+
54+
--primary: 210 40% 98%;
55+
--primary-foreground: 222.2 47.4% 11.2%;
56+
57+
--secondary: 217.2 32.6% 17.5%;
58+
--secondary-foreground: 210 40% 98%;
59+
60+
--muted: 217.2 32.6% 17.5%;
61+
--muted-foreground: 215 20.2% 65.1%;
62+
63+
--accent: 217.2 32.6% 17.5%;
64+
--accent-foreground: 210 40% 98%;
65+
66+
--destructive: 0 62.8% 30.6%;
67+
--destructive-foreground: 210 40% 98%;
68+
69+
--border: 217.2 32.6% 17.5%;
70+
--input: 217.2 32.6% 17.5%;
71+
--ring: 212.7 26.8% 83.9%;
72+
}
2773
}
74+
75+
@layer base {
76+
* {
77+
@apply border-border;
78+
}
79+
80+
body {
81+
@apply bg-background text-foreground;
82+
}
83+
}

0 commit comments

Comments
 (0)