diff --git a/package-lock.json b/package-lock.json
index 79f52b34f..cdd05bc6b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -434,6 +434,15 @@
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
"integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w=="
},
+ "axios": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
+ "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
+ "requires": {
+ "follow-redirects": "1.5.0",
+ "is-buffer": "1.1.6"
+ }
+ },
"axobject-query": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-0.1.0.tgz",
@@ -4657,6 +4666,28 @@
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0="
},
+ "history": {
+ "version": "4.7.2",
+ "resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz",
+ "integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==",
+ "requires": {
+ "invariant": "2.2.4",
+ "loose-envify": "1.3.1",
+ "resolve-pathname": "2.2.0",
+ "value-equal": "0.4.0",
+ "warning": "3.0.0"
+ },
+ "dependencies": {
+ "warning": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
+ "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
+ "requires": {
+ "loose-envify": "1.3.1"
+ }
+ }
+ }
+ },
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -4667,6 +4698,11 @@
"minimalistic-crypto-utils": "1.0.1"
}
},
+ "hoist-non-react-statics": {
+ "version": "2.5.5",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
+ "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw=="
+ },
"home-or-tmp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
@@ -8809,6 +8845,33 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-4.0.0.tgz",
"integrity": "sha512-FlsPxavEyMuR6TjVbSSywovXSEyOg6ZDj5+Z8nbsRl9EkOzAhEIcS+GLoQDC5fz/t9suhUXWmUrOBrgeUvrMxw=="
},
+ "react-router": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz",
+ "integrity": "sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==",
+ "requires": {
+ "history": "4.7.2",
+ "hoist-non-react-statics": "2.5.5",
+ "invariant": "2.2.4",
+ "loose-envify": "1.3.1",
+ "path-to-regexp": "1.7.0",
+ "prop-types": "15.6.1",
+ "warning": "4.0.1"
+ }
+ },
+ "react-router-dom": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.3.1.tgz",
+ "integrity": "sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA==",
+ "requires": {
+ "history": "4.7.2",
+ "invariant": "2.2.4",
+ "loose-envify": "1.3.1",
+ "prop-types": "15.6.1",
+ "react-router": "4.3.1",
+ "warning": "4.0.1"
+ }
+ },
"react-scripts": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-1.1.4.tgz",
@@ -9231,6 +9294,11 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
"integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY="
},
+ "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",
@@ -10564,6 +10632,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",
@@ -10600,6 +10673,14 @@
"makeerror": "1.0.11"
}
},
+ "warning": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.1.tgz",
+ "integrity": "sha512-rAVtTNZw+cQPjvGp1ox0XC5Q2IBFyqoqh+QII4J/oguyu83Bax1apbo2eqB8bHRS+fqYUBagys6lqUoVwKSmXQ==",
+ "requires": {
+ "loose-envify": "1.3.1"
+ }
+ },
"watch": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/watch/-/watch-0.10.0.tgz",
diff --git a/package.json b/package.json
index 951a38e2f..a7160dab9 100644
--- a/package.json
+++ b/package.json
@@ -3,8 +3,11 @@
"version": "0.1.0",
"private": true,
"dependencies": {
+ "axios": "^0.18.0",
"react": "^16.4.1",
"react-dom": "^16.4.1",
+ "react-router": "^4.3.1",
+ "react-router-dom": "^4.3.1",
"react-scripts": "1.1.4"
},
"scripts": {
@@ -13,4 +16,4 @@
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
-}
\ No newline at end of file
+}
diff --git a/src/App.css b/src/App.css
index c5c6e8a68..a777d2e08 100644
--- a/src/App.css
+++ b/src/App.css
@@ -1,5 +1,7 @@
.App {
text-align: center;
+ background-color: #00064d;
+ color: #bbbbbb;
}
.App-logo {
@@ -15,7 +17,9 @@
}
.App-title {
- font-size: 1.5em;
+ font-size: 2em;
+ margin-top: 1em;
+
}
.App-intro {
@@ -26,3 +30,22 @@
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
+
+table {
+ border: 2px solid black;
+ padding: 10px;
+ margin: 20px;
+ background-color: lightyellow;
+ width: 95%;
+ text-align: left;
+}
+
+.ul {
+ display: flex;
+ justify-content: space-around;
+ list-style-type: none;
+ border: 1px ;
+ margin-top: 5em;
+
+
+}
diff --git a/src/App.js b/src/App.js
index 203067e4d..7986d570d 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,19 +1,100 @@
import React, { Component } from 'react';
-import logo from './logo.svg';
import './App.css';
+import FormPage from './components/FormPage';
+import Home from './components/Home';
+import Search from './components/Search';
+import Status from './components/Status';
+import { BrowserRouter as Router, Route, Link } from "react-router-dom";
+
+
class App extends Component {
+
+ constructor() {
+ super();
+
+ this.state = {
+
+ movieTitle: '',
+ customerId: '',
+ customerName: '',
+
+ status: {
+ message: 'loaded the page',
+ type: 'success'
+ }
+ }
+ }
+
+ updateStatus = (message, type) => {
+ this.setState({
+ status: {
+ message: message,
+ type: type
+ }
+ })
+ }
+
+ custHandler = (customerInfo) => {
+ console.log('in custHandler');
+ console.log(customerInfo);
+ this.setState({
+ customerId: customerInfo.id,
+ customerName: customerInfo.name
+ });
+ }
+
+ movHandler = (movieTitle) => {
+ console.log('in movHandler');
+ console.log(movieTitle);
+ this.setState({
+ movieTitle: movieTitle
+ });
+ }
+
render() {
return (
-
+
+
);
}
}
diff --git a/src/components/AddToLibraryForm.js b/src/components/AddToLibraryForm.js
new file mode 100644
index 000000000..1d5c00fdf
--- /dev/null
+++ b/src/components/AddToLibraryForm.js
@@ -0,0 +1,50 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import axios from 'axios';
+
+class AddToLibraryForm extends Component {
+
+ static propTypes = {
+ title: PropTypes.string.isRequired
+ }
+
+ constructor(props) {
+ super();
+
+ this.state = {
+ title: props.title,
+ overview: props.overview,
+ release_date: props.release_date,
+ image_url: props.image_url,
+ };
+
+ }
+
+ onFormSubmit = (event) => {
+ let URL = `http://localhost:3000/movies?title=${this.state.title}&overview=${this.state.overview}&release_date=${this.state.release_date}&image_url=${this.state.image_url}`
+ event.preventDefault();
+ axios.post(URL)
+ .then((response)=> {
+ })
+ .catch((error) => {
+ // this.props.updateStatusCallback(error.message, 'error');
+
+ });
+ }
+
+ render(){
+
+ return(
+
+ )
+ }
+}
+
+export default AddToLibraryForm;
diff --git a/src/components/Customer.js b/src/components/Customer.js
new file mode 100644
index 000000000..99f48fed2
--- /dev/null
+++ b/src/components/Customer.js
@@ -0,0 +1,48 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+class Customer extends Component {
+
+ static propTypes = {
+ customerId: PropTypes.string,
+ name: PropTypes.string,
+ phone: PropTypes.string,
+ checkedOut: PropTypes.number,
+ rentMovie: PropTypes.func
+ }
+
+ onClickHandler = (event) => {
+ let customerInfo = event.target;
+ this.props.rentMovie(customerInfo);
+ }
+
+ render() {
+
+ let customerInfo = {};
+ customerInfo["customerId"] = this.props.customerId;
+ customerInfo["name"] = this.props.name;
+
+ return(
+
+
+
+ {this.props.name}
+
+
+
+ {this.props.phone}
+
+
+
+ {this.props.checkedOut}
+
+
+
+
+
+
+ )
+ }
+}
+
+export default Customer;
diff --git a/src/components/Customers.js b/src/components/Customers.js
new file mode 100644
index 000000000..33c6f60ea
--- /dev/null
+++ b/src/components/Customers.js
@@ -0,0 +1,68 @@
+import React, { Component } from 'react';
+import axios from 'axios';
+import Customer from './Customer';
+import RentalForm from './RentalForm';
+import PropTypes from 'prop-types';
+
+class Customers extends Component {
+
+ static propTypes = {
+ rentalCallback: PropTypes.func,
+ }
+
+ constructor() {
+ super();
+
+ this.state = {
+ customers: [],
+ };
+ }
+
+ componentDidMount() {
+ const CUSTOMERS_URL = 'http://localhost:3000/customers'
+
+ axios.get(CUSTOMERS_URL)
+ .then((response) => {
+
+ this.setState({customers: response.data});
+ })
+ .catch((error) => {
+
+ // this.props.updateStatusCallback(error.message, 'error');
+ });
+ }
+
+ rentalCallback = (customerInfo) => {
+ this.props.rentalCallback(customerInfo);
+ }
+
+ render() {
+
+ const customers = this.state.customers.map((customer, index) => {
+
+ return(
+
+
+
+
+ < Customer key={index}
+ customerId={customer.id}
+ name={customer.name}
+ phone={customer.phone}
+ rentMovie={this.rentalCallback}
+ />
+
+
+ )
+ });
+
+ return(
+
+
+ {customers}
+
+ )
+ }
+}
+
+export default Customers;
diff --git a/src/components/FormPage.js b/src/components/FormPage.js
new file mode 100644
index 000000000..90758adfb
--- /dev/null
+++ b/src/components/FormPage.js
@@ -0,0 +1,29 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import RentalForm from './RentalForm';
+
+class CustomersPage extends Component {
+
+ static propTypes = {
+ movieTitle: PropTypes.string,
+ customerId: PropTypes.string,
+ customerName: PropTypes.string,
+ selectedMovHandler: PropTypes.func,
+ selectedCustHandler: PropTypes.func,
+ hideCustomers: PropTypes.bool,
+ hideMovies: PropTypes.bool
+ }
+
+ render() {
+ return(
+
+
CUSTOMERS PAGE
+
+
+ )
+ }
+}
+
+
+
+export default CustomersPage;
diff --git a/src/components/Home.js b/src/components/Home.js
new file mode 100644
index 000000000..1190e8b7e
--- /dev/null
+++ b/src/components/Home.js
@@ -0,0 +1,15 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+class Home extends Component {
+
+ render() {
+ return(
+ Click the links above to navigate the site.
+ )
+ }
+}
+
+
+
+export default Home;
diff --git a/src/components/Movie.js b/src/components/Movie.js
new file mode 100644
index 000000000..c92fe750c
--- /dev/null
+++ b/src/components/Movie.js
@@ -0,0 +1,79 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import AddToLibraryForm from './AddToLibraryForm';
+
+
+class Movie extends Component {
+ static propTypes = {
+ title: PropTypes.string.isRequired,
+ overview: PropTypes.string,
+ release_date: PropTypes.string,
+ image_url: PropTypes.string.isRequired,
+ inLibrary: PropTypes.bool,
+ rentMovie: PropTypes.func
+ }
+
+ onClickHandler = (event) => {
+ console.log('made it to movie clickhandler');
+ console.log(this.props.rentMovie);
+ let movieTitle = event.target.name;
+ console.log(movieTitle);
+ this.props.rentMovie(movieTitle);
+ }
+
+
+ render() {
+
+ const displayButton = () => {
+ if (this.props.inLibrary) {
+ return ()
+ }else{
+
+ return(
+
+ )
+
+ };
+ }
+
+ const display = displayButton();
+
+ return(
+
+
+
+
+
+ {this.props.title} |
+
+
+
+
+
+ |
+
+
+
+ Release: |
+ {this.props.release_date} |
+
+
+
+ Overview: |
+ {this.props.overview} |
+
+
+
+
+ {display}
+
+
+
+
+ )
+
+ }
+
+}
+
+export default Movie;
diff --git a/src/components/MovieLibrary.css b/src/components/MovieLibrary.css
new file mode 100644
index 000000000..7231dcd9b
--- /dev/null
+++ b/src/components/MovieLibrary.css
@@ -0,0 +1,3 @@
+.ul {
+ list-style: "none;"
+}
diff --git a/src/components/MovieLibrary.js b/src/components/MovieLibrary.js
new file mode 100644
index 000000000..bd0c1ac5b
--- /dev/null
+++ b/src/components/MovieLibrary.js
@@ -0,0 +1,73 @@
+import React, { Component } from 'react';
+import Movie from './Movie';
+import axios from 'axios';
+import PropTypes from 'prop-types'
+import './MovieLibrary.js';
+import '../App.css';
+
+class MovieLibrary extends Component {
+
+ static propTypes = {
+ rentalCallback: PropTypes.isRequired
+ }
+
+ constructor() {
+ super();
+
+ this.state = {
+ movies: [],
+
+ };
+ }
+
+ componentDidMount() {
+ const MOVIE_URL = 'http://localhost:3000/movies'
+
+ axios.get(MOVIE_URL)
+ .then((response) => {
+
+ this.setState({movies: response.data});
+ })
+ .catch((error) => {
+
+ // this.props.updateStatusCallback(error.message, 'error');
+ });
+ }
+
+ movieCallback = (movieTitle) => {
+ console.log('made it to the Library');
+ console.log(movieTitle);
+ console.log(this.props.rentalCallback(movieTitle));
+
+ this.props.rentalCallback(movieTitle);
+ }
+
+
+ render() {
+
+ const movies = this.state.movies.map((movie, index) => {
+
+ return(
+
+ < Movie key={index}
+ title={movie.title}
+ overview={movie.overview}
+ release_date={movie.release_date}
+ image_url={movie.image_url}
+ inLibrary={false}
+ rentMovie={this.movieCallback}/>
+
+ )
+ });
+
+ return(
+
+ )
+
+ }
+
+}
+
+export default MovieLibrary;
diff --git a/src/components/MovieLibraryPage.js b/src/components/MovieLibraryPage.js
new file mode 100644
index 000000000..e86132d44
--- /dev/null
+++ b/src/components/MovieLibraryPage.js
@@ -0,0 +1,26 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import RentalForm from './RentalForm';
+
+class MovieLibraryPage extends Component {
+
+ static propTypes = {
+ movieTitle: PropTypes.string,
+ customerId: PropTypes.string,
+ customerName: PropTypes.string,
+ selectedMovHandler: PropTypes.func,
+ selectedCustHandler: PropTypes.func
+ }
+
+ render() {
+ return(
+
+
MOV LIBRARY PAGE
+
+
+ )
+ }
+}
+
+
+export default MovieLibraryPage;
diff --git a/src/components/RentalForm.js b/src/components/RentalForm.js
new file mode 100644
index 000000000..319068ed5
--- /dev/null
+++ b/src/components/RentalForm.js
@@ -0,0 +1,90 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import axios from 'axios';
+import Customers from './Customers';
+import MovieLibrary from './MovieLibrary';
+
+class RentalForm extends Component {
+
+ static propTypes = {
+ movieTitle: PropTypes.string,
+ customerId: PropTypes.string,
+ customerName: PropTypes.string,
+ hideCustomers: PropTypes.bool,
+ hideMovies: PropTypes.bool,
+ selectedMovHandler: PropTypes.func,
+ selectedCustHandler: PropTypes.func
+ }
+
+ constructor(props) {
+ super();
+
+ this.state = {
+ movieTitle: props.movieTitle,
+ customerId: props.customerId,
+ customerName: props.customerName,
+ hideCustomers: props.hideCustomers,
+ hideMovies: props.hideMovies
+ };
+
+ }
+
+ selectedCustomer = (customerInfo) => {
+ this.props.selectedCustHandler(customerInfo);
+ }
+
+ selectedMovie = (movieTitle) => {
+ this.props.selectedMovHandler(movieTitle);
+ }
+
+ onFormSubmit = (event) => {
+ event.preventDefault();
+ console.log('in onFormSubmit');
+ console.log(event.target);
+
+ let movieTitle = this.state.movieTitle;
+ let customerId = this.state.customerId;
+
+ let date = new Date();
+ date.setDate(date.getDate() + 7);
+
+ const RENTAL_URL = `http://localhost:3000/rentals/${movieTitle}/check-out`
+
+ axios.post(RENTAL_URL, {
+ title: movieTitle,
+ customer_id: customerId,
+ due_date: date
+ })
+ .then((response) => {
+
+ console.log(response);
+ })
+ .catch((error) => {
+
+ // this.props.updateStatusCallback(error.message, 'error');
+ });
+ }
+
+ render(){
+
+ return(
+
+
+
+ )
+ }
+}
+
+export default RentalForm;
diff --git a/src/components/Search.js b/src/components/Search.js
new file mode 100644
index 000000000..925e2168d
--- /dev/null
+++ b/src/components/Search.js
@@ -0,0 +1,65 @@
+import React, { Component } from 'react';
+import axios from 'axios';
+import SearchForm from './SearchForm';
+import RentalForm from './RentalForm';
+import Movie from './Movie';
+
+class Search extends Component {
+
+ constructor() {
+ super();
+
+ this.state = {
+ searchResults: [],
+ };
+
+ }
+
+ processSearchTerm = (search) => {
+ const MOVIE_URL = 'http://localhost:3000/movies'
+
+ let customURL = `${MOVIE_URL}?query=${search.searchTerm}`
+
+ axios.get(customURL)
+ .then((response) => {
+ console.log(response);
+
+ this.setState({searchResults: response.data});
+ })
+ .catch((error) => {
+ // this.props.updateStatusCallback(error.message, 'error');
+ });
+ }
+
+ render() {
+
+ const searchResults = this.state.searchResults.map((movie, index) => {
+
+ return (
+ < Movie key={index}
+ title={movie.title}
+ overview={movie.overview}
+ release_date={movie.release_date}
+ image_url={movie.image_url}
+ inLibrary={true}/>
+ )
+ });
+
+ return(
+
+
+
+
SEARCH JS
+
+
+
+
+
+ {searchResults}
+
+
+ )
+ }
+}
+
+export default Search;
diff --git a/src/components/SearchForm.js b/src/components/SearchForm.js
new file mode 100644
index 000000000..e2e078721
--- /dev/null
+++ b/src/components/SearchForm.js
@@ -0,0 +1,51 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+class SearchForm extends Component {
+
+ static propTypes = {
+ searchCallback: PropTypes.func.isRequired
+ }
+
+ constructor() {
+ super();
+
+ this.state = {
+ searchTerm: '',
+ };
+
+ }
+
+ onInputChange = (event) => {
+ let enteredTerm = {};
+ enteredTerm[event.target.name] = event.target.value;
+ this.setState(enteredTerm);
+
+ console.log('term');
+ console.log(event.target);
+ }
+
+ onFormSubmit = (event) => {
+ event.preventDefault();
+ this.props.searchCallback(this.state);
+
+ this.setState({
+ searchTerm: '',
+ });
+ }
+
+ render() {
+
+ return(
+
+
+
+
+ )
+ }
+}
+
+export default SearchForm;
diff --git a/src/components/Status.js b/src/components/Status.js
new file mode 100644
index 000000000..c879db132
--- /dev/null
+++ b/src/components/Status.js
@@ -0,0 +1,21 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+class Status extends React.Component {
+
+ static propTypes ={
+ message: PropTypes.string,
+ type: PropTypes.string
+ }
+
+ render() {
+ return (
+
+ );
+ }
+
+}
+
+export default Status;
diff --git a/src/index.css b/src/index.css
index b4cc7250b..4fe70f8e9 100644
--- a/src/index.css
+++ b/src/index.css
@@ -3,3 +3,7 @@ body {
padding: 0;
font-family: sans-serif;
}
+
+ul {
+ list-style: "none;"
+}