This commit is contained in:
zadit
2025-01-13 07:36:24 +07:00
parent 2864a00814
commit ba5c440a2a
7 changed files with 465 additions and 334 deletions

View File

@@ -19,8 +19,10 @@ import {
import Switch from "react-switch"; // Import the Switch component
import Carousel from '../components/Carousel'
import styles from './MaterialList.module.css'; // Import the CSS Module
const SetPaymentQr = ({ cafeId }) => {
// All your state and logic goes here (unchanged)
const [materials, setMaterials] = useState([]);
const [mutations, setMutations] = useState([]);
const [newMaterialName, setNewMaterialName] = useState("");
@@ -34,6 +36,7 @@ const SetPaymentQr = ({ cafeId }) => {
const [latestMutation, setLatestMutation] = useState([]);
const [currentQuantity, setCurrentQuantity] = useState(-1);
const [currentPrice, setCurrentPrice] = useState(0);
const [newPrice, setNewPrice] = useState(0);
const [quantityChange, setQuantityChange] = useState(0);
const [sortOrder, setSortOrder] = useState("desc");
const [isEditCurrentPrice, setIsEditCurrentPrice] = useState(false);
@@ -53,7 +56,7 @@ const SetPaymentQr = ({ cafeId }) => {
const handleChange = (e) => {
const formattedValue = formatCurrency(e.target.value);
setCurrentPrice(formattedValue);
setNewPrice(formattedValue);
};
useEffect(() => {
@@ -87,11 +90,7 @@ const SetPaymentQr = ({ cafeId }) => {
fetchMutations();
}, [cafeId]);
const handleSortChange = (e) => {
setSortOrder(e.target.value);
};
const filteredMutations = mutations.filter((mutation) => mutation.materialId === materials[selectedMaterialIndex].materialId) || [];
const filteredMutations = mutations.filter((mutation) => mutation.materialId === materials[selectedMaterialIndex]?.materialId) || [];
const sortedMutations = filteredMutations
.filter((mutation) => mutation.materialId === materials[selectedMaterialIndex].materialId)
@@ -156,32 +155,11 @@ const SetPaymentQr = ({ cafeId }) => {
}
};
const handlePrevious = () => {
if (selectedMaterialIndex) {
setQuantityChange(0);
const currentIndex = materials.findIndex(
(material) => material.materialId === selectedMaterialIndex
);
if (currentIndex > 0) {
setSelectedMaterialIndex(materials[currentIndex - 1].materialId);
}
}
};
const handleNext = () => {
if (selectedMaterialIndex) {
setQuantityChange(0);
const currentIndex = materials.findIndex(
(material) => material.materialId === selectedMaterialIndex
);
if (currentIndex < materials.length - 1) {
setSelectedMaterialIndex(materials[currentIndex + 1].materialId);
}
}
};
const handleQuantityChange = (change) => {
setQuantityChange((prev) => prev + change);
if (quantityChange + change < 1) setNewPrice(currentPrice);
setIsEditCurrentPrice(false);
};
useEffect(() => {
@@ -202,24 +180,27 @@ const SetPaymentQr = ({ cafeId }) => {
setLatestMutation(latestMutation);
setCurrentQuantity(latestMutation.newStock);
setCurrentPrice(formatCurrency(latestMutation.priceAtp));
setNewPrice(formatCurrency(latestMutation.priceAtp));
} else {
setCurrentQuantity(0); // Default value if no mutations exist
setLatestMutation({ newStock: 0 });
setCurrentPrice(0);
setNewPrice(0);
}
}
setIsViewingHistory(false);
}, [materials, mutations, selectedMaterialIndex]);
const handleUpdateStock = async () => {
setLoading(true);
try {
const newPrice = convertToInteger(currentPrice)
const newprice = convertToInteger(newPrice)
const newStock = currentQuantity + quantityChange;
const formData = new FormData();
formData.append("newStock", newStock);
formData.append("priceAtp", newPrice);
formData.append("priceAtp", newprice);
formData.append("reason", "Stock update");
await createMaterialMutation(materials[selectedMaterialIndex].materialId, formData);
@@ -244,103 +225,106 @@ const SetPaymentQr = ({ cafeId }) => {
return date.toLocaleString();
};
return (
<div style={styles.container}>
{loading ?
<div className={styles.container}>
{loading ? (
<></>
) : (
<>
</>
:
<>
<h3 style={styles.title}>Bahan baku</h3>
<h3 className={styles.title}>Bahan baku</h3>
<Carousel items={materials} onSelect={(e) => setSelectedMaterialIndex(e)} selectedIndex={selectedMaterialIndex} />
{selectedMaterialIndex != -1 ?
{selectedMaterialIndex !== -1 ? (
<>
<div style={styles.switchContainer}>
<div className={styles.switchContainer}>
<h3>Stok sekarang {currentQuantity}</h3>
</div>
<div style={styles.stokContainer}>
<button onClick={() => handleQuantityChange(currentQuantity + quantityChange > 0 ? -1 : 0)} style={styles.stockButton}>
<div className={styles.stokContainer}>
<button onClick={() => handleQuantityChange(currentQuantity + quantityChange > 0 ? -1 : 0)} className={styles.stockButton}>
-
</button>
<p>{currentQuantity + quantityChange}</p>
<button onClick={() => handleQuantityChange(1)} style={styles.stockButton}>
<button onClick={() => handleQuantityChange(1)} className={styles.stockButton}>
+
</button>
</div>
<div style={styles.uploadMessage}>
<div className={styles.uploadMessage}>
<p>harga per {materials && materials[selectedMaterialIndex]?.unit} sekarang</p>
</div>
<div style={styles.resultMessage}>
<div className={styles.resultMessage}>
<input
style={{
width: "200px",
border: isEditCurrentPrice ? "1px solid #ccc" : "1px solid transparent",
backgroundColor: isEditCurrentPrice ? "white" : "transparent",
}}
className={styles.resultMessageInput} // Replace inline style with CSS module class
disabled={!isEditCurrentPrice || quantityChange < 1}
value={currentPrice}
value={newPrice}
onChange={handleChange}
placeholder="Enter amount"
/>
<div onClick={() => quantityChange < 1 ? null : setIsEditCurrentPrice(!isEditCurrentPrice)} style={quantityChange < 1 ? styles.changeButtonDisabled : styles.changeButtonEnabled}>{isEditCurrentPrice ? 'Terapkan' : 'Ganti'}</div>
<div onClick={() => quantityChange < 1 ? null : setIsEditCurrentPrice(!isEditCurrentPrice)} className={quantityChange < 1 ? styles.changeButtonDisabled : styles.changeButtonEnabled}>
{isEditCurrentPrice ? 'Terapkan' : 'Ganti'}
</div>
</div>
<div style={styles.buttonContainer}>
<button onClick={handleUpdateStock} style={styles.saveButton}>
<div className={styles.buttonContainer}>
<button onClick={handleUpdateStock} className={styles.saveButton}>
Laporkan {quantityChange > 0 ? 'penambahan' : 'stok sekarang'} {quantityChange < 1 ? currentQuantity + quantityChange : quantityChange} {materials[selectedMaterialIndex]?.unit}
</button>
</div>
<div onClick={() => setIsViewingHistory(!isViewingHistory)} style={styles.historyTab}>
<h3> {isViewingHistory ? '˅' : '˃'} Riwayat stok</h3>
<div style={styles.historyContainer}>
{selectedMaterialIndex != -1 && isViewingHistory && !loading && (
<div style={styles.mutationContainer}>
{sortedMutations.length > 0 ? (
sortedMutations.map((mutation) => (
<div key={mutation.id} style={styles.mutationCard}>
<h4 style={styles.mutationTitle}>
{formatDate(mutation.createdAt)}
</h4>
<p>Details: {mutation.reason}</p>
<p>stok {mutation.newStock}</p>
</div>
))
) : (
<p>No mutations available.</p>
)}
<div className={styles.historyTab}>
<h3 onClick={() => setIsViewingHistory(!isViewingHistory)}> {isViewingHistory ? '˅' : '˃'} Riwayat stok</h3>
{selectedMaterialIndex !== -1 && isViewingHistory && !loading && (
<>
<div className={styles.sorter} onClick={() => setSortOrder(sortOrder == 'asc' ? 'desc' : 'asc')}>
Urutkan: {sortOrder === 'asc' ? "terlama" : "terbaru"} <div style={{ transform: 'rotate(90deg)' }}>&lt;&gt;</div>
</div>
)}
</div>
<div className={styles.historyContainer}>
<div className={styles.mutationContainer}>
{sortedMutations.length > 0 ? (
sortedMutations.map((mutation) => (
<div key={mutation.id} className={styles.mutationCard}>
<div style={{ width: '42px', backgroundColor: '#b9b9b9', borderRadius: '10px', padding: '3px', paddingBottom: '0' }}>
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
<g id="SVGRepo_iconCarrier">
<g id="Interface / Book">
<path id="Vector" d="M5 19.5002V6.2002C5 5.08009 5 4.51962 5.21799 4.0918C5.40973 3.71547 5.71547 3.40973 6.0918 3.21799C6.51962 3 7.08009 3 8.2002 3H17.4002C17.9602 3 18.2407 3 18.4546 3.10899C18.6427 3.20487 18.7948 3.35774 18.8906 3.5459C18.9996 3.75981 19 4.04005 19 4.6001V16.4001C19 16.9601 18.9996 17.2398 18.8906 17.4537C18.7948 17.6419 18.6429 17.7952 18.4548 17.8911C18.2411 18 17.961 18 17.402 18H7.25C6.00736 18 5 19.0074 5 20.25C5 20.6642 5.33579 21 5.75 21H16.402C16.961 21 17.2411 21 17.4548 20.8911C17.6429 20.7952 17.7948 20.642 17.8906 20.4538C17.9996 20.2399 18 19.9601 18 19.4V18" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
</svg>
</div>
<div className={styles.mutationTitle}>
<h4>{formatDate(mutation.createdAt)}</h4>
<p>Total stok: {mutation.newStock} || +{mutation.newStock - mutation.oldStock} || {formatCurrency((mutation.newStock - mutation.oldStock) * mutation.priceAtp)}</p>
</div>
</div>
))
) : (
<p>Tidak ada laporan perubahan stok.</p>
)}
</div>
</div>
</>
)}
</div>
</> :
</>
) : (
<>
<div
style={{ display: "flex", alignItems: "center", margin: "10px", marginTop: '17px', marginBottom: '34px' }}
>
<div className={styles.description}>
<div style={{ marginRight: "5px", fontSize: "1.2em" }}></div>
<h6 style={{ margin: 0, textAlign: "left" }}>
<h6 style={{ margin: 0, textAlign: "left", fontSize: '12px' }}>
Fitur ini mempermudah mengelola biaya dan memantau pengeluaran bahan.
</h6>
</div>
<div style={styles.switchContainer}>
<div className={styles.switchContainer}>
<h3>Buat bahan baru</h3>
</div>
<div style={styles.resultMessage}>
<div className={styles.resultMessage}>
<input
style={{
width: "100%",
height: '31px',
border: "1px solid #ccc"
}}
className={styles.resultMessageInput}
value={newMaterialName}
onChange={(event) => setNewMaterialName(event.target.value)}
placeholder="Masukkan nama barang"
style={{width: '100%', height: '31px'}}
/>
</div>
@@ -348,7 +332,8 @@ const SetPaymentQr = ({ cafeId }) => {
id="materialUnit"
value={newMaterialUnit}
onChange={(e) => setNewMaterialUnit(e.target.value)}
style={styles.unit}
className={styles.unit}
style={{height: '37px'}}
>
<option value="gram">Satuan: gram</option>
<option value="ons">Satuan: ons</option>
@@ -362,131 +347,17 @@ const SetPaymentQr = ({ cafeId }) => {
<option value="box">Satuan: box</option>
</select>
<div style={styles.buttonContainer}>
<button style={styles.saveButton}>
<div className={styles.buttonContainer}>
<button className={styles.saveButton} onClick={handleCreateMaterial}>
Buat bahan baku
</button>
</div>
</>
}
)}
</>
}
)}
</div>
);
};
// Styles
const styles = {
container: {
width: '100%',
minHeight: '50vh',
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",
},
changeButtonEnabled: {
paddingRight: '10px',
backgroundColor: 'green',
borderRadius: '30px',
color: 'white',
fontWeight: 700,
height: '36px',
lineHeight: '36px',
paddingLeft: '10px',
paddingHeight: '10px',
},
changeButtonDisabled: {
paddingRight: '10px',
backgroundColor: '#a1a1a1',
borderRadius: '30px',
color: 'white',
fontWeight: 700,
height: '36px',
lineHeight: '36px',
paddingLeft: '10px',
paddingHeight: '10px',
},
resultMessage: {
marginTop: "-13px",
textAlign: "left",
display: 'flex',
justifyContent: 'space-between'
},
stokContainer: {
display: 'flex',
justifyContent: 'space-evenly',
alignItems: 'center',
marginTop: '18px',
marginBottom: "6px",
textAlign: "left",
},
buttonContainer: {
marginTop: "11px",
textAlign: "left",
},
stockButton: {
padding: "10px 20px",
fontSize: "3.5vw",
backgroundColor: "#28a745",
color: "#fff",
border: "none",
borderRadius: "30px",
cursor: "pointer",
transition: "background-color 0.3s",
},
saveButton: {
width: '100%',
padding: "10px 20px",
fontSize: "3.5vw",
backgroundColor: "#28a745",
color: "#fff",
border: "none",
borderRadius: "30px",
cursor: "pointer",
transition: "background-color 0.3s",
},
switchContainer: {
marginTop: "20px",
textAlign: "left",
},
historyTab: {
textAlign: "left",
},
historyContainer: {
textAlign: "left",
maxHeight: '200px',
overflowY: 'auto'
},
description: {
margin: "10px 0",
fontSize: "14px",
color: "#666",
},
unit: {
marginTop: '11px',
width: '100%',
height: '31px',
},
};
export default SetPaymentQr;