created new page for menu item and updated new route for menu item
This commit is contained in:
parent
79548f963c
commit
50ba58e900
6 changed files with 119 additions and 57 deletions
8
donutshop_ecommerce/package-lock.json
generated
8
donutshop_ecommerce/package-lock.json
generated
|
@ -19,7 +19,7 @@
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-hot-toast": "^2.4.1",
|
"react-hot-toast": "^2.4.1",
|
||||||
"react-icons": "^5.2.0",
|
"react-icons": "^5.2.1",
|
||||||
"react-scroll-parallax": "^3.4.5",
|
"react-scroll-parallax": "^3.4.5",
|
||||||
"react-slick": "^0.30.2",
|
"react-slick": "^0.30.2",
|
||||||
"slick-carousel": "^1.8.1",
|
"slick-carousel": "^1.8.1",
|
||||||
|
@ -6667,9 +6667,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-icons": {
|
"node_modules/react-icons": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz",
|
||||||
"integrity": "sha512-n52Y7Eb4MgQZHsSZOhSXv1zs2668/hBYKfSRIvKh42yExjyhZu0d1IK2CLLZ3BZB1oo13lDfwx2vOh2z9FTV6Q==",
|
"integrity": "sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "*"
|
"react": "*"
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-hot-toast": "^2.4.1",
|
"react-hot-toast": "^2.4.1",
|
||||||
"react-icons": "^5.2.0",
|
"react-icons": "^5.2.1",
|
||||||
"react-scroll-parallax": "^3.4.5",
|
"react-scroll-parallax": "^3.4.5",
|
||||||
"react-slick": "^0.30.2",
|
"react-slick": "^0.30.2",
|
||||||
"slick-carousel": "^1.8.1",
|
"slick-carousel": "^1.8.1",
|
||||||
|
|
|
@ -7,4 +7,11 @@ export async function POST(req){
|
||||||
const menuItemDoc = await MenuItem.create(data);
|
const menuItemDoc = await MenuItem.create(data);
|
||||||
|
|
||||||
return Response.json(menuItemDoc)
|
return Response.json(menuItemDoc)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GET(){
|
||||||
|
mongoose.connect(process.env.MONGO_URL)
|
||||||
|
return Response.json(
|
||||||
|
await MenuItem.find()
|
||||||
|
)
|
||||||
}
|
}
|
83
donutshop_ecommerce/src/app/menu-items/new/page.js
Normal file
83
donutshop_ecommerce/src/app/menu-items/new/page.js
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
"use client"
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import UserTab from '../../../components/layout/UserTab'
|
||||||
|
import EditImage from '../../../components/layout/EditImage'
|
||||||
|
import toast from 'react-hot-toast'
|
||||||
|
import useProfile from '../../../components/UseProfile'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { redirect } from 'next/navigation'
|
||||||
|
|
||||||
|
const NewMenuItemPage = () => {
|
||||||
|
const {loading, data} = useProfile();
|
||||||
|
const [menuImg, setMenuImg] = useState('');
|
||||||
|
const [itemName, setItemName] = useState('');
|
||||||
|
const [description, setDescription] = useState('');
|
||||||
|
const [basePrice, setBasePrice] = useState('');
|
||||||
|
const [goToItems, setGoToItems] = useState(false)
|
||||||
|
|
||||||
|
async function handleMenuFormSubmit(ev){
|
||||||
|
ev.preventDefault();
|
||||||
|
const data = {menuImg, itemName, description, basePrice,};
|
||||||
|
const menuSavingPromise = new Promise(async (resolve, reject) => {
|
||||||
|
const response = await fetch('/api/menu-items', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
headers: {'Content-Type': 'application/json'}
|
||||||
|
});
|
||||||
|
if(response.ok)
|
||||||
|
resolve();
|
||||||
|
else
|
||||||
|
reject();
|
||||||
|
});
|
||||||
|
await toast.promise(menuSavingPromise, {
|
||||||
|
loading: 'Saving...',
|
||||||
|
success: 'Menu is saved',
|
||||||
|
error: 'Fail to save menu!',
|
||||||
|
});
|
||||||
|
|
||||||
|
setGoToItems(true)
|
||||||
|
}
|
||||||
|
if(goToItems){
|
||||||
|
return redirect('/menu-items')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(loading){
|
||||||
|
return <p className='flex justify-center items-center'>Loading...</p>
|
||||||
|
}
|
||||||
|
if(!data.admin){
|
||||||
|
return <p className='flex justify-center items-center'>Please login as an admin</p>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='px-5 mb-10'>
|
||||||
|
<UserTab isAdmin={true}/>
|
||||||
|
<div className='max-w-md mx-auto mt-10'>
|
||||||
|
<form className='mt-10' onSubmit={handleMenuFormSubmit}>
|
||||||
|
<div className='flex flex-col gap-2 justify-center items-center max-w-[100px] mx-auto mb-5'>
|
||||||
|
<EditImage link={menuImg} setLink={setMenuImg}/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className='-mb-1 text-gray-700 font-semibold text-sm flex'>Item name</label>
|
||||||
|
<input type='text' placeholder='Enter items name' value={itemName} onChange={ev => setItemName(ev.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className='-mb-1 text-gray-700 font-semibold text-sm flex'>Description</label>
|
||||||
|
<input type='text' placeholder='Enter discription' value={description} onChange={ev => setDescription(ev.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className='-mb-1 text-gray-700 font-semibold text-sm flex'>Price</label>
|
||||||
|
<input type='text' placeholder='Enter base price' value={basePrice} onChange={ev => setBasePrice(ev.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<button type='submit' className='w-full bg-pink-500 text-white p-2 rounded-md hover:opacity-80 duration-300'>Save</button>
|
||||||
|
</form>
|
||||||
|
<div className='max-w-md mx-auto mt-2'>
|
||||||
|
<Link href={'/menu-items'} className='w-full p-2 flex justify-center items-center my-2 rounded-md outline-none border border-pink-500 hover:opacity-60 duration-300'>Show all menu items</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NewMenuItemPage
|
|
@ -1,40 +1,21 @@
|
||||||
"use client"
|
"use client"
|
||||||
import React, { useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import UserTab from '../../components/layout/UserTab'
|
import { IoMdAddCircle } from "react-icons/io";
|
||||||
import useProfile from '../../components/UseProfile'
|
import useProfile from '../../components/UseProfile'
|
||||||
import EditImage from '../../components/layout/EditImage'
|
import UserTab from '../../components/layout/UserTab';
|
||||||
import toast from 'react-hot-toast'
|
import Link from 'next/link';
|
||||||
|
|
||||||
const MenuItemsPage = () => {
|
const MenuItemsPage = () => {
|
||||||
const {loading, data} = useProfile();
|
const {loading, data} = useProfile();
|
||||||
const [menuImg, setMenuImg] = useState('');
|
const [menuItems, setMenuItems] = useState([]);
|
||||||
const [itemName, setItemName] = useState('');
|
|
||||||
const [description, setDescription] = useState('');
|
useEffect(() => {
|
||||||
const [basePrice, setBasePrice] = useState('');
|
fetch('/api/menu-items').then(res => {
|
||||||
|
res.json().then(menuItems => {
|
||||||
|
setMenuItems(menuItems);
|
||||||
|
})
|
||||||
async function handleMenuFormSubmit(ev){
|
})
|
||||||
ev.preventDefault();
|
}, [])
|
||||||
const data = {menuImg, itemName, description, basePrice,};
|
|
||||||
const menuSavingPromise = new Promise(async (resolve, reject) => {
|
|
||||||
const response = await fetch('/api/menu-items', {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
headers: {'Content-Type': 'application/json'}
|
|
||||||
});
|
|
||||||
if(response.ok)
|
|
||||||
resolve();
|
|
||||||
else
|
|
||||||
reject();
|
|
||||||
});
|
|
||||||
await toast.promise(menuSavingPromise, {
|
|
||||||
loading: 'Saving...',
|
|
||||||
success: 'Menu is saved',
|
|
||||||
error: 'Fail to save menu!',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(loading){
|
if(loading){
|
||||||
return <p className='flex justify-center items-center'>Loading...</p>
|
return <p className='flex justify-center items-center'>Loading...</p>
|
||||||
|
@ -48,25 +29,16 @@ const MenuItemsPage = () => {
|
||||||
<div className='px-5 mb-10'>
|
<div className='px-5 mb-10'>
|
||||||
<UserTab isAdmin={true}/>
|
<UserTab isAdmin={true}/>
|
||||||
<div className='max-w-md mx-auto mt-10'>
|
<div className='max-w-md mx-auto mt-10'>
|
||||||
<form className='mt-10' onSubmit={handleMenuFormSubmit}>
|
<Link href={'/menu-items/new'} className='w-full border p-2 flex justify-between items-center my-2 rounded-md outline-none border-[#DCA0AE]'>Create new menu item
|
||||||
<div className='flex flex-col gap-2 justify-center items-center max-w-[100px] mx-auto mb-5'>
|
<IoMdAddCircle className='text-lg text-pink-500'/>
|
||||||
<EditImage link={menuImg} setLink={setMenuImg}/>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className='max-w-md mx-auto'>
|
||||||
<label className='-mb-1 text-gray-700 font-semibold text-sm flex'>Item name</label>
|
<p className='mt-10 text-sm text-gray-700 -mb-2 font-semibold'>Edit menu items</p>
|
||||||
<input type='text' placeholder='Enter items name' value={itemName} onChange={ev => setItemName(ev.target.value)}/>
|
{menuItems?.length > 0 && menuItems.map(item => (
|
||||||
</div>
|
<button className='w-full p-2 flex justify-center items-center my-2 rounded-md outline-none border border-pink-500 hover:opacity-60 duration-300'>{item.itemName}</button>
|
||||||
<div>
|
))}
|
||||||
<label className='-mb-1 text-gray-700 font-semibold text-sm flex'>Description</label>
|
</div>
|
||||||
<input type='text' placeholder='Enter discription' value={description} onChange={ev => setDescription(ev.target.value)}/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label className='-mb-1 text-gray-700 font-semibold text-sm flex'>Price</label>
|
|
||||||
<input type='text' placeholder='Enter base price' value={basePrice} onChange={ev => setBasePrice(ev.target.value)}/>
|
|
||||||
</div>
|
|
||||||
<button type='submit' className='w-full bg-pink-500 text-white p-2 rounded-md hover:opacity-80 duration-300'>Save</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ const UserTab = ({isAdmin}) => {
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
<>
|
<>
|
||||||
<Link href='/categories' className={path === '/categories' ? 'active' : ''}>Categories</Link>
|
<Link href='/categories' className={path === '/categories' ? 'active' : ''}>Categories</Link>
|
||||||
<Link href='/menu-items' className={path === '/menu-items' ? 'active' : ''}>Items</Link>
|
<Link href='/menu-items' className={path.includes('menu-items') ? 'active' : ''}>Items</Link>
|
||||||
<Link href='/users' className={path === '/users' ? 'active' : ''}>Users</Link>
|
<Link href='/users' className={path === '/users' ? 'active' : ''}>Users</Link>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
Loading…
Add table
Reference in a new issue