From f1af066f26d5791ccc2aabaf3cd76a97ca300cf9 Mon Sep 17 00:00:00 2001 From: Bilal Date: Wed, 24 Jan 2024 03:34:43 +0500 Subject: [PATCH] Next-Project --- package-lock.json | 10 ++ package.json | 1 + src/app/api/register/route.js | 67 ++++++++++++ src/app/globals.css | 13 +++ src/app/layout.js | 2 +- src/app/login/page.jsx | 55 ++++++++++ src/app/register/page.jsx | 103 ++++++++++++++++++ .../FormElements/InputComponent/index.jsx | 20 ++++ .../FormElements/SelectComponent/index.jsx | 36 ++++++ src/components/Loader/componentlevel/index.js | 17 +++ src/components/Navbar.jsx | 56 ++++++++-- src/database/index.js | 20 ++++ src/models/user.js | 12 ++ src/services/register/index.js | 17 +++ src/utils/index.js | 60 +++++++++- 15 files changed, 477 insertions(+), 12 deletions(-) create mode 100644 src/app/api/register/route.js create mode 100644 src/app/login/page.jsx create mode 100644 src/app/register/page.jsx create mode 100644 src/components/FormElements/InputComponent/index.jsx create mode 100644 src/components/FormElements/SelectComponent/index.jsx create mode 100644 src/components/Loader/componentlevel/index.js create mode 100644 src/database/index.js create mode 100644 src/models/user.js create mode 100644 src/services/register/index.js diff --git a/package-lock.json b/package-lock.json index 2fba6cc..7013b2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "next": "14.1.0", "react": "^18", "react-dom": "^18", + "react-spinners": "^0.13.8", "react-toastify": "^10.0.4", "stripe": "^14.13.0" }, @@ -4674,6 +4675,15 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, + "node_modules/react-spinners": { + "version": "0.13.8", + "resolved": "https://registry.npmjs.org/react-spinners/-/react-spinners-0.13.8.tgz", + "integrity": "sha512-3e+k56lUkPj0vb5NDXPVFAOkPC//XyhKPJjvcGjyMNPWsBKpplfeyialP74G7H7+It7KzhtET+MvGqbKgAqpZA==", + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-toastify": { "version": "10.0.4", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.4.tgz", diff --git a/package.json b/package.json index 3b1dbb4..9fd28ac 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "next": "14.1.0", "react": "^18", "react-dom": "^18", + "react-spinners": "^0.13.8", "react-toastify": "^10.0.4", "stripe": "^14.13.0" }, diff --git a/src/app/api/register/route.js b/src/app/api/register/route.js new file mode 100644 index 0000000..b384e47 --- /dev/null +++ b/src/app/api/register/route.js @@ -0,0 +1,67 @@ +import connectToDB from "@/database"; +import User from "@/models/user"; +import { hash } from "bcryptjs"; +import Joi from "joi"; +import { NextResponse } from "next/server"; + +const schema = Joi.object({ + name: Joi.string().required(), + email: Joi.string().email().required(), + password: Joi.string().min(6).required(), + role: Joi.string().required(), +}); + +export const dynamic = "force-dynamic"; + +export async function POST(req) { + await connectToDB(); + + const { name, email, password, role } = await req.json(); + //validate the schema + + const { error } = schema.validate({ name, email, password, role }); + + if (error) { + console.log(error); + return NextResponse.json({ + success: false, + message: error.details[0].message, + }); + } + + try { + //check if the user is exists or not + + const isUserAlreadyExists = await User.findOne({ email }); + + if (isUserAlreadyExists) { + return NextResponse.json({ + success: false, + message: "User is already exists. Please try with different email.", + }); + } else { + const hashPassword = await hash(password, 12); + + const newlyCreatedUser = await User.create({ + name, + email, + password: hashPassword, + role, + }); + + if (newlyCreatedUser) { + return NextResponse.json({ + success: true, + message: "Account created successfully.", + }); + } + } + } catch (error) { + console.log("Error while new user registration. Please try again"); + + return NextResponse.json({ + success: false, + message: "Something went wrong ! Please try again later", + }); + } +} \ No newline at end of file diff --git a/src/app/globals.css b/src/app/globals.css index a90f074..96506dc 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -2,3 +2,16 @@ @tailwind components; @tailwind utilities; +body::-webkit-scrollbar { + width: 5px; +} + +body::-webkit-scrollbar-track { + box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); +} + +body::-webkit-scrollbar-thumb { + background-color: darkgrey; + outline: 1px solid slategrey; +} + diff --git a/src/app/layout.js b/src/app/layout.js index 66a4dbc..5528f89 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -16,7 +16,7 @@ export default function RootLayout({ children }) { -
{children}
+
{children}
diff --git a/src/app/login/page.jsx b/src/app/login/page.jsx new file mode 100644 index 0000000..eb89dbd --- /dev/null +++ b/src/app/login/page.jsx @@ -0,0 +1,55 @@ +"use client"; +import InputComponent from "@/components/FormElements/InputComponent"; +import { loginFormControls } from "@/utils"; +import { useRouter } from "next/navigation"; +import React from "react"; + +const Login = () => { + const router = useRouter(); + return ( +
+
+
+
+
+

+ Login +

+
+ {loginFormControls.map((controlItem) => + controlItem.componentType === "input" ? ( + + ) : null + )} + +
+

New to Website ?

+ +
+
+
+
+
+
+
+ ); +}; + +export default Login; diff --git a/src/app/register/page.jsx b/src/app/register/page.jsx new file mode 100644 index 0000000..dc7b0fc --- /dev/null +++ b/src/app/register/page.jsx @@ -0,0 +1,103 @@ +"use client"; +import InputComponent from "@/components/FormElements/InputComponent"; +import SelectComponent from "@/components/FormElements/SelectComponent"; +import { registerNewUser } from "@/services/register"; +import { registrationFormControls } from "@/utils"; +import React, { useState } from "react"; + +const Register = () => { + const isRegistered = false; + const initialFormData = { + name: "", + email: "", + password: "", + role: "customer", + }; + + const [formData, setFormData] = useState(initialFormData); + console.log(formData); + + function isFormValid() { + return formData && + formData.name && + formData.name.trim() !== "" && + formData.email && + formData.email.trim() !== "" && + formData.password && + formData.password.trim() !== "" + ? true + : false; + } + async function handleRegisterOnSubmit(){ +const data = await registerNewUser(formData) +console.log(data) + } + return ( +
+
+
+
+
+

+ {isRegistered + ? "Registration Successfull !" + : "Sign up for an account"} +

+ {isRegistered ? ( + + ) : ( +
+ {registrationFormControls.map((controlItem) => + controlItem.componentType === "input" ? ( + { + setFormData({ + ...formData, + [controlItem.id]: event.target.value, + }); + }} + value={formData[controlItem.id]} + /> + ) : controlItem.componentType === "select" ? ( + { + setFormData({ + ...formData, + [controlItem.id]: event.target.value, + }); + }} + value={formData[controlItem.id]} + /> + ) : null + )} + +
+ )} +
+
+
+
+
+ ); +}; + +export default Register; diff --git a/src/components/FormElements/InputComponent/index.jsx b/src/components/FormElements/InputComponent/index.jsx new file mode 100644 index 0000000..2980d25 --- /dev/null +++ b/src/components/FormElements/InputComponent/index.jsx @@ -0,0 +1,20 @@ +import React from "react"; + +const InputComponent = ({ label, placeholder, type, value, onChange }) => { + return ( +
+

+ {label} +

+ +
+ ); +}; + +export default InputComponent; diff --git a/src/components/FormElements/SelectComponent/index.jsx b/src/components/FormElements/SelectComponent/index.jsx new file mode 100644 index 0000000..fee7639 --- /dev/null +++ b/src/components/FormElements/SelectComponent/index.jsx @@ -0,0 +1,36 @@ +import React from "react"; + +const SelectComponent = ({ label, value, onChange, options = [] }) => { + return ( +
+
+

+ {label} +

+ +
+
+ ); +}; + +export default SelectComponent; diff --git a/src/components/Loader/componentlevel/index.js b/src/components/Loader/componentlevel/index.js new file mode 100644 index 0000000..574adc1 --- /dev/null +++ b/src/components/Loader/componentlevel/index.js @@ -0,0 +1,17 @@ +"use client"; + +import { PulseLoader } from "react-spinners"; + +export default function ComponentLevelLoader({ text, color, loading, size }) { + return ( + + {text} + + + ); +} \ No newline at end of file diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index bc09e23..5f7c290 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -1,6 +1,6 @@ "use client"; import { GlobalContext } from "@/context"; -import { adminNavOptions, navOptions, styles } from "@/utils"; +import { adminNavOptions, navOptions } from "@/utils"; import React, { Fragment, useContext } from "react"; import CommonModal from "./CommonModal"; const Navbar = () => { @@ -18,7 +18,11 @@ const Navbar = () => { }`} id="nav-items" > -