From 47846b0d3dd523e0b5ad7c301aa9d5790662df4c Mon Sep 17 00:00:00 2001 From: Alex Hoskins Date: Wed, 10 Nov 2021 15:46:31 -0800 Subject: [PATCH 1/5] mvp done --- README.md | 50 +++++++------- client/src/App.js | 39 ++++++++--- client/src/components/AddMovieForm.js | 81 +++++++++++++++++++++++ client/src/components/DeleteMovieModal.js | 18 ++++- client/src/components/EditMovieForm.js | 25 ++++++- client/src/components/Movie.js | 21 ++++-- client/src/components/MovieHeader.js | 2 +- 7 files changed, 193 insertions(+), 43 deletions(-) create mode 100644 client/src/components/AddMovieForm.js diff --git a/README.md b/README.md index 9225889f..f105c9cf 100644 --- a/README.md +++ b/README.md @@ -16,58 +16,58 @@ CRUD applications are the foundation of most web applications. Being able to man ## Instructions ### Task 1: Project Set Up -* [ ] Create a forked copy of this project. -* [ ] Clone your OWN version of the repository in your terminal -* [ ] cd into the project base directory `cd web-module-project-HTTP` -* [ ] Download server dependencies by running `npm install` -* [ ] Run the local web server by running `node server.js` -* [ ] Open a new terminal window and cd into the client code `cd client` -* [ ] Download project dependencies by running `npm install` -* [ ] Start up the app using `npm start` +* [x] Create a forked copy of this project. +* [x] Clone your OWN version of the repository in your terminal +* [x] cd into the project base directory `cd web-module-project-HTTP` +* [x] Download server dependencies by running `npm install` +* [x] Run the local web server by running `node server.js` +* [x] Open a new terminal window and cd into the client code `cd client` +* [x] Download project dependencies by running `npm install` +* [x] Start up the app using `npm start` ### Task 2: Project Requirements #### Editing a Movie > *Let's start by walking through the process of adding the routing, component and service calls need for resource updating* -* [ ] First, we need to be able to navigate to the edit movie component. In App.js, add in the ` `component to the supplied edit route. +* [x] First, we need to be able to navigate to the edit movie component. In App.js, add in the ` `component to the supplied edit route. -* [ ] Next, we need to grab the id being passed into the component through the url. Use the `useParams` hook to get the id value. +* [x] Next, we need to grab the id being passed into the component through the url. Use the `useParams` hook to get the id value. -* [ ] We need to be able to load in the current movie's attributes into our local form state. When `EditMovieForm` mount, retrieve our current id's movie from the api and save the data returned to local state. +* [x] We need to be able to load in the current movie's attributes into our local form state. When `EditMovieForm` mount, retrieve our current id's movie from the api and save the data returned to local state. -* [ ] At this point, nothing happens when the edit form is submitted. Add in the api call needed to update the server with our updated movie data. +* [x] At this point, nothing happens when the edit form is submitted. Add in the api call needed to update the server with our updated movie data. -* [ ] Don't forget to make sure that your server data and your local state are in sync! Make any changes the edit route needed to give the edit form access to App's `setMovies` method. +* [x] Don't forget to make sure that your server data and your local state are in sync! Make any changes the edit route needed to give the edit form access to App's `setMovies` method. -* [ ] Now that we have access to `setMovies`, made sure the updated list of movies is saved to our global state. +* [x] Now that we have access to `setMovies`, made sure the updated list of movies is saved to our global state. -* [ ] Redirect the user to the currently edited movie's individual info page. +* [x] Redirect the user to the currently edited movie's individual info page. #### Deleting a Movie > *You added in a CRUD feature! Good job! Now let's get deleted squared away...* -* [ ] Identify the component that holds the "button" needed for deletion. Add an event handler to that button. +* [x] Identify the component that holds the "button" needed for deletion. Add an event handler to that button. -* [ ] Build an event handler that makes a request to delete the currently viewed movie. Observe what is returned from the request. +* [x] Build an event handler that makes a request to delete the currently viewed movie. Observe what is returned from the request. -* [ ] You will once again need to keep the server and state data in sync. In `App.js`, complete the `deleteMovie` method so that it receives an id, filters out any movie with that id and sets state to that resultant movie list. +* [x] You will once again need to keep the server and state data in sync. In `App.js`, complete the `deleteMovie` method so that it receives an id, filters out any movie with that id and sets state to that resultant movie list. -* [ ] Pass `deleteMovie` into the approprate component. +* [x] Pass `deleteMovie` into the approprate component. -* [ ] Run `deleteMovie` on the currently selected movie when your delete request is complete and redirect the user to the `/movies` route. +* [x] Run `deleteMovie` on the currently selected movie when your delete request is complete and redirect the user to the `/movies` route. #### Adding a Movie > *Alright! You ready! Let's see you use the skills of the previous steps to build a crud function from start to finish.* -* [ ] Use `EditMovieForm.js` as a model to build an `AddMovieForm` component from scratch. The component should hold all the attributes of a new movie in local state. +* [x] Use `EditMovieForm.js` as a model to build an `AddMovieForm` component from scratch. The component should hold all the attributes of a new movie in local state. -* [ ] Add in a route that allows access to `AddMovieForm`. +* [x] Add in a route that allows access to `AddMovieForm`. -* [ ] Locate the part of the ui that should redirect to your new `AddMovieForm`. Make that button works as expected. +* [x] Locate the part of the ui that should redirect to your new `AddMovieForm`. Make that button works as expected. -* [ ] In `AddMovieForm,` add an event handler for form submission. When the form is submitted, run the approprate request for adding a movie with the component's state values. +* [x] In `AddMovieForm,` add an event handler for form submission. When the form is submitted, run the approprate request for adding a movie with the component's state values. -* [ ] Make sure your component has access to and runs and modifications needed to global state and redirects to `/movies` after creation. +* [x] Make sure your component has access to and runs and modifications needed to global state and redirects to `/movies` after creation. ### Stretch goals - Make the added DeleteMovieModal appear and be reacted to before deletion occurs. diff --git a/client/src/App.js b/client/src/App.js index 048a1923..fd74a684 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,6 +1,6 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState} from "react"; -import { Route, Switch, Redirect } from "react-router-dom"; +import { Route, Switch, Redirect, useHistory} from "react-router-dom"; import MovieList from './components/MovieList'; import Movie from './components/Movie'; @@ -8,12 +8,14 @@ import MovieHeader from './components/MovieHeader'; import EditMovieForm from './components/EditMovieForm'; import FavoriteMovieList from './components/FavoriteMovieList'; - +import AddMovieForm from "./components/AddMovieForm"; import axios from 'axios'; +import DeleteMovieModal from "./components/DeleteMovieModal"; const App = (props) => { const [movies, setMovies] = useState([]); const [favoriteMovies, setFavoriteMovies] = useState([]); + const { push } = useHistory(); useEffect(()=>{ axios.get('http://localhost:5000/api/movies') @@ -21,15 +23,28 @@ const App = (props) => { setMovies(res.data); }) .catch(err => { - console.log(err); + console.log('this is error', err); }); }, []); - const deleteMovie = (id)=> { + const deleteMovie = (num)=> { + axios.delete(`http://localhost:5000/api/movies/${num}`) + .then(res => { + setMovies( + movies.filter(movie=>{ + return movie.id !== res.data + }) + ) + push(`/movies`) + }) + .catch(err => { + console.log('this is error', err); + }); } - const addToFavorites = (movie) => { - + const addToFavorites = (e) => { + e.preventDefault(); + } return ( @@ -45,12 +60,20 @@ const App = (props) => { + + + + + - + + + + diff --git a/client/src/components/AddMovieForm.js b/client/src/components/AddMovieForm.js new file mode 100644 index 00000000..f4afe198 --- /dev/null +++ b/client/src/components/AddMovieForm.js @@ -0,0 +1,81 @@ +import React, { useState, useEffect } from 'react'; +import { useParams, useHistory } from 'react-router-dom'; +import { Link } from 'react-router-dom'; +import axios from 'axios'; + +const AddMovieForm = (props) => { + const { push } = useHistory(); + + const [movie, setMovie] = useState({ + title:"", + director: "", + genre: "", + metascore: 0, + description: "" + }); + + + + const handleChange = (e) => { + setMovie({ + ...movie, + [e.target.name]: e.target.value + }); + } + + const handleSubmit = (e) => { + e.preventDefault(); + axios.post(`http://localhost:5000/api/movies/`, movie) + .then(resp=> { + console.log('resp data from pos', resp.data) + props.setMovies(resp.data); + push(`/movies`); + + }) + .catch(err=> { + console.log(err); + }) + } + + const { title, director, genre, metascore, description } = movie; + + return ( +
+
+
+
+

Add Movie

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+ + +
+
+
+
); +} + +export default AddMovieForm; \ No newline at end of file diff --git a/client/src/components/DeleteMovieModal.js b/client/src/components/DeleteMovieModal.js index 87b96bb5..e85ffa84 100644 --- a/client/src/components/DeleteMovieModal.js +++ b/client/src/components/DeleteMovieModal.js @@ -1,6 +1,18 @@ import React from 'react'; +import { useHistory } from 'react-router-dom'; -const DeleteMovieModal = () => { +const DeleteMovieModal = (props) => { + const {handleDelete, handleToggle}= props; + const { push } = useHistory(); + + const del = ()=>{ + handleDelete(); + push('/movies') + } + + const tog = ()=>{ + handleToggle(); + } return (
@@ -14,8 +26,8 @@ const DeleteMovieModal = () => {

This action cannot be undone.

- - + +
diff --git a/client/src/components/EditMovieForm.js b/client/src/components/EditMovieForm.js index 9c058388..629533ce 100644 --- a/client/src/components/EditMovieForm.js +++ b/client/src/components/EditMovieForm.js @@ -5,8 +5,9 @@ import { Link } from 'react-router-dom'; import axios from 'axios'; const EditMovieForm = (props) => { + console.log(props) const { push } = useHistory(); - + const { id } = useParams(); const [movie, setMovie] = useState({ title:"", director: "", @@ -14,6 +15,18 @@ const EditMovieForm = (props) => { metascore: 0, description: "" }); + + useEffect(()=>{ + axios.get(`http://localhost:5000/api/movies/${id}`) + .then(res=>{ + console.log(res.data) + setMovie(res.data); + }) + .catch(err=>{ + console.log(err.response); + }) + }, []); + const handleChange = (e) => { setMovie({ @@ -24,6 +37,16 @@ const EditMovieForm = (props) => { const handleSubmit = (e) => { e.preventDefault(); + axios.put(`http://localhost:5000/api/movies/${id}`, movie) + .then(resp=> { + console.log('resp data from edit', resp.data) + props.setMovies(resp.data); + push(`/movies/${id}`); + + }) + .catch(err=> { + console.log(err); + }) } const { title, director, genre, metascore, description } = movie; diff --git a/client/src/components/Movie.js b/client/src/components/Movie.js index fc2b0e05..5ba31122 100644 --- a/client/src/components/Movie.js +++ b/client/src/components/Movie.js @@ -1,13 +1,13 @@ import React, { useEffect, useState } from 'react'; import { Link, useParams, useHistory } from 'react-router-dom'; - +import DeleteMovieModal from "./DeleteMovieModal"; import axios from 'axios'; const Movie = (props) => { - const { addToFavorites } = props; + const { addToFavorites, deleteMovie } = props; const [movie, setMovie] = useState(''); - + const [isToggled, setIsToggled]=useState(false) const { id } = useParams(); const { push } = useHistory(); @@ -21,6 +21,15 @@ const Movie = (props) => { }) }, [id]); + const handleDelete=()=>{ + deleteMovie(id); + } + const handleToggle=()=>{ + setIsToggled(!isToggled) + } + + + return(
@@ -48,13 +57,15 @@ const Movie = (props) => {

{movie.description}

- + {!isToggled &&
Favorite Edit - +
+ }
+ {isToggled && }
diff --git a/client/src/components/MovieHeader.js b/client/src/components/MovieHeader.js index 48ee5dd6..9174d8e9 100644 --- a/client/src/components/MovieHeader.js +++ b/client/src/components/MovieHeader.js @@ -8,7 +8,7 @@ const MovieHeader = ()=> {

IMDB Movie Database

- Add New Movie + Add New Movie View All Movies
From 3f73aa487e6634caaf2af686a805e7e2cfb8f432 Mon Sep 17 00:00:00 2001 From: Alex Hoskins Date: Wed, 10 Nov 2021 15:48:15 -0800 Subject: [PATCH 2/5] mvp --- client/src/components/DeleteMovieModal.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/components/DeleteMovieModal.js b/client/src/components/DeleteMovieModal.js index e85ffa84..48ad7741 100644 --- a/client/src/components/DeleteMovieModal.js +++ b/client/src/components/DeleteMovieModal.js @@ -9,7 +9,7 @@ const DeleteMovieModal = (props) => { handleDelete(); push('/movies') } - + const tog = ()=>{ handleToggle(); } @@ -35,4 +35,5 @@ const DeleteMovieModal = (props) => { ) } + export default DeleteMovieModal; From d263f16caefe51dc44a5820044a4ee4016faa47f Mon Sep 17 00:00:00 2001 From: Alex Hoskins Date: Wed, 10 Nov 2021 15:49:31 -0800 Subject: [PATCH 3/5] mvp --- client/src/components/DeleteMovieModal.js | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/components/DeleteMovieModal.js b/client/src/components/DeleteMovieModal.js index 48ad7741..8dc90bf0 100644 --- a/client/src/components/DeleteMovieModal.js +++ b/client/src/components/DeleteMovieModal.js @@ -35,5 +35,4 @@ const DeleteMovieModal = (props) => { ) } - export default DeleteMovieModal; From ea4dad0929105f9f5484ca972846fcc787927f49 Mon Sep 17 00:00:00 2001 From: Alex Hoskins Date: Wed, 10 Nov 2021 15:52:43 -0800 Subject: [PATCH 4/5] ... --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f105c9cf..5c66c475 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ CRUD applications are the foundation of most web applications. Being able to man - Add in `addToFavorites` functionality. When the favorite button is pushed in the `Movie` component, make sure that when the favorite button is pushed, the id and name of the currently viewed into the favorite state slice in `App.js.` - For extra credit, ensure that only unique movies can be added as favorites. Consider the `.find` method for arrays. - Add in some Style! - +Testing!! ### Resource: API documentation #### GET `http://localhost:5000/api/movies` From 0282df3363a309212fffece4256ee5ebe4c26d4e Mon Sep 17 00:00:00 2001 From: Alex Hoskins Date: Wed, 10 Nov 2021 16:29:14 -0800 Subject: [PATCH 5/5] Added functionality to favorites section --- client/src/App.js | 21 +++++++++++++++------ client/src/components/Movie.js | 5 ++++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/client/src/App.js b/client/src/App.js index fd74a684..a68cce65 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -13,6 +13,7 @@ import axios from 'axios'; import DeleteMovieModal from "./components/DeleteMovieModal"; const App = (props) => { + const [movies, setMovies] = useState([]); const [favoriteMovies, setFavoriteMovies] = useState([]); const { push } = useHistory(); @@ -35,16 +36,24 @@ const App = (props) => { return movie.id !== res.data }) ) - push(`/movies`) - }) + const newFav= favoriteMovies.filter(mov=>{ + return res.data !== mov.id + }) + setFavoriteMovies(newFav) + }) .catch(err => { console.log('this is error', err); }); } - const addToFavorites = (e) => { - e.preventDefault(); - + const addToFavorites = (movie) => { + const newFav= favoriteMovies.filter(mov=>{ + return movie.id !== mov.id + }) + setFavoriteMovies([ + movie, + ...newFav + ]) } return ( @@ -68,7 +77,7 @@ const App = (props) => { - + diff --git a/client/src/components/Movie.js b/client/src/components/Movie.js index 5ba31122..18176c43 100644 --- a/client/src/components/Movie.js +++ b/client/src/components/Movie.js @@ -27,6 +27,9 @@ const Movie = (props) => { const handleToggle=()=>{ setIsToggled(!isToggled) } + const handleFav=()=>{ + addToFavorites(movie) + } @@ -59,7 +62,7 @@ const Movie = (props) => { {!isToggled &&
- Favorite + Favorite Edit