React Food Ordering App الجزء الثاني
فهاد الحزء الثاني من React Food Ordering App غادي نزيدوا ل panier ديالنا وغادي نشوفوا كيفاش نعرضوا الاكلات على حساب الصنف أي ل catégorie.
نظرة سريعة بالفيديو
1- إضافة ل FoodItem Component
فنفس dossier components زيد fichier FoodItem.js لي هو ل component لي غادي يعرض كل منتج أو أكلة.
غادي يكون فيه الكود التالي :
//
import React, { useContext } from 'react';
import { ShoppingContext } from "./context/ShoppingContext";
export default function FoodItem ({food}) {
const { addToCart } = useContext(ShoppingContext);
return (
<div className="col-md-4 mb-2">
<div className="card" style={{width: '18rem'}}>
<img src={food.food_image} height="200" className="card-img-top" alt={food.food_name} />
<div className="card-body">
<h5 className="card-title">{food.food_name}</h5>
<p className="card-text">{food.food_price}$</p>
<div className="accordion" id="accordionExample">
<div className="accordion-item">
<h2 className="accordion-header" id="headingOne">
<button className="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target={`#food-${food.id}`} aria-expanded="true" aria-controls="collapseOne">
<i className="bi bi-eye"></i>
</button>
</h2>
<div id={`food-${food.id}`} className="accordion-collapse collapse" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
<div className="accordion-body">
<div className="lead">
{food.food_desc}
</div>
<button
onClick={() => addToCart(food)}
className="btn btn-danger mt-2">
<i className="bi bi-cart"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
2- إضافة Cart Component
فنفس dossier components زيد fichier Cart.js لي فيه غادي تكون ل panier ديالنا ولي فيها غادي نشوف الأكلات لي زدت, نعدل على الكمية لي بغيت أو نحذفهم من ل panier.
غادي يكون فيه الكود التالي :
//
import React, { useContext } from "react";
import { ShoppingContext } from "./context/ShoppingContext";
export default function Cart() {
const { cartItems, incrementQ, decrementQ, removeFromCart } =
useContext(ShoppingContext);
return (
<div className="row my-4">
<div className="col-md-12">
<div className="card">
<div className="card-body">
<table className="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Image</th>
<th scope="col">Name</th>
<th scope="col">Quantity</th>
<th scope="col">Price</th>
<th scope="col">Subtotal</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{cartItems.map((item) => (
<tr key={item.id}>
<th scope="row">{item.id}</th>
<td>
<img
src={item.food_image}
alt={item.food_name}
className="img-fluid rounded"
width={60}
height={60}
/>
</td>
<td>{item.food_name}</td>
<td>
<i
className="bi bi-caret-up"
style={{ cursor: "pointer" }}
onClick={() => incrementQ(item)}
></i>
<span className="mx-2">{item.quantity}</span>
<i
className="bi bi-caret-down"
style={{ cursor: "pointer" }}
onClick={() => decrementQ(item)}
></i>
</td>
<td>${item.food_price}</td>
<td>${item.food_price * item.quantity}</td>
<td>
<i
className="bi bi-cart-x text-danger"
style={{ cursor: "pointer" }}
onClick={() => removeFromCart(item)}
></i>
</td>
</tr>
))}
<tr>
<th colSpan={3} className="text-center">
Total
</th>
<th colSpan={3} className="text-center">
<span className="badge bg-danger rounded-pill">
$
{cartItems.reduce(
(acc, item) => (acc += item.food_price * item.quantity),
0
)}
</span>
</th>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
);
}
3- إضافة ShoppingContext
من بعد فنفس dossier components زيد dossier context فيه زيد fichier ShoppingContext.js لي فيه هاد الكود :
//
import { createContext } from "react";
export const ShoppingContext = createContext();
4- تعديل App.js
من بعد غادي تدير تعديلات على ل fichier App.js ودير ل commande :
npm start
باش ت tester ل app .
الكود ديال الملف هو :
//
import Home from "./components/Home";
import Navbar from "./components/Navbar";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import React, { useState } from 'react';
import {ShoppingContext} from './components/context/ShoppingContext';
import { foods, categories } from './data/food.js'
import Swal from 'sweetalert2';
import Cart from "./components/Cart";
function App() {
const [cartItems,setCartItems] = useState([]);
const addToCart = (item) => {
let productItem = cartItems.find(product => product.id === item.id);
if(productItem){
productItem.quantity += 1;
setCartItems([...cartItems]);
Swal.fire({
position: 'top-end',
icon: 'success',
title: 'Your item has been updated',
showConfirmButton: false,
timer: 1500
});
}else{
item.quantity = 1;
setCartItems([item,...cartItems]);
Swal.fire({
position: 'top-end',
icon: 'success',
title: 'Your item has been saved',
showConfirmButton: false,
timer: 1500
});
}
}
const incrementQ = (item) => {
let productItem = cartItems.find(product => product.id === item.id);
if(productItem){
productItem.quantity += 1;
setCartItems([...cartItems]);
Swal.fire({
position: 'top-end',
icon: 'success',
title: 'Your item has been updated',
showConfirmButton: false,
timer: 1500
});
}
}
const decrementQ = (item) => {
let productItem = cartItems.find(product => product.id === item.id);
if(productItem){
productItem.quantity -= 1;
if(productItem.quantity === 0){
setCartItems(cartItems.filter(product => product.id !== item.id));
}else{
setCartItems([...cartItems]);
}
Swal.fire({
position: 'top-end',
icon: 'success',
title: 'Your item has been updated',
showConfirmButton: false,
timer: 1500
});
}
}
const removeFromCart = (item) => {
setCartItems(cartItems.filter(product => product.id !== item.id));
Swal.fire({
position: 'top-end',
icon: 'success',
title: 'Your item has been removed',
showConfirmButton: false,
timer: 1500
});
}
return (
<ShoppingContext.Provider value={
{
foods, categories, addToCart, incrementQ,
decrementQ, cartItems, removeFromCart
}
}
>
<div className="container">
<BrowserRouter>
<Navbar cartItems={cartItems}/>
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="/cart" element={<Cart />} />
</Routes>
</BrowserRouter>
</div>
</ShoppingContext.Provider>
);
}
export default App;