diff --git a/.eslintrc.js b/.eslintrc.js index 17514e7..0fd9d6e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,4 +1,4 @@ -module.exports = { +/* module.exports = { env: { browser: true, es2021: true, @@ -61,3 +61,4 @@ module.exports = { "react/prop-types": "off", }, }; + */ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9e370aa --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,25 @@ +{ + "workbench.colorCustomizations": { + "activityBar.activeBackground": "#fa1b49", + "activityBar.activeBorder": "#155e02", + "activityBar.background": "#fa1b49", + "activityBar.foreground": "#e7e7e7", + "activityBar.inactiveForeground": "#e7e7e799", + "activityBarBadge.background": "#155e02", + "activityBarBadge.foreground": "#e7e7e7", + "editorGroup.border": "#fa1b49", + "panel.border": "#fa1b49", + "sash.hoverBorder": "#fa1b49", + "sideBar.border": "#fa1b49", + "statusBar.background": "#dd0531", + "statusBar.foreground": "#e7e7e7", + "statusBarItem.hoverBackground": "#fa1b49", + "statusBarItem.remoteBackground": "#dd0531", + "statusBarItem.remoteForeground": "#e7e7e7", + "titleBar.activeBackground": "#dd0531", + "titleBar.activeForeground": "#e7e7e7", + "titleBar.inactiveBackground": "#dd053199", + "titleBar.inactiveForeground": "#e7e7e799" + }, + "peacock.color": "#dd0531" +} \ No newline at end of file diff --git a/src/App.js b/src/App.js index bdd3b32..46ac474 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,4 @@ -import React, { Component } from "react"; +import React from "react"; import { BrowserRouter, Route } from "react-router-dom"; import Home from "./pages/Home"; @@ -6,8 +6,9 @@ import NewProduct from "./pages/NewProduct"; import * as api from "./api"; -const LOCAL_STORAGE_KEY = "react-sc-state"; +import useApp from "./components/Hooks/useApp"; +const LOCAL_STORAGE_KEY = "react-sc-state"; function loadLocalStorageData() { const prevItems = localStorage.getItem(LOCAL_STORAGE_KEY); @@ -39,62 +40,18 @@ function buildNewCartItem(cartItem) { }; } -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() { - const prevItems = loadLocalStorageData(); - - if (!prevItems) { - this.setState({ - isLoading: true, - }); - - api.getProducts().then((data) => { - this.setState({ - products: data, - isLoading: false, - }); - }); - return; - } - - this.setState({ - cartItems: prevItems.cartItems, - products: prevItems.products, - }); - } - - componentDidUpdate() { - const { cartItems, products } = this.state; - - localStorage.setItem( - LOCAL_STORAGE_KEY, - JSON.stringify({ cartItems, products }), - ); - } - - handleAddToCart(productId) { - const { cartItems, products } = this.state; - +function App() { + const { + products, + cartItems, + isLoading, + hasError, + loadingError, + setCartItems, + setProducts, + } = useApp(loadLocalStorageData, LOCAL_STORAGE_KEY); + + const handleAddToCart = (productId) => { const prevCartItem = cartItems.find((item) => item.id === productId); const foundProduct = products.find((product) => product.id === productId); @@ -114,19 +71,17 @@ class App extends Component { }; }); - this.setState({ cartItems: updatedCartItems }); + setCartItems(updatedCartItems); return; } const updatedProduct = buildNewCartItem(foundProduct); - this.setState((prevState) => ({ - cartItems: [...prevState.cartItems, updatedProduct], - })); - } - - handleChange(event, productId) { - const { cartItems } = this.state; + setCartItems((prevState) => { + return [...prevState, updatedProduct]; + }); + }; + const handleChange = (event, productId) => { const updatedCartItems = cartItems.map((item) => { if (item.id === productId && item.quantity <= item.unitsInStock) { return { @@ -137,22 +92,15 @@ class App extends Component { return item; }); + setCartItems(updatedCartItems); + }; - this.setState({ cartItems: updatedCartItems }); - } - - handleRemove(productId) { - const { cartItems } = this.state; + const handleRemove = (productId) => { const updatedCartItems = cartItems.filter((item) => item.id !== productId); + setCartItems(updatedCartItems); + }; - this.setState({ - cartItems: updatedCartItems, - }); - } - - handleDownVote(productId) { - const { products } = this.state; - + const handleDownVote = (productId) => { const updatedProducts = products.map((product) => { if ( product.id === productId && @@ -173,13 +121,10 @@ class App extends Component { return product; }); + setProducts(updatedProducts); + }; - this.setState({ products: updatedProducts }); - } - - handleUpVote(productId) { - const { products } = this.state; - + const handleUpVote = (productId) => { const updatedProducts = products.map((product) => { if ( product.id === productId && @@ -200,12 +145,10 @@ class App extends Component { return product; }); - this.setState({ products: updatedProducts }); - } - - handleSetFavorite(productId) { - const { products } = this.state; + setProducts(updatedProducts); + }; + const handleSetFavorite = (productId) => { const updatedProducts = products.map((product) => { if (product.id === productId) { return { @@ -217,58 +160,45 @@ class App extends Component { return product; }); - this.setState({ products: updatedProducts }); - } - - saveNewProduct(newProduct) { - this.setState((prevState) => ({ - products: [newProduct, ...prevState.products], - newProductFormOpen: !prevState.newProductFormOpen, - })); - } + setProducts(updatedProducts); + }; - render() { - const { - cartItems, - products, - isLoading, - hasError, - loadingError, - } = this.state; + const saveNewProduct = (newProduct) => { + setProducts((prevState) => [newProduct, ...prevState]); + }; - return ( - - ( - - )} - /> - ( - - )} - /> - - ); - } + return ( + + ( + + )} + /> + ( + + )} + /> + + ); } export default App; diff --git a/src/components/Hooks/useApp.js b/src/components/Hooks/useApp.js new file mode 100644 index 0000000..3da2fe4 --- /dev/null +++ b/src/components/Hooks/useApp.js @@ -0,0 +1,47 @@ +import { useEffect, useState } from "react"; +import * as api from "../../api/getProducts"; + +function useApp(loadLocalStorageData, LOCAL_STORAGE_KEY) { + const [products, setProducts] = useState([]); + + const [cartItems, setCartItems] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [hasError, setHasError] = useState(false); + const [loadingError, setLoadingError] = useState(null); + + useEffect(() => { + const prevItems = loadLocalStorageData(); + + if (!prevItems) { + setIsLoading(true); + + api.getProducts().then((data) => { + setProducts(data); + setIsLoading(false); + }); + return; + } + + setProducts(prevItems.products); + setCartItems(prevItems.cartItems); + }, []); + + useEffect(() => { + localStorage.setItem( + LOCAL_STORAGE_KEY, + JSON.stringify({ cartItems, products }), + ); + }, [products, cartItems]); + + return { + products: products, + cartItems: cartItems, + isLoading: isLoading, + hasError: hasError, + loadingError: loadingError, + setCartItems: setCartItems, + setProducts: setProducts, + }; +} + +export default useApp; diff --git a/src/components/NewProductForm/NewProductForm.js b/src/components/NewProductForm/NewProductForm.js index 3bb3ea1..2a813af 100644 --- a/src/components/NewProductForm/NewProductForm.js +++ b/src/components/NewProductForm/NewProductForm.js @@ -1,4 +1,4 @@ -import React, { Component } from "react"; +import React, { useState } from "react"; import { Redirect } from "react-router-dom"; import { v4 as uuid } from "uuid"; import { Formik } from "formik"; @@ -33,171 +33,161 @@ function addProductDetails(product) { }; } -class NewProductForm extends Component { - constructor(props) { - super(props); - this.state = { - submitted: false, - }; +const NewProductForm = (props) => { + const [submitted, setSubmitted] = useState(false); + const { saveNewProduct } = props; - this.setSubmitted = this.setSubmitted.bind(this); - } - - setSubmitted() { + const setSubmittedState = () => { setTimeout(() => { - this.setState({ - submitted: true, - }); + console.log("handleSubmit Works"); + setSubmitted(true); }, 500); - } + }; - render() { - const { submitted } = this.state; - const { saveNewProduct } = this.props; + return ( + <> + { + const newProduct = addProductDetails(values); + saveNewProduct(newProduct); + setSubmitting(true); + setSubmittedState(); - return ( - <> - { - const newProduct = addProductDetails(values); - saveNewProduct(newProduct); - setSubmitting(true); - this.setSubmitted(); - }} - > - {({ - handleChange, - handleBlur, - handleSubmit, - errors, - values, - touched, - isValidating, - isValid, - isSubmitting, - }) => ( -
- - - - - - - - - - -
- )} -
- {submitted && } - - ); - } -} + console.log("Form Submitted"); + }} + > + {({ + handleChange, + handleBlur, + handleSubmit, + errors, + values, + touched, + isValidating, + isValid, + isSubmitting, + }) => ( +
+ + + + + + + + + + +
+ )} +
+ {submitted && } + + ); +}; export default NewProductForm;