diff --git a/package-lock.json b/package-lock.json
index 14198e1323..ea4f8413e1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6049,6 +6049,14 @@
"minimalistic-crypto-utils": "^1.0.1"
}
},
+ "hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "requires": {
+ "react-is": "^16.7.0"
+ }
+ },
"hosted-git-info": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
@@ -11116,6 +11124,18 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.0.tgz",
"integrity": "sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA=="
},
+ "react-redux": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.0.tgz",
+ "integrity": "sha512-EvCAZYGfOLqwV7gh849xy9/pt55rJXPwmYvI4lilPM5rUT/1NxuuN59ipdBksRVSvz0KInbPnp4IfoXJXCqiDA==",
+ "requires": {
+ "@babel/runtime": "^7.5.5",
+ "hoist-non-react-statics": "^3.3.0",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.7.2",
+ "react-is": "^16.9.0"
+ }
+ },
"react-scripts": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.0.tgz",
@@ -11238,6 +11258,15 @@
"strip-indent": "^3.0.0"
}
},
+ "redux": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz",
+ "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==",
+ "requires": {
+ "loose-envify": "^1.4.0",
+ "symbol-observable": "^1.2.0"
+ }
+ },
"regenerate": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
@@ -12929,6 +12958,11 @@
"util.promisify": "~1.0.0"
}
},
+ "symbol-observable": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
+ },
"symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
diff --git a/package.json b/package.json
index 310bc22aff..b0e61a0927 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,9 @@
"node-sass": "^4.13.1",
"react": "^16.13.0",
"react-dom": "^16.13.0",
- "react-scripts": "3.4.0"
+ "react-redux": "^7.2.0",
+ "react-scripts": "3.4.0",
+ "redux": "^4.0.5"
},
"scripts": {
"start": "react-scripts start",
diff --git a/src/App.js b/src/App.js
index a6fc09d22b..679527417e 100755
--- a/src/App.js
+++ b/src/App.js
@@ -1,48 +1,57 @@
-import React from 'react';
-
-import Header from './components/Header';
-import AddedFeatures from './components/AddedFeatures';
-import AdditionalFeatures from './components/AdditionalFeatures';
-import Total from './components/Total';
-
-const App = () => {
- const state = {
- additionalPrice: 0,
- car: {
- price: 26395,
- name: '2019 Ford Mustang',
- image:
- 'https://cdn.motor1.com/images/mgl/0AN2V/s1/2019-ford-mustang-bullitt.jpg',
- features: []
- },
- additionalFeatures: [
- { id: 1, name: 'V-6 engine', price: 1500 },
- { id: 2, name: 'Racing detail package', price: 1500 },
- { id: 3, name: 'Premium sound system', price: 500 },
- { id: 4, name: 'Rear spoiler', price: 250 }
- ]
- };
+import React from "react";
+
+import { connect } from "react-redux";
+
+import { removeItem, addItem } from "./actions";
+import Header from "./components/Header";
+import AddedFeatures from "./components/AddedFeatures";
+import AdditionalFeatures from "./components/AdditionalFeatures";
+import Total from "./components/Total";
+
+const App = props => {
const removeFeature = item => {
// dispatch an action here to remove an item
+
+
+ props.removeItem(item);
};
const buyItem = item => {
// dipsatch an action here to add an item
+
+ props.addItem(item);
};
+ // const { state, removeFeature, buyItem } = props;
+
return (
);
};
-export default App;
+
+const mapStateToProps = state => {
+ console.log("maps props", state);
+ return {
+ features: state.car.features,
+ car: state.car,
+ additionalFeatures: state.additionalFeatures,
+ additionalPrice: state.additionalPrice
+ };
+};
+
+export default connect(mapStateToProps, { removeItem, addItem })(App);
\ No newline at end of file
diff --git a/src/actions/index.js b/src/actions/index.js
new file mode 100644
index 0000000000..2e27c61847
--- /dev/null
+++ b/src/actions/index.js
@@ -0,0 +1,10 @@
+export const removeItem = item => {
+ return { type: "REMOVE_ITEM", payload: { id: item.id, price: item.price } };
+};
+
+export const addItem = item => {
+ return {
+ type: "BUY_ITEM",
+ payload: { id: item.id, name: item.name, price: item.price }
+ };
+};
\ No newline at end of file
diff --git a/src/components/AddedFeature.js b/src/components/AddedFeature.js
index 92aff93bfc..eff8c95a59 100755
--- a/src/components/AddedFeature.js
+++ b/src/components/AddedFeature.js
@@ -4,8 +4,8 @@ const AddedFeature = props => {
return (
{/* Add an onClick to run a function to remove a feature */}
-
- {props.feature.name}
+
+ {props.feature.name} (-{props.feature.price})
);
};
diff --git a/src/components/AddedFeatures.js b/src/components/AddedFeatures.js
index 620feb377b..03067d832f 100755
--- a/src/components/AddedFeatures.js
+++ b/src/components/AddedFeatures.js
@@ -9,7 +9,11 @@ const AddedFeatures = props => {
{props.car.features.length ? (
{props.car.features.map(item => (
-
+
))}
) : (
diff --git a/src/components/AdditionalFeature.js b/src/components/AdditionalFeature.js
index 5741b88d5b..7489ab51d4 100755
--- a/src/components/AdditionalFeature.js
+++ b/src/components/AdditionalFeature.js
@@ -4,7 +4,7 @@ const AdditionalFeature = props => {
return (
{/* Add an onClick that will let you add a feature to your car */}
-
+
{props.feature.name} (+{props.feature.price})
);
diff --git a/src/components/AdditionalFeatures.js b/src/components/AdditionalFeatures.js
index 5e3cc2e150..a3eaffa08a 100755
--- a/src/components/AdditionalFeatures.js
+++ b/src/components/AdditionalFeatures.js
@@ -8,7 +8,10 @@ const AdditionalFeatures = props => {
{props.additionalFeatures.length ? (
{props.additionalFeatures.map(item => (
-
+
))}
) : (
diff --git a/src/index.js b/src/index.js
index a24f2c35f0..91c7c48361 100755
--- a/src/index.js
+++ b/src/index.js
@@ -1,9 +1,21 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import App from './App';
+import React from "react";
+import ReactDOM from "react-dom";
+import { createStore } from "redux";
+import { Provider } from "react-redux";
-import 'bulma/css/bulma.css';
-import './styles.scss';
+import mainReducer from "./reducers/mainReducer";
-const rootElement = document.getElementById('root');
-ReactDOM.render(, rootElement);
+import App from "./App";
+
+import "bulma/css/bulma.css";
+import "./styles.scss";
+
+const store = createStore(mainReducer);
+
+const rootElement = document.getElementById("root");
+ReactDOM.render(
+
+
+ ,
+ rootElement
+);
\ No newline at end of file
diff --git a/src/reducers/mainReducer.js b/src/reducers/mainReducer.js
new file mode 100644
index 0000000000..7c092a319d
--- /dev/null
+++ b/src/reducers/mainReducer.js
@@ -0,0 +1,45 @@
+const initialState = {
+ additionalPrice: 0,
+ car: {
+ price: 26395,
+ name: "2019 Ford Mustang",
+ image:
+ "https://cdn.motor1.com/images/mgl/0AN2V/s1/2019-ford-mustang-bullitt.jpg",
+ features: []
+ },
+ additionalFeatures: [
+ { id: 1, name: "V-6 engine", price: 1500 },
+ { id: 2, name: "Racing detail package", price: 1500 },
+ { id: 3, name: "Premium sound system", price: 500 },
+ { id: 4, name: "Rear spoiler", price: 250 }
+ ]
+ };
+
+ const mainReducer = (state = initialState, action) => {
+ switch (action.type) {
+ case "BUY_ITEM":
+ return {
+ ...state,
+ car: {
+ ...state.car,
+ price: state.car.price + action.payload.price,
+ features: [...state.car.features, action.payload]
+ }
+ };
+ case "REMOVE_ITEM":
+ return {
+ ...state,
+ car: {
+ ...state.car,
+ price: state.car.price - action.payload.price,
+ features: [...state.car.features.filter(
+ item => item.id !== action.payload.id
+ )]
+ }
+ };
+ default:
+ return state;
+ }
+ };
+
+ export default mainReducer;
\ No newline at end of file