updated AppContext for size and topping, created popup for selecting item sizes and toppings
This commit is contained in:
parent
3d11d8e696
commit
d9ee93365f
7 changed files with 55 additions and 20 deletions
|
@ -23,7 +23,11 @@ const MenuItemSchema = new Schema({
|
|||
},
|
||||
sizes:{
|
||||
type: [ExtraPriceSchema]
|
||||
}
|
||||
},
|
||||
extraItems:{
|
||||
type: [ExtraPriceSchema]
|
||||
},
|
||||
|
||||
}, {timestamps: true})
|
||||
|
||||
export const MenuItem = models?.MenuItem || model('MenuItem', MenuItemSchema)
|
|
@ -19,11 +19,11 @@ const MenuPage = () => {
|
|||
|
||||
|
||||
return (
|
||||
<div className='w-full h-full pb-20 md:pb-40'>
|
||||
<div className='pb-20 md:pb-40'>
|
||||
{categories?.length > 0 && categories.map(c => (
|
||||
<div className='px-5 lg:px-10 py-5 sm:py-10'>
|
||||
<p className='text-center text-3xl md:text-4xl text-pink-500 uppercase font-bold drop-shadow-[0_2px_2px_rgba(105,105,105,1)]'>{c.name}</p>
|
||||
<div className='grid grid-cols-1 min-[480px]:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-5 mt-10'>
|
||||
<div className='px-10 min-[380px]:px-5 lg:px-10 py-5 sm:py-10'>
|
||||
<p className='text-center text-2xl sm:text-3xl md:text-4xl text-pink-500 uppercase font-bold drop-shadow-[0_2px_2px_rgba(105,105,105,1)]'>{c.name}</p>
|
||||
<div className='grid grid-cols-1 min-[380px]:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 min-[380px]:gap-5 mt-5 sm:mt-10'>
|
||||
{menuItems.filter(item => item.category === c._id).map(item => (
|
||||
<Menu {...item}/>
|
||||
))}
|
||||
|
|
|
@ -37,9 +37,9 @@ const AppProvider = ({children}) => {
|
|||
}
|
||||
}
|
||||
|
||||
function addToCart(product, size=null){
|
||||
function addToCart(product, size=null, extra=[]){
|
||||
setCartProducts(prevProducts => {
|
||||
const cartProduct = {...product, size}
|
||||
const cartProduct = {...product, size, extra}
|
||||
const newProducts = [...prevProducts, cartProduct];
|
||||
saveCartProductsToLocalStorage(newProducts);
|
||||
return newProducts
|
||||
|
|
|
@ -9,6 +9,7 @@ const MenuItemForm = ({handleMenuFormSubmit, menuItem}) => {
|
|||
const [description, setDescription] = useState(menuItem?.description || '');
|
||||
const [basePrice, setBasePrice] = useState(menuItem?.basePrice || '');
|
||||
const [sizes, setSizes] = useState(menuItem?.sizes || []);
|
||||
const [extraItems, setExtraItems] = useState(menuItem?.extraItems || []);
|
||||
const [category, setCategory] = useState(menuItem?.category || '');
|
||||
const [categories, setCategories] = useState([]);
|
||||
|
||||
|
@ -23,7 +24,7 @@ const MenuItemForm = ({handleMenuFormSubmit, menuItem}) => {
|
|||
|
||||
|
||||
return (
|
||||
<form className='mt-10' onSubmit={ev => handleMenuFormSubmit(ev, {menuImg, itemName, description, basePrice, sizes, category,})}>
|
||||
<form className='mt-10' onSubmit={ev => handleMenuFormSubmit(ev, {menuImg, itemName, description, basePrice, sizes, extraItems, category,})}>
|
||||
<div className='flex flex-col gap-2 justify-center items-center max-w-[100px] mx-auto mb-5'>
|
||||
<EditImage link={menuImg} setLink={setMenuImg}/>
|
||||
</div>
|
||||
|
@ -47,7 +48,8 @@ const MenuItemForm = ({handleMenuFormSubmit, menuItem}) => {
|
|||
<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>
|
||||
<MenuItemProps props={sizes} setProps={setSizes}/>
|
||||
<MenuItemProps name={'Sizes'} props={sizes} setProps={setSizes} addLabel={'Add sizes'}/>
|
||||
<MenuItemProps name={'Toppings'} props={extraItems} setProps={setExtraItems} addLabel={'Add toppings'}/>
|
||||
<button type='submit' className='w-full bg-pink-500 text-white p-2 rounded-md hover:opacity-80 duration-300'>Save</button>
|
||||
</form>
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { useState } from 'react'
|
|||
import { IoTrashOutline } from "react-icons/io5";
|
||||
import { MdKeyboardArrowDown, MdKeyboardArrowUp } from "react-icons/md";
|
||||
|
||||
const MenuItemProps = ({props, setProps}) => {
|
||||
const MenuItemProps = ({name, addLabel, props, setProps}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
function addProp(){
|
||||
|
@ -29,7 +29,7 @@ const MenuItemProps = ({props, setProps}) => {
|
|||
<div>
|
||||
<div className='border p-2 block my-2 w-full rounded-md outline-none border-[#DCA0AE]'>
|
||||
<button onClick={() => setIsOpen(prev => !prev)} type='button' className='w-full flex justify-between items-center text-[#DCA0AE] '>
|
||||
<label className='mb-2 text-gray-700 font-semibold text-sm flex'>Box of donuts ({props.length})</label>
|
||||
<label className='mb-2 text-gray-700 font-semibold text-sm flex'>{name}({props.length})</label>
|
||||
{isOpen && (
|
||||
<MdKeyboardArrowUp/>
|
||||
)}
|
||||
|
@ -41,8 +41,8 @@ const MenuItemProps = ({props, setProps}) => {
|
|||
{props?.length > 0 && props.map((size, index) => (
|
||||
<div className='flex gap-2 items-center'>
|
||||
<div>
|
||||
<label className='-mb-1 text-gray-700 text-sm flex'>Donuts</label>
|
||||
<input type='text' placeholder='Donuts' value={size.itemName} onChange={ev => editProp(ev, index, 'itemName')}/>
|
||||
<label className='-mb-1 text-gray-700 text-sm flex'>Name</label>
|
||||
<input type='text' placeholder='Size name' value={size.itemName} onChange={ev => editProp(ev, index, 'itemName')}/>
|
||||
</div>
|
||||
<div>
|
||||
<label className='-mb-1 text-gray-700 text-sm flex'>Price</label>
|
||||
|
@ -53,7 +53,7 @@ const MenuItemProps = ({props, setProps}) => {
|
|||
</div>
|
||||
</div>
|
||||
))}
|
||||
<button type='button' onClick={addProp} className='bg-gray-200 w-full p-2 rounded-md hover:opacity-80'>Add donuts</button>
|
||||
<button type='button' onClick={addProp} className='bg-gray-200 w-full p-2 rounded-md hover:opacity-80'>{addLabel}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,12 +4,12 @@ import { CartContext } from '../AppContext';
|
|||
import toast from 'react-hot-toast';
|
||||
|
||||
const Menu = (menuItem) => {
|
||||
const {menuImg, itemName, description, basePrice, sizes} = menuItem
|
||||
const {menuImg, itemName, description, basePrice, sizes, extraItems} = menuItem
|
||||
const {addToCart} = useContext(CartContext);
|
||||
const [showPopup, setShowPopup] = useState(false);
|
||||
|
||||
function handleAddToCartButtonClick(){
|
||||
if(sizes.length === 0 ){
|
||||
if(sizes.length === 0 && extraItems.length === 0){
|
||||
toast.success('Add to cart');
|
||||
addToCart(menuItem);
|
||||
} else{
|
||||
|
@ -17,16 +17,45 @@ const Menu = (menuItem) => {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{showPopup && (
|
||||
<div className='fixed inset-0 bg-black/80 block sm:flex justify-center items-center'>
|
||||
<div className='bg-white p-5 rounded-md'>test</div>
|
||||
<div className='fixed inset-0 bg-black/80 flex justify-center items-center'>
|
||||
<div className='bg-white p-5 rounded-md'>
|
||||
<div className='py-0 sm:py-5 flex flex-col gap-2 sm:gap-4 justify-center items-center text-center px-0 sm:px-10'>
|
||||
<Image src={menuImg} width={300} height={300} alt='menu-donut' className='w-[100px] min-[550px]:w-[120px]'/>
|
||||
<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>
|
||||
{sizes?.length > 0 && (
|
||||
<div className='w-full border-t-[1px] border-pink-500 border-dashed'>
|
||||
<p className='text-xs sm:text-sm font-semibold capitalize text-[#95743D] px-2 m-2'>Choose your size</p>
|
||||
{sizes.map(size => (
|
||||
<div className='flex justify-start text-start text-xs sm:text-sm gap-2 py-1'>
|
||||
<input type='radio' name='size'/>{size.itemName} ${basePrice + size.price}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{extraItems?.length > 0 && (
|
||||
<div className='w-full border-t-[1px] border-pink-500 border-dashed'>
|
||||
<p className='text-xs sm:text-sm font-semibold capitalize text-[#95743D] px-2 m-2'>Extra toppings</p>
|
||||
{extraItems.map(extraTopping => (
|
||||
<div className='flex justify-start text-start text-xs sm:text-sm gap-2 py-1'>
|
||||
<input type='checkbox' name={extraTopping.itemName}/>{extraTopping.itemName} (${extraTopping.price})
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<button type='button' className='bg-pink-500 text-white p-1 sm:p-2 text-sm sm:text-base rounded-md hover:opacity-80 duration-300 mt-5'>Add to cart</button>
|
||||
</div>
|
||||
</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 border border-pink-500 h-[300px] sm:h-[400px] lg:h-[450px] shadow-md hover:shadow-[#E78895] duration-300'>
|
||||
<Image src={menuImg} width={300} height={300} alt='menu-donut' className='w-[150px] sm:w-[180px] lg:w-[230px]'/>
|
||||
<Image src={menuImg} width={300} height={300} alt='menu-donut' className='w-[100px] min-[450px]:w-[150px] min-[550px]:w-[180px] lg:w-[230px]'/>
|
||||
<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 font-semibold'>${basePrice}</p>
|
||||
|
|
|
@ -27,7 +27,7 @@ const MenuItem = (menuItem) => {
|
|||
<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'>{description}</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