diff --git a/package-lock.json b/package-lock.json index 79f52b34f..140e58626 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,58 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-4.0.0.tgz", "integrity": "sha512-FlsPxavEyMuR6TjVbSSywovXSEyOg6ZDj5+Z8nbsRl9EkOzAhEIcS+GLoQDC5fz/t9suhUXWmUrOBrgeUvrMxw==" }, + "react-marquee": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/react-marquee/-/react-marquee-1.0.0.tgz", + "integrity": "sha512-AXHGGWdK+BBhKln/ysXD1CLV6pdv9LDm0beoyQ+RYI8FO2PzqwGqDYrS6ssH3TvYytiLCxY0pIxUGGXNn1f/gg==", + "requires": { + "prop-types": "15.6.1" + } + }, + "react-marquee-double": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/react-marquee-double/-/react-marquee-double-0.1.8.tgz", + "integrity": "sha512-qRdZ8q6EZg6y8GI50bshjcTTD5J7omvNnkxF6HwJK1CGkNBvNLchQUjA1MQ7c37GUv1Oh6ACwoDJ4o++rvBrsg==", + "requires": { + "prop-types": "15.6.1" + } + }, + "react-meta-tags": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/react-meta-tags/-/react-meta-tags-0.4.1.tgz", + "integrity": "sha512-bY5PcuFsoAc4HHYOMcMIOgQgPG7gXBg/5pDrPsPQozYQrFqOCpQId5UUTrq9BK2jvKWDgD30Du3AgWnSKa2jSA==", + "requires": { + "babel-runtime": "6.26.0", + "prop-types": "15.6.1" + } + }, + "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", @@ -8870,6 +8958,14 @@ } } }, + "react-text-marquee": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-text-marquee/-/react-text-marquee-1.0.1.tgz", + "integrity": "sha1-b6wWpozu67iylAMIjkVBzdbtfhM=", + "requires": { + "prop-types": "15.6.1" + } + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -9231,6 +9327,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 +10665,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 +10706,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..22b56aa71 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,15 @@ "version": "0.1.0", "private": true, "dependencies": { + "axios": "^0.18.0", "react": "^16.4.1", "react-dom": "^16.4.1", - "react-scripts": "1.1.4" + "react-marquee": "^1.0.0", + "react-marquee-double": "^0.1.8", + "react-meta-tags": "^0.4.1", + "react-router-dom": "^4.3.1", + "react-scripts": "1.1.4", + "react-text-marquee": "^1.0.1" }, "scripts": { "start": "react-scripts start", @@ -13,4 +19,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..d2112b91f 100644 --- a/src/App.css +++ b/src/App.css @@ -26,3 +26,7 @@ from { transform: rotate(0deg); } to { transform: rotate(360deg); } } + +body { + background-color: #2067B2; +} diff --git a/src/App.js b/src/App.js index 203067e4d..06236fa97 100644 --- a/src/App.js +++ b/src/App.js @@ -1,19 +1,11 @@ import React, { Component } from 'react'; -import logo from './logo.svg'; import './App.css'; +import VideoStore from './components/VideoStore' class App extends Component { render() { return ( -
-
- logo -

Welcome to React

-
-

- To get started, edit src/App.js and save to reload. -

-
+ ); } } diff --git a/src/components/Customer.css b/src/components/Customer.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/Customer.js b/src/components/Customer.js new file mode 100644 index 000000000..1c0b334d5 --- /dev/null +++ b/src/components/Customer.js @@ -0,0 +1,16 @@ +import React, { Component } from 'react'; +import './Customer.css'; + +const Customer = (props) => { + // {"id":1,"name":"Shelley Rocha","registered_at":"2015-04-29T14:54:14.000Z","address":"Ap #292-5216 Ipsum Rd.","city":"Hillsboro","state":"OR","postal_code":"24309","phone":"(322) 510-8695","account_credit":13.15,"movies_checked_out_count":0} + return ( +
+
{props.customer.name} (Checked out: {props.customer.movies_checked_out_count})
+
{props.customer.address}
+
{props.customer.city} {props.customer.state} {props.customer.postal_code}
+
{props.customer.phone}
+
+ ); +} + +export default Customer; diff --git a/src/components/CustomerList.css b/src/components/CustomerList.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/CustomerList.js b/src/components/CustomerList.js new file mode 100644 index 000000000..e89c15263 --- /dev/null +++ b/src/components/CustomerList.js @@ -0,0 +1,59 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import axios from 'axios'; + +import './CustomerList.css'; +import Customer from './Customer' + +class CustomerList extends Component { + constructor() { + super(); + this.state = { + customers: [], + }; + } + + componentDidMount() { + this.props.setStatus('Loading customers...', 'pending'); + axios.get(`${this.props.url}/customers`) + .then( (response) => { + console.log( response.data ); + this.setState({ + customers: response.data + }); + this.props.setStatus(`Loaded ${response.data.length} customers`, 'success'); + } ) + .catch( (error) => { + this.props.setStatus(`Failed to load customers: ${error.message}`, 'error'); + console.log("got to the error"); + console.log(error); + } ); + } + + onClickSelect(e, customer) { + this.props.selectCustomerCallback(customer); + } + + render () { + const customers = this.state.customers.map((customer, index) => { + return ( +
+ +
+
+ ) + }) + return ( +
+ {customers} +
+ ); + } +} + +CustomerList.propTypes = { + url: PropTypes.string.isRequired, + selectCustomerCallback: PropTypes.func.isRequired, +}; + +export default CustomerList; diff --git a/src/components/FeaturedFilms.css b/src/components/FeaturedFilms.css new file mode 100644 index 000000000..cb75e5590 --- /dev/null +++ b/src/components/FeaturedFilms.css @@ -0,0 +1,19 @@ +h2 { + text-align: center; + margin-bottom: 50px; +} + +.features-container { + display: grid; + /*grid-template-columns: 1fr 1fr 1fr;*/ + /*grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));*/ + grid-template-columns: repeat(auto-fit, 186px); + grid-template-rows: auto; + justify-items: center; + justify-content: space-evenly; +} + +.grid-item { + justify-self: center; + align-items: center; +} diff --git a/src/components/FeaturedFilms.js b/src/components/FeaturedFilms.js new file mode 100644 index 000000000..a9d18d3a2 --- /dev/null +++ b/src/components/FeaturedFilms.js @@ -0,0 +1,61 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import axios from 'axios'; +import './FeaturedFilms.css'; +import Movie from './Movie' + + +class FeaturedFilms extends Component { + constructor() { + super(); + this.state = { + movies: [], + }; + } + + componentDidMount() { + axios.get(`${this.props.url}/movies`) + .then( (response) => { + console.log( response.data ); + this.setState({ + movies: response.data + }); + } ) + .catch( (error) => { + this.props.setStatus(`Failed to load movies: ${error.message}`, 'success'); + }); + } + + onClickSelect(e, movie) { + this.props.selectMovieCallback(movie); + e.preventDefault(); + } + + render () { + let movies = this.state.movies.map((movie, index) => { + return ( +
+
+ +
+ +
+ ) + }) + movies = movies.sort(() => .5 - Math.random()); + movies = movies.slice(0,3); + return ( +
+ {movies} +
+ ); + } +} + +FeaturedFilms.propTypes = { + // url: PropTypes.string.isRequired, + // selectMovieCallback: PropTypes.func.isRequired, +}; + +export default FeaturedFilms; diff --git a/src/components/Movie.css b/src/components/Movie.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/Movie.js b/src/components/Movie.js new file mode 100644 index 000000000..b97c322bb --- /dev/null +++ b/src/components/Movie.js @@ -0,0 +1,17 @@ +import React, { Component } from 'react'; +import './Movie.css'; + +const Movie = (props) => { + // {"id":1,"title":"Psycho","overview":"When larcenous real estate clerk Marion Crane goes on the lam with a wad of cash and hopes of starting a new life, she ends up at the notorious Bates Motel, where manager Norman Bates cares for his housebound mother. The place seems quirky, but fineā€¦ until Marion decides to take a shower.","release_date":"1960-06-16","image_url":"https://image.tmdb.org/t/p/w185/81d8oyEFgj7FlxJqSDXWr8JH8kV.jpg","external_id":539} + + return ( +
+
{props.movie.title}/
+
{props.movie.title}
+
{props.movie.overview}
+
{props.movie.release_date}
+
+ ); +} + +export default Movie; diff --git a/src/components/RentalLibrary.css b/src/components/RentalLibrary.css new file mode 100644 index 000000000..5b409abba --- /dev/null +++ b/src/components/RentalLibrary.css @@ -0,0 +1,18 @@ +button { + padding: 5px; + margin: 5px; +} + +.grid-container { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(186px, 1fr)); + /*grid-template-columns: 1fr 1fr 1fr (auto-fit, 186px);*/ + /*grid-template-columns: repeat(auto-fit, 186px);*/ + grid-column-gap: 25px; + grid-row-gap: 25px; +} + +.grid-item { + justify-self: center; + align-items: center; +} diff --git a/src/components/RentalLibrary.js b/src/components/RentalLibrary.js new file mode 100644 index 000000000..d905cdea6 --- /dev/null +++ b/src/components/RentalLibrary.js @@ -0,0 +1,63 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import axios from 'axios'; + +import './RentalLibrary.css'; +import Movie from './Movie' + +class RentalLibrary extends Component { + constructor() { + super(); + this.state = { + movies: [], + }; + } + + componentDidMount() { + this.props.setStatus('Loading library...', 'pending'); + axios.get(`${this.props.url}/movies`) + .then( (response) => { + this.props.setStatus(`Successfully loaded ${response.data.length} movies from the rental library`, 'success'); + console.log( response.data ); + this.setState({ + movies: response.data + }); + } ) + .catch( (error) => { + this.props.setStatus(`Failed to load movies: ${error.message}`, 'success'); + console.log("got to the error"); + console.log(error); + }); + } + + onClickSelect(e, movie) { + this.props.selectMovieCallback(movie); + e.preventDefault(); + } + + render () { + let movies = this.state.movies.map((movie, index) => { + return ( +
+
+ +
+ +
+ ) + }) + return ( +
+ {movies} +
+ ); + } +} + +RentalLibrary.propTypes = { + url: PropTypes.string.isRequired, + selectMovieCallback: PropTypes.func.isRequired, +}; + +export default RentalLibrary; diff --git a/src/components/SearchForm.css b/src/components/SearchForm.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/SearchForm.js b/src/components/SearchForm.js new file mode 100644 index 000000000..c8d7f2dae --- /dev/null +++ b/src/components/SearchForm.js @@ -0,0 +1,70 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import axios from 'axios'; +import './SearchForm.css'; +import SearchResults from './SearchResults' + + +class SearchForm extends Component { + constructor() { + super(); + this.state = { + title: '', + results: [], + }; + } + + onFieldChange = (event) => { + const fieldName = event.target.name; + const fieldValue = event.target.value + const updateState = {}; + updateState[fieldName] = fieldValue; + this.setState(updateState); + } + + onFormSubmit = (event) => { + event.preventDefault(); + this.props.setStatus(`Searching for "${this.state.title}"...`, 'pending'); + console.log(`searching for ${this.state.title}`); + axios.get(`${this.props.url}/movies?query=${this.state.title}`) + .then((response) => { + this.props.setStatus(`Found ${response.data.length} results for ${this.state.title}`, 'success'); + console.log(response.data); + this.setState({results: response.data}); + }) + .catch((error) => { + this.props.setStatus(`Could not search for "${this.state.title}": ${error.message}`, 'error'); + }); + } + + render() { + return ( +
+
+
+ + +
+ +
+ +
+ ); + } +} + +SearchForm.propTypes = { + url: PropTypes.string.isRequired, +} + +export default SearchForm; diff --git a/src/components/SearchResults.css b/src/components/SearchResults.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/SearchResults.js b/src/components/SearchResults.js new file mode 100644 index 000000000..ba4ca8904 --- /dev/null +++ b/src/components/SearchResults.js @@ -0,0 +1,53 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import axios from 'axios'; + +import './SearchResults.css'; +import Movie from './Movie' + +class SearchResults extends Component { + + onClickSelect(e, movie) { + console.log(e); + console.log(movie); + this.props.setStatus(`Adding movie "${movie.title}" to library...`, 'pending'); + axios.post(`${this.props.url}/movies`, movie) + .then((response) => { + console.log(response); + this.props.setStatus(`Successfully added "${movie.title}" to library`, 'success'); + alert(`Successfully added ${movie.title} to Library`) + }) + .catch((error) => { + this.props.setStatus( + `Could not add "${movie.title}" to library: ${error.message}`, 'error'); + }); + } + + render () { + console.log(results); + const results = this.props.results.map((movie, index) => { + return ( +
+ + +
+ ) + }) + return ( +
+ {results} +
+ ); + } +} + +SearchResults.propTypes = { + results: PropTypes.array.isRequired, +}; + +export default SearchResults; diff --git a/src/components/Selections.css b/src/components/Selections.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/Selections.js b/src/components/Selections.js new file mode 100644 index 000000000..f7d1f7e86 --- /dev/null +++ b/src/components/Selections.js @@ -0,0 +1,16 @@ +import React, { Component } from 'react'; +import './Selections.css'; + + +const Selections = (props) => { + const customer = props.customer ? props.customer.name : "None"; + const movie = props.movie ? props.movie.title : "None"; + return ( +
+
Selected Customer: {customer} | Selected Movie: {movie}
+
+ ); +} + + +export default Selections; diff --git a/src/components/StatusBar.css b/src/components/StatusBar.css new file mode 100644 index 000000000..b643ba02c --- /dev/null +++ b/src/components/StatusBar.css @@ -0,0 +1,33 @@ +.status-bar { + border: 1px solid black; + display: -ms-flexbox; + display: flex; + -ms-flex-pack: justify; + justify-content: space-between; +} + +.status-bar--hide { + display: none; +} + +.status-bar--error { + background-color: rgb(245, 160, 160); +} + +.status-bar--success { + background-color: rgb(123, 249, 108); +} + +.status-bar--pending { + background-color: rgb(147, 255, 255) +} + +.status-bar__text { + margin: .4em; +} + +.status-bar__button { + background-color: inherit; + border: none; + cursor: pointer; +} diff --git a/src/components/StatusBar.js b/src/components/StatusBar.js new file mode 100644 index 000000000..9352fb074 --- /dev/null +++ b/src/components/StatusBar.js @@ -0,0 +1,38 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +import './StatusBar.css'; + +class StatusBar extends React.Component { + static propTypes = { + message: PropTypes.string.isRequired, + type: PropTypes.oneOf(['error', 'success', 'pending']), + clearStatus: PropTypes.func.isRequired, + } + + + + render() { + let className = "status-bar " + if (this.props.message.length === 0) { + className += "status-bar--hide" + } else { + className += `status-bar--${this.props.type}`; + } + return( +
+

+ {this.props.message} +

+ +
+ ); + } +} + +export default StatusBar; diff --git a/src/components/VideoStore.css b/src/components/VideoStore.css new file mode 100644 index 000000000..056a7a3b7 --- /dev/null +++ b/src/components/VideoStore.css @@ -0,0 +1,63 @@ +@import url('https://fonts.googleapis.com/css?family=Monoton'); +@import url('https://fonts.googleapis.com/css?family=Press+Start+2P'); + +li { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; +} + +.validation-errors-display { + text-align: center; + margin-bottom: 2em; +} + +.validation-errors-display__list { + list-style-type: none; + padding: 0; +} + +.grid-container { + display: grid; + /*grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));*/ + grid-template-columns: 1fr 1fr 1fr 1fr (auto-fit, 186px); + /*grid-template-columns: repeat(auto-fit, 186px);*/ + grid-column-gap: 25px; + grid-row-gap: 25px; +} + +.flex-container { + display: flex; + justify-content: space-between; +} + +.flex-container h1 { + font-family: 'Monoton', cursive; + margin-bottom: 0; +} + +.marquee { + font-family: 'Press Start 2P', cursive; +} + +/*img, ul, li { + display: flex; +}*/ + +.nav-links { + color: #CBE9EB; + text-shadow: orange 0.1em 0.1em 0.2em; + font-weight: bold; +} + +ul { + display: flex; + flex-direction: column; + padding-left: 0; +} + +li { + padding: 5px; + justify-content: center; +} diff --git a/src/components/VideoStore.js b/src/components/VideoStore.js new file mode 100644 index 000000000..3440abbf6 --- /dev/null +++ b/src/components/VideoStore.js @@ -0,0 +1,178 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { BrowserRouter as Router, Route, Link } from "react-router-dom"; +import CustomerList from './CustomerList'; +import Selections from './Selections'; +import RentalLibrary from './RentalLibrary'; +import './VideoStore.css'; +import SearchForm from './SearchForm'; +import StatusBar from './StatusBar'; +import FeaturedFilms from './FeaturedFilms'; +import axios from 'axios'; +import MarqueeDouble from 'react-marquee-double'; + + +class VideoStore extends Component { + constructor () { + super (); + this.state = { + selectedMovie: null, + selectedCustomer: null, + status: { + message: '', + } + } + } + + selectCustomer = (customer) => { + console.log("selecting customer " + customer.name); + this.setState({ + selectedCustomer: customer, + }); + } + + selectMovie = (movie) => { + console.log("selecting movie " + movie.title); + this.setState({ + selectedMovie: movie, + }); + } + + setStatus = (message, type) => { + this.setState({ + status: { message, type } + }); + } + + clearStatus = () => { + this.setState({ status: { message: '' }}) + } + + resetSelection = () => { + console.log("resetting select data"); + this.setState({ + selectedMovie: null, + selectedCustomer: null, + }); + } + + checkoutSelection = (e) => { + if ( this.state.selectedCustomer!=null && this.state.selectedMovie!=null ) { + let dueDate = new Date(); + dueDate.setDate(dueDate.getDate() + 7); + axios.post(`${this.props.url}/rentals/${this.state.selectedMovie.title}/check-out?customer_id=${this.state.selectedCustomer.id}&due_date=${dueDate}`) + .then( (response) => { + this.setStatus( + `Successfully checked out ${this.state.selectedMovie.title} to ${this.state.selectedCustomer.name}`, + 'success'); + }) + .catch((error)=> { + this.setStatus( + `Could not check out ${this.state.selectedMovie.title} to ${this.state.selectedCustomer.name}: ${error.message}`, + 'error'); + // console.log(error); + }); + } + } + + render() { + const Home = () => ( +
+

Featured Films

+ +
+ ); + + const Search = () => ( +
+ +
+ ); + + const Library = () => ( +
+ +
+ ); + + const Customers = () => ( +
+ +
+ ); + + return ( + +
+ ( +
+ {this.marquee = ref}} + step={1} interval={20} + autoStart={true} + direction={'left'} + delay={1000} + onStart={()=>{this.marquee.delay()}}> +

_______________________________Welcome Online_______________________________

+
+
+ +
    +
  • Video King

  • +
  • Video rentals on the World Wide Web

  • +
  • Home
  • +
  • Search
  • +
  • Library
  • +
  • Customers
  • +
+ +
+
+ +
+ + +
+
+ +
+ )} /> + + + + + +
+
+ ); + } + } + + VideoStore.propTypes = { + url: PropTypes.string.isRequired, + } + + export default VideoStore;