updated code
This commit is contained in:
parent
dc6672a96d
commit
91ae0f79a5
10 changed files with 86 additions and 48 deletions
BIN
donutshop_ecommerce/public/cross.png
Normal file
BIN
donutshop_ecommerce/public/cross.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
|
@ -1,11 +1,12 @@
|
||||||
import * as mongoose from "mongoose"
|
import * as mongoose from "mongoose"
|
||||||
import NextAuth from "next-auth"
|
import NextAuth, { getServerSession } from "next-auth"
|
||||||
import CredentialsProvider from "next-auth/providers/credentials"
|
import CredentialsProvider from "next-auth/providers/credentials"
|
||||||
import { User } from "../../models/User"
|
import { User } from "../../models/User"
|
||||||
import bcrypt from 'bcrypt'
|
import bcrypt from 'bcrypt'
|
||||||
import GoogleProvider from "next-auth/providers/google";
|
import GoogleProvider from "next-auth/providers/google";
|
||||||
import { MongoDBAdapter } from "@auth/mongodb-adapter"
|
import { MongoDBAdapter } from "@auth/mongodb-adapter"
|
||||||
import clientPromise from "../../../../libs/mongoConnect"
|
import clientPromise from "../../../../libs/mongoConnect"
|
||||||
|
import { UserInfo } from "../../models/UserInfo"
|
||||||
|
|
||||||
export const authOptions = {
|
export const authOptions = {
|
||||||
secret: process.env.SECRET,
|
secret: process.env.SECRET,
|
||||||
|
@ -37,6 +38,21 @@ export const authOptions = {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function isAdmin(){
|
||||||
|
const session = await getServerSession(authOptions);
|
||||||
|
const userEmail = session?.user?.email;
|
||||||
|
if (!userEmail) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userInfo = await UserInfo.findOne({email:userEmail});
|
||||||
|
if (!userInfo) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return userInfo.admin;
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = NextAuth(authOptions);
|
const handler = NextAuth(authOptions);
|
||||||
|
|
|
@ -1,19 +1,24 @@
|
||||||
import mongoose from "mongoose";
|
import mongoose from "mongoose";
|
||||||
import { Category } from "../models/Category";
|
import { Category } from "../models/Category";
|
||||||
|
import { isAdmin } from "../auth/[...nextauth]/route";
|
||||||
|
|
||||||
export async function POST(req){
|
export async function POST(req){
|
||||||
mongoose.connect(process.env.MONGO_URL)
|
mongoose.connect(process.env.MONGO_URL)
|
||||||
const {name} = await req.json();
|
const {name} = await req.json();
|
||||||
const categoryDoc = await Category.create({name})
|
if(await isAdmin()){
|
||||||
|
const categoryDoc = await Category.create({name})
|
||||||
return Response.json(categoryDoc);
|
return Response.json(categoryDoc);
|
||||||
|
} else {
|
||||||
|
return Response.json({})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function PUT(req){
|
export async function PUT(req){
|
||||||
mongoose.connect(process.env.MONGO_URL)
|
mongoose.connect(process.env.MONGO_URL)
|
||||||
const {_id, name} = await req.json();
|
const {_id, name} = await req.json();
|
||||||
await Category.updateOne({_id}, {name});
|
if(await isAdmin()){
|
||||||
|
await Category.updateOne({_id}, {name});
|
||||||
|
}
|
||||||
return Response.json(true);
|
return Response.json(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +33,8 @@ export async function DELETE(req){
|
||||||
mongoose.connect(process.env.MONGO_URL)
|
mongoose.connect(process.env.MONGO_URL)
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
const _id = url.searchParams.get('_id');
|
const _id = url.searchParams.get('_id');
|
||||||
await Category.deleteOne({_id})
|
if(await isAdmin()){
|
||||||
|
await Category.deleteOne({_id})
|
||||||
|
}
|
||||||
return Response.json(true)
|
return Response.json(true)
|
||||||
}
|
}
|
|
@ -1,18 +1,26 @@
|
||||||
import mongoose from "mongoose";
|
import mongoose from "mongoose";
|
||||||
import { MenuItem } from "../models/MenuItem";
|
import { MenuItem } from "../models/MenuItem";
|
||||||
|
import { isAdmin } from "../auth/[...nextauth]/route";
|
||||||
|
|
||||||
export async function POST(req){
|
export async function POST(req){
|
||||||
mongoose.connect(process.env.MONGO_URL)
|
mongoose.connect(process.env.MONGO_URL)
|
||||||
const data = await req.json();
|
const data = await req.json();
|
||||||
const menuItemDoc = await MenuItem.create(data);
|
if(await isAdmin()){
|
||||||
|
const menuItemDoc = await MenuItem.create(data);
|
||||||
return Response.json(menuItemDoc)
|
return Response.json(menuItemDoc)
|
||||||
|
} else {
|
||||||
|
return Response.json({});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function PUT(req){
|
export async function PUT(req){
|
||||||
mongoose.connect(process.env.MONGO_URL)
|
mongoose.connect(process.env.MONGO_URL)
|
||||||
const {_id, ...data} = await req.json();
|
if(await isAdmin()){
|
||||||
await MenuItem.findByIdAndUpdate(_id, data);
|
const {_id, ...data} = await req.json();
|
||||||
|
await MenuItem.findByIdAndUpdate(_id, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return Response.json(true)
|
return Response.json(true)
|
||||||
}
|
}
|
||||||
|
@ -21,14 +29,16 @@ export async function GET(){
|
||||||
mongoose.connect(process.env.MONGO_URL)
|
mongoose.connect(process.env.MONGO_URL)
|
||||||
return Response.json(
|
return Response.json(
|
||||||
await MenuItem.find()
|
await MenuItem.find()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function DELETE(req){
|
export async function DELETE(req){
|
||||||
mongoose.connect(process.env.MONGO_URL)
|
mongoose.connect(process.env.MONGO_URL)
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
const _id = url.searchParams.get('_id');
|
const _id = url.searchParams.get('_id');
|
||||||
await MenuItem.deleteOne({_id})
|
if(await isAdmin()){
|
||||||
|
await MenuItem.deleteOne({_id})
|
||||||
|
}
|
||||||
|
|
||||||
return Response.json(true)
|
return Response.json(true)
|
||||||
}
|
}
|
|
@ -1,31 +1,23 @@
|
||||||
import mongoose from "mongoose";
|
import mongoose from "mongoose";
|
||||||
import { getServerSession } from "next-auth"
|
import { getServerSession } from "next-auth"
|
||||||
import { authOptions } from "../auth/[...nextauth]/route"
|
import { authOptions, isAdmin } from "../auth/[...nextauth]/route"
|
||||||
import { UserInfo } from "../models/UserInfo"
|
|
||||||
import { Order } from "../models/Order"
|
import { Order } from "../models/Order"
|
||||||
|
|
||||||
export async function GET(req){
|
export async function GET(req){
|
||||||
mongoose.connect(process.env.MONGO_URL);
|
mongoose.connect(process.env.MONGO_URL);
|
||||||
const session = await getServerSession(authOptions);
|
const session = await getServerSession(authOptions);
|
||||||
const userEmail = session?.user?.email;
|
const userEmail = session?.user?.email;
|
||||||
|
const admin = isAdmin();
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
const _id = url.searchParams.get('_id')
|
const _id = url.searchParams.get('_id')
|
||||||
if(_id){
|
if(_id){
|
||||||
return Response.json( await Order.findById(_id));
|
return Response.json( await Order.findById(_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
let isAdmin = false;
|
if(admin){
|
||||||
|
|
||||||
if(userEmail){
|
|
||||||
const userInfo = await UserInfo.findOne({email:userEmail});
|
|
||||||
if(userInfo){
|
|
||||||
const isAdmin = userInfo.admin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(isAdmin){
|
|
||||||
return Response.json( await Order.find() )
|
return Response.json( await Order.find() )
|
||||||
}
|
}
|
||||||
|
|
||||||
if(userEmail){
|
if(userEmail){
|
||||||
return Response.json( await Order.find({userEmail}) )
|
return Response.json( await Order.find({userEmail}) )
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
import mongoose from "mongoose";
|
import mongoose from "mongoose";
|
||||||
import { User } from "../models/User";
|
import { User } from "../models/User";
|
||||||
|
import { isAdmin } from "../auth/[...nextauth]/route";
|
||||||
|
|
||||||
export async function GET(){
|
export async function GET(){
|
||||||
mongoose.connect(process.env.MONGO_URL);
|
mongoose.connect(process.env.MONGO_URL);
|
||||||
const users = await User.find();
|
if(await isAdmin()) {
|
||||||
|
const users = await User.find();
|
||||||
return Response.json(users);
|
return Response.json(users);
|
||||||
|
} else {
|
||||||
|
return Response.json([]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@ import { useParams } from 'next/navigation'
|
||||||
import AddressInfo from '../../../components/layout/AddressInfo'
|
import AddressInfo from '../../../components/layout/AddressInfo'
|
||||||
|
|
||||||
const OrdersPage = () => {
|
const OrdersPage = () => {
|
||||||
const {clearCart, cartProducts} = useContext(CartContext);
|
const {clearCart} = useContext(CartContext);
|
||||||
const {id} = useParams();
|
const {id} = useParams();
|
||||||
const [order, setOrder] = useState();
|
const [order, setOrder] = useState();
|
||||||
|
|
||||||
|
@ -37,13 +37,23 @@ const OrdersPage = () => {
|
||||||
return (
|
return (
|
||||||
<div className='pb-20 md:pb-40'>
|
<div className='pb-20 md:pb-40'>
|
||||||
<div className='px-5 md:px-10 py-5 sm:py-10 max-w-xl mx-auto'>
|
<div className='px-5 md:px-10 py-5 sm:py-10 max-w-xl mx-auto'>
|
||||||
|
{order?.paid ? (
|
||||||
<div className='flex flex-col gap-4 items-center justify-center text-center mb-10'>
|
<div className='flex flex-col gap-4 items-center justify-center text-center mb-10'>
|
||||||
<Image src='/check.png' width={100} height={100} alt='checked' className='mb-5'/>
|
<Image src='/check.png' width={100} height={100} alt='checked' className='mb-5'/>
|
||||||
<p className='uppercase'>Thank you</p>
|
<p className='uppercase'>Thank you</p>
|
||||||
<p className='uppercase text-xl'>Your order is confirmed</p>
|
<p className='uppercase text-xl'>Your order is confirmed</p>
|
||||||
<button type='button' className='p-2 bg-pink-500 rounded-md text-xs text-white hover:opacity-80 uppercase'>Track your order</button>
|
<button type='button' className='p-2 bg-pink-500 rounded-md text-xs text-white hover:opacity-80 uppercase'>Track your order</button>
|
||||||
</div>
|
</div>
|
||||||
{order && (
|
) : (
|
||||||
|
<div className='flex flex-col gap-4 items-center justify-center text-center mb-10'>
|
||||||
|
<Image src='/cross.png' width={100} height={100} alt='checked' className='mb-5'/>
|
||||||
|
<p className='uppercase text-red-600'>Action needed</p>
|
||||||
|
<p className='uppercase text-xl text-red-600'>Payment is required</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
{order&& (
|
||||||
<div className='flex flex-col gap-5 py-5 px-5 border rounded-md shadow-md'>
|
<div className='flex flex-col gap-5 py-5 px-5 border rounded-md shadow-md'>
|
||||||
<div className='border-b pb-5'>
|
<div className='border-b pb-5'>
|
||||||
<p className='mb-5 text-pink-500 font-semibold text-center'>Order Summary</p>
|
<p className='mb-5 text-pink-500 font-semibold text-center'>Order Summary</p>
|
||||||
|
|
|
@ -41,7 +41,12 @@ const OrderPage = () => {
|
||||||
<div className='flex flex-col gap-2'>
|
<div className='flex flex-col gap-2'>
|
||||||
<div className='text-gray-700 font-semibold'>{order.userEmail}</div>
|
<div className='text-gray-700 font-semibold'>{order.userEmail}</div>
|
||||||
<div className='mb-2'>
|
<div className='mb-2'>
|
||||||
<Link href={'/orders/'+order._id} className='bg-gray-200 text-gray-700 p-2 text-xs font-semibold'>Order info</Link>
|
{order.paid? (
|
||||||
|
<Link href={'/orders/'+order._id} className='bg-gray-200 text-gray-700 p-2 text-xs font-semibold'>Receipt info</Link>
|
||||||
|
): (
|
||||||
|
<Link href={'/orders/'+order._id} className='bg-gray-200 text-gray-700 p-2 text-xs font-semibold'>Order info</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className='text-xs text-gray-500'>{dateTime(order.createdAt)}</div>
|
<div className='text-xs text-gray-500'>{dateTime(order.createdAt)}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,7 +14,7 @@ const HomeDrink = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch('/api/menu-items').then(res => {
|
fetch('/api/menu-items').then(res => {
|
||||||
res.json().then(menuItems => {
|
res.json().then(menuItems => {
|
||||||
setBestSeller(menuItems.slice(-5))
|
setBestSeller(menuItems.slice(5, 10))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
|
|
@ -18,20 +18,14 @@ const MenuItem = (menuItem) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className='py-1 sm:py-5 flex flex-col gap-2 sm:gap-4 justify-center items-center text-center rounded-xl bg-white h-[350px] sm:h-[450px]'>
|
||||||
{showPopup && (
|
<Image src={menuImg} width={300} height={300} alt='menu-donut' className='w-[200px] sm:w-[250px]'/>
|
||||||
<div className='fixed inset-0 bg-black/80'>
|
<p className='text-sm sm:text-base font-semibold capitalize text-[#95743D] px-2'>{itemName}</p>
|
||||||
|
<p className='text-xs sm:text-sm px-2 line-clamp-2 text-[#95743D]'>{description}</p>
|
||||||
|
<p className='text-[#95743D] text-sm'>${basePrice}</p>
|
||||||
|
<button type='button' onClick={handleAddToCartButtonClick} className='px-2 py-1 sm:px-4 sm:py-2 rounded-full text-xs sm:text-sm border border-[#E78895] text-[#95743D] font-semibold hover:bg-[#E78895] hover:text-[#FDE2DE] duration-300'>Add to cart</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className='py-1 sm:py-5 flex flex-col gap-2 sm:gap-4 justify-center items-center text-center rounded-xl bg-white h-[350px] sm:h-[450px]'>
|
|
||||||
<Image src={menuImg} width={300} height={300} alt='menu-donut' className='w-[200px] sm:w-[250px]'/>
|
|
||||||
<p className='text-sm sm:text-base font-semibold capitalize text-[#95743D] px-2'>{itemName}</p>
|
|
||||||
<p className='text-xs sm:text-sm px-2 line-clamp-2 text-[#95743D]'>{description}</p>
|
|
||||||
<p className='text-[#95743D] text-sm'>${basePrice}</p>
|
|
||||||
<button type='button' onClick={handleAddToCartButtonClick} className='px-2 py-1 sm:px-4 sm:py-2 rounded-full text-xs sm:text-sm border border-[#E78895] text-[#95743D] font-semibold hover:bg-[#E78895] hover:text-[#FDE2DE] duration-300'>Add to cart</button>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue