From ee58d5f3e88847280b68dbf2906d59db046fb2e3 Mon Sep 17 00:00:00 2001 From: Matt Cameron Date: Wed, 23 May 2018 19:31:19 -0500 Subject: [PATCH 01/10] impl ProductDetail --- .vscode/settings.json | 3 + src/App.js | 352 +++++++++++++------------------- src/components/Carousel.js | 0 src/components/Footer.js | 0 src/components/Header.js | 0 src/components/ProductDetail.js | 34 +++ src/index.js | 14 +- 7 files changed, 189 insertions(+), 214 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/components/Carousel.js create mode 100644 src/components/Footer.js create mode 100644 src/components/Header.js create mode 100644 src/components/ProductDetail.js diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9d2ce8c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "prettier.singleQuote": false, +} \ No newline at end of file diff --git a/src/App.js b/src/App.js index b6f04e9..738e668 100644 --- a/src/App.js +++ b/src/App.js @@ -1,204 +1,146 @@ -import React, { Component } from 'react'; -import logo from './logo.svg'; -import './App.css'; +import React, { Component } from "react"; +import ProductDetail from "./components/ProductDetail"; -function App() { - return ( -
- {/*
*/} - + {/*
*/} +
- -
-

Shop Name

- + -
- {/**/} -
- -
- -
- -
- {/*
*/} -
- {/**/} -
-
- -
-

$24.99

-

First Product -

-

See more snippets like this online store item at Bootsnipp - http://bootsnipp.com.

-
-
-

15 reviews

-

- - - - - -

-
-
-
- {/*
*/} -
-
- -
-

$64.99

-

Second Product -

-

This is a short description. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

-
-
-

12 reviews

-

- - - - - -

-
-
-
- -
-
- -
-

$74.99

-

Third Product -

-

This is a short description. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

-
-
-

31 reviews

-

- - - - - -

-
-
+
+ {/**/} +
+
+ + {/**/} +
+ {/**/} + {productDetails} + {/**/} + {/*

Like this template?

@@ -206,30 +148,26 @@ function App() { View Tutorial
*/} -
-
- +
+
-
- -
- -
+
+
- {/*
*/} + {/*
*/}
-
-
-

Copyright © Your Website 2014

-
+
+
+

Copyright © Your Website 2014

+
- {/*
*/} -
+ {/**/}
- ); +
+ ); } export default App; diff --git a/src/components/Carousel.js b/src/components/Carousel.js new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Footer.js b/src/components/Footer.js new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Header.js b/src/components/Header.js new file mode 100644 index 0000000..e69de29 diff --git a/src/components/ProductDetail.js b/src/components/ProductDetail.js new file mode 100644 index 0000000..e819579 --- /dev/null +++ b/src/components/ProductDetail.js @@ -0,0 +1,34 @@ +import React from "react"; + +export default function ProductDetail(props) { + const { name, price, description, reviews, rating} = props.product; + const starSpans = []; + for (let index = 0; index < rating; index++) { + starSpans.push(); + } + return ( +
+
+ +
+

{price}

+

+ {name} +

+

+ {description} {" "} + + Bootsnipp - http://bootsnipp.com + . +

+
+
+

{reviews} reviews

+

+ {starSpans} +

+
+
+
+ ); +} diff --git a/src/index.js b/src/index.js index e58303d..96fb478 100644 --- a/src/index.js +++ b/src/index.js @@ -1,10 +1,10 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './App'; -import './index.css'; -import state from './state'; +import React from "react"; +import ReactDOM from "react-dom"; +import App from "./App"; +import "./index.css"; +import state from "./state"; ReactDOM.render( - , - document.getElementById('root') + , + document.getElementById("root") ); From 33339189ea851dd535e4b90b4072bf8fde2fe4d0 Mon Sep 17 00:00:00 2001 From: Matt Cameron Date: Wed, 23 May 2018 19:34:34 -0500 Subject: [PATCH 02/10] empty stars --- src/components/ProductDetail.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/ProductDetail.js b/src/components/ProductDetail.js index e819579..341829d 100644 --- a/src/components/ProductDetail.js +++ b/src/components/ProductDetail.js @@ -4,7 +4,11 @@ export default function ProductDetail(props) { const { name, price, description, reviews, rating} = props.product; const starSpans = []; for (let index = 0; index < rating; index++) { - starSpans.push(); + starSpans.push(); + } + const emptyStarSpans = []; + for (let index = 0; index < 5 - rating; index++) { + emptyStarSpans.push(); } return (
@@ -25,7 +29,7 @@ export default function ProductDetail(props) {

{reviews} reviews

- {starSpans} + {starSpans}{emptyStarSpans}

From 196d181d462dbc020b63758ed4ead9b94db3263d Mon Sep 17 00:00:00 2001 From: Matt Cameron Date: Wed, 23 May 2018 19:41:54 -0500 Subject: [PATCH 03/10] impl main components --- src/App.js | 129 ++++--------------------------------- src/components/Carousel.js | 62 ++++++++++++++++++ src/components/Footer.js | 13 ++++ src/components/Header.js | 46 +++++++++++++ 4 files changed, 133 insertions(+), 117 deletions(-) diff --git a/src/App.js b/src/App.js index 738e668..bc69fd7 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,9 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; + +import Header from "./components/Header"; +import Footer from "./components/Footer"; +import Carousel from "./components/Carousel"; import ProductDetail from "./components/ProductDetail"; import logo from "./logo.svg"; @@ -11,48 +16,7 @@ function App(props) { return (
- {/*
*/} - - {/*
*/} +
@@ -72,74 +36,9 @@ function App(props) {
- {/**/} -
-
- -
-
- {/*
*/} +
- {/**/} {productDetails} - {/**/} {/*

Like this template? @@ -156,18 +55,14 @@ function App(props) {

- {/*
*/} -
-
-
-

Copyright © Your Website 2014

-
-
-
- {/*
*/} +

); } +App.propTypes = { + products: PropTypes.array.isRequired, +}; + export default App; diff --git a/src/components/Carousel.js b/src/components/Carousel.js index e69de29..91db3ff 100644 --- a/src/components/Carousel.js +++ b/src/components/Carousel.js @@ -0,0 +1,62 @@ +import React from "react"; + +export default function Carousel() { + return ( +
+
+ +
+
+ ); +} diff --git a/src/components/Footer.js b/src/components/Footer.js index e69de29..7accbb3 100644 --- a/src/components/Footer.js +++ b/src/components/Footer.js @@ -0,0 +1,13 @@ +import React from "react"; + +export default function Footer() { + return ( +
+
+
+

Copyright © Your Website 2014

+
+
+
+ ); +} diff --git a/src/components/Header.js b/src/components/Header.js index e69de29..1e4f28f 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -0,0 +1,46 @@ +import React from "react"; + +export default function Header() { + return ( + + ); +} From 3856555bc7304db97fbf081e4800d8997defcd13 Mon Sep 17 00:00:00 2001 From: Matt Cameron Date: Wed, 23 May 2018 20:32:30 -0500 Subject: [PATCH 04/10] cart items --- src/App.js | 91 +++++++++++++++++++++------------ src/components/Header.js | 9 +++- src/components/ProductDetail.js | 23 +++++++-- 3 files changed, 84 insertions(+), 39 deletions(-) diff --git a/src/App.js b/src/App.js index bc69fd7..1cf193e 100644 --- a/src/App.js +++ b/src/App.js @@ -9,37 +9,61 @@ import ProductDetail from "./components/ProductDetail"; import logo from "./logo.svg"; import "./App.css"; -function App(props) { - const productDetails = props.products.map((p) => { - return ; - }); +class App extends Component { + state = { + cartItems: [], + }; - return ( -
-
+ constructor(props) { + super(props); + this.addItemToCart = this.addItemToCart.bind(this); + } -
-
-
-

Shop Name

-
- - Category 1 - - - Category 2 - - - Category 3 - + addItemToCart(item) { + const items = this.state.cartItems.slice(); + items.push(item); + this.setState({ + cartItems: items + }); + } + + render() { + const productDetails = this.props.products.map((p) => { + return ( + + ); + }); + + return ( +
+
+ +
+ -
- -
- {productDetails} - {/* +
+ +
+ {productDetails} + {/*

Like this template?

@@ -47,18 +71,19 @@ function App(props) { View Tutorial
*/} +
-
-
-
+
+
-
+
+
-
- ); + ); + } } App.propTypes = { diff --git a/src/components/Header.js b/src/components/Header.js index 1e4f28f..00224de 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -1,6 +1,7 @@ import React from "react"; +import PropTypes from "prop-types"; -export default function Header() { +export default function Header(props) { return ( ); } + +Header.propTypes = { + numberOfItemsInCart: PropTypes.number.isRequired, +}; diff --git a/src/components/ProductDetail.js b/src/components/ProductDetail.js index 341829d..65fba62 100644 --- a/src/components/ProductDetail.js +++ b/src/components/ProductDetail.js @@ -1,14 +1,17 @@ import React from "react"; +import PropTypes from "prop-types"; export default function ProductDetail(props) { - const { name, price, description, reviews, rating} = props.product; + const { name, price, description, reviews, rating } = props.product; const starSpans = []; for (let index = 0; index < rating; index++) { starSpans.push(); } const emptyStarSpans = []; for (let index = 0; index < 5 - rating; index++) { - emptyStarSpans.push(); + emptyStarSpans.push( + + ); } return (
@@ -20,19 +23,31 @@ export default function ProductDetail(props) { {name}

- {description} {" "} + {description}{" "} Bootsnipp - http://bootsnipp.com .

+

{reviews} reviews

- {starSpans}{emptyStarSpans} + {starSpans} + {emptyStarSpans}

); + + function onClick() { + props.onAddItemToCart(props.product); + } } + + +ProductDetail.propTypes = { + product: PropTypes.object.isRequired, + onAddItemToCart: PropTypes.func.isRequired, +}; From 95df5bd4748e699bebc60f3be469c74248785027 Mon Sep 17 00:00:00 2001 From: Matt Cameron Date: Wed, 30 May 2018 09:28:51 -0500 Subject: [PATCH 05/10] added checkout button --- src/components/Header.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/Header.js b/src/components/Header.js index 00224de..bbeb7ed 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -39,6 +39,9 @@ export default function Header(props) {
  • Items In Cart ({props.numberOfItemsInCart})
  • +
  • + { props.numberOfItemsInCart > 0 ? Checkout : null } +
  • From fd1dc58d150cc27331b0fd0cbe63bc19d3531264 Mon Sep 17 00:00:00 2001 From: Matt Cameron Date: Wed, 30 May 2018 09:58:16 -0500 Subject: [PATCH 06/10] added server and order routes --- package-lock.json | 271 ++++++++++++++++---------- package.json | 6 +- server/controllers/OrderController.js | 32 +++ server/index.js | 28 +++ server/models/Order.js | 26 +++ server/routes/OrderRoutes.js | 14 ++ 6 files changed, 278 insertions(+), 99 deletions(-) create mode 100644 server/controllers/OrderController.js create mode 100644 server/index.js create mode 100644 server/models/Order.js create mode 100644 server/routes/OrderRoutes.js diff --git a/package-lock.json b/package-lock.json index 29156fd..1e0eb9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,6 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "dev": true, "requires": { "mime-types": "2.1.18", "negotiator": "0.6.1" @@ -190,8 +189,7 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "array-union": { "version": "1.0.2", @@ -1257,7 +1255,6 @@ "version": "1.18.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", - "dev": true, "requires": { "bytes": "3.0.0", "content-type": "1.0.4", @@ -1274,14 +1271,12 @@ "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" }, "qs": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", - "dev": true + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" } } }, @@ -1375,6 +1370,11 @@ "node-int64": "0.4.0" } }, + "bson": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.6.tgz", + "integrity": "sha512-D8zmlb46xfuK2gGvKmUjIklQEouN2nQ0LEHHeZ/NoHM2LDiMk2EYzZ5Ntw/Urk+bgMDosOZxaRzXxvhI5TcAVQ==" + }, "buffer": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", @@ -1407,8 +1407,7 @@ "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, "caller-path": { "version": "0.1.0", @@ -1798,14 +1797,12 @@ "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "content-type-parser": { "version": "1.0.2", @@ -1822,14 +1819,12 @@ "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "core-js": { "version": "1.2.7", @@ -2090,7 +2085,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -2167,14 +2161,12 @@ "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, "destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "detect-indent": { "version": "4.0.0", @@ -2276,10 +2268,9 @@ } }, "dotenv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-2.0.0.tgz", - "integrity": "sha1-vXWcNXqqcDZeAclrewvsCKbg2Uk=", - "dev": true + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz", + "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==" }, "duplexer": { "version": "0.1.1", @@ -2300,8 +2291,7 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { "version": "1.3.45", @@ -2324,8 +2314,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "encoding": { "version": "0.1.12", @@ -2476,8 +2465,7 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, "escape-string-regexp": { "version": "1.0.5", @@ -2756,8 +2744,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "event-emitter": { "version": "0.3.5", @@ -2827,7 +2814,6 @@ "version": "4.16.3", "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", - "dev": true, "requires": { "accepts": "1.3.5", "array-flatten": "1.1.1", @@ -2864,14 +2850,12 @@ "qs": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", - "dev": true + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" } } }, @@ -3031,7 +3015,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", - "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "1.0.2", @@ -3142,14 +3125,12 @@ "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "fs-extra": { "version": "0.30.0", @@ -4502,7 +4483,6 @@ "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, "requires": { "depd": "1.1.2", "inherits": "2.0.3", @@ -4630,8 +4610,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "inquirer": { "version": "0.12.0", @@ -4678,8 +4657,7 @@ "ipaddr.js": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", - "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=", - "dev": true + "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=" }, "is-absolute-url": { "version": "2.1.0", @@ -5468,6 +5446,11 @@ "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=", "dev": true }, + "kareem": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.1.0.tgz", + "integrity": "sha512-ycoMY1tVkcH1/NaxGn2erZaUC3CodmX7Fl6DUVXjN73+uecWYTaaldRkxNY3HeSKQnQTWnoxRKnZfVHcB8tIWg==" + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -5550,8 +5533,7 @@ "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" }, "lodash._arraycopy": { "version": "3.0.0", @@ -5641,6 +5623,11 @@ "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, "lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -5767,8 +5754,7 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "memory-fs": { "version": "0.3.0", @@ -5789,14 +5775,12 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "micromatch": { "version": "2.3.11", @@ -5828,14 +5812,12 @@ "mime-db": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" }, "mime-types": { "version": "2.1.18", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, "requires": { "mime-db": "1.33.0" } @@ -5864,11 +5846,88 @@ "minimist": "0.0.8" } }, + "mongodb": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.0.8.tgz", + "integrity": "sha512-mj7yIUyAr9xnO2ev8pcVJ9uX7gSum5LLs1qIFoWLxA5Il50+jcojKtaO1/TbexsScZ9Poz00Pc3b86GiSqJ7WA==", + "requires": { + "mongodb-core": "3.0.8" + } + }, + "mongodb-core": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.0.8.tgz", + "integrity": "sha512-dFxfhH9N7ohuQnINyIl6dqEF8sYOE0WKuymrFf3L3cipJNrx+S8rAbNOTwa00/fuJCjBMJNFsaA+R2N16//UIw==", + "requires": { + "bson": "1.0.6", + "require_optional": "1.0.1" + } + }, + "mongoose": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.1.3.tgz", + "integrity": "sha512-v+hHI/NxJtcVPm2cY+/kJfTfkkXVCz/le0iVdnh3enGi+fClhoaztjTtXQMdzIzNc+M0R93KcARpzvPQq/cWKQ==", + "requires": { + "async": "2.1.4", + "bson": "1.0.6", + "kareem": "2.1.0", + "lodash.get": "4.4.2", + "mongodb": "3.0.8", + "mongoose-legacy-pluralize": "1.0.2", + "mpath": "0.4.1", + "mquery": "3.0.0", + "ms": "2.0.0", + "regexp-clone": "0.0.1", + "sliced": "1.0.1" + }, + "dependencies": { + "async": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.1.4.tgz", + "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=", + "requires": { + "lodash": "4.17.10" + } + } + } + }, + "mongoose-legacy-pluralize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", + "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" + }, + "mpath": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.4.1.tgz", + "integrity": "sha512-NNY/MpBkALb9jJmjpBlIi6GRoLveLUM0pJzgbp9vY9F7IQEb/HREC/nxrixechcQwd1NevOhJnWWV8QQQRE+OA==" + }, + "mquery": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.0.0.tgz", + "integrity": "sha512-WL1Lk8v4l8VFSSwN3yCzY9TXw+fKVYKn6f+w86TRzOLSE8k1yTgGaLBPUByJQi8VcLbOdnUneFV/y3Kv874pnQ==", + "requires": { + "bluebird": "3.5.0", + "debug": "2.6.9", + "regexp-clone": "0.0.1", + "sliced": "0.0.5" + }, + "dependencies": { + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" + }, + "sliced": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", + "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8=" + } + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "mute-stream": { "version": "0.0.5", @@ -5892,8 +5951,7 @@ "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "dev": true + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, "next-tick": { "version": "1.0.0", @@ -6105,7 +6163,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, "requires": { "ee-first": "1.1.1" } @@ -6272,8 +6329,7 @@ "parseurl": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", - "dev": true + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" }, "path-browserify": { "version": "0.0.0", @@ -6311,8 +6367,7 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, "path-type": { "version": "1.1.0", @@ -7071,7 +7126,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", - "dev": true, "requires": { "forwarded": "0.1.2", "ipaddr.js": "1.6.0" @@ -7163,14 +7217,12 @@ "range-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" }, "raw-body": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", - "dev": true, "requires": { "bytes": "3.0.0", "http-errors": "1.6.2", @@ -7181,14 +7233,12 @@ "depd": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" }, "http-errors": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "dev": true, "requires": { "depd": "1.1.1", "inherits": "2.0.3", @@ -7199,14 +7249,12 @@ "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" }, "setprototypeof": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" } } }, @@ -7321,6 +7369,12 @@ "isarray": "1.0.0" } }, + "dotenv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-2.0.0.tgz", + "integrity": "sha1-vXWcNXqqcDZeAclrewvsCKbg2Uk=", + "dev": true + }, "eslint": { "version": "3.16.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.16.1.tgz", @@ -7563,6 +7617,11 @@ "is-equal-shallow": "0.1.3" } }, + "regexp-clone": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", + "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" + }, "regexpu-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", @@ -7709,6 +7768,22 @@ "resolve-from": "1.0.1" } }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "2.0.0", + "semver": "5.5.0" + }, + "dependencies": { + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + } + } + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -7821,14 +7896,12 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" }, "send": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "dev": true, "requires": { "debug": "2.6.9", "depd": "1.1.2", @@ -7848,8 +7921,7 @@ "mime": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" } } }, @@ -7872,7 +7944,6 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "dev": true, "requires": { "encodeurl": "1.0.2", "escape-html": "1.0.3", @@ -7900,8 +7971,7 @@ "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" }, "sha.js": { "version": "2.2.6", @@ -7926,6 +7996,11 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, + "shortid": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.8.tgz", + "integrity": "sha1-AzsRfWoul1gE9vCWnb59PQs1UTE=" + }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -7938,6 +8013,11 @@ "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", "dev": true }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, "sntp": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", @@ -8069,8 +8149,7 @@ "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, "stream-browserify": { "version": "2.0.1", @@ -8387,7 +8466,6 @@ "version": "1.6.16", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", - "dev": true, "requires": { "media-typer": "0.3.0", "mime-types": "2.1.18" @@ -8452,8 +8530,7 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, "upper-case": { "version": "1.1.3", @@ -8548,8 +8625,7 @@ "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { "version": "3.2.1", @@ -8570,8 +8646,7 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, "vendors": { "version": "1.0.2", diff --git a/package.json b/package.json index 9a0699c..083fe41 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,12 @@ "react-scripts": "^0.9.5" }, "dependencies": { + "dotenv": "^5.0.1", + "express": "^4.16.3", + "mongoose": "^5.1.3", "react": "^15.5.4", - "react-dom": "^15.5.4" + "react-dom": "^15.5.4", + "shortid": "^2.2.8" }, "scripts": { "start": "react-scripts start", diff --git a/server/controllers/OrderController.js b/server/controllers/OrderController.js new file mode 100644 index 0000000..3071a13 --- /dev/null +++ b/server/controllers/OrderController.js @@ -0,0 +1,32 @@ +const Order = require("../models/Order"); +const shortid = require("shortid"); + +module.exports.list = function (request, response) { + Order.find({}) + .exec() + .then((orders) => { + return response.json(orders); + }); +}; + +module.exports.show = function (request, response) { + Order.findById({ + id: request.params.id, + }) + .exec() + .then((order) => { + return response.json(order); + }); +}; + +module.exports.create = function (request, response) { + const body = request.body; + const newOrder = new Order({ + id: body.id || shortid.generate(), + date: body.date, + items: body.items, + }); + newOrder.save().then((order) => { + return response.json(order); + }); +}; diff --git a/server/index.js b/server/index.js new file mode 100644 index 0000000..b121ad4 --- /dev/null +++ b/server/index.js @@ -0,0 +1,28 @@ +require("dotenv").config(); +const express = require("express"); +const bodyParser = require("body-parser"); + +const app = express(); + +app.use(bodyParser.json()); +app.use(require("./routes/OrderRoutes")); + +const mongoose = require("mongoose"); +const mlabUri = process.env.SECRET || ""; +if (!mlabUri) { + console.log( + "*************************************************************************" + ); + console.error( + "WARNING! Set the SECRET environment variable in .env to your MLAB URI." + ); + console.log( + "*************************************************************************" + ); +} +mongoose.connect(mlabUri); + +const port = process.env.PORT || 3001; +app.listen(port, () => { + console.log(`Listening on port:${port}`); +}); diff --git a/server/models/Order.js b/server/models/Order.js new file mode 100644 index 0000000..d3418de --- /dev/null +++ b/server/models/Order.js @@ -0,0 +1,26 @@ +const mongoose = require("mongoose"); + +const orderItemSchema = new mongoose.Schema({ + productId: { + type: String, + required: true, + }, + price: { + type: Number, + required: true, + } +}); + +const orderSchema = new mongoose.Schema({ + id: { + type: Number, + required: true, + }, + date: { + type: String, + required: true, + }, + items: [orderItemSchema] +}); + +module.exports = mongoose.model("Order", orderSchema); diff --git a/server/routes/OrderRoutes.js b/server/routes/OrderRoutes.js new file mode 100644 index 0000000..7071dd6 --- /dev/null +++ b/server/routes/OrderRoutes.js @@ -0,0 +1,14 @@ +const express = require("express"); +const router = express.Router(); +const path = "/orders"; +const { + list, + show, + create, +} = require("../controllers/OrderController"); + +router.get(path, list); +router.get(path + "/:id", show); +router.post(path, create); + +module.exports = router; From 8f9ed2753229c48c69c89f7d321207b5c511c9cb Mon Sep 17 00:00:00 2001 From: Matt Cameron Date: Wed, 30 May 2018 13:02:02 -0500 Subject: [PATCH 07/10] implemented product routes --- package.json | 3 ++- server/controllers/ProductController.js | 19 ++++++++++++++ server/index.js | 1 + server/models/Product.js | 34 +++++++++++++++++++++++++ server/routes/ProductRoutes.js | 12 +++++++++ src/App.js | 27 +++++++++++++++----- src/components/ProductDetail.js | 4 +-- src/index.js | 6 +++-- 8 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 server/controllers/ProductController.js create mode 100644 server/models/Product.js create mode 100644 server/routes/ProductRoutes.js diff --git a/package.json b/package.json index 083fe41..a900118 100644 --- a/package.json +++ b/package.json @@ -22,5 +22,6 @@ "build": "react-scripts build", "test": "npm run lint && react-scripts test --env=jsdom", "eject": "react-scripts eject" - } + }, + "proxy": "http://localhost:3001" } diff --git a/server/controllers/ProductController.js b/server/controllers/ProductController.js new file mode 100644 index 0000000..d3fe8df --- /dev/null +++ b/server/controllers/ProductController.js @@ -0,0 +1,19 @@ +const Product = require("../models/Product"); + +module.exports.list = function (request, response) { + Product.find({}) + .exec() + .then((products) => { + return response.json(products); + }); +}; + +module.exports.show = function (request, response) { + Product.findById({ + id: request.params.id, + }) + .exec() + .then((product) => { + return response.json(product); + }); +}; diff --git a/server/index.js b/server/index.js index b121ad4..d188b31 100644 --- a/server/index.js +++ b/server/index.js @@ -6,6 +6,7 @@ const app = express(); app.use(bodyParser.json()); app.use(require("./routes/OrderRoutes")); +app.use(require("./routes/ProductRoutes")); const mongoose = require("mongoose"); const mlabUri = process.env.SECRET || ""; diff --git a/server/models/Product.js b/server/models/Product.js new file mode 100644 index 0000000..040643c --- /dev/null +++ b/server/models/Product.js @@ -0,0 +1,34 @@ +const mongoose = require("mongoose"); + +const productSchema = new mongoose.Schema({ + id: { + type: Number, + required: true, + }, + name: { + type: String, + required: true, + }, + description: { + type: String, + required: true, + }, + reviews: { + type: Number, + required: false, + }, + rating: { + type: Number, + required: false, + }, + imgUrl: { + type: String, + required: false, + }, + price: { + type: String, + required: true, + }, +}); + +module.exports = mongoose.model("Product", productSchema); diff --git a/server/routes/ProductRoutes.js b/server/routes/ProductRoutes.js new file mode 100644 index 0000000..2b97031 --- /dev/null +++ b/server/routes/ProductRoutes.js @@ -0,0 +1,12 @@ +const express = require("express"); +const router = express.Router(); +const path = "/products"; +const { + list, + show, +} = require("../controllers/ProductController"); + +router.get(path, list); +router.get(path + "/:id", show); + +module.exports = router; diff --git a/src/App.js b/src/App.js index 1cf193e..3f68796 100644 --- a/src/App.js +++ b/src/App.js @@ -1,17 +1,18 @@ import React, { Component } from "react"; -import PropTypes from "prop-types"; +// import PropTypes from "prop-types"; import Header from "./components/Header"; import Footer from "./components/Footer"; import Carousel from "./components/Carousel"; import ProductDetail from "./components/ProductDetail"; -import logo from "./logo.svg"; +// import logo from "./logo.svg"; import "./App.css"; class App extends Component { state = { cartItems: [], + products: [], }; constructor(props) { @@ -23,12 +24,24 @@ class App extends Component { const items = this.state.cartItems.slice(); items.push(item); this.setState({ - cartItems: items + cartItems: items, }); } + componentDidMount() { + fetch("/products") + .then((response) => { + return response.json(); + }) + .then((products) => { + this.setState({ + products + }); + }); + } + render() { - const productDetails = this.props.products.map((p) => { + const productDetails = this.state.products.map((p) => { return ( ); @@ -16,7 +16,7 @@ export default function ProductDetail(props) { return (
    - +

    {price}

    diff --git a/src/index.js b/src/index.js index 96fb478..4db180c 100644 --- a/src/index.js +++ b/src/index.js @@ -2,9 +2,11 @@ import React from "react"; import ReactDOM from "react-dom"; import App from "./App"; import "./index.css"; -import state from "./state"; + +// import state from "./state"; ReactDOM.render( - , + // , + , document.getElementById("root") ); From d2644f754da31bdb7c2c920d1c85de5f49cd2dbe Mon Sep 17 00:00:00 2001 From: Matt Cameron Date: Wed, 30 May 2018 13:21:25 -0500 Subject: [PATCH 08/10] impl checkout --- server/controllers/OrderController.js | 13 +++++++++---- server/models/Order.js | 4 ++-- src/App.js | 23 +++++++++++++++++++++-- src/components/Header.js | 7 ++++++- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/server/controllers/OrderController.js b/server/controllers/OrderController.js index 3071a13..a90d579 100644 --- a/server/controllers/OrderController.js +++ b/server/controllers/OrderController.js @@ -1,7 +1,7 @@ const Order = require("../models/Order"); const shortid = require("shortid"); -module.exports.list = function (request, response) { +module.exports.list = (request, response) => { Order.find({}) .exec() .then((orders) => { @@ -9,7 +9,7 @@ module.exports.list = function (request, response) { }); }; -module.exports.show = function (request, response) { +module.exports.show = (request, response) => { Order.findById({ id: request.params.id, }) @@ -19,12 +19,17 @@ module.exports.show = function (request, response) { }); }; -module.exports.create = function (request, response) { +module.exports.create = (request, response) => { const body = request.body; const newOrder = new Order({ id: body.id || shortid.generate(), date: body.date, - items: body.items, + items: body.items.map((i) => { + return { + productId: i.id, + price: i.price, + }; + }), }); newOrder.save().then((order) => { return response.json(order); diff --git a/server/models/Order.js b/server/models/Order.js index d3418de..adf41c1 100644 --- a/server/models/Order.js +++ b/server/models/Order.js @@ -6,14 +6,14 @@ const orderItemSchema = new mongoose.Schema({ required: true, }, price: { - type: Number, + type: String, required: true, } }); const orderSchema = new mongoose.Schema({ id: { - type: Number, + type: String, required: true, }, date: { diff --git a/src/App.js b/src/App.js index 3f68796..4a0b4f8 100644 --- a/src/App.js +++ b/src/App.js @@ -18,6 +18,7 @@ class App extends Component { constructor(props) { super(props); this.addItemToCart = this.addItemToCart.bind(this); + this.submitOrder = this.submitOrder.bind(this); } addItemToCart(item) { @@ -28,6 +29,21 @@ class App extends Component { }); } + submitOrder() { + const order = { + date: Date(), + items: this.state.cartItems, + }; + console.log("order submitted", order); + return fetch("/orders", { + body: JSON.stringify(order), + headers: { + "content-type": "application/json", + }, + method: "POST", + }).then((response) => response.json()); + } + componentDidMount() { fetch("/products") .then((response) => { @@ -35,7 +51,7 @@ class App extends Component { }) .then((products) => { this.setState({ - products + products, }); }); } @@ -53,7 +69,10 @@ class App extends Component { return (
    -
    +
    diff --git a/src/components/Header.js b/src/components/Header.js index bbeb7ed..913f5da 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -40,7 +40,11 @@ export default function Header(props) { Items In Cart ({props.numberOfItemsInCart})
  • - { props.numberOfItemsInCart > 0 ? Checkout : null } + {props.numberOfItemsInCart > 0 ? ( + + Checkout + + ) : null}
  • @@ -51,4 +55,5 @@ export default function Header(props) { Header.propTypes = { numberOfItemsInCart: PropTypes.number.isRequired, + onSubmitOrder: PropTypes.func.isRequired, }; From 0b5bff007814e603fd9d49625797940e9236f2f1 Mon Sep 17 00:00:00 2001 From: Matt Cameron Date: Wed, 30 May 2018 13:21:36 -0500 Subject: [PATCH 09/10] cleanup --- src/App.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/App.js b/src/App.js index 4a0b4f8..a7865e6 100644 --- a/src/App.js +++ b/src/App.js @@ -34,7 +34,6 @@ class App extends Component { date: Date(), items: this.state.cartItems, }; - console.log("order submitted", order); return fetch("/orders", { body: JSON.stringify(order), headers: { From bfa0147231f5b2ca42e89ff3b148865add1f9a1d Mon Sep 17 00:00:00 2001 From: Matt Cameron Date: Wed, 30 May 2018 13:21:51 -0500 Subject: [PATCH 10/10] cleanup --- src/App.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/App.js b/src/App.js index a7865e6..ab4c3ff 100644 --- a/src/App.js +++ b/src/App.js @@ -1,12 +1,10 @@ import React, { Component } from "react"; -// import PropTypes from "prop-types"; import Header from "./components/Header"; import Footer from "./components/Footer"; import Carousel from "./components/Carousel"; import ProductDetail from "./components/ProductDetail"; -// import logo from "./logo.svg"; import "./App.css"; class App extends Component { @@ -117,8 +115,4 @@ class App extends Component { } } -// App.propTypes = { -// products: PropTypes.array.isRequired, -// }; - export default App;