0

i am trying to make a bill and want to add items to the bill when i add a items multiple time i want to increment the total price also i want it to be displayed as total amount when i decrease the amount i want to decrement the pice from both

pls have a look at the codesandbox https://codesandbox.io/s/still-https-ztn52x?file=/src/dashbord.jsx

 function bill({ billItems }) {
    return (
      <>
        <div className="foo">
          <table>
            <tbody>
              <tr>
                <th>item</th> <th>price</th> <th>qty</th> <th>total_price</th>
              </tr>
              {trayItems &&
                trayItems.map((ele, index) => {
                  return (
                    <tr key={index}>
                      <td>{ele.item}</td>
                      <td>{ele.price}</td>

                      <td>{ele.quantity}</td>
                      <th>0</th>
                      <td>
                        <button onClick={() => incre(ele.user_id)}>+</button>
                        <button onClick={() => decre(ele.user_id)}>-</button>
                      </td>
                    </tr>
                  );
                })}
            </tbody>
          </table>
        </div>
      </>
    );
  }


  return (
    <>
      <div>
        {item &&
          item
            .filter((person) => person.status === 0)
            .map((ele, index) => {
              return (
                <div
                  style={{ cursor: "pointer", border: "1px solid black" }}
                  key={index}
                  className="newmo-card"
                  onClick={() => handleCheckClick(ele)}
                >
                  {`${ele.item}`}
                  <br />
                  <br />
                  <span> {`${ele.total_price}`}</span>
                </div>
              );
            })}
      </div>
      <bill billItems={billItems} />
      <h3> total amount 0</h3>
    </>

also i want to remove the item from list when the quantity is 0

4 Answers 4

2

You need to filter trayItems when you map them in decre function. This will remove the items that have a quantity less than or equal to 1.

You need to calculate the total. There are 2 ways to go about it. Either create a new state that stores a calculated total or calculate it on the fly while managing/manipulating the trayItems's totalPrice. I have created a new state rather than making it more complex. You will need to re-render when the total changes so do that calculation inside a useEffect hook for re-render when the total changes.

Here is my solution:

import { Fragment, useEffect, useState } from "react";
import "./styles.css";

const item = [
  {
    user_id: 1,
    item: "biriani",
    price: "50",
    selling_price: "60",
    created_at: "2022-08-29T10:12:58.000000Z",
    updated_at: "2022-09-15T14:05:45.000000Z",
    tax: "5%",
    total_price: "80",
    status: 0,
    quantity: 0
  },
  {
    user_id: 5,
    item: "alfarm",
    price: "100",
    selling_price: "120",
    created_at: "2022-09-07T11:06:23.000000Z",
    updated_at: "2022-09-07T11:06:23.000000Z",
    tax: "5%",
    total_price: "140",
    status: 0,
    quantity: 0
  },
  {
    user_id: 4,
    item: "burger",
    price: "80",
    selling_price: "80",
    created_at: "2022-08-29T10:21:13.000000Z",
    updated_at: "2022-09-14T04:46:36.000000Z",
    tax: "5%",
    total_price: "100",
    status: 0,
    quantity: 0
  },
  {
    user_id: 8,
    item: "sandwich",
    price: "100",
    selling_price: "120",
    created_at: "2022-09-07T13:27:33.000000Z",
    updated_at: "2022-09-14T04:46:37.000000Z",
    tax: "5",
    total_price: "140",
    status: 0,
    quantity: 0
  },
  {
    user_id: 9,
    item: "pizza",
    price: "200",
    selling_price: "220",
    created_at: "2022-09-07T13:27:33.000000Z",
    updated_at: "2022-09-07T13:27:33.000000Z",
    tax: "5",
    total_price: "240",
    status: 0,
    quantity: 0
  },
  {
    user_id: 10,
    item: "chicken sadwich",
    price: "200",
    selling_price: "220",
    created_at: "2022-09-07T13:27:33.000000Z",
    updated_at: "2022-09-07T13:27:33.000000Z",
    tax: "5",
    total_price: "250",
    status: 0,
    quantity: 0
  },
  {
    user_id: 11,
    item: "sharja shake",
    price: "60",
    selling_price: "70",
    created_at: "2022-09-09T06:58:45.000000Z",
    updated_at: "2022-09-15T14:05:53.000000Z",
    tax: "5%",
    total_price: "80",
    status: 0,
    quantity: 0
  },

  {
    user_id: 1,
    item: "biriani",
    price: "50",
    selling_price: "60",
    created_at: "2022-08-29T10:12:58.000000Z",
    updated_at: "2022-09-15T06:17:20.000000Z",
    tax: "5%",
    total_price: "80",
    status: 1,
    quantity: 0
  },
  {
    user_id: 5,
    item: "alfarm",
    price: "100",
    selling_price: "120",
    created_at: "2022-09-07T11:06:23.000000Z",
    updated_at: "2022-09-07T11:06:23.000000Z",
    tax: "5%",
    total_price: "140",
    status: 0,
    quantity: 0
  }
];

export default function App() {
  const [trayItems, settrayItems] = useState([]);
  console.log(trayItems);
  const [total, setTotal] = useState(0);
  useEffect(() => {
    let newTotal = 0;
    trayItems.forEach((stat) => {
      newTotal += stat.price * stat.quantity;
    });
    setTotal(newTotal);
  }, [trayItems]);

  const handleCheckClick = (ele) => {
    const dupe = trayItems.find((obj) => obj.user_id === ele.user_id);
    settrayItems(
      dupe
        ? trayItems
        : [...trayItems, { ...ele, quantity: (ele.quantity = 1) }]
    );
  };

  const incre = (idd) => {
    settrayItems(
      trayItems.map((stat) =>
        stat.user_id === idd ? { ...stat, quantity: stat.quantity + 1 } : stat
      )
    );
  };
  const deleteFromTray = (currentTray, id) => {
    return currentTray.filter((item) => item.user_id !== id);
  };

  const decre = (idd) => {
    trayItems.every((stat, index) => {
      if (stat.user_id === idd) {
        stat.quantity > 1
          ? settrayItems([
              ...trayItems.slice(0, index),
              {
                ...stat,
                quantity: stat.quantity - 1
              },
              ...trayItems.slice(index + 1, trayItems.length)
            ])
          : settrayItems([
              ...trayItems.slice(0, index),
              ...trayItems.slice(index + 1, trayItems.length)
            ]);
        return false;
      }
      return true;
    });

    console.log("trashcoder", trayItems);
  };

  function Tray({ trayItems }) {
    return (
      <>
        <div className="foo">
          <table>
            <tbody>
              <tr>
                <th>item</th> <th>price</th> <th>qty</th> <th>total_price</th>
              </tr>
              {trayItems &&
                trayItems.map((ele, index) => {
                  return (
                    <tr key={index}>
                      <td>{ele.item}</td>
                      <td>{ele.price}</td>

                      <td>{ele.quantity}</td>
                      <th>{ele.price * ele.quantity}</th>
                      <td>
                        <button onClick={() => incre(ele.user_id)}>+</button>
                        <button onClick={() => decre(ele.user_id)}>-</button>
                      </td>
                    </tr>
                  );
                })}
            </tbody>
          </table>
        </div>
      </>
    );
  }

  return (
    <>
      <div>
        {item &&
          item
            .filter((person) => person.status === 0)
            .map((ele, index) => {
              return (
                <div
                  style={{ cursor: "pointer", border: "1px solid black" }}
                  key={index}
                  className="newmo-card"
                  onClick={() => handleCheckClick(ele)}
                >
                  {`${ele.item}`}
                  <br />
                  <br />
                  <span> {`${ele.total_price}`}</span>
                </div>
              );
            })}
      </div>
      <Tray trayItems={trayItems} />
      <h3> total amount {total}</h3>
    </>
  );
}

CodeSandBox link: https://codesandbox.io/s/cold-brook-sj207w?file=/src/dashbord.jsx:0-5500

Sign up to request clarification or add additional context in comments.

Comments

2

First, in the map of tray items you can multiple the quantity and price for the total

change this
<th>0</th>

to this 
<th>{ele.quantity * ele.price}</th>

As for displaying the total amount for each item, you need to create a function that will add all the items price * quantity. Here's sample function and implementation for your reference.

  const handleTotal = () => {
      // reduce will add all of your price and set a default value in case the items is empty
      return trayItems.reduce(
        (acc, curr) => Number(acc) + (curr.quantity * Number(curr.price)),0
      );
    }

then you need to change this 

<h3> total amount 0</h3>

to this

<h3>{`total amount ${handleTotal()}}</h3>

For removing the item if the quantity is 0, first, you need to modify your decrement function so that it will allow to make the quantity 0


const decre = (idd) => {
    settrayItems(
      trayItems.map((stat) =>
        stat.user_id === idd
          ? {
              ...stat,
              quantity:
                stat.quantity !== 1 ? stat.quantity - 1 : (stat.quantity = 0)
            }
          : stat
      )
    );
  };

Then add a checker that will show if the quantity is greater than 0

{trayItems &&
                trayItems.map((ele, index) => {
                  if (ele.quantity > 0) {
                    return (
                      <tr key={index}>
                        <td>{ele.item}</td>
                        <td>{ele.price}</td>

                        <td>{ele.quantity}</td>
                        <th>0</th>
                        <td>
                          <button onClick={() => incre(ele.user_id)}>+</button>
                          <button onClick={() => decre(ele.user_id)}>-</button>
                        </td>
                      </tr>
                    );
                  }
                })}

To re add the item again in the tray you need to modify the handleCheckClick so that if the trayItem.quantity is equal to 0 it will add 1 to it.

const handleCheckClick = (ele) => {
    const dupe = trayItems.find((obj) => obj.user_id === ele.user_id);
    settrayItems(
      dupe
        ? trayItems.map((item) => {
            if (item.quantity > 0) return item;
            return {
              ...item,
              quantity: item.quantity + 1
            };
          })
        : [...trayItems, { ...ele, quantity: (ele.quantity = 1) }]
    );
  };

9 Comments

for some reason i am getinng total amount [object Object]
You need to convert the price as Number because It's a string
can u make edit in the answer what i must be changing
I edit it now, I also remove the if statement because there's a default value in reduce method which is 0
oke thanx but can u help me fix the last part of my question i want to remove the item from list when the quantity is 0
|
1

First of all, clean your data. Always make sure your data is in a good state before using it.

I added a filtering in your decre function. This will filter out items with no quantity (also, I'm doing the mapping on the "previous state").

A new state is added (total). The value is updated every time the trayItems state is updated (useEffect).

However, I would suggest you to use a reducer instead.

Codesandbox: https://codesandbox.io/s/goofy-chatelet-d9oe8f?file=/src/dashbord.jsx

1 Comment

agreed, The state design needs to be addressed. My suggestion is that separate the bill related properties like quantity and total_price into a separate state maybe called cart or even bill
0

I tried your code and also solved it can you check it if you want exactly like this or anything different:

import { Fragment, useEffect, useState } from "react";
import "./styles.css";

const item = [
  {
    user_id: 1,
    item: "biriani",
    price: "50",
    selling_price: "60",
    created_at: "2022-08-29T10:12:58.000000Z",
    updated_at: "2022-09-15T14:05:45.000000Z",
    tax: "5%",
    total_price: "80",
    status: 0,
    quantity: 0
  },
  {
    user_id: 5,
    item: "alfarm",
    price: "100",
    selling_price: "120",
    created_at: "2022-09-07T11:06:23.000000Z",
    updated_at: "2022-09-07T11:06:23.000000Z",
    tax: "5%",
    total_price: "140",
    status: 0,
    quantity: 0
  },
  {
    user_id: 4,
    item: "burger",
    price: "80",
    selling_price: "80",
    created_at: "2022-08-29T10:21:13.000000Z",
    updated_at: "2022-09-14T04:46:36.000000Z",
    tax: "5%",
    total_price: "100",
    status: 0,
    quantity: 0
  },
  {
    user_id: 8,
    item: "sandwich",
    price: "100",
    selling_price: "120",
    created_at: "2022-09-07T13:27:33.000000Z",
    updated_at: "2022-09-14T04:46:37.000000Z",
    tax: "5",
    total_price: "140",
    status: 0,
    quantity: 0
  },
  {
    user_id: 9,
    item: "pizza",
    price: "200",
    selling_price: "220",
    created_at: "2022-09-07T13:27:33.000000Z",
    updated_at: "2022-09-07T13:27:33.000000Z",
    tax: "5",
    total_price: "240",
    status: 0,
    quantity: 0
  },
  {
    user_id: 10,
    item: "chicken sadwich",
    price: "200",
    selling_price: "220",
    created_at: "2022-09-07T13:27:33.000000Z",
    updated_at: "2022-09-07T13:27:33.000000Z",
    tax: "5",
    total_price: "250",
    status: 0,
    quantity: 0
  },
  {
    user_id: 11,
    item: "sharja shake",
    price: "60",
    selling_price: "70",
    created_at: "2022-09-09T06:58:45.000000Z",
    updated_at: "2022-09-15T14:05:53.000000Z",
    tax: "5%",
    total_price: "80",
    status: 0,
    quantity: 0
  },

  {
    user_id: 1,
    item: "biriani",
    price: "50",
    selling_price: "60",
    created_at: "2022-08-29T10:12:58.000000Z",
    updated_at: "2022-09-15T06:17:20.000000Z",
    tax: "5%",
    total_price: "80",
    status: 1,
    quantity: 0
  },
  {
    user_id: 5,
    item: "alfarm",
    price: "100",
    selling_price: "120",
    created_at: "2022-09-07T11:06:23.000000Z",
    updated_at: "2022-09-07T11:06:23.000000Z",
    tax: "5%",
    total_price: "140",
    status: 0,
    quantity: 0
  }
];

export default function App() {
  const [trayItems, settrayItems] = useState([]);
  const [totalAmount, setTotalAmount] = useState(0);
  console.log(trayItems);

  const handleCheckClick = (ele) => {
    const dupe = trayItems.find((obj) => obj.user_id === ele.user_id);
    settrayItems(
      dupe
        ? trayItems
        : [...trayItems, { ...ele, quantity: (ele.quantity = 1) }]
    );
  };

  const incre = (idd) => {
    settrayItems(
      trayItems.map((stat) =>
        stat.user_id === idd ? { ...stat, quantity: stat.quantity + 1 } : stat
      )
    );
  
  };

  const decre = (idd) => {
    settrayItems(
      trayItems.map((stat) =>
        stat.user_id === idd
          ? {
              ...stat,
              quantity:
                stat.quantity !== 1 ? stat.quantity - 1 : (stat.quantity = 1)
            }
          : stat
      )
    );
    
  };

  useEffect(() => {
    let tt = trayItems.reduce((accumulator, object) => {
      return accumulator + (Number(object.price) * object.quantity);
    }, 0);
    setTotalAmount(tt);
  }, [trayItems]); // just calculate the amount based on item and quantity

  function Tray({ trayItems }) {
    return (
      <>
        <div className="foo">
          <table>
            <tbody>
              <tr>
                <th>item</th> <th>price</th> <th>qty</th> <th>total_price</th>
              </tr>
              {trayItems &&
                trayItems.map((ele, index) => {
                  return (
                    <tr key={index}>
                      <td>{ele.item}</td>
                      <td>{ele.price}</td>

                      <td>{ele.quantity}</td>
                      <th>0</th>
                      <td>
                        <button onClick={() => incre(ele.user_id)}>+</button>
                        <button onClick={() => decre(ele.user_id)}>-</button>
                      </td>
                    </tr>
                  );
                })}
            </tbody>
          </table>
        </div>
      </>
    );
  }

  return (
    <>
      <div>
        {item &&
          item
            .filter((person) => person.status === 0)
            .map((ele, index) => {
              return (
                <div
                  style={{ cursor: "pointer", border: "1px solid black" }}
                  key={index}
                  className="newmo-card"
                  onClick={() => handleCheckClick(ele)}
                >
                  {`${ele.item}`}
                  <br />
                  <br />
                  <span> {`${ele.total_price}`}</span>
                </div>
              );
            })}
      </div>
      <Tray trayItems={trayItems} />
      <h3> total amount {totalAmount}</h3>
    </>
  );
}

2 Comments

can u make a codesanbox so i can test the code
here is the link you can check: link

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.