This commit is contained in:
Kenneth Jannette
2023-04-23 03:30:48 -05:00
parent 304cb3457d
commit c728db6923
5 changed files with 9773 additions and 121 deletions

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
node_modules node_modules
yarn.lock yarn.lock
.DS_Store .DS_Store
secrets.js
build/

9733
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,91 +1,89 @@
import React from 'react' import React from "react";
import { Router } from 'react-router-dom' import { Router } from "react-router-dom";
import { Link, Route } from 'react-router-dom' import { Link, Route } from "react-router-dom";
import Bookshelf from './Bookshelf' import Bookshelf from "./Bookshelf";
import createHistory from 'history/createBrowserHistory' import createHistory from "history/createBrowserHistory";
import { get, getAll, update } from './BooksAPI' import { get, getAll, update } from "./BooksAPI";
import SearchPage from './SearchPage' import SearchPage from "./SearchPage";
import './App.css' import "./App.css";
export const history = createHistory(); export const history = createHistory();
class BooksApp extends React.Component { class BooksApp extends React.Component {
constructor() { constructor() {
super(); super();
this.state = { this.state = {
books: [], books: [],
}
}; };
}
componentDidMount() { componentDidMount() {
getAll().then((books) => { getAll().then((books) => {
this.setState({ books }) this.setState({ books });
}) });
}; }
onResultSelect = (e) => { onResultSelect = (e) => {
const id = e.target.name;
const id = e.target.name const newShelf = e.target.value;
const newShelf = e.target.value let newBook;
let newBook
get(id).then((result) => { get(id).then((result) => {
newBook = result newBook = result;
newBook.shelf = newShelf newBook.shelf = newShelf;
this.setState({ this.setState({
books: [...this.state.books, newBook] books: [...this.state.books, newBook],
}); });
const newBooks = this.state.books const newBooks = this.state.books;
newBooks.forEach((book) => { newBooks.forEach((book) => {
update(book, book.shelf) update(book, book.shelf);
})
}); });
history.push('/'); });
history.push("/");
}; };
onSelectChange = (e) => { onSelectChange = (e) => {
const id = e.target.name const id = e.target.name;
const newShelf = e.target.value const newShelf = e.target.value;
const books = this.state.books const books = this.state.books;
books.forEach((book) => { books.forEach((book) => {
if (book.id === id) { if (book.id === id) {
book.shelf = newShelf; book.shelf = newShelf;
update(book, newShelf) update(book, newShelf);
} }
}); });
this.setState({ books }); this.setState({ books });
} };
render() { render() {
return ( return (
<Router history={history}> <Router history={history}>
<div className="app"> <div className="app">
<Route
<Route exact path='/' render={() => ( exact
path="/"
render={() => (
<Bookshelf <Bookshelf
books={this.state.books} books={this.state.books}
onSelect={this.onSelectChange} onSelect={this.onSelectChange}
/> />
)}/> )}
/>
<Route path='/search' render={() => ( <Route
path="/search"
render={() => (
<SearchPage <SearchPage
books={this.state.books} books={this.state.books}
onSelect={this.onResultSelect} onSelect={this.onResultSelect}
/> />
)}/> )}
/>
<div className="open-search"> <div className="open-search">
<Link to="/search">Search for Books</Link> <Link to="/search">Search for Books</Link>
</div> </div>
</div> </div>
</Router> </Router>
) );
}
} }
};
export default BooksApp export default BooksApp;

View File

@@ -1,16 +1,8 @@
import React from 'react' import React from "react";
import ReactDOM from 'react-dom' import ReactDOM from "react-dom";
import App from './App' import App from "./App";
/**
This course is not designed to teach Test Driven Development.
Feel free to use this file to test your application, but it
is not required.
**/
it('renders without crashing', () => {
const div = document.createElement('div')
ReactDOM.render(<App />, div)
})
it("renders as expected", () => {
const div = document.createElement("div");
ReactDOM.render(<App />, div);
});

View File

@@ -1,44 +1,43 @@
import SEARCH_API from "../secrets";
const api = "https://reactnd-books-api.udacity.com" const api = SEARCH_API;
// Generate a unique token // Generate a unique token
let token = localStorage.token let token = localStorage.token;
if (!token) if (!token) token = localStorage.token = Math.random().toString(36).substr(-8);
token = localStorage.token = Math.random().toString(36).substr(-8)
const headers = { const headers = {
'Accept': 'application/json', Accept: "application/json",
'Authorization': token Authorization: token,
} };
export const get = (bookId) => export const get = (bookId) =>
fetch(`${api}/books/${bookId}`, { headers }) fetch(`${api}/books/${bookId}`, { headers })
.then(res => res.json()) .then((res) => res.json())
.then(data => data.book) .then((data) => data.book);
export const getAll = () => export const getAll = () =>
fetch(`${api}/books`, { headers }) fetch(`${api}/books`, { headers })
.then(res => res.json()) .then((res) => res.json())
.then(data => data.books) .then((data) => data.books);
export const update = (book, shelf) => export const update = (book, shelf) =>
fetch(`${api}/books/${book.id}`, { fetch(`${api}/books/${book.id}`, {
method: 'PUT', method: "PUT",
headers: { headers: {
...headers, ...headers,
'Content-Type': 'application/json' "Content-Type": "application/json",
}, },
body: JSON.stringify({ shelf }) body: JSON.stringify({ shelf }),
}).then(res => res.json()) }).then((res) => res.json());
export const search = (query) => export const search = (query) =>
fetch(`${api}/search`, { fetch(`${api}/search`, {
method: 'POST', method: "POST",
headers: { headers: {
...headers, ...headers,
'Content-Type': 'application/json' "Content-Type": "application/json",
}, },
body: JSON.stringify({ query }) body: JSON.stringify({ query }),
}).then(res => res.json()) })
.then(data => data.books) .then((res) => res.json())
.then((data) => data.books);