ok
This commit is contained in:
@@ -156,19 +156,18 @@ const shrink = keyframes`
|
||||
border-radius: 50%;
|
||||
}
|
||||
`;
|
||||
|
||||
const Rectangle = styled.div`
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
right: 15px;
|
||||
width: 200px;
|
||||
height: auto;
|
||||
max-height: 87vh; /* or another appropriate value */
|
||||
background-color: white;
|
||||
z-index: 10;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
animation: ${(props) => (props.animate === "grow" ? grow : shrink)} 0.5s
|
||||
forwards;
|
||||
overflow: hidden;
|
||||
overflow-y: auto; /* Enable vertical scrolling */
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
`;
|
||||
@@ -246,6 +245,7 @@ const Header = ({
|
||||
if (rectangleRef.current && !rectangleRef.current.contains(event.target)) {
|
||||
setAnimate("shrink");
|
||||
setTimeout(() => setShowRectangle(false), 500);
|
||||
rectangleRef.current.style.overflow = "hidden";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -304,7 +304,9 @@ const Header = ({
|
||||
<Child onClick={goToLogin}>Click to login</Child>
|
||||
)}
|
||||
{user.username !== undefined && (
|
||||
<Child onClick={() => setModal("edit_account")}>Edit</Child>
|
||||
<Child onClick={() => setModal("edit_account")}>
|
||||
Edit profile
|
||||
</Child>
|
||||
)}
|
||||
{shopId &&
|
||||
user.userId == shopOwnerId &&
|
||||
@@ -312,59 +314,77 @@ const Header = ({
|
||||
user.roleId === 1 && (
|
||||
<>
|
||||
<Child onClick={goToAdminCafes}>see your other cafes</Child>
|
||||
<Child onClick={() => setModal("edit_tables")}>
|
||||
{shopName} table maps
|
||||
</Child>
|
||||
<Child hasChildren>
|
||||
{shopName} clerks
|
||||
<Child onClick={() => setModal("craete_account_clerk")}>
|
||||
+ Add clerk
|
||||
</Child>
|
||||
{shopClerks &&
|
||||
shopClerks.map((key, index) => (
|
||||
<Child key={index}>
|
||||
{shopClerks[index].username}
|
||||
<button
|
||||
onClick={() =>
|
||||
removeConnectedGuestSides(guestSides[index][3])
|
||||
}
|
||||
>
|
||||
remove
|
||||
</button>
|
||||
</Child>
|
||||
))}
|
||||
</Child>
|
||||
<Child onClick={() => setModal("add_material")}>
|
||||
add material
|
||||
</Child>
|
||||
<Child onClick={() => setModal("update_stock")}>
|
||||
update stock
|
||||
</Child>
|
||||
<Child hasChildren>
|
||||
{shopName}
|
||||
<Child onClick={() => setModal("edit_tables")}>
|
||||
table maps
|
||||
</Child>
|
||||
<Child hasChildren>
|
||||
clerks
|
||||
<Child onClick={() => setModal("craete_account_clerk")}>
|
||||
+ Add clerk
|
||||
</Child>
|
||||
{shopClerks &&
|
||||
shopClerks.map((key, index) => (
|
||||
<Child key={index}>
|
||||
{shopClerks[index].username}
|
||||
<button
|
||||
onClick={() =>
|
||||
removeConnectedGuestSides(
|
||||
guestSides[index][3]
|
||||
)
|
||||
}
|
||||
>
|
||||
remove
|
||||
</button>
|
||||
</Child>
|
||||
))}
|
||||
</Child>
|
||||
<Child onClick={() => setModal("payment_option")}>
|
||||
payment options
|
||||
</Child>
|
||||
</Child>
|
||||
</>
|
||||
)}
|
||||
{user.username !== undefined &&
|
||||
((user.userId == shopOwnerId && user.roleId === 1) ||
|
||||
(user.cafeId == shopId && user.roleId === 2)) && (
|
||||
<Child onClick={() => setModal("update_stock")}>
|
||||
update stock
|
||||
</Child>
|
||||
)}
|
||||
{user.username !== undefined &&
|
||||
user.roleId == 2 &&
|
||||
user.cafeId == shopId && (
|
||||
user.cafeId == shopId &&
|
||||
user.roleId === 2 && (
|
||||
<Child hasChildren>
|
||||
connected guest sides
|
||||
<Child onClick={goToGuestSideLogin}>+ Add guest side</Child>
|
||||
{guestSides &&
|
||||
guestSides.map((key, index) => (
|
||||
<Child key={index}>
|
||||
guest side {index + 1}
|
||||
<button
|
||||
onClick={() =>
|
||||
removeConnectedGuestSides(guestSides[index][3])
|
||||
}
|
||||
>
|
||||
remove
|
||||
</button>
|
||||
{shopName}
|
||||
<Child onClick={() => setModal("update_stock")}>
|
||||
update stock
|
||||
</Child>
|
||||
{user.username !== undefined &&
|
||||
user.roleId == 2 &&
|
||||
user.cafeId == shopId && (
|
||||
<Child hasChildren>
|
||||
connected guest sides
|
||||
<Child onClick={goToGuestSideLogin}>
|
||||
+ Add guest side
|
||||
</Child>
|
||||
{guestSides &&
|
||||
guestSides.map((key, index) => (
|
||||
<Child key={index}>
|
||||
guest side {index + 1}
|
||||
<button
|
||||
onClick={() =>
|
||||
removeConnectedGuestSides(
|
||||
guestSides[index][3]
|
||||
)
|
||||
}
|
||||
>
|
||||
remove
|
||||
</button>
|
||||
</Child>
|
||||
))}
|
||||
</Child>
|
||||
))}
|
||||
)}
|
||||
</Child>
|
||||
)}
|
||||
{user.username !== undefined && (
|
||||
|
||||
@@ -58,12 +58,22 @@ export default function ItemType({
|
||||
className={styles["item-type-image"]}
|
||||
/>
|
||||
{blank && (
|
||||
<input
|
||||
type="file"
|
||||
accept="image/*"
|
||||
className={styles["item-type-image-input"]}
|
||||
onChange={handleImageChange}
|
||||
/>
|
||||
<div className={styles["item-type-image-container"]}>
|
||||
<input
|
||||
type="file"
|
||||
accept="image/*"
|
||||
className={styles["item-type-image-input"]}
|
||||
onChange={handleImageChange}
|
||||
id="image-input"
|
||||
/>
|
||||
Click to add image
|
||||
<label
|
||||
htmlFor="image-input"
|
||||
className={styles["item-type-image-text"]}
|
||||
>
|
||||
Click to add image
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<input
|
||||
|
||||
@@ -41,16 +41,24 @@
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.item-type-image-input {
|
||||
.item-type-image-container {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.item-type-image-input {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.item-type-create {
|
||||
position: absolute;
|
||||
top: 80%; /* Position below the input */
|
||||
top: 76%; /* Position below the input */
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
margin-top: 10px; /* Space between input and button */
|
||||
|
||||
@@ -19,12 +19,7 @@ const ItemTypeLister = ({ shopId, shopOwnerId, user, itemTypes }) => {
|
||||
<div className="item-type-lister">
|
||||
<div className="item-type-list">
|
||||
{itemTypes && itemTypes.length > 1 && (
|
||||
<ItemType
|
||||
name={"All"}
|
||||
imageUrl={
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAY1BMVEX///8BAQEEBAT09PT8/PzFxcWGhobu7u7R0dHLy8uoqKhTU1N7e3tXV1fIyMguLi7d3d08PDyenp41NTWBgYF1dXVHR0dMTEwTExPj4+O6urrp6emWlpasrKy2trZeXl4aGhrSJRZxAAADF0lEQVR4nO3Zi3aiMBCAYQIR71VbtXft+z/lJoFigAkNbYHdPf/X3VPqGeMkwdxIEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT0dGBVaSOe5vuV/4giqR1mXOPXL6M1X4r9Cn5l+kqCx3R2Nq7igjWPYoeWjbPkpg09LdiJ/dyPK3P22O+iIid5ZvtebvJZxGxi/y4Pa9Px5efJvh99i56fVM3q+4RJFv5seHeseVqP/btdYDsY5hE7nZVGqn5/7jvqOHiUASVDsE+NyXsH5UfvLub4qtoP/Hd5lEkYn+Zf+Fb9d7lXAa73/fB2KUryytZvQ9Qgy9pm3TqNbW7WAai72udojqruKwq5sdOMJ4ub51SXNnrp2cxdqH8YHcd7PHnp7J+foebphu9inMl+pAyyQ5i7KE13Nj3ftQ6sDIfvkoNef22U59fmoswKqzaCTurRqz942ILaZZs/j6OVrPS805o6dS8dG3Uz65fAhVUqrG6MROFvkpdaF7ZjT1nvAj5Fm2/b1VxpsSszc+s2d96r+rf2Fv02FP/SeoSl9ildZfmUtLulbxV7kW6+Z3TOBWrVBVqWbdiN3LKxqYVuxbj3CeNUS2PON45D80+zLbBGm6z5lDzEIg0Hzdm9ZIkPHioXTN0/hiMPbfmgF0wlj78be5TxVz+l+/hSZ7vVXMstXuh7rFU14IvwaYbeyztmg/rd6mdD8UZLm3Nhzo8H6rR50N5TWN+rllz2dZjTZPYNU0qr2nkNf2AOtalPleBjnVpy0Uaw8TFwdCkvUVq9xaC6L2F9SG3xuh7C11uVG91c20fuT9UX+wPG7vlNLy1HtDnHr/KojORnnv81LtVXbmT7PHdOU119FL8Crd0/3Mav+RJzmnks7bwAbx/1pb+C2dthZ+cl4aO9l0prfPSCQ/2izPvzQBn3pupz7wL3vOFqEczsc8tkuSveW5RinqcJF/Lwf7TxsmfPcWmoIWrUGjt+eF3Uvolfdq3Pg71ehsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACASfwBIesXINu4PFgAAAAASUVORK5CYII="
|
||||
}
|
||||
/>
|
||||
<ItemType name={"All"} imageUrl={"uploads/1718732420960.png"} />
|
||||
)}
|
||||
{itemTypes &&
|
||||
itemTypes.map(
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import React from "react";
|
||||
import styles from "./Modal.module.css";
|
||||
import TablesPage from "./TablesPage.js";
|
||||
import PaymentOptions from "./PaymentOptions.js";
|
||||
import TableMaps from "../components/TableMaps";
|
||||
import Transactions from "../pages/Transactions";
|
||||
import Transaction_pending from "../pages/Transaction_pending";
|
||||
import Transaction_confirmed from "../pages/Transaction_confirmed";
|
||||
import Transaction_success from "../pages/Transaction_success";
|
||||
import Transaction_failed from "../pages/Transaction_failed";
|
||||
import MaterialList from "../pages/MaterialList.js";
|
||||
import MaterialMutationsPage from "../pages/MaterialMutationsPage.js";
|
||||
|
||||
const Modal = ({ shopId, isOpen, onClose, modalContent }) => {
|
||||
const Modal = ({ shop, isOpen, onClose, modalContent }) => {
|
||||
if (!isOpen) return null;
|
||||
|
||||
// Function to handle clicks on the overlay
|
||||
@@ -30,16 +32,24 @@ const Modal = ({ shopId, isOpen, onClose, modalContent }) => {
|
||||
<button onClick={onClose} className={styles.closeButton}>
|
||||
×
|
||||
</button>
|
||||
{modalContent === "edit_tables" && <TablesPage shopId={shopId} />}
|
||||
{modalContent === "edit_tables" && <TablesPage shop={shop} />}
|
||||
{modalContent === "new_transaction" && (
|
||||
<Transactions propsShopId={shopId} />
|
||||
<Transactions propsShopId={shop.cafeId} />
|
||||
)}{" "}
|
||||
{modalContent === "transaction_pending" && <Transaction_pending />}
|
||||
{modalContent === "transaction_confirmed" && (
|
||||
<Transaction_confirmed paymentUrl={shop.qrPayment} />
|
||||
)}
|
||||
{modalContent === "transaction_success" && <Transaction_success />}
|
||||
{modalContent === "transaction_failed" && <Transaction_failed />}
|
||||
{modalContent === "add_material" && <MaterialList cafeId={shopId} />}
|
||||
{modalContent === "payment_option" && (
|
||||
<PaymentOptions paymentUrl={shop.qrPayment} shopId={shop.cafeId} />
|
||||
)}
|
||||
{modalContent === "add_material" && (
|
||||
<MaterialList cafeId={shop.cafeId} />
|
||||
)}
|
||||
{modalContent === "update_stock" && (
|
||||
<MaterialMutationsPage cafeId={shopId} />
|
||||
<MaterialMutationsPage cafeId={shop.cafeId} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
165
src/components/PaymentOptions.js
Normal file
165
src/components/PaymentOptions.js
Normal file
@@ -0,0 +1,165 @@
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import jsQR from "jsqr"; // Import jsQR library
|
||||
import { getImageUrl } from "../helpers/itemHelper";
|
||||
import { saveCafeDetails } from "../helpers/cafeHelpers"; // Import the helper function
|
||||
|
||||
const SetPaymentQr = ({
|
||||
isConfigure,
|
||||
tableNo,
|
||||
qrCodeUrl,
|
||||
paymentUrl,
|
||||
initialQrPosition,
|
||||
initialQrSize,
|
||||
handleQrSave,
|
||||
shopId, // Pass cafeId as a prop to identify which cafe to update
|
||||
}) => {
|
||||
const [qrPosition, setQrPosition] = useState(initialQrPosition);
|
||||
const [qrSize, setQrSize] = useState(initialQrSize);
|
||||
const [qrPayment, setQrPayment] = useState(getImageUrl(paymentUrl));
|
||||
const [qrCodeDetected, setQrCodeDetected] = useState(false);
|
||||
const qrPaymentInputRef = useRef(null);
|
||||
const overlayTextRef = useRef(null);
|
||||
const qrCodeContainerRef = useRef(null);
|
||||
|
||||
// Use useEffect to detect QR code after qrPayment updates
|
||||
useEffect(() => {
|
||||
if (qrPayment) {
|
||||
detectQRCodeFromContainer();
|
||||
}
|
||||
}, [qrPayment]);
|
||||
|
||||
const handleFileChange = (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const newqrPayment = URL.createObjectURL(file); // Create a temporary URL for display
|
||||
setQrPayment(newqrPayment);
|
||||
}
|
||||
};
|
||||
|
||||
const detectQRCodeFromContainer = () => {
|
||||
const container = qrCodeContainerRef.current;
|
||||
const canvas = document.createElement("canvas");
|
||||
const context = canvas.getContext("2d");
|
||||
|
||||
// Create an image element to load the background image
|
||||
const img = new Image();
|
||||
img.crossOrigin = "Anonymous"; // Handle CORS if needed
|
||||
img.onload = () => {
|
||||
// Set canvas size
|
||||
canvas.width = container.offsetWidth;
|
||||
canvas.height = container.offsetHeight;
|
||||
|
||||
// Draw image on canvas
|
||||
context.drawImage(img, 0, 0, canvas.width, canvas.height);
|
||||
|
||||
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
|
||||
const qrCode = jsQR(imageData.data, canvas.width, canvas.height);
|
||||
|
||||
if (qrCode) {
|
||||
setQrCodeDetected(true);
|
||||
console.log("QR Code detected:", qrCode.data);
|
||||
} else {
|
||||
setQrCodeDetected(false);
|
||||
console.log("No QR Code detected");
|
||||
}
|
||||
};
|
||||
img.src = qrPayment; // Load the image URL
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
const qrPaymentFile = qrPaymentInputRef.current.files[0]; // Get the selected file for qrPayment
|
||||
|
||||
// Prepare the details object
|
||||
const details = {
|
||||
qrPosition,
|
||||
qrSize,
|
||||
qrPaymentFile, // Include qrPayment file
|
||||
};
|
||||
|
||||
// Call saveCafeDetails function with the updated details object
|
||||
saveCafeDetails(shopId, details)
|
||||
.then((response) => {
|
||||
console.log("Cafe details saved:", response);
|
||||
// handleQrSave(qrPosition, qrSize, qrPayment);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error saving cafe details:", error);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
id="qr-code-container"
|
||||
ref={qrCodeContainerRef}
|
||||
style={{
|
||||
position: "relative",
|
||||
width: "300px",
|
||||
height: "300px",
|
||||
background: `center center / contain no-repeat url(${qrPayment})`,
|
||||
backgroundSize: "contain",
|
||||
overflow: "hidden",
|
||||
border: "1px solid #ddd",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
ref={overlayTextRef}
|
||||
style={styles.overlayText}
|
||||
onClick={() => qrPaymentInputRef.current.click()}
|
||||
>
|
||||
Click To Change Image
|
||||
</div>
|
||||
<input
|
||||
type="file"
|
||||
accept="image/*"
|
||||
ref={qrPaymentInputRef}
|
||||
style={{ display: "none" }}
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ marginTop: "20px" }}>
|
||||
{qrCodeDetected ? <p>QR Code Detected</p> : <p>No QR Code Detected</p>}
|
||||
<div style={{ marginTop: "20px" }}>
|
||||
<button
|
||||
onClick={handleSave}
|
||||
style={{
|
||||
padding: "10px 20px",
|
||||
fontSize: "16px",
|
||||
backgroundColor: "#28a745",
|
||||
color: "#fff",
|
||||
border: "none",
|
||||
borderRadius: "4px",
|
||||
cursor: "pointer",
|
||||
transition: "background-color 0.3s",
|
||||
}}
|
||||
onMouseOver={(e) =>
|
||||
(e.currentTarget.style.backgroundColor = "#218838")
|
||||
}
|
||||
onMouseOut={(e) =>
|
||||
(e.currentTarget.style.backgroundColor = "#28a745")
|
||||
}
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
overlayText: {
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
||||
color: "#fff",
|
||||
padding: "10px",
|
||||
borderRadius: "5px",
|
||||
cursor: "pointer",
|
||||
},
|
||||
// Other styles omitted for brevity
|
||||
};
|
||||
|
||||
export default SetPaymentQr;
|
||||
@@ -1,5 +1,7 @@
|
||||
import React, { useState, useRef } from "react";
|
||||
import html2canvas from "html2canvas";
|
||||
import { getImageUrl } from "../helpers/itemHelper";
|
||||
import { saveCafeDetails } from "../helpers/cafeHelpers"; // Import the helper function
|
||||
|
||||
const QRCodeWithBackground = ({
|
||||
isConfigure,
|
||||
@@ -9,11 +11,12 @@ const QRCodeWithBackground = ({
|
||||
initialQrPosition,
|
||||
initialQrSize,
|
||||
handleQrSave,
|
||||
shopId, // Pass cafeId as a prop to identify which cafe to update
|
||||
}) => {
|
||||
const [qrPosition, setQrPosition] = useState(initialQrPosition);
|
||||
const [qrSize, setQrSize] = useState(initialQrSize);
|
||||
const [bgImage, setBgImage] = useState(backgroundUrl);
|
||||
const fileInputRef = useRef(null);
|
||||
const [bgImage, setBgImage] = useState(getImageUrl(backgroundUrl)); // URL or File
|
||||
const qrBackgroundInputRef = useRef(null);
|
||||
const overlayTextRef = useRef(null);
|
||||
|
||||
const handlePositionChange = (e) => {
|
||||
@@ -31,13 +34,30 @@ const QRCodeWithBackground = ({
|
||||
const handleFileChange = (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const newBgImage = URL.createObjectURL(file);
|
||||
const newBgImage = URL.createObjectURL(file); // Create a temporary URL for display
|
||||
setBgImage(newBgImage);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
handleQrSave(qrPosition, qrSize, bgImage);
|
||||
const qrBackgroundFile = qrBackgroundInputRef.current.files[0]; // Get the selected file for qrBackground
|
||||
|
||||
// Prepare the details object
|
||||
const details = {
|
||||
qrPosition,
|
||||
qrSize,
|
||||
qrBackgroundFile, // Include qrBackground file
|
||||
};
|
||||
|
||||
// Call saveCafeDetails function with the updated details object
|
||||
saveCafeDetails(shopId, details)
|
||||
.then((response) => {
|
||||
console.log("Cafe details saved:", response);
|
||||
handleQrSave(qrPosition, qrSize, bgImage);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error saving cafe details:", error);
|
||||
});
|
||||
};
|
||||
|
||||
const printQRCode = () => {
|
||||
@@ -118,7 +138,7 @@ const QRCodeWithBackground = ({
|
||||
position: "relative",
|
||||
width: "300px",
|
||||
height: "300px",
|
||||
background: `url(${bgImage}) no-repeat center center`,
|
||||
background: `center center / contain no-repeat url(${bgImage})`,
|
||||
backgroundSize: "contain",
|
||||
overflow: "hidden",
|
||||
border: "1px solid #ddd",
|
||||
@@ -141,7 +161,7 @@ const QRCodeWithBackground = ({
|
||||
<div
|
||||
ref={overlayTextRef}
|
||||
style={styles.overlayText}
|
||||
onClick={() => fileInputRef.current.click()}
|
||||
onClick={() => qrBackgroundInputRef.current.click()}
|
||||
>
|
||||
Click To Change Image
|
||||
</div>
|
||||
@@ -150,7 +170,7 @@ const QRCodeWithBackground = ({
|
||||
<input
|
||||
type="file"
|
||||
accept="image/*"
|
||||
ref={fileInputRef}
|
||||
ref={qrBackgroundInputRef}
|
||||
style={{ display: "none" }}
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
@@ -276,16 +296,15 @@ const QRCodeWithBackground = ({
|
||||
borderRadius: "4px",
|
||||
cursor: "pointer",
|
||||
transition: "background-color 0.3s",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
onMouseOver={(e) =>
|
||||
(e.currentTarget.style.backgroundColor = "#138496")
|
||||
(e.currentTarget.style.backgroundColor = "#117a8b")
|
||||
}
|
||||
onMouseOut={(e) =>
|
||||
(e.currentTarget.style.backgroundColor = "#17a2b8")
|
||||
}
|
||||
>
|
||||
Save Image
|
||||
Save QR Code
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
@@ -293,54 +312,41 @@ const QRCodeWithBackground = ({
|
||||
);
|
||||
};
|
||||
|
||||
// Styles for the configuration labels and inputs
|
||||
const styles = {
|
||||
label: {
|
||||
display: "block",
|
||||
fontSize: "16px",
|
||||
fontWeight: "bold",
|
||||
marginBottom: "5px",
|
||||
overlayText: {
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
||||
color: "#fff",
|
||||
padding: "10px",
|
||||
borderRadius: "5px",
|
||||
cursor: "pointer",
|
||||
},
|
||||
sliderContainer: {
|
||||
marginBottom: "20px",
|
||||
},
|
||||
label: {
|
||||
display: "block",
|
||||
marginBottom: "10px",
|
||||
},
|
||||
sliderWrapper: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "10px",
|
||||
marginTop: "5px",
|
||||
},
|
||||
input: {
|
||||
flex: "1",
|
||||
margin: "0 10px",
|
||||
},
|
||||
value: {
|
||||
fontSize: "16px",
|
||||
minWidth: "50px",
|
||||
textAlign: "right",
|
||||
},
|
||||
labelStart: {
|
||||
fontSize: "14px",
|
||||
marginRight: "10px",
|
||||
},
|
||||
labelEnd: {
|
||||
fontSize: "14px",
|
||||
},
|
||||
fileInput: {
|
||||
marginLeft: "10px",
|
||||
},
|
||||
overlayText: {
|
||||
position: "absolute",
|
||||
fontSize: "70px",
|
||||
backgroundColor: "rgba(0, 0, 0, 0.7)",
|
||||
top: "0",
|
||||
bottom: "0",
|
||||
color: "white",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
cursor: "pointer", // Indicates it's clickable
|
||||
zIndex: 10, // Ensure it appears above other elements
|
||||
value: {
|
||||
marginLeft: "10px",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import QRCodeWithBackground from "./QR"; // Adjust path as needed
|
||||
|
||||
const TableList = ({ shopUrl, tables, onSelectTable, selectedTable }) => {
|
||||
const [initialPos, setInitialPos] = useState({ left: 50, top: 50 });
|
||||
const [initialSize, setInitialSize] = useState(20);
|
||||
const [bgImageUrl, setBgImageUrl] = useState(
|
||||
"https://example.com/your-background-image.png"
|
||||
);
|
||||
const TableList = ({ shop, tables, onSelectTable, selectedTable }) => {
|
||||
const [initialPos, setInitialPos] = useState({
|
||||
left: shop.xposition,
|
||||
top: shop.yposition,
|
||||
});
|
||||
const [initialSize, setInitialSize] = useState(shop.scale);
|
||||
const [bgImageUrl, setBgImageUrl] = useState(shop.qrBackground);
|
||||
const shopUrl = window.location.hostname + "/" + shop.cafeId;
|
||||
|
||||
const generateQRCodeUrl = (tableCode) =>
|
||||
`https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(
|
||||
@@ -51,6 +52,7 @@ const TableList = ({ shopUrl, tables, onSelectTable, selectedTable }) => {
|
||||
<div style={{ marginBottom: "10px" }}>configure</div>
|
||||
{-1 == selectedTable?.tableId && (
|
||||
<QRCodeWithBackground
|
||||
shopId={shop.cafeId}
|
||||
isConfigure={true}
|
||||
handleQrSave={handleQrSave}
|
||||
setInitialPos={setInitialPos}
|
||||
@@ -62,41 +64,43 @@ const TableList = ({ shopUrl, tables, onSelectTable, selectedTable }) => {
|
||||
/>
|
||||
)}
|
||||
</li>
|
||||
{tables
|
||||
.filter((table) => table.tableNo !== 0)
|
||||
.map((table) => (
|
||||
<li
|
||||
key={table.tableId}
|
||||
style={{
|
||||
backgroundColor:
|
||||
table.tableId === selectedTable?.tableId
|
||||
? "lightblue"
|
||||
: "white",
|
||||
marginBottom: "10px",
|
||||
padding: "10px",
|
||||
borderRadius: "4px",
|
||||
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => onSelectTable(table)}
|
||||
>
|
||||
<div style={{ marginBottom: "10px" }}>
|
||||
Table {table.tableNo}
|
||||
</div>
|
||||
{table.tableId === selectedTable?.tableId && (
|
||||
<>
|
||||
<QRCodeWithBackground
|
||||
tableNo={table.tableNo}
|
||||
qrCodeUrl={generateQRCodeUrl(table.tableCode)}
|
||||
backgroundUrl={bgImageUrl}
|
||||
initialQrPosition={initialPos}
|
||||
initialQrSize={initialSize}
|
||||
/>
|
||||
<h5>{shopUrl + "/" + table.tableCode}</h5>
|
||||
</>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
{tables &&
|
||||
tables
|
||||
.filter((table) => table.tableNo !== 0)
|
||||
.map((table) => (
|
||||
<li
|
||||
key={table.tableId}
|
||||
style={{
|
||||
backgroundColor:
|
||||
table.tableId === selectedTable?.tableId
|
||||
? "lightblue"
|
||||
: "white",
|
||||
marginBottom: "10px",
|
||||
padding: "10px",
|
||||
borderRadius: "4px",
|
||||
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => onSelectTable(table)}
|
||||
>
|
||||
<div style={{ marginBottom: "10px" }}>
|
||||
Table {table.tableNo}
|
||||
</div>
|
||||
{table.tableId === selectedTable?.tableId && (
|
||||
<>
|
||||
<QRCodeWithBackground
|
||||
tableNo={table.tableNo}
|
||||
qrCodeUrl={generateQRCodeUrl(table.tableCode)}
|
||||
backgroundUrl={bgImageUrl}
|
||||
initialQrPosition={initialPos}
|
||||
initialQrSize={initialSize}
|
||||
cafeId={shop.cafeId}
|
||||
/>
|
||||
<h5>{shopUrl + "/" + table.tableCode}</h5>
|
||||
</>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { getTables, updateTable, createTable } from "../helpers/tableHelper";
|
||||
import TableCanvas from "./TableCanvas";
|
||||
import TableList from "./TableList";
|
||||
|
||||
const TablesPage = ({ shopId }) => {
|
||||
const TablesPage = ({ shop }) => {
|
||||
const [tables, setTables] = useState([]);
|
||||
const [selectedTable, setSelectedTable] = useState(null);
|
||||
const [newTable, setNewTable] = useState(null);
|
||||
@@ -13,7 +13,8 @@ const TablesPage = ({ shopId }) => {
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const fetchedTables = await getTables(shopId);
|
||||
console.log(shop);
|
||||
const fetchedTables = await getTables(shop.cafeId);
|
||||
setTables(fetchedTables);
|
||||
setOriginalTables(fetchedTables);
|
||||
} catch (error) {
|
||||
@@ -22,7 +23,7 @@ const TablesPage = ({ shopId }) => {
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, [shopId]);
|
||||
}, [shop.cafeId]);
|
||||
|
||||
const handleAddTable = () => {
|
||||
const nextId = Math.random().toString(36).substr(2, 11);
|
||||
@@ -131,7 +132,7 @@ const TablesPage = ({ shopId }) => {
|
||||
const handleSave = async () => {
|
||||
if (newTable) {
|
||||
try {
|
||||
const createdTable = await createTable(shopId, {
|
||||
const createdTable = await createTable(shop.cafeId, {
|
||||
...newTable,
|
||||
tableNo,
|
||||
});
|
||||
@@ -144,7 +145,7 @@ const TablesPage = ({ shopId }) => {
|
||||
}
|
||||
} else if (selectedTable) {
|
||||
try {
|
||||
const updatedTable = await updateTable(shopId, {
|
||||
const updatedTable = await updateTable(shop.cafeId, {
|
||||
...selectedTable,
|
||||
tableNo,
|
||||
});
|
||||
@@ -202,7 +203,7 @@ const TablesPage = ({ shopId }) => {
|
||||
tableNo={tableNo}
|
||||
/> */}
|
||||
<TableList
|
||||
shopUrl={window.location.hostname + "/" + shopId}
|
||||
shop={shop}
|
||||
tables={tables}
|
||||
onSelectTable={handleSelect}
|
||||
selectedTable={selectedTable}
|
||||
|
||||
Reference in New Issue
Block a user