Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"axios": "^0.19.0",
"formik": "^1.5.8",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-router-dom": "^5.0.1",
Expand Down
107 changes: 101 additions & 6 deletions client/src/App.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,123 @@
import React, { useState } from "react";
import { Route } from "react-router-dom";
import React, { useState, useEffect } from "react";
import { Route, withRouter, Link } from "react-router-dom";
import axios from "axios";
import SavedList from "./Movies/SavedList";
import MovieList from "./Movies/MovieList";
import Movie from "./Movies/Movie";
import UpdateMovieForm from "./Movies/UpdateMovieForm";
import AddMovieForm from "./Movies/AddMovieForm";

const App = () => {
const App = props => {
const [savedList, setSavedList] = useState([]);
const [listMovies, setListMovies] = useState([]);

const addToSavedList = movie => {
setSavedList([...savedList, movie]);
};

const setMovieList = data => {
setListMovies(data);
};

const updateMovie = movie => {
axios
.put(`http://localhost:5000/api/movies/${movie.id}`, movie)
.then(res => {
fetchMovies();
props.history.push("/");
})
.catch(error => {
alert(error.message);
});
};

const fetchMovies = () => {
axios
.get("http://localhost:5000/api/movies")
.then(res => {
setListMovies(res.data);
})
.catch(err => alert(err.response));
};

useEffect(() => {
fetchMovies();
}, []);

const deleteMovie = id => {
axios
.delete(`http://localhost:5000/api/movies/${id}`)
.then(res => {
fetchMovies();
props.history.push("/");
})
.catch(error => {
alert(error);
});
};

const addMovie = values => {
debugger;
axios
.post("http://localhost:5000/api/movies", values)
.then(res => {
fetchMovies();
props.history.push("/");
})
.catch(error => {
alert(error)
});
};

return (
<>
<SavedList list={savedList} />
<Route exact path="/" component={MovieList} />
<Link to="/add-movie">Add movie</Link>
<Route
exact
path="/"
render={props => {
return (
<MovieList
{...props}
setMovieList={setMovieList}
listMovies={listMovies}
/>
);
}}
/>
<Route
path="/movies/:id"
render={props => {
return <Movie {...props} addToSavedList={addToSavedList} />;
return (
<Movie
{...props}
addToSavedList={addToSavedList}
deleteMovie={deleteMovie}
/>
);
}}
/>
<Route
path="/update-movie/:id"
render={props => {
return (
<UpdateMovieForm
{...props}
listMovies={listMovies}
updateMovie={updateMovie}
/>
);
}}
/>
<Route
path="/add-movie"
render={props => {
return <AddMovieForm {...props} addMovie={addMovie} />;
}}
/>
</>
);
};

export default App;
export default withRouter(App);
68 changes: 68 additions & 0 deletions client/src/Movies/AddMovieForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from "react";
import { Formik, Form, Field, FieldArray } from "formik";

const initialForm = {
title: null,
director: null,
metascore: null,
stars: []
};

export default function AddMovieForm({ addMovie }) {
return (
<Formik
initialValues={initialForm}
onSubmit={addMovie}
render={props => {
return (
<Form>
<label>
Director
<Field name="director" type="text" />
</label>
<label>
Title
<Field name="title" type="text" />
</label>
<label>
Metascore
<Field name="metascore" type="text" />
</label>
<FieldArray
name="stars"
render={arrayHelpers => (
<div>
{props.values.stars && props.values.stars.length > 0 ? (
props.values.stars.map((star, index) => (
<div key={index}>
<Field name={`stars.${index}`} />
<button
type="button"
onClick={() => arrayHelpers.remove(index)} // remove a friend from the list
>
-
</button>
<button
type="button"
onClick={() => arrayHelpers.insert(index, "")} // insert an empty string at a position
>
+
</button>
</div>
))
) : (
<button type="button" onClick={() => arrayHelpers.push("")}>
{/* show this when user has removed all friends from the list */}
Add a star
</button>
)}
</div>
)}
/>
<button type="submit">Submit</button>
</Form>
);
}}
/>
);
}
24 changes: 19 additions & 5 deletions client/src/Movies/Movie.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,61 @@
import React from "react";
import axios from "axios";
import MovieCard from "./MovieCard";
import {Link} from 'react-router-dom';


export default class Movie extends React.Component {
constructor(props) {
super(props);
this.state = {
movie: null
};
}

componentDidMount() {
this.fetchMovie(this.props.match.params.id);
}

componentWillReceiveProps(newProps) {
if (this.props.match.params.id !== newProps.match.params.id) {
this.fetchMovie(newProps.match.params.id);
}
}

fetchMovie = id => {
axios
.get(`http://localhost:5000/api/movies/${id}`)
.then(res => this.setState({ movie: res.data }))
.catch(err => console.log(err.response));
};

saveMovie = () => {
const addToSavedList = this.props.addToSavedList;
addToSavedList(this.state.movie);
};

onClickToDeleteMovie = id => {
const deleteMovie = this.props.deleteMovie;
deleteMovie(id);
};

render() {
if (!this.state.movie) {
return <div>Loading movie information...</div>;
}

return (
<div className="save-wrapper">
<MovieCard movie={this.state.movie} />
<div className="save-button" onClick={this.saveMovie}>
Save
</div>
<button>
<Link to={`/update-movie/${this.state.movie.id}`}>Update</Link>
</button>
<button onClick={e => this.onClickToDeleteMovie(this.state.movie.id)}>
Delete
</button>
</div>
);
}
Expand Down
14 changes: 2 additions & 12 deletions client/src/Movies/MovieList.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
import React, { Component } from "react";
import axios from "axios";
import { Link } from "react-router-dom";
import MovieCard from "./MovieCard";

export default class MovieList extends Component {
constructor(props) {
super(props);
this.state = {
movies: []
};
}

componentDidMount() {
axios
.get("http://localhost:5000/api/movies")
.then(res => this.setState({ movies: res.data }))
.catch(err => console.log(err.response));
}

render() {
return (
<div className="movie-list">
{this.state.movies.map(movie => (
{this.props.listMovies.map(movie => (
<MovieDetails key={movie.id} movie={movie} />
))}
</div>
Expand Down
3 changes: 3 additions & 0 deletions client/src/Movies/SavedList.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import React, { Component } from 'react';
import { NavLink, Link } from 'react-router-dom';



export default class SavedList extends Component {
constructor(props) {
super(props);
Expand Down
47 changes: 47 additions & 0 deletions client/src/Movies/UpdateMovieForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";
import { Formik, Form, Field, FieldArray } from "formik";

export default function UpdateMovieForm({ listMovies, match, updateMovie }) {
const movieToUpdate = listMovies.find(item => {
return item.id === Number(match.params.id);
});
return (
<div>
<Formik
initialValues={movieToUpdate}
onSubmit={updateMovie}
render={props => {
return (
<Form>
<label>
Director
<Field name="director" type="text" />
</label>
<label>
Title
<Field name="title" type="text" />
</label>
<label>
Metascore
<Field name="metascore" type="text" />
</label>
<FieldArray
name="stars"
render={arrayHelpers => {
return (
<div>
{props.values.stars.map((star, index) => {
return <Field name={`stars.${index}`} />;
})}
</div>
);
}}
/>
<button type="submit">Submit</button>
</Form>
);
}}
/>
</div>
);
}
Loading