2

mail@pastecode.io avatar
unknown
plain_text
a month ago
13 kB
1
Indexable
Never
import React, { useState, useEffect } from "react";
import QrScanner from "react-qr-scanner";
import "./BorrowBook.css";
import Navbar from "../components/Navbar";
import Sidebar from "../components/Sidebar";
import { BASE_URL } from "../server/Endpoint";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
  faArrowLeft,
  faArrowRight,
  faTimes,
} from "@fortawesome/free-solid-svg-icons";

const BorrowBook = () => {
  const [formData, setFormData] = useState({
    memberId: "",
    bookCopyId: "",
    additionalDays: "",
    fullName: "",
    username: "",
    gender: "",
    title: "",
    author: "",
    category: "",
  });
  const [message, setMessage] = useState({ text: "", type: "" });
  const [showMemberScanner, setShowMemberScanner] = useState(false);
  const [showBookScanner, setShowBookScanner] = useState(false);
  const [loanHistory, setLoanHistory] = useState([]);
  const [currentPage, setCurrentPage] = useState(0);
  const [totalPages, setTotalPages] = useState(1);

  useEffect(() => {
    const fetchLoanHistory = async (page) => {
      try {
        const token = localStorage.getItem("token");
        const response = await fetch(
          `${BASE_URL}api/staff/loans/allLoanHistory/${page}?page=${page}`,
          {
            method: "GET",
            headers: {
              "ngrok-skip-browser-warning": "69420",
              "Content-Type": "application/json",
              Authorization: `Bearer ${token}`,
            },
          }
        );

        if (!response.ok) {
          throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const data = await response.json();
        setLoanHistory(data.content); // Assuming the API returns a paginated response with `content`
        setTotalPages(data.totalPages);
      } catch (error) {
        console.error("Error fetching loan history:", error);
        setMessage({
          text: "Không thể lấy lịch sử mượn sách. Vui lòng thử lại sau !!!",
          type: "error",
        });
      }
    };

    fetchLoanHistory(currentPage);
  }, [currentPage]);

  const handlePageChange = (page) => {
    setCurrentPage(page);
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    const { memberId, bookCopyId, additionalDays } = formData;
    const token = localStorage.getItem("token");
    const staffId = localStorage.getItem("userId");
    const role = localStorage.getItem("role");

    if (role !== "STAFF") {
      setMessage({
        text: "Bạn không có quyền thực hiện chức năng này.",
        type: "error",
      });
      return;
    }

    const url = `${BASE_URL}api/staff/loans/borrow?memberId=${memberId}&bookCopyId=${bookCopyId}&additionalDays=${additionalDays}&createBy=${staffId}`;

    try {
      const response = await fetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
          "ngrok-skip-browser-warning": "69420",
          Authorization: `Bearer ${token}`,
        },
      });

      if (!response.ok) {
        const errorText = await response.text();
        if (errorText.includes("No book found")) {
          setMessage({
            text: "Không có sách nào mượn với UserID này.",
            type: "error",
          });
        } else if (errorText.includes("No user found")) {
          setMessage({
            text: "Không có người dùng nào với UserID này.",
            type: "error",
          });
        } else {
          setMessage({
            text: "Không thể mượn sách. Vui lòng thử lại !!!",
            type: "error",
          });
        }
        return;
      }
      setMessage({
        text: "Mượn sách thành công!",
        type: "success",
      });
      setFormData({
        memberId: "",
        bookCopyId: "",
        additionalDays: "",
        fullName: "",
        username: "",
        gender: "",
        title: "",
        author: "",
        category: "",
      });
    } catch (error) {
      setMessage({
        text: "Không thể mượn sách. Vui lòng thử lại !!!",
        type: "error",
      });
    }
  };

  const handleScanMember = (data) => {
    if (data) {
      try {
        const parsedData = JSON.parse(data.text);
        setFormData((prevFormData) => ({
          ...prevFormData,
          memberId: parsedData.memberid || "",
          fullName: parsedData.fullName || "",
          username: parsedData.username || "",
          gender: parsedData.gender || "",
        }));
        setShowMemberScanner(false);
      } catch (error) {
        console.error("Error parsing QR code data:", error);
      }
    }
  };

  const handleScanBook = (data) => {
    if (data) {
      try {
        const parsedData = JSON.parse(data.text);
        setFormData((prevFormData) => ({
          ...prevFormData,
          bookCopyId: parsedData.bookCopyId || "",
          title: parsedData.title || "",
          author: parsedData.author || "",
          category: parsedData.categoryCode || "",
        }));
        setShowBookScanner(false);
      } catch (error) {
        console.error("Error parsing QR code data:", error);
      }
    }
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData((prevFormData) => ({
      ...prevFormData,
      [name]: value,
    }));
  };

  const handleError = (err) => {
    console.error(err);
  };

  const formatDate = (dateString) => {
    const options = { day: "numeric", month: "long", year: "numeric" };
    const date = new Date(dateString);
    return date.toLocaleDateString("vi-VN", options);
  };

  const previewStyle = {
    height: 240,
    width: 400,
  };

  return (
    <div className="borrow-book-container">
      <Navbar />
      <div className="borrow-book-main">
        <Sidebar className="borrow-book-sidebar" />
        <div className="borrow-book-content">
          <h2 className="borrow-book-title">Borrow Books</h2>
          <form onSubmit={handleSubmit} className="borrow-book-form">
            <div className="borrow-book-form-group">
              <label>Member ID:</label>
              <div className="borrow-book-input-group">
                <input
                  type="number"
                  name="memberId"
                  value={formData.memberId}
                  onChange={handleChange}
                  required
                />
                <button
                  type="button"
                  onClick={() => setShowMemberScanner((prev) => !prev)}
                  className="scan-button"
                >
                  {showMemberScanner ? "Close Scanner" : "Scan QR"}
                </button>
              </div>
            </div>
            <div className="borrow-book-member-info">
              <p>
                Full Name:{" "}
                <span className="info-text">{formData.fullName}</span>
              </p>
              <p>
                Username: <span className="info-text">{formData.username}</span>
              </p>
              <p>
                Gender: <span className="info-text">{formData.gender}</span>
              </p>
            </div>
            {showMemberScanner && (
              <div className="borrow-book-qr-scanner-container">
                <QrScanner
                  delay={300}
                  style={previewStyle}
                  onError={handleError}
                  onScan={handleScanMember}
                />
                <button
                  type="button"
                  onClick={() => setShowMemberScanner(false)}
                  className="borrow-book-close-button"
                >
                  X
                </button>
              </div>
            )}
            <div className="borrow-book-form-group">
              <label>Book ID:</label>
              <div className="borrow-book-input-group">
                <input
                  type="number"
                  name="bookCopyId"
                  value={formData.bookCopyId}
                  onChange={handleChange}
                  required
                />
                <button
                  type="button"
                  onClick={() => setShowBookScanner((prev) => !prev)}
                  className="scan-button"
                >
                  {showBookScanner ? "Close Scanner" : "Scan QR"}
                </button>
              </div>
            </div>
            {showBookScanner && (
              <div className="qr-scanner-container">
                <QrScanner
                  delay={300}
                  style={previewStyle}
                  onError={handleError}
                  onScan={handleScanBook}
                />
                <button
                  type="button"
                  onClick={() => setShowBookScanner(false)}
                  className="borrow-book-close-button"
                >
                  X
                </button>
              </div>
            )}
            <div className="borrow-book-book-info">
              <p>
                Title: <span className="info-text">{formData.title}</span>
              </p>
              <p>
                Author: <span className="info-text">{formData.author}</span>
              </p>
              <p>
                Category: <span className="info-text">{formData.category}</span>
              </p>
            </div>
            <div className="borrow-book-form-group">
              <label>Additional Days:</label>
              <input
                type="number"
                name="additionalDays"
                value={formData.additionalDays}
                onChange={handleChange}
                required
              />
            </div>
            <button type="submit" className="submit-button">
              Borrow Book
            </button>
            {message.text && (
              <div
                className={`borrow-book-message ${
                  message.type === "error" ? "error" : "success"
                }`}
              >
                {message.text}
              </div>
            )}
          </form>
          <div className="borrow-book-history">
            <h3>Loan History</h3>
            <table className="loan-history-table">
              <thead>
                <tr>
                  <th className="member-id">Loan ID</th>
                  <th className="title">Title</th>
                  <th className="user-name">User name</th>
                  <th className="borrowed-date">Borrowed Date</th>
                  <th className="returned-date">Returned Date</th>
                  <th className="status">Status</th>
                  <th className="action"></th>
                </tr>
              </thead>
              <tbody>
                {loanHistory.map((loan, index) => (
                  <tr key={index}>
                    <td className="member-id">{loan.loanId}</td>
                    <td className="title">{loan.copyBookTitle}</td>
                    <td className="user-name">{loan.userFullName}</td>
                    <td className="borrowed-date">
                      {formatDate(loan.loanDate)}
                    </td>
                    <td className="returned-date">
                      {formatDate(loan.dueDate)}
                    </td>
                    <td className="status">{loan.status}</td>
                    <td className="action">
                      <Link to={`/borroweddetail/${loan.loanId}`}>View</Link>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <div className="pagination">
            <button
              className="prev"
              onClick={() => handlePageChange(currentPage - 1)}
              disabled={currentPage === 0}
            >
              <FontAwesomeIcon icon={faArrowLeft} />
            </button>
            {Array.from({ length: totalPages }).map((_, index) => (
              <button
                key={index}
                onClick={() => handlePageChange(index)}
                className={index === currentPage ? "active" : ""}
              >
                {index + 1}
              </button>
            ))}
            <button
              className="next"
              onClick={() => handlePageChange(currentPage + 1)}
              disabled={currentPage === totalPages - 1}
            >
              <FontAwesomeIcon icon={faArrowRight} />
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

export default BorrowBook;
Leave a Comment