Create .env file and add DATABASE_URL and SECRET. (Ben will share URL)
1. Gabriela - Write the model for Movies & TV Shows.
Gabriela will start by checking out into a branch to develop her feature. (When working in a group, you should NEVER put changes directly into the main/master branch of the repository. The 'git Commander' will push that code once it has been tested for functionality.)
git checkout -b models
Now, she'll create the model files and add the code:
Now, Gabriela will push her feature branch to her origin (the fork of the main class code-along) Use git push <remote> <branch> to push a branch to a repository.
git add .
git commit -m 'add models'
git push origin models
git checkout main <-- Don't forget to checkout back to main branch!!!
Gabriela will now log into her GitHub and submit a pull request on her repository with the changes. One of the instructors will approve/deny the pull request and merge the changes. EVERYONE needs to pull the code after the pull request is merged to prevent merge conflicts.
git pull upstream main
If you do end up with merge conflicts because you've added something before pulling code, you can sync back up with the latest commit by using:
git fetch --all
git reset --hard upstream/main
Great job Gabriela!
2. Cem - Stub up the movie & tv show controllers (bring in the model, stub up exports).
8. David - Stub up the <AddMovie> component (create basic class component and display the page name in a simple HTML element). Create a CSS file for <AddMovie>, (add a flex display, centering, and a margin) and import it within the component.
// AddMovie.jsximportReact,{Component}from'react';import'./AddMovie.css';classAddMovieextendsComponent{state={};render(){return(<h3>Add Movie Page</h3>)}}exportdefaultAddMovie;
9. Karen - Import the <AddMovie> component in App.js and write a Route for it such that the user is redirected to log in if they aren't. Import the function to create a movie in App.js, write a handleAddMovie function, and pass it to <AddMovie> along with the user stored in state.
10. Pratik - Add state in <AddMovie> (for formData and form validation). Create a formRef in <AddMovie> and display a form with all movie fields and a button to submit the form. Write the handleSubmit and handleChange functions on <AddMovie>.
// AddMovie.jsximportReact,{Component}from'react';import'./AddMovie.css';classAddMovieextendsComponent{state={invalidForm: true,formData: {name: '',cast: [],description: '',mpaaRating: '',releaseDate: '',runTime: '',genre: '',imdbRating: '',image: '',},};formRef=React.createRef();handleSubmit=e=>{e.preventDefault();this.props.handleAddMovie(this.state.formData);};handleChange=e=>{constformData={...this.state.formData,[e.target.name]: e.target.value};this.setState({
formData,invalidForm: !this.formRef.current.checkValidity()});};render(){return(<><divclassName="AddMovie"><formclassName="col s12"ref={this.formRef}onSubmit={this.handleSubmit}><divclassName="row"><divclassName="input-field col s12"><inputname="name"id="movie_name"type="text"className="active"value={this.state.formData.name}onChange={this.handleChange}required/><labelhtmlFor="movie_name">Movie Name</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="cast"id="cast"type="text"className="active"value={this.state.formData.cast}onChange={this.handleChange}required/><labelhtmlFor="cast">Cast (Separate with commas)</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="description"id="description"type="text"className="active"value={this.state.formData.description}onChange={this.handleChange}/><labelhtmlFor="description">Description</label></div></div><div><label>MPAA Rating</label><p><label><inputclassName="with-gap"name="mpaaRating"value="G"onChange={this.handleChange}type="radio"/><span>G</span></label></p><p><label><inputclassName="with-gap"name="mpaaRating"value="PG"onChange={this.handleChange}type="radio"/><span>PG</span></label></p><p><label><inputclassName="with-gap"name="mpaaRating"value="PG-13"onChange={this.handleChange}type="radio"/><span>PG-13</span></label></p><p><label><inputclassName="with-gap"name="mpaaRating"value="R"onChange={this.handleChange}type="radio"/><span>R</span></label></p><p><label><inputclassName="with-gap"name="mpaaRating"value="NC-17"onChange={this.handleChange}type="radio"/><span>NC-17</span></label></p></div><divclassName="row"><divclassName="input-field col s12"><inputname="releaseDate"id="release"type="text"className="active"value={this.state.formData.releaseDate}onChange={this.handleChange}/><labelhtmlFor="release">Release Year</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="runTime"id="runtime"type="text"className="active"value={this.state.formData.runTime}onChange={this.handleChange}/><labelhtmlFor="runtime">Run-time (Min)</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="genre"id="genre"type="text"className="active"value={this.state.formData.genre}onChange={this.handleChange}/><labelhtmlFor="genre">Genre</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="imdbRating"id="imdb"type="text"className="active"value={this.state.formData.imdbRating}onChange={this.handleChange}/><labelhtmlFor="imdb">IMDB Rating</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="image"id="imageURL"type="text"className="active"value={this.state.formData.image}onChange={this.handleChange}/><labelhtmlFor="imageURL">Image URL</label></div></div><buttontype="submit"className="btn red"disabled={this.state.invalidForm}><iclassName="material-icons left">add</i>
Add Movie
</button></form></div></>)}}exportdefaultAddMovie;
11. Earl - Write the route / controller function in the back end to index movies. Write the API call in movies-api.js to index movies.
// routes/movies.jsconstrouter=require('express').Router();constmoviesCtrl=require('../controllers/movies');// Public Routesrouter.get('/',moviesCtrl.index);// Protected Routesrouter.use(require('../config/auth'));router.post('/',checkAuth,moviesCtrl.create);functioncheckAuth(req,res,next){if(req.user)returnnext();returnres.status(401).json({msg: 'Not Authorized'});}module.exports=router;
13. Dan - Stub up the <MovieList> component (create a basic function component and display the page name in a simple HTML element). Create a CSS file for the <MovieList> page and import it within the component. Import the <MovieList> component in App.js and write a route for it, (pass state for movies and user as props).
14. Anderson - Create a <MovieCard> component in the 'components' directory, stub it up with a presentational component that displays a message when rendered (don't display any props yet)
15. Robert - Write the router / controller for deleting a movie. Write the API call in movies-api.js to handle deleting a movie by id. Write a handleDeleteMovie function in App.js and pass it as props to <MovieList>.
16. Will - Import <MovieCard> component in the <MovieList> component and them map props (movie, delete, and user) to <MovieCard> components to be rendered.
17. Chloe - Add a Materialize 'Card' to display the info passed in as props for a movie on the <MovieCard> component, implement a <Link> component to add a Materialize button that will pass the movie to '/edit'.
18. Cory - Write the router / controller for updating a movie. Write the API call in movies-api.js to handle updating a movie by id. Add a handleUpdateMovie function in App.js.
// routes/movies.jsconstrouter=require('express').Router();constmoviesCtrl=require('../controllers/movies');// Public Routesrouter.get('/',moviesCtrl.index);// Protected Routesrouter.use(require('../config/auth'));router.post('/',checkAuth,moviesCtrl.create);router.delete('/:id',checkAuth,moviesCtrl.delete);router.put('/:id',checkAuth,moviesCtrl.update)functioncheckAuth(req,res,next){if(req.user)returnnext();returnres.status(401).json({msg: 'Not Authorized'});}module.exports=router;
19. Alex - Create an <EditMovie> folder/component in the 'components' directory. Create the matching CSS file and add the same formatting from <AddMovie>. Copy and paste the contents of <AddMovie> to <EditMovie>, then make changes to reflect editing (initialize state using location, change the 'Add' button to a 'Save' button, and update the MPAA rating fields to show the current value when the page is loaded, and add a <Link> for the user to cancel and be returned to the movie list).
21. Alexandria - Write the route / controller function in the back end for creating a tv show. Write the API call in tvshows-api.js to create a tv show.
22. Brett - Stub up the <AddTVShow> component (create basic class component and display the page name in a simple HTML element). Create a CSS file for <AddTVShow>, (add a flex display, centering, and a margin) and import it within the component.
// AddTVShow.jsximportReact,{Component}from'react';import'./AddTVShow.css';classAddTVShowextendsComponent{state={};render(){return(<h3>Add TV Show Page</h3>)}}exportdefaultAddTVShow;
23. Will - Import the <AddTVShow> component in App.js and write a Route for it such that the user is redirected to log in if they aren't. Import the function to create a tv show in App.js, write a handleAddTVShow function, and pass it to <AddTVShow> along with the user stored in state.
24. Jam - Add state in <AddTVShow> (for formData and form validation). Create a formRef in <AddTVShow> and display a form with all tv show fields and a button to submit the form. Write the handleSubmit and handleChange functions on <AddTVShow>.
// AddTVShow.jsximportReact,{Component}from'react';import'./AddTVShow.css'classAddTVShowextendsComponent{state={invalidForm: true,formData: {name: '',cast: [],description: '',seasons: '',releaseDate: '',episodes: '',imdbRating: '',image: ''}};formRef=React.createRef();handleSubmit=e=>{e.preventDefault();this.props.handleAddTVShow(this.state.formData);};handleChange=e=>{constformData={...this.state.formData,[e.target.name]: e.target.value};this.setState({
formData,invalidForm: !this.formRef.current.checkValidity()});};render(){return(<><divclassName="AddTVShow"><formclassName="col s12"ref={this.formRef}onSubmit={this.handleSubmit}><divclassName="row"><divclassName="input-field col s12"><inputname="name"id="name"type="text"className="active"value={this.state.formData.name}onChange={this.handleChange}required/><labelhtmlFor="name">TV Show Name</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="cast"id="cast"type="text"className="active"value={this.state.formData.cast}onChange={this.handleChange}required/><labelhtmlFor="cast">Cast (Separate with commas)</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="description"id="description"type="text"className="active"value={this.state.formData.description}onChange={this.handleChange}/><labelhtmlFor="description">Description</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="releaseDate"id="release"type="text"className="active"value={this.state.formData.releaseDate}onChange={this.handleChange}/><labelhtmlFor="release">Release Year</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="seasons"id="seasons"type="text"className="active"value={this.state.formData.seasons}onChange={this.handleChange}/><labelhtmlFor="seasons">Seasons</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="episodes"id="episodes"type="text"className="active"value={this.state.formData.episodes}onChange={this.handleChange}/><labelhtmlFor="episodes">Episodes</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="imdbRating"id="imdbRating"type="text"className="active"value={this.state.formData.imdbRating}onChange={this.handleChange}/><labelhtmlFor="imdbRating">IMDB Rating</label></div></div><divclassName="row"><divclassName="input-field col s12"><inputname="image"id="imageURL"type="text"className="active"value={this.state.formData.image}onChange={this.handleChange}/><labelhtmlFor="imageURL">Image URL</label></div></div><buttontype="submit"className="btn red"disabled={this.state.invalidForm}><iclassName="material-icons left">add</i>
Add TV Show
</button></form></div></>)}}exportdefaultAddTVShow;
25. Anderson - Write the route / controller function in the back end to index tv shows. Write the API call in tvshows-api.js to index tv shows.
// routes/tvshows.jsconstrouter=require('express').Router();consttvshowsCtrl=require('../controllers/tvshows');// Public Routesrouter.get('/',tvshowsCtrl.index);// Protected Routesrouter.use(require('../config/auth'));router.post('/',checkAuth,tvshowsCtrl.create);functioncheckAuth(req,res,next){if(req.user)returnnext();returnres.status(401).json({msg: 'Not Authorized'});}module.exports=router;
27. Robert - Stub up the <TVShowList> component (create a basic function component and display the page name in a simple HTML element) Create a CSS file for the <TVShowList> page and import it within the component. Import the <TVShowList> component in App.js and write a route for it, (pass state for tv shows and user as props).
28. Dan - Create a <TVShowCard> folder/component in the 'components' directory, stub it up with a presentational component that displays a message when rendered (don't display any props yet).
importReactfrom'react';import{Link}from'react-router-dom';functionTVShowCard(){return(<h3>TV Show Card</h3>)}exportdefaultTVShowCard;
29. Kailah - Write the router / controller for deleting a tv show. Write the API call in tvshow-api.js to handle deleting a tv show by id. Write a handleDeleteTVShow function in App.js and pass it as props to <TVShowList>.
30. Karen - Import <TVShowCard> component in the <TVShowList> component and them map props (tvshow, delete, and user) to <TVShowCard> components to be rendered. Add a Materialize 'Card' to display the info passed in as props for a tv show on the <TVShowCard> component, implement a <Link> component to add a Materialize button that will pass the movie to '/edit'.
31. Cory - Write the router / controller for updating a tv show. Write the API call in tvshows-api.js to handle updating a tv show by id. Add a handleUpdateTVShow function in App.js.
// routes/tvshows.jsconstrouter=require('express').Router();consttvshowsCtrl=require('../controllers/tvshows');// Public Routesrouter.get('/',tvshowsCtrl.index);// Protected Routesrouter.use(require('../config/auth'));router.post('/',checkAuth,tvshowsCtrl.create);router.put('/:id',checkAuth,tvshowsCtrl.update);router.delete('/:id',checkAuth,tvshowsCtrl.delete);functioncheckAuth(req,res,next){if(req.user)returnnext();returnres.status(401).json({msg: 'Not Authorized'});}module.exports=router;
32. Stavon - Create an <EditTVShow> folder/component in the 'components' directory, stub it up with a class component. Copy and paste the contents of <AddTVShow> to <EditTVShow>, then make changes to reflect editing (initialize state using location, change the 'Add' button to a 'Save' button, and add a <Link> for the user to cancel and be returned to the tv show list).