0

I am developing an book inventory form to add book. I use Nextjs and Prisma, tRPC. I don't know why but i have run successfully with this code and the layout is perfect. However, many seconds later, some reason make it have error.

import Head from "next/head";
import { ChangeEvent, useEffect, useRef, useState } from "react";
import { Card, CardHeader, CardBody, Typography, Input, Select, Option, Button } from "@material-tailwind/react";
import DashboardLayout from "@/layouts/dashboard";
import { type NextPageWithLayout } from "../page";
import { api } from "@/utils/api";

const TABLE_HEAD = ["ID", "Tên sách", "Thể loại", "Nhà xuất bản", "Năm xuất bản", "Số lượng", "Đơn giá"];


const BookEntryTicket: NextPageWithLayout = () => {

  const [bookTitle, setBookTitle] = useState<any>();
  const [publisher, setPublisher] = useState("");
  const [publishedYear, setPublishedYear] = useState("");
  const [price, setPrice] = useState(0);
  const [quantity, setQuantity] = useState("");
  const [isTableOpen, setIsTableOpen] = useState(true); // Thêm state để theo dõi trạng thái của bảng sách
  const [tableHeight, setTableHeight] = useState(0);
  const tableRef = useRef(null);
  const [bookList, setBookList] = useState<any[]>([]);
  const [totalPrice, setTotalPrice] = useState(0);
  const { data, isLoading, isFetching } = api.title.getAll.useQuery({});


  const handleFormSubmit = (e: { preventDefault: () => void; }) => {
    e.preventDefault();
    // Add your logic here to handle form submission

  };

  const calculateTotalPrice = () => {
    const totalPrice = bookList.reduce(
      (accumulator, book) => accumulator + book.quantity * book.price,
      0
    );
    setTotalPrice(totalPrice);
  };

  useEffect(() => {
    calculateTotalPrice();
  }, [bookList]);
  

  const hanldeAddBook = (e: { preventDefault: () => void; }) => {
    e.preventDefault();

    const newBook = {
      id: bookList.length + 1,
      name: bookTitle,
      genre: "Kinh dị",
      publisher,
      published_year: publishedYear,
      quantity,
      price,
    };
  
    setBookList((prevBookList) => [...prevBookList, newBook]);
  }

  const toggleTable = () => {
    setIsTableOpen(!isTableOpen); // Thay đổi trạng thái của bảng khi nhấn vào nút "Hiển thị danh sách sách"
  };

  useEffect(() => {
    if (tableRef.current) {
      setTableHeight(isTableOpen ? (tableRef.current as HTMLTableElement)?.scrollHeight ?? 0 : 0);
    }
  }, [isTableOpen, bookList]); 
  
  const handleDeleteBook = (bookId: number) => {
    setBookList((prevBookList) => prevBookList.filter((book) => book.id !== bookId));
  };
  

  return (
    <>
      <Head>
        <title>Phiếu nhập sách</title>
      </Head>
      <div className="mb-8 mt-12">
        <Card>
          <CardHeader
            variant="gradient"
            color="blue"
            className="mb-2 flex items-center justify-between px-6 py-4"
          >
            <Typography variant="h6" color="white">
              Thông tin sách
            </Typography>
          </CardHeader>
          <CardBody className="flex flex-col gap-6">
            <div className="flex flex-row gap-10">
              <div className="flex flex-col gap-6 w-full">
                <Select 
                  label="Tên đầu sách" 
                  onChange={(e) => {
                    setBookTitle(e);
                  }}
                >
                  {data && data.map((book) => (
                    <Option key={book.MaDauSach} value={book.TenDauSach}>
                      {book.TenDauSach}
                    </Option>
                  ))}
                </Select>
                <Input variant="outlined" label="Năm xuất bản" onChange={(e) => setPublishedYear(e.target.value)}/>
                <Input variant="outlined" label="Đơn giá nhập" onChange={(e) => setPrice(parseInt(e.target.value))}/>
              </div>
              <div className="flex flex-col gap-6 w-full">
                <Input variant="outlined" label="Nhà xuất bản" onChange={(e) => setPublisher(e.target.value)}/>
                <Input variant="outlined" label="Số lượng" onChange={(e) => setQuantity(e.target.value)}/>
                <div className="flex flex-row gap-10 justify-end">
                  <Button onClick={hanldeAddBook}>Thêm sách</Button>
                </div>
              </div>
            </div>
            {/* <div className="flex flex-row gap-10 justify-end">
              <Button onClick={hanldeAddBook}>Thêm sách</Button>
            </div> */}
          </CardBody>
        </Card>
        <Card className="mt-10">
          <CardHeader
            variant="gradient"
            color="blue"
            className="mb-2 flex items-center justify-between px-6 py-4"
          >
            <Typography variant="h6" color="white">
              Phiếu nhập sách
            </Typography>
          </CardHeader>
          <CardBody className="flex flex-col gap-6">
            <div className="flex flex-row gap-10 w-full">
            <div className="flex-grow">
              <Input variant="outlined" label="Ngày nhập sách" type="date" />
            </div>
            <div className="flex-grow flex items-center">
              <Typography variant="h6" color="blue-gray">
                Tổng tiền: {
                  totalPrice.toLocaleString("vi-VN", {
                    style: "currency",
                    currency: "VND",
                  }
                )}
              </Typography>
            </div>
            </div>
            <div className="flex flex-col gap-6 w-full">
              <Card 
                className="overflow-hidden" 
                style={{ 
                  maxHeight: tableHeight,
                  transition: isTableOpen ? 'max-height 0.5s ease-in-out' : 'none',
                  overflow: 'hidden'
                }}>
                <table className="w-full min-w-max table-auto text-left" ref={tableRef}>
                  <thead>
                    <tr>
                      {TABLE_HEAD.map((head) => (
                        <th key={head} className="border-b border-blue-gray-100 bg-blue-gray-50 p-4">
                          <Typography
                            variant="small"
                            color="blue-gray"
                            className="font-normal leading-none opacity-70"
                          >
                            {head}
                          </Typography>
                        </th>
                      ))}
                      <th className="border-b border-blue-gray-100 bg-blue-gray-50 p-4"></th> {/* Add new column for delete button */}
                    </tr>
                  </thead>
                  <tbody> 
                    {bookList && bookList.map(({ id, name, genre, publisher, published_year, quantity, price }, index) => {
                      const isLast = index === (TABLE_HEAD.length - 1);
                      const classes = isLast ? "p-4" : "p-4 border-b border-blue-gray-50";
                      return (
                        <tr key={id}>
                          <td className={classes}>
                            <Typography variant="small" color="blue-gray" className="font-normal">
                              {index + 1}
                            </Typography>
                          </td>
                          <td className={classes}>
                            <Typography variant="small" color="blue-gray" className="font-normal">
                              {name}
                            </Typography>
                          </td>
                          <td className={classes}>
                            <Typography variant="small" color="blue-gray" className="font-normal">
                              {genre}
                            </Typography>
                          </td>
                          <td className={classes}>
                            <Typography variant="small" color="blue-gray" className="font-normal">
                              {publisher}
                            </Typography>
                          </td>
                          <td className={classes}>
                            <Typography variant="small" color="blue-gray" className="font-normal">
                              {published_year}
                            </Typography>
                          </td>
                          <td className={classes}>
                            <Typography variant="small" color="blue-gray" className="font-normal">
                              {quantity}
                            </Typography>
                          </td>
                          <td className={classes}>
                            <Typography variant="small" color="blue-gray" className="font-normal">
                              {price.toLocaleString("vi-VN", {
                                  style: "currency",
                                  currency: "VND"
                              })}
                            </Typography>
                          </td>
                          <td className={classes}>
                          <Typography
                            variant="small"
                            color="red"
                            className="cursor-pointer"
                            onClick={() => handleDeleteBook(id)} // Add onClick event for delete action
                          >
                            Xóa
                          </Typography>
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </Card>
            </div>
            <div className="flex flex-row gap-3 justify-end w-full">
              <Button onClick={toggleTable}>{isTableOpen ? "Ẩn danh sách sách" : "Hiển thị danh sách sách"}</Button>
              <Button>Lưu phiếu</Button>
            </div>
          </CardBody>
        </Card>
      </div>
    </>
  );
};

BookEntryTicket.getLayout = (page) => <DashboardLayout>{page}</DashboardLayout>;

export default BookEntryTicket;

I cannot identify which '-1' from. I just checked the index of array but no problem with it. I hope you can debug for me

0 Answers0