Skip to content

Commit

Permalink
Auto format
Browse files Browse the repository at this point in the history
  • Loading branch information
tobias-dev committed Apr 23, 2020
1 parent 280684e commit 34e4457
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 128 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"react": "^16.6.3",
"react-debounce-input": "^3.2.2",
"react-dom": "^16.6.3",
"react-router-dom": "^5.1.2",
"react-scripts": "2.1.1"
},
"scripts": {
Expand Down
118 changes: 61 additions & 57 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react'
import { Route, Link } from 'react-router-dom'
import * as BooksAPI from './BooksAPI'
import Shelf from './Shelf'
import Search from './Search'
import './App.css'
import React from 'react';
import { Route, Link } from 'react-router-dom';
import * as BooksAPI from './BooksAPI';
import Shelf from './Shelf';
import Search from './Search';
import './App.css';

const shelfList = [
{
Expand All @@ -23,60 +23,61 @@ const shelfList = [
class BooksApp extends React.Component {
state = {
booksInShelf: {}, // Contains books that are assigned to any shelf
}
};

componentDidMount() {
BooksAPI.getAll()
.then((books) => {
// Store books with IDs as keys, so that they can be easily accessed by ID
const booksWithId = {};
books.forEach((book) => {
booksWithId[book.id] = book;
})
this.setState(() => ({
booksInShelf: booksWithId
}))
})
BooksAPI.getAll().then((books) => {
// Store books with IDs as keys, so that they can be easily accessed by ID
const booksWithId = {};
books.forEach((book) => {
booksWithId[book.id] = book;
});
this.setState(() => ({
booksInShelf: booksWithId,
}));
});
}

moveBook = (book, newShelfId) => {
BooksAPI.update(book, newShelfId)
.then(() => {
this.setState((prevState) => {
const bookId = book.id;
book.shelf = newShelfId; // Update shelf
this.isShelf(newShelfId) ?
prevState.booksInShelf[bookId] = book : // Updated or new book
delete prevState.booksInShelf.bookId; // Delete book if not in shelf anymore
return prevState;
});
})
}
BooksAPI.update(book, newShelfId).then(() => {
this.setState((prevState) => {
const bookId = book.id;
book.shelf = newShelfId; // Update shelf
this.isShelf(newShelfId)
? (prevState.booksInShelf[bookId] = book) // Updated or new book
: delete prevState.booksInShelf.bookId; // Delete book if not in shelf anymore
return prevState;
});
});
};

getBooksByShelf = (shelfId) => {
const { booksInShelf } = this.state;
return Object.keys(booksInShelf)
.map((bookId) => booksInShelf[bookId])
.filter((book) => book.shelf === shelfId);
}
};

isShelf = (shelfId) => {
return shelfList.map((shelf) => shelf.id).includes(shelfId);
}
};

render() {
const { booksInShelf } = this.state;

return (
<div className="app">
<Route exact path='/' render={() => (
<div className="list-books">
<div className="list-books-title">
<h1>MyReads</h1>
</div>
<div className="list-books-content">
<div>
{shelfList.map((shelf) => (
<div className='app'>
<Route
exact
path='/'
render={() => (
<div className='list-books'>
<div className='list-books-title'>
<h1>MyReads</h1>
</div>
<div className='list-books-content'>
<div>
{shelfList.map((shelf) => (
<Shelf
key={shelf.id}
shelf={shelf}
Expand All @@ -85,27 +86,30 @@ class BooksApp extends React.Component {
booksAnyShelf={booksInShelf}
onBookMove={this.moveBook}
/>
)
)}
))}
</div>
</div>
<div className='open-search'>
<Link to='/search'>
<button>Add a book</button>
</Link>
</div>
</div>
<div className="open-search">
<Link to='/search'>
<button>Add a book</button>
</Link>
</div>
</div>)}
)}
/>
<Route path='/search' render={() => (
<Search
shelfList={shelfList}
booksAnyShelf={booksInShelf}
onBookMove={this.moveBook}
/>)}
<Route
path='/search'
render={() => (
<Search
shelfList={shelfList}
booksAnyShelf={booksInShelf}
onBookMove={this.moveBook}
/>
)}
/>
</div>
)
);
}
}

export default BooksApp
export default BooksApp;
19 changes: 10 additions & 9 deletions src/Book.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ const Book = (props) => {
const { title, authors, imageLinks } = book;

return (
<div className="book">
<div className="book-top">
<div className="book-cover"
<div className='book'>
<div className='book-top'>
<div
className='book-cover'
style={{
width: 128,
height: 188,
backgroundImage: imageLinks ? `url("${imageLinks.thumbnail}")` : ''
backgroundImage: imageLinks ? `url("${imageLinks.thumbnail}")` : '',
}}
/>
<ShelfChanger
Expand All @@ -23,11 +24,11 @@ const Book = (props) => {
onBookMove={onBookMove}
/>
</div>
<div className="book-title">{title}</div>
<div className="book-authors">{(authors || []).join(', ')}</div>
<div className='book-title'>{title}</div>
<div className='book-authors'>{(authors || []).join(', ')}</div>
</div>
)
}
);
};

