Skip to content
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
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
package-lock.json
src
40,790 changes: 40,144 additions & 646 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.3.5",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-markdown": "^2.0.1",
"eslint-plugin-markdown": "^2.2.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-react": "^7.23.2",
Expand Down
259 changes: 126 additions & 133 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Component } from "react";
import React, { useState, useEffect } from "react";
import { BrowserRouter, Route } from "react-router-dom";

import Home from "./pages/Home";
Expand All @@ -22,7 +22,7 @@ function loadLocalStorageData() {
}
}

function buildNewCartItem(cartItem) {
const buildNewCartItem = (cartItem) => {
if (cartItem.quantity >= cartItem.unitsInStock) {
return cartItem;
}
Expand All @@ -37,69 +37,62 @@ function buildNewCartItem(cartItem) {
updatedAt: cartItem.updatedAt,
quantity: cartItem.quantity + 1,
};
}

class App extends Component {
constructor(props) {
super(props);

this.state = {
products: [],
cartItems: [],
isLoading: false,
hasError: false,
loadingError: null,
};

this.handleAddToCart = this.handleAddToCart.bind(this);
this.handleRemove = this.handleRemove.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleDownVote = this.handleDownVote.bind(this);
this.handleUpVote = this.handleUpVote.bind(this);
this.handleSetFavorite = this.handleSetFavorite.bind(this);
this.saveNewProduct = this.saveNewProduct.bind(this);
}

componentDidMount() {
};

function App() {
const [allStates, setAllStates] = useState({
products: [],
cartItems: [],
isLoading: false,
hasError: false,
loadingError: null,
newProductFormOpen: null,
});

useEffect(() => {
const prevItems = loadLocalStorageData();

if (!prevItems) {
this.setState({
isLoading: true,
});
setAllStates((prevState) => ({ ...prevState, isLoading: true }));

api.getProducts().then((data) => {
this.setState({
setAllStates((prevState) => ({
...prevState,
products: data,
isLoading: false,
});
}));
});
return;
}

this.setState({
setAllStates((prevState) => ({
...prevState,
cartItems: prevItems.cartItems,
products: prevItems.products,
});
}

componentDidUpdate() {
const { cartItems, products } = this.state;
}));
}, []);

useEffect(() => {
const { cartItems, products } = allStates;
if (products.length > 0) {
localStorage.setItem(
LOCAL_STORAGE_KEY,
JSON.stringify({
cartItems,
products,
}),
);
}
}, [allStates.cartItems, allStates.products]);

localStorage.setItem(
LOCAL_STORAGE_KEY,
JSON.stringify({ cartItems, products }),
const handleAddToCart = (productId) => {
const prevCartItem = allStates.cartItems.find(
(item) => item.id === productId,
);
const foundProduct = allStates.products.find(
(product) => product.id === productId,
);
}

handleAddToCart(productId) {
const { cartItems, products } = this.state;

const prevCartItem = cartItems.find((item) => item.id === productId);
const foundProduct = products.find((product) => product.id === productId);

if (prevCartItem) {
const updatedCartItems = cartItems.map((item) => {
const updatedCartItems = allStates.cartItems.map((item) => {
if (item.id !== productId) {
return item;
}
Expand All @@ -113,21 +106,24 @@ class App extends Component {
quantity: item.quantity + 1,
};
});
setAllStates((prevState) => ({
...prevState,
cartItems: updatedCartItems,
}));

this.setState({ cartItems: updatedCartItems });
return;
}

const updatedProduct = buildNewCartItem(foundProduct);
this.setState((prevState) => ({

setAllStates((prevState) => ({
...prevState,
cartItems: [...prevState.cartItems, updatedProduct],
}));
}

handleChange(event, productId) {
const { cartItems } = this.state;
};

const updatedCartItems = cartItems.map((item) => {
const handleChange = (event, productId) => {
const updatedCartItems = allStates.cartItems.map((item) => {
if (item.id === productId && item.quantity <= item.unitsInStock) {
return {
...item,
Expand All @@ -137,23 +133,24 @@ class App extends Component {

return item;
});

this.setState({ cartItems: updatedCartItems });
}

handleRemove(productId) {
const { cartItems } = this.state;
const updatedCartItems = cartItems.filter((item) => item.id !== productId);

this.setState({
setAllStates((prevState) => ({
...prevState,
cartItems: updatedCartItems,
});
}
}));
};

handleDownVote(productId) {
const { products } = this.state;
const handleRemove = (productId) => {
const updatedCartItems = allStates.cartItems.filter(
(item) => item.id !== productId,
);
setAllStates((prevState) => ({
...prevState,
cartItems: updatedCartItems,
}));
};

const updatedProducts = products.map((product) => {
const handleDownVote = (productId) => {
const updatedProducts = allStates.products.map((product) => {
if (
product.id === productId &&
product.votes.downVotes.currentValue <
Expand All @@ -173,14 +170,14 @@ class App extends Component {

return product;
});
setAllStates((prevState) => ({
...prevState,
products: updatedProducts,
}));
};

this.setState({ products: updatedProducts });
}

handleUpVote(productId) {
const { products } = this.state;

const updatedProducts = products.map((product) => {
const handleUpVote = (productId) => {
const updatedProducts = allStates.products.map((product) => {
if (
product.id === productId &&
product.votes.upVotes.currentValue < product.votes.upVotes.upperLimit
Expand All @@ -199,14 +196,14 @@ class App extends Component {

return product;
});
setAllStates((prevState) => ({
...prevState,
products: updatedProducts,
}));
};

this.setState({ products: updatedProducts });
}

handleSetFavorite(productId) {
const { products } = this.state;

const updatedProducts = products.map((product) => {
const handleSetFavorite = (productId) => {
const updatedProducts = allStates.products.map((product) => {
if (product.id === productId) {
return {
...product,
Expand All @@ -217,58 +214,54 @@ class App extends Component {
return product;
});

this.setState({ products: updatedProducts });
}
setAllStates((prevState) => ({
...prevState,
products: updatedProducts,
}));
};

saveNewProduct(newProduct) {
this.setState((prevState) => ({
products: [newProduct, ...prevState.products],
const saveNewProduct = (newProduct) => {
setAllStates((prevState) => {
return { ...prevState, products: [...prevState.products, newProduct] };
});
setAllStates((prevState) => ({
...prevState,
newProductFormOpen: !prevState.newProductFormOpen,
}));
}
};

render() {
const {
cartItems,
products,
isLoading,
hasError,
loadingError,
} = this.state;

return (
<BrowserRouter>
<Route
path="/"
exact
render={(routeProps) => (
<Home
{...routeProps}
fullWidth
cartItems={cartItems}
products={products}
isLoading={isLoading}
hasError={hasError}
loadingError={loadingError}
handleDownVote={this.handleDownVote}
handleUpVote={this.handleUpVote}
handleSetFavorite={this.handleSetFavorite}
handleAddToCart={this.handleAddToCart}
handleRemove={this.handleRemove}
handleChange={this.handleChange}
/>
)}
/>
<Route
path="/new-product"
exact
render={(routeProps) => (
<NewProduct {...routeProps} saveNewProduct={this.saveNewProduct} />
)}
/>
</BrowserRouter>
);
}
return (
<BrowserRouter>
<Route
path="/"
exact
render={(routeProps) => (
<Home
{...routeProps}
fullWidth
cartItems={allStates.cartItems}
products={allStates.products}
isLoading={allStates.isLoading}
hasError={allStates.hasError}
loadingError={allStates.loadingError}
handleDownVote={handleDownVote}
handleUpVote={handleUpVote}
handleSetFavorite={handleSetFavorite}
handleAddToCart={handleAddToCart}
handleRemove={handleRemove}
handleChange={handleChange}
/>
)}
/>
<Route
path="/new-product"
exact
render={(routeProps) => (
<NewProduct {...routeProps} saveNewProduct={saveNewProduct} />
)}
/>
</BrowserRouter>
);
}

export default App;
Loading