diff --git a/package-lock.json b/package-lock.json index 4a6cb79..445a7be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "caniuse-lite": "^1.0.30001690", "html2canvas": "^1.4.1", "jsqr": "^1.4.0", "qrcode.react": "^3.1.0", @@ -6723,9 +6724,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001636", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", - "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", + "version": "1.0.30001690", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", "funding": [ { "type": "opencollective", diff --git a/package.json b/package.json index 41af52d..aadabfc 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "groovebrew-mockup", "version": "0.1.0", "private": true, + "homepage": ".", "dependencies": { "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", @@ -9,6 +10,7 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "caniuse-lite": "^1.0.30001690", "html2canvas": "^1.4.1", "jsqr": "^1.4.0", "qrcode.react": "^3.1.0", diff --git a/src/App.js b/src/App.js index b625cc4..74cb1eb 100644 --- a/src/App.js +++ b/src/App.js @@ -204,11 +204,6 @@ function App() { setModal("transaction_failed", data); }); - socket.on("transaction_canceled", async (data) => { - console.log("transaction notification"); - setModal("transaction_canceled", data); - }); - const checkNotifications = () => { let permission = Notification.permission; @@ -280,24 +275,34 @@ function App() { socket.off("signout-guest-session"); }; }, [socket, shopId]); + + async function checkIfStillViewingOtherTransaction(){ + + console.log("transaction notification"); + console.log(modalContent); + + let response; + response = await getTransactionsFromCafe(shopId, 0, true); + transactionList.current = response; + console.log(response); + + // Get current URL's search parameters inside the socket event handler + const searchParams = new URLSearchParams(location.search); + let transaction_info = searchParams.get("transactionId") || ''; // Get transactionId or set it to empty string + console.log(transaction_info); // Log the updated transaction_info + + // If transaction_info is an empty string, set the modal + if (transaction_info == '') return false; + else return true; + } + useEffect(() => { // This will ensure that searchParams and transaction_info get updated on each render socket.on("transaction_created", async (data) => { console.log("transaction notification"); - console.log(modalContent); - - let response; - response = await getTransactionsFromCafe(shopId, 0, true); - console.log(data); - transactionList.current = response; - - // Get current URL's search parameters inside the socket event handler - const searchParams = new URLSearchParams(location.search); - let transaction_info = searchParams.get("transactionId") || ''; // Get transactionId or set it to empty string - console.log(transaction_info); // Log the updated transaction_info - + const isViewingOtherTransaction = await checkIfStillViewingOtherTransaction(); // If transaction_info is an empty string, set the modal - if (transaction_info === '') { + if (!isViewingOtherTransaction) { setModal("new_transaction", data); } @@ -312,9 +317,20 @@ function App() { }); }); + socket.on("transaction_canceled", async (data) => { + console.log("transaction notification"); + + const isViewingOtherTransaction = await checkIfStillViewingOtherTransaction(); + // If transaction_info is an empty string, set the modal + if (!isViewingOtherTransaction) { + setModal("new_transaction", data); + } + }); + // Clean up the socket event listener on unmount or when dependencies change return () => { socket.off("transaction_created"); + socket.off("transaction_canceled"); }; }, [socket, shopId, location]); // Ensure location is in the dependencies to respond to changes in the URL diff --git a/src/components/Header.js b/src/components/Header.js index c15504b..bb44734 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -190,28 +190,32 @@ const ChildWrapper = styled.div` flex-direction: column; width: 100%; `; - const Child = styled.div` width: 100%; height: 40px; margin: 5px; - background-color: rgba(88, 55, 50, 0.2); border-top-left-radius: 5px; border-bottom-left-radius: 5px; - padding-top: 10px; padding-left: 5px; font-family: "Poppins", sans-serif; font-weight: 500; font-style: normal; ${(props) => - props.hasChildren && - ` - height: auto; - padding-bottom: 10px; - `} + props.hasChildren + ? ` + border: 1px solid #ababab; + height: auto; + padding-bottom: 10px; + ` + : ` + display: flex; + align-items: center; + background-color: rgb(223 223 223); + `} `; + const Header = ({ HeaderText, HeaderSize='6vw', @@ -343,7 +347,7 @@ const Header = ({ {shopName} - Mode edit + Mode edit   div:first-child { + padding-top: 21px; + + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Old versions of Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently +*/ } + .expand-button { font-size: 20px; position: relative; @@ -138,7 +154,21 @@ text-align: center; line-height: 40px; /* Center text vertically */ -} + + -webkit-tap-highlight-color: transparent; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + outline: none; + + transition: padding-top 0.3s ease; + padding-top: 8px; + } .expand-button h5 { font-weight: 500; @@ -146,8 +176,8 @@ text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.36); } -.expand-button:hover { - background-color: #73a585; +.expand-button.expanded{ + padding-top: 0px; } /* Adjust height of the music player container when expanded */ @@ -224,10 +254,6 @@ /* Adjust fill color */ } -/* Add hover effect for the search icon */ -.search-box .search-icon:hover { - color: #555; -} .rectangle { position: relative; height: 200px; diff --git a/src/components/MusicPlayer.js b/src/components/MusicPlayer.js index aeecc6a..5b43db8 100644 --- a/src/components/MusicPlayer.js +++ b/src/components/MusicPlayer.js @@ -284,16 +284,16 @@ export function MusicPlayer({ socket, shopId, user, shopOwnerId, isSpotifyNeedLo const handleSetPlayer = () => { const token = localStorage.getItem("auth"); + socket.emit("claimPlayer", { + token, + shopId, + }); if (isSpotifyNeedLogin) { - socket.emit("claimPlayer", { - token, - shopId, - }); } else { - socket.emit("unClaimPlayer", { - token, - shopId, - }); + // socket.emit("unClaimPlayer", { + // token, + // shopId, + // }); } }; @@ -333,9 +333,9 @@ export function MusicPlayer({ socket, shopId, user, shopOwnerId, isSpotifyNeedLo }, [expanded]); - const [text, setText] = useState("Awaiting the next hit"); + const [text, setText] = useState("Menunggu musik favoritmu"); const textIndex = useRef(0); - const [messages, setMessages] = useState(["Awaiting the next hit", "Click to request your fav song"]); + const [messages, setMessages] = useState(["Menunggu musik favoritmu", "Klik untuk putar musik favoritmu"]); useEffect(() => { @@ -343,8 +343,8 @@ export function MusicPlayer({ socket, shopId, user, shopOwnerId, isSpotifyNeedLo const newMessages = [ currentSong != null && currentSong.item != undefined ? `${currentSong.item.artists[0].name} - ${currentSong.item.name}` - : "Awaiting the next hit", - "Click to request your fav song" + : "Menunggu musik favoritmu", + "Klik untuk putar musik favoritmu" ]; setMessages(newMessages); @@ -374,9 +374,10 @@ export function MusicPlayer({ socket, shopId, user, shopOwnerId, isSpotifyNeedLo
- + */} {currentLines.present.map((line, index) => (
)} -
+
@@ -490,24 +491,24 @@ export function MusicPlayer({ socket, shopId, user, shopOwnerId, isSpotifyNeedLo /> ))} { - songName === "" && - queue && - Array.isArray(queue) && - queue.length > 0 && ( - queue.map((song, index) => ( - onDecision(song.trackId, vote)} - /> - )) - ) -} + songName === "" && + queue && + Array.isArray(queue) && + queue.length > 0 && ( + queue.map((song, index) => ( + onDecision(song.trackId, vote)} + /> + )) + ) + } {songName == "" && queue.length < 1 && (
-
No Beats Ahead - Drop Your Hits
+
Antrian kosong - Pilih musikmu
)} {songName == "" && queue.length > 0 && queue.length < 3 && ( @@ -516,11 +517,10 @@ export function MusicPlayer({ socket, shopId, user, shopOwnerId, isSpotifyNeedLo
)}
-
+
+
- {expanded - ? "︿" - : "request your song"} + {expanded? '⋀' : 'Lihat antrian musik'}
} diff --git a/src/components/PaymentOptions.js b/src/components/PaymentOptions.js index 768e58e..05c715b 100644 --- a/src/components/PaymentOptions.js +++ b/src/components/PaymentOptions.js @@ -141,7 +141,7 @@ const SetPaymentQr = ({ shopId }) => {
-

Pengecekan ketersediaan ganda

+

Pengecekan ketersediaan ganda

Nyalakan agar kasir memeriksa kembali ketersediaan produk sebelum pelanggan membayar.

diff --git a/src/pages/Cart.js b/src/pages/Cart.js index 5055eb2..4a00ef3 100644 --- a/src/pages/Cart.js +++ b/src/pages/Cart.js @@ -144,9 +144,11 @@ export default function Invoice({ table, sendParam, deviceType, socket }) { console.log(localStorage.getItem('cart')) console.log(cartItems) + if(localStorage.getItem('cart') == "[]") return; + // Parse the local storage cart const localStorageCart = JSON.parse(localStorage.getItem('cart')); - + console.log(localStorageCart) // Create a set of itemIds from the local storage cart for quick lookup const localStorageItemIds = new Set(localStorageCart[0].items.map(item => item.itemId)); diff --git a/src/pages/CreateCafe.js b/src/pages/CreateCafe.js index 361f2c2..5f1e71e 100644 --- a/src/pages/CreateCafe.js +++ b/src/pages/CreateCafe.js @@ -1,9 +1,8 @@ import React, { useState } from 'react'; -import { createClerks } from '../helpers/userHelpers'; // Adjust the import path as needed +import { createCafe } from '../helpers/cafeHelpers'; // Adjust the import path as needed const CreateClerk = ({ shopId }) => { - const [username, setUsername] = useState(''); - const [password, setPassword] = useState(''); + const [name, setName] = useState(''); const [loading, setLoading] = useState(false); const [message, setMessage] = useState(''); @@ -13,16 +12,16 @@ const CreateClerk = ({ shopId }) => { setMessage(''); // Basic validation - if (!username || !password) { - setMessage('Username and password are required'); + if (!name) { + setMessage('name is required'); setLoading(false); return; } try { - const create = await createClerks(shopId, username, password); + const create = await createCafe(name); - if (create) setMessage('Clerk created successfully'); + if (create) setMessage('Cafe created successfully'); else setMessage('Failed to create clerk'); } catch (error) { setMessage('Error creating clerk'); @@ -37,16 +36,9 @@ const CreateClerk = ({ shopId }) => {
setUsername(e.target.value)} - style={styles.input} - /> - setPassword(e.target.value)} + placeholder="Cafe name" + value={name} + onChange={(e) => setName(e.target.value)} style={styles.input} /> {message && (

diff --git a/src/pages/LinktreePage.module.css b/src/pages/LinktreePage.module.css index b0837c6..6389989 100644 --- a/src/pages/LinktreePage.module.css +++ b/src/pages/LinktreePage.module.css @@ -497,7 +497,7 @@ .cafeListWrapper { background-color: white; border-radius: 20px 20px 0 0; - top: 83vh; + bottom: 0; position: absolute; width: 100%; } diff --git a/src/pages/Transaction_confirmed.js b/src/pages/Transaction_confirmed.js index b22da36..d131740 100644 --- a/src/pages/Transaction_confirmed.js +++ b/src/pages/Transaction_confirmed.js @@ -138,7 +138,7 @@ export default function Transactions({

-

silahkan bayar ke kasir

+ {transaction.payment_type == 'cashless' ?

silahkan bayar QR

:

silahkan bayar ke kasir

}

Transaction ID: {transaction.transactionId}

Payment Type: {transaction.payment_type}

diff --git a/src/pages/Transaction_pending.js b/src/pages/Transaction_pending.js index ce8b822..f677428 100644 --- a/src/pages/Transaction_pending.js +++ b/src/pages/Transaction_pending.js @@ -5,7 +5,7 @@ import { ColorRing } from "react-loader-spinner"; import { getTransaction, confirmTransaction, - declineTransaction, + cancelTransaction, } from "../helpers/transactionHelpers"; import { getTables } from "../helpers/tableHelper"; import TableCanvas from "../components/TableCanvas"; @@ -29,12 +29,24 @@ export default function Transactions({ propsShopId, sendParam, deviceType, handl try { const fetchedTransaction = await getTransaction(transactionId); setTransaction(fetchedTransaction); - console.log(transaction); + console.log(fetchedTransaction); // Log the fetched transaction } catch (error) { console.error("Error fetching transaction:", error); } }; - fetchData(); + + const waitForLocalStorage = async () => { + while (localStorage.getItem("auth") === null) { + await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait 1 second + } + }; + + const initialize = async () => { + await waitForLocalStorage(); + await fetchData(); + }; + + initialize(); }, [searchParams]); useEffect(() => { @@ -75,7 +87,7 @@ export default function Transactions({ propsShopId, sendParam, deviceType, handl if (isPaymentLoading) return; setIsPaymentLoading(true); try { - const c = await declineTransaction(transactionId); + const c = await cancelTransaction(transactionId); // if (c) { // // Update the confirmed status locally // setTransactions((prevTransactions) => @@ -180,7 +192,7 @@ export default function Transactions({ propsShopId, sendParam, deviceType, handl