ok
This commit is contained in:
190
src/App.js
190
src/App.js
@@ -10,7 +10,6 @@ import {
|
|||||||
} from "react-router-dom";
|
} from "react-router-dom";
|
||||||
import socket from "./services/socketService";
|
import socket from "./services/socketService";
|
||||||
|
|
||||||
|
|
||||||
import Dashboard from "./pages/Dashboard";
|
import Dashboard from "./pages/Dashboard";
|
||||||
import ScanMeja from "./pages/ScanMeja";
|
import ScanMeja from "./pages/ScanMeja";
|
||||||
import CafePage from "./pages/CafePage";
|
import CafePage from "./pages/CafePage";
|
||||||
@@ -27,7 +26,7 @@ import { getTableByCode } from "./helpers/tableHelper.js";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
getTransactionsFromCafe,
|
getTransactionsFromCafe,
|
||||||
checkIsMyTransaction
|
checkIsMyTransaction,
|
||||||
} from "./helpers/transactionHelpers";
|
} from "./helpers/transactionHelpers";
|
||||||
import {
|
import {
|
||||||
getConnectedGuestSides,
|
getConnectedGuestSides,
|
||||||
@@ -45,7 +44,7 @@ import {
|
|||||||
} from "./helpers/subscribeHelpers.js";
|
} from "./helpers/subscribeHelpers.js";
|
||||||
import Modal from "./components/Modal"; // Import your modal component
|
import Modal from "./components/Modal"; // Import your modal component
|
||||||
|
|
||||||
import { requestNotificationPermission } from './services/notificationService'; // Import the notification service
|
import { requestNotificationPermission } from "./services/notificationService"; // Import the notification service
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -73,35 +72,32 @@ function App() {
|
|||||||
|
|
||||||
const [newTransaction, setNewTransaction] = useState({});
|
const [newTransaction, setNewTransaction] = useState({});
|
||||||
|
|
||||||
|
|
||||||
const queryParams = new URLSearchParams(location.search);
|
const queryParams = new URLSearchParams(location.search);
|
||||||
const tokenParams = queryParams.get("token");
|
const tokenParams = queryParams.get("token");
|
||||||
if(tokenParams) localStorage.setItem('auth', tokenParams)
|
if (tokenParams) localStorage.setItem("auth", tokenParams);
|
||||||
|
|
||||||
const validTransactionStates = [
|
const validTransactionStates = [
|
||||||
'new_transaction',
|
"new_transaction",
|
||||||
'transaction_canceled',
|
"transaction_canceled",
|
||||||
'transaction_pending',
|
"transaction_pending",
|
||||||
'transaction_confirmed',
|
"transaction_confirmed",
|
||||||
'payment_claimed',
|
"payment_claimed",
|
||||||
'transaction_success',
|
"transaction_success",
|
||||||
'transaction_end',
|
"transaction_end",
|
||||||
'transaction_failed',
|
"transaction_failed",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
const calculateTotalsFromLocalStorage = () => {
|
const calculateTotalsFromLocalStorage = () => {
|
||||||
const { totalCount, totalPrice } = calculateTotals(shopId);
|
const { totalCount, totalPrice } = calculateTotals(shopId);
|
||||||
setTotalItemsCount(totalCount);
|
setTotalItemsCount(totalCount);
|
||||||
setTotalPrice(totalPrice);
|
setTotalPrice(totalPrice);
|
||||||
|
|
||||||
|
|
||||||
// If 'lastTransaction' exists, proceed
|
// If 'lastTransaction' exists, proceed
|
||||||
const lastTransaction = JSON.parse(localStorage.getItem("lastTransaction"));
|
const lastTransaction = JSON.parse(localStorage.getItem("lastTransaction"));
|
||||||
console.log(lastTransaction);
|
console.log(lastTransaction);
|
||||||
|
|
||||||
if (lastTransaction != null) {
|
if (lastTransaction != null) {
|
||||||
console.log(lastTransaction)
|
console.log(lastTransaction);
|
||||||
setLastTransaction(lastTransaction);
|
setLastTransaction(lastTransaction);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -145,9 +141,13 @@ function App() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setModal('transaction_confirmed', { transactionId: lastTransaction.transactionId })
|
setModal("transaction_confirmed", {
|
||||||
const myLastTransaction = await checkIsMyTransaction(lastTransaction.transactionId);
|
transactionId: lastTransaction.transactionId,
|
||||||
console.log(myLastTransaction)
|
});
|
||||||
|
const myLastTransaction = await checkIsMyTransaction(
|
||||||
|
lastTransaction.transactionId
|
||||||
|
);
|
||||||
|
console.log(myLastTransaction);
|
||||||
if (myLastTransaction.isMyTransaction) {
|
if (myLastTransaction.isMyTransaction) {
|
||||||
setLastTransaction(lastTransaction);
|
setLastTransaction(lastTransaction);
|
||||||
} else {
|
} else {
|
||||||
@@ -155,7 +155,6 @@ function App() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const handleSetParam = async ({ shopIdentifier, tableCode }) => {
|
const handleSetParam = async ({ shopIdentifier, tableCode }) => {
|
||||||
setShopIdentifier(shopIdentifier);
|
setShopIdentifier(shopIdentifier);
|
||||||
|
|
||||||
@@ -170,12 +169,14 @@ function App() {
|
|||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
console.log("gettingItems");
|
console.log("gettingItems");
|
||||||
try {
|
try {
|
||||||
const { response, cafe, data } = await getItemTypesWithItems(shopIdentifier);
|
const { response, cafe, data } = await getItemTypesWithItems(
|
||||||
|
shopIdentifier
|
||||||
|
);
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
setShopId(cafe.cafeId)
|
setShopId(cafe.cafeId);
|
||||||
setShop(cafe);
|
setShop(cafe);
|
||||||
setShopItems(data);
|
setShopItems(data);
|
||||||
console.log(data)
|
console.log(data);
|
||||||
// Filter out unavailable items
|
// Filter out unavailable items
|
||||||
const filteredData = data
|
const filteredData = data
|
||||||
.map((itemType) => ({
|
.map((itemType) => ({
|
||||||
@@ -241,7 +242,7 @@ function App() {
|
|||||||
// Call `setModal` with content and parameters
|
// Call `setModal` with content and parameters
|
||||||
setModal("transaction_pending", data);
|
setModal("transaction_pending", data);
|
||||||
|
|
||||||
localStorage.setItem('cart', []);
|
localStorage.setItem("cart", []);
|
||||||
|
|
||||||
calculateTotalsFromLocalStorage();
|
calculateTotalsFromLocalStorage();
|
||||||
});
|
});
|
||||||
@@ -250,7 +251,7 @@ function App() {
|
|||||||
console.log(JSON.stringify(data));
|
console.log(JSON.stringify(data));
|
||||||
setModal("transaction_confirmed", data);
|
setModal("transaction_confirmed", data);
|
||||||
|
|
||||||
localStorage.setItem('cart', []);
|
localStorage.setItem("cart", []);
|
||||||
|
|
||||||
// const startTime = Date.now(); // Capture the start time
|
// const startTime = Date.now(); // Capture the start time
|
||||||
// const timeout = 10000; // 10 seconds timeout in milliseconds
|
// const timeout = 10000; // 10 seconds timeout in milliseconds
|
||||||
@@ -266,7 +267,9 @@ function App() {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// If 'lastTransaction' exists, proceed
|
// If 'lastTransaction' exists, proceed
|
||||||
const lastTransaction = JSON.parse(localStorage.getItem("lastTransaction"));
|
const lastTransaction = JSON.parse(
|
||||||
|
localStorage.getItem("lastTransaction")
|
||||||
|
);
|
||||||
console.log(lastTransaction);
|
console.log(lastTransaction);
|
||||||
|
|
||||||
if (lastTransaction != null) {
|
if (lastTransaction != null) {
|
||||||
@@ -274,7 +277,6 @@ function App() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
socket.on("transaction_success", async (data) => {
|
socket.on("transaction_success", async (data) => {
|
||||||
console.log("transaction notification");
|
console.log("transaction notification");
|
||||||
setModal("transaction_success", data);
|
setModal("transaction_success", data);
|
||||||
@@ -316,7 +318,6 @@ function App() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const handleNotificationClick = async () => {
|
const handleNotificationClick = async () => {
|
||||||
const permission = await requestNotificationPermission();
|
const permission = await requestNotificationPermission();
|
||||||
|
|
||||||
@@ -325,7 +326,7 @@ function App() {
|
|||||||
// Set up notifications or show a success modal
|
// Set up notifications or show a success modal
|
||||||
} else {
|
} else {
|
||||||
console.error("Notification permission denied.");
|
console.error("Notification permission denied.");
|
||||||
setModal('blocked_notification'); // Show modal for blocked notifications
|
setModal("blocked_notification"); // Show modal for blocked notifications
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -334,10 +335,21 @@ function App() {
|
|||||||
|
|
||||||
// Check current permission
|
// Check current permission
|
||||||
const searchParams = new URLSearchParams(location.search);
|
const searchParams = new URLSearchParams(location.search);
|
||||||
let searchModal = searchParams.get("modal") || ''; // Get transactionId or set it to empty string
|
let searchModal = searchParams.get("modal") || ""; // Get transactionId or set it to empty string
|
||||||
|
|
||||||
if (permission !== "granted" && searchModal == '') {
|
if (permission !== "granted" && searchModal == "") {
|
||||||
setModal("message", { captMessage: 'Notifikasi tidak aktif', descMessage: 'Aktifkan notifikasi supaya kamu tetap dapat info pesanan, meski sedang buka aplikasi lain.', yesText: 'Aktifkan', noText: 'Tutup' }, null, handleNotificationClick);
|
setModal(
|
||||||
|
"message",
|
||||||
|
{
|
||||||
|
captMessage: "Notifikasi tidak aktif",
|
||||||
|
descMessage:
|
||||||
|
"Aktifkan notifikasi supaya kamu tetap dapat info pesanan, meski sedang buka aplikasi lain.",
|
||||||
|
yesText: "Aktifkan",
|
||||||
|
noText: "Tutup",
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
handleNotificationClick
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -346,10 +358,15 @@ function App() {
|
|||||||
removeLocalStorage("auth");
|
removeLocalStorage("auth");
|
||||||
setDeviceType("guestDevice");
|
setDeviceType("guestDevice");
|
||||||
} else {
|
} else {
|
||||||
console.log(data)
|
console.log(data);
|
||||||
if (data.data.user.cafeId != null) navigate(`/${data.data.user.cafeIdentityName}`, { replace: true });
|
if (data.data.user.cafeId != null)
|
||||||
|
navigate(`/${data.data.user.cafeIdentityName}`, { replace: true });
|
||||||
setUser(data.data.user);
|
setUser(data.data.user);
|
||||||
if (data.data.latestOpenBillTransaction != null) localStorage.setItem('lastTransaction', JSON.stringify(data.data.latestOpenBillTransaction))
|
if (data.data.latestOpenBillTransaction != null)
|
||||||
|
localStorage.setItem(
|
||||||
|
"lastTransaction",
|
||||||
|
JSON.stringify(data.data.latestOpenBillTransaction)
|
||||||
|
);
|
||||||
if (
|
if (
|
||||||
data.data.user.password == "unsetunsetunset" &&
|
data.data.user.password == "unsetunsetunset" &&
|
||||||
localStorage.getItem("settings")
|
localStorage.getItem("settings")
|
||||||
@@ -393,7 +410,6 @@ function App() {
|
|||||||
socket.on("updateQueue", ({ queue }) => {
|
socket.on("updateQueue", ({ queue }) => {
|
||||||
setQueue(queue); // Only set the queue if it's a valid non-empty array
|
setQueue(queue); // Only set the queue if it's a valid non-empty array
|
||||||
console.log("Updated Queue:", queue); // Log the valid queue
|
console.log("Updated Queue:", queue); // Log the valid queue
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
@@ -402,7 +418,6 @@ function App() {
|
|||||||
}, [socket, shopId]);
|
}, [socket, shopId]);
|
||||||
|
|
||||||
async function checkIfStillViewingOtherTransaction(data) {
|
async function checkIfStillViewingOtherTransaction(data) {
|
||||||
|
|
||||||
console.log("transaction notification");
|
console.log("transaction notification");
|
||||||
console.log(modalContent);
|
console.log(modalContent);
|
||||||
|
|
||||||
@@ -412,21 +427,21 @@ function App() {
|
|||||||
|
|
||||||
// Get current URL's search parameters inside the socket event handler
|
// Get current URL's search parameters inside the socket event handler
|
||||||
const searchParams = new URLSearchParams(location.search);
|
const searchParams = new URLSearchParams(location.search);
|
||||||
let transaction_info = searchParams.get("transactionId") || ''; // Get transactionId or set it to empty string
|
let transaction_info = searchParams.get("transactionId") || ""; // Get transactionId or set it to empty string
|
||||||
|
|
||||||
if(response[0].transactionId != transaction_info) transactionList.current = response;
|
if (response[0].transactionId != transaction_info)
|
||||||
|
transactionList.current = response;
|
||||||
|
|
||||||
let depthh = transactionList.current.findIndex(
|
let depthh = transactionList.current.findIndex(
|
||||||
item => item.transactionId.toString() === transaction_info.toString()
|
(item) => item.transactionId.toString() === transaction_info.toString()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (transaction_info != response[0].transactionId)
|
if (transaction_info != response[0].transactionId) setDepth(depthh);
|
||||||
setDepth(depthh);
|
|
||||||
else setModal("new_transaction", data);
|
else setModal("new_transaction", data);
|
||||||
|
|
||||||
console.log(transaction_info == response[0].transactionId)
|
console.log(transaction_info == response[0].transactionId);
|
||||||
// If transaction_info is an empty string, set the modal
|
// If transaction_info is an empty string, set the modal
|
||||||
if (transaction_info.toString() == '') return false;
|
if (transaction_info.toString() == "") return false;
|
||||||
else return true;
|
else return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,13 +451,14 @@ function App() {
|
|||||||
console.log("transaction notification");
|
console.log("transaction notification");
|
||||||
setNewTransaction(data);
|
setNewTransaction(data);
|
||||||
|
|
||||||
if(!location.pathname.endsWith('/transactions')){
|
if (!location.pathname.endsWith("/transactions")) {
|
||||||
const isViewingOtherTransaction = await checkIfStillViewingOtherTransaction(data);
|
const isViewingOtherTransaction =
|
||||||
// If transaction_info is an empty string, set the modal
|
await checkIfStillViewingOtherTransaction(data);
|
||||||
if (!isViewingOtherTransaction) {
|
// If transaction_info is an empty string, set the modal
|
||||||
setModal("new_transaction", data);
|
if (!isViewingOtherTransaction) {
|
||||||
|
setModal("new_transaction", data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Show browser notification
|
// Show browser notification
|
||||||
let permission = Notification.permission;
|
let permission = Notification.permission;
|
||||||
if (permission !== "granted") return;
|
if (permission !== "granted") return;
|
||||||
@@ -458,13 +474,14 @@ function App() {
|
|||||||
console.log("transaction notification");
|
console.log("transaction notification");
|
||||||
|
|
||||||
setNewTransaction(data);
|
setNewTransaction(data);
|
||||||
if(location.pathname != '/transactions'){
|
if (location.pathname != "/transactions") {
|
||||||
const isViewingOtherTransaction = await checkIfStillViewingOtherTransaction(data);
|
const isViewingOtherTransaction =
|
||||||
// If transaction_info is an empty string, set the modal
|
await checkIfStillViewingOtherTransaction(data);
|
||||||
if (!isViewingOtherTransaction) {
|
// If transaction_info is an empty string, set the modal
|
||||||
setModal("new_transaction", data);
|
if (!isViewingOtherTransaction) {
|
||||||
navigate(`?transactionId=${data.transactionId}`, { replace: true });
|
setModal("new_transaction", data);
|
||||||
}
|
navigate(`?transactionId=${data.transactionId}`, { replace: true });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -473,34 +490,36 @@ function App() {
|
|||||||
socket.off("transaction_created");
|
socket.off("transaction_created");
|
||||||
socket.off("transaction_canceled");
|
socket.off("transaction_canceled");
|
||||||
};
|
};
|
||||||
}, [socket, shopId, location]); // Ensure location is in the dependencies to respond to changes in the URL
|
}, [socket, shopId, location]); // Ensure location is in the dependencies to respond to changes in the URL
|
||||||
|
|
||||||
function handleMoveToTransaction(direction, from) {
|
function handleMoveToTransaction(direction, from) {
|
||||||
console.log(direction);
|
console.log(direction);
|
||||||
console.log(from);
|
console.log(from);
|
||||||
|
|
||||||
// Find the current index based on the 'from' transactionId
|
// Find the current index based on the 'from' transactionId
|
||||||
const currentIndex = transactionList.current.findIndex(item => item.transactionId == from);
|
const currentIndex = transactionList.current.findIndex(
|
||||||
|
(item) => item.transactionId == from
|
||||||
|
);
|
||||||
|
|
||||||
// Determine the new transactionId based on the direction
|
// Determine the new transactionId based on the direction
|
||||||
let newTransactionId;
|
let newTransactionId;
|
||||||
if (direction === 'next') {
|
if (direction === "next") {
|
||||||
|
|
||||||
// If we're not at the last transaction, get the next transactionId
|
// If we're not at the last transaction, get the next transactionId
|
||||||
newTransactionId = currentIndex < transactionList.current.length - 1
|
newTransactionId =
|
||||||
? transactionList.current[currentIndex + 1].transactionId
|
currentIndex < transactionList.current.length - 1
|
||||||
: from; // If already at the end, stay on the current transactionId
|
? transactionList.current[currentIndex + 1].transactionId
|
||||||
} else if (direction === 'previous') {
|
: from; // If already at the end, stay on the current transactionId
|
||||||
|
} else if (direction === "previous") {
|
||||||
setDepth(currentIndex - 1);
|
setDepth(currentIndex - 1);
|
||||||
// If we're not at the first transaction, get the previous transactionId
|
// If we're not at the first transaction, get the previous transactionId
|
||||||
newTransactionId = currentIndex > 0
|
newTransactionId =
|
||||||
? transactionList.current[currentIndex - 1].transactionId
|
currentIndex > 0
|
||||||
: from; // If already at the beginning, stay on the current transactionId
|
? transactionList.current[currentIndex - 1].transactionId
|
||||||
|
: from; // If already at the beginning, stay on the current transactionId
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log the new transactionId
|
// Log the new transactionId
|
||||||
console.log('New Transaction ID:', newTransactionId);
|
console.log("New Transaction ID:", newTransactionId);
|
||||||
|
|
||||||
// Update the URL with the new transactionId using navigate
|
// Update the URL with the new transactionId using navigate
|
||||||
navigate(`?transactionId=${newTransactionId}`, { replace: true });
|
navigate(`?transactionId=${newTransactionId}`, { replace: true });
|
||||||
@@ -510,7 +529,6 @@ function App() {
|
|||||||
// setModalContent({ cafeId: shopId, transactionId: newTransactionId });
|
// setModalContent({ cafeId: shopId, transactionId: newTransactionId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const handleModalFromURL = () => {
|
const handleModalFromURL = () => {
|
||||||
const queryParams = new URLSearchParams(location.search);
|
const queryParams = new URLSearchParams(location.search);
|
||||||
const modal = queryParams.get("modal");
|
const modal = queryParams.get("modal");
|
||||||
@@ -542,8 +560,8 @@ function App() {
|
|||||||
document.body.style.overflow = "hidden";
|
document.body.style.overflow = "hidden";
|
||||||
|
|
||||||
setIsModalOpen(true);
|
setIsModalOpen(true);
|
||||||
setModalContent(content)
|
setModalContent(content);
|
||||||
console.log(onCloseFunction)
|
console.log(onCloseFunction);
|
||||||
|
|
||||||
if (onCloseFunction) {
|
if (onCloseFunction) {
|
||||||
setOnModalCloseFunction(() => onCloseFunction); // Store the close function
|
setOnModalCloseFunction(() => onCloseFunction); // Store the close function
|
||||||
@@ -560,7 +578,8 @@ function App() {
|
|||||||
const closeModal = (closeTheseContent = []) => {
|
const closeModal = (closeTheseContent = []) => {
|
||||||
if (
|
if (
|
||||||
Array.isArray(closeTheseContent) &&
|
Array.isArray(closeTheseContent) &&
|
||||||
(closeTheseContent.length === 0 || closeTheseContent.includes(modalContent))
|
(closeTheseContent.length === 0 ||
|
||||||
|
closeTheseContent.includes(modalContent))
|
||||||
) {
|
) {
|
||||||
setIsModalOpen(false);
|
setIsModalOpen(false);
|
||||||
setModalContent(null);
|
setModalContent(null);
|
||||||
@@ -569,16 +588,16 @@ function App() {
|
|||||||
const queryParams = new URLSearchParams(location.search);
|
const queryParams = new URLSearchParams(location.search);
|
||||||
|
|
||||||
// Clear all query parameters
|
// Clear all query parameters
|
||||||
queryParams.keys() && [...queryParams.keys()].forEach(key => {
|
queryParams.keys() &&
|
||||||
queryParams.delete(key);
|
[...queryParams.keys()].forEach((key) => {
|
||||||
});
|
queryParams.delete(key);
|
||||||
|
});
|
||||||
|
|
||||||
// Update the URL without any query parameters
|
// Update the URL without any query parameters
|
||||||
navigate({ search: queryParams.toString() }, { replace: true });
|
navigate({ search: queryParams.toString() }, { replace: true });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// const askNotificationPermission = async () => {
|
// const askNotificationPermission = async () => {
|
||||||
// let permission = Notification.permission;
|
// let permission = Notification.permission;
|
||||||
@@ -637,11 +656,15 @@ function App() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if ("serviceWorker" in navigator) {
|
if ("serviceWorker" in navigator) {
|
||||||
navigator.serviceWorker.register("/service-worker.js")
|
navigator.serviceWorker
|
||||||
.then(registration => {
|
.register("/service-worker.js")
|
||||||
console.log("Service Worker registered with scope:", registration.scope);
|
.then((registration) => {
|
||||||
|
console.log(
|
||||||
|
"Service Worker registered with scope:",
|
||||||
|
registration.scope
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
console.error("Service Worker registration failed:", error);
|
console.error("Service Worker registration failed:", error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -702,6 +725,9 @@ function App() {
|
|||||||
cartItemsLength={totalItemsCount}
|
cartItemsLength={totalItemsCount}
|
||||||
totalPrice={totalPrice}
|
totalPrice={totalPrice}
|
||||||
lastTransaction={lastTransaction}
|
lastTransaction={lastTransaction}
|
||||||
|
shop={shop}
|
||||||
|
totalItemsCount={totalItemsCount}
|
||||||
|
deviceType={deviceType}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,11 +35,16 @@ const Title = styled.h2`
|
|||||||
font-family: "Plus Jakarta Sans", sans-serif;
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-size:${(props) => (props.HeaderSize)};
|
font-size: ${(props) => props.HeaderSize};
|
||||||
color: rgba(88, 55, 50, 1);
|
color: rgba(88, 55, 50, 1);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
font-size: 2vw;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
||||||
const ProfileName = styled.h2`
|
const ProfileName = styled.h2`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
font-family: "Plus Jakarta Sans", sans-serif;
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
@@ -81,8 +86,8 @@ const gg = keyframes`
|
|||||||
height: 60px;
|
height: 60px;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
top: 45px;
|
top: 5px;
|
||||||
right: 51px;
|
right: 20px;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
@@ -90,8 +95,8 @@ const gg = keyframes`
|
|||||||
|
|
||||||
const ss = keyframes`
|
const ss = keyframes`
|
||||||
0% {
|
0% {
|
||||||
top: 45px;
|
top: 5px;
|
||||||
right: 51px;
|
right: 20px;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
@@ -127,8 +132,8 @@ const g = keyframes`
|
|||||||
height: 60px;
|
height: 60px;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
top: 28px;
|
top: 34px;
|
||||||
right: 242px;
|
right: 229px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
@@ -137,7 +142,7 @@ const g = keyframes`
|
|||||||
const s = keyframes`
|
const s = keyframes`
|
||||||
0% {
|
0% {
|
||||||
top: 28px;
|
top: 28px;
|
||||||
right: 242px;
|
right: 229px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
@@ -151,14 +156,15 @@ const s = keyframes`
|
|||||||
|
|
||||||
const grow = keyframes`
|
const grow = keyframes`
|
||||||
0% {
|
0% {
|
||||||
right: 12px;
|
right: 0px;
|
||||||
|
top: 0px;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
border-top-left-radius: 50%;
|
border-top-left-radius: 50%;
|
||||||
border-bottom-left-radius: 50%;
|
border-bottom-left-radius: 50%;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
right: 28px;
|
right: -17px;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
border-top-left-radius: 15px;
|
border-top-left-radius: 15px;
|
||||||
border-bottom-left-radius: 15px;
|
border-bottom-left-radius: 15px;
|
||||||
@@ -167,13 +173,14 @@ const grow = keyframes`
|
|||||||
|
|
||||||
const shrink = keyframes`
|
const shrink = keyframes`
|
||||||
0% {
|
0% {
|
||||||
right: 12px;
|
right: -17px;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
height: auto;
|
height: auto;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
right: 28px;
|
right: 0px;
|
||||||
|
top: 0px;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@@ -182,7 +189,7 @@ const shrink = keyframes`
|
|||||||
const Rectangle = styled.div`
|
const Rectangle = styled.div`
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 39px;
|
top: 9px;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
max-height: 87vh; /* or another appropriate value */
|
max-height: 87vh; /* or another appropriate value */
|
||||||
@@ -323,59 +330,105 @@ const Header = ({
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<HeaderBarbackground shopName={shopName}>
|
<HeaderBarbackground shopName={shopName}>
|
||||||
<HeaderBar HeaderMargin={HeaderMargin} shopName={shopName}>
|
<HeaderBar HeaderMargin={HeaderMargin} shopName={shopName}>
|
||||||
<Title HeaderSize={HeaderSize}>
|
<Title HeaderSize={HeaderSize}>
|
||||||
{shopName == null
|
{shopName == null
|
||||||
? HeaderText == null
|
? HeaderText == null
|
||||||
? "kedaimaster"
|
? "kedaimaster"
|
||||||
: HeaderText
|
: HeaderText
|
||||||
: shopName}
|
: shopName}
|
||||||
</Title>
|
</Title>
|
||||||
<div style={{ visibility: showProfile ? "visible" : "hidden" }}>
|
<div style={{ visibility: showProfile ? "visible" : "hidden", position: 'relative' }}>
|
||||||
<ProfileImage
|
<ProfileImage
|
||||||
src={shopImage && !shopImage.includes('undefined') ? shopImage || 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-DjX_bGBax4NL14ULvkAdU4FP3FKoWXWu5w&s' : "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-DjX_bGBax4NL14ULvkAdU4FP3FKoWXWu5w&s"}
|
src={shopImage && !shopImage.includes('undefined') ? shopImage || 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-DjX_bGBax4NL14ULvkAdU4FP3FKoWXWu5w&s' : "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-DjX_bGBax4NL14ULvkAdU4FP3FKoWXWu5w&s"}
|
||||||
alt="Profile"
|
alt="Profile"
|
||||||
onClick={user.username !== undefined ? handleImageClick : null}
|
onClick={user.username !== undefined ? handleImageClick : null}
|
||||||
animate={showRectangle && animate}
|
animate={showRectangle && animate}
|
||||||
/>
|
/>
|
||||||
<ProfileName animate={showRectangle && animate}>
|
<ProfileName animate={showRectangle && animate}>
|
||||||
{showProfile && user.username !== undefined ? user.username : "guest"}
|
{showProfile && user.username !== undefined ? user.username : "guest"}
|
||||||
</ProfileName>
|
</ProfileName>
|
||||||
{showRectangle && (
|
{showRectangle && (
|
||||||
<Rectangle ref={rectangleRef} animate={animate}>
|
<Rectangle ref={rectangleRef} animate={animate}>
|
||||||
<ChildContainer>
|
<ChildContainer>
|
||||||
{guestSideOfClerk && guestSideOfClerk.clerkUsername && (
|
{guestSideOfClerk && guestSideOfClerk.clerkUsername && (
|
||||||
<Child hasChildren>
|
<Child hasChildren>
|
||||||
this is the guest side of {guestSideOfClerk.clerkUsername}
|
this is the guest side of {guestSideOfClerk.clerkUsername}
|
||||||
</Child>
|
</Child>
|
||||||
)}
|
)}
|
||||||
{user.username !== undefined && (
|
{user.username !== undefined && (
|
||||||
<Child onClick={() => setModal("edit_account")}>
|
<Child onClick={() => setModal("edit_account")}>
|
||||||
Kelola akun
|
Kelola akun
|
||||||
</Child>
|
</Child>
|
||||||
)}
|
)}
|
||||||
{user.roleId == 0 && (
|
{user.roleId == 0 && (
|
||||||
<Child onClick={()=>setModal('create_coupon', {})}>Buat Voucher</Child>)}
|
<Child onClick={() => setModal('create_coupon', {})}>Buat Voucher</Child>)}
|
||||||
{shopId && user.roleId == 1 && (
|
{shopId && user.roleId == 1 && (
|
||||||
<Child onClick={goToAdminCafes}>Dashboard</Child>)}
|
<Child onClick={goToAdminCafes}>Dashboard</Child>)}
|
||||||
{shopId &&
|
{shopId &&
|
||||||
user.user_id == shopOwnerId &&
|
user.user_id == shopOwnerId &&
|
||||||
user.username !== undefined &&
|
user.username !== undefined &&
|
||||||
user.roleId === 1 && (
|
user.roleId === 1 && (
|
||||||
<>
|
<>
|
||||||
<Child hasChildren>
|
<Child hasChildren>
|
||||||
<Child>
|
<Child>
|
||||||
{shopName}
|
{shopName}
|
||||||
|
</Child>
|
||||||
|
<Child onClick={() => setModal("reports")}>Lihat laporan</Child>
|
||||||
|
<Child onClick={() => setModal("add_material")}>
|
||||||
|
Kelola stok
|
||||||
|
</Child>
|
||||||
|
|
||||||
|
<Child hasChildren>
|
||||||
|
<Child>Konfigurasi</Child>
|
||||||
|
<Child onClick={() => setModal("welcome_config")}>
|
||||||
|
Desain kafe
|
||||||
|
</Child>
|
||||||
|
<Child onClick={() => setModal("edit_tables")}>
|
||||||
|
Identifikasi kedai
|
||||||
|
</Child>
|
||||||
|
<Child onClick={() => setModal("payment_option")}>
|
||||||
|
Metode pembayaran
|
||||||
|
</Child>
|
||||||
|
</Child>
|
||||||
|
<Child hasChildren>
|
||||||
|
<Child>Kasir</Child>
|
||||||
|
<Child onClick={() => setModal("create_clerk")}>
|
||||||
|
+ Tambah
|
||||||
|
</Child>
|
||||||
|
{shopClerks &&
|
||||||
|
shopClerks.map((key, index) => (
|
||||||
|
<Child key={index}>
|
||||||
|
{shopClerks[index].username}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
removeConnectedGuestSides(
|
||||||
|
guestSides[index][3]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
remove
|
||||||
|
</button>
|
||||||
|
</Child>
|
||||||
|
))}
|
||||||
|
</Child>
|
||||||
</Child>
|
</Child>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{user.username !== undefined &&
|
||||||
|
user.cafeId == shopId &&
|
||||||
|
user.roleId === 2 && (
|
||||||
|
<Child hasChildren>
|
||||||
|
<Child>{shopName}</Child>
|
||||||
|
|
||||||
<Child>
|
<Child>
|
||||||
Mode Edit
|
Mode Edit
|
||||||
<Switch
|
<Switch
|
||||||
borderRadius={0}
|
borderRadius={0}
|
||||||
checked={isEditMode}
|
checked={isEditMode}
|
||||||
onChange={() => setIsEditMode(!isEditMode)}
|
onChange={() => setIsEditMode(!isEditMode)}
|
||||||
/>
|
/>
|
||||||
</Child>
|
</Child>
|
||||||
<Child onClick={() => setModal("reports")}>Lihat laporan</Child>
|
|
||||||
<Child onClick={() => setModal("add_material")}>
|
<Child onClick={() => setModal("add_material")}>
|
||||||
Kelola stok
|
Kelola stok
|
||||||
</Child>
|
</Child>
|
||||||
@@ -392,97 +445,43 @@ const Header = ({
|
|||||||
Metode pembayaran
|
Metode pembayaran
|
||||||
</Child>
|
</Child>
|
||||||
</Child>
|
</Child>
|
||||||
<Child hasChildren>
|
{user.username !== undefined &&
|
||||||
<Child>Kasir</Child>
|
user.roleId == 2 &&
|
||||||
<Child onClick={() => setModal("create_clerk")}>
|
user.cafeId == shopId && (
|
||||||
+ Tambah
|
<Child hasChildren>
|
||||||
</Child>
|
Tablet tamu
|
||||||
{shopClerks &&
|
<Child onClick={goToGuestSideLogin}>
|
||||||
shopClerks.map((key, index) => (
|
+ Tambah
|
||||||
<Child key={index}>
|
|
||||||
{shopClerks[index].username}
|
|
||||||
<button
|
|
||||||
onClick={() =>
|
|
||||||
removeConnectedGuestSides(
|
|
||||||
guestSides[index][3]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
remove
|
|
||||||
</button>
|
|
||||||
</Child>
|
</Child>
|
||||||
))}
|
{guestSides &&
|
||||||
</Child>
|
guestSides.map((key, index) => (
|
||||||
</Child>
|
<Child key={index}>
|
||||||
</>
|
guest side {index + 1}
|
||||||
)}
|
<button
|
||||||
{user.username !== undefined &&
|
onClick={() =>
|
||||||
user.cafeId == shopId &&
|
removeConnectedGuestSides(
|
||||||
user.roleId === 2 && (
|
guestSides[index][3]
|
||||||
<Child hasChildren>
|
)
|
||||||
<Child>{shopName}</Child>
|
}
|
||||||
|
>
|
||||||
<Child>
|
remove
|
||||||
Mode Edit
|
</button>
|
||||||
<Switch
|
</Child>
|
||||||
borderRadius={0}
|
))}
|
||||||
checked={isEditMode}
|
|
||||||
onChange={() => setIsEditMode(!isEditMode)}
|
|
||||||
/>
|
|
||||||
</Child>
|
|
||||||
<Child onClick={() => setModal("add_material")}>
|
|
||||||
Kelola stok
|
|
||||||
</Child>
|
|
||||||
|
|
||||||
<Child hasChildren>
|
|
||||||
<Child>Konfigurasi</Child>
|
|
||||||
<Child onClick={() => setModal("welcome_config")}>
|
|
||||||
Desain kafe
|
|
||||||
</Child>
|
|
||||||
<Child onClick={() => setModal("edit_tables")}>
|
|
||||||
Identifikasi kedai
|
|
||||||
</Child>
|
|
||||||
<Child onClick={() => setModal("payment_option")}>
|
|
||||||
Metode pembayaran
|
|
||||||
</Child>
|
|
||||||
</Child>
|
|
||||||
{user.username !== undefined &&
|
|
||||||
user.roleId == 2 &&
|
|
||||||
user.cafeId == shopId && (
|
|
||||||
<Child hasChildren>
|
|
||||||
Tablet tamu
|
|
||||||
<Child onClick={goToGuestSideLogin}>
|
|
||||||
+ Tambah
|
|
||||||
</Child>
|
</Child>
|
||||||
{guestSides &&
|
)}
|
||||||
guestSides.map((key, index) => (
|
|
||||||
<Child key={index}>
|
|
||||||
guest side {index + 1}
|
|
||||||
<button
|
|
||||||
onClick={() =>
|
|
||||||
removeConnectedGuestSides(
|
|
||||||
guestSides[index][3]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
remove
|
|
||||||
</button>
|
|
||||||
</Child>
|
|
||||||
))}
|
|
||||||
</Child>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Child onClick={() => setModal("reports")}>Laporan</Child>
|
<Child onClick={() => setModal("reports")}>Laporan</Child>
|
||||||
</Child>
|
</Child>
|
||||||
|
)}
|
||||||
|
{user.username !== undefined && (
|
||||||
|
<Child hasChildren ><Child onClick={isLogout}>Logout</Child></Child>
|
||||||
)}
|
)}
|
||||||
{user.username !== undefined && (
|
</ChildContainer>
|
||||||
<Child hasChildren ><Child onClick={isLogout}>Logout</Child></Child>
|
</Rectangle>
|
||||||
)}
|
)}
|
||||||
</ChildContainer>
|
</div>
|
||||||
</Rectangle>
|
</HeaderBar></HeaderBarbackground>
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</HeaderBar></HeaderBarbackground>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ const Item = ({
|
|||||||
const [itemDescription, setItemDescription] = useState(initialDescription);
|
const [itemDescription, setItemDescription] = useState(initialDescription);
|
||||||
const fileInputRef = useRef(null);
|
const fileInputRef = useRef(null);
|
||||||
|
|
||||||
|
const formatToRupiah = (value) => {
|
||||||
|
if (typeof value !== "number") return value;
|
||||||
|
return value.toLocaleString("id-ID");
|
||||||
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(imageUrl);
|
console.log(imageUrl);
|
||||||
console.log(selectedImage);
|
console.log(selectedImage);
|
||||||
@@ -156,7 +160,6 @@ const Item = ({
|
|||||||
</h3>
|
</h3>
|
||||||
{forInvoice && (
|
{forInvoice && (
|
||||||
<>
|
<>
|
||||||
<p className={styles.multiplySymbol}>x</p>
|
|
||||||
<p className={styles.qtyInvoice}>{itemQty}</p>
|
<p className={styles.qtyInvoice}>{itemQty}</p>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -208,12 +211,12 @@ const Item = ({
|
|||||||
marginLeft: '1rem',
|
marginLeft: '1rem',
|
||||||
marginRight: '0.5rem',
|
marginRight: '0.5rem',
|
||||||
marginTop: '0.125rem'
|
marginTop: '0.125rem'
|
||||||
}}>{promoPrice}</span>
|
}}>{formatToRupiah(promoPrice)}</span>
|
||||||
<span style={{
|
<span style={{
|
||||||
marginTop: '0.125rem',
|
marginTop: '0.125rem',
|
||||||
color: 'rgb(114, 114, 114)',
|
color: 'rgb(114, 114, 114)',
|
||||||
textDecoration: 'line-through'
|
textDecoration: 'line-through'
|
||||||
}}>{initialPrice}</span>
|
}}>{formatToRupiah(initialPrice)}</span>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
:
|
:
|
||||||
@@ -223,7 +226,7 @@ const Item = ({
|
|||||||
<span style={{
|
<span style={{
|
||||||
marginRight: '0.5rem',
|
marginRight: '0.5rem',
|
||||||
marginTop: '0.125rem'
|
marginTop: '0.125rem'
|
||||||
}}>{initialPrice}</span>
|
}}>{formatToRupiah(initialPrice)}</span>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
@@ -302,7 +305,7 @@ const Item = ({
|
|||||||
))}
|
))}
|
||||||
|
|
||||||
{forInvoice && (
|
{forInvoice && (
|
||||||
<p className={styles.itemPriceInvoice}>Rp {itemQty * (promoPrice > 0? promoPrice : itemPrice)}</p>
|
<p className={styles.itemPriceInvoice}>Rp {itemQty * (promoPrice > 0? formatToRupiah(promoPrice) : formatToRupiah(itemPrice))}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{forCart && (
|
{forCart && (
|
||||||
|
|||||||
@@ -13,9 +13,12 @@
|
|||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
color: rgba(88, 55, 50, 1);
|
color: rgba(88, 55, 50, 1);
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
box-sizing: border-box; /* Include padding and border in the element's total width */
|
box-sizing: border-box;
|
||||||
width: 100%; /* Ensure the item does not exceed the parent's width */
|
/* Include padding and border in the element's total width */
|
||||||
overflow: hidden; /* Prevent internal overflow */
|
width: 100%;
|
||||||
|
/* Ensure the item does not exceed the parent's width */
|
||||||
|
overflow: hidden;
|
||||||
|
/* Prevent internal overflow */
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
@@ -24,7 +27,7 @@
|
|||||||
/* border-top: 2px solid #00000017; */
|
/* border-top: 2px solid #00000017; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.notLast{
|
.notLast {
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
border-bottom: 2px solid #00000017;
|
border-bottom: 2px solid #00000017;
|
||||||
}
|
}
|
||||||
@@ -40,7 +43,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.itemInvoice:last-child {
|
.itemInvoice:last-child {
|
||||||
margin-bottom: 0; /* Remove margin-bottom for the last child */
|
margin-bottom: 0;
|
||||||
|
/* Remove margin-bottom for the last child */
|
||||||
}
|
}
|
||||||
|
|
||||||
.itemImage {
|
.itemImage {
|
||||||
@@ -102,7 +106,8 @@
|
|||||||
.itemName {
|
.itemName {
|
||||||
font-family: "Plus Jakarta Sans", sans-serif;
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
width: calc(100% - 15px); /* Adjust the width to prevent overflow */
|
width: calc(100% - 15px);
|
||||||
|
/* Adjust the width to prevent overflow */
|
||||||
font-size: 5vw;
|
font-size: 5vw;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
@@ -131,7 +136,8 @@
|
|||||||
font-family: "Plus Jakarta Sans", sans-serif;
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
width: calc(100% - 15px); /* Adjust the width to prevent overflow */
|
width: calc(100% - 15px);
|
||||||
|
/* Adjust the width to prevent overflow */
|
||||||
font-size: 3.3vw;
|
font-size: 3.3vw;
|
||||||
/* margin-bottom: 35px; */
|
/* margin-bottom: 35px; */
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
@@ -175,7 +181,8 @@
|
|||||||
font-family: "Plus Jakarta Sans", sans-serif;
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
width: 30px; /* Adjust the width to prevent overflow */
|
width: 30px;
|
||||||
|
/* Adjust the width to prevent overflow */
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -184,18 +191,19 @@
|
|||||||
|
|
||||||
.addButton {
|
.addButton {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
border: 2px solid #a8c7a9;
|
border: 2px solid #a8c7a9;
|
||||||
/* border: none; */
|
/* border: none; */
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 87px;
|
width: 87px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grayscale {
|
.grayscale {
|
||||||
filter: grayscale(100%);
|
filter: grayscale(100%);
|
||||||
}
|
}
|
||||||
@@ -203,6 +211,7 @@
|
|||||||
.disabled {
|
.disabled {
|
||||||
color: gray;
|
color: gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
.plusNegative {
|
.plusNegative {
|
||||||
width: 35px;
|
width: 35px;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
@@ -217,6 +226,7 @@
|
|||||||
left: -33px;
|
left: -33px;
|
||||||
top: 21px;
|
top: 21px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.remove {
|
.remove {
|
||||||
width: 25px;
|
width: 25px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
@@ -249,3 +259,267 @@
|
|||||||
left: 15px;
|
left: 15px;
|
||||||
right: 15px;
|
right: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.itemContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
/* gap: 10px; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-left: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
color: rgba(88, 55, 50, 1);
|
||||||
|
font-size: 32px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* Include padding and border in the element's total width */
|
||||||
|
width: 100%;
|
||||||
|
/* Ensure the item does not exceed the parent's width */
|
||||||
|
overflow: hidden;
|
||||||
|
/* Prevent internal overflow */
|
||||||
|
padding-top: 10px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item:not(.itemInvoice) {
|
||||||
|
/* border-top: 2px solid #00000017; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.notLast {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-bottom: 2px solid #00000017;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemInvoice {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
padding-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemInvoice:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
/* Remove margin-bottom for the last child */
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemImage {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageContainer {
|
||||||
|
position: relative;
|
||||||
|
width: 20%;
|
||||||
|
height: 20%;
|
||||||
|
border-radius: 12px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 15px;
|
||||||
|
left: 8px;
|
||||||
|
right: 8px;
|
||||||
|
bottom: 15px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
font-size: 3.3vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileInput {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemDetails {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemInvoiceDetails {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-top: -15px;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemName {
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-style: normal;
|
||||||
|
width: calc(100% - 15px);
|
||||||
|
/* Adjust the width to prevent overflow */
|
||||||
|
font-size: 5vw;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 0;
|
||||||
|
margin: 0 5px;
|
||||||
|
color: rgba(88, 55, 50, 1);
|
||||||
|
background-color: transparent;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemInvoiceName {
|
||||||
|
width: calc(260% - 15px);
|
||||||
|
background-color: transparent;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiplySymbol {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qtyInvoice {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemPrice {
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
width: calc(100% - 15px);
|
||||||
|
/* Adjust the width to prevent overflow */
|
||||||
|
font-size: 3.3vw;
|
||||||
|
/* margin-bottom: 35px; */
|
||||||
|
margin-left: 5px;
|
||||||
|
color: #3a3a3a;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemPriceInvoice {
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-left: 5px;
|
||||||
|
color: #d9c61c;
|
||||||
|
text-align: right;
|
||||||
|
margin-top: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemQty {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-left: 5px;
|
||||||
|
color: #a8c7a9;
|
||||||
|
fill: #a8c7a9;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemQtyValue {
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 19px;
|
||||||
|
margin-left: 1px;
|
||||||
|
margin-right: 1px;
|
||||||
|
width: 25px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemQtyInput {
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
width: 30px;
|
||||||
|
/* Adjust the width to prevent overflow */
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.addButton {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: 2px solid #a8c7a9;
|
||||||
|
/* border: none; */
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 87px;
|
||||||
|
height: 32px;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grayscale {
|
||||||
|
filter: grayscale(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabled {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plusNegative {
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
margin: 2.5px 0 -0.5px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plusNegative2 {
|
||||||
|
width: 84px;
|
||||||
|
height: 21px;
|
||||||
|
position: absolute;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
left: -33px;
|
||||||
|
top: 21px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
margin-top: -10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemInvoice .itemDetails {
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemInvoice .itemName,
|
||||||
|
.itemInvoice .itemPrice,
|
||||||
|
.itemInvoice .itemQty .qtyInvoice .multiplySymbol {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blank {
|
||||||
|
border: 1px solid #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notblank {
|
||||||
|
border: 1px solid #ffffff00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.createItem {
|
||||||
|
position: absolute;
|
||||||
|
left: 15px;
|
||||||
|
right: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -243,7 +243,7 @@ const ItemConfig = ({
|
|||||||
|
|
||||||
<ThreeDots height={20} width={20} />
|
<ThreeDots height={20} width={20} />
|
||||||
) : (
|
) : (
|
||||||
isBeingEdit ? 'Simpan' : 'Buat Item'
|
isBeingEdit ? 'Simpan' : 'Simpan'
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export default function ItemType({
|
|||||||
imageUrl,
|
imageUrl,
|
||||||
selected,
|
selected,
|
||||||
rectangular,
|
rectangular,
|
||||||
|
typeLength
|
||||||
}) {
|
}) {
|
||||||
const inputRef = useRef(null);
|
const inputRef = useRef(null);
|
||||||
const [namee, setName] = useState(name);
|
const [namee, setName] = useState(name);
|
||||||
@@ -68,7 +69,7 @@ export default function ItemType({
|
|||||||
: "item-type-nomargin"
|
: "item-type-nomargin"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
style={{ zIndex: blank ? 301 : "inherit" }}
|
style={{ zIndex: blank ? 301 : "inherit", width: `calc(${100 / (Math.min(typeLength, 3) + 1)}% - 10px)` }}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
onClick={
|
onClick={
|
||||||
|
|||||||
@@ -94,3 +94,102 @@
|
|||||||
.noborder {
|
.noborder {
|
||||||
border: 1px solid #ffffff00;
|
border: 1px solid #ffffff00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px){
|
||||||
|
.item-type {
|
||||||
|
width: calc(25% - 20px);
|
||||||
|
height: calc(30% - 20px);
|
||||||
|
margin: 1px 10px 0px;
|
||||||
|
overflow: visible;
|
||||||
|
text-align: center;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.item-type-rectangular {
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
height: calc(100% - 20px);
|
||||||
|
overflow: visible;
|
||||||
|
text-align: center;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: start;
|
||||||
|
position: relative; /* Ensure absolute positioning inside works */
|
||||||
|
}
|
||||||
|
.item-type-nomargin {
|
||||||
|
width: calc(25% - 20px);
|
||||||
|
height: calc(39% - 20px);
|
||||||
|
overflow: visible;
|
||||||
|
text-align: center;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative; /* Ensure absolute positioning inside works */
|
||||||
|
}
|
||||||
|
.item-type-rect {
|
||||||
|
position: relative;
|
||||||
|
height: 30%;
|
||||||
|
width: 30%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 15px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-type-name {
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
width: calc(25vw - 30px);
|
||||||
|
text-align: center;
|
||||||
|
background-color: transparent;
|
||||||
|
position: relative; /* Needed for positioning the button */
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-type-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-type-image-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.item-type-image-input {
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-type-create {
|
||||||
|
position: absolute;
|
||||||
|
top: 76%; /* Position below the input */
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
margin-top: 10px; /* Space between input and button */
|
||||||
|
width: 20vw;
|
||||||
|
text-align: center; /* Center button text */
|
||||||
|
}
|
||||||
|
|
||||||
|
.border {
|
||||||
|
border: 1px solid #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noborder {
|
||||||
|
border: 1px solid #ffffff00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
.item-type-lister {
|
.item-type-lister {
|
||||||
width: 100vw;
|
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
padding: 3px 0px;
|
padding: 3px 0px;
|
||||||
@@ -11,6 +10,7 @@
|
|||||||
-ms-overflow-style: none; /* IE and Edge */
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
scrollbar-width: none; /* Firefox */
|
scrollbar-width: none; /* Firefox */
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-type {
|
.item-type {
|
||||||
|
|||||||
@@ -141,13 +141,14 @@ const ItemTypeLister = ({
|
|||||||
itemTypes.map(
|
itemTypes.map(
|
||||||
(itemType) =>
|
(itemType) =>
|
||||||
(
|
(
|
||||||
itemType.itemList.length > 0 || (user && (user.user_id == shopOwnerId || user.cafeId == shopId))) && (
|
|
||||||
<ItemType
|
<ItemType
|
||||||
key={itemType.itemTypeId}
|
key={itemType.itemTypeId}
|
||||||
name={itemType.name}
|
name={itemType.name}
|
||||||
imageUrl={getImageUrl(itemType.image)}
|
imageUrl={getImageUrl(itemType.image)}
|
||||||
onClick={() => onFilterChange(itemType.itemTypeId)}
|
onClick={() => onFilterChange(itemType.itemTypeId)}
|
||||||
selected={filterId === itemType.itemTypeId}
|
selected={filterId === itemType.itemTypeId}
|
||||||
|
typeLength={itemTypes.length}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ export function MusicPlayer({ socket, shopId, user, shopOwnerId, isSpotifyNeedLo
|
|||||||
|
|
||||||
const [text, setText] = useState("Menunggu musik favoritmu");
|
const [text, setText] = useState("Menunggu musik favoritmu");
|
||||||
const textIndex = useRef(0);
|
const textIndex = useRef(0);
|
||||||
const [messages, setMessages] = useState(["Menunggu musik favoritmu", "Klik untuk putar musik favoritmu"]);
|
const [messages, setMessages] = useState(["Menunggu musik favoritmu", "Upgrade to use"]);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -376,7 +376,7 @@ export function MusicPlayer({ socket, shopId, user, shopOwnerId, isSpotifyNeedLo
|
|||||||
currentSong != null && currentSong[0]?.trackId != 'kCGs5_oCtBE' && currentSong[0]?.trackId != 'O8eYd7oAZtA' && currentSong[0]?.name != undefined
|
currentSong != null && currentSong[0]?.trackId != 'kCGs5_oCtBE' && currentSong[0]?.trackId != 'O8eYd7oAZtA' && currentSong[0]?.name != undefined
|
||||||
? `${currentSong[0]?.name} - ${currentSong[0]?.artist}`
|
? `${currentSong[0]?.name} - ${currentSong[0]?.artist}`
|
||||||
: "Menunggu musik favoritmu",
|
: "Menunggu musik favoritmu",
|
||||||
"Klik untuk putar musik favoritmu"
|
"Upgrade to use"
|
||||||
];
|
];
|
||||||
|
|
||||||
setMessages(newMessages);
|
setMessages(newMessages);
|
||||||
@@ -421,7 +421,7 @@ export function MusicPlayer({ socket, shopId, user, shopOwnerId, isSpotifyNeedLo
|
|||||||
return (
|
return (
|
||||||
<div className={`music-player`} style={{ marginBottom: `${viewing ? '-10px' : ''}` }}>
|
<div className={`music-player`} style={{ marginBottom: `${viewing ? '-10px' : ''}` }}>
|
||||||
<div
|
<div
|
||||||
onClick={toggleView}
|
// onClick={toggleView}
|
||||||
className="current-bgr"
|
className="current-bgr"
|
||||||
style={{ backgroundImage: `url(${backgroundImage})` }}
|
style={{ backgroundImage: `url(${backgroundImage})` }}
|
||||||
// style={{ backgroundImage: `url(${videoSrc != "" ? '' : backgroundImage})` }}
|
// style={{ backgroundImage: `url(${videoSrc != "" ? '' : backgroundImage})` }}
|
||||||
|
|||||||
@@ -10,9 +10,14 @@ import {
|
|||||||
|
|
||||||
import "../App.css";
|
import "../App.css";
|
||||||
|
|
||||||
import API_BASE_URL from '../config';
|
import API_BASE_URL from "../config";
|
||||||
import Watermark from "../components/Watermark";
|
import Watermark from "../components/Watermark";
|
||||||
import { getImageUrl, createItem, updateItem, moveItemType } from "../helpers/itemHelper.js";
|
import {
|
||||||
|
getImageUrl,
|
||||||
|
createItem,
|
||||||
|
updateItem,
|
||||||
|
moveItemType,
|
||||||
|
} from "../helpers/itemHelper.js";
|
||||||
import SearchInput from "../components/SearchInput";
|
import SearchInput from "../components/SearchInput";
|
||||||
import ItemTypeLister from "../components/ItemTypeLister";
|
import ItemTypeLister from "../components/ItemTypeLister";
|
||||||
import { MusicPlayer } from "../components/MusicPlayer";
|
import { MusicPlayer } from "../components/MusicPlayer";
|
||||||
@@ -23,11 +28,17 @@ import Switch from "react-switch";
|
|||||||
|
|
||||||
import { ThreeDots } from "react-loader-spinner";
|
import { ThreeDots } from "react-loader-spinner";
|
||||||
|
|
||||||
import { getLocalStorage, updateLocalStorage, removeLocalStorage } from "../helpers/localStorageHelpers";
|
import {
|
||||||
|
getLocalStorage,
|
||||||
|
updateLocalStorage,
|
||||||
|
removeLocalStorage,
|
||||||
|
} from "../helpers/localStorageHelpers";
|
||||||
import { unsubscribeUser } from "../helpers/subscribeHelpers.js";
|
import { unsubscribeUser } from "../helpers/subscribeHelpers.js";
|
||||||
import WelcomePage from "./WelcomePage.js";
|
import WelcomePage from "./WelcomePage.js";
|
||||||
import { useNavigationHelpers } from "../helpers/navigationHelpers";
|
import { useNavigationHelpers } from "../helpers/navigationHelpers";
|
||||||
|
|
||||||
|
import Cart from "./Cart";
|
||||||
|
|
||||||
function CafePage({
|
function CafePage({
|
||||||
shopId,
|
shopId,
|
||||||
table,
|
table,
|
||||||
@@ -48,21 +59,21 @@ function CafePage({
|
|||||||
queue,
|
queue,
|
||||||
cartItemsLength,
|
cartItemsLength,
|
||||||
totalPrice,
|
totalPrice,
|
||||||
lastTransaction
|
lastTransaction,
|
||||||
|
shop,
|
||||||
|
totalItemsCount,
|
||||||
|
deviceType,
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const token = searchParams.get("token");
|
const token = searchParams.get("token");
|
||||||
const { shopIdentifier, tableCode } = useParams();
|
const { shopIdentifier, tableCode } = useParams();
|
||||||
sendParam({ shopIdentifier, tableCode });
|
sendParam({ shopIdentifier, tableCode });
|
||||||
|
|
||||||
const {
|
const { goToCart, goToTransactions } = useNavigationHelpers(
|
||||||
goToCart,
|
shopIdentifier,
|
||||||
goToTransactions
|
table.tableCode
|
||||||
} = useNavigationHelpers(shopIdentifier, table.tableCode);
|
);
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
@@ -90,10 +101,20 @@ function CafePage({
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
|
const [isTablet, setIsTablet] = useState(window.innerWidth >= 768);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleResize = () => {
|
||||||
|
setIsTablet(window.innerWidth >= 768);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("resize", handleResize);
|
||||||
|
return () => window.removeEventListener("resize", handleResize);
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (window.gtag && shopIdentifier) {
|
if (window.gtag && shopIdentifier) {
|
||||||
window.gtag('event', 'page_view', {
|
window.gtag("event", "page_view", {
|
||||||
page_title: `Cafe - ${shopIdentifier}`,
|
page_title: `Cafe - ${shopIdentifier}`,
|
||||||
page_location: window.location.href,
|
page_location: window.location.href,
|
||||||
page_path: `/` + shopIdentifier,
|
page_path: `/` + shopIdentifier,
|
||||||
@@ -116,22 +137,26 @@ function CafePage({
|
|||||||
// checkWelcomePageConfig();
|
// checkWelcomePageConfig();
|
||||||
}, [welcomePageConfig]);
|
}, [welcomePageConfig]);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function fetchData() {
|
function fetchData() {
|
||||||
console.log(user.user_id == shopOwnerId)
|
console.log(user.user_id == shopOwnerId);
|
||||||
setModal("create_item");
|
setModal("create_item");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(getLocalStorage('auth'))
|
console.log(getLocalStorage("auth"));
|
||||||
if (getLocalStorage("auth") != null) {
|
if (getLocalStorage("auth") != null) {
|
||||||
const executeFetch = async () => {
|
const executeFetch = async () => {
|
||||||
while (user.length == 0) {
|
while (user.length == 0) {
|
||||||
await new Promise((resolve) => setTimeout(resolve, 100)); // Wait until the user is not null
|
await new Promise((resolve) => setTimeout(resolve, 100)); // Wait until the user is not null
|
||||||
}
|
}
|
||||||
console.log(user)
|
console.log(user);
|
||||||
console.log('open')
|
console.log("open");
|
||||||
if (user.length != 0 && user.user_id == shopOwnerId && shopItems.length == 0) fetchData();
|
if (
|
||||||
|
user.length != 0 &&
|
||||||
|
user.user_id == shopOwnerId &&
|
||||||
|
shopItems.length == 0
|
||||||
|
)
|
||||||
|
fetchData();
|
||||||
};
|
};
|
||||||
executeFetch();
|
executeFetch();
|
||||||
}
|
}
|
||||||
@@ -154,13 +179,39 @@ function CafePage({
|
|||||||
socket.on("joined-room", (response) => {
|
socket.on("joined-room", (response) => {
|
||||||
const { isSpotifyNeedLogin, isExceededDeadline } = response;
|
const { isSpotifyNeedLogin, isExceededDeadline } = response;
|
||||||
setNeedSpotifyLogin(isSpotifyNeedLogin);
|
setNeedSpotifyLogin(isSpotifyNeedLogin);
|
||||||
if (isExceededDeadline) setModal("message", { captMessage: 'Kafe sedang tidak tersedia' });
|
if (isExceededDeadline)
|
||||||
|
setModal("message", { captMessage: "Kafe sedang tidak tersedia" });
|
||||||
setIsExceededDeadline(isExceededDeadline);
|
setIsExceededDeadline(isExceededDeadline);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket) fetchData();
|
if (socket) fetchData();
|
||||||
}, [socket]);
|
}, [socket]);
|
||||||
|
useEffect(() => {
|
||||||
|
const isTablet = window.innerWidth >= 768;
|
||||||
|
|
||||||
|
const handleFirstClick = async () => {
|
||||||
|
if (
|
||||||
|
isTablet &&
|
||||||
|
document.fullscreenEnabled &&
|
||||||
|
!document.fullscreenElement
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
await document.documentElement.requestFullscreen();
|
||||||
|
document.removeEventListener("click", handleFirstClick);
|
||||||
|
} catch (err) {
|
||||||
|
console.warn("Gagal masuk fullscreen:", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tambahkan listener satu kali
|
||||||
|
document.addEventListener("click", handleFirstClick);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("click", handleFirstClick);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleGetStarted = () => {
|
const handleGetStarted = () => {
|
||||||
setIsStarted(false);
|
setIsStarted(false);
|
||||||
@@ -175,16 +226,19 @@ function CafePage({
|
|||||||
const newItems = [...shopItems];
|
const newItems = [...shopItems];
|
||||||
|
|
||||||
let targetIndex;
|
let targetIndex;
|
||||||
if (direction === 'up' && index > 0) {
|
if (direction === "up" && index > 0) {
|
||||||
targetIndex = index - 1;
|
targetIndex = index - 1;
|
||||||
} else if (direction === 'down' && index < newItems.length - 1) {
|
} else if (direction === "down" && index < newItems.length - 1) {
|
||||||
targetIndex = index + 1;
|
targetIndex = index + 1;
|
||||||
}
|
}
|
||||||
console.log(index);
|
console.log(index);
|
||||||
console.log(targetIndex);
|
console.log(targetIndex);
|
||||||
if (targetIndex !== undefined) {
|
if (targetIndex !== undefined) {
|
||||||
// Swap items
|
// Swap items
|
||||||
[newItems[index], newItems[targetIndex]] = [newItems[targetIndex], newItems[index]];
|
[newItems[index], newItems[targetIndex]] = [
|
||||||
|
newItems[targetIndex],
|
||||||
|
newItems[index],
|
||||||
|
];
|
||||||
newItems[index].order = targetIndex;
|
newItems[index].order = targetIndex;
|
||||||
newItems[targetIndex].order = index;
|
newItems[targetIndex].order = index;
|
||||||
|
|
||||||
@@ -192,9 +246,14 @@ function CafePage({
|
|||||||
|
|
||||||
// Call the API to move the item type
|
// Call the API to move the item type
|
||||||
try {
|
try {
|
||||||
await moveItemType(itemTypeId, previousItems[targetIndex].itemTypeId, index, targetIndex);
|
await moveItemType(
|
||||||
|
itemTypeId,
|
||||||
|
previousItems[targetIndex].itemTypeId,
|
||||||
|
index,
|
||||||
|
targetIndex
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error moving item type:', error);
|
console.error("Error moving item type:", error);
|
||||||
// Revert the changes if the backend fails
|
// Revert the changes if the backend fails
|
||||||
setShopItems(previousItems);
|
setShopItems(previousItems);
|
||||||
}
|
}
|
||||||
@@ -224,156 +283,265 @@ function CafePage({
|
|||||||
isFullscreen={true}
|
isFullscreen={true}
|
||||||
/>
|
/>
|
||||||
) : ( */}
|
) : ( */}
|
||||||
<div className={`Cafe ${isExceededDeadline ? 'grayscale' : ''}`}>
|
<div
|
||||||
|
className={`Cafe ${isExceededDeadline ? "grayscale" : ""}`}
|
||||||
|
style={{
|
||||||
|
display: isTablet ? "flex" : "block",
|
||||||
|
flexDirection: "row",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{API_BASE_URL != "https://dev.api.kedaimaster.com" &&
|
||||||
|
API_BASE_URL != "https://api.kedaimaster.com" && (
|
||||||
|
<div className="Watermark"></div>
|
||||||
|
)}
|
||||||
|
<div style={{ width: isTablet ? "60%" : "100%" }}>
|
||||||
|
<div className="App-header">
|
||||||
|
<Header
|
||||||
|
HeaderText={"Menu"}
|
||||||
|
showProfile={true}
|
||||||
|
setModal={setModal}
|
||||||
|
isLogout={handleLogout}
|
||||||
|
shopId={shopId}
|
||||||
|
shopName={shopName}
|
||||||
|
shopImage={config.image}
|
||||||
|
shopOwnerId={shopOwnerId}
|
||||||
|
shopClerks={shopClerks}
|
||||||
|
tableCode={table.tableCode}
|
||||||
|
user={user}
|
||||||
|
guestSides={guestSides}
|
||||||
|
guestSideOfClerk={guestSideOfClerk}
|
||||||
|
removeConnectedGuestSides={removeConnectedGuestSides}
|
||||||
|
setIsEditMode={(e) => setIsEditMode(e)}
|
||||||
|
isEditMode={isEditMode}
|
||||||
|
/>
|
||||||
|
<MusicPlayer
|
||||||
|
socket={socket}
|
||||||
|
shopId={shopId}
|
||||||
|
user={user}
|
||||||
|
shopOwnerId={shopOwnerId}
|
||||||
|
isSpotifyNeedLogin={isSpotifyNeedLogin}
|
||||||
|
queue={queue}
|
||||||
|
setModal={setModal}
|
||||||
|
/>
|
||||||
|
{user.username !== undefined &&
|
||||||
|
(user.cafeId === shopId || user.user_id === shopOwnerId) &&
|
||||||
|
(user.roleId === 1 || user.roleId === 2) && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#5c7c5c",
|
||||||
|
padding: "7px 28px",
|
||||||
|
margin: "0 10px",
|
||||||
|
borderRadius: "15px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
textShadow: "2px 2px 4px rgba(0, 0, 0, 0.7)",
|
||||||
|
fontSize: "16px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Mode Edit
|
||||||
|
<Switch
|
||||||
|
borderRadius={0}
|
||||||
|
checked={isEditMode}
|
||||||
|
onChange={() => setIsEditMode(!isEditMode)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{API_BASE_URL != 'https://dev.api.kedaimaster.com' && API_BASE_URL != 'https://api.kedaimaster.com' &&
|
<ItemTypeLister
|
||||||
<div className="Watermark"></div>
|
user={user}
|
||||||
}
|
shopOwnerId={shopOwnerId}
|
||||||
<div className="App-header">
|
shopId={shopId}
|
||||||
<Header
|
itemTypes={shopItems}
|
||||||
HeaderText={"Menu"}
|
setShopItems={setShopItems}
|
||||||
showProfile={true}
|
isEditMode={isEditMode}
|
||||||
setModal={setModal}
|
onFilterChange={(e) => setFilterId(e)}
|
||||||
isLogout={handleLogout}
|
filterId={filterId}
|
||||||
shopId={shopId}
|
beingEditedType={beingEditedType}
|
||||||
shopName={shopName}
|
setBeingEditedType={setBeingEditedType}
|
||||||
shopImage={config.image}
|
/>
|
||||||
shopOwnerId={shopOwnerId}
|
{/* <div style={{ marginTop: "15px" }}></div> */}
|
||||||
shopClerks={shopClerks}
|
<div>
|
||||||
tableCode={table.tableCode}
|
{shopItems
|
||||||
user={user}
|
.filter(
|
||||||
guestSides={guestSides}
|
(itemType) =>
|
||||||
guestSideOfClerk={guestSideOfClerk}
|
filterId == 0 || itemType.itemTypeId === filterId
|
||||||
removeConnectedGuestSides={removeConnectedGuestSides}
|
)
|
||||||
setIsEditMode={(e) => setIsEditMode(e)}
|
.map((itemType, index) => (
|
||||||
isEditMode={isEditMode}
|
<ItemLister
|
||||||
/>
|
index={index}
|
||||||
<MusicPlayer
|
indexTotal={shopItems.length}
|
||||||
socket={socket}
|
shopId={shopId}
|
||||||
shopId={shopId}
|
shopOwnerId={shopOwnerId}
|
||||||
user={user}
|
user={user}
|
||||||
shopOwnerId={shopOwnerId}
|
key={itemType.itemTypeId}
|
||||||
isSpotifyNeedLogin={isSpotifyNeedLogin}
|
itemTypeId={itemType.itemTypeId}
|
||||||
queue={queue}
|
typeName={itemType.name}
|
||||||
setModal={setModal}
|
typeImage={itemType.image}
|
||||||
/>{
|
setShopItems={setShopItems}
|
||||||
user.username !== undefined &&
|
itemList={itemType.itemList}
|
||||||
(user.cafeId === shopId || user.user_id === shopOwnerId) &&
|
typeVisibility={itemType.visibility}
|
||||||
(user.roleId === 1 || user.roleId === 2) && (
|
moveItemTypeUp={(e) =>
|
||||||
<div style={{
|
moveItemTypeHandler(e, "up", index)
|
||||||
backgroundColor: '#5c7c5c',
|
}
|
||||||
padding: '7px 28px',
|
moveItemTypeDown={(e) =>
|
||||||
margin: '0 10px',
|
moveItemTypeHandler(e, "down", index)
|
||||||
borderRadius: '15px',
|
}
|
||||||
display: 'flex',
|
isEditMode={isEditMode}
|
||||||
alignItems: 'center',
|
beingEditedType={beingEditedType}
|
||||||
justifyContent: 'space-between',
|
setBeingEditedType={setBeingEditedType}
|
||||||
textShadow: '2px 2px 4px rgba(0, 0, 0, 0.7)',
|
raw={isEditMode || filterId == 0 ? false : true}
|
||||||
fontSize: '16px'
|
handleCreateItem={(
|
||||||
}}>
|
itemTypeID,
|
||||||
Mode Edit
|
|
||||||
<Switch
|
|
||||||
borderRadius={0}
|
|
||||||
checked={isEditMode}
|
|
||||||
onChange={() => setIsEditMode(!isEditMode)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
<ItemTypeLister
|
|
||||||
user={user}
|
|
||||||
shopOwnerId={shopOwnerId}
|
|
||||||
shopId={shopId}
|
|
||||||
itemTypes={shopItems}
|
|
||||||
setShopItems={setShopItems}
|
|
||||||
isEditMode={isEditMode}
|
|
||||||
onFilterChange={(e) => setFilterId(e)}
|
|
||||||
filterId={filterId}
|
|
||||||
beingEditedType={beingEditedType}
|
|
||||||
setBeingEditedType={setBeingEditedType}
|
|
||||||
/>
|
|
||||||
{/* <div style={{ marginTop: "15px" }}></div> */}
|
|
||||||
<div>
|
|
||||||
{shopItems
|
|
||||||
.filter(
|
|
||||||
(itemType) =>
|
|
||||||
filterId == 0 || itemType.itemTypeId === filterId
|
|
||||||
)
|
|
||||||
.map((itemType, index) => (
|
|
||||||
<ItemLister
|
|
||||||
index={index}
|
|
||||||
indexTotal={shopItems.length}
|
|
||||||
shopId={shopId}
|
|
||||||
shopOwnerId={shopOwnerId}
|
|
||||||
user={user}
|
|
||||||
key={itemType.itemTypeId}
|
|
||||||
itemTypeId={itemType.itemTypeId}
|
|
||||||
typeName={itemType.name}
|
|
||||||
typeImage={itemType.image}
|
|
||||||
setShopItems={setShopItems}
|
|
||||||
itemList={itemType.itemList}
|
|
||||||
typeVisibility={itemType.visibility}
|
|
||||||
moveItemTypeUp={(e) => moveItemTypeHandler(e, 'up', index)}
|
|
||||||
moveItemTypeDown={(e) => moveItemTypeHandler(e, 'down', index)}
|
|
||||||
isEditMode={isEditMode}
|
|
||||||
beingEditedType={beingEditedType}
|
|
||||||
setBeingEditedType={setBeingEditedType}
|
|
||||||
raw={isEditMode || filterId == 0 ? false : true}
|
|
||||||
handleCreateItem={(
|
|
||||||
itemTypeID,
|
|
||||||
name,
|
|
||||||
price,
|
|
||||||
selectedImage,
|
|
||||||
description,
|
|
||||||
promoPrice,
|
|
||||||
) =>
|
|
||||||
createItem(
|
|
||||||
shopId,
|
|
||||||
name,
|
name,
|
||||||
price,
|
price,
|
||||||
selectedImage,
|
selectedImage,
|
||||||
itemTypeID,
|
|
||||||
description,
|
description,
|
||||||
promoPrice,
|
promoPrice
|
||||||
)
|
) =>
|
||||||
}
|
createItem(
|
||||||
handleUpdateItem={(itemId, name, price, selectedImage, description, promoPrice) =>
|
shopId,
|
||||||
updateItem(itemId, name, price, selectedImage, description, promoPrice)
|
name,
|
||||||
}
|
price,
|
||||||
/>
|
selectedImage,
|
||||||
))}
|
itemTypeID,
|
||||||
{!isEditMode && (user.username || cartItemsLength > 0) &&
|
description,
|
||||||
<div style={{ marginTop: '10px', height: '40px', position: 'sticky', bottom: '40px', display: 'flex', justifyContent: 'center', alignItems: 'center', textAlign: 'center' }}>
|
promoPrice
|
||||||
{(lastTransaction != null || cartItemsLength > 0) &&
|
)
|
||||||
<div onClick={goToCart} style={{ backgroundColor: '#73a585', width: user.username ? '55vw' : '70vw', height: '40px', borderRadius: '30px', display: 'flex', justifyContent: 'space-between', padding: '0 20px' }}>
|
}
|
||||||
<div style={{ display: 'flex', flexWrap: 'wrap', alignContent: 'center' }}>{lastTransaction != null && '+'}{cartItemsLength} item</div>
|
handleUpdateItem={(
|
||||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', width: '130px' }}>
|
itemId,
|
||||||
{((lastTransaction == null || lastTransaction?.payment_type != 'paylater')) ?
|
name,
|
||||||
<span style={{ whiteSpace: 'nowrap' }}>Rp{totalPrice}</span>
|
price,
|
||||||
:
|
selectedImage,
|
||||||
<span style={{ whiteSpace: 'nowrap' }}>Open bill</span>
|
description,
|
||||||
}
|
promoPrice
|
||||||
<div style={{ display: 'flex', alignItems: 'center', marginLeft: '5px', width: '20px' }}>
|
) =>
|
||||||
<svg viewBox="0 0 34 34" style={{ fill: 'white', marginTop: '4px' }}>
|
updateItem(
|
||||||
<path d="M9.79175 24.75C8.09591 24.75 6.72383 26.1375 6.72383 27.8333C6.72383 29.5292 8.09591 30.9167 9.79175 30.9167C11.4876 30.9167 12.8751 29.5292 12.8751 27.8333C12.8751 26.1375 11.4876 24.75 9.79175 24.75ZM0.541748 0.0833435V3.16668H3.62508L9.17508 14.8679L7.09383 18.645C6.84717 19.0767 6.70842 19.5854 6.70842 20.125C6.70842 21.8208 8.09591 23.2083 9.79175 23.2083H28.2917V20.125H10.4392C10.2234 20.125 10.0538 19.9554 10.0538 19.7396L10.1001 19.5546L11.4876 17.0417H22.973C24.1292 17.0417 25.1467 16.4096 25.6709 15.4538L31.1901 5.44834C31.3134 5.23251 31.3751 4.97043 31.3751 4.70834C31.3751 3.86043 30.6813 3.16668 29.8334 3.16668H7.03217L5.583 0.0833435H0.541748ZM25.2084 24.75C23.5126 24.75 22.1405 26.1375 22.1405 27.8333C22.1405 29.5292 23.5126 30.9167 25.2084 30.9167C26.9042 30.9167 28.2917 29.5292 28.2917 27.8333C28.2917 26.1375 26.9042 24.75 25.2084 24.75Z"></path>
|
itemId,
|
||||||
</svg>
|
name,
|
||||||
|
price,
|
||||||
|
selectedImage,
|
||||||
|
description,
|
||||||
|
promoPrice
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
{!isEditMode && !isTablet && (user.username || cartItemsLength > 0) && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginTop: "10px",
|
||||||
|
height: "40px",
|
||||||
|
position: "sticky",
|
||||||
|
bottom: "40px",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{(lastTransaction != null || cartItemsLength > 0) && (
|
||||||
|
<div
|
||||||
|
onClick={goToCart}
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#73a585",
|
||||||
|
width: user.username ? "55vw" : "70vw",
|
||||||
|
height: "40px",
|
||||||
|
borderRadius: "30px",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
padding: "0 20px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
alignContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{lastTransaction != null && "+"}
|
||||||
|
{cartItemsLength} item
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "flex-end",
|
||||||
|
width: "130px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{lastTransaction == null ||
|
||||||
|
lastTransaction?.payment_type != "paylater" ? (
|
||||||
|
<span style={{ whiteSpace: "nowrap" }}>
|
||||||
|
Rp{totalPrice}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span style={{ whiteSpace: "nowrap" }}>
|
||||||
|
Open bill
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
marginLeft: "5px",
|
||||||
|
width: "20px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 34 34"
|
||||||
|
style={{ fill: "white", marginTop: "4px" }}
|
||||||
|
>
|
||||||
|
<path d="M9.79175 24.75C8.09591 24.75 6.72383 26.1375 6.72383 27.8333C6.72383 29.5292 8.09591 30.9167 9.79175 30.9167C11.4876 30.9167 12.8751 29.5292 12.8751 27.8333C12.8751 26.1375 11.4876 24.75 9.79175 24.75ZM0.541748 0.0833435V3.16668H3.62508L9.17508 14.8679L7.09383 18.645C6.84717 19.0767 6.70842 19.5854 6.70842 20.125C6.70842 21.8208 8.09591 23.2083 9.79175 23.2083H28.2917V20.125H10.4392C10.2234 20.125 10.0538 19.9554 10.0538 19.7396L10.1001 19.5546L11.4876 17.0417H22.973C24.1292 17.0417 25.1467 16.4096 25.6709 15.4538L31.1901 5.44834C31.3134 5.23251 31.3751 4.97043 31.3751 4.70834C31.3751 3.86043 30.6813 3.16668 29.8334 3.16668H7.03217L5.583 0.0833435H0.541748ZM25.2084 24.75C23.5126 24.75 22.1405 26.1375 22.1405 27.8333C22.1405 29.5292 23.5126 30.9167 25.2084 30.9167C26.9042 30.9167 28.2917 29.5292 28.2917 27.8333C28.2917 26.1375 26.9042 24.75 25.2084 24.75Z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
}
|
{user.username && (
|
||||||
{user.username &&
|
<div
|
||||||
<div onClick={goToTransactions} style={{ backgroundColor: '#73a585', width: '15vw', height: '40px', borderRadius: '30px', display: 'flex', justifyContent: 'center', marginLeft: lastTransaction != null || cartItemsLength > 0 ? '6px' : '0px' }}>
|
onClick={goToTransactions}
|
||||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: '38px', marginRight: '5px' }}>
|
style={{
|
||||||
<div style={{ display: 'flex', alignItems: 'center', marginLeft: '5px', width: '20px' }}>
|
backgroundColor: "#73a585",
|
||||||
<svg viewBox="0 0 512 512">
|
width: "15vw",
|
||||||
<g
|
height: "40px",
|
||||||
transform="translate(0 460) scale(0.09 -0.09)"
|
borderRadius: "30px",
|
||||||
style={{ fill: 'white', marginTop: '4px' }}
|
display: "flex",
|
||||||
stroke="none"
|
justifyContent: "center",
|
||||||
>
|
marginLeft:
|
||||||
<path
|
lastTransaction != null || cartItemsLength > 0
|
||||||
d="M1639 5107 c-47 -13 -70 -28 -177 -109 -119 -90 -246 -102 -381 -34
|
? "6px"
|
||||||
|
: "0px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
width: "38px",
|
||||||
|
marginRight: "5px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
marginLeft: "5px",
|
||||||
|
width: "20px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg viewBox="0 0 512 512">
|
||||||
|
<g
|
||||||
|
transform="translate(0 460) scale(0.09 -0.09)"
|
||||||
|
style={{ fill: "white", marginTop: "4px" }}
|
||||||
|
stroke="none"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M1639 5107 c-47 -13 -70 -28 -177 -109 -119 -90 -246 -102 -381 -34
|
||||||
-53 27 -83 36 -121 36 -88 0 -167 -57 -190 -138 -8 -26 -10 -620 -8 -1982 l3
|
-53 27 -83 36 -121 36 -88 0 -167 -57 -190 -138 -8 -26 -10 -620 -8 -1982 l3
|
||||||
-1945 24 -38 c13 -21 42 -50 64 -65 l41 -27 1535 -5 1536 -5 58 -22 c158 -60
|
-1945 24 -38 c13 -21 42 -50 64 -65 l41 -27 1535 -5 1536 -5 58 -22 c158 -60
|
||||||
291 -205 322 -352 10 -45 74 -108 119 -117 78 -14 154 25 182 93 12 27 14 398
|
291 -205 322 -352 10 -45 74 -108 119 -117 78 -14 154 25 182 93 12 27 14 398
|
||||||
@@ -389,23 +557,49 @@ function CafePage({
|
|||||||
20 6 475 9 1183 8 l1150 -2 38 -24z m4 -903 c62 -41 88 -90 88 -168 0 -78 -26
|
20 6 475 9 1183 8 l1150 -2 38 -24z m4 -903 c62 -41 88 -90 88 -168 0 -78 -26
|
||||||
-127 -88 -168 l-41 -27 -665 0 -666 0 -38 24 c-76 47 -111 140 -88 229 14 51
|
-127 -88 -168 l-41 -27 -665 0 -666 0 -38 24 c-76 47 -111 140 -88 229 14 51
|
||||||
76 117 123 131 20 6 291 9 684 8 l650 -2 41 -27z"
|
76 117 123 131 20 6 291 9 684 8 l650 -2 41 -27z"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
d="M592 489 c-47 -14 -109 -79 -123 -131 -33 -122 37 -265 159 -325 l57
|
d="M592 489 c-47 -14 -109 -79 -123 -131 -33 -122 37 -265 159 -325 l57
|
||||||
-28 1815 -2 c1736 -2 1813 -2 1765 15 -125 43 -186 126 -205 279 -12 89
|
-28 1815 -2 c1736 -2 1813 -2 1765 15 -125 43 -186 126 -205 279 -12 89
|
||||||
-39 138 -97 174 l-38 24 -1650 2 c-1023 1 -1662 -2 -1683 -8z"
|
-39 138 -97 174 l-38 24 -1650 2 c-1023 1 -1662 -2 -1683 -8z"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
}
|
</div>
|
||||||
</div>
|
)}
|
||||||
}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/* <Watermark /> */}
|
||||||
</div>
|
</div>
|
||||||
<Watermark />
|
{isTablet &&
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: "40%",
|
||||||
|
position: "fixed",
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
zIndex: 199
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Cart
|
||||||
|
shopId={shopId}
|
||||||
|
shop={shop}
|
||||||
|
table={table}
|
||||||
|
setModal={setModal}
|
||||||
|
sendParam={sendParam}
|
||||||
|
socket={socket}
|
||||||
|
totalItemsCount={totalItemsCount}
|
||||||
|
deviceType={deviceType}
|
||||||
|
shopItems={shopItems}
|
||||||
|
setShopItems={setShopItems}
|
||||||
|
isTablet={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
{/* )} */}
|
{/* )} */}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
handlePaymentFromGuestSide,
|
handlePaymentFromGuestSide,
|
||||||
handlePaymentFromGuestDevice,
|
handlePaymentFromGuestDevice,
|
||||||
handleExtendFromGuestDevice,
|
handleExtendFromGuestDevice,
|
||||||
handleCloseBillFromGuestDevice
|
handleCloseBillFromGuestDevice,
|
||||||
} from "../helpers/transactionHelpers";
|
} from "../helpers/transactionHelpers";
|
||||||
|
|
||||||
import { getItemsByCafeId } from "../helpers/cartHelpers.js";
|
import { getItemsByCafeId } from "../helpers/cartHelpers.js";
|
||||||
@@ -22,15 +22,22 @@ import { getItemsByCafeId } from "../helpers/cartHelpers.js";
|
|||||||
import Dropdown from "./Dropdown.js";
|
import Dropdown from "./Dropdown.js";
|
||||||
import { useNavigationHelpers } from "../helpers/navigationHelpers";
|
import { useNavigationHelpers } from "../helpers/navigationHelpers";
|
||||||
|
|
||||||
|
export default function Invoice({
|
||||||
export default function Invoice({ shopId, setModal, table, sendParam, deviceType, socket, shopItems, setShopItems }) {
|
shopId,
|
||||||
|
setModal,
|
||||||
|
table,
|
||||||
|
sendParam,
|
||||||
|
deviceType,
|
||||||
|
socket,
|
||||||
|
shopItems,
|
||||||
|
setShopItems,
|
||||||
|
isTablet
|
||||||
|
}) {
|
||||||
const { shopIdentifier, tableCode } = useParams();
|
const { shopIdentifier, tableCode } = useParams();
|
||||||
|
|
||||||
sendParam({ shopIdentifier, tableCode });
|
sendParam({ shopIdentifier, tableCode });
|
||||||
|
|
||||||
const {
|
const { goToShop } = useNavigationHelpers(shopIdentifier, table.tableCode);
|
||||||
goToShop
|
|
||||||
} = useNavigationHelpers(shopIdentifier, table.tableCode);
|
|
||||||
|
|
||||||
const [cartItems, setCartItems] = useState([]);
|
const [cartItems, setCartItems] = useState([]);
|
||||||
const [totalPrice, setTotalPrice] = useState(0);
|
const [totalPrice, setTotalPrice] = useState(0);
|
||||||
@@ -51,14 +58,14 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
const fetchPaymentMethods = async () => {
|
const fetchPaymentMethods = async () => {
|
||||||
try {
|
try {
|
||||||
const methods = await getPaymentMethods(shopId);
|
const methods = await getPaymentMethods(shopId);
|
||||||
console.log(methods)
|
console.log(methods);
|
||||||
const lastTransaction = JSON.parse(localStorage.getItem('lastTransaction'));
|
const lastTransaction = JSON.parse(
|
||||||
if (lastTransaction?.payment_type == 'paylater') methods.isOpenBillAvailable = false;
|
localStorage.getItem("lastTransaction")
|
||||||
setPaymentMethods(methods)
|
);
|
||||||
|
if (lastTransaction?.payment_type == "paylater")
|
||||||
} catch (err) {
|
methods.isOpenBillAvailable = false;
|
||||||
|
setPaymentMethods(methods);
|
||||||
}
|
} catch (err) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (shopId) {
|
if (shopId) {
|
||||||
@@ -70,29 +77,27 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
const fetchCartItems = async () => {
|
const fetchCartItems = async () => {
|
||||||
try {
|
try {
|
||||||
const cart = getItemsByCafeId(shopId);
|
const cart = getItemsByCafeId(shopId);
|
||||||
const itemMap = new Map(cart.map(item => [item.itemId, item.qty]));
|
const itemMap = new Map(cart.map((item) => [item.itemId, item.qty]));
|
||||||
|
|
||||||
// Step 2: Filter and transform shopItems
|
// Step 2: Filter and transform shopItems
|
||||||
const filteredItems = shopItems
|
const filteredItems = shopItems
|
||||||
.map(itemType => ({
|
.map((itemType) => ({
|
||||||
itemTypeId: itemType.itemTypeId,
|
itemTypeId: itemType.itemTypeId,
|
||||||
cafeId: itemType.cafeId,
|
cafeId: itemType.cafeId,
|
||||||
typeName: itemType.name,
|
typeName: itemType.name,
|
||||||
itemList: itemType.itemList
|
itemList: itemType.itemList
|
||||||
.filter(item => itemMap.has(item.itemId)) // Keep only items in getItemsByCafeId
|
.filter((item) => itemMap.has(item.itemId)) // Keep only items in getItemsByCafeId
|
||||||
.map(item => ({
|
.map((item) => ({
|
||||||
itemId: item.itemId,
|
itemId: item.itemId,
|
||||||
price: (item.promoPrice ? item.promoPrice : item.price),
|
price: item.promoPrice ? item.promoPrice : item.price,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
image: item.image,
|
image: item.image,
|
||||||
qty: itemMap.get(item.itemId), // Add qty from getItemsByCafeId
|
qty: itemMap.get(item.itemId), // Add qty from getItemsByCafeId
|
||||||
availability: item.availability
|
availability: item.availability,
|
||||||
}))
|
})),
|
||||||
}))
|
}))
|
||||||
.filter(itemType => itemType.itemList.length > 0); // Remove empty itemTypes
|
.filter((itemType) => itemType.itemList.length > 0); // Remove empty itemTypes
|
||||||
console.log(filteredItems)
|
console.log(filteredItems);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Update local storage by removing unavailable items
|
// Update local storage by removing unavailable items
|
||||||
const updatedLocalStorage =
|
const updatedLocalStorage =
|
||||||
@@ -120,7 +125,10 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
return (
|
return (
|
||||||
total +
|
total +
|
||||||
itemType.itemList.reduce((subtotal, item) => {
|
itemType.itemList.reduce((subtotal, item) => {
|
||||||
return subtotal + item.qty * (item.promoPrice ? item.promoPrice : item.price);
|
return (
|
||||||
|
subtotal +
|
||||||
|
item.qty * (item.promoPrice ? item.promoPrice : item.price)
|
||||||
|
);
|
||||||
}, 0)
|
}, 0)
|
||||||
);
|
);
|
||||||
}, 0);
|
}, 0);
|
||||||
@@ -128,7 +136,7 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
setCartItems(filteredItems);
|
setCartItems(filteredItems);
|
||||||
setTotalPrice(totalPrice);
|
setTotalPrice(totalPrice);
|
||||||
setIsLoading(false)
|
setIsLoading(false);
|
||||||
}, 100); //delay is in milliseconds
|
}, 100); //delay is in milliseconds
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching cart items:", error);
|
console.error("Error fetching cart items:", error);
|
||||||
@@ -138,18 +146,17 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
|
|
||||||
fetchCartItems();
|
fetchCartItems();
|
||||||
|
|
||||||
|
|
||||||
const getNewestCartItems = async () => {
|
const getNewestCartItems = async () => {
|
||||||
try {
|
try {
|
||||||
// Fetch items from the cart details (latest state)
|
// Fetch items from the cart details (latest state)
|
||||||
const items = await getCartDetails(shopId);
|
const items = await getCartDetails(shopId);
|
||||||
|
|
||||||
// Loop through each item type in the items from the cart details
|
// Loop through each item type in the items from the cart details
|
||||||
items.forEach(itemType => {
|
items.forEach((itemType) => {
|
||||||
itemType.itemList.forEach(item => {
|
itemType.itemList.forEach((item) => {
|
||||||
// Loop through the shopItems and find the corresponding itemId
|
// Loop through the shopItems and find the corresponding itemId
|
||||||
shopItems.forEach(shopItemType => {
|
shopItems.forEach((shopItemType) => {
|
||||||
shopItemType.itemList.forEach(shopItem => {
|
shopItemType.itemList.forEach((shopItem) => {
|
||||||
if (shopItem.itemId === item.itemId) {
|
if (shopItem.itemId === item.itemId) {
|
||||||
// Update shopItems with the new data from items (e.g., availability, price)
|
// Update shopItems with the new data from items (e.g., availability, price)
|
||||||
shopItem.availability = item.availability;
|
shopItem.availability = item.availability;
|
||||||
@@ -179,7 +186,8 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
}, 100); // delay is in milliseconds
|
}, 100); // delay is in milliseconds
|
||||||
|
|
||||||
// Update local storage by removing unavailable items and updating prices
|
// Update local storage by removing unavailable items and updating prices
|
||||||
const updatedLocalStorage = JSON.parse(localStorage.getItem("cart")) || [];
|
const updatedLocalStorage =
|
||||||
|
JSON.parse(localStorage.getItem("cart")) || [];
|
||||||
const newLocalStorage = updatedLocalStorage.map((cafe) => {
|
const newLocalStorage = updatedLocalStorage.map((cafe) => {
|
||||||
if (cafe.cafeId === shopId) {
|
if (cafe.cafeId === shopId) {
|
||||||
return {
|
return {
|
||||||
@@ -194,8 +202,10 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
// Update the price in the local storage item
|
// Update the price in the local storage item
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
price: updatedItem.promoPrice ? updatedItem.promoPrice : updatedItem.price,
|
price: updatedItem.promoPrice
|
||||||
availability: updatedItem.availability
|
? updatedItem.promoPrice
|
||||||
|
: updatedItem.price,
|
||||||
|
availability: updatedItem.availability,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +241,10 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
return (
|
return (
|
||||||
total +
|
total +
|
||||||
itemType.itemList.reduce((subtotal, item) => {
|
itemType.itemList.reduce((subtotal, item) => {
|
||||||
return subtotal + item.qty * (item.promoPrice ? item.promoPrice : item.price);
|
return (
|
||||||
|
subtotal +
|
||||||
|
item.qty * (item.promoPrice ? item.promoPrice : item.price)
|
||||||
|
);
|
||||||
}, 0)
|
}, 0)
|
||||||
);
|
);
|
||||||
}, 0);
|
}, 0);
|
||||||
@@ -240,13 +253,12 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
console.error("Error fetching cart items:", error);
|
console.error("Error fetching cart items:", error);
|
||||||
// Handle error if needed
|
// Handle error if needed
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
getNewestCartItems();
|
getNewestCartItems();
|
||||||
}, [shopId]);
|
}, [shopId, localStorage.getItem('cart')]);
|
||||||
|
|
||||||
const handlePayCloseBill = async (orderMethod) =>{
|
const handlePayCloseBill = async (orderMethod) => {
|
||||||
setIsPaymentLoading(true);
|
setIsPaymentLoading(true);
|
||||||
console.log("tipe" + deviceType);
|
console.log("tipe" + deviceType);
|
||||||
if (transactionData) {
|
if (transactionData) {
|
||||||
@@ -257,7 +269,7 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
socketId
|
socketId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const handlePay = async (orderMethod) => {
|
const handlePay = async (orderMethod) => {
|
||||||
setIsPaymentLoading(true);
|
setIsPaymentLoading(true);
|
||||||
@@ -271,39 +283,36 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
orderMethod,
|
orderMethod,
|
||||||
socketId
|
socketId
|
||||||
);
|
);
|
||||||
localStorage.removeItem('lastTransaction')
|
localStorage.removeItem("lastTransaction");
|
||||||
// Dispatch the custom event
|
// Dispatch the custom event
|
||||||
window.dispatchEvent(new Event("localStorageUpdated"));
|
window.dispatchEvent(new Event("localStorageUpdated"));
|
||||||
|
} else if (deviceType == "clerk") {
|
||||||
|
const pay = await handlePaymentFromClerk(
|
||||||
|
shopId,
|
||||||
|
email,
|
||||||
|
orderMethod,
|
||||||
|
orderType,
|
||||||
|
tableNumber
|
||||||
|
);
|
||||||
|
} else if (deviceType == "guestSide") {
|
||||||
|
const pay = await handlePaymentFromGuestSide(
|
||||||
|
shopId,
|
||||||
|
email,
|
||||||
|
orderMethod,
|
||||||
|
orderType,
|
||||||
|
tableNumber
|
||||||
|
);
|
||||||
|
} else if (deviceType == "guestDevice") {
|
||||||
|
const socketId = socket.id;
|
||||||
|
const pay = await handlePaymentFromGuestDevice(
|
||||||
|
shopId,
|
||||||
|
orderMethod,
|
||||||
|
orderType,
|
||||||
|
table.tableNo || tableNumber,
|
||||||
|
textareaRef.current.value,
|
||||||
|
socketId
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
|
||||||
if (deviceType == "clerk") {
|
|
||||||
const pay = await handlePaymentFromClerk(
|
|
||||||
shopId,
|
|
||||||
email,
|
|
||||||
orderMethod,
|
|
||||||
orderType,
|
|
||||||
tableNumber
|
|
||||||
);
|
|
||||||
} else if (deviceType == "guestSide") {
|
|
||||||
const pay = await handlePaymentFromGuestSide(
|
|
||||||
shopId,
|
|
||||||
email,
|
|
||||||
orderMethod,
|
|
||||||
orderType,
|
|
||||||
tableNumber
|
|
||||||
);
|
|
||||||
} else if (deviceType == "guestDevice") {
|
|
||||||
const socketId = socket.id;
|
|
||||||
const pay = await handlePaymentFromGuestDevice(
|
|
||||||
shopId,
|
|
||||||
orderMethod,
|
|
||||||
orderType,
|
|
||||||
table.tableNo || tableNumber,
|
|
||||||
textareaRef.current.value,
|
|
||||||
socketId
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("transaction from " + deviceType + "success");
|
console.log("transaction from " + deviceType + "success");
|
||||||
setIsPaymentLoading(false);
|
setIsPaymentLoading(false);
|
||||||
@@ -331,26 +340,34 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
}, [table]);
|
}, [table]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(localStorage.getItem('cart'))
|
console.log(localStorage.getItem("cart"));
|
||||||
console.log(cartItems)
|
console.log(cartItems);
|
||||||
|
|
||||||
if (localStorage.getItem('cart') == null || localStorage.getItem('cart') == '' || localStorage.getItem('cart') == '[]') return;
|
if (
|
||||||
|
localStorage.getItem("cart") == null ||
|
||||||
|
localStorage.getItem("cart") == "" ||
|
||||||
|
localStorage.getItem("cart") == "[]"
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
// Parse the local storage cart
|
// Parse the local storage cart
|
||||||
const localStorageCart = JSON.parse(localStorage.getItem('cart'));
|
const localStorageCart = JSON.parse(localStorage.getItem("cart"));
|
||||||
console.log(localStorageCart)
|
console.log(localStorageCart);
|
||||||
// Create a set of itemIds from the local storage cart for quick lookup
|
// Create a set of itemIds from the local storage cart for quick lookup
|
||||||
const localStorageItemIds = new Set(localStorageCart[0].items.map(item => item.itemId));
|
const localStorageItemIds = new Set(
|
||||||
|
localStorageCart[0].items.map((item) => item.itemId)
|
||||||
|
);
|
||||||
|
|
||||||
// Filter out items from cartItems that do not exist in the local storage cart
|
// Filter out items from cartItems that do not exist in the local storage cart
|
||||||
const updatedCartItems = cartItems.map(itemType => ({
|
const updatedCartItems = cartItems.map((itemType) => ({
|
||||||
...itemType,
|
...itemType,
|
||||||
itemList: itemType.itemList.filter(item => localStorageItemIds.has(item.itemId))
|
itemList: itemType.itemList.filter((item) =>
|
||||||
|
localStorageItemIds.has(item.itemId)
|
||||||
|
),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
setCartItems(updatedCartItems);
|
setCartItems(updatedCartItems);
|
||||||
|
|
||||||
|
|
||||||
const totalPrice = updatedCartItems.reduce((total, itemType) => {
|
const totalPrice = updatedCartItems.reduce((total, itemType) => {
|
||||||
return (
|
return (
|
||||||
total +
|
total +
|
||||||
@@ -360,8 +377,7 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
);
|
);
|
||||||
}, 0);
|
}, 0);
|
||||||
setTotalPrice(totalPrice);
|
setTotalPrice(totalPrice);
|
||||||
}, [localStorage.getItem('cart')]);
|
}, [localStorage.getItem("cart")]);
|
||||||
|
|
||||||
|
|
||||||
const handleOrderTypeChange = (event) => {
|
const handleOrderTypeChange = (event) => {
|
||||||
setOrderType(event.target.value);
|
setOrderType(event.target.value);
|
||||||
@@ -379,44 +395,81 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
setEmail(event.target.value);
|
setEmail(event.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const transactionData = JSON.parse(localStorage.getItem('lastTransaction'));
|
const transactionData = JSON.parse(localStorage.getItem("lastTransaction"));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.Invoice} style={{ height: (getItemsByCafeId(shopId).length > 0 ? '' : '100vh'), minHeight: (getItemsByCafeId(shopId).length > 0 ? '100vh' : '') }}>
|
<div
|
||||||
|
className={styles.Invoice}
|
||||||
|
style={{
|
||||||
|
height: getItemsByCafeId(shopId).length > 0 ? "" : "100vh",
|
||||||
|
minHeight: getItemsByCafeId(shopId).length > 0 ? "100vh" : "",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
onClick={goToShop}
|
||||||
|
style={{
|
||||||
|
marginLeft: "22px",
|
||||||
|
marginTop: "49px",
|
||||||
|
marginRight: "10px",
|
||||||
|
display: "flex",
|
||||||
|
flexWrap: "nowrap",
|
||||||
|
alignItems: "center",
|
||||||
|
fontSize: "25px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{!isTablet &&
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="30"
|
||||||
|
height="30"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
>
|
||||||
|
<path d="M48,256c0,114.87,93.13,208,208,208s208-93.13,208-208S370.87,48,256,48,48,141.13,48,256Zm212.65-91.36a16,16,0,0,1,.09,22.63L208.42,240H342a16,16,0,0,1,0,32H208.42l52.32,52.73A16,16,0,1,1,238,347.27l-79.39-80a16,16,0,0,1,0-22.54l79.39-80A16,16,0,0,1,260.65,164.64Z" />
|
||||||
|
</svg>
|
||||||
|
}
|
||||||
|
Keranjang
|
||||||
|
</div>
|
||||||
|
|
||||||
<div onClick={goToShop} style={{ marginLeft: '22px', marginTop: '49px', marginRight: '10px', display: 'flex', flexWrap: 'nowrap', alignItems: 'center', fontSize: '25px' }} ><svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 512 512"><path d="M48,256c0,114.87,93.13,208,208,208s208-93.13,208-208S370.87,48,256,48,48,141.13,48,256Zm212.65-91.36a16,16,0,0,1,.09,22.63L208.42,240H342a16,16,0,0,1,0,32H208.42l52.32,52.73A16,16,0,1,1,238,347.27l-79.39-80a16,16,0,0,1,0-22.54l79.39-80A16,16,0,0,1,260.65,164.64Z" /></svg>Keranjang</div>
|
{transactionData == null && getItemsByCafeId(shopId).length < 1 ? (
|
||||||
|
<div
|
||||||
{(transactionData == null && getItemsByCafeId(shopId).length < 1) ?
|
style={{
|
||||||
<div style={{ height: '75vh', display: 'flex', justifyContent: 'center', flexDirection: 'column', alignContent: 'center', alignItems: 'center' }}>
|
height: "75vh",
|
||||||
<div style={{ width: '50%' }}>
|
display: "flex",
|
||||||
<svg
|
justifyContent: "center",
|
||||||
viewBox="0 0 32 32"
|
flexDirection: "column",
|
||||||
style={{ fill: "#8F8787" }}
|
alignContent: "center",
|
||||||
>
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ width: isTablet ? "30%":"50%" }}>
|
||||||
|
<svg viewBox="0 0 32 32" style={{ fill: "#8F8787" }}>
|
||||||
<path d="M9.79175 24.75C8.09591 24.75 6.72383 26.1375 6.72383 27.8333C6.72383 29.5292 8.09591 30.9167 9.79175 30.9167C11.4876 30.9167 12.8751 29.5292 12.8751 27.8333C12.8751 26.1375 11.4876 24.75 9.79175 24.75ZM0.541748 0.0833435V3.16668H3.62508L9.17508 14.8679L7.09383 18.645C6.84717 19.0767 6.70842 19.5854 6.70842 20.125C6.70842 21.8208 8.09591 23.2083 9.79175 23.2083H28.2917V20.125H10.4392C10.2234 20.125 10.0538 19.9554 10.0538 19.7396L10.1001 19.5546L11.4876 17.0417H22.973C24.1292 17.0417 25.1467 16.4096 25.6709 15.4538L31.1901 5.44834C31.3134 5.23251 31.3751 4.97043 31.3751 4.70834C31.3751 3.86043 30.6813 3.16668 29.8334 3.16668H7.03217L5.583 0.0833435H0.541748ZM25.2084 24.75C23.5126 24.75 22.1405 26.1375 22.1405 27.8333C22.1405 29.5292 23.5126 30.9167 25.2084 30.9167C26.9042 30.9167 28.2917 29.5292 28.2917 27.8333C28.2917 26.1375 26.9042 24.75 25.2084 24.75Z" />
|
<path d="M9.79175 24.75C8.09591 24.75 6.72383 26.1375 6.72383 27.8333C6.72383 29.5292 8.09591 30.9167 9.79175 30.9167C11.4876 30.9167 12.8751 29.5292 12.8751 27.8333C12.8751 26.1375 11.4876 24.75 9.79175 24.75ZM0.541748 0.0833435V3.16668H3.62508L9.17508 14.8679L7.09383 18.645C6.84717 19.0767 6.70842 19.5854 6.70842 20.125C6.70842 21.8208 8.09591 23.2083 9.79175 23.2083H28.2917V20.125H10.4392C10.2234 20.125 10.0538 19.9554 10.0538 19.7396L10.1001 19.5546L11.4876 17.0417H22.973C24.1292 17.0417 25.1467 16.4096 25.6709 15.4538L31.1901 5.44834C31.3134 5.23251 31.3751 4.97043 31.3751 4.70834C31.3751 3.86043 30.6813 3.16668 29.8334 3.16668H7.03217L5.583 0.0833435H0.541748ZM25.2084 24.75C23.5126 24.75 22.1405 26.1375 22.1405 27.8333C22.1405 29.5292 23.5126 30.9167 25.2084 30.9167C26.9042 30.9167 28.2917 29.5292 28.2917 27.8333C28.2917 26.1375 26.9042 24.75 25.2084 24.75Z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h1 style={{ fontSize: '120%', color: '#8F8787' }}>Tidak ada item di keranjang</h1>
|
<h1 style={{ fontSize: "120%", color: "#8F8787" }}>
|
||||||
|
Tidak ada item di keranjang
|
||||||
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
:
|
) : isLoading ? (
|
||||||
(isLoading ? <></> :
|
<></>
|
||||||
<>
|
) : (
|
||||||
{getItemsByCafeId(shopId).length > 0 &&
|
<>
|
||||||
<div className={styles.RoundedRectangle}>
|
{getItemsByCafeId(shopId).length > 0 && (
|
||||||
{cartItems.map((itemType) => (
|
<div className={styles.RoundedRectangle}>
|
||||||
<ItemLister
|
{cartItems.map((itemType) => (
|
||||||
shopId={shopId}
|
<ItemLister
|
||||||
forInvoice={true}
|
shopId={shopId}
|
||||||
key={itemType.id}
|
forInvoice={true}
|
||||||
typeName={itemType.typeName}
|
key={itemType.id}
|
||||||
itemList={itemType.itemList}
|
typeName={itemType.typeName}
|
||||||
/>
|
itemList={itemType.itemList}
|
||||||
))}
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
{table.tableNo != null && (
|
{table.tableNo != null && (
|
||||||
<div className={styles.OrderTypeContainer}>
|
<div className={styles.OrderTypeContainer}>
|
||||||
<span htmlFor="orderType">Diantar ke {table.tableNo}</span>
|
<span htmlFor="orderType">Diantar ke {table.tableNo}</span>
|
||||||
{/* <select
|
{/* <select
|
||||||
id="orderType"
|
id="orderType"
|
||||||
value={orderType}
|
value={orderType}
|
||||||
onChange={handleOrderTypeChange}
|
onChange={handleOrderTypeChange}
|
||||||
@@ -427,166 +480,230 @@ export default function Invoice({ shopId, setModal, table, sendParam, deviceType
|
|||||||
<option value="pickup">Pickup</option>
|
<option value="pickup">Pickup</option>
|
||||||
{table == null && <option value="serve">Serve</option>}
|
{table == null && <option value="serve">Serve</option>}
|
||||||
</select> */}
|
</select> */}
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{orderType === "serve" && table.length < 1 && (
|
|
||||||
<div className={styles.OrderTypeContainer}>
|
|
||||||
<span htmlFor="orderType">Serve to:</span>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder="Table Number"
|
|
||||||
value={tableNumber}
|
|
||||||
onChange={handleTableNumberChange}
|
|
||||||
className={styles.TableNumberInput}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className={styles.NoteContainer}>
|
|
||||||
<span>Atas Nama :</span>
|
|
||||||
<span></span>
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className={styles.NoteContainer} >
|
{orderType === "serve" && table.length < 1 && (
|
||||||
|
<div className={styles.OrderTypeContainer}>
|
||||||
|
<span htmlFor="orderType">Serve to:</span>
|
||||||
<input
|
<input
|
||||||
className={styles.NoteInput}
|
type="text"
|
||||||
placeholder="Tambahkan catatan..."
|
placeholder="Table Number"
|
||||||
|
value={tableNumber}
|
||||||
|
onChange={handleTableNumberChange}
|
||||||
|
className={styles.TableNumberInput}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className={styles.NoteContainer}style={{height: '18px'}}>
|
<div className={styles.NoteContainer}>
|
||||||
<span>Catatan :</span>
|
<span>Atas Nama :</span>
|
||||||
<span></span>
|
<span></span>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.NoteContainer}>
|
|
||||||
<textarea
|
|
||||||
ref={textareaRef}
|
|
||||||
className={styles.NoteInput}
|
|
||||||
placeholder="Tambahkan catatan..."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
|
|
||||||
{transactionData &&
|
<div className={styles.NoteContainer}>
|
||||||
<div className={styles.RoundedRectangle} style={{ backgroundColor: '#c3c3c3', fontSize: '15px', display: 'flex', justifyContent: 'space-between' }}>
|
<input
|
||||||
{transactionData.payment_type != 'paylater' ?
|
className={styles.NoteInput}
|
||||||
<>
|
placeholder="Tambahkan catatan..."
|
||||||
<div onClick={() => setModal('transaction_item', { transactionId: transactionData.transactionId })} className={styles.AddedLastTransaction}>
|
/>
|
||||||
Pembayaran akan ditambahkan ke transaksi sebelumnya
|
|
||||||
</div>
|
|
||||||
<div className={styles.CancelAddedLastTransaction} onClick={() => { window.location.reload(); localStorage.removeItem('lastTransaction') }}>
|
|
||||||
<svg
|
|
||||||
style={{ width: '40px', height: '40px' }}
|
|
||||||
className={styles['plusNegative2']}
|
|
||||||
clipRule="evenodd"
|
|
||||||
fillRule="evenodd"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeMiterlimit="2"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="m12.002 2c5.518 0 9.998 4.48 9.998 9.998 0 5.517-4.48 9.997-9.998 9.997-5.517 0-9.997-4.48-9.997-9.997 0-5.518 4.48-9.998 9.997-9.998zm0 1.5c-4.69 0-8.497 3.808-8.497 8.498s3.807 8.497 8.497 8.497 8.498-3.807 8.498-8.497-3.808-8.498-8.498-8.498zm-.747 7.75h-3.5c-.414 0-.75.336-.75.75s.336.75.75.75h3.5v3.5c0 .414.336.75.75.75s.75-.336.75-.75v-3.5h3.5c.414 0 .75-.336.75-.75s-.336-.75-.75-.75h-3.5v-3.5c0-.414-.336-.75-.75-.75s-.75.336-.75.75z"
|
|
||||||
fillRule="nonzero"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
:
|
|
||||||
|
|
||||||
<div className={styles.AddedLastTransaction}>
|
|
||||||
<div>
|
|
||||||
Open bill
|
|
||||||
<div onClick={() => setModal('transaction_item', { transactionId: transactionData.transactionId })}>
|
|
||||||
Lihat tagihan
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{getItemsByCafeId(shopId).length > 0 ?
|
|
||||||
|
|
||||||
<button className={styles.PayButton3} onClick={() => handlePay(orderMethod)}>
|
|
||||||
{isPaymentLoading ? (
|
|
||||||
<ColorRing height="50" width="50" color="white" />
|
|
||||||
) : (
|
|
||||||
<div>
|
|
||||||
{transactionData ?
|
|
||||||
|
|
||||||
<span>Tambahkan</span>
|
|
||||||
:
|
|
||||||
<span>Pesan</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
<span>Rp{totalPrice}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
:
|
|
||||||
|
|
||||||
<button className={styles.PayButton3} style={{ backgroundColor: 'rgb(42 145 24)', letterSpacing: '1px' }} onClick={goToShop}>
|
|
||||||
<div>
|
|
||||||
<span>Tambahkan item lain</span>
|
|
||||||
</div>
|
|
||||||
</button>}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
<div className={styles.PaymentOption}>
|
<div className={styles.NoteContainer} style={{ height: "18px" }}>
|
||||||
<div className={styles.TotalContainer}>
|
<span>Catatan :</span>
|
||||||
<span>Pembayaran</span>
|
<span></span>
|
||||||
<span>
|
|
||||||
{paymentMethods != null && <Dropdown setDropdownKey={() => setDropdownKey(dropdownKey + 1)} paymentMethods={paymentMethods} onChange={handleOrderMethodChange} />}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
{transactionData && transactionData.payment_type === 'paylater' ?
|
|
||||||
<div style={{ display: 'flex', paddingLeft: '25px', paddingRight: '25px', marginTop: '17px' }}>
|
|
||||||
<button className={styles.PayButton} onClick={() => handlePayCloseBill(orderMethod)}>
|
|
||||||
{isPaymentLoading ? (
|
|
||||||
<ColorRing height="50" width="50" color="white" />
|
|
||||||
) : (
|
|
||||||
<div>
|
|
||||||
<span>Tutup bill</span>
|
|
||||||
|
|
||||||
<span>Rp{
|
<div className={styles.NoteContainer}>
|
||||||
transactionData.DetailedTransactions.reduce((total, transaction) => {
|
<textarea
|
||||||
return total + (transaction.promoPrice == 0 || transaction.promoPrice == null
|
ref={textareaRef}
|
||||||
? transaction.price * transaction.qty
|
className={styles.NoteInput}
|
||||||
: transaction.promoPrice * transaction.qty);
|
placeholder="Tambahkan catatan..."
|
||||||
}, 0)
|
/>
|
||||||
}</span>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
|
|
||||||
<div style={{ display: 'flex', paddingLeft: '25px', paddingRight: '25px', marginTop: '17px' }}>
|
|
||||||
<button className={styles.PayButton} onClick={() => handlePay(orderMethod)}>
|
|
||||||
{isPaymentLoading ? (
|
|
||||||
<ColorRing height="50" width="50" color="white" />
|
|
||||||
) : (
|
|
||||||
<div>
|
|
||||||
{transactionData ?
|
|
||||||
|
|
||||||
<span>Tambahkan</span>
|
|
||||||
:
|
|
||||||
<span>Pesan</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
<span>Rp{totalPrice}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.PaymentOptionMargin}></div>
|
)}
|
||||||
</>
|
|
||||||
)
|
{transactionData && (
|
||||||
}
|
<div
|
||||||
|
className={styles.RoundedRectangle}
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#c3c3c3",
|
||||||
|
fontSize: "15px",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{transactionData.payment_type != "paylater" ? (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
onClick={() =>
|
||||||
|
setModal("transaction_item", {
|
||||||
|
transactionId: transactionData.transactionId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
className={styles.AddedLastTransaction}
|
||||||
|
>
|
||||||
|
Pembayaran akan ditambahkan ke transaksi sebelumnya
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={styles.CancelAddedLastTransaction}
|
||||||
|
onClick={() => {
|
||||||
|
window.location.reload();
|
||||||
|
localStorage.removeItem("lastTransaction");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
style={{ width: "40px", height: "40px" }}
|
||||||
|
className={styles["plusNegative2"]}
|
||||||
|
clipRule="evenodd"
|
||||||
|
fillRule="evenodd"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeMiterlimit="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="m12.002 2c5.518 0 9.998 4.48 9.998 9.998 0 5.517-4.48 9.997-9.998 9.997-5.517 0-9.997-4.48-9.997-9.997 0-5.518 4.48-9.998 9.997-9.998zm0 1.5c-4.69 0-8.497 3.808-8.497 8.498s3.807 8.497 8.497 8.497 8.498-3.807 8.498-8.497-3.808-8.498-8.498-8.498zm-.747 7.75h-3.5c-.414 0-.75.336-.75.75s.336.75.75.75h3.5v3.5c0 .414.336.75.75.75s.75-.336.75-.75v-3.5h3.5c.414 0 .75-.336.75-.75s-.336-.75-.75-.75h-3.5v-3.5c0-.414-.336-.75-.75-.75s-.75.336-.75.75z"
|
||||||
|
fillRule="nonzero"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className={styles.AddedLastTransaction}>
|
||||||
|
<div>
|
||||||
|
Open bill
|
||||||
|
<div
|
||||||
|
onClick={() =>
|
||||||
|
setModal("transaction_item", {
|
||||||
|
transactionId: transactionData.transactionId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Lihat tagihan
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{getItemsByCafeId(shopId).length > 0 ? (
|
||||||
|
<button
|
||||||
|
className={styles.PayButton3}
|
||||||
|
onClick={() => handlePay(orderMethod)}
|
||||||
|
>
|
||||||
|
{isPaymentLoading ? (
|
||||||
|
<ColorRing height="40" width="40" color="white" />
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
{transactionData ? (
|
||||||
|
<span>Tambahkan</span>
|
||||||
|
) : (
|
||||||
|
<span>Pesan</span>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<span>Rp{totalPrice}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
className={styles.PayButton3}
|
||||||
|
style={{
|
||||||
|
backgroundColor: "rgb(42 145 24)",
|
||||||
|
letterSpacing: "1px",
|
||||||
|
}}
|
||||||
|
onClick={goToShop}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<span>Tambahkan item lain</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className={styles.PaymentOption}>
|
||||||
|
<div className={styles.TotalContainer}>
|
||||||
|
<span>Pembayaran</span>
|
||||||
|
<span>
|
||||||
|
{paymentMethods != null && (
|
||||||
|
<Dropdown
|
||||||
|
setDropdownKey={() => setDropdownKey(dropdownKey + 1)}
|
||||||
|
paymentMethods={paymentMethods}
|
||||||
|
onChange={handleOrderMethodChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{transactionData && transactionData.payment_type === "paylater" ? (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
paddingLeft: "25px",
|
||||||
|
paddingRight: "25px",
|
||||||
|
marginTop: "17px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className={styles.PayButton}
|
||||||
|
onClick={() => handlePayCloseBill(orderMethod)}
|
||||||
|
>
|
||||||
|
{isPaymentLoading ? (
|
||||||
|
<ColorRing height="50" width="50" color="white" />
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
<span>Tutup bill</span>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
Rp
|
||||||
|
{transactionData.DetailedTransactions.reduce(
|
||||||
|
(total, transaction) => {
|
||||||
|
return (
|
||||||
|
total +
|
||||||
|
(transaction.promoPrice == 0 ||
|
||||||
|
transaction.promoPrice == null
|
||||||
|
? transaction.price * transaction.qty
|
||||||
|
: transaction.promoPrice * transaction.qty)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
0
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
paddingLeft: "25px",
|
||||||
|
paddingRight: "25px",
|
||||||
|
marginTop: "17px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className={styles.PayButton}
|
||||||
|
onClick={() => handlePay(orderMethod)}
|
||||||
|
>
|
||||||
|
{isPaymentLoading ? (
|
||||||
|
<ColorRing height="50" width="50" color="white" />
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
{transactionData ? (
|
||||||
|
<span>Tambahkan</span>
|
||||||
|
) : (
|
||||||
|
<span>Pesan</span>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<span>Rp{totalPrice}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className={styles.PaymentOptionMargin}></div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
.Invoice {
|
.Invoice {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@@ -40,11 +42,10 @@
|
|||||||
font-size: calc(10px + 2vmin);
|
font-size: calc(10px + 2vmin);
|
||||||
color: rgba(88, 55, 50, 1);
|
color: rgba(88, 55, 50, 1);
|
||||||
border-radius: 15px 15px 0 0;
|
border-radius: 15px 15px 0 0;
|
||||||
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
left: 0;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.PaymentOptionMargin {
|
.PaymentOptionMargin {
|
||||||
@@ -59,6 +60,10 @@
|
|||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 220px;
|
height: 220px;
|
||||||
|
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 40%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.TotalContainer {
|
.TotalContainer {
|
||||||
@@ -92,13 +97,13 @@
|
|||||||
margin-bottom: 23px;
|
margin-bottom: 23px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.PayButton div{
|
.PayButton div {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
}
|
}
|
||||||
.PayButton3{
|
.PayButton3 {
|
||||||
font-family: "Plus Jakarta Sans", sans-serif;
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -115,8 +120,7 @@
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.PayButton3 div {
|
||||||
.PayButton3 div{
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
@@ -201,22 +205,275 @@
|
|||||||
overflow-wrap: break-word; /* Ensure text wraps */
|
overflow-wrap: break-word; /* Ensure text wraps */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.AddedLastTransaction {
|
||||||
.AddedLastTransaction{
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
margin-bottom: 7px;
|
margin-bottom: 7px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
.AddedLastTransaction div{
|
.AddedLastTransaction div {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
.CancelAddedLastTransaction{
|
.CancelAddedLastTransaction {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
margin-right: 30px;
|
margin-right: 30px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.Invoice {
|
||||||
|
overflow-x: hidden;
|
||||||
|
background-color: white;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
font-size: calc(10px + 2vmin);
|
||||||
|
color: rgba(88, 55, 50, 1);
|
||||||
|
background-color: #e9e9e9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.TotalContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 10px 30px;
|
||||||
|
padding-top: 20px;
|
||||||
|
/* margin-bottom: 17px; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.Invoice-title {
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 6vw;
|
||||||
|
color: rgba(88, 55, 50, 1);
|
||||||
|
text-align: left;
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-top: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Invoice-detail {
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 20px;
|
||||||
|
color: rgba(88, 55, 50, 1);
|
||||||
|
text-align: left;
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-top: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PaymentOption {
|
||||||
|
overflow: visible;
|
||||||
|
background-color: white;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: calc(10px + 2vmin);
|
||||||
|
color: rgba(88, 55, 50, 1);
|
||||||
|
border-radius: 15px 15px 0 0;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 40%;
|
||||||
|
left: 60%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PaymentOptionMargin {
|
||||||
|
z-index: -1;
|
||||||
|
overflow-x: hidden;
|
||||||
|
background-color: white;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: calc(10px + 2vmin);
|
||||||
|
color: rgba(88, 55, 50, 1);
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
height: 220px;
|
||||||
|
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PayButton {
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 20px;
|
||||||
|
|
||||||
|
width: 80vw;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50px;
|
||||||
|
background-color: rgba(88, 55, 50, 1);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
margin: 0px auto;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PayButton div {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
.PayButton3 {
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 20px;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50px;
|
||||||
|
background-color: rgba(88, 55, 50, 1);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
margin: 0px auto;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PayButton3 div {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
.Pay2Button {
|
||||||
|
text-align: center;
|
||||||
|
color: rgba(88, 55, 50, 1);
|
||||||
|
font-size: 1em;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Confirm {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 80vw;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 1.5em;
|
||||||
|
padding: 10px 0;
|
||||||
|
margin-bottom: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.RoundedRectangle {
|
||||||
|
border-radius: 20px;
|
||||||
|
padding-top: 5px;
|
||||||
|
margin: 12px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.EmailContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 80vw;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 10px 0;
|
||||||
|
margin-bottom: 7px;
|
||||||
|
}
|
||||||
|
.OrderTypeContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 80vw;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 10px 0;
|
||||||
|
margin-bottom: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Note {
|
||||||
|
text-align: left;
|
||||||
|
color: rgba(88, 55, 50, 1);
|
||||||
|
font-size: 1em;
|
||||||
|
margin-bottom: 13px;
|
||||||
|
margin-left: 50px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.NoteContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 80vw;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 10px 0;
|
||||||
|
margin-bottom: 7px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.NoteInput {
|
||||||
|
width: 78vw;
|
||||||
|
height: 18px;
|
||||||
|
border-radius: 20px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 15px;
|
||||||
|
border: 1px solid rgba(88, 55, 50, 0.5);
|
||||||
|
resize: none; /* Prevent resizing */
|
||||||
|
overflow-wrap: break-word; /* Ensure text wraps */
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddedLastTransaction {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 10px 20px;
|
||||||
|
margin-bottom: 7px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.AddedLastTransaction div {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.CancelAddedLastTransaction {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
margin-right: 30px;
|
||||||
|
margin-top: 10px;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.PaymentOptionMargin {
|
||||||
|
z-index: -1;
|
||||||
|
overflow-x: hidden;
|
||||||
|
background-color: white;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: calc(10px + 2vmin);
|
||||||
|
color: rgba(88, 55, 50, 1);
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
height: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.TotalContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 80vw;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-family: "Plus Jakarta Sans", sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 1.3em;
|
||||||
|
padding: 10px 0;
|
||||||
|
padding-top: 20px;
|
||||||
|
/* margin-bottom: 17px; */
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,8 +42,12 @@
|
|||||||
line-height: 2.25rem;
|
line-height: 2.25rem;
|
||||||
letter-spacing: -1px;
|
letter-spacing: -1px;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
|
margin: 10px
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.buttonWrapper {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
.descHeading {
|
.descHeading {
|
||||||
width: 99%;
|
width: 99%;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ const LinktreePage = ({ handleYes, handleNo }) => {
|
|||||||
<div className={styles.dashboardContainer} >
|
<div className={styles.dashboardContainer} >
|
||||||
<div className={styles.mainHeading}>{captMessage}</div>
|
<div className={styles.mainHeading}>{captMessage}</div>
|
||||||
{descMessage && <div className={styles.descHeading}>{descMessage}</div>}
|
{descMessage && <div className={styles.descHeading}>{descMessage}</div>}
|
||||||
{handleYes && <div onClick={handleYes} className={styles.button}>{yesText}</div>}
|
<div className={styles.buttonWrapper}>
|
||||||
|
<div onClick={handleYes} className={styles.button}>{yesText}</div>
|
||||||
{noText && <div onClick={handleNo} className={styles.button}>{noText}</div>}
|
{noText && <div onClick={handleNo} className={styles.button}>{noText}</div>}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -164,15 +164,15 @@ export default function Transactions({ propsShopId, sendParam, deviceType }) {
|
|||||||
{isPaymentLoading ? (
|
{isPaymentLoading ? (
|
||||||
<ColorRing height="50" width="50" color="white" />
|
<ColorRing height="50" width="50" color="white" />
|
||||||
) : transaction.confirmed === 1 ? (
|
) : transaction.confirmed === 1 ? (
|
||||||
"Confirm has paid" // Display "Confirm has paid" if the transaction is confirmed (1)
|
"Konfirmasi telah bayar" // Display "Confirm has paid" if the transaction is confirmed (1)
|
||||||
) : transaction.confirmed === -1 ? (
|
) : transaction.confirmed === -1 ? (
|
||||||
"Declined" // Display "Declined" if the transaction is declined (-1)
|
"Ditolah" // Display "Declined" if the transaction is declined (-1)
|
||||||
) : transaction.confirmed === 2 ? (
|
) : transaction.confirmed === 2 ? (
|
||||||
"Confirm item has ready" // Display "Item ready" if the transaction is ready (2)
|
"Konfirmasi item telah siap" // Display "Item ready" if the transaction is ready (2)
|
||||||
) : transaction.confirmed === 3 ? (
|
) : transaction.confirmed === 3 ? (
|
||||||
"Transaction success" // Display "Item ready" if the transaction is ready (2)
|
"Transaksi selesai" // Display "Item ready" if the transaction is ready (2)
|
||||||
) : (
|
) : (
|
||||||
"Confirm availability" // Display "Confirm availability" if the transaction is not confirmed (0)
|
"Konfirmasi ketersediaan" // Display "Confirm availability" if the transaction is not confirmed (0)
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -181,7 +181,7 @@ export default function Transactions({ propsShopId, sendParam, deviceType }) {
|
|||||||
className={styles.DeclineButton}
|
className={styles.DeclineButton}
|
||||||
onClick={() => handleDecline(transaction.transactionId)}
|
onClick={() => handleDecline(transaction.transactionId)}
|
||||||
>
|
>
|
||||||
decline
|
Tolak
|
||||||
</h5>
|
</h5>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,12 +16,8 @@ export default function Transaction_pending() {
|
|||||||
<div className={styles.Transaction}>
|
<div className={styles.Transaction}>
|
||||||
<div className={containerStyle}>
|
<div className={containerStyle}>
|
||||||
<div style={{ marginTop: "30px", textAlign: "center" }}>
|
<div style={{ marginTop: "30px", textAlign: "center" }}>
|
||||||
<h2>transaction failed</h2>
|
<h2>Transaksi dibatalkan</h2>
|
||||||
<img
|
|
||||||
className={styles.expression}
|
|
||||||
src="https://i.imgur.com/B6k9exa.png"
|
|
||||||
alt="Failed"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user