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 ( -
-
- logo -

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.

+ movies +
+ )}/> + + } + /> + } + /> + } + /> +
+
+
); } } 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}

+ this is an image +
+
{props.overview}
+
+
+ +
+
+
+ ) +} + + +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}

+ this is an image +
+
{props.overview}
+
+ +
+
+ ) +} + + +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 ( +
+
+
+

Search for new Movies

+
+
+ + + + +
{this.state.success}
+
+ + +
+
+ {results} +
+
+ )}; + } + + 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();