import React from 'react'; import FourButtons from './Components/FourButtons'; import { Dialog } from 'react-overlay-pack'; import CorrectSign from './material/sign_correct.png'; import ErrorSign from './material/sign_error.png'; import ElementDisplay from './Components/ElementDisplay'; function App() { /* Activate Hooks */ const { useState } = React; /* Initializing Hooks for component values showed in main page */ const [queryStr, setQueryStr] = useState('') const [sign, setSign] = useState(CorrectSign) const [text, setText] = useState('This area shows the result of requests..') const [formState, setFormState] = useState('hide') const [dialogState, setDialogState] = useState(false) const [renderState, setRenderState] = useState(false) /* initializing form-like input of bookData for PUT and POST */ const [bookURLState, setBookURLState] = useState('') const [bookTitleState, setBookTitleState] = useState('') const [bookIDState, setBookIDState] = useState('') const [bookISBNState, setBookISBNState] = useState('') const [bookAuthorState, setBookAuthorState] = useState('') const [bookAuthorURLState, setBookAuthorURLState] = useState('') const [bookRatingState, setBookRatingState] = useState('') const [bookRatingCountState, setBookRatingCountState] = useState('') const [bookReviewCountState, setBookReviewCountState] = useState('') const [bookImageURLState, setBookImageURLState] = useState('') const [bookSimilarBooksState, setBookSimilarBooksState] = useState('') /* Initializing form-like input of authorData for PUT AND POST */ const [authorNameState, setAuthorNameState] = useState('') const [authorURLState, setAuthorURLState] = useState('') const [authorIDState, setAuthorIDState] = useState('') const [authorRatingState, setAuthorRatingState] = useState('') const [authorRatingCountState, setAuthorRatingCountState] = useState('') const [authorReviewCountState, setAuthorReviewCountState] = useState('') const [authorImageURLState, setAuthorImageURLState] = useState('') const [authorRelatedAuthorsState, setAuthorRelatedAuthorsState] = useState('') const [authorAuthorBooksState, setAuthorAuthorBooksState] = useState('') /* Hooks used to show whether the data passed in is bookData or authorData */ const [dataState, setDataState] = useState({}) /* Activating axios */ const axios = require('axios').default; var center = {display: 'flex', justifyContent: 'center', alignItems: 'center'} /** Function used to hide the input form */ function hideForm() { setFormState('hide') } /** Function used to show bookData input form */ function changeFormStateBook() { setRenderState(false) if (formState === 'hide') { setFormState('showBook') } else { setFormState('hide') } } /** Function used to show authorData input form */ function changeFormStateAuthor() { setRenderState(false) if (formState === 'hide') { setFormState('showAuthor') } else { setFormState('hide') } } /** Function used to set Dialog visible, which is called when a response is received */ function showDialog() { setDialogState(true) } /** Function used in GET Requests */ function get() { axios.get('http://127.0.0.1:5000/api/' + queryStr) .then(function (response) { // handle success setSign(CorrectSign) showDialog() document.getElementById('dialog').value = response.status + ":\n" + response.statusText if (queryStr.includes('book')) { setDataState(response.data['books']) } else { setDataState(response.data['authors']) } setRenderState(true) }) .catch(function (error) { // handle error setSign(ErrorSign) showDialog() document.getElementById('dialog').value = error //.response.status + ":\n" + error.response.statusText }) } /** Function used in PUT and POST: extract user input of bookData from the form and parse into JSON */ function createJson() { var bookData = {} bookData.type = 'book' /* Set corresponding value if the input is not empty */ if(bookURLState !== '') {bookData.book_url = bookURLState} if(bookTitleState !== '') {bookData.title = bookTitleState} if(bookIDState !== '') {bookData.id = bookIDState} if(bookISBNState !== '') {bookData.ISBN = bookISBNState} if(bookAuthorURLState !== '') {bookData.author_url = bookAuthorURLState} if(bookAuthorState !== '') {bookData.author = bookAuthorState} if(bookRatingState !== '') {bookData.rating = parseFloat(bookRatingState)} if(bookRatingCountState !== '') {bookData.rating_count = parseInt(bookRatingCountState)} if(bookReviewCountState !== '') {bookData.review_count = parseInt(bookReviewCountState)} if(bookSimilarBooksState !== '') {bookData.similar_books = bookSimilarBooksState.split(', ')} setDataState(bookData) return bookData } /** Function used in PUT and POST: extract user input of authorData from the form and parse into JSON */ function createJsonAuthor() { var authorData = {} authorData.type = 'author' /* Set corresponding value if the input is not empty */ if(authorNameState !== '') {authorData.name = authorNameState} if(authorURLState !== '') {authorData.author_url = authorURLState} if(authorIDState !== '') {authorData.id = authorIDState} if(authorRatingState !== '') {authorData.rating = parseFloat(authorRatingState)} if(authorRatingCountState !== '') {authorData.rating_count = parseInt(authorRatingCountState)} if(authorReviewCountState !== '') {authorData.review_count = parseInt(authorReviewCountState)} if(authorImageURLState !== '') {authorData.image_url = authorImageURLState} if(authorRelatedAuthorsState !== '') {authorData.related_authors = authorRelatedAuthorsState.split(', ')} if(authorAuthorBooksState !== '') {authorData.author_books = authorAuthorBooksState.split(',')} setDataState(authorData) return authorData } /** Function used in PUT requests */ function put() { setRenderState(false) hideForm() var data; if (queryStr.includes('book')) { data = createJson() } else { data = createJsonAuthor() } let config = { headers: { 'Content-Type': 'application/json', } } axios.put('http://127.0.0.1:5000/api/' + queryStr, data, config) .then(function (response) { // handle success setSign(CorrectSign) showDialog() document.getElementById('dialog').value = response.status + ":\n" + response.statusText }) .catch(function (error) { // handle error setSign(ErrorSign) showDialog() document.getElementById('dialog').value = error //.response.status + ":\n" + error.response.statusText }) } /** Function used in POST requests */ function post() { setRenderState(false) let config = { headers: { 'Content-Type': 'application/json', } } hideForm() var data; if (queryStr.includes('book')) { data = createJson() } else { data = createJsonAuthor() } axios.post('http://127.0.0.1:5000/api/' + queryStr, JSON.stringify(data), config) .then(function (response) { // handle success setSign(CorrectSign) showDialog() document.getElementById('dialog').value = response.status + ":\n" + response.statusText }) .catch(function (error) { // handle error setSign(ErrorSign); showDialog(); document.getElementById('dialog').value = error //.response.status + ":\n" + error.response.statusText }) } /** Function used in DELETE requests */ function delete_data() { setRenderState(false) axios.delete('http://127.0.0.1:5000/api/' + queryStr) .then(function (response) { // handle success setSign(CorrectSign) showDialog() document.getElementById('dialog').value = response.status + ":\n" + response.statusText }) .catch(function (error) { // handle error setSign(ErrorSign) showDialog() document.getElementById('dialog').value = error //.response.status + ":\n" + error.response.statusText }) } /** HTML code */ return ( <div> {/* Dialog used when received response from server */} {dialogState === true && <Dialog //Warning, not responsive! show={dialogState} onOutsideClick={() => setDialogState(false)}> <div style={{marginTop:'20%'}}> <div style={{ marginLeft: '35%' }}> <img alt='responseStatus' src={sign}/> </div> <div> <textarea id='dialog' readOnly={true} rows="3" cols="38" style={{ border:'2px solid silver', backgroundColor: 'white', fontSize: '200%', margin: '50px' }}> {text} </textarea> </div> </div> </Dialog>} <h1 style={center}> Welcome to the home page of GoodReads Crawler! </h1> <h3 style={center}> Please input your query string:</h3> <div style={center}> <input id='queryString' type='text' placeholder='example: book/?id=12345678' size='40' value={queryStr} onChange={(e) => setQueryStr(e.target.value)} /> </div> <h3 style={center}> Please input your data for uploading (only effective for POST and PUT):</h3> {/* Buttons used to select book or author data to be passed to PUT/POST */} {formState === 'hide' && <div style={center}> <button style={{width:60}} onClick={changeFormStateBook}> book </button> <button style={{marginLeft:10, width:60}} onClick={changeFormStateAuthor}> author </button> </div>} {/* Form-like input for bookData */} {formState === 'showBook' && <form style={{border:'2px solid silver', marginLeft:'180px', marginRight: '180px'}}> <div style={center}> <input id='bookURL' style={center} type='text' size='40' value={bookURLState} placeholder='bookURL' onChange={(e) => setBookURLState(e.target.value)}/> </div> <div style={center}> <input id='bookTtile' style={center} type='text' size='40' value={bookTitleState} placeholder='bookTtile' onChange={(e) => setBookTitleState(e.target.value)}/> </div> <div style={center}> <input id='bookID' type='text' size='40' value={bookIDState} placeholder='bookID' onChange={(e) => setBookIDState(e.target.value)}/> </div> <div style={center}> <input id='bookISBN' type='text' size='40' value={bookISBNState} placeholder='bookISBN' onChange={(e) => setBookISBNState(e.target.value)}/> </div> <div style={center}> <input id='bookAuthorURL' type='text' size='40' value={bookAuthorURLState} placeholder='bookAuthorURL' onChange={(e) => setBookAuthorURLState(e.target.value)}/> </div> <div style={center}> <input id='bookAuthor' type='text' size='40' value={bookAuthorState} placeholder='bookAuthor' onChange={(e) => setBookAuthorState(e.target.value)}/> </div> <div style={center}> <input id='bookRating' type='text' size='40' value={bookRatingState} placeholder='bookRating' onChange={(e) => setBookRatingState(e.target.value)}/> </div> <div style={center}> <input id='bookRatingCount' type='text' size='40' value={bookRatingCountState} placeholder='bookRatingCount' onChange={(e) => setBookRatingCountState(e.target.value)}/> </div> <div style={center}> <input id='bookReviewCount' type='text' size='40' value={bookReviewCountState} placeholder='bookReviewCount' onChange={(e) => setBookReviewCountState(e.target.value)}/> </div> <div style={center}> <input id='bookImageURL' type='text' size='40' value={bookImageURLState} placeholder='bookImageURL' onChange={(e) => setBookImageURLState(e.target.value)}/> </div> <div style={center}> <input id='bookSimilarBooks' type='text' size='40' value={bookSimilarBooksState} placeholder='bookSimilarBooks' onChange={(e) => setBookSimilarBooksState(e.target.value)}/> </div> </form> } {/* Form-like input for authorData */} {formState === 'showAuthor' && <form style={{border:'2px solid silver', marginLeft:'180px', marginRight: '180px'}}> <div style={center}> <input id='authorName' style={center} type='text' size='40' value={authorNameState} placeholder='authorName' onChange={(e) => setAuthorNameState(e.target.value)}/> </div> <div style={center}> <input id='authorURL' style={center} type='text' size='40' value={authorURLState} placeholder='authorURL' onChange={(e) => setAuthorURLState(e.target.value)}/> </div> <div style={center}> <input id='authorID' type='text' size='40' value={authorIDState} placeholder='authorID' onChange={(e) => setAuthorIDState(e.target.value)}/> </div> <div style={center}> <input id='authorRating' type='text' size='40' value={authorRatingState} placeholder='authorRating' onChange={(e) => setAuthorRatingState(e.target.value)}/> </div> <div style={center}> <input id='authorRatingCount' type='text' size='40' value={authorRatingCountState} placeholder='authorRatingCount' onChange={(e) => setAuthorRatingCountState(e.target.value)}/> </div> <div style={center}> <input id='authorReviewCount' type='text' size='40' value={authorReviewCountState} placeholder='authorReviewCount' onChange={(e) => setAuthorReviewCountState(e.target.value)}/> </div> <div style={center}> <input id='authorImageURL' type='text' size='40' value={authorImageURLState} placeholder='authorImageURL' onChange={(e) => setAuthorImageURLState(e.target.value)}/> </div> <div style={center}> <input id='authorRelatedAuthors' type='text' size='40' value={authorRelatedAuthorsState} placeholder='authorRelatedAuthors' onChange={(e) => setAuthorRelatedAuthorsState(e.target.value)}/> </div> <div style={center}> <input id='authorBooks' type='text' size='40' value={authorAuthorBooksState} placeholder='authorBooks' onChange={(e) => setAuthorAuthorBooksState(e.target.value)}/> </div> </form> } {formState !== 'hide' && <button style={{marginLeft:600, width:60}} onClick={hideForm}> back </button> } <div style={{marginTop:20, display: 'flex', justifyContent: 'center', alignItems: 'center'}}> {/* Fout buttons for GET PUT POST and DELETE */} <FourButtons backColor='blue' borderColor='RoyalBlue' leftMargin={0} text='GET' func={get} /> <FourButtons backColor='black' borderColor='gray' leftMargin={20} text='PUT' func={put} /> <FourButtons backColor='green' borderColor='seagreen' leftMargin={20} text='POST' func={post} /> <FourButtons backColor='red' borderColor='indianred' leftMargin={20} text='DELETE' func={delete_data} /> </div> {renderState === true && <div> {/* Data Table used to render response json data */} <ElementDisplay data={dataState}/> </div>} </div> ); } export default App;