diff --git a/.gitignore b/.gitignore
index d30f40ef4..fbc176002 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@
.env.development.local
.env.test.local
.env.production.local
+.env
npm-debug.log*
yarn-debug.log*
diff --git a/package-lock.json b/package-lock.json
index 2207e63b9..52e5306bc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1902,6 +1902,38 @@
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
},
+ "axios": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz",
+ "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==",
+ "requires": {
+ "follow-redirects": "1.5.10",
+ "is-buffer": "^2.0.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+ "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+ "requires": {
+ "debug": "=3.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
"axobject-query": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz",
@@ -2396,6 +2428,11 @@
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
},
+ "bootstrap": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz",
+ "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
+ },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -4287,9 +4324,9 @@
}
},
"dotenv": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz",
- "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w=="
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.0.0.tgz",
+ "integrity": "sha512-30xVGqjLjiUOArT4+M5q9sYdvuR4riM6yK9wMcas9Vbp6zZa+ocC9dp6QoftuhTPhFAiLK/0C5Ni2nou/Bk8lg=="
},
"dotenv-expand": {
"version": "4.2.0",
@@ -5603,6 +5640,11 @@
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE="
},
+ "gud": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
+ "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
+ },
"gzip-size": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.0.0.tgz",
@@ -5777,6 +5819,19 @@
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
},
+ "history": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/history/-/history-4.9.0.tgz",
+ "integrity": "sha512-H2DkjCjXf0Op9OAr6nJ56fcRkTSNrUiv41vNJ6IswJjif6wlpZK0BTfFbi7qK9dXLSYZxkq5lBsj3vUjlYBYZA==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "loose-envify": "^1.2.0",
+ "resolve-pathname": "^2.2.0",
+ "tiny-invariant": "^1.0.2",
+ "tiny-warning": "^1.0.0",
+ "value-equal": "^0.4.0"
+ }
+ },
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -5787,6 +5842,14 @@
"minimalistic-crypto-utils": "^1.0.1"
}
},
+ "hoist-non-react-statics": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz",
+ "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==",
+ "requires": {
+ "react-is": "^16.7.0"
+ }
+ },
"hosted-git-info": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
@@ -8134,6 +8197,16 @@
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
},
+ "mini-create-react-context": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz",
+ "integrity": "sha512-2v+OeetEyliMt5VHMXsBhABoJ0/M4RCe7fatd/fBy6SMiKazUSEt3gxxypfnk2SHMkdBYvorHRoQxuGoiwbzAw==",
+ "requires": {
+ "@babel/runtime": "^7.4.0",
+ "gud": "^1.0.0",
+ "tiny-warning": "^1.0.2"
+ }
+ },
"mini-css-extract-plugin": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz",
@@ -10194,6 +10267,52 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
"integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA=="
},
+ "react-router": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.0.1.tgz",
+ "integrity": "sha512-EM7suCPNKb1NxcTZ2LEOWFtQBQRQXecLxVpdsP4DW4PbbqYWeRiLyV/Tt1SdCrvT2jcyXAXmVTmzvSzrPR63Bg==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "history": "^4.9.0",
+ "hoist-non-react-statics": "^3.1.0",
+ "loose-envify": "^1.3.1",
+ "mini-create-react-context": "^0.3.0",
+ "path-to-regexp": "^1.7.0",
+ "prop-types": "^15.6.2",
+ "react-is": "^16.6.0",
+ "tiny-invariant": "^1.0.2",
+ "tiny-warning": "^1.0.0"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "path-to-regexp": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
+ "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
+ "requires": {
+ "isarray": "0.0.1"
+ }
+ }
+ }
+ },
+ "react-router-dom": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.0.1.tgz",
+ "integrity": "sha512-zaVHSy7NN0G91/Bz9GD4owex5+eop+KvgbxXsP/O+iW1/Ln+BrJ8QiIR5a6xNPtrdTvLkxqlDClx13QO1uB8CA==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "history": "^4.9.0",
+ "loose-envify": "^1.3.1",
+ "prop-types": "^15.6.2",
+ "react-router": "5.0.1",
+ "tiny-invariant": "^1.0.2",
+ "tiny-warning": "^1.0.0"
+ }
+ },
"react-scripts": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.0.1.tgz",
@@ -10252,6 +10371,13 @@
"webpack-dev-server": "3.2.1",
"webpack-manifest-plugin": "2.0.4",
"workbox-webpack-plugin": "4.2.0"
+ },
+ "dependencies": {
+ "dotenv": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz",
+ "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w=="
+ }
}
},
"read-pkg": {
@@ -10575,6 +10701,11 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
},
+ "resolve-pathname": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz",
+ "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg=="
+ },
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -11685,6 +11816,16 @@
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
},
+ "tiny-invariant": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.0.4.tgz",
+ "integrity": "sha512-lMhRd/djQJ3MoaHEBrw8e2/uM4rs9YMNk0iOr8rHQ0QdbM7D4l0gFl3szKdeixrlyfm9Zqi4dxHCM2qVG8ND5g=="
+ },
+ "tiny-warning": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.2.tgz",
+ "integrity": "sha512-rru86D9CpQRLvsFG5XFdy0KdLAvjdQDyZCsRcuu60WtzFylDM3eAWSxEVz5kzL2Gp544XiUvPbVKtOA/txLi9Q=="
+ },
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -12122,6 +12263,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "value-equal": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz",
+ "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw=="
+ },
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
diff --git a/package.json b/package.json
index e7e4a7c62..2b6042543 100644
--- a/package.json
+++ b/package.json
@@ -3,8 +3,12 @@
"version": "0.1.0",
"private": true,
"dependencies": {
+ "axios": "^0.19.0",
+ "bootstrap": "^4.3.1",
+ "dotenv": "^8.0.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
+ "react-router-dom": "^5.0.1",
"react-scripts": "3.0.1"
},
"scripts": {
@@ -12,5 +16,17 @@
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
+ },
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
}
}
diff --git a/src/App.css b/src/App.css
index c5c6e8a68..fc050e4dc 100644
--- a/src/App.css
+++ b/src/App.css
@@ -1,28 +1,69 @@
-.App {
- text-align: center;
+.nav {
+ font-family: 'Nunito', sans-serif;
+ margin-block-end: 1em;
+ justify-content: flex-start;
+}
+
+.nav-item {
+ padding: 10px;
+ font-size: 1.25em;
}
-.App-logo {
- animation: App-logo-spin infinite 20s linear;
- height: 80px;
+
+
+#search-button {
+ border: 1px solid white;
}
-.App-header {
- background-color: #222;
- height: 150px;
- padding: 20px;
+.nav-link {
color: white;
}
-.App-title {
- font-size: 1.5em;
+.nav-link:hover {
+ background-color: white;
+ color: #007bff;
+ border-radius: 0.25rem;
+}
+
+section {
+ margin-top: 1rem;
+ font-family: 'Nunito', sans-serif;
+}
+
+.checkout {
+ margin-top: 1rem;
+ margin-left: 2rem;
+ list-style-type: none;
+ width: 400px;
+ border: 1px solid lightgrey;
+ padding-top: 2rem;
+ padding-bottom: 2rem;
+ border-radius: 0.25em;
+ font-family: 'Nunito', sans-serif;
+ font-size: 1.25em;
+}
+
+li {
+ margin-bottom: 1.5rem;
+}
+
+.homepage {
+ text-align: center;
+ font-family: 'Nunito', sans-serif;
+}
+
+.homepage__title {
+ font-weight: bolder;
+}
+
+.homepage-p {
+ font-size: 1.5rem;
}
-.App-intro {
- font-size: large;
+img {
+ border-radius: 0.25rem;
}
-@keyframes App-logo-spin {
- from { transform: rotate(0deg); }
- to { transform: rotate(360deg); }
+.error {
+ margin-top: 5rem;
}
diff --git a/src/App.js b/src/App.js
index 203067e4d..314f09090 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,21 +1,142 @@
import React, { Component } from 'react';
-import logo from './logo.svg';
import './App.css';
+import { BrowserRouter as Router, Route, Link } from "react-router-dom";
+import CustomerList from './components/CustomerList';
+import RentalLibrary from './components/RentalLibrary';
+import Search from './components/Search';
+import axios from 'axios';
class App extends Component {
+ constructor(props) {
+ super(props)
+ this.state = {
+ selectedMovie: "",
+ selectedCustomer: "",
+ movieList: [],
+ customerList: [],
+ message: "",
+ }
+ }
+
+ getCustomers = (customers) => {
+ this.setState( {customerList: customers})
+ }
+
+ onSelectCustomer = (customerId) => {
+ const customer = this.state.customerList.find(customer => customer.id === customerId);
+ this.setState({selectedCustomer: customer});
+ }
+
+ getMovies = (movies) => {
+
+ this.setState( {movieList: movies})
+ }
+
+ onSelectMovie = (movieId) => {
+ const movie = this.state.movieList.find(movie => movie.id === movieId);
+ this.setState({selectedMovie: movie});
+ }
+
+ addMovie = (movie) => {
+ const list = [...this.state.movieList]
+ list.push(movie);
+
+ this.setState({movieList: list});
+ }
+
+ getTitle = () => {
+ const movie = this.state.selectedMovie.title
+ return movie
+ }
+
+ getName = () => {
+ const customer = this.state.selectedCustomer.name
+ return customer
+ }
+
+ checkout = () => {
+ const date = new Date();
+ let sevenDays = date.setDate(date.getDate() + 7)
+ sevenDays = new Date(sevenDays).toISOString()
+ console.log(date)
+ const params = {
+ customer_id: this.state.selectedCustomer.id,
+ title: this.state.selectedMovie.title,
+ due_date: sevenDays
+ }
+ console.log(params.due_date);
+
+ axios.post(`http://localhost:3000/rentals/${this.state.selectedMovie.title}/check-out`, params)
+ .then((response) => {
+ console.log("success");
+ this.setState({
+ message: `Successfully checked out ${this.state.selectedMovie.title}.`
+ })
+ })
+ .catch((error) => {
+ this.setState({
+ message: `${this.state.selectedMovie.title} was not checked out.`
+ });
+ });
+ }
+
render() {
return (
-
-
-
- Welcome to React
-
-
- To get started, edit src/App.js
and save to reload.
-
+
+
+
+
+
+
+ {this.state.message}
+
+
+ Currently Selected:
+
+
+ -
+ Movie: {this.getTitle()}
+
+ -
+ Customer: {this.getName()}
+
+
+
+
+ (
+
+
Welcome to AA Video Rentals
+
Select Customers or Movies at the top to start the rental process!
+
If you don't find the video you are looking for, add a new one by using search.
+

+
+ )}/>
+
+ }
+ />
+ }
+ />
+ }
+ />
+
+
+
);
}
}
export default App;
+
+
diff --git a/src/components/Customer.css b/src/components/Customer.css
new file mode 100644
index 000000000..ed8f5e9cd
--- /dev/null
+++ b/src/components/Customer.css
@@ -0,0 +1,48 @@
+.customer {
+ font-family: 'Nunito', sans-serif;
+ text-align: center;
+ font-weight: bolder;
+}
+
+.card-title {
+ text-align: left;
+}
+
+.content {
+ font-family: 'Nunito', sans-serif;
+ font-size: 2rem;
+ font-weight: bolder;
+}
+
+.card {
+ margin: 5px;
+ width: 30rem;
+}
+
+.card-text {
+ text-align: center;
+ font-size: 1.2rem;
+ font-weight: bold;
+ padding-right: 35px;
+}
+
+.card-text.money {
+ font-size: 1.3rem;
+ text-decoration-line: underline
+}
+
+.customer__info {
+ list-style-type: none;
+}
+
+.select__button {
+ text-align: center;
+}
+
+.select__customer a {
+ color: white;
+}
+
+.select__customer a:hover {
+ color: goldenrod;
+}
diff --git a/src/components/Customer.js b/src/components/Customer.js
new file mode 100644
index 000000000..b7b098f73
--- /dev/null
+++ b/src/components/Customer.js
@@ -0,0 +1,42 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import './Customer.css'
+
+const Customer = (props) => {
+ const selectCustomer = () => {
+ return props.selectCustomerCallback(props.id)
+ }
+
+ return (
+
+
+
+
+ - {props.name}
+ - {props.address}
+ - {props.city}, {props.state}
+ - ${props.account_credit} account credit
+
+
+
+
+
+
+ )
+}
+
+Customer.propTypes = {
+ id:PropTypes.number,
+ name:PropTypes.string,
+ address:PropTypes.string,
+ city:PropTypes.string,
+ state:PropTypes.string,
+ postal:PropTypes.string,
+ phone:PropTypes.string,
+ account_credit:PropTypes.number,
+ selectCustomerCallback: PropTypes.func,
+};
+
+export default Customer;
diff --git a/src/components/CustomerList.js b/src/components/CustomerList.js
new file mode 100644
index 000000000..1c5ccfad5
--- /dev/null
+++ b/src/components/CustomerList.js
@@ -0,0 +1,64 @@
+import React, { Component } from 'react';
+import axios from 'axios';
+import Customer from './Customer'
+import PropTypes from 'prop-types'
+
+class CustomerList extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ customerList: [],
+ }
+ }
+
+ componentDidMount() {
+ axios.get('http://localhost:3000/customers')
+ .then((response) => {
+ this.setState( {customerList: response.data})
+ this.props.getCustomerCallback(this.state.customerList);
+ })
+ .catch((error) => {
+ this.setState({
+ errorMessage: error.message
+ });
+ });
+ }
+
+ selectCustomerCallback = (id) => {
+ this.props.selectCustomerCallback(id);
+ }
+
+ render() {
+ const customers = this.state.customerList.map((customer) => {
+ return
+ });
+
+ return (
+
+
All Customers
+
+ {customers}
+
+
+ )
+ }
+}
+
+CustomerList.propTypes = {
+ selectCustomerCallback: PropTypes.func,
+}
+
+export default CustomerList;
+
+
diff --git a/src/components/Movie.css b/src/components/Movie.css
new file mode 100644
index 000000000..6f6b62613
--- /dev/null
+++ b/src/components/Movie.css
@@ -0,0 +1,50 @@
+.movie {
+ font-family: 'Nunito', sans-serif;
+}
+
+/* .space {
+ display: flex;
+ justify-content: space-around;
+} */
+
+.movie__header {
+ text-align: center;
+ font-weight: bolder;
+}
+
+.movie__title {
+ text-align: center;
+ font-weight: bolder;
+ font-size: 2rem;
+}
+
+.card {
+ margin: 5px;
+ width: 30rem;
+}
+
+.card-text.text {
+ padding-left: 10px;
+ text-align: center;
+ font-size: 1.4rem;
+ font-weight: bolder;
+ text-decoration: underline;
+}
+
+
+.customer__info {
+ list-style-type: none;
+}
+
+.select_button {
+ padding-top: 5px;
+ text-align: center;
+}
+
+.select__movie a {
+ color: white;
+}
+
+.select__movie a:hover {
+ color: goldenrod;
+}
diff --git a/src/components/Movie.js b/src/components/Movie.js
new file mode 100644
index 000000000..9ee5b3f7a
--- /dev/null
+++ b/src/components/Movie.js
@@ -0,0 +1,39 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import "./Movie.css"
+
+
+const Movie = (props) => {
+ const selectMovie = () => {
+ return props.selectMovieCallback(props.id)
+ }
+
+ return (
+
+
+
{props.title}
+

+
+
+
+
+ )
+}
+
+
+Movie.propTypes = {
+ id:PropTypes.number,
+ title:PropTypes.string,
+ overview:PropTypes.string,
+ release_date:PropTypes.string,
+ image_url:PropTypes.string,
+ external_id:PropTypes.number,
+ buttonClassname:PropTypes.string,
+ selectMovieCallback:PropTypes.func,
+};
+
+export default Movie;
diff --git a/src/components/RentalLibrary.css b/src/components/RentalLibrary.css
new file mode 100644
index 000000000..145dd3d9a
--- /dev/null
+++ b/src/components/RentalLibrary.css
@@ -0,0 +1,4 @@
+.row {
+ display: flex;
+ justify-content: space-around;
+}
diff --git a/src/components/RentalLibrary.js b/src/components/RentalLibrary.js
new file mode 100644
index 000000000..84acc0f39
--- /dev/null
+++ b/src/components/RentalLibrary.js
@@ -0,0 +1,66 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import axios from 'axios';
+import Movie from './Movie';
+import './RentalLibrary';
+
+class RentalLibrary extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ movies: [],
+ };
+ }
+
+ componentDidMount() {
+ axios.get('http://localhost:3000/movies')
+ .then((response) => {
+ this.setState( {movies: response.data} );
+ this.props.getMovieCallback(this.state.movies);
+ })
+ .catch((error) => {
+ this.setState({
+ error: error.message
+ });
+ });
+ }
+
+ selectMovieCallback = (id) => {
+ this.props.selectMovieCallback(id);
+ }
+
+ render() {
+ const allRentals = this.state.movies.map((movie) => {
+ return
+
+ });
+
+ return (
+
+
+
Rent Today!
+
+ {allRentals}
+
+
+
+ )
+ }
+}
+
+RentalLibrary.propTypes = {
+ selectMovieCallback:PropTypes.func,
+ getMovieCallback:PropTypes.func,
+};
+
+export default RentalLibrary;
diff --git a/src/components/Result.css b/src/components/Result.css
new file mode 100644
index 000000000..65f0fadb2
--- /dev/null
+++ b/src/components/Result.css
@@ -0,0 +1,46 @@
+ .result {
+ font-family: 'Nunito', sans-serif;
+ }
+
+ .result__header {
+ text-align: center;
+ font-size: 4rem;
+ font-weight: bolder;
+ }
+
+ .result__title {
+ text-align: center;
+ font-weight: bolder;
+ font-size: 3rem;
+ }
+
+ .card {
+ margin: 5px;
+ width: 30rem;
+ }
+
+ .card-text.text {
+ padding-left: 10px;
+ text-align: center;
+ font-size: 1.4rem;
+ font-weight: bolder;
+ text-decoration: underline;
+ }
+
+
+ .customer__info {
+ list-style-type: none;
+ }
+
+ .select_button {
+ padding-top: 5px;
+ text-align: center;
+ }
+
+ .select__result a {
+ color: white;
+ }
+
+ .select__result a:hover {
+ color: goldenrod;
+ }
diff --git a/src/components/Result.js b/src/components/Result.js
new file mode 100644
index 000000000..a9e899a2c
--- /dev/null
+++ b/src/components/Result.js
@@ -0,0 +1,41 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import "./Result.css"
+
+
+const Result = (props) => {
+
+ return (
+
+
+
{props.title}
+

+
+
+
+
+ )
+}
+
+
+Result.propTypes = {
+ id:PropTypes.number,
+ title:PropTypes.string,
+ overview:PropTypes.string,
+ release_date:PropTypes.string,
+ image_url:PropTypes.string,
+ external_id:PropTypes.number,
+ buttonClassname:PropTypes.string,
+ getResultTitleCallback:PropTypes.func,
+};
+
+export default Result;
diff --git a/src/components/Search.css b/src/components/Search.css
new file mode 100644
index 000000000..b2d18d414
--- /dev/null
+++ b/src/components/Search.css
@@ -0,0 +1,30 @@
+.search {
+ text-align: center;
+ font-family: 'Nunito', sans-serif;
+}
+
+.search-space {
+ margin-bottom: 3rem;
+}
+
+.search-label {
+ margin-top: 1em;
+ font-size: 1.4rem;
+}
+
+.search-form-item-label {
+ margin-right: 0.25em;
+}
+
+.search-form-item-form {
+ margin-right: 1em;
+}
+
+.row {
+ display: flex;
+}
+
+.search-movie {
+ font-weight: bolder;
+}
+
diff --git a/src/components/Search.js b/src/components/Search.js
new file mode 100644
index 000000000..121d0dd8b
--- /dev/null
+++ b/src/components/Search.js
@@ -0,0 +1,140 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import axios from 'axios';
+import Result from './Result'
+import Movie from './Movie'
+import "./Search.css"
+import { throwStatement } from '@babel/types';
+
+require('dotenv').config();
+
+class Search extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ result: [],
+ searchTitle: "",
+ errorMessage: "",
+ success: ""
+ }
+ }
+
+ onInputChange = (event) => {
+ const updatedState = {};
+
+ const field = event.target.name;
+ const value = event.target.value;
+
+ updatedState[field] = value;
+ this.setState(updatedState);
+ }
+
+ onSearch = (event) => {
+ event.preventDefault();
+
+ this.searchMovie(this.state.searchTitle);
+
+ this.setState({
+ searchTitle: "",
+ });
+ }
+
+ addMovieCallback = (movie) => {
+ const movieData = {
+ title: movie.title,
+ overview: movie.overview,
+ release_date: movie.release_date,
+ image_url: movie.image_url,
+ external_id: movie.external_id,
+ inventory: 15
+ }
+
+ axios.post('http://localhost:3000/movies', movieData)
+
+ .then((response) => {
+ console.log(response.data)
+ this.setState({success: "This movies was added to the rental library"})
+
+ console.log(`successfully added ${response.data.title}`)
+ })
+ .catch((error) => {
+ this.setState({errorMessage: error.message})
+ })
+
+
+ }
+
+ componentDidMount () {
+ this.searchMovie();
+ };
+
+ searchMovie = (searchTitle) => {
+ const URL = `http://localhost:3000/movies?query=${searchTitle}`
+
+ axios.get(URL)
+ .then((response) => {
+ const movies = response.data.map((movie, i) => {
+ return {
+ id: i,
+ key: i,
+ title: movie.title,
+ overview: movie.overview,
+ release_date: movie.release_date,
+ image_url: movie.image_url,
+ external_id: movie.external_id,
+ }
+ })
+ this.setState({
+ result: movies,
+ });
+ })
+ .catch((error) => {
+ this.setState({
+ errorMessage: error.message,
+ })
+ })
+ }
+
+ render() {
+ const results = this.state.result.map((movie, i) => {
+ return
+ })
+ return (
+
+ )};
+ }
+
+ export default Search;
+
diff --git a/src/index.css b/src/index.css
index b4cc7250b..287c49a28 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,3 +1,5 @@
+@import url('https://fonts.googleapis.com/css?family=Nunito&display=swap');
+
body {
margin: 0;
padding: 0;
diff --git a/src/index.js b/src/index.js
index fae3e3500..cb6856b7c 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
+import 'bootstrap/dist/css/bootstrap.css';
ReactDOM.render(
, document.getElementById('root'));
registerServiceWorker();