ok
This commit is contained in:
@@ -47,6 +47,7 @@ function CafePage({
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
const [isEditMode, setIsEditMode] = useState(false);
|
||||
const [filterId, setFilterId] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (user.cafeId != null && user.cafeId != shopId) {
|
||||
@@ -112,6 +113,7 @@ function CafePage({
|
||||
guestSideOfClerk={guestSideOfClerk}
|
||||
removeConnectedGuestSides={removeConnectedGuestSides}
|
||||
setIsEditMode={(e) => setIsEditMode(e)}
|
||||
isEditMode={isEditMode}
|
||||
/>
|
||||
<div style={{ marginTop: "5px" }}></div>
|
||||
<SearchInput shopId={shopId} tableCode={table.tableCode} />
|
||||
@@ -121,28 +123,43 @@ function CafePage({
|
||||
shopOwnerId={shopOwnerId}
|
||||
shopId={shopId}
|
||||
itemTypes={shopItems}
|
||||
isEditMode={isEditMode}
|
||||
onFilterChange={(e) => setFilterId(e)}
|
||||
filterId={filterId}
|
||||
/>
|
||||
<div style={{ marginTop: "-13px" }}></div>
|
||||
<h2 className="title">Music Req.</h2>
|
||||
<MusicPlayer
|
||||
socket={socket}
|
||||
shopId={shopId}
|
||||
user={user}
|
||||
isSpotifyNeedLogin={isSpotifyNeedLogin}
|
||||
/>
|
||||
{filterId === 0 ? (
|
||||
<>
|
||||
<h2 className="title">Music Req.</h2>
|
||||
<MusicPlayer
|
||||
socket={socket}
|
||||
shopId={shopId}
|
||||
user={user}
|
||||
isSpotifyNeedLogin={isSpotifyNeedLogin}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<div style={{ marginTop: "35px" }}></div>
|
||||
)}
|
||||
|
||||
<div style={{ marginTop: "-15px" }}></div>
|
||||
{shopItems.map((itemType) => (
|
||||
<ItemLister
|
||||
shopId={shopId}
|
||||
shopOwnerId={shopOwnerId}
|
||||
user={user}
|
||||
key={itemType.itemTypeId}
|
||||
itemTypeId={itemType.itemTypeId}
|
||||
typeName={itemType.name}
|
||||
itemList={itemType.itemList}
|
||||
isEditMode={isEditMode}
|
||||
/>
|
||||
))}
|
||||
{shopItems
|
||||
.filter(
|
||||
(itemType) => filterId == 0 || itemType.itemTypeId === filterId
|
||||
)
|
||||
.map((itemType) => (
|
||||
<ItemLister
|
||||
shopId={shopId}
|
||||
shopOwnerId={shopOwnerId}
|
||||
user={user}
|
||||
key={itemType.itemTypeId}
|
||||
itemTypeId={itemType.itemTypeId}
|
||||
typeName={itemType.name}
|
||||
itemList={itemType.itemList}
|
||||
isEditMode={isEditMode}
|
||||
raw={isEditMode || filterId == 0 ? false : true}
|
||||
/>
|
||||
))}
|
||||
</body>
|
||||
{user.username && (
|
||||
<AccountUpdateModal
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useRef, useEffect, useState } from "react";
|
||||
import styles from "./Invoice.module.css";
|
||||
import { useParams, useLocation } from "react-router-dom"; // Changed from useSearchParams to useLocation
|
||||
import { useParams } from "react-router-dom"; // Changed from useSearchParams to useLocation
|
||||
import { ThreeDots, ColorRing } from "react-loader-spinner";
|
||||
|
||||
import ItemLister from "../components/ItemLister";
|
||||
@@ -15,19 +15,12 @@ export default function Invoice({ table, sendParam, deviceType, socket }) {
|
||||
const { shopId, tableCode } = useParams();
|
||||
sendParam({ shopId, tableCode });
|
||||
|
||||
const location = useLocation(); // Use useLocation hook instead of useSearchParams
|
||||
const searchParams = new URLSearchParams(location.search); // Pass location.search directly
|
||||
|
||||
// const email = searchParams.get("email");
|
||||
// const orderType = searchParams.get("orderType");
|
||||
// const tableNumber = searchParams.get("tableNumber");
|
||||
|
||||
const [cartItems, setCartItems] = useState([]);
|
||||
const [totalPrice, setTotalPrice] = useState(0);
|
||||
const [isPaymentLoading, setIsPaymentLoading] = useState(false); // State for payment button loading animation
|
||||
|
||||
const textareaRef = useRef(null);
|
||||
const [orderType, setOrderType] = useState("serve");
|
||||
const [orderType, setOrderType] = useState("pickup");
|
||||
const [tableNumber, setTableNumber] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
|
||||
@@ -35,10 +28,41 @@ export default function Invoice({ table, sendParam, deviceType, socket }) {
|
||||
const fetchCartItems = async () => {
|
||||
try {
|
||||
const items = await getCartDetails(shopId);
|
||||
setCartItems(items);
|
||||
console.log(items);
|
||||
|
||||
// Calculate total price based on fetched cart items
|
||||
const totalPrice = items.reduce((total, itemType) => {
|
||||
// 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
|
||||
|
||||
setCartItems(filteredItems);
|
||||
|
||||
// Update local storage by removing unavailable items
|
||||
const updatedLocalStorage =
|
||||
JSON.parse(localStorage.getItem("cart")) || [];
|
||||
const newLocalStorage = updatedLocalStorage.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(newLocalStorage));
|
||||
|
||||
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) => {
|
||||
@@ -107,6 +131,11 @@ export default function Invoice({ table, sendParam, deviceType, socket }) {
|
||||
}
|
||||
}, [textareaRef.current]);
|
||||
|
||||
useEffect(() => {
|
||||
if (table?.tableId != undefined) setOrderType("serve");
|
||||
console.log(table);
|
||||
}, [table]);
|
||||
|
||||
const handleOrderTypeChange = (event) => {
|
||||
setOrderType(event.target.value);
|
||||
};
|
||||
|
||||
66
src/pages/NotificationBlocked.js
Normal file
66
src/pages/NotificationBlocked.js
Normal file
@@ -0,0 +1,66 @@
|
||||
// NotificationBlocked.js
|
||||
import React from "react";
|
||||
|
||||
const NotificationBlocked = () => {
|
||||
return (
|
||||
<div style={styles.container}>
|
||||
<h2 style={styles.header}>Notifications Blocked</h2>
|
||||
<p style={styles.message}>
|
||||
It looks like notifications are currently blocked in your browser.
|
||||
Enabling notifications will help you receive important updates, such as
|
||||
new orders or alerts, directly on your device.
|
||||
</p>
|
||||
<h3 style={styles.instructionsHeader}>To enable notifications:</h3>
|
||||
<ol style={styles.instructions}>
|
||||
<li>Open Chrome and go to our café's website.</li>
|
||||
<li>Tap the menu (three dots) in the top-right corner.</li>
|
||||
<li>
|
||||
Go to <strong>Settings</strong> > <strong>Site settings</strong>{" "}
|
||||
> <strong>Notifications</strong>.
|
||||
</li>
|
||||
<li>
|
||||
Find our café's site in the list and change the setting to{" "}
|
||||
<strong>Allow</strong>.
|
||||
</li>
|
||||
</ol>
|
||||
<p style={styles.footer}>
|
||||
Once you enable notifications, you'll start receiving updates right
|
||||
away! If you need help, feel free to ask!
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
padding: "20px",
|
||||
border: "1px solid #ddd",
|
||||
borderRadius: "5px",
|
||||
backgroundColor: "#f9f9f9",
|
||||
boxShadow: "0 2px 5px rgba(0,0,0,0.1)",
|
||||
maxWidth: "400px",
|
||||
margin: "20px auto",
|
||||
textAlign: "center",
|
||||
},
|
||||
header: {
|
||||
color: "#e74c3c",
|
||||
},
|
||||
message: {
|
||||
marginBottom: "20px",
|
||||
},
|
||||
instructionsHeader: {
|
||||
marginTop: "20px",
|
||||
fontWeight: "bold",
|
||||
},
|
||||
instructions: {
|
||||
listStyleType: "decimal",
|
||||
paddingLeft: "20px",
|
||||
textAlign: "left",
|
||||
},
|
||||
footer: {
|
||||
marginTop: "20px",
|
||||
fontStyle: "italic",
|
||||
},
|
||||
};
|
||||
|
||||
export default NotificationBlocked;
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
// src/CafePage.js
|
||||
import React, { useState } from "react";
|
||||
import { useParams, useSearchParams, useNavigate } from "react-router-dom";
|
||||
@@ -17,7 +16,7 @@ function SearchResult({ user, shopItems, sendParam }) {
|
||||
sendParam({ shopId, tableCode });
|
||||
|
||||
const [searchValue, setSearchValue] = useState(
|
||||
"dwadawa vvwqd21qb13 4kfawfdwa dhawldhawr dliawbdjawndlks"
|
||||
"dwakbdawkjhbdaw wadhbakdbaw wadh abkd wba aww wadhbd kablawdloq w"
|
||||
);
|
||||
|
||||
// Function to handle search input change
|
||||
@@ -69,4 +68,4 @@ function SearchResult({ user, shopItems, sendParam }) {
|
||||
);
|
||||
}
|
||||
|
||||
export default SearchResult;
|
||||
export default SearchResult;
|
||||
|
||||
@@ -188,7 +188,7 @@ export default function Transactions({ propsShopId, sendParam, deviceType }) {
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
{transaction.confirmed == 0 && (
|
||||
{transaction.confirmed < 2 && (
|
||||
<h5
|
||||
className={styles.DeclineButton}
|
||||
onClick={() => handleDecline(transaction.transactionId)}
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useRef, useEffect, useState } from "react";
|
||||
import styles from "./Transactions.module.css";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { ColorRing } from "react-loader-spinner";
|
||||
import ButtonWithReplica from "../components/ButtonWithReplica";
|
||||
import {
|
||||
getTransaction,
|
||||
confirmTransaction,
|
||||
@@ -156,11 +157,10 @@ export default function Transactions({ propsShopId, sendParam, deviceType }) {
|
||||
Rp {calculateTotalPrice(transaction.DetailedTransactions)}
|
||||
</span>
|
||||
</div>
|
||||
<div className={styles.TotalContainer}>
|
||||
<button
|
||||
className={styles.PayButton}
|
||||
<div className={styles.PaymentContainer}>
|
||||
<ButtonWithReplica
|
||||
disabled={isPaymentLoading}
|
||||
onClick={() => handleConfirm(transaction.transactionId)}
|
||||
disabled={isPaymentLoading} // Disable button if confirmed (1) or declined (-1) or loading
|
||||
>
|
||||
{isPaymentLoading ? (
|
||||
<ColorRing height="50" width="50" color="white" />
|
||||
@@ -175,7 +175,7 @@ export default function Transactions({ propsShopId, sendParam, deviceType }) {
|
||||
) : (
|
||||
"Confirm availability" // Display "Confirm availability" if the transaction is not confirmed (0)
|
||||
)}
|
||||
</button>
|
||||
</ButtonWithReplica>
|
||||
</div>
|
||||
<h5
|
||||
className={styles.DeclineButton}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
} from "../helpers/transactionHelpers";
|
||||
import { getTables } from "../helpers/tableHelper";
|
||||
import TableCanvas from "../components/TableCanvas";
|
||||
import ButtonWithReplica from "../components/ButtonWithReplica";
|
||||
|
||||
export default function Transactions({ propsShopId, sendParam, deviceType }) {
|
||||
const { shopId, tableId } = useParams();
|
||||
@@ -143,6 +144,7 @@ export default function Transactions({ propsShopId, sendParam, deviceType }) {
|
||||
</span>
|
||||
</div>
|
||||
<div className={styles.TotalContainer}>
|
||||
<ButtonWithReplica />
|
||||
<button
|
||||
className={styles.PayButton}
|
||||
onClick={() => handleConfirm(transaction.transactionId)}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: rgba(88, 55, 50, 1);
|
||||
background-color: #e9e9e9;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.Transactions-title {
|
||||
@@ -34,6 +35,8 @@
|
||||
|
||||
.TransactionListContainer {
|
||||
overflow-y: auto; /* Enables vertical scrolling */
|
||||
background-color: #dbdbdb;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.TotalContainer {
|
||||
@@ -50,6 +53,21 @@
|
||||
margin-bottom: 17px;
|
||||
}
|
||||
|
||||
.PaymentContainer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%; /* Ensures it takes up full width */
|
||||
margin: 0 auto;
|
||||
font-family: "Poppins", sans-serif;
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
font-size: 1.5em;
|
||||
padding: 10px;
|
||||
box-sizing: border-box; /* Includes padding in width */
|
||||
margin-bottom: 17px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.PayButton {
|
||||
font-family: "Poppins", sans-serif;
|
||||
font-weight: 500;
|
||||
|
||||
Reference in New Issue
Block a user