Skip to content
This repository was archived by the owner on Nov 5, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/package-lock.json
/client/dist/bundle.js
/client/.DS_Store
/node_modules/
Archive.zip
.env
.DS_Store

# Elastic Beanstalk Files
.elasticbeanstalk/*
!.elasticbeanstalk/*.cfg.yml
!.elasticbeanstalk/*.global.yml
41 changes: 41 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SERVER

const express = require('express')
const parser = require('body-parser')
const axios = require('axios');
const app = express()

const db = require('./database/index.js')

if (process.env.NODE_ENV !== 'production') {
require('dotenv').config();
}

const port = process.env.PORT || 8000;
const apiKey = process.env.API_KEY

app.use(express.static(__dirname + '/client/dist'));
app.use(parser.json());

app.get('/books/top', (req, res) => {
let url = `https://api.nytimes.com/svc/books/v3/lists/current/hardcover-fiction.json?api-key=${apiKey}`
axios.get(url)
.then(response => res.end(JSON.stringify(response.data)))
.catch(err => res.end(err))
})

app.get('/books/wishlist', (req, res) => {
db.getWishlistBooks((err, response) => res.end(JSON.stringify(response)))
})

app.post('/books/wishlist', (req, res) => {
db.addToWishlist(req.body.currentBook, (err) => res.end(err))
})

app.delete('/books/wishlist', (req, res) => {
db.removeFromWishlist(req.body.currentBook, (err) => res.end(err))
})

app.listen(port, () => {
console.log(`listening on port ${port}`)
})
12 changes: 12 additions & 0 deletions client/dist/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>OkayReads</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div id="root"></div>
<div id="modal-root"></div>
<script type="text/javascript" src="bundle.js"></script>
</body>
</html>
173 changes: 173 additions & 0 deletions client/dist/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
html, body, #app {
margin: 0;
padding: 0;
font-family: "Roboto", sans-serif;
font-weight: 400;
height: 100%;
width: 100%;
}

#app {
height: 100%;
width: 100%;
background-color: rgba(231, 76, 60, 0.25);
display: flex;
flex-direction: column;
overflow: hidden;
}

.main {
flex-grow: 1;
display: flex;
}

.wishlist-empty{
color: white;
}

.books {
flex-basis:80%;
display: flex;
flex-wrap: wrap;
min-height: 20rem;
margin: 0;
padding: 20px;
overflow-y: scroll;
background-color: #2c3e50;
}

.book_item {
flex-basis: 22%;
box-sizing: border-box;
margin: 1.5%;
display: flex;
flex-direction: column;
list-style: none;
background-color: #fff;
border: 1px solid #eee;
box-shadow: 0 10px 28px -7px rgba(0,0,0,0.1);
cursor: pointer;
}

.book_item > div > img {
width: 100%;
}

.book_description {
display: flex;
flex-grow: 1;
flex-direction: column;
justify-content: space-between;
padding: 10px;
}

.book_description h2 {
color: #555;
font-weight: bold;
margin-bottom: 20px;
}

.book_details {
display: flex;
justify-content: space-between;
}

.book_details span {
color: #555;
font-size: 0.8rem;
font-weight: bold;
}

.book_year, .book_rating {
display: flex;
flex-direction: column;
}

.book_year, .book_rating{
color: #aaa;
margin-bottom: 5px;
font-size: 0.65rem;
font-weight: normal;
}

.book_rating {
align-items: flex-end;
}

.app {
height: 10em;
width: 10em;
background: lightblue;
overflow: hidden;
}

#modal-root {
position: relative;
z-index: 999;
}

.modal-right {
padding: 2rem;
}

.modal {
background-color: rgba(248, 247, 247, 0.8);
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
}

.modal-left{
padding-bottom: 1rem;
}

#modal-x{
float: right;
cursor: pointer;
}

.preview {
background-color: white;
padding: 10px;
max-width: 70%;
}

.right-align {
float: right;
padding: 5px;
}

.header {
padding: 10px;
}

button{
border: 0;
background: #21a8ca;
border-radius: 5px;
padding: 0.5rem 1rem;
font-size: 0.8rem;
line-height: 1;
color: white;
cursor: pointer;
}

.close-btn {
width: 100%;
border: 0;
background: #21a8ca;
border-radius: 5px;
padding: 0.5rem 1rem;
font-size: 0.8rem;
line-height: 1;
color: white;
}

#wishlist-notice{
visibility: hidden;
}
44 changes: 44 additions & 0 deletions client/src/components/books.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

import React, { Component } from 'react';

class Books extends Component {

render() {

if (!this.props.books) {
return (
<div className="books">
<span className="wishlist-empty">Oh no! You haven't added any books to your wishlist. Check out the NYT bestsellers and start adding now!</span>
</div>
)
}


return (
<ul className="books" >
{
this.props.books.map((book, idx) => {
return <li className="book_item" key={book.rank} data-rank={book.rank} onClick={this.props.handleBookClick}>
<div>
<img src={book.book_image} width="209" />
<div className="book_description">
<h2>{book.title}</h2>
<section className="book_details">
<div className="book_author">
<span className="title"></span>
<span>{book.author}</span>
</div>
<div className="book_rank">
<span className="title">Rank: </span>
<span>{book.rank}</span>
</div>
</section>
</div>
</div></li>
})
}
</ul>)
}
}

export default Books
31 changes: 31 additions & 0 deletions client/src/components/modal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

import React, { Component } from 'react';
import ReactDOM, { createPortal } from 'react-dom';

const modalRoot = document.getElementById('modal-root');

class Modal extends Component {

constructor(props) {
super(props)
this.el = document.createElement('div');
}

componentDidMount() {
modalRoot.appendChild(this.el);
}

componentWillUnmount() {
modalRoot.removeChild(this.el);
}

render() {
return createPortal(
this.props.children,
this.el,
);

}
}

export default Modal
46 changes: 46 additions & 0 deletions client/src/components/selectedBook.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, { Fragment } from 'react'

const SelectedBook = ({ currentBook, handleHideModal, showWishlist, showMsg, addToWishlist, deleteFromWishlist }) => (
<div className="modal">
<div className="preview">
<div className="book_description">
<h2>{currentBook.title} <span id="modal-x" onClick={handleHideModal}>X</span></h2>
<section className="book_details">
{/* div 1 */}
<div className="modal-left">
<img src={currentBook.book_image} width="209" />
</div>
{/* div 2 */}
<div className="modal-right">
<div>
<span>Author: {currentBook.author}</span>
</div>
<div>
<span>Rank: {currentBook.rank}</span>
</div><br />
<div>
<span>{currentBook.description}</span>
</div><br />
<div>
<button onClick={() => window.open(currentBook.amazon_product_url, "_blank")}>Get the book</button><br /><br />
{showWishlist ? <button onClick={() => handleOnClick(deleteFromWishlist)}>Remove from Wishlist</button>
: <button onClick={() => handleOnClick(addToWishlist)}>Add to Wishlist</button>
}<br /><br />
<div><span>{showMsg}</span></div>
</div>
</div>
</section>
<div>
<button className="close-btn" onClick={handleHideModal}>Return to books</button>
</div>
</div>
</div>
</div>
);

const handleOnClick = function (method) {
method()

}

export default SelectedBook
Loading