From 39aa56099d78ee126f9ed583bf9a17e51f940ddb Mon Sep 17 00:00:00 2001 From: zadit <75159257+insvrgent@users.noreply.github.com> Date: Wed, 15 Jan 2025 07:53:06 +0700 Subject: [PATCH] ok --- package-lock.json | 3 +- src/components/PaymentOptions.js | 505 +++++------------------ src/components/TablesPage.js | 685 +++++++++++++++++++++++-------- 3 files changed, 620 insertions(+), 573 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8b4e91c..7cd811e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10268,8 +10268,7 @@ "node_modules/html-to-image": { "version": "1.11.11", "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.11.11.tgz", - "integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==", - "license": "MIT" + "integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==" }, "node_modules/html-webpack-plugin": { "version": "5.6.0", diff --git a/src/components/PaymentOptions.js b/src/components/PaymentOptions.js index 2916cbb..d600aca 100644 --- a/src/components/PaymentOptions.js +++ b/src/components/PaymentOptions.js @@ -1,440 +1,167 @@ import React, { useState, useRef, useEffect } from "react"; import jsQR from "jsqr"; import { getImageUrl } from "../helpers/itemHelper"; -import { getTables, updateTable, createTable } from "../helpers/tableHelper"; import { getCafe, saveCafeDetails, setConfirmationStatus, } from "../helpers/cafeHelpers"; +import Switch from "react-switch"; // Import the Switch component -import { toPng } from 'html-to-image'; - -const SetPaymentQr = ({ shop }) => { - const [initialPos, setInitialPos] = useState({ - left: shop.xposition, - top: shop.yposition, - }); - - const [isViewingQR, setIsViewingQR] = useState(false); - const [isConfigFont, setIsConfigFont] = useState(false); - const [fontsize, setfontsize] = useState(shop.fontsize); - const [fontcolor, setfontcolor] = useState(shop.fontcolor); - const [initialFontPos, setInitialFontPos] = useState({ - left: shop.fontxposition, - top: shop.fontyposition, - }); - - const [initialSize, setInitialSize] = useState(shop.scale); - const [bgImageUrl, setBgImageUrl] = useState(getImageUrl(shop.qrBackground)); - const qrBackgroundInputRef = useRef(null); - const shopUrl = window.location.hostname + "/" + shop.cafeId; - - const generateQRCodeUrl = (tableCode) => { - if (tableCode != null) { - return `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent( - shopUrl + "/" + tableCode - )}`; - } else { - return `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent( - shopUrl - )}`; - } - }; - +const SetPaymentQr = ({ shopId, + qrCodeUrl }) => { + const [qrPosition, setQrPosition] = useState([50, 50]); + const [qrSize, setQrSize] = useState(50); + const [qrPayment, setQrPayment] = useState(); + const [qrCodeDetected, setQrCodeDetected] = useState(false); + const [isNeedConfirmationState, setIsNeedConfirmationState] = useState(0); + const qrPaymentInputRef = useRef(null); + const qrCodeContainerRef = useRef(null); + const [cafe, setCafe] = useState({}); const [isConfig, setIsConfig] = useState(false); - const [isConfigQR, setIsConfigQR] = useState(false); - const [isViewTables, setIsViewTables] = useState(false); - - const [tables, setTables] = useState([]); - - const [selectedTable, setSelectedTable] = useState(null); - - const [tableNo, setTableNo] = useState(null); useEffect(() => { - const fetchData = async () => { + const fetchCafe = async () => { try { - console.log(shop); - const fetchedTables = await getTables(shop.cafeId); - setTables(fetchedTables); + const response = await getCafe(shopId); + setCafe(response); + setQrPayment(getImageUrl(response.qrPayment)); + console.log(response.needsConfirmation); + + setIsNeedConfirmationState(response.needsConfirmation === true ? 1 : 0); // Set state based on fetched data + setQrPosition([response.xposition, response.yposition]); + setQrSize(response.scale); } catch (error) { - console.error("Error fetching tables:", error); + console.error("Error fetching cafe:", error); } }; + fetchCafe(); + }, [shopId]); - fetchData(); - }, [shop.cafeId]); - - const handleSave = () => { - const qrBackgroundFile = qrBackgroundInputRef.current.files[0]; // Get the selected file for qrBackground - - // Prepare the details object - const details = { - qrSize: initialSize, - qrPosition: initialPos, - qrBackgroundFile, - fontsize, - fontcolor, - fontPosition: initialFontPos, - }; - - // Call saveCafeDetails function with the updated details object - saveCafeDetails(shop.cafeId, details) - .then((response) => { - console.log("Cafe details saved:", response); - }) - .catch((error) => { - console.error("Error saving cafe details:", error); - }); - }; - - - const handlePositionChange = (e) => { - const { name, value } = e.target; - setInitialPos((prevPosition) => ({ - ...prevPosition, - [name]: parseFloat(value).toFixed(2), - })); - }; - - const handleFontPositionChange = (e) => { - const { name, value } = e.target; - setInitialFontPos((prevPosition) => ({ - ...prevPosition, - [name]: parseFloat(value).toFixed(2), - })); - }; - - const handleSizeChange = (e) => { - setInitialSize(parseFloat(e.target.value).toFixed(2)); - }; - - const handleFontSizeChange = (e) => { - setfontsize(parseFloat(e.target.value).toFixed(2)); - }; + // Detect QR code when qrPayment updates + useEffect(() => { + if (qrPayment) { + detectQRCodeFromContainer(); + } + }, [qrPayment]); + // Handle file input change const handleFileChange = (e) => { const file = e.target.files[0]; if (file) { - const newBgImage = URL.createObjectURL(file); // Create a temporary URL for display - setBgImageUrl(newBgImage); + const newqrPayment = URL.createObjectURL(file); + setQrPayment(newqrPayment); } }; - const handleCreate = async () => { - // if (newTable) { - try { - const createdTable = await createTable(shop.cafeId, { - // ...newTable, - tableNo, - }); - setTables([...tables, createdTable]); - setTableNo(""); - } catch (error) { - console.error("Error creating table:", error); + // Detect QR code from the container + const detectQRCodeFromContainer = () => { + const container = qrCodeContainerRef.current; + const canvas = document.createElement("canvas"); + const context = canvas.getContext("2d"); + const img = new Image(); + img.crossOrigin = "Anonymous"; + img.onload = () => { + canvas.width = container.offsetWidth; + canvas.height = container.offsetHeight; + 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); + setQrCodeDetected(!!qrCode); + if (qrCode) { + console.log("QR Code detected:", qrCode.data); } + }; + img.src = qrPayment; + }; + + // Save cafe details + const handleSave = async () => { + const qrPaymentFile = qrPaymentInputRef.current.files[0]; + const details = { + qrPosition, + qrSize, + qrPaymentFile, + }; + + try { + const response = await saveCafeDetails(cafe.cafeId, details); + console.log("Cafe details saved:", response); + } catch (error) { + console.error("Error saving cafe details:", error); + } + + try { + const response = await setConfirmationStatus(cafe.cafeId, isNeedConfirmationState === 1); + setIsNeedConfirmationState(response.needsConfirmation ? 1 : 0); // Update state after saving + } catch (error) { + console.error(error); + setIsNeedConfirmationState(cafe.needsConfirmation ? 1 : 0); // Fallback to initial value + } + }; + + // Handle Switch toggle + const handleChange = (checked) => { + setIsNeedConfirmationState(checked ? 1 : 0); // Toggle state based on the switch + }; + + const handleError = () => { + setQrPayment('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSPsNr0TPq8dHT3nBwDQ6OHQQTrqzVFoeBOmuWfgyErrLbJi6f6CnnYhpNHEvkJ_2X-kyI&usqp=CAU'); // Set your fallback image here }; - function downloadQrCodeContainer({ selectedTable, shop }) { - const node = document.getElementById('qr-code-container'); - - if (!node) return; - - const isTableSelected = selectedTable != null; - - toPng(node, { pixelRatio: 2 }) // Adjust pixel ratio for higher resolution - .then((dataUrl) => { - const link = document.createElement('a'); - link.href = dataUrl; - - // Set the file name based on whether selectedTable exists - link.download = isTableSelected - ? `QR Meja (${selectedTable.tableNo}).png` - : `QR ${shop.name}.png`; - - link.click(); - }) - .catch((err) => { - console.error('Could not download the image', err); - }) - } - - return (
-

QR kedai dan meja

- +

Konfigurasi pembayaran

qrPaymentInputRef.current.click()} style={{ - background: `center center / contain no-repeat url(${bgImageUrl})`, - backgroundSize: "contain", - border: "1px solid #ddd", - ...styles.qrCodeContainer, - backgroundImage: `url(${bgImageUrl})`, + backgroundImage: `url(${qrPayment})`, backgroundPosition: "center", backgroundRepeat: "no-repeat", backgroundSize: "contain", }} > - QR Code -
50 ? -1 : 1})`, - position: "absolute", - fontSize: `${fontsize * 3}%`, - left: `${initialFontPos.left}%`, - top: `${initialFontPos.top}%`, - textAlign: initialFontPos.left > 50 ? 'right' : 'left' - }}> -

50 ? -1 : 1})`, - width: '200%', - lineHeight: 0, - fontFamily: 'Plus Jakarta Sans', - color: fontcolor - }} >{selectedTable == null ? (isConfigFont ? 'Nomor meja' : '') : selectedTable.tableNo}

-
- {!isViewingQR ? - <>

Klik untuk ganti background

-

{setIsConfig(!isConfig); setIsConfigQR(false); setIsConfigFont(false)}}> {isConfig ? '˅' : '˃'} Konfigurasi

-
qrBackgroundInputRef.current.click()} style={styles.uploadButton}>Ganti
+ {qrCodeDetected && qrPayment !== 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSPsNr0TPq8dHT3nBwDQ6OHQQTrqzVFoeBOmuWfgyErrLbJi6f6CnnYhpNHEvkJ_2X-kyI&usqp=CAU' ?

QR terdeteksi

:

Tidak ada qr terdeteksi

} + {qrCodeDetected && qrPayment !== 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSPsNr0TPq8dHT3nBwDQ6OHQQTrqzVFoeBOmuWfgyErrLbJi6f6CnnYhpNHEvkJ_2X-kyI&usqp=CAU' ?
qrPaymentInputRef.current.click()} style={styles.uploadButton}>Ganti
:
qrPaymentInputRef.current.click()} style={styles.uploadButton}>Unggah
}
- {isConfig && -
-

{ setIsConfigQR(!isConfigQR); setIsConfigFont(false) }}> - {isConfigQR ? '˅' : '˃'} Konfigurasi QR -

- {isConfigQR && <> -
- -
-
- -
-
- -
- } - -

{ setIsConfigFont(!isConfigFont); setIsConfigQR(false) }}> - {isConfigFont ? '˅' : '˃'} Konfigurasi nomor -

- {isConfigFont && ( - <> -
- -
-
- -
-
- -
-
- -
- - )} - - -
- } -

setIsViewTables(!isViewTables)}> - {isViewTables ? '˅' : '˃'} Daftar meja +

+ Nyalakan agar kasir memeriksa kembali ketersediaan produk sebelum pelanggan membayar.

- - {isViewTables && -
-
- setTableNo(e.target.value)} value={tableNo}/> -
Buat meja
-
- {tables && tables - .filter((table) => table.tableNo !== 0) - .map((table) => ( -
  • setSelectedTable(selectedTable == table ? null : table)} - > -
    - {table.tableNo} -
    -
  • - )) - } -
    - } +
    +
    -
    - : - <> -
    -

    QR ini akan menjadi identifikasi bahwa pelanggan memesan dari {selectedTable? `(${selectedTable?.tableNo})` : 'link kafe ini. Untuk mengantarkan pelanggan ke meja yang teridentifikasi, anda perlu membuat meja.'}

    -
    -
    - -
    -
    -

    setIsViewingQR(false)} > - Kembali -

    -
    - - }
    ); }; @@ -442,10 +169,6 @@ const SetPaymentQr = ({ shop }) => { // Styles const styles = { container: { - overflowY: 'auto', - overflowX: 'hidden', - maxHeight: '100%', - width: '100%', backgroundColor: "white", padding: "20px", borderRadius: "8px", @@ -469,7 +192,6 @@ const styles = { uploadMessage: { fontWeight: 600, textAlign: "left", - fontSize: "15px" }, uploadButton: { paddingRight: '10px', @@ -484,7 +206,6 @@ const styles = { }, resultMessage: { marginTop: "-24px", - marginBottom: "10px", textAlign: "left", display: 'flex', justifyContent: 'space-between' @@ -492,18 +213,9 @@ const styles = { buttonContainer: { marginTop: "20px", textAlign: "left", - display: 'flex', - justifyContent: 'space-evenly' - }, - backButtonContainer: { - marginTop: "2px", - marginBottom: "-10px", - textAlign: "left", - display: 'flex', - justifyContent: 'space-evenly' }, saveButton: { - padding: "10px 15px", + padding: "10px 20px", fontSize: "16px", backgroundColor: "#28a745", color: "#fff", @@ -514,10 +226,11 @@ const styles = { }, switchContainer: { textAlign: "left", - marginTop: '-15px' }, description: { margin: "10px 0", + fontSize: "14px", + color: "#666", }, sliderContainer: { marginBottom: "20px", diff --git a/src/components/TablesPage.js b/src/components/TablesPage.js index 30fdd7a..dbd9c2d 100644 --- a/src/components/TablesPage.js +++ b/src/components/TablesPage.js @@ -1,14 +1,56 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useRef, useEffect } from "react"; +import jsQR from "jsqr"; +import { getImageUrl } from "../helpers/itemHelper"; import { getTables, updateTable, createTable } from "../helpers/tableHelper"; -import TableCanvas from "./TableCanvas"; -import TableList from "./TableList"; +import { + getCafe, + saveCafeDetails, + setConfirmationStatus, +} from "../helpers/cafeHelpers"; + +import { toPng } from 'html-to-image'; + +const SetPaymentQr = ({ shop }) => { + const [initialPos, setInitialPos] = useState({ + left: shop.xposition, + top: shop.yposition, + }); + + const [isViewingQR, setIsViewingQR] = useState(false); + const [isConfigFont, setIsConfigFont] = useState(false); + const [fontsize, setfontsize] = useState(shop.fontsize); + const [fontcolor, setfontcolor] = useState(shop.fontcolor); + const [initialFontPos, setInitialFontPos] = useState({ + left: shop.fontxposition, + top: shop.fontyposition, + }); + + const [initialSize, setInitialSize] = useState(shop.scale); + const [bgImageUrl, setBgImageUrl] = useState(getImageUrl(shop.qrBackground)); + const qrBackgroundInputRef = useRef(null); + const shopUrl = window.location.hostname + "/" + shop.cafeId; + + const generateQRCodeUrl = (tableCode) => { + if (tableCode != null) { + return `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent( + shopUrl + "/" + tableCode + )}`; + } else { + return `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent( + shopUrl + )}`; + } + }; + + const [isConfig, setIsConfig] = useState(false); + const [isConfigQR, setIsConfigQR] = useState(false); + const [isViewTables, setIsViewTables] = useState(false); -const TablesPage = ({ shop }) => { const [tables, setTables] = useState([]); + const [selectedTable, setSelectedTable] = useState(null); - const [newTable, setNewTable] = useState(null); - const [originalTables, setOriginalTables] = useState([]); - const [tableNo, setTableNo] = useState(""); // State for table name + + const [tableNo, setTableNo] = useState(null); useEffect(() => { const fetchData = async () => { @@ -16,7 +58,6 @@ const TablesPage = ({ shop }) => { console.log(shop); const fetchedTables = await getTables(shop.cafeId); setTables(fetchedTables); - setOriginalTables(fetchedTables); } catch (error) { console.error("Error fetching tables:", error); } @@ -25,111 +66,63 @@ const TablesPage = ({ shop }) => { fetchData(); }, [shop.cafeId]); - const handleAddTable = () => { - const nextId = Math.random().toString(36).substr(2, 11); + const handleSave = () => { + const qrBackgroundFile = qrBackgroundInputRef.current.files[0]; // Get the selected file for qrBackground - setTables(originalTables); - setNewTable({ - tableId: nextId, - xposition: 100, - yposition: 100, - tableNo: nextId, - }); - setSelectedTable(null); - setTableNo(""); // Reset table name - }; + // Prepare the details object + const details = { + qrSize: initialSize, + qrPosition: initialPos, + qrBackgroundFile, + fontsize, + fontcolor, + fontPosition: initialFontPos, + }; - const moveTable = (direction) => { - if (!selectedTable && !newTable) return; - - const moveAmount = 10; - const { xposition, yposition } = selectedTable || newTable; - let newX = xposition; - let newY = yposition; - - switch (direction) { - case "left": - newX = xposition - moveAmount; - break; - case "right": - newX = xposition + moveAmount; - break; - case "up": - newY = yposition - moveAmount; - break; - case "down": - newY = yposition + moveAmount; - break; - default: - break; - } - - if (newTable) { - setNewTable({ - ...newTable, - xposition: newX, - yposition: newY, - }); - } else if (selectedTable) { - setTables( - tables.map((table) => - table.tableId === selectedTable.tableId - ? { ...table, xposition: newX, yposition: newY } - : table - ) - ); - setSelectedTable({ - ...selectedTable, - xposition: newX, - yposition: newY, + // Call saveCafeDetails function with the updated details object + saveCafeDetails(shop.cafeId, details) + .then((response) => { + console.log("Cafe details saved:", response); + }) + .catch((error) => { + console.error("Error saving cafe details:", error); }); + }; + + + const handlePositionChange = (e) => { + const { name, value } = e.target; + setInitialPos((prevPosition) => ({ + ...prevPosition, + [name]: parseFloat(value).toFixed(2), + })); + }; + + const handleFontPositionChange = (e) => { + const { name, value } = e.target; + setInitialFontPos((prevPosition) => ({ + ...prevPosition, + [name]: parseFloat(value).toFixed(2), + })); + }; + + const handleSizeChange = (e) => { + setInitialSize(parseFloat(e.target.value).toFixed(2)); + }; + + const handleFontSizeChange = (e) => { + setfontsize(parseFloat(e.target.value).toFixed(2)); + }; + + const handleFileChange = (e) => { + const file = e.target.files[0]; + if (file) { + const newBgImage = URL.createObjectURL(file); // Create a temporary URL for display + setBgImageUrl(newBgImage); } }; - const handleSelectTable = (event) => { - const canvas = event.target; - const rect = canvas.getBoundingClientRect(); - const x = event.clientX - rect.left; - const y = event.clientY - rect.top; - - const clickedTable = tables.find( - (table) => - x >= table.xposition && - x <= table.xposition + 40 && - y >= table.yposition && - y <= table.yposition + 30 - ); - - if (clickedTable) { - setSelectedTable(clickedTable); - setNewTable(null); - setTableNo(clickedTable.tableNo || ""); // Set table name if exists - } else if (newTable) { - setSelectedTable(newTable); - setTableNo(newTable.tableNo || ""); // Set table name if exists - } - }; - - const handleSelect = (table) => { - console.log(table); - setSelectedTable(null); - setSelectedTable(table); - setNewTable(null); - setTables(originalTables); - if (table.tableNo != 0) - setTableNo(table.tableNo || ""); // Set table name if exists - else setTableNo(0); - console.log(table.tableNo); - }; - - const handleCancel = () => { - setSelectedTable(null); - setNewTable(null); - setTables(originalTables); - setTableNo(""); // Reset table name - }; - - const handleSave = async () => { + const handleCreate = async () => { // if (newTable) { try { const createdTable = await createTable(shop.cafeId, { @@ -137,81 +130,423 @@ const TablesPage = ({ shop }) => { tableNo, }); setTables([...tables, createdTable]); - setOriginalTables([...tables, createdTable]); - setNewTable(null); - setTableNo(""); // Reset table name + setTableNo(""); } catch (error) { console.error("Error creating table:", error); } - // } else if (selectedTable) { - // try { - // const updatedTable = await updateTable(shop.cafeId, { - // ...selectedTable, - // tableNo, - // }); - // setTables( - // tables.map((table) => - // table.tableId === updatedTable.tableId ? updatedTable : table - // ) - // ); - // setOriginalTables( - // tables.map((table) => - // table.tableId === updatedTable.tableId ? updatedTable : table - // ) - // ); - // setSelectedTable(null); - // setTableNo(""); // Reset table name - // } catch (error) { - // console.error("Error updating table:", error); - // } - // } - }; - - const handleSetTableNo = (event) => { - const newValue = event.target.value; - // Prevent setting value to '0' or starting with '0' - if (newValue === "" || /^[1-9][0-9]*$/.test(newValue)) { - setTableNo(newValue); - } }; + function downloadQrCodeContainer({ selectedTable, shop }) { + const node = document.getElementById('qr-code-container'); + + if (!node) return; + + const isTableSelected = selectedTable != null; + + toPng(node, { pixelRatio: 2 }) // Adjust pixel ratio for higher resolution + .then((dataUrl) => { + const link = document.createElement('a'); + link.href = dataUrl; + + // Set the file name based on whether selectedTable exists + link.download = isTableSelected + ? `QR Meja (${selectedTable.tableNo}).png` + : `QR ${shop.name}.png`; + + link.click(); + }) + .catch((err) => { + console.error('Could not download the image', err); + }) + } + + return ( -
    - {/* */} - +
    +

    QR kedai dan meja

    + +
    + QR Code +
    50 ? -1 : 1})`, + position: "absolute", + fontSize: `${fontsize * 3}%`, + left: `${initialFontPos.left}%`, + top: `${initialFontPos.top}%`, + textAlign: initialFontPos.left > 50 ? 'right' : 'left' + }}> +

    50 ? -1 : 1})`, + width: '200%', + lineHeight: 0, + fontFamily: 'Plus Jakarta Sans', + color: fontcolor + }} >{selectedTable == null ? (isConfigFont ? 'Nomor meja' : '') : selectedTable.tableNo}

    +
    + +
    + {!isViewingQR ? + <> +
    +

    Klik untuk ganti background

    +
    +
    +

    {setIsConfig(!isConfig); setIsConfigQR(false); setIsConfigFont(false)}}> {isConfig ? '˅' : '˃'} Konfigurasi

    +
    qrBackgroundInputRef.current.click()} style={styles.changeButton}>Ganti
    +
    +
    + {isConfig && +
    +

    { setIsConfigQR(!isConfigQR); setIsConfigFont(false) }}> + {isConfigQR ? '˅' : '˃'} Konfigurasi QR +

    + {isConfigQR && <> +
    + +
    +
    + +
    +
    + +
    + } + +

    { setIsConfigFont(!isConfigFont); setIsConfigQR(false) }}> + {isConfigFont ? '˅' : '˃'} Konfigurasi nomor +

    + {isConfigFont && ( + <> +
    + +
    +
    + +
    +
    + +
    +
    + +
    + + )} + + +
    + } +

    setIsViewTables(!isViewTables)}> + {isViewTables ? '˅' : '˃'} Daftar meja +

    + + {isViewTables && +
    +
    + setTableNo(e.target.value)} value={tableNo}/> +
    Buat meja
    +
    + {tables && tables + .filter((table) => table.tableNo !== 0) + .map((table) => ( +
  • setSelectedTable(selectedTable == table ? null : table)} + > +
    + {table.tableNo} +
    +
  • + )) + } +
    + } +
    +
    + + +
    + : + <> +
    +

    QR ini akan menjadi identifikasi bahwa pelanggan memesan dari {selectedTable? `(${selectedTable?.tableNo})` : 'link kafe ini. Untuk mengantarkan pelanggan ke meja yang teridentifikasi, anda perlu membuat meja.'}

    +
    +
    + +
    +
    +

    setIsViewingQR(false)} > + Kembali +

    +
    + + }
    ); }; -export default TablesPage; +// Styles +const styles = { + container: { + overflowY: 'auto', + overflowX: 'hidden', + maxHeight: '80vh', + width: '100%', + backgroundColor: "white", + padding: "20px", + borderRadius: "8px", + boxShadow: "0 2px 10px rgba(0, 0, 0, 0.1)", + textAlign: "center", // Center text and children + }, + title: { + marginBottom: "20px", + fontWeight: "bold", + }, + qrCodeContainer: { + backgroundColor: '#999999', + borderRadius: '20px', + position: "relative", + width: "100%", + height: "200px", + backgroundSize: "contain", + overflow: "hidden", + margin: "0 auto", // Center the QR code container + }, + uploadMessage: { + fontWeight: 600, + textAlign: "left", + fontSize: "15px" + }, + changeButton: { + paddingRight: '10px', + backgroundColor: 'green', + borderRadius: '30px', + color: 'white', + fontWeight: 700, + height: '36px', + lineHeight: '36px', + paddingLeft: '10px', + paddingHeight: '10px', + }, + uploadButton: { + paddingRight: '10px', + backgroundColor: 'green', + borderRadius: '30px', + color: 'white', + fontWeight: 700, + height: '36px', + lineHeight: '36px', + paddingLeft: '10px', + paddingHeight: '10px', + width: '40%', + textAlign: 'center' + }, + resultMessage: { + marginTop: "-24px", + marginBottom: "10px", + textAlign: "left", + display: 'flex', + justifyContent: 'space-between' + }, + buttonContainer: { + marginTop: "20px", + textAlign: "left", + display: 'flex', + justifyContent: 'space-evenly' + }, + backButtonContainer: { + marginTop: "2px", + marginBottom: "-10px", + textAlign: "left", + display: 'flex', + justifyContent: 'space-evenly' + }, + saveButton: { + padding: "10px 15px", + fontSize: "16px", + backgroundColor: "#28a745", + color: "#fff", + border: "none", + borderRadius: "30px", + cursor: "pointer", + transition: "background-color 0.3s", + }, + switchContainer: { + textAlign: "left", + marginTop: '-15px' + }, + description: { + margin: "10px 0", + }, + sliderContainer: { + marginBottom: "20px", + }, + label: { + display: "block", + marginBottom: "10px", + }, + sliderWrapper: { + display: "flex", + alignItems: "center", + }, + input: { + flex: "1", + margin: "0 10px", + }, +}; + +export default SetPaymentQr;