Book.propTypes = {
book: PropTypes.object.isRequired,
Expand All @@ -36,4 +37,4 @@ Book.propTypes = {
onBookMove: PropTypes.func.isRequired,
};

export default Book
export default Book;
12 changes: 6 additions & 6 deletions src/ListBooks.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react';
import Book from './Book'
import Book from './Book';
import PropTypes from 'prop-types';

const ListBooks = (props) => {
const { booksThisList, shelfList, booksAnyShelf, onBookMove } = props;

return (
<ol className="books-grid">
<ol className='books-grid'>
{booksThisList.map((book) => (
<li key={book.id}>
<Book
Expand All @@ -18,8 +18,8 @@ const ListBooks = (props) => {
</li>
))}
</ol>
)
}
);
};

ListBooks.propTypes = {
booksThisList: PropTypes.array.isRequired,
Expand All @@ -28,4 +28,4 @@ ListBooks.propTypes = {
onBookMove: PropTypes.func.isRequired,
};

export default ListBooks
export default ListBooks;
58 changes: 30 additions & 28 deletions src/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,61 +10,63 @@ class Search extends Component {
query: '',
books: [],
hasSearchError: false,
}
};

handleSearch = (e) => {
const query = e.target.value;
this.setState(() => ({
query
}), () => {
BooksAPI.search(query)
.then((books) => {
typeof books === 'undefined' || books.hasOwnProperty('error') ?
this.setState(() => ({
books: [],
hasSearchError: true,
})) :
this.setState(() => ({
books: books || [],
hasSearchError: false,
}))
this.setState(
() => ({
query,
}),
() => {
BooksAPI.search(query).then((books) => {
typeof books === 'undefined' || books.hasOwnProperty('error')
? this.setState(() => ({
books: [],
hasSearchError: true,
}))
: this.setState(() => ({
books: books || [],
hasSearchError: false,
}));
});
})
}
}
);
};

render() {
const { query, books, hasSearchError } = this.state;
const { shelfList, booksAnyShelf, onBookMove } = this.props;

return (
<div className="search-books">
<div className="search-books-bar">
<div className='search-books'>
<div className='search-books-bar'>
<Link to='/'>
<button className="close-search">Close</button>
<button className='close-search'>Close</button>
</Link>
<div className="search-books-input-wrapper">
<div className='search-books-input-wrapper'>
<DebounceInput
type="text"
placeholder="Search by title or author"
type='text'
placeholder='Search by title or author'
value={query}
debounceTimeout={150}
className={hasSearchError ? 'error' : ''}
onChange={this.handleSearch}
/>
</div>
</div>
<div className="search-books-results">
{!hasSearchError &&
<div className='search-books-results'>
{!hasSearchError && (
<ListBooks
booksThisList={books}
shelfList={shelfList}
booksAnyShelf={booksAnyShelf}
onBookMove={onBookMove}
/>
}
)}
</div>
</div>
)
);
}
}

Expand All @@ -74,4 +76,4 @@ Search.propTypes = {
onBookMove: PropTypes.func.isRequired,
};

export default Search
export default Search;
19 changes: 12 additions & 7 deletions src/Shelf.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@ import ListBooks from './ListBooks';
import PropTypes from 'prop-types';

class Shelf extends Component {

shouldComponentUpdate(nextProps) {
// Only update if a book is added or removed
return this.props.booksThisShelf.length !== nextProps.booksThisShelf.length;
}

render() {
const { shelf, shelfList, booksThisShelf, booksAnyShelf, onBookMove } = this.props;
const {
shelf,
shelfList,
booksThisShelf,
booksAnyShelf,
onBookMove,
} = this.props;

return (
<div className="bookshelf">
<h2 className="bookshelf-title">{shelf.label}</h2>
<div className="bookshelf-books">
<div className='bookshelf'>
<h2 className='bookshelf-title'>{shelf.label}</h2>
<div className='bookshelf-books'>
<ListBooks
booksThisList={booksThisShelf}
shelfList={shelfList}
Expand All @@ -24,7 +29,7 @@ class Shelf extends Component {
/>
</div>
</div>
)
);
}
}

Expand All @@ -36,4 +41,4 @@ Shelf.propTypes = {
onBookMove: PropTypes.func.isRequired,
};

export default Shelf
export default Shelf;
Loading

0 comments on commit 34e4457

Please sign in to comment.