Commit 1a41cf17 by Kristian Freeman

Migrate state handling and actions to redux

parent b13516ac
......@@ -2,6 +2,16 @@ import React, { Component } from 'react';
import "./index.css"
import "./normalize.css"
import { connect } from 'react-redux'
import {
attemptWidgetCreation,
checkOrderForPackaging,
generateOrder,
orderMaterials,
shipOrder
} from './actions'
import Inventory from './Inventory'
import Materials from './Materials'
import Management from './Management'
......@@ -15,137 +25,52 @@ const Header = () => <img className="logo" src="/logo.png" />
const Error = (props) => <h4>{props.message}</h4>
class App extends Component {
constructor() {
super()
this.state = {
error: null,
failed: 0,
orders: [],
materials: {
dowel: { count: 2 },
screw: { count: 8 },
wheel: { count: 3 }
},
packaged: 0,
shipped: 0,
widgets: []
}
this.addWidget = this.addWidget.bind(this)
this.generateOrder = this.generateOrder.bind(this)
this.orderMaterials = this.orderMaterials.bind(this)
this.packageOrder = this.packageOrder.bind(this)
this.presentError = this.presentError.bind(this)
this.shipOrder = this.shipOrder.bind(this)
}
addWidget() {
const newMaterials = this.state.materials
newMaterials.dowel.count -= 1
newMaterials.screw.count -= 2
newMaterials.wheel.count -= 2
let newState = { materials: newMaterials }
if (this.qaCheck()) {
const newWidget = { created: Date.now() }
const newWidgetsInventory = [].concat(this.state.widgets, newWidget)
newState.error = null
newState.widgets = newWidgetsInventory
} else {
newState.failed = this.state.failed += 1
newState.error = "A widget failed QA!"
}
this.setState(Object.assign({}, this.state, newState))
}
generateOrder() {
const newOrder = {
created: Date.now(),
widgets: Math.floor(Math.random() * 10) + 1
}
const newOrders = [].concat(this.state.orders, newOrder)
const newState = Object.assign({}, this.state, {
orders: newOrders
})
this.setState(newState)
}
orderMaterials() {
const { materials } = this.state
const { dowel, screw, wheel } = materials
this.setState(Object.assign({}, this.state, {
error: null,
materials: {
dowel: { count: dowel.count + 10 },
screw: { count: screw.count + 10 },
wheel: { count: wheel.count + 10 }
}
}))
}
packageOrder() {
const { orders, packaged, widgets } = this.state
const newOrders = [].concat(orders)
const order = newOrders.pop()
if (order.widgets <= widgets.length) {
const newWidgets = widgets
for (var i=0; i < order.widgets; i++) {
newWidgets.shift()
}
this.setState({
error: null,
orders: newOrders,
packaged: packaged + 1,
widgets: newWidgets
})
} else {
this.presentError("Not enough widgets to fill order!")
}
}
presentError(message) {
this.setState(Object.assign({}, this.state, { error: message }))
}
qaCheck() {
const check = Math.floor(Math.random() * 10)
return check < 7
}
shipOrder() {
const { packaged, shipped } = this.state
this.setState({
error: null,
packaged: packaged - 1,
shipped: shipped + 1
})
}
render() {
const { error, failed, materials, orders, packaged, shipped, widgets } = this.state
const {
attemptWidgetCreation,
checkOrderForPackaging,
error,
failed,
generateOrder,
materials,
orderMaterials,
orders,
packaged,
shipped,
shipOrder,
widgets
} = this.props
return (
<div>
<Header />
{error ? <Error message={error} /> : null}
<Orders generateOrder={this.generateOrder} orders={orders} />
<Orders generateOrder={generateOrder} orders={orders} />
<Materials materials={materials} />
<Manufacturing
addWidget={this.addWidget}
addWidget={attemptWidgetCreation}
materials={materials}
presentError={this.presentError}
/>
<QA failed={failed} />
<Inventory widgets={widgets} />
<Packaging orders={orders} packaged={packaged} packageOrder={this.packageOrder} />
<Shipping packaged={packaged} shipped={shipped} shipOrder={this.shipOrder} />
<Management orderMaterials={this.orderMaterials} />
<Packaging orders={orders} packaged={packaged} packageOrder={checkOrderForPackaging} />
<Shipping packaged={packaged} shipped={shipped} shipOrder={shipOrder} />
<Management orderMaterials={orderMaterials} />
</div>
);
}
}
export default App;
const mapStateToProps = (state) => state
const mapActionCreators = {
attemptWidgetCreation,
checkOrderForPackaging,
generateOrder,
orderMaterials,
shipOrder
}
export default connect(
mapStateToProps,
mapActionCreators
)(App);
import React, { Component } from 'react';
class Manufacturing extends Component {
constructor() {
super()
this.manufactureWidget = this.manufactureWidget.bind(this)
}
manufactureWidget() {
const { addWidget, materials, presentError } = this.props
if (materials.dowel.count >= 1 && materials.screw.count >= 2 && materials.wheel.count >= 2) {
addWidget()
} else {
presentError("Not enough materials to create a widget")
}
}
render() {
return (
<div>
<h2>Manufacturing</h2>
<button onClick={this.manufactureWidget}>Manufacture widget</button>
<button onClick={this.props.addWidget}>Manufacture widget</button>
</div>
);
}
......
import {
ADD_WIDGET,
GENERATE_ORDER,
ORDER_MATERIALS,
PACKAGE_ORDER,
PRESENT_ERROR,
DOWELS_NEEDED,
SCREWS_NEEDED,
WHEELS_NEEDED
} from './constants'
export function attemptWidgetCreation() {
return (dispatch, getState) => {
const { materials } = getState()
const { dowel, screw, wheel } = materials
if (dowel.count >= DOWELS_NEEDED && screw.count >= SCREWS_NEEDED && wheel.count >= WHEELS_NEEDED) {
dispatch(addWidget())
} else {
dispatch(presentError("Not enough materials to create a widget"))
}
}
}
export function addWidget() {
return {
type: ADD_WIDGET
}
}
export function generateOrder() {
return {
type: GENERATE_ORDER
}
}
export function orderMaterials() {
return {
type: ORDER_MATERIALS
}
}
export function checkOrderForPackaging() {
return (dispatch, getState) => {
const { orders, widgets } = getState()
const order = orders[0]
if (order.widgets <= widgets.length) {
dispatch(packageOrder())
} else {
dispatch(presentError("Not enough widgets to fill order!"))
}
}
}
export function packageOrder(order) {
return {
type: PACKAGE_ORDER,
order
}
}
export function presentError(message) {
return {
type: PRESENT_ERROR,
message
}
}
export default {
attemptWidgetCreation,
generateOrder,
orderMaterials,
packageOrder,
presentError
}
export const ADD_WIDGET = 'ADD_WIDGET'
export const GENERATE_ORDER = 'GENERATE_ORDER'
export const ORDER_MATERIALS = 'ORDER_MATERIALS'
export const PACKAGE_ORDER = 'PACKAGE_ORDER'
export const PRESENT_ERROR = 'PRESENT_ERROR'
export const SHIP_ORDER = 'SHIP_ORDER'
export const DOWELS_NEEDED = 1
export const SCREWS_NEEDED = 2
export const WHEELS_NEEDED = 2
import {
ADD_WIDGET,
GENERATE_ORDER,
ORDER_MATERIALS,
PACKAGE_ORDER,
PRESENT_ERROR,
SHIP_ORDER,
DOWELS_NEEDED,
SCREWS_NEEDED,
WHEELS_NEEDED
} from './constants'
const initialState = {
error: null,
failed: 0,
orders: [],
materials: {
dowel: { count: 2 },
screw: { count: 8 },
wheel: { count: 3 }
},
packaged: 0,
shipped: 0,
widgets: []
}
const addWidget = (state) => {
const newMaterials = state.materials
newMaterials.dowel.count -= DOWELS_NEEDED
newMaterials.screw.count -= SCREWS_NEEDED
newMaterials.wheel.count -= WHEELS_NEEDED
let newState = { materials: newMaterials }
if (qaCheck()) {
const newWidget = { created: Date.now() }
const newWidgetsInventory = [].concat(state.widgets, newWidget)
newState.error = null
newState.widgets = newWidgetsInventory
} else {
newState.failed = state.failed += 1
newState.error = "A widget failed QA!"
}
return Object.assign({}, state, newState)
}
const qaCheck = () => {
const check = Math.floor(Math.random() * 10)
return check < 7
}
const generateOrder = (state) => {
const newOrder = {
created: Date.now(),
widgets: Math.floor(Math.random() * 10) + 1
}
const newOrders = [].concat(state.orders, newOrder)
return Object.assign({}, state, {
orders: newOrders
})
}
const orderMaterials = (state) => {
const { materials } = state
const { dowel, screw, wheel } = materials
return Object.assign({}, state, {
error: null,
materials: {
dowel: { count: dowel.count + 10 },
screw: { count: screw.count + 10 },
wheel: { count: wheel.count + 10 }
}
})
}
const packageOrder = (state, order) => {
const newWidgets = state.widgets
for (var i=0; i < order.widgets; i++) {
newWidgets.shift()
}
const newOrders = [].
concat(state.orders).
slice(state.orders.indexOf(order), 1)
return Object.assign({}, state, {
error: null,
orders: newOrders,
packaged: state.packaged + 1,
widgets: state.newWidgets
})
}
const presentError = (state, message) => {
return Object.assign({}, state, {
error: message
})
}
const shipOrder = (state) => {
return Object.assign({}, state, {
error: null,
packaged: state.packaged - 1,
shipped: state.shipped + 1
})
}
export default function appState(state = initialState, action) {
switch (action.type) {
case ADD_WIDGET:
return addWidget(state)
case GENERATE_ORDER:
return generateOrder(state)
case ORDER_MATERIALS:
return orderMaterials(state)
case PACKAGE_ORDER:
return packageOrder(state, action.order)
case PRESENT_ERROR:
return presentError(state, action.message)
case SHIP_ORDER:
return shipOrder(state)
default:
return state
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment