Skip to content
Snippets Groups Projects
App.js 18.41 KiB
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;