Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zoey's solution #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
123 changes: 92 additions & 31 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -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) => <div>{props.name}</div>;

const DaBest = ({name}) => <h1>The Best: {name}</h1>;
const Product = ({ product }) => (
<div>
<p>Name: {product.name}</p>
<p>Department: {product.department}</p>
<p>Price: {product.price}</p>
<p>Stock: {product.stock}</p>
</div>
);

const DaBest = ({ name }) => <h1>The Best: {name}</h1>;

const DeleteButton = ({ deleteProduct, id }) => (
<button onClick={() => deleteProduct(id)}>Delete</button>
);

const Form = ({ handleSubmit }) => {
return (
<form onSubmit={handleSubmit}>
<label>
Name:<input name="Name" type="text" autoFocus />
</label>

<label>
Department:<input name="Department" type="text" />
</label>

<label>
Price:<input name="Price" type="text" />
</label>

<label>
Stock:<input name="Stock" type="text" />
</label>

<button>Add Product</button>
</form>
);
};

const AdderButton = ({add}) => <button onClick={() => add({name: 'Sofa'})}>Add Sofa</button>
const SearchInput = ({ handleOnChange }) => (
<input
onChange={handleOnChange}
type="text"
autoFocus
placeholder="Search for a product"
/>
);

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 (
<div>
<DaBest name={whoIsTheBest}/>
{productList.map(product => <Product name={product.name} key={product.id}/>)}

<AdderButton {...this.props} />
<DaBest name={whoIsTheBest} />
<SearchInput handleOnChange={this.handleOnChange} />
{productList
.filter(product => {
let name = product.name.toLowerCase();
return name.includes(searchString.toLowerCase());
})
.map(product => (
<div key={product.id}>
<Product product={product} />
<DeleteButton
deleteProduct={this.props.deleteProduct}
id={product.id}
/>
</div>
))}
<Form handleSubmit={this.handleSubmit} />
</div>
);
}
}


// 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);
24 changes: 22 additions & 2 deletions src/actions/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
export const ACTION_TYPES = {
addProduct: 'ADD_PRODUCTS',
deleteProduct: 'DELETE_PRODUCTS',
updateSearchString: 'UPDATE_SEARCH_STRING'
};

export function addProduct(product) {
debugger;
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
}
};
}
15 changes: 9 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<Provider store={ store }>
<App />
</Provider>,
document.getElementById('root')
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
registerServiceWorker();
44 changes: 29 additions & 15 deletions src/reducers/index.js
Original file line number Diff line number Diff line change
@@ -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
});