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

@@ -612,6 +612,8 @@ function App() {
socket={socket}
totalItemsCount={totalItemsCount}
deviceType={deviceType}
shopItems={shopItems}
setShopItems={setShopItems}
/>
{/* <Footer
shopId={shopIdentifier}

View File

@@ -60,7 +60,7 @@ const ButtonWithReplica = ({
try {
console.log(paymentUrl);
const qrv = await decodeQRCodeFromUrl(paymentUrl);
setQRValue('00020101021126760024ID.CO.SPEEDCASH.MERCHANT01189360081530001108500215ID10210011085060303UBE51440014ID.CO.QRIS.WWW0215ID20211101828900303UBE5204829953033605802ID5908DINNCAFE6008SURABAYA61056029462260506S155880105280940703A0163041E7B');
setQRValue(qrv);
} catch (error) {
console.error(error);
}

View File

@@ -191,7 +191,8 @@ const Item = ({
alignItems: 'center',
whiteSpace: 'nowrap',
borderRadius: '9999px',
backgroundImage: 'linear-gradient(to right, #e52535, #eb525e)',
backgroundColor: !isAvailable ? 'gray' : 'unset',
backgroundImage: isAvailable && 'linear-gradient(to right, #e52535, #eb525e)',
padding: '0.25rem 0rem',
color: 'rgb(255, 255, 255)',
fontSize: '0.75rem',

View File

@@ -320,6 +320,7 @@ export const handlePaymentFromGuestDevice = async (
items: items.map((item) => ({
itemId: item.itemId,
qty: item.qty,
price: item.price
})),
};

View File

@@ -17,7 +17,7 @@ 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 });
@@ -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,6 +340,7 @@ export default function Invoice({ shopId, table, sendParam, deviceType, socket }
<h1 style={{ fontSize: '120%', color: '#8F8787' }}>Tidak ada item di keranjang</h1>
</div>
:
(isLoading ? <></> :
<>
<div className={styles.RoundedRectangle}>
{cartItems.map((itemType) => (
@@ -301,6 +427,7 @@ export default function Invoice({ shopId, table, sendParam, deviceType, socket }
</div>
<div className={styles.PaymentOptionMargin}></div>
</>
)
}
</div>
);

View File

@@ -51,7 +51,7 @@ export default function Transactions({ propsShopId, sendParam, deviceType }) {
const calculateTotalPrice = (detailedTransactions) => {
return detailedTransactions.reduce((total, dt) => {
return total + dt.qty * dt.Item.price;
return total + dt.qty * (dt.promoPrice ? dt.promoPrice : dt.price);
}, 0);
};
@@ -122,7 +122,7 @@ export default function Transactions({ propsShopId, sendParam, deviceType }) {
{transaction.DetailedTransactions.map((detail) => (
<li key={detail.detailedTransactionId}>
<span>{detail.Item.name}</span> - {detail.qty} x Rp{" "}
{detail.Item.price}
{detail.promoPrice ? detail.promoPrice : detail.price}
</li>
))}
</ul>

View File

@@ -567,11 +567,20 @@ const App = ({ forCafe = true, cafeId = -1,
/>
)
}
{selectedCafeId != -1 && (
<RoundedRectangle
title={"Total promo"}
loading={loading}
value={'Rp'+analytics?.currentTotals.totalPromoSpend}
// width="calc(50% - 10px)"
onClick={() => window.location.href = window.location.origin + '/' + otherCafes.find(item => item.cafeId === selectedCafeId).cafeIdentifyName}
/>
)}
{!forCafe && selectedCafeId != -1 && selectedCafeId != 0 && (
<RoundedRectangle
title={"Kunjungi bisnis"}
loading={loading}
width="calc(100% - 10px)"
// width="calc(100% - 10px)"
onClick={() => window.location.href = window.location.origin + '/' + otherCafes.find(item => item.cafeId === selectedCafeId).cafeIdentifyName}
/>
)}

View File

@@ -52,7 +52,7 @@ export default function Transactions({ propsShopId, sendParam, deviceType, handl
const calculateTotalPrice = (detailedTransactions) => {
return detailedTransactions.reduce((total, dt) => {
return total + dt.qty * dt.Item.price;
return total + dt.qty * (dt.promoPrice ? dt.promoPrice : dt.price);
}, 0);
};
@@ -175,7 +175,7 @@ export default function Transactions({ propsShopId, sendParam, deviceType, handl
{transaction.DetailedTransactions.map((detail) => (
<li key={detail.detailedTransactionId}>
<span>{detail.Item.name}</span> - {detail.qty} x Rp{" "}
{detail.Item.price}
{detail.promoPrice ? detail.promoPrice : detail.price}
</li>
))}
</ul>

View File

@@ -73,7 +73,7 @@ export default function Transactions({
const calculateTotalPrice = (detailedTransactions) => {
return detailedTransactions.reduce((total, dt) => {
return total + dt.qty * dt.Item.price;
return total + dt.qty * (dt.promoPrice ? dt.promoPrice : dt.price);
}, 0);
};
@@ -124,7 +124,7 @@ export default function Transactions({
return (
<div className={styles.Transaction}>
<div className={styles.TransactionListContainer}>
<div className={styles.TransactionListContainer} style={{ overflow: 'hidden' }}>
{transaction && (
<div
key={transaction.transactionId}
@@ -164,7 +164,7 @@ export default function Transactions({
).map((detail) => (
<li key={detail.detailedTransactionId}>
<span>{detail.Item.name}</span> - {detail.qty} x Rp{" "}
{detail.Item.price}
{detail.promoPrice ? detail.promoPrice : detail.price}
</li>
))}
</ul>
@@ -172,8 +172,7 @@ export default function Transactions({
<h2 className={styles["Transactions-detail"]}>
{transaction.serving_type === "pickup"
? "Self pickup"
: `Serve to ${
transaction.Table ? transaction.Table.tableNo : "N/A"
: `Serve to ${transaction.Table ? transaction.Table.tableNo : "N/A"
}`}
</h2>
{(transaction.notes !== "") && (
@@ -222,13 +221,15 @@ export default function Transactions({
isPaymentOpen={isPaymentOpen}
>
{transaction.payment_type == 'cash' || isPaymentLoading ? (
<>
{transaction.payment_type == 'cash' && <p>Bayar nanti</p>}
</>
(transaction.payment_type == 'cash' && 'Bayar nanti')
) : isPaymentOpen ? (
"Claim has paid" // Display "Confirm has paid" if the transaction is confirmed (1)
(transaction.paymentClaimed ? <>
<div style={{position: 'absolute', left: '15px', top: '9px'}}>
<ColorRing
height="20"
width="20" className={styles['receipt-logo']} /></div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Menunggu konfirmasi</> : "Klaim telah bayar") // Display "Confirm has paid" if the transaction is confirmed (1)
) : (
"Show payment" // Display "Confirm availability" if the transaction is not confirmed (0)
"Tampilkan QR" // Display "Confirm availability" if the transaction is not confirmed (0)
)}
</ButtonWithReplica>
</div>

View File

@@ -64,7 +64,7 @@ export default function Transactions({ propsShopId, sendParam, deviceType, handl
const calculateTotalPrice = (detailedTransactions) => {
return detailedTransactions.reduce((total, dt) => {
return total + dt.qty * dt.Item.price;
return total + dt.qty * (dt.promoPrice ? dt.promoPrice : dt.price);
}, 0);
};
@@ -156,7 +156,7 @@ export default function Transactions({ propsShopId, sendParam, deviceType, handl
{transaction.DetailedTransactions.map((detail) => (
<li key={detail.detailedTransactionId}>
<span>{detail.Item.name}</span> - {detail.qty} x Rp{" "}
{detail.Item.price}
{detail.promoPrice ? detail.promoPrice : detail.Item.price}
</li>
))}
</ul>

View File

@@ -26,9 +26,40 @@ export default function Transactions({ shopId, propsShopId, sendParam, deviceTyp
try {
let response;
response = await getTransactionsFromCafe(shopId || propsShopId, 5, false);
console.log(response)
if(response) {
setTransactions(response);
return;
}
} catch (error) {
console.error("Error fetching transactions:", error);
}
try {
let response;
response = await getMyTransactions(shopId || propsShopId, 5);
setMyTransactions(response);
console.log(response)
const combinedTransactions = [];
response.forEach(cafe => {
const { cafeId, name: cafeName, transactions } = cafe;
transactions.forEach(transaction => {
const newTransaction = {
...transaction,
cafeId,
cafeName,
DetailedTransactions: transaction.detailedTransactions // Rename here
};
delete newTransaction.detailedTransactions; // Remove the old key
combinedTransactions.push(newTransaction);
});
});
// combinedTransactions now contains all transactions with cafe info and renamed key
console.log(combinedTransactions)
// combinedTransactions now contains all transactions with cafe info
setTransactions(combinedTransactions);
} catch (error) {
console.error("Error fetching transactions:", error);
}
@@ -52,7 +83,7 @@ export default function Transactions({ shopId, propsShopId, sendParam, deviceTyp
const calculateTotalPrice = (detailedTransactions) => {
return detailedTransactions.reduce((total, dt) => {
return total + dt.qty * dt.Item.price;
return total + dt.qty * (dt.promoPrice ? dt.promoPrice : dt.price);
}, 0);
};
@@ -184,7 +215,7 @@ export default function Transactions({ shopId, propsShopId, sendParam, deviceTyp
{transaction.DetailedTransactions.map((detail) => (
<li key={detail.detailedTransactionId}>
<span>{detail.Item.name}</span> - {detail.qty} x Rp{" "}
{detail.Item.price}
{detail.promoPrice ? detail.promoPrice : detail.price}
</li>
))}
</ul>
@@ -195,7 +226,7 @@ export default function Transactions({ shopId, propsShopId, sendParam, deviceTyp
}`}
</h2>
{transaction.notes != "" && (
{transaction.notes && (
<>
<div className={styles.NoteContainer}>
<span>Note :</span>
@@ -211,6 +242,7 @@ export default function Transactions({ shopId, propsShopId, sendParam, deviceTyp
</div>
</>
)}
<div className={styles.TotalContainer}>
<span>Total:</span>
<span>