React Food Ordering App الجزء الثاني

منذ 3 أشهر imadbelasri Reactjs
RS

فهاد الحزء الثاني من 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;