Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a925ca1
created routes with React Router, set up basic app
steve-messing Jan 19, 2021
2767c3d
created CustomerList component
steve-messing Jan 19, 2021
29843e2
Started CustomersList component
kashenafi Jan 20, 2021
318b033
fixed dependencies
steve-messing Jan 20, 2021
62375cb
can display list of videos from rails api
steve-messing Jan 20, 2021
ddc82fd
playing with react-select to display video library
steve-messing Jan 20, 2021
79da559
search or select
steve-messing Jan 20, 2021
fe59c0d
Merge pull request #1 from sophieemessing/video-library
steve-messing Jan 20, 2021
122053b
working on customer list display
kashenafi Jan 20, 2021
977d3f2
saving changes
steve-messing Jan 20, 2021
0f79fea
Merge pull request #2 from sophieemessing/CustomerListdisplay
kashenafi Jan 20, 2021
0db5bc1
merging
steve-messing Jan 20, 2021
8f23958
merge to master
steve-messing Jan 20, 2021
a69fd80
renaming folder
steve-messing Jan 20, 2021
808eb8d
renamed back to components
steve-messing Jan 20, 2021
2defe23
selected video states stored in app
steve-messing Jan 20, 2021
2518dea
user can serarch TMDB database for videos
steve-messing Jan 21, 2021
fe8cb30
added axios post for adding API videos to library
steve-messing Jan 21, 2021
69902cb
Customer display working & started checkout
kashenafi Jan 21, 2021
5a83dbf
merging changes
steve-messing Jan 21, 2021
2467c0f
Update App.js
steve-messing Jan 21, 2021
7d97ea8
Update CustomerList.js
steve-messing Jan 21, 2021
bf81c94
Update VideoLibrary.js
steve-messing Jan 21, 2021
d75eec6
Delete src/Components directory
steve-messing Jan 21, 2021
59d20d2
started adding bootstrap
steve-messing Jan 22, 2021
3124a5a
Checkout working, started customer details
kashenafi Jan 22, 2021
16a067e
Merge pull request #4 from sophieemessing/Jan21
kashenafi Jan 22, 2021
168064b
Merge pull request #3 from sophieemessing/bootstrap
kashenafi Jan 22, 2021
22cf53c
added checkout button to navbar
steve-messing Jan 22, 2021
06f1e99
customer shows customer, video shows video
steve-messing Jan 22, 2021
6f61a2b
frontend
steve-messing Jan 22, 2021
75873aa
styling is done
steve-messing Jan 22, 2021
5a194b5
Merged styling work, checkout & add confirmation
kashenafi Jan 22, 2021
acd7e69
Merge pull request #5 from sophieemessing/Jan22
steve-messing Jan 24, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@
"single",
{ "allowTemplateLiterals": true, "avoidEscape": true }
],
"camelcase": "error"
"camelcase": ["error", {"properties": "never"}]
}
}
18,176 changes: 11,214 additions & 6,962 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@
"version": "0.1.1",
"private": true,
"dependencies": {
"bootstrap": "^4.6.0",
"react": "^17.0.1",
"react-bootstrap": "^1.4.3",
"react-dom": "^17.0.1",
"react-scripts": "4.0.1"
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.1",
"react-select": "^3.2.0",
"react-toastify": "^6.2.0",
"reactjs-toastr": "^1.1.0"
},
"devDependencies": {
"gh-pages": "^3.1.0",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.3",
"@testing-library/user-event": "^12.6.0"
"@testing-library/user-event": "^12.6.0",
"gh-pages": "^3.1.0"
},
"scripts": {
"start": "PORT=3001 react-scripts start",
Expand Down
78 changes: 62 additions & 16 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -1,28 +1,74 @@
.App {
text-align: center;
@import url('https://fonts.googleapis.com/css2?family=Fraunces:wght@900&family=Roboto:wght@300&display=swap');

.navbar {
background-color: #e50914;
}

.navbar-logo {
font-family: 'Fraunces', serif;
font-size: 2rem;
color: white;
text-decoration: none;
}

.App-logo {
animation: App-logo-spin infinite 20s linear;
height: 80px;
.navbar-logo:hover {
color: orange;
text-decoration: none;
}

.App-header {
background-color: #222;
height: 150px;
padding: 20px;
/* a.navbar-wrapper {
padding: 24px 20px 8px 20px;
} */

.navbar-link {
color: white;
text-decoration: none;
}

.navbar-link:hover {
color: greenyellow;
text-decoration: none;
}

.selected {
color: white;
text-decoration: none;
}

.App-title {
font-size: 1.5em;
a.navbar-button.nav-link {
padding-top: 16px;
}

.App-intro {
font-size: large;
h4 {
font-weight: bold;
}

@keyframes App-logo-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
img {
padding: 10px
}

.video-details {
margin-left: 20px;
padding: 10px;
}

* {
font-family: 'Roboto', sans-serif;
}

.video-grid {
list-style: none;
display: flex;
flex-wrap: wrap;
padding: 20px;
margin: -10px;
background-color: black;
}

.video-grid-items.img {
flex-grow: 1;
}

.App {
text-align: left;
}
196 changes: 182 additions & 14 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,189 @@
import React, { Component } from 'react';
import logo from './logo.svg';
import React, { Component, useState, useEffect } from 'react';
import './App.css';
import axios from 'axios'
import 'bootstrap/dist/css/bootstrap.min.css';
import {Nav, Navbar, Button, Container} from 'react-bootstrap'

class App extends Component {
render() {
import CustomerList from './components/Customers';
import VideoLibrary from './components/VideoLibrary';
import SelectedVideo from './components/SelectedVideo';
import Search from './components/Search'
import SelectedCustomer from './components/SelectedCustomer';
import {toast} from 'react-toastify'

import 'react-toastify/dist/ReactToastify.css';


import {
BrowserRouter as Router,
Route,
Switch,
Link,
} from 'react-router-dom';
import Detail from './components/Detail';


const App = (props) => {

toast.configure();

const [selectedVideo, setSelectedVideo] = useState(null)
const [selectedCustomer, setSelectedCustomer] = useState(null)
const [errorMessage, setErrorMessage] = useState('')

const handleVideoChange = ((selectedData) => {
setSelectedVideo(selectedData.value)
})

const handleCustomerChange = ((selectedData) => {
setSelectedCustomer(selectedData.value)
})

const resetState = () => {
setSelectedVideo(null);
setSelectedCustomer(null);
};

const addRental = () => {

axios
.post(`http://localhost:3000/rentals/${selectedVideo.title}/check-out`, {
customer_id: selectedCustomer.id,
due_date: new Date(
Date.now() + 1000 /*sec*/ * 60 /*min*/ * 60 /*hour*/ * 24 /*day*/ * 7
)
})

.then((res) => {

toast.success(`${selectedCustomer.name} has successfully checked out ${selectedVideo.title}`);
resetState()
setTimeout(function(){ window.location = '/'}, 5000)

})
.catch((error) => {
setErrorMessage(error.message);
});
};


//// this is an experiment ////

const allVideosURL = 'http://localhost:3000/videos'

const [videos, setVideos] = useState([])

useEffect(() => {
axios.get(allVideosURL)
.then((response) => {
const RailsApiVideoList = response.data
setVideos(RailsApiVideoList);
})
.catch((error) => {
console.log(error.message);
});
}, []);

function VideoGrid() {
const videoGrid = videos.map((video) =>
<li key={video.id} className="video-grid-item">
<img src={video.image_url}></img>
</li>
);
return (
<ul className="video-grid">{videoGrid}</ul>
);
}


// const HomePageGrid = () // working on this now SM

return (

<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
<Router>

<Navbar collapseOnSelect expand="lg" className="navbar">

<Nav.Link>
<Link to="/" exact={true} className="navbar-logo">The Video Store</Link>
</Nav.Link>

<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">

<Nav className="mr-auto">


<Nav.Link>
<Link to="/search" exact={true} className="navbar-link">Search</Link>
</Nav.Link>

<Nav.Link>
<Link to="/customers" exact={true} className="navbar-link">Customers</Link>
</Nav.Link>

<Nav.Link>
<Link to="/library" exact={true} className="navbar-link">Video Library</Link>
</Nav.Link>

</Nav>

<Nav className="ml-auto">
<Nav.Link>
<Link to="/library" className="navbar-link">Video: {selectedVideo &&(selectedVideo.title)} </Link>
</Nav.Link>

<Nav.Link>
<Link to="/customers" className="navbar-link">Customer: {selectedCustomer &&(selectedCustomer.name)} </Link>
</Nav.Link>
</Nav>
<Nav className="ml-auto">
<Nav.Link>
{selectedVideo && selectedCustomer ?
<Button className="customer-button" onClick={() => addRental()}>
Checkout
</Button> : ''}

</Nav.Link>

</Nav>
</Navbar.Collapse>
</Navbar>


<Switch>
<Route exact={true} path="/">
<VideoGrid/>
</Route>
<Route path="/search">
<Container>
<Search />
</Container>
</Route>
<Route exact path="/customers">
<Container>
<CustomerList onSelectCustomer={handleCustomerChange} selectedCustomer={selectedCustomer}/>
<SelectedCustomer customer={selectedCustomer}/>
</Container>
</Route>
<Route exact path="/library">
<Container>
<VideoLibrary addRental={addRental} selectedCustomer={selectedCustomer} onSelectVideo={handleVideoChange} selectedVideo={selectedVideo}/>
<SelectedVideo video={selectedVideo}/>
</Container>
</Route>

<Route exact path="/detail">
<Detail />
</Route>
</Switch>


</Router>
</div>
);

}

export default App;
55 changes: 55 additions & 0 deletions src/components/Customers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import Select from 'react-select';
import axios from 'axios'

import {Container, Form, Col} from 'react-bootstrap'

const CustomerList = (props) => {

const allCustomersURL = 'http://localhost:3000/customers'

const [customers, setCustomers] = useState([])
const [errorMessage, setErrorMessage] = useState(null)

useEffect(() => {

axios.get(allCustomersURL)
.then((response) => {
const RailsApiCustomerList = response.data
setCustomers(RailsApiCustomerList);
console.log(response);
})
.catch((error) => {
setErrorMessage(error.message);
console.log(errorMessage);
});
}, []);

return (
<div>
<br/>
<Col lg={10}>
<h3>Customers</h3>
<Form.Label>Select or Search for a Customer: </Form.Label>
<Select
value={props.selectedCustomer}
onChange={props.onSelectCustomer}
options={customers.map((customer, index) => {

return {
label: customer.name,
value: customer,
key: index
};
})}
/>
</Col>
<br/>
</div>
)
}

CustomerList.propTypes = {}

export default CustomerList
12 changes: 12 additions & 0 deletions src/components/Detail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react'

const Detail = () => {

return (
<div>
detail page
</div>
)
}

export default Detail
Loading