Files
groovee/src/components/PaymentOptions.js
insvrgent 5d8b2af2c9 ok
2025-01-13 15:47:39 +07:00

461 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useRef, useEffect } from "react";
import jsQR from "jsqr";
import { getImageUrl } from "../helpers/itemHelper";
import { getTables, updateTable, createTable } from "../helpers/tableHelper";
import {
getCafe,
saveCafeDetails,
setConfirmationStatus,
} from "../helpers/cafeHelpers";
import Switch from "react-switch"; // Import the Switch component
const SetPaymentQr = ({ shop }) => {
const [initialPos, setInitialPos] = useState({
left: shop.xposition,
top: shop.yposition,
});
const [isConfigFont, setIsConfigFont] = useState(false);
const [fontsize, setfontsize] = useState(shop.fontsize);
const [fontcolor, setfontcolor] = useState(shop.fontcolor);
const [initialFontPos, setInitialFontPos] = useState({
left: shop.fontxposition,
top: shop.fontyposition,
});
const [initialSize, setInitialSize] = useState(shop.scale);
const [bgImageUrl, setBgImageUrl] = useState(getImageUrl(shop.qrBackground));
const qrBackgroundInputRef = useRef(null);
const shopUrl = window.location.hostname + "/" + shop.cafeId;
const generateQRCodeUrl = (tableCode) => {
if (tableCode != null) {
return `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(
shopUrl + "/" + tableCode
)}`;
} else {
return `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(
shopUrl
)}`;
}
};
const [isConfig, setIsConfig] = useState(false);
const [isConfigQR, setIsConfigQR] = useState(false);
const [isViewTables, setIsViewTables] = useState(false);
const [tables, setTables] = useState([]);
const [selectedTable, setSelectedTable] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
console.log(shop);
const fetchedTables = await getTables(shop.cafeId);
setTables(fetchedTables);
} catch (error) {
console.error("Error fetching tables:", error);
}
};
fetchData();
}, [shop.cafeId]);
const handleSave = () => {
const qrBackgroundFile = qrBackgroundInputRef.current.files[0]; // Get the selected file for qrBackground
// Prepare the details object
const details = {
qrSize: initialSize,
qrPosition: initialPos,
qrBackgroundFile,
fontsize,
fontcolor,
fontPosition: initialFontPos,
};
// Call saveCafeDetails function with the updated details object
saveCafeDetails(shop.cafeId, details)
.then((response) => {
console.log("Cafe details saved:", response);
})
.catch((error) => {
console.error("Error saving cafe details:", error);
});
};
const handlePositionChange = (e) => {
const { name, value } = e.target;
setInitialPos((prevPosition) => ({
...prevPosition,
[name]: parseFloat(value).toFixed(2),
}));
};
const handleFontPositionChange = (e) => {
const { name, value } = e.target;
setInitialFontPos((prevPosition) => ({
...prevPosition,
[name]: parseFloat(value).toFixed(2),
}));
};
const handleSizeChange = (e) => {
setInitialSize(parseFloat(e.target.value).toFixed(2));
};
const handleFontSizeChange = (e) => {
setfontsize(parseFloat(e.target.value).toFixed(2));
};
const handleFileChange = (e) => {
const file = e.target.files[0];
if (file) {
const newBgImage = URL.createObjectURL(file); // Create a temporary URL for display
setBgImageUrl(newBgImage);
}
};
return (
<div style={styles.container}>
<h3 style={styles.title}>QR kedai dan meja</h3>
<div
id="qr-code-container"
style={{
background: `center center / contain no-repeat url(${bgImageUrl})`,
backgroundSize: "contain",
border: "1px solid #ddd",
...styles.qrCodeContainer,
backgroundImage: `url(${bgImageUrl})`,
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
backgroundSize: "contain",
}}
>
<img
src={generateQRCodeUrl(selectedTable?.tableCode || null)}
alt="QR Code"
style={{
position: "absolute",
width: `${initialSize}%`,
left: `${initialPos.left}%`,
top: `${initialPos.top}%`,
transform: "translate(-50%, -50%)",
}} />
<div style={{
transformOrigin: 'left',
transform: `scaleX(${initialFontPos.left > 50 ? -1 : 1})`,
position: "absolute",
fontSize: `${fontsize * 3}%`,
left: `${initialFontPos.left}%`,
top: `${initialFontPos.top}%`,
textAlign: initialFontPos.left > 50 ? 'right' : 'left'
}}>
<h1 style={{
transform: `scaleX(${initialFontPos.left > 50 ? -1 : 1})`,
width: '200%',
lineHeight: 0,
fontFamily: 'Plus Jakarta Sans',
color: fontcolor
}} >{selectedTable == null ? 'Nomor meja' : selectedTable.tableNo}</h1>
</div>
<input
type="file"
accept="image/*"
ref={qrBackgroundInputRef}
style={{ display: "none" }}
onChange={handleFileChange}
/>
</div>
<div style={styles.uploadMessage}>
<p>Klik untuk ganti background</p>
</div>
<div style={styles.resultMessage}>
<p onClick={() => setIsConfig(!isConfig)}> {isConfig ? '˅' : '˃'} Konfigurasi</p>
<div
onClick={() => qrBackgroundInputRef.current.click()} style={styles.uploadButton}>Ganti</div>
</div>
<div style={styles.switchContainer}>
{isConfig &&
<div style={{ marginLeft: '15px' }}>
<p style={styles.description} onClick={() => { setIsConfigQR(!isConfigQR); setIsConfigFont(false) }}>
{isConfigQR ? '˅' : '˃'} Konfigurasi QR
</p>
{isConfigQR && <>
<div style={styles.sliderContainer}>
<label style={styles.label}>
QR Code Size:
<div style={styles.sliderWrapper}>
<span style={styles.labelStart}>10%</span>
<input
type="range"
step="0.25"
min="10"
max="100"
value={initialSize}
onChange={handleSizeChange}
style={styles.input}
/>
<span style={styles.value}>{initialSize}%</span>
</div>
</label>
</div>
<div style={styles.sliderContainer}>
<label style={styles.label}>
QR Code Position X:
<div style={styles.sliderWrapper}>
<span style={styles.labelStart}>0%</span>
<input
type="range"
step="0.25"
name="left"
min="0"
max="100"
value={initialPos.left}
onChange={handlePositionChange}
style={styles.input}
/>
<span style={styles.value}>{initialPos.left}%</span>
</div>
</label>
</div>
<div style={styles.sliderContainer}>
<label style={styles.label}>
QR Code Position Y:
<div style={styles.sliderWrapper}>
<span style={styles.labelStart}>0%</span>
<input
type="range"
step="0.25"
name="top"
min="0"
max="100"
value={initialPos.top}
onChange={handlePositionChange}
style={styles.input}
/>
<span style={styles.value}>{initialPos.top}%</span>
</div>
</label>
</div>
</>}
<p style={styles.description} onClick={() => { setIsConfigFont(!isConfigFont); setIsConfigQR(false) }}>
{isConfigFont ? '˅' : '˃'} Konfigurasi nomor
</p>
{isConfigFont && (
<>
<div style={styles.sliderContainer}>
<label style={styles.label}>
Ukuran nomor meja:
<div style={styles.sliderWrapper}>
<span style={styles.labelStart}>10%</span>
<input
type="range"
step="0.25"
min="10"
max="100"
value={fontsize}
onChange={handleFontSizeChange}
style={styles.input}
/>
<span style={styles.value}>{fontsize}%</span>
</div>
</label>
</div>
<div style={styles.sliderContainer}>
<label style={styles.label}>
Posisi nomor meja - horizontal:
<div style={styles.sliderWrapper}>
<span style={styles.labelStart}>0%</span>
<input
type="range"
step="0.25"
name="left"
min="0"
max="100"
value={initialFontPos.left}
onChange={handleFontPositionChange}
style={styles.input}
/>
<span style={styles.value}>{initialFontPos.left}%</span>
</div>
</label>
</div>
<div style={styles.sliderContainer}>
<label style={styles.label}>
Posisi nomor meja - vertikal:
<div style={styles.sliderWrapper}>
<span style={styles.labelStart}>0%</span>
<input
type="range"
step="0.25"
name="top"
min="0"
max="100"
value={initialFontPos.top}
onChange={handleFontPositionChange}
style={styles.input}
/>
<span style={styles.value}>{initialFontPos.top}%</span>
</div>
</label>
</div>
<div style={styles.sliderContainer}>
<label style={styles.label}>
Warna nomor meja:
<div style={styles.sliderWrapper}>
<input
type="color"
value='#FFFFFF' // This should be the state holding the selected font color
onChange={(e) => setfontcolor(e.target.value)} // Update the font color state
style={styles.colorInput} // Add your styles for the color input if needed
/>
<span style={styles.value}>{fontcolor}</span> {/* Display the selected color value */}
</div>
</label>
</div>
</>
)}
</div>
}
<p style={styles.description} onClick={() => setIsViewTables(!isViewTables)}>
{isViewTables ? '˅' : '˃'} Daftar meja
</p>
{isViewTables &&
<div style={{marginTop: '34px', marginLeft: '15px'}}>
<div style={styles.resultMessage}>
<input style={{borderRadius: '12px', paddingLeft: '13px'}} placeholder="Meja A1"/>
<div
onClick={() => qrBackgroundInputRef.current.click()} style={styles.uploadButton}>Buat meja</div>
</div>
{tables && tables
.filter((table) => table.tableNo !== 0)
.map((table) => (
<li
key={table.tableId}
style={{
backgroundColor:
table.tableId === selectedTable?.tableId
? "lightblue"
: "white",
marginBottom: "10px",
padding: "10px",
borderRadius: "4px",
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
cursor: "pointer",
listStyle: 'square'
}}
onClick={() => setSelectedTable(selectedTable == table ? null : table)}
>
<div style={{ marginBottom: "10px" }}>
{table.tableNo}
</div>
</li>
))
}
</div>
}
</div>
<div style={styles.buttonContainer}>
<button onClick={handleSave} style={styles.saveButton}>
Simpan
</button>
</div>
</div>
);
};
// Styles
const styles = {
container: {
width: '100%',
backgroundColor: "white",
padding: "20px",
borderRadius: "8px",
boxShadow: "0 2px 10px rgba(0, 0, 0, 0.1)",
textAlign: "center", // Center text and children
},
title: {
marginBottom: "20px",
fontWeight: "bold",
},
qrCodeContainer: {
backgroundColor: '#999999',
borderRadius: '20px',
position: "relative",
width: "100%",
height: "200px",
backgroundSize: "contain",
overflow: "hidden",
margin: "0 auto", // Center the QR code container
},
uploadMessage: {
fontWeight: 600,
textAlign: "left",
},
uploadButton: {
paddingRight: '10px',
backgroundColor: 'green',
borderRadius: '30px',
color: 'white',
fontWeight: 700,
height: '36px',
lineHeight: '36px',
paddingLeft: '10px',
paddingHeight: '10px',
},
resultMessage: {
marginTop: "-24px",
textAlign: "left",
display: 'flex',
justifyContent: 'space-between'
},
buttonContainer: {
marginTop: "20px",
textAlign: "left",
},
saveButton: {
padding: "10px 20px",
fontSize: "16px",
backgroundColor: "#28a745",
color: "#fff",
border: "none",
borderRadius: "30px",
cursor: "pointer",
transition: "background-color 0.3s",
},
switchContainer: {
textAlign: "left",
marginTop: '-15px'
},
description: {
margin: "10px 0",
},
sliderContainer: {
marginBottom: "20px",
},
label: {
display: "block",
marginBottom: "10px",
},
sliderWrapper: {
display: "flex",
alignItems: "center",
},
input: {
flex: "1",
margin: "0 10px",
},
};
export default SetPaymentQr;