Skip to content

Commit

Permalink
Next-Project
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeWithMian committed Jan 23, 2024
1 parent b4a3c2e commit f1af066
Show file tree
Hide file tree
Showing 15 changed files with 477 additions and 12 deletions.
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
67 changes: 67 additions & 0 deletions src/app/api/register/route.js
Original file line number Diff line number Diff line change
@@ -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",
});
}
}
13 changes: 13 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

2 changes: 1 addition & 1 deletion src/app/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function RootLayout({ children }) {
<body className={inter.className}>
<GlobalState>
<Navbar/>
<main>{children}</main>
<main className=" flex min-h-screen flex-col mt-[85px]">{children}</main>
</GlobalState>
</body>
</html>
Expand Down
55 changes: 55 additions & 0 deletions src/app/login/page.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="bg-white relative">
<div className="flex flex-col items-center justify-between pt-0 pr-10 pb-0 pl-10 mt-8 mr-auto xl:px-5 lg:flex-row">
<div className="flex flex-col justify-center items-center w-full pr-10 pl-10 lg:flex-row">
<div className="w-full mt-10 mr-0 mb-0 ml-0 relative max-w-2xl lg:mt-0 lg:w-5/12">
<div className="flex flex-col items-center justify-start pt-10 pr-10 pb-10 pl-10 bg-white shadow-2xl rounded-xl relative z-10">
<p className="w-full text-4xl font-medium text-center font-serif">
Login
</p>
<div className="w-full mt-6 mr-0 mb-0 ml-0 relative space-y-8">
{loginFormControls.map((controlItem) =>
controlItem.componentType === "input" ? (
<InputComponent
type={controlItem.type}
placeholder={controlItem.placeholder}
label={controlItem.label}
/>
) : null
)}
<button
className="inline-flex w-full items-center justify-center bg-black px-6 py-4 text-lg
text-white transition-all duration-200 ease-in-out focus:shadow font-medium uppercase tracking-wide
"
>
Login
</button>
<div className="flex flex-col gap-2">
<p>New to Website ?</p>
<button
className="inline-flex w-full items-center justify-center bg-black px-6 py-4 text-lg
text-white transition-all duration-200 ease-in-out focus:shadow font-medium uppercase tracking-wide
"
onClick={() => router.push("/register")}
>
Register
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
};

export default Login;
103 changes: 103 additions & 0 deletions src/app/register/page.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="bg-white relative">
<div className="flex flex-col items-center justify-between pt-0 pr-10 pb-0 pl-10 mt-8 mr-auto xl:px-5 lg:flex-row">
<div className="flex flex-col justify-center items-center w-full pr-10 pl-10 lg:flex-row">
<div className="w-full mt-10 mr-0 mb-0 ml-0 relative max-w-2xl lg:mt-0 lg:w-5/12">
<div className="flex flex-col items-center justify-start pt-10 pr-10 pb-10 pl-10 bg-white shadow-2xl rounded-xl relative z-10">
<p className="w-full text-4xl font-medium text-center font-serif">
{isRegistered
? "Registration Successfull !"
: "Sign up for an account"}
</p>
{isRegistered ? (
<button
className="inline-flex w-full items-center justify-center bg-black px-6 py-4 text-lg
text-white transition-all duration-200 ease-in-out focus:shadow font-medium uppercase tracking-wide
"
>
Login
</button>
) : (
<div className="w-full mt-6 mr-0 mb-0 ml-0 relative space-y-8">
{registrationFormControls.map((controlItem) =>
controlItem.componentType === "input" ? (
<InputComponent
type={controlItem.type}
placeholder={controlItem.placeholder}
label={controlItem.label}
onChange={(event) => {
setFormData({
...formData,
[controlItem.id]: event.target.value,
});
}}
value={formData[controlItem.id]}
/>
) : controlItem.componentType === "select" ? (
<SelectComponent
options={controlItem.options}
label={controlItem.label}
onChange={(event) => {
setFormData({
...formData,
[controlItem.id]: event.target.value,
});
}}
value={formData[controlItem.id]}
/>
) : null
)}
<button
className="disabled:opacity-50 inline-flex w-full items-center justify-center bg-black px-6 py-4 text-lg
text-white transition-all duration-200 ease-in-out focus:shadow font-medium uppercase tracking-wide
"
disabled={!isFormValid()}
onClick={handleRegisterOnSubmit}
>
Register
</button>
</div>
)}
</div>
</div>
</div>
</div>
</div>
);
};

export default Register;
20 changes: 20 additions & 0 deletions src/components/FormElements/InputComponent/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from "react";

const InputComponent = ({ label, placeholder, type, value, onChange }) => {
return (
<div className="relative">
<p className="bg-white absolute pt-0 pr-2 pb-0 pl-2 -mt-3 mr-0 mb-0 ml-2 font-medium text-gray-600">
{label}
</p>
<input
placeholder={placeholder}
type={type || "text"}
value={value}
onChange={onChange}
className="border placeholder-gray-400 focus:outline-none focus:border-black w-full pt-4 pr-4 pb-4 pl-4 mr-0 mt-0 ml-0 text-base bloack bg-white border-gray-300 rounded-md"
/>
</div>
);
};

export default InputComponent;
36 changes: 36 additions & 0 deletions src/components/FormElements/SelectComponent/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";

const SelectComponent = ({ label, value, onChange, options = [] }) => {
return (
<div>
<div className="relative">
<p className="pt-0 pr-2 absolute pb-0 pl-2 -mt-3 mr-0 mb-0 ml-2 font-medium text-gray-600 bg-white">
{label}
</p>
<select
value={value}
onChange={onChange}
className="border placeholder-gray-400 focus:outline-none focus:border-black w-full pt-4 pr-4 pb-4 pl-4 mr-0 mt-0 ml-0 text-base block bg-white border-gray-300 rounded-md"
>
{options && options.length ? (
options.map((optionItem) => (
<option
id={optionItem.id}
value={optionItem.id}
key={optionItem.id}
>
{optionItem.label}
</option>
))
) : (
<option id="" value={""}>
Select
</option>
)}
</select>
</div>
</div>
);
};

export default SelectComponent;
17 changes: 17 additions & 0 deletions src/components/Loader/componentlevel/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use client";

import { PulseLoader } from "react-spinners";

export default function ComponentLevelLoader({ text, color, loading, size }) {
return (
<span className="flex gap-1 items-center">
{text}
<PulseLoader
color={color}
loading={loading}
size={size || 10}
data-testid="loader"
/>
</span>
);
}
Loading

0 comments on commit f1af066

Please sign in to comment.