Add untracked files

Add untracked files

diff --git a/src/App.js b/src/App.js
index 3784575..253bc50 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,25 +1,234 @@
-import logo from './logo.svg';
-import './App.css';
+/* eslint-disable react-hooks/exhaustive-deps */
+import React, { useState, useEffect, useCallback } from "react";
+import Web3 from "web3";
+import { newKitFromWeb3 } from "@celo/contractkit";
+import "./App.css";
+import { contractABI, contractAddress } from "./utils/const";
+import {
+  Navbar,
+  Welcome,
+  AddBook,
+  BookList,
+  ReadingList,
+} from "./components/Index";
 
 function App() {
+  const [currentAccount, setCurrentAccount] = useState("");
+  const [books, setBooks] = useState([]);
+  const [bookCount, setBookCount] = useState(0);
+  const [contract, setContractInstance] = useState(null);
+  const [kit, setKit] = useState(null);
+  const [userBorrowedBooks, setUserBorrowedBooks] = useState([]);
+  const [bookCIDs, setBookCIDs] = useState([]);
+  const [selectedCID, setSelectedCID] = useState("");
+
+  const initContract = useCallback(async () => {
+    try {
+      if (!window.ethereum) {
+        console.error("Celo Wallet extension not detected");
+        return;
+      }
+
+      const web3 = new Web3(window.ethereum);
+      const kit = newKitFromWeb3(web3);
+      await window.ethereum.request({ method: "eth_requestAccounts" });
+      const contract = new kit.web3.eth.Contract(contractABI, contractAddress);
+
+      setCurrentAccount((await kit.web3.eth.getAccounts())[0]);
+      setKit(kit);
+      setContractInstance(contract);
+    } catch (error) {
+      console.log(error);
+    }
+  }, [contractAddress]);
+  useEffect(() => {
+    if (currentAccount) {
+      initContract();
+    }
+  }, [currentAccount, initContract]);
+
+  const checkIfWalletIsConnected = () => {
+    try {
+      if (!window.ethereum)
+        return alert("Please install the Celo wallet extension");
+
+      const web3 = new Web3(window.ethereum);
+      web3.eth.getAccounts((err, accounts) => {
+        if (err) {
+          console.error(err);
+          throw new Error("Failed to get accounts");
+        }
+        if (accounts && accounts.length) {
+          setCurrentAccount(accounts[0]);
+        } else {
+          console.log("No accounts found");
+        }
+        console.log(accounts);
+      });
+    } catch (error) {
+      console.log(error);
+      throw new Error("No ethereum object");
+    }
+  };
+  useEffect(() => {
+    checkIfWalletIsConnected();
+  }, []);
+
+  const connectToWallet = async () => {
+    try {
+      if (!window.ethereum)
+        throw new Error("Celo wallet extension not detected");
+
+      await window.ethereum.enable({ method: "eth_requestAccounts" });
+      const accounts = await window.ethereum.request({
+        method: "eth_accounts",
+      });
+      setCurrentAccount(accounts[0]);
+    } catch (error) {
+      console.log(error);
+      throw new Error("Failed to connect to Celo wallet");
+    }
+  };
+
+  const addBook = async (title, author, pinataCid, availableCopies) => {
+    try {
+      console.log(
+        "title:",
+        title,
+        "author:",
+        author,
+        "pinataCid:",
+        pinataCid,
+        "availableCopies:",
+        availableCopies
+      );
+
+      await contract.methods
+        .addBook(title, author, pinataCid, availableCopies)
+        .send({ from: currentAccount, gasLimit: 2000000 });
+
+      const bookCount = await contract.methods.getBookCount().call();
+      setBookCount(bookCount);
+
+      // Fetch the new book by its index (bookCount - 1) and update the state
+      const newBook = await contract.methods.getAllBooks().call();
+      setBooks([...books, newBook]);
+    } catch (error) {
+      console.error(error);
+    }
+  };
+
+  const fetchBooks = async () => {
+    try {
+      if (!contract) return;
+      const bookCount = await contract.methods.getBookCount().call();
+      const booksArray = await contract.methods.getAllBooks().call();
+
+      setBooks(booksArray);
+    } catch (error) {
+      console.error("Error fetching books:", error);
+    }
+  };
+
+  useEffect(() => {
+    fetchBooks();
+  }, [contract]);
+
+  const borrowBook = async (bookId) => {
+    try {
+      await contract.methods
+        .borrowBook(bookId)
+        .send({ from: currentAccount, gasLimit: 2000000 });
+      const updateBooks = books.map((book) => {
+        if (book.id === bookId) {
+          return { ...book, availableCopies: book.availableCopies - 1 };
+        }
+        return book;
+      });
+      setBooks(updateBooks);
+    } catch (error) {
+      console.error("Error borrowing the book:", error);
+    }
+  };
+
+  const readingList = async () => {
+    try {
+      const borrowedBooks = await contract.methods
+        .readingList(currentAccount)
+        .call();
+      setUserBorrowedBooks(borrowedBooks);
+    } catch (error) {
+      console.error("Error fetching reading list:", error);
+    }
+  };
+  useEffect(() => {
+    if (currentAccount && contract) {
+      readingList();
+    }
+  }, [currentAccount, contract, readingList]);
+
+  const getBookCIDs = async () => {
+    const bookCIDs = await Promise.all(
+      userBorrowedBooks.map(async (bookId) => {
+        const pinataCid = await contract.methods.getBookCID(bookId).call();
+
+        return { bookId, pinataCid };
+      })
+    );
+
+    setBookCIDs(bookCIDs);
+  };
+
+  useEffect(() => {
+    if (userBorrowedBooks.length > 0) {
+      getBookCIDs();
+    }
+  }, [userBorrowedBooks]);
+
+  const openPDF = (pinataCid) => {
+    setSelectedCID(pinataCid);
+  };
+
+  const returnBook = async (bookId) => {
+    try {
+      await contract.methods
+        .returnBook(bookId)
+        .send({ from: currentAccount, gasLimit: 200000 });
+      const updatedBooks = books.map((book) => {
+        if (book.id === bookId) {
+          return { ...book, availableCopies: book.availableCopies + 1 };
+        }
+        return book;
+      });
+      setBooks(updatedBooks);
+    } catch (error) {
+      console.error("Error returning the book:", error);
+    }
+  };
+
   return (
-    <div className="App">
-      <header className="App-header">
-        <img src={logo} className="App-logo" alt="logo" />
-        <p>
-          Edit <code>src/App.js</code> and save to reload.
-        </p>
-        <a
-          className="App-link"
-          href="https://reactjs.org"
-          target="_blank"
-          rel="noopener noreferrer"
-        >
-          Learn React
-        </a>
-      </header>
+    <div className="min-h-screen">
+      <div className="gradient-bg-welcome">
+        <Navbar />
+        <Welcome
+          connectToWallet={connectToWallet}
+          currentAccount={currentAccount}
+        />
+      </div>
+      <AddBook addBook={addBook} />
+      <BookList
+        books={books}
+        borrowBook={borrowBook}
+        readingList={readingList}
+      />
+      <ReadingList
+        borrowedBooks={userBorrowedBooks}
+        bookCIDs={bookCIDs}
+        openPDF={openPDF}
+        selectedCID={selectedCID}
+        returnBook={returnBook}
+      />
     </div>
   );
 }
-
 export default App;

GitHub
sha: 7c7da1cfb84eb663d70790edb13895b31e5440a7

1 Like