2
unknown
plain_text
a month ago
16 kB
1
Indexable
Never
import React, { useState } from "react"; import "./ReturnBook.css"; import { BASE_URL } from "../server/Endpoint"; import QrScanner from "react-qr-scanner"; const ReturnBook = () => { const [memberId, setMemberId] = useState(""); const [bookCopyId, setBookCopyId] = useState(""); const [message, setMessage] = useState(""); const [messageType, setMessageType] = useState(""); const [loanDetails, setLoanDetails] = useState(null); const [penaltyDetails, setPenaltyDetails] = useState([]); const [showMemberScanner, setShowMemberScanner] = useState(false); const [showBookScanner, setShowBookScanner] = useState(false); const [showFeeModal, setShowFeeModal] = useState(false); const [showPenaltyConfirmationModal, setShowPenaltyConfirmationModal] = useState(false); const [isCoverTear, setIsCoverTear] = useState(false); const [isSpineDamage, setIsSpineDamage] = useState(false); const [isPageLoss, setIsPageLoss] = useState(false); const [isWriting, setIsWriting] = useState(false); const [totalAmount, setTotalAmount] = useState(0); const [feeApplied, setFeeApplied] = useState(false); const fetchPenaltyDetails = async (loanId) => { const url = `${BASE_URL}api/staff/penalty/get-penalties-by-loan-id?loanId=${loanId}`; try { const token = localStorage.getItem("token"); const response = await fetch(url, { method: "GET", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, }); if (!response.ok) throw new Error("Failed to fetch penalty details."); const penalties = await response.json(); setPenaltyDetails(penalties); const calculatedTotalAmount = penalties.reduce( (total, penalty) => total + penalty.totalAmount, 0 ); setTotalAmount(calculatedTotalAmount); console.log("Penalties fetched:", penalties); console.log("Calculated Total Amount:", calculatedTotalAmount); } catch (error) { console.error("Error fetching penalty details:", error); setMessage(`Error: ${error.message}`); } }; const handleFetchLoanDetails = async (e) => { e.preventDefault(); const memberIdInt = parseInt(memberId, 10); const copyIdInt = parseInt(bookCopyId, 10); if (isNaN(memberIdInt) || isNaN(copyIdInt)) { setMessage("Vui lòng nhập ID hợp lệ."); return; } const url = `${BASE_URL}api/staff/loans/return?memberId=${memberIdInt}&bookCopyId=${copyIdInt}`; try { const token = localStorage.getItem("token"); const response = await fetch(url, { method: "GET", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, }); if (!response.ok) throw new Error( `Không tìm thấy thông tin cho User ID ${memberId} và Book Copy ID ${bookCopyId}.` ); const loan = await response.json(); if (loan.status === "BORROWING") { setLoanDetails(loan); setMessage(""); fetchPenaltyDetails(loan.id); } else { setLoanDetails(null); setMessage("Sách đã được trả."); } } catch (error) { console.error("Lỗi khi lấy thông tin sách mượn:", error); setMessage(`Lỗi: ${error.message}`); setLoanDetails(null); } }; const handleApplyPenalty = async () => { if (loanDetails) { const token = localStorage.getItem("token"); const staffId = localStorage.getItem("userId"); const role = localStorage.getItem("role"); if (role !== "STAFF") { setMessage("Bạn không có quyền thực hiện chức năng này."); return; } const url = `${BASE_URL}api/staff/penalty/apply-penalty?loanId=${loanDetails.id}&userId=${staffId}&isCoverTear=${isCoverTear}&isSpineDamage=${isSpineDamage}&isPageLoss=${isPageLoss}&isWriting=${isWriting}`; try { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", "ngrok-skip-browser-warning": "69420", Authorization: `Bearer ${token}`, }, }); if (response.ok) { setShowPenaltyConfirmationModal(true); setFeeApplied(true); fetchPenaltyDetails(loanDetails.id); } else { throw new Error(`HTTP error! Status: ${response.status}`); } } catch (error) { console.error("Lỗi khi áp dụng phí phạt:", error); setMessage(`Lỗi: ${error.message}`); } } }; const handlePayPenaltyAndReturn = async () => { if (penaltyDetails.length > 0) { const token = localStorage.getItem("token"); const penaltyId = penaltyDetails[0].id; const totalAmount = penaltyDetails[0].totalAmount; const createdBy = localStorage.getItem("userId"); const url = `${BASE_URL}api/staff/penalty/pay-penalty?penaltyId=${penaltyId}`; const penaltyData = { id: penaltyId, totalAmount: totalAmount, createdBy: createdBy, status: "PAID", }; try { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, body: JSON.stringify(penaltyData), }); if (response.ok) { setMessage("Phí phạt đã được thanh toán!"); setMessageType("success"); setFeeApplied(true); handleReturnBook(); } else { throw new Error(`HTTP error! Status: ${response.status}`); } } catch (error) { console.error("Lỗi khi thanh toán phí phạt:", error); setMessage(`Lỗi: ${error.message}`); } } else { handleReturnBook(); } }; const handleReturnBook = async () => { if (loanDetails) { const token = localStorage.getItem("token"); const staffUpdate = localStorage.getItem("userId"); const role = localStorage.getItem("role"); if (role !== "STAFF") { setMessage("Bạn không có quyền thực hiện chức năng này."); return; } const url = `${BASE_URL}api/staff/loans/return?loanId=${loanDetails.id}&updateBy=${staffUpdate}`; try { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, }); if (response.ok) { setMessage("Trả sách thành công!"); setMessageType("success"); setLoanDetails(null); setShowFeeModal(false); setShowPenaltyConfirmationModal(false); setFeeApplied(false); } else { throw new Error(`HTTP error! Status: ${response.status}`); } } catch (error) { console.error("Lỗi khi trả sách:", error); setMessage(`Lỗi: ${error.message}`); setMessageType("error"); } } }; const handleScanMember = (data) => { if (data) { try { const parsedData = JSON.parse(data.text); setMemberId(parsedData.memberid || ""); setShowMemberScanner(false); } catch (error) { console.error("Error parsing QR code data:", error); setMessage( "Không thể phân tích dữ liệu QR code cho thành viên. Vui lòng thử lại." ); setMessageType("error"); } } }; const handleScanBook = (data) => { if (data) { try { const parsedData = JSON.parse(data.text); setBookCopyId(parsedData.bookCopyId || ""); setShowBookScanner(false); } catch (error) { console.error("Error parsing QR code data:", error); setMessage( "Không thể phân tích dữ liệu QR code cho sách. Vui lòng thử lại." ); setMessageType("error"); } } }; const handleError = (err) => { console.error("QR Scan Error:", err); setMessage("Lỗi khi quét QR code. Vui lòng thử lại."); setMessageType("error"); }; const handleOpenMemberScanner = () => { setShowMemberScanner(true); }; const handleOpenBookScanner = () => { setShowBookScanner(true); }; const handleCloseFeeModal = () => { setShowFeeModal(false); }; const handlePenaltyCheckboxChange = (event) => { const { name, checked } = event.target; switch (name) { case "coverTear": setIsCoverTear(checked); break; case "spineDamage": setIsSpineDamage(checked); break; case "pageLoss": setIsPageLoss(checked); break; case "writing": setIsWriting(checked); break; default: break; } }; const previewStyle = { height: 200, width: 260, }; return ( <div className="myapp-container"> <form onSubmit={handleFetchLoanDetails} className="return-form"> <div className="form-group-member"> <label htmlFor="memberId">Member ID:</label> <div className="input-button-group"> <input id="memberId" type="text" value={memberId} onChange={(e) => setMemberId(e.target.value)} required /> <button type="button" onClick={() => setShowMemberScanner(!showMemberScanner)} className="scan-button" > {showMemberScanner ? "Close" : "Scan QR"} </button> {showMemberScanner && ( <div className="qr-scanner-container"> <QrScanner delay={300} style={previewStyle} onError={handleError} onScan={handleScanMember} /> <button type="button" onClick={() => setShowMemberScanner(false)} className="close-button-return" > X </button> </div> )} </div> </div> <div className="form-group-book"> <label htmlFor="bookId">Book ID:</label> <div className="input-button-group"> <input id="bookId" type="text" value={bookCopyId} onChange={(e) => setBookCopyId(e.target.value)} required /> <button type="button" onClick={() => setShowBookScanner(!showBookScanner)} className="scan-button" > {showBookScanner ? "Close" : "Scan QR"} </button> </div> {showBookScanner && ( <div className="qr-scanner-container"> <QrScanner delay={300} style={previewStyle} onError={handleError} onScan={handleScanBook} /> <button type="button" onClick={() => setShowBookScanner(false)} className="close-button-return" > X </button> </div> )} </div> <button type="submit" className="submit-button"> Find Book </button> </form> {message && ( <div className={`message ${ messageType === "success" ? "success" : "error" }`} > {message} </div> )} {loanDetails && ( <div className="myapp-loan-details"> <h2>Loan Details</h2> <p> <strong>Borrowed Date:</strong>{" "} {new Date(loanDetails.loanDate).toLocaleDateString()} </p> <p> <strong>Due Date:</strong>{" "} {new Date(loanDetails.dueDate).toLocaleDateString()} </p> <p> <strong>Status:</strong> {loanDetails.status} </p> <button onClick={() => setShowFeeModal(true)} className="myapp-action-button" > Apply Penalty </button> <button onClick={handleReturnBook} className="myapp-action-button"> Return </button> </div> )} {showFeeModal && ( <div className="myapp-modal"> <div className="myapp-modal-content"> <h2>Apply Penalty</h2> <label> <input type="checkbox" name="coverTear" checked={isCoverTear} onChange={handlePenaltyCheckboxChange} /> Cover Tear </label> <label> <input type="checkbox" name="spineDamage" checked={isSpineDamage} onChange={handlePenaltyCheckboxChange} /> Spine Damage </label> <label> <input type="checkbox" name="pageLoss" checked={isPageLoss} onChange={handlePenaltyCheckboxChange} /> Page Loss </label> <label> <input type="checkbox" name="writing" checked={isWriting} onChange={handlePenaltyCheckboxChange} /> Writing </label> <button onClick={handleApplyPenalty} className="myapp-action-button" > Apply Penalty </button> <button onClick={handleCloseFeeModal} className="myapp-close-button" > Close </button> </div> </div> )} {showPenaltyConfirmationModal && ( <div className="myapp-modal"> <div className="myapp-modal-content"> <h2>Penalty Confirmation</h2> {penaltyDetails.length > 0 ? ( <div> <p> <strong>Total Amount:</strong> ${totalAmount} </p> <button onClick={handlePayPenaltyAndReturn} className="myapp-action-button" > Pay Penalty and Return Book </button> <button onClick={() => setShowPenaltyConfirmationModal(false)} className="myapp-close-button" > Close </button> </div> ) : ( <p>No penalties found.</p> )} </div> </div> )} </div> ); }; export default ReturnBook;
Leave a Comment