Skip to content

Instantly share code, notes, and snippets.

@Sammykhaleel
Created July 6, 2020 23:11
Show Gist options
  • Save Sammykhaleel/1751ef87dd482fec514e8d1d9c9b53a3 to your computer and use it in GitHub Desktop.
Save Sammykhaleel/1751ef87dd482fec514e8d1d9c9b53a3 to your computer and use it in GitHub Desktop.
import React from "react";
import axios from "axios";
import { BrowserRouter as Router, Route } from "react-router-dom";
import { LoginView } from "../login-view/login-view";
import { RegistrationView } from "../registration-view/registration-view";
import { MovieCard } from "../movie-card/movie-card";
import { MovieView } from "../movie-view/movie-view";
import { ProfileView } from "../profile-view/profile-view";
import { DirectorView } from "../director-view/director-view";
import { GenreView } from "../genre-view/genre-view";
import { UpdateView } from "../update-view/update-view";
import Button from "react-bootstrap/Button";
import Navbar from "react-bootstrap/Navbar";
import { Link } from "react-router-dom";
import "./main-view.scss";
import Row from "react-bootstrap/Row";
import Container from "react-bootstrap/Container";
import Col from "react-bootstrap/Col";
export class MainView extends React.Component {
constructor() {
// Call the superclass constructor
// so React can initialize it
super();
// Initialize the state to an empty object so we can destructure it later
this.state = {
movies: [],
user: null,
profileInfo: null,
};
}
getMovies(token) {
axios
.get("https://vfa.herokuapp.com/movies", {
headers: { Authorization: "Bearer " + token },
})
.then((response) => {
// Assign result to a state
this.setState({
movies: response.data,
});
})
.catch((error) => {
console.log(error);
});
}
getAccount(accessToken) {
const url =
"https://vfa.herokuapp.com/users/" + localStorage.getItem("user");
console.log(url);
axios
.get(url, {
headers: { Authorization: "Bearer " + accessToken },
})
.then((response) => {
// console.log(response.data);
// Assign result to a state
this.setState({
profileInfo: response.data,
});
})
.catch(function (error) {
console.log(error);
});
}
componentDidMount() {
// Get value of token from localStorage if present
let accessToken = localStorage.getItem("token");
if (accessToken !== null) {
this.setState({
user: localStorage.getItem("user"),
});
this.getMovies(accessToken);
this.getAccount(accessToken);
}
}
logOut() {
localStorage.removeItem("token");
localStorage.removeItem("user");
localStorage.removeItem("id");
this.setState({
user: null,
});
}
onLoggedIn(authData) {
this.setState({
user: authData.user.Username,
});
// Add authData to browser's cache (that we got from props.logInFunc(data) in the profile.view)
localStorage.setItem("token", authData.token);
localStorage.setItem("user", authData.user.Username);
localStorage.setItem("id", authData.user._id);
// Calls endpoint once user is logged in
this.getMovies(authData.token);
this.getAccount(authData.token);
}
render() {
// If the state isn't initialized, this will throw on runtime
// before the data is initially loaded
const { movies, user, profileInfo } = this.state;
// Logging to check states
// console.log('M = ' + movies);
// console.log('U = ' + user);
// console.log('pi =' + profileInfo);
// Before the movies have been loaded
if (!movies && !profileInfo) return <div className="main-view" />;
return (
<Router>
<div className="main-view text-center container-fluid main-view-styles ">
{/* Nav start */}
<Navbar
sticky="top"
bg="light"
expand="lg"
className="mb-3 shadow-sm p-3 mb-5"
>
<Navbar.Brand
href="http://localhost:1234/"
className="navbar-brand"
>
VFA
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse
className="justify-content-end"
id="basic-navbar-nav"
>
{!user ? (
<ul>
<Link to={`/`}>
<Button variant="link">login</Button>
</Link>
<Link to={`/register`}>
<Button variant="link">Register</Button>
</Link>
</ul>
) : (
<ul>
<Link to={`/`}>
<Button variant="link" onClick={() => this.logOut()}>
Log out
</Button>
</Link>
<Link to={`/users/`}>
<Button variant="link">Account</Button>
</Link>
<Link to={`/`}>
<Button variant="link">Movies</Button>
</Link>
<Link to={`/about`}>
<Button variant="link">About</Button>
</Link>
<Link to={`/contact`}>
<Button variant="link">Contact</Button>
</Link>
</ul>
)}
</Navbar.Collapse>
</Navbar>
{/* Nav end */}
{/* If this.user === null don't show Link */}
<Route
exact
path="/"
render={() => {
if (!user)
return (
<LoginView logInFunc={(user) => this.onLoggedIn(user)} />
);
return (
<div className="row d-flex mt-4 ml-2">
{movies.map((m) => (
<MovieCard key={m._id} movie={m} />
))}
</div>
);
}}
/>
<Route
path="/movies/:movieId"
render={({ match }) => (
<MovieView
movie={movies.find((m) => m._id === match.params.movieId)}
/>
)}
/>
<Route
path="/users/"
render={() => (
<ProfileView
user={user}
profileInfo={this.state.profileInfo}
movies={movies}
logOutFunc={() => this.logOut()}
/>
)}
/>
<Route
path="/Update/:name"
render={() => (
<UpdateView user={user} profileInfo={this.state.profileInfo} />
)}
/>
<Route
path="/directors/:name"
render={({ match }) => (
<DirectorView
director={movies.find(
(m) => m.Director.Name === match.params.name
)}
movies={movies}
/>
)}
/>
<Route
path="/genres/:name"
render={({ match }) => (
<GenreView
genre={movies.find((m) => m.Genre.Name === match.params.name)}
movies={movies}
/>
)}
/>
<Route path="/register" render={() => <RegistrationView />} />
</div>
</Router>
);
}
}
import React from 'react';
import axios from 'axios';
import Button from 'react-bootstrap/Button';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import Row from 'react-bootstrap/Row';
import Container from 'react-bootstrap/Container';
import Col from 'react-bootstrap/Col';
import Card from 'react-bootstrap/Card';
import './profile-view.scss';
export class ProfileView extends React.Component {
constructor() {
super();
this.state = {};
}
removeFavourite(movie) {
/* Send a request to the server for authentication */
const url =
'https://vfa.herokuapp.com/users/' +
localStorage.getItem('id') +
'/favourites/' +
movie; // 'https://vfa.herokuapp.com/users/localStorage.getItem('user')}/favourites/${movie}';
axios
.delete(url, {
headers: { Authorization: 'Bearer ' + localStorage.getItem('token') }, // `Bearer ${localStorage.getItem('token')}`
})
// reload page
.then(() => {
document.location.reload(true);
})
.then(() => {
alert('Movie removed from favourites');
})
.catch((error) => {
console.log('Issue deleting movie from favourites... >' + error);
});
}
unregisterAccount() {
if (!confirm('Are you sure?')) {
return;
}
const url = 'https://vfa.herokuapp.com/users/' + localStorage.getItem('id');
console.log(url);
axios
.delete(url, {
headers: { Authorization: 'Bearer ' + localStorage.getItem('token') },
})
.then((response) => {
console.log(response.data);
// Set profile info to null
this.setState({
profileInfo: null,
user: null,
});
this.props.logOutFunc();
window.open('/', '_self');
alert('Your account was successfully deleted');
})
.catch(function (error) {
console.log(error);
});
}
render() {
const { user, profileInfo, movies } = this.props;
if (!profileInfo || !user) return <div>Loading</div>;
console.log(profileInfo.FavouriteMovies);
const favouritesList = movies.filter((movie) =>
profileInfo.FavouriteMovies.includes(movie._id)
);
console.log('FL =' + favouritesList);
return (
<Container className="profile-view wrapper container-fluid">
<Row>
<Col className="col-3" />
<Col className="container-fluid align-items-center col-6">
<img
className="profile-avatar "
src="https://via.placeholder.com/150"
/>
<div className="account-username ">
<span className="label">Username: </span>
<span className="value">{profileInfo.Username}</span>
</div>
<div className="account-email ">
<span className="label">Email: </span>
<span className="value">{profileInfo.Email}</span>
</div>
<div className="account-birthday ">
<span className="label">Birthday: </span>
<span className="value">{profileInfo.Birthday}</span>
</div>
<div className="account-password ">
<span className="label">Password: </span>
<span className="value">***********</span>
</div>
</Col>
<Col className="col-3" />
</Row>
<Container>
<h4>Favourites List</h4>
<div className="d-flex row mt-3 ml-1">
{favouritesList.map((movie) => {
return (
<div key={movie._id}>
<Card className="mb-3 mr-2 h-100" style={{ width: '16rem' }}>
<Card.Img variant="top" src={movie.ImagePath} />
<Card.Body>
<Link className="text-muted" to={`/movies/${movie._id}`}>
<Card.Title>{movie.Title}</Card.Title>
</Link>
<Card.Text>
{movie.Description.substring(0, 90)}...
</Card.Text>
</Card.Body>
<Card.Footer className="bg-white border-top-0">
<span className="d-flex align-items-center">
<Button
variant="primary"
size="sm"
className="mr-2"
onClick={() => this.removeFavourite(movie._id)}
>
<i className="material-icons bin">Remove</i>
</Button>
</span>
</Card.Footer>
</Card>
</div>
);
})}
</div>
</Container>
<Row>
<Col>
<Link to={`/update/${profileInfo.Username}`}>
<Button variant="primary" className="update-button">
Update my profile
</Button>
</Link>
<div className="">
<Button onClick={() => this.unregisterAccount()} variant="link">
Delete Account
</Button>
</div>
<Link to={`/`}>
<Button variant="link">Home</Button>
</Link>
</Col>
</Row>
</Container>
);
}
}
ProfileView.propTypes = {
profileInfo: PropTypes.shape({
Username: PropTypes.string.isRequired,
Email: PropTypes.string.isRequired,
// ImagePath: PropTypes.string.isRequired,
Birthday: PropTypes.string.isRequired,
}).isRequired,
logOutFunc: PropTypes.func.isRequired,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment