diff --git a/src/App.js b/src/App.js index f54312b..b88928a 100644 --- a/src/App.js +++ b/src/App.js @@ -1,63 +1,124 @@ -import React, {Component} from 'react'; +import React, { Component } from 'react'; import './App.css'; -import {connect} from 'react-redux'; -import {addProduct} from './actions/index'; +import { connect } from 'react-redux'; +import { addProduct, deleteProduct, updateSearchString } from './actions/index'; import Chance from 'chance'; export const chance = Chance(); -const Product = (props) =>
{props.name}
; - -const DaBest = ({name}) =>

The Best: {name}

; +const Product = ({ product }) => ( +
+

Name: {product.name}

+

Department: {product.department}

+

Price: {product.price}

+

Stock: {product.stock}

+
+); + +const DaBest = ({ name }) =>

The Best: {name}

; + +const DeleteButton = ({ deleteProduct, id }) => ( + +); + +const Form = ({ handleSubmit }) => { + return ( +
+ + + + + + + + + +
+ ); +}; -const AdderButton = ({add}) => +const SearchInput = ({ handleOnChange }) => ( + +); class App extends Component { - - - constructor(props) { - super(props); - } - - componentDidMount() { - this.props.add({ + handleSubmit = event => { + event.preventDefault(); + let product = { id: chance.guid(), - name: 'Table', - department: 'Furniture', - price: '300.00', - stock: 5, - }); - } + name: event.target[0].value, + department: event.target[1].value, + price: event.target[2].value, + stock: event.target[3].value + }; + this.props.add(product); + event.target[0].value = ''; + event.target[1].value = ''; + event.target[2].value = ''; + event.target[3].value = ''; + }; + + handleOnChange = event => { + this.props.updateSearchString(event.target.value); + }; render() { - const {productList, add, whoIsTheBest} = this.props; - debugger; + const { searchString, productList, whoIsTheBest } = this.props; return (
- - {productList.map(product => )} - - + + + {productList + .filter(product => { + let name = product.name.toLowerCase(); + return name.includes(searchString.toLowerCase()); + }) + .map(product => ( +
+ + +
+ ))} +
); } } - // React x REDUX STUFF const mapStateToProps = state => { return { productList: state.products.productList, whoIsTheBest: 'Della', - + searchString: state.products.searchString, // an example of how to derive state in the mapStateToProps function - this is a specific 'subset' of the full list - lowStockProducts: state.products.productList.filter(prod => prod.stock && prod.stock < 4), - } + lowStockProducts: state.products.productList.filter( + prod => prod.stock && prod.stock < 4 + ) + }; }; const mapDispatchToProps = { add: addProduct, + deleteProduct: deleteProduct, + updateSearchString: updateSearchString }; export default connect(mapStateToProps, mapDispatchToProps)(App); diff --git a/src/actions/index.js b/src/actions/index.js index 79e204e..bf3c0f7 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -1,5 +1,7 @@ export const ACTION_TYPES = { addProduct: 'ADD_PRODUCTS', + deleteProduct: 'DELETE_PRODUCTS', + updateSearchString: 'UPDATE_SEARCH_STRING' }; export function addProduct(product) { @@ -7,7 +9,25 @@ export function addProduct(product) { return { type: ACTION_TYPES.addProduct, payload: { - product, + product } - } + }; +} + +export function deleteProduct(id) { + return { + type: ACTION_TYPES.deleteProduct, + payload: { + id + } + }; +} + +export function updateSearchString(searchInput) { + return { + type: ACTION_TYPES.updateSearchString, + payload: { + searchInput + } + }; } diff --git a/src/index.js b/src/index.js index dfc54fd..ae6190d 100644 --- a/src/index.js +++ b/src/index.js @@ -6,14 +6,17 @@ import { Provider } from 'react-redux'; import App from '../src/App'; import '../src/index.css'; import reducer from './reducers'; -import registerServiceWorker from "../src/registerServiceWorker"; +import registerServiceWorker from '../src/registerServiceWorker'; -const store = createStore(reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()); +const store = createStore( + reducer, + window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() +); ReactDOM.render( - - - , - document.getElementById('root') + + + , + document.getElementById('root') ); registerServiceWorker(); diff --git a/src/reducers/index.js b/src/reducers/index.js index 5cb12f1..3b1945a 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,27 +1,41 @@ -import {combineReducers} from 'redux'; - -import {generateProducts} from '../utils/data'; -import {ACTION_TYPES} from '../actions'; +import { combineReducers } from 'redux'; +import { generateProducts } from '../utils/data'; +import { ACTION_TYPES } from '../actions'; // you'll notice I set my initial state below on line 13 to equal this object! This is a common pattern const INITIAL_STATE = { - productList: generateProducts(10), - searchString: '' // hint for optional homework + productList: generateProducts(10), + searchString: '' // hint for optional homework }; -export const products = (state = INITIAL_STATE, {type, payload}) => { - switch (type) { - case ACTION_TYPES.addProduct: - // using object spread, I am saying - I want to return the old state, except change the productList property - return {...state, productList: state.productList.concat(payload.product)}; - } - return state; +export const products = (state = INITIAL_STATE, { type, payload }) => { + switch (type) { + case ACTION_TYPES.addProduct: + // using object spread, I am saying - I want to return the old state, except change the productList property + return { + ...state, + productList: [...state.productList, payload.product] + }; + case ACTION_TYPES.deleteProduct: + return { + ...state, + productList: state.productList.filter( + product => product.id !== payload.id + ) + }; + case ACTION_TYPES.updateSearchString: + return { + ...state, + searchString: payload.searchInput + }; + default: + return state; + } }; - // This is how you can combine many reducers into one large reducer: // https://redux.js.org/api-reference/combinereducers export default combineReducers({ - products, + products });