diff --git a/components/Books.js b/components/Books.js index c3b0ce8..b0bd61c 100644 --- a/components/Books.js +++ b/components/Books.js @@ -1,55 +1,39 @@ -import React from "react"; +import React, { useState } from "react"; import Swal from "sweetalert2"; import { host } from "../utils/constants"; -import { withSession } from "../hooks/withSession"; import { signIn } from "next-auth/react"; -import ChangeIdentifier from "./ChangeIdentifier"; +import { useSession } from "next-auth/react"; -class Books extends React.Component { - /** - * @param {Object} props - * @constructor - */ - constructor(props) { - super(props); - this.state = { - option: "gb", - bookid: "", - email: "", - show: true, - loader: false, - isDuplicate: false, - isValidIdentifier: true, - IATitle: "", - IAIdentifier: "", - inputDisabled: false, - }; - this.onSubmit = this.onSubmit.bind(this); - } +const Books = () => { + const { data: session } = useSession(); + const [option, setOption] = useState("gb"); + const [bookid, setBookId] = useState(""); + const [email, setEmail] = useState(""); + const [show, setShow] = useState(true); + const [loader, setLoader] = useState(false); + const [isDuplicate, setIsDuplicate] = useState(false); + const [IATitle, setIATitle] = useState(""); + const [IAIdentifier, setIAIdentifier] = useState(""); + const [inputDisabled, setInputDisabled] = useState(false); /** * Change the `option` state when user selects a different library - * @param {Object} event */ - handleChange = (event) => { - this.setState({ - option: event.target.value, - bookid: "", - isDuplicate: false, - isValidIdentifier: true, - IATitle: "", - IAIdentifier: "", - inputDisabled: false, - }); + const handleChange = (event) => { + setOption(event.target.value); + setBookId(""); + setIsDuplicate(false); + setIATitle(""); + setIAIdentifier(""); + setInputDisabled(false); }; /** * Change the example when user selects a different library - * @return {String} */ - showExample = () => { + const showExample = () => { let url = ""; - switch (this.state.option) { + switch (option) { case "gb": url = "https://books.google.co.in/books?id=At46AQAAMAAJ"; break; @@ -71,7 +55,7 @@ class Books extends React.Component { * Makes a request from Google Books API based on the entered book Id * If the book Id is not valid the request resolves with an error message */ - validateGoogleBook = (enteredId) => { + const validateGoogleBook = (enteredId) => { let googleUrl = `https://www.googleapis.com/books/v1/volumes/${enteredId}`; fetch(googleUrl) .then((response) => response.json()) @@ -81,13 +65,11 @@ class Books extends React.Component { } else if (details.error) { alert("Please give a valid volume ID."); } else { - this.setState({ - bookid: details.id, - bookTitle: details.volumeInfo.title, - bookAuthors: details.volumeInfo.authors, - bookDescription: details.volumeInfo.description, - bookCover: details.volumeInfo.imageLinks.thumbnail, - }); + setBookId(details.id); + setBookTitle(details.volumeInfo.title); + setBookAuthors(details.volumeInfo.authors); + setBookDescription(details.volumeInfo.description); + setBookCover(details.volumeInfo.imageLinks.thumbnail); } }) .catch((error) => { @@ -95,26 +77,21 @@ class Books extends React.Component { }); }; - onResetButtonClicked = () => { - this.setState({ - isDuplicate: false, - isValidIdentifier: true, - inputDisabled: false, - IATitle: "", - IAIdentifier: "", - }); + const onResetButtonClicked = () => { + setIsDuplicate(false); + setInputDisabled(false); + setIAIdentifier(""); + setIATitle(""); }; - onSwalClosed = () => { - this.setState({ - inputDisabled: false, - IAIdentifier: "", - IATitle: "", - }); + const onSwalClosed = () => { + setInputDisabled(false); + setIAIdentifier(""); + setIATitle(""); }; - renderContent = (option) => { - switch (option) { + const renderContent = (currentOption) => { + switch (currentOption) { case "gb": return ( <> @@ -129,11 +106,9 @@ class Books extends React.Component { name="bookid" type="text" required - disabled={this.state.inputDisabled} + disabled={inputDisabled} placeholder="At46AQAAMAAJ" - onChange={(event) => - this.setState({ bookid: event.target.value }) - } + onChange={(event) => setBookId(event.target.value)} aria-describedby="bid" /> @@ -150,10 +125,8 @@ class Books extends React.Component { type="text" id="bookid" name="bookid" - disabled={this.state.inputDisabled} - onChange={(event) => - this.setState({ bookid: event.target.value }) - } + disabled={inputDisabled} + onChange={(event) => setBookId(event.target.value)} required placeholder="http://www.panjabdigilib.org/webuser/searches/displayPage.jsp?ID=9073&page=1&CategoryID=1&Searched=" /> @@ -174,11 +147,9 @@ class Books extends React.Component { id="bookid" name="bookid" type="text" - disabled={this.state.inputDisabled} + disabled={inputDisabled} placeholder="249146214" - onChange={(event) => - this.setState({ bookid: event.target.value }) - } + onChange={(event) => setBookId(event.target.value)} required aria-describedby="bid" /> @@ -188,323 +159,267 @@ class Books extends React.Component { } }; - isPDLValidUrl = (urlString) => { - var urlPattren = new RegExp( - "((http|https)\\:\\/\\/)(www.)?(panjabdigilib\\.org\\/webuser\\/searches\\/displayPage\\.jsp\\?ID\\=)([0-9]*)(\\&page\\=)([0-9]*)(\\&CategoryID\\=)([0-9]*)(\\&Searched\\=)([a-zA-Z0-9@:%._+~#?&//=]*)" + const isPDLValidUrl = (urlString) => { + const urlPattern = new RegExp( + `((http|https)://)(www.)?panjabdigilib\\.org/webuser/searches/displayPage\\.jsp\\?ID=([0-9]*)&page=([0-9]*)&CategoryID=([0-9]*)(&Searched=[a-zA-Z0-9@:%._+~#?&//=]*)` ); - return urlPattren.test(urlString); + return urlPattern.test(urlString); }; - onSubmit = (event, userName) => { + const onSubmit = async (event) => { event.preventDefault(); - if (!userName || userName === "") { + // Check if user is logged in + if (!session || !session.user) { Swal("Error!", "Log in with Wikimedia to continue", "error"); return; } - this.setState({ - loader: true, - isDuplicate: false, - isValidIdentifier: true, - }); + setLoader(true); + setIsDuplicate(false); let url = ""; - const isAlphanumericLess50 = /^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]{1,50}$/; - switch (this.state.option) { + switch (option) { case "gb": - url = `${host}/check?bookid=${this.state.bookid}&option=${ - this.state.option + - (this.state.email ? "&email=" + this.state.email : "") - }&userName=${userName}&IAtitle=${this.state.IAIdentifier}`; - fetch(url) - .then((response) => response.json()) - .then(async (response) => { - this.setState({ - loader: false, - }); - if (response.isDuplicate) { - this.setState({ - isDuplicate: true, - IATitle: response.titleInIA, - inputDisabled: true, - }); - } else if (!isAlphanumericLess50.test(response.IAIdentifier)) { - this.setState({ - isValidIdentifier: false, - IATitle: response.IAIdentifier, - inputDisabled: true, - }); + url = `${host}/check?bookid=${bookid}&option=${option}${ + email ? "&email=" + email : "" + }&userName=${session.user.name}&IAtitle=${IAIdentifier}`; + try { + const response = await fetch(url); + const data = await response.json(); + setLoader(false); + + if (data.isDuplicate) { + setIsDuplicate(true); + setIATitle(data.titleInIA); + setInputDisabled(true); + } else { + if (data.error) { + Swal("Error!", data.message, "error"); } else { - if (response.error) { - Swal("Error!", response.message, "error"); - } else { - const { value: url } = await Swal({ - input: "url", - backdrop: true, - width: "50%", - allowEscapeKey: false, - allowOutsideClick: false, - showCloseButton: true, - onClose: this.onSwalClosed, - title: 'Just a few more steps...', - html: - `
    ` + - `
  1. Go to this link: ${response.title}
  2. ` + - `
  3. Enter the captcha.
  4. ` + - `
  5. Enter the URL below (https://books.googleusercontent.com/books/content?req=xxx)
  6. `, + const { value: url } = await Swal({ + input: "url", + backdrop: true, + width: "50%", + allowEscapeKey: false, + allowOutsideClick: false, + showCloseButton: true, + onClose: onSwalClosed, + title: 'Just a few more steps...', + html: + `
      ` + + `
    1. Go to this link: ${data.title}
    2. ` + + `
    3. Enter the captcha.
    4. ` + + `
    5. Enter the URL below (https://books.googleusercontent.com/books/content?req=xxx)
    6. `, + }); + + if (url && typeof url !== "object") { + setLoader(true); + const downloadResponse = await fetch(`${host}/download`, { + body: JSON.stringify({ + url: url, + titleInIA: data.IAIdentifier, + }), + headers: { + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + }, + method: "POST", }); + setLoader(false); - if (url && typeof url !== "object") { - this.setState({ - loader: true, - }); - fetch(`${host}/download`, { - body: JSON.stringify({ - url: url, - titleInIA: response.IAIdentifier, - }), - headers: { - "Content-Type": "application/json", - "Access-Control-Allow-Origin": "*", - }, - method: "POST", - }) - .then((response) => response.json()) - .then((response) => { - this.setState({ - loader: false, - }); - if (response.error) - Swal("Error!", response.message, "error"); - else Swal("Voila!", response.message, "success"); - }); + const downloadData = await downloadResponse.json(); + if (downloadData.error) { + Swal("Error!", downloadData.message, "error"); + } else { + Swal("Voila!", downloadData.message, "success"); } } } - }); + } + } catch (error) { + console.error(error); + } break; - // case "obp": - // const IDobp = this.state.bookid; - // const categoryObp = ""; - // url = `/check?bookid=${IDobp}&option=${ - // this.state.option + - // (this.state.email ? "&email=" + this.state.email : "") - // }&categoryID=${categoryObp}`; - // fetch(url) - // .then((res) => res.json()) - // .then((response) => { - // this.setState({ - // loader: false, - // }); - // if (response.error) Swal("Error!", response.message, "error"); - // else Swal("Voila!", response.message, "success"); - // }); - // break; - case "pn": - if (this.isPDLValidUrl(this.state.bookid)) { - const searchParams = new URL(this.state.bookid).searchParams; + if (isPDLValidUrl(bookid)) { + const searchParams = new URL(bookid).searchParams; const ID = searchParams.get("ID"); const categoryID = searchParams.get("CategoryID"); - url = `${host}/check?bookid=${ID}&option=${ - this.state.option + - (this.state.email ? "&email=" + this.state.email : "") - }&categoryID=${categoryID}&userName=${userName}&IAtitle=${ - this.state.IAIdentifier - }`; - fetch(url) - .then((res) => res.json()) - .then((response) => { - this.setState({ - loader: false, - }); - if (response.isDuplicate) { - this.setState({ - isDuplicate: true, - IATitle: response.titleInIA, - inputDisabled: true, - }); - } else if (!isAlphanumericLess50.test(response.IAIdentifier)) { - this.setState({ - isValidIdentifier: false, - IATitle: response.IAIdentifier, - inputDisabled: true, - }); + url = `${host}/check?bookid=${ID}&option=${option}${ + email ? "&email=" + email : "" + }&categoryID=${categoryID}&userName=${ + session.user.name + }&IAtitle=${IAIdentifier}`; + try { + const response = await fetch(url); + const data = await response.json(); + setLoader(false); + + if (data.isDuplicate) { + setIsDuplicate(true); + setIATitle(data.titleInIA); + setInputDisabled(true); + } else { + if (data.error) { + Swal("Error!", data.message, "error"); } else { - if (response.error) Swal("Error!", response.message, "error"); - else Swal("Voila!", response.message, "success"); + Swal("Voila!", data.message, "success"); } - }); + } + } catch (error) { + console.error(error); + } } else { - this.setState({ - loader: false, - }); + setLoader(false); Swal("Opps...", "Enter a valid URL", "error"); } break; case "trove": - url = `${host}/check?bookid=${this.state.bookid}&option=${ - this.state.option + - (this.state.email ? "&email=" + this.state.email : "") - }&userName=${userName}&IAtitle=${this.state.IAIdentifier}`; - fetch(url) - .then((res) => res.json()) - .then((response) => { - this.setState({ - loader: false, - }); - if (response.isDuplicate) { - this.setState({ - isDuplicate: true, - IATitle: response.titleInIA, - inputDisabled: true, - }); - } else if (!isAlphanumericLess50.test(response.IAIdentifier)) { - this.setState({ - isValidIdentifier: false, - IATitle: response.IAIdentifier, - inputDisabled: true, - }); + url = `${host}/check?bookid=${bookid}&option=${option}${ + email ? "&email=" + email : "" + }&userName=${session.user.name}&IAtitle=${IAIdentifier}`; + try { + const response = await fetch(url); + const data = await response.json(); + setLoader(false); + + if (data.isDuplicate) { + setIsDuplicate(true); + setIATitle(data.titleInIA); + setInputDisabled(true); + } else { + if (data.error) { + Swal("Error!", data.message, "error"); } else { - if (response.error) Swal("Error!", response.message, "error"); - else Swal("Voila!", response.message, "success"); + Swal("Voila!", data.message, "success"); } - }); + } + } catch (error) { + console.error(error); + } + break; + + default: + // Some other cases can be handled here if needed + break; } }; - render() { - const { data: session } = this.props.session; - return ( - -
      -

      Book Uploader Bot

      -
      - - Upload books, newspapers, magazines etc. from public libraries to - Internet Archive - -
      -
      this.onSubmit(e, session.user.name)}> -
      -

      1. Select a library

      - -
      -
      - {this.renderContent(this.state.option)} -
      - {this.state.isDuplicate ? ( - - A file with this identifier{" "} - - (https://archive.org/{this.state.IATitle}) - {" "} - already exists at Internet Archive. Please enter a different - identifier to proceed. - - } - inputPlaceholder="Enter unique file identifier" - onIdentifierChange={(event) => - this.setState({ IAIdentifier: event.target.value }) - } - /> - ) : null} - - {this.state.isValidIdentifier === false ? ( - - The file you want to upload with title -{" "} - {this.state.IATitle} either contains special characters or - exceeds 50 characters in length. Please provide an - identifier that consists only of letters (A-Z) and numbers - (0-9). - - } - inputPlaceholder="Enter a valid Identifier that is less than 50 characters and Alphanumeric" - onIdentifierChange={(event) => - this.setState({ IAIdentifier: event.target.value }) - } - /> - ) : null} - - {session && ( -
      -
      - - {this.state.isDuplicate === true || - this.state.isValidIdentifier === false ? ( - - ) : null} -
      + return ( +
      +

      Book Uploader Bot

      +
      + + Upload books, newspapers, magazines etc. from public libraries to + Internet Archive + +
      + +
      +

      1. Select a library

      + +
      +
      {renderContent(option)}
      + {isDuplicate && ( +
      + +
      + A file with this identifier{" "} + + (https://archive.org/{IATitle}) + {" "} + already exists at Internet Archive. Please enter a different + identifier to proceed. +
      + + https://archive.org/details/ + + setIAIdentifier(event.target.value)} + required + placeholder="Enter unique file identifier" + />
      - )} - {!session && ( -
      -
      - - Upload restricted. Login with Wikimedia Account to continue. - -
      +
      +
      + )} + {session && ( +
      +
      + + {isDuplicate === true && ( -
      - )} - - {this.state.loader ? ( -
      + )} +
      +
      + )} + {!session && ( +
      +
      - Fetching information. Please wait.. + Upload restricted. Login with Wikimedia Account to continue. -
      -
      -
      - ) : null} + +
      + )} + + {loader && ( +
      + + Fetching information. Please wait... + +
      +
      +
      - - ); - } -} - -const BooksWithSession = withSession(Books); + )} +
      + ); +}; -export default BooksWithSession; +export default Books; diff --git a/components/UploadedItems.js b/components/UploadedItems.js index 5ec99e0..8a8cf35 100644 --- a/components/UploadedItems.js +++ b/components/UploadedItems.js @@ -1,57 +1,53 @@ -import React, { Component } from "react"; +import { useState, useEffect } from "react"; import Link from "next/link"; const url = `https://archive.org/advancedsearch.php?q=bub.wikimedia+&rows=0&output=json`; -class UploadedItems extends Component { - constructor(props) { - super(props); - this.state = { - booksUploaded: 0 - } - this.fetchData = this.fetchData.bind(this); - } +const UploadedItems = () => { + // Define the state using the useState hook + const [booksUploaded, setBooksUploaded] = useState(0); - fetchData() { + // Fetch data when the component mounts + useEffect(() => { + fetchData(); + }, []); + + // Function to fetch data + const fetchData = () => { fetch(url) .then((response) => response.json()) .then((responseJson) => { const booksCount = responseJson.response.numFound; - this.setState({ booksUploaded: booksCount }); + setBooksUploaded(booksCount); }) .catch((error) => { console.error(error); }); - } - - componentDidMount() { - this.fetchData(); - } + }; - render() { - return ( -
      - - + return ( +
      + + - ); - } -} +
      + ); +}; export default UploadedItems; -