2

mail@pastecode.io avatar
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