Skip to content

[FEATURE]: Menu Item Customization Feature - #1159

Open
PrishaJain64 wants to merge 3 commits into
anushkasark08:mainfrom
PrishaJain64:feat/customize
Open

[FEATURE]: Menu Item Customization Feature#1159
PrishaJain64 wants to merge 3 commits into
anushkasark08:mainfrom
PrishaJain64:feat/customize

Conversation

@PrishaJain64

Copy link
Copy Markdown
Contributor

📌 Summary

Toppings/add-ons selection — Each menu item can define a list of toppings. Customers pick one or more via checkboxes. If an item sets allowMultipleToppings: false, it switches to radio buttons so only one can be picked (e.g. "Sweet" vs "Salted" lime soda).

Variant selection — A separate list (e.g. size, portion, flavor) shown as radio buttons — only one variant can be active at a time. Variants can raise or lower the price (e.g. "Half" biryani is cheaper than "Full").

Per-option price display — Every topping and variant shows its exact price impact right next to its name (e.g. "Extra Cheese (+₹40)"), so the customer always knows the cost before selecting.

Dynamic live price calculation — The displayed total recalculates instantly on every click — no submit button needed to see the new price. It's just base price + sum of selected toppings + variant modifier, all multiplied by quantity.

Quantity selector with live total — Simple +/− stepper (minimum 1) that multiplies into the final price shown on the Add to Cart button itself.

"Sold Out" handling — If a dish's isAvailable flag is false, the Add to Cart button disables and its label changes to "Currently Sold Out" — prevents adding something the kitchen can't make.

Add to Cart button (always visible) — Originally it only appeared when an item had customizations; fixed so every item gets the button, whether or not it has toppings/variants to choose.

"Added ✓" confirmation — After clicking Add to Cart, the button briefly shows "Added ✓" and disables, then the modal auto-closes — gives the customer clear feedback the action worked before it disappears.

Session-based cart (Context API) — Cart state lives in React memory via CartContext, not the database. It resets on page refresh — a deliberate choice since your app doesn't have an order/checkout flow yet, just reservations.

Cart drawer — A slide-out panel (like a typical e-commerce cart) listing every item added: thumbnail, name, chosen variant, chosen toppings, and price.

Per-item quantity edit / remove — Inside the drawer, each line item has its own +/− stepper and an × to remove it entirely, independent from the other items.

Clear cart button — Wipes all items at once, useful for restarting an order.

Cart total calculation — Sums unitPrice × quantity across all cart entries, shown at the bottom of the drawer.

Cart icon with badge in navbar — A 🛒 icon sits in the nav bar (visible whether logged in or not) with a small red-gold badge showing the total item count, so customers see at a glance whether they have things in their cart.

Portal-rendered drawer — The drawer is injected directly into document.body via createPortal rather than rendered inside the navbar's DOM tree. This was a bug fix: the navbar's glassmorphism effect uses backdrop-filter, which silently creates a new CSS containing block , so a normal position: fixed drawer nested inside it gets visually trapped to the navbar's box instead of covering the full screen.

Backend schema support — Added a customizations field to the MenuItem Mongoose model holding toppings[], variants[], and the allowMultipleToppings flag, so this data is stored per-dish in MongoDB rather than hardcoded in the frontend.


🎯 Related Issue

Closes #1131


🛠️ Type of Change

  • New Feature
  • UI / UX Improvement

📋 What Changed?

Backend

  • MenuItem.js: added customizations schema field
    • toppings[]{ name, price }
    • variants[]{ name, priceModifier } (supports negative values, e.g. Half vs Full portion)
    • allowMultipleToppings: Boolean — toggles checkbox vs radio behavior for toppings
  • seed.js: added sample customizations data to 5 items (Masala Dosa, Butter Chicken, Hyderabadi Biryani, Gulab Jamun, Fresh Lime Soda) covering multi-select, single-select, and positive/negative price modifiers

Frontend — New

  • context/CartContext.jsx: session-only cart state (cartItems, addToCart, removeFromCart, updateQuantity, clearCart, derived cartCount/cartTotal)
  • components/CartDrawer.jsx: slide-in cart panel with item list, per-item quantity controls, remove, clear cart, and total
    • Rendered via createPortal(..., document.body) to escape the navbar's backdrop-filter stacking context (fixes drawer clipping to header bounds instead of covering the viewport)

Frontend — Modified

  • components/MenuCard.jsx
    • Added customization panel to the existing dish detail modal (toppings checkboxes/radios, variant radios, quantity stepper)
    • Live price calculation: unitPrice = basePrice + toppingsTotal + variantModifier, finalPrice = unitPrice * quantity
    • handleAddToCart pushes selected options into CartContext
    • Add to Cart button always renders (previously only showed when customizations existed)
    • Button disables with "Currently Sold Out" when item.isAvailable is false
    • Brief "Added ✓" confirmation state before auto-closing modal
  • components/Navbar.jsx
    • Added cart icon with live item-count badge
    • Wired up CartDrawer open/close state
  • App.jsx
    • Wrapped app in CartProvider alongside existing AuthProvider/MenuProvider

🧪 Testing

  • Traced the price calculation logic (unitPrice = basePrice + toppingsTotal + variantModifier) manually against sample data to confirm it produces correct sums for both positive and negative modifiers

  • Reviewed MenuCard.jsx state resets on modal reopen to confirm stale topping/variant selections wouldn't leak between different dishes

  • Reviewed the hasCustomizations conditional to confirm the Add to Cart button and panel now render for all items after the fix

  • Tested locally

  • Tested on Chrome

  • Tested responsive layouts

  • Verified no console errors

  • Existing functionality still works


📸 Screenshots

Screenshot 2026-08-03 235857 Screenshot 2026-08-03 235910

♿ Accessibility

If applicable:

  • Semantic HTML maintained
  • Keyboard navigation tested
  • Images include alt text
  • Color contrast remains accessible

✅ Checklist

  • I have read the project's CONTRIBUTING.md.
  • My branch follows the naming convention.
  • My commit messages follow the recommended format.
  • I have tested my changes.
  • I have linked the related issue.
  • This PR is focused on a single change.

@netlify

netlify Bot commented Aug 3, 2026

Copy link
Copy Markdown

Deploy Preview for theelighthouse ready!

Name Link
🔨 Latest commit 2e7ddab
🔍 Latest deploy log https://app.netlify.com/projects/theelighthouse/deploys/6a70e69ca259fd0008607e8e
😎 Deploy Preview https://deploy-preview-1159--theelighthouse.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@PrishaJain64

Copy link
Copy Markdown
Contributor Author

hi @anushkasark08 , please review the pull request and let me know if any changes are to be made

@anushkasark08

Copy link
Copy Markdown
Owner

@PrishaJain64resolve merge conflicts!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: Menu Item Customization Feature

2 participants