import React, { useState, useRef, useEffect } from "react"; import jsQR from "jsqr"; import { getImageUrl } from "../helpers/itemHelper"; import { getCafe, saveCafeDetails, setConfirmationStatus, } from "../helpers/cafeHelpers"; import { getMaterials, createMaterial, deleteMaterial, } from "../helpers/materialHelpers"; import { createMaterialMutation, getMaterialMutations, } from "../helpers/materialMutationHelpers"; import Switch from "react-switch"; // Import the Switch component import Carousel from '../components/Carousel' const SetPaymentQr = ({ cafeId }) => { const [materials, setMaterials] = useState([]); const [mutations, setMutations] = useState([]); const [newMaterialName, setNewMaterialName] = useState(""); const [newMaterialUnit, setNewMaterialUnit] = useState("kilogram"); const [newMaterialImage, setNewMaterialImage] = useState(null); const [deleting, setDeleting] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [showForm, setShowForm] = useState(false); const [selectedMaterialIndex, setSelectedMaterialIndex] = useState(-1); const [latestMutation, setLatestMutation] = useState([]); const [currentQuantity, setCurrentQuantity] = useState(-1); const [currentPrice, setCurrentPrice] = useState(0); const [quantityChange, setQuantityChange] = useState(0); const [sortOrder, setSortOrder] = useState("desc"); const [isEditCurrentPrice, setIsEditCurrentPrice] = useState(false); const [isViewingHistory, setIsViewingHistory] = useState(false); const convertToInteger = (formattedValue) => { // Remove dots and convert to integer return parseInt(formattedValue.replace(/\./g, ""), 10); }; const formatCurrency = (value) => { if (!value) return ""; // Remove existing formatting (dots) and format again const numericValue = value.toString().replace(/\D/g, ""); // Keep only digits return numericValue.replace(/\B(?=(\d{3})+(?!\d))/g, "."); // Add dot as thousands separator }; const handleChange = (e) => { const formattedValue = formatCurrency(e.target.value); setCurrentPrice(formattedValue); }; useEffect(() => { const fetchMaterials = async () => { try { const data = await getMaterials(cafeId); setMaterials(data); console.log(data) setError(null); if (data.length > 0) { setSelectedMaterialIndex(0); } } catch (error) { console.error("Error fetching materials:", error); setError("Failed to fetch materials."); } }; const fetchMutations = async () => { try { const data = await getMaterialMutations(cafeId); setMutations(data); } catch (err) { setError(err.message); } finally { setLoading(false); } }; fetchMaterials(); fetchMutations(); }, [cafeId]); const handleSortChange = (e) => { setSortOrder(e.target.value); }; const filteredMutations = mutations.filter((mutation) => mutation.materialId === materials[selectedMaterialIndex].materialId) || []; const sortedMutations = filteredMutations .filter((mutation) => mutation.materialId === materials[selectedMaterialIndex].materialId) .sort((a, b) => { if (sortOrder === "asc") { return new Date(a.createdAt) - new Date(b.createdAt); } else { return new Date(b.createdAt) - new Date(a.createdAt); } }); const handleCreateMaterial = async (e) => { e.preventDefault(); setLoading(true); const formData = new FormData(); formData.append("name", newMaterialName); formData.append("unit", newMaterialUnit); if (newMaterialImage) { formData.append("image", newMaterialImage); } try { await createMaterial(cafeId, formData); setNewMaterialName(""); setNewMaterialUnit("kilogram"); setNewMaterialImage(null); setShowForm(false); const data = await getMaterials(cafeId); setMaterials(data); setError(null); if (data.length > 0) { setSelectedMaterialIndex(0); } } catch (error) { console.error("Error creating material:", error); setError("Failed to create material."); } finally { setLoading(false); } }; const handleDeleteMaterial = async (materialId) => { setDeleting(materialId); try { await deleteMaterial(materialId); const updatedMaterials = materials.filter( (material) => material.materialId !== materialId ); setMaterials(updatedMaterials); setError(null); if (selectedMaterialIndex === materialId) { setSelectedMaterialIndex( updatedMaterials.length > 0 ? updatedMaterials[0].materialId : null ); } } catch (error) { console.error("Error deleting material:", error); setError("Failed to delete material."); } finally { setDeleting(null); } }; 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); }; useEffect(() => { setQuantityChange(0); if (materials.length > 0 || selectedMaterialIndex > -1) { const materialMutations = mutations.filter( (mutation) => mutation.materialId === materials[selectedMaterialIndex]?.materialId ); console.log(materialMutations) if (materialMutations.length > 0) { const latestMutation = materialMutations.reduce( (latest, current) => new Date(current.createdAt) > new Date(latest.createdAt) ? current : latest, materialMutations[0] ); setLatestMutation(latestMutation); setCurrentQuantity(latestMutation.newStock); setCurrentPrice(formatCurrency(latestMutation.priceAtp)); } else { setCurrentQuantity(0); // Default value if no mutations exist setLatestMutation({ newStock: 0 }); setCurrentPrice(0); } } }, [materials, mutations, selectedMaterialIndex]); const handleUpdateStock = async () => { setLoading(true); try { const newPrice = convertToInteger(currentPrice) const newStock = currentQuantity + quantityChange; const formData = new FormData(); formData.append("newStock", newStock); formData.append("priceAtp", newPrice); formData.append("reason", "Stock update"); await createMaterialMutation(materials[selectedMaterialIndex].materialId, formData); setQuantityChange(0); const updatedMutations = await getMaterialMutations(cafeId); setMutations(updatedMutations); setCurrentQuantity(newStock); setError(null); } catch (error) { console.error("Error updating stock:", error); setError("Failed to update stock."); } finally { setLoading(false); } }; const currentMaterial = materials.find( (material) => material.materialId === selectedMaterialIndex ); const formatDate = (timestamp) => { const date = new Date(timestamp); return date.toLocaleString(); }; return (
{loading ? <> : <>

Bahan baku

setSelectedMaterialIndex(e)} selectedIndex={selectedMaterialIndex} /> {selectedMaterialIndex != -1 ? <>

Stok sekarang {currentQuantity}

{currentQuantity + quantityChange}

harga per {materials && materials[selectedMaterialIndex]?.unit} sekarang

quantityChange < 1 ? null : setIsEditCurrentPrice(!isEditCurrentPrice)} style={quantityChange < 1 ? styles.changeButtonDisabled : styles.changeButtonEnabled}>{isEditCurrentPrice ? 'Terapkan' : 'Ganti'}
setIsViewingHistory(!isViewingHistory)} style={styles.historyTab}>

{isViewingHistory ? '˅' : '˃'} Riwayat stok

{selectedMaterialIndex != -1 && isViewingHistory && !loading && (
{sortedMutations.length > 0 ? ( sortedMutations.map((mutation) => (

{formatDate(mutation.createdAt)}

Details: {mutation.reason}

stok {mutation.newStock}

)) ) : (

No mutations available.

)}
)}
: <>
Fitur ini mempermudah mengelola biaya dan memantau pengeluaran bahan.

Buat bahan baru

setNewMaterialName(event.target.value)} placeholder="Masukkan nama barang" />
} }
); }; // 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;