Skip to content

setup #95

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
50 changes: 25 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<EditMovieForm> `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 `<EditMovieForm> `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.
Expand Down
20 changes: 15 additions & 5 deletions client/src/App.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
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';
import AddMovieForm from './components/AddMovie';

import MovieHeader from './components/MovieHeader';

Expand All @@ -12,20 +13,24 @@ import FavoriteMovieList from './components/FavoriteMovieList';
import axios from 'axios';

const App = (props) => {
const { id } = props;
const [movies, setMovies] = useState([]);
const [favoriteMovies, setFavoriteMovies] = useState([]);

useEffect(()=>{
axios.get('http://localhost:5000/api/movies')

axios.get(`http://localhost:5000/api/movies`)
.then(res => {
setMovies(res.data);
})
.catch(err => {
console.log(err);
});
}, []);
}, [movies]);

const deleteMovie = (id)=> {
setMovies(movies.filter(movie => movie.id !== Number(id)));

}

const addToFavorites = (movie) => {
Expand All @@ -45,14 +50,19 @@ const App = (props) => {

<Switch>
<Route path="/movies/edit/:id">
<EditMovieForm/>
</Route>

<Route path="/movies/:id">
<Movie/>
<Movie {...props} deleteMovie={deleteMovie}/>
</Route>

<Route path="/movies">
<MovieList movies={movies}/>
<MovieList movies={movies} id={id}/>
</Route>

<Route path="/add">
<AddMovieForm setMovies={setMovies}/>
</Route>

<Route path="/">
Expand Down
75 changes: 75 additions & 0 deletions client/src/components/AddMovie.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
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 [newMovie, setNewMovie] = useState({
title:"",
director: "",
genre: "",
metascore: 0,
description: ""
});

const handleChange = (e) => {
setNewMovie({
...newMovie,
[e.target.name]: e.target.value
});
}

const handleSubmit = (e) => {
e.preventDefault();
axios.post(`http://localhost:5000/api/movies`, newMovie)
.then(res=> {
props.setMovies(res.data)
push(`/movies`)
})
.catch(err=> console.log(err))
}

const { title, director, genre, metascore, description } = newMovie;

return (
<div className="col">
<div className="modal-content">
<form onSubmit={handleSubmit}>
<div className="modal-header">
<h4 className="modal-title">Add New Movie</h4>
</div>
<div className="modal-body">
<div className="form-group">
<label>Title</label>
<input value={title} onChange={handleChange} name="title" type="text" className="form-control"/>
</div>
<div className="form-group">
<label>Director</label>
<input value={director} onChange={handleChange} name="director" type="text" className="form-control"/>
</div>
<div className="form-group">
<label>Genre</label>
<input value={genre} onChange={handleChange} name="genre" type="text" className="form-control"/>
</div>
<div className="form-group">
<label>Metascore</label>
<input value={metascore} onChange={handleChange} name="metascore" type="number" className="form-control"/>
</div>
<div className="form-group">
<label>Description</label>
<textarea value={description} onChange={handleChange} name="description" className="form-control"></textarea>
</div>

</div>
<div className="modal-footer">
<input type="submit" className="btn btn-info" value="Add"/>
<Link to={`/movies/1`}><input type="button" className="btn btn-default" value="Cancel"/></Link>
</div>
</form>
</div>
</div>);
}

export default AddMovieForm
1 change: 1 addition & 0 deletions client/src/components/DeleteMovieModal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import axios from 'axios';
import React from 'react';

const DeleteMovieModal = () => {
Expand Down
17 changes: 16 additions & 1 deletion client/src/components/EditMovieForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { Link } from 'react-router-dom';

import axios from 'axios';

const EditMovieForm = (props) => {
const EditMovieForm = props => {

const { id } = useParams();
const { push } = useHistory();

const [movie, setMovie] = useState({
Expand All @@ -15,6 +17,13 @@ const EditMovieForm = (props) => {
description: ""
});

useEffect(() => {
axios
.get(`http://localhost:5000/api/movies/${id}`)
.then((res) => setMovie(res.data))
.catch((err) => console.log(err))
},[]);

const handleChange = (e) => {
setMovie({
...movie,
Expand All @@ -24,6 +33,12 @@ const EditMovieForm = (props) => {

const handleSubmit = (e) => {
e.preventDefault();
axios
.put(`http://localhost:5000/api/movies/${id}`, movie )
.then((res) => {
setMovie(res.data[id])
push(`/movies/${id}`)})
.catch((err) => console.log(err));
}

const { title, director, genre, metascore, description } = movie;
Expand Down
13 changes: 12 additions & 1 deletion client/src/components/Movie.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import axios from 'axios';

const Movie = (props) => {
const { addToFavorites } = props;
// const { deleteMovie } = props;

const [movie, setMovie] = useState('');

Expand All @@ -21,6 +22,16 @@ const Movie = (props) => {
})
}, [id]);


const handleDelete = ()=> {
axios.delete(`http://localhost:5000/api/movies/${id}`)
.then(res=> {
props.deleteMovie(id)
push('/movies')
})
.catch(err=> console.log(err))
}

return(<div className="modal-page col">
<div className="modal-dialog">
<div className="modal-content">
Expand Down Expand Up @@ -52,7 +63,7 @@ const Movie = (props) => {
<section>
<span className="m-2 btn btn-dark">Favorite</span>
<Link to={`/movies/edit/${movie.id}`} className="m-2 btn btn-success">Edit</Link>
<span className="delete"><input type="button" className="m-2 btn btn-danger" value="Delete"/></span>
<span className="delete"><input type="button" className="m-2 btn btn-danger" value="Delete" onClick={handleDelete}/></span>
</section>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/MovieHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const MovieHeader = ()=> {
<h2>IMDB Movie Database</h2>
</div>
<div className="col-sm-6">
<Link className="btn btn-success"><i className="material-icons">&#xE147;</i> <span>Add New Movie</span></Link>
<Link to="/add" className="btn btn-success"><i className="material-icons">&#xE147;</i> <span>Add New Movie</span></Link>
<Link to="/movies" className="btn btn-primary">View All Movies</Link>
</div>
</div>
Expand Down