This commit is contained in:
zadit
2025-02-16 01:19:51 +07:00
parent 422398c65e
commit df0dbafe18
11 changed files with 285 additions and 112 deletions

View File

@@ -17,9 +17,9 @@ import { getItemsByCafeId } from "../helpers/cartHelpers.js";
import { useNavigationHelpers } from "../helpers/navigationHelpers";
export default function Invoice({ shopId, table, sendParam, deviceType, socket }) {
export default function Invoice({ shopId, table, sendParam, deviceType, socket, shopItems, setShopItems }) {
const { shopIdentifier, tableCode } = useParams();
sendParam({ shopIdentifier, tableCode });
const {
@@ -35,24 +35,37 @@ export default function Invoice({ shopId, table, sendParam, deviceType, socket }
const [orderMethod, setOrderMethod] = useState("cash");
const [tableNumber, setTableNumber] = useState("");
const [email, setEmail] = useState("");
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const fetchCartItems = async () => {
try {
const items = await getCartDetails(shopId);
console.log(items);
const cart = getItemsByCafeId(shopId);
const itemMap = new Map(cart.map(item => [item.itemId, item.qty]));
// Filter out unavailable items
const filteredItems = items
.map((itemType) => ({
...itemType,
itemList: itemType.itemList.filter((item) => item.availability),
// Step 2: Filter and transform shopItems
const filteredItems = shopItems
.map(itemType => ({
itemTypeId: itemType.itemTypeId,
cafeId: itemType.cafeId,
typeName: itemType.name,
itemList: itemType.itemList
.filter(item => itemMap.has(item.itemId)) // Keep only items in getItemsByCafeId
.map(item => ({
itemId: item.itemId,
price: (item.promoPrice ? item.promoPrice : item.price),
name: item.name,
image: item.image,
qty: itemMap.get(item.itemId), // Add qty from getItemsByCafeId
availability: item.availability
}))
}))
.filter((itemType) => itemType.itemList.length > 0); // Remove empty itemTypes
setCartItems(filteredItems);
.filter(itemType => itemType.itemList.length > 0); // Remove empty itemTypes
console.log(filteredItems)
// Update local storage by removing unavailable items
const updatedLocalStorage =
JSON.parse(localStorage.getItem("cart")) || [];
@@ -79,7 +92,118 @@ export default function Invoice({ shopId, table, sendParam, deviceType, socket }
return (
total +
itemType.itemList.reduce((subtotal, item) => {
return subtotal + item.qty * item.price;
return subtotal + item.qty * (item.promoPrice ? item.promoPrice : item.price);
}, 0)
);
}, 0);
setTimeout(function () {
setCartItems(filteredItems);
setTotalPrice(totalPrice);
setIsLoading(false)
}, 100); //delay is in milliseconds
} catch (error) {
console.error("Error fetching cart items:", error);
// Handle error if needed
}
};
fetchCartItems();
const getNewestCartItems = async () => {
try {
// Fetch items from the cart details (latest state)
const items = await getCartDetails(shopId);
// Loop through each item type in the items from the cart details
items.forEach(itemType => {
itemType.itemList.forEach(item => {
// Loop through the shopItems and find the corresponding itemId
shopItems.forEach(shopItemType => {
shopItemType.itemList.forEach(shopItem => {
if (shopItem.itemId === item.itemId) {
// Update shopItems with the new data from items (e.g., availability, price)
shopItem.availability = item.availability;
shopItem.price = item.price; // If needed, update other properties like price
shopItem.promoPrice = item.promoPrice;
}
});
});
});
});
// After updating shopItems, set the new state
setShopItems(shopItems);
// Filter out unavailable items
const filteredItems = items
.map((itemType) => ({
...itemType,
itemList: itemType.itemList.filter((item) => item.availability),
}))
.filter((itemType) => itemType.itemList.length > 0); // Remove empty itemTypes
setIsLoading(true);
setTimeout(function () {
setCartItems(filteredItems);
setIsLoading(false);
}, 100); // delay is in milliseconds
// Update local storage by removing unavailable items and updating prices
const updatedLocalStorage = JSON.parse(localStorage.getItem("cart")) || [];
const newLocalStorage = updatedLocalStorage.map((cafe) => {
if (cafe.cafeId === shopId) {
return {
...cafe,
items: cafe.items.map((item) => {
// Find the updated item in filteredItems and set its updated price
const updatedItem = filteredItems
.flatMap((itemType) => itemType.itemList)
.find((filtered) => filtered.itemId === item.itemId);
if (updatedItem) {
// Update the price in the local storage item
return {
...item,
price: updatedItem.promoPrice?updatedItem.promoPrice:updatedItem.price,
availability: updatedItem.availability
};
}
// If no updated item found, return the original item
return item;
}),
};
}
return cafe;
});
const newLocalStoragee = newLocalStorage.map((cafe) => {
if (cafe.cafeId === shopId) {
return {
...cafe,
items: cafe.items.filter((item) =>
filteredItems.some((filtered) =>
filtered.itemList.some(
(i) => i.itemId === item.itemId && i.availability
)
)
),
};
}
return cafe;
});
localStorage.setItem("cart", JSON.stringify(newLocalStoragee));
window.dispatchEvent(new Event("localStorageUpdated"));
// Calculate total price based on filtered cart items
const totalPrice = filteredItems.reduce((total, itemType) => {
return (
total +
itemType.itemList.reduce((subtotal, item) => {
return subtotal + item.qty * (item.promoPrice ? item.promoPrice:item.price);
}, 0)
);
}, 0);
@@ -88,9 +212,10 @@ export default function Invoice({ shopId, table, sendParam, deviceType, socket }
console.error("Error fetching cart items:", error);
// Handle error if needed
}
};
fetchCartItems();
getNewestCartItems();
}, [shopId]);
const handlePay = async (isCash) => {
@@ -215,22 +340,23 @@ export default function Invoice({ shopId, table, sendParam, deviceType, socket }
<h1 style={{ fontSize: '120%', color: '#8F8787' }}>Tidak ada item di keranjang</h1>
</div>
:
<>
<div className={styles.RoundedRectangle}>
{cartItems.map((itemType) => (
<ItemLister
shopId={shopId}
forInvoice={true}
key={itemType.id}
typeName={itemType.typeName}
itemList={itemType.itemList}
/>
))}
(isLoading ? <></> :
<>
<div className={styles.RoundedRectangle}>
{cartItems.map((itemType) => (
<ItemLister
shopId={shopId}
forInvoice={true}
key={itemType.id}
typeName={itemType.typeName}
itemList={itemType.itemList}
/>
))}
{table.tableNo != null && (
<div className={styles.OrderTypeContainer}>
<span htmlFor="orderType">Diantar ke {table.tableNo}</span>
{/* <select
{table.tableNo != null && (
<div className={styles.OrderTypeContainer}>
<span htmlFor="orderType">Diantar ke {table.tableNo}</span>
{/* <select
id="orderType"
value={orderType}
onChange={handleOrderTypeChange}
@@ -241,66 +367,67 @@ export default function Invoice({ shopId, table, sendParam, deviceType, socket }
<option value="pickup">Pickup</option>
{table == null && <option value="serve">Serve</option>}
</select> */}
</div>
)}
{orderType === "serve" && table.length < 1 && (
<div className={styles.OrderTypeContainer}>
<span htmlFor="orderType">Serve to:</span>
<input
type="text"
placeholder="Table Number"
value={tableNumber}
onChange={handleTableNumberChange}
className={styles.TableNumberInput}
/>
</div>
)}
<div className={styles.NoteContainer}>
<span>Catatan :</span>
<span></span>
</div>
)}
{orderType === "serve" && table.length < 1 && (
<div className={styles.OrderTypeContainer}>
<span htmlFor="orderType">Serve to:</span>
<input
type="text"
placeholder="Table Number"
value={tableNumber}
onChange={handleTableNumberChange}
className={styles.TableNumberInput}
<div className={styles.NoteContainer}>
<textarea
ref={textareaRef}
className={styles.NoteInput}
placeholder="Tambahkan catatan..."
/>
</div>
)}
</div>
<div className={styles.PaymentOption}>
<div className={styles.TotalContainer}>
<span>Pembayaran</span>
<span>
<select
style={{ borderRadius: '6px', fontSize: '20px' }}
id="orderMethod"
value={orderMethod}
onChange={handleOrderMethodChange}
>
<option value="cash">&nbsp;Tunai</option>
<option value="cashless">&nbsp;Non Tunai&nbsp;</option>
</select>
</span>
</div>
<div style={{ display: 'flex', paddingLeft: '25px', paddingRight: '25px' }}>
<button className={styles.PayButton} onClick={() => handlePay(orderMethod == 'cash' ? true : false)}>
{isPaymentLoading ? (
<ColorRing height="50" width="50" color="white" />
) : (
<div>
<span>Pesan</span>
<div className={styles.NoteContainer}>
<span>Catatan :</span>
<span></span>
<span>Rp{totalPrice}</span>
</div>
)}
</button>
</div>
<div onClick={goToShop} style={{ textAlign: 'center', marginBottom: '20px' }}>Kembali</div>
</div>
<div className={styles.NoteContainer}>
<textarea
ref={textareaRef}
className={styles.NoteInput}
placeholder="Tambahkan catatan..."
/>
</div>
</div>
<div className={styles.PaymentOption}>
<div className={styles.TotalContainer}>
<span>Pembayaran</span>
<span>
<select
style={{ borderRadius: '6px', fontSize: '20px' }}
id="orderMethod"
value={orderMethod}
onChange={handleOrderMethodChange}
>
<option value="cash">&nbsp;Tunai</option>
<option value="cashless">&nbsp;Non Tunai&nbsp;</option>
</select>
</span>
</div>
<div style={{ display: 'flex', paddingLeft: '25px', paddingRight: '25px' }}>
<button className={styles.PayButton} onClick={() => handlePay(orderMethod == 'cash' ? true : false)}>
{isPaymentLoading ? (
<ColorRing height="50" width="50" color="white" />
) : (
<div>
<span>Pesan</span>
<span>Rp{totalPrice}</span>
</div>
)}
</button>
</div>
<div onClick={goToShop} style={{ textAlign: 'center', marginBottom: '20px' }}>Kembali</div>
</div>
<div className={styles.PaymentOptionMargin}></div>
</>
<div className={styles.PaymentOptionMargin}></div>
</>
)
}
</div>
);