From 77bb1424863e8f8a468b6901c9c39de2e0627065 Mon Sep 17 00:00:00 2001 From: Hughes Date: Tue, 2 Nov 2021 19:01:09 -0500 Subject: [PATCH] mvp --- package-lock.json | 71 ++++++++++++++++------------- package.json | 4 +- src/App.js | 10 +++- src/actions/favoriteActions.js | 23 ++++++++++ src/actions/movieActions.js | 10 ++++ src/components/AddMovieForm.js | 24 +++++++--- src/components/FavoriteMovieList.js | 18 ++++++-- src/components/Movie.js | 29 +++++++++--- src/components/MovieHeader.js | 19 ++++++-- src/components/MovieList.js | 13 ++++-- src/index.js | 2 + src/reducers/favoriteReducer.js | 34 ++++++++++++++ src/reducers/movieReducer.js | 12 ++++- 13 files changed, 207 insertions(+), 62 deletions(-) create mode 100644 src/actions/favoriteActions.js create mode 100644 src/reducers/favoriteReducer.js diff --git a/package-lock.json b/package-lock.json index 0d7da9d4..a0928bce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1614,9 +1614,9 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "@types/prop-types": { - "version": "15.7.3", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" + "version": "15.7.4", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" }, "@types/q": { "version": "1.5.4", @@ -1624,9 +1624,9 @@ "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, "@types/react": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.3.tgz", - "integrity": "sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.33.tgz", + "integrity": "sha512-pLWntxXpDPaU+RTAuSGWGSEL2FRTNyRQOjSWDke/rxRg14ncsZvx8AKWMWZqvc1UOaJIAoObdZhAWvRaHFi5rw==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -1634,9 +1634,9 @@ } }, "@types/react-redux": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz", - "integrity": "sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw==", + "version": "7.1.20", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.20.tgz", + "integrity": "sha512-q42es4c8iIeTgcnB+yJgRTTzftv3eYYvCZOh1Ckn2eX/3o5TdsQYKUWpLoLuGlcY/p+VAhV9IOEZJcWk/vfkXw==", "requires": { "@types/hoist-non-react-statics": "^3.3.0", "@types/react": "*", @@ -1645,9 +1645,9 @@ } }, "@types/scheduler": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", - "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==" + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "@types/stack-utils": { "version": "1.0.1", @@ -4076,9 +4076,9 @@ } }, "csstype": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.7.tgz", - "integrity": "sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g==" + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", + "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" }, "cyclist": { "version": "1.0.1", @@ -10591,16 +10591,31 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-redux": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.3.tgz", - "integrity": "sha512-ZhAmQ1lrK+Pyi0ZXNMUZuYxYAZd59wFuVDGUt536kSGdD0ya9Q7BfsE95E3TsFLE3kOSFp5m6G5qbatE+Ic1+w==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz", + "integrity": "sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==", "requires": { - "@babel/runtime": "^7.12.1", - "@types/react-redux": "^7.1.16", + "@babel/runtime": "^7.15.4", + "@types/react-redux": "^7.1.20", "hoist-non-react-statics": "^3.3.2", "loose-envify": "^1.4.0", "prop-types": "^15.7.2", - "react-is": "^16.13.1" + "react-is": "^17.0.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.0.tgz", + "integrity": "sha512-Nht8L0O8YCktmsDV6FqFue7vQLRx3Hb0B37lS5y0jDRqRxlBG4wIJHnf9/bgSE2UyipKFA01YtS+npRdTWBUyw==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + } } }, "react-router": { @@ -10748,12 +10763,11 @@ } }, "redux": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz", - "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz", + "integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==", "requires": { - "loose-envify": "^1.4.0", - "symbol-observable": "^1.2.0" + "@babel/runtime": "^7.9.2" } }, "regenerate": { @@ -12215,11 +12229,6 @@ "util.promisify": "~1.0.0" } }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" - }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", diff --git a/package.json b/package.json index 8ec2acec..6d995649 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,10 @@ "axios": "^0.19.0", "react": "^16.9.0", "react-dom": "^16.9.0", - "react-redux": "^7.2.3", + "react-redux": "^7.2.6", "react-router-dom": "^5.0.1", "react-scripts": "^3.1.1", - "redux": "^4.0.5" + "redux": "^4.1.2" }, "scripts": { "start": "react-scripts start", diff --git a/src/App.js b/src/App.js index cb66bfe6..4480e882 100644 --- a/src/App.js +++ b/src/App.js @@ -12,7 +12,7 @@ import AddMovieForm from './components/AddMovieForm'; import FavoriteMovieList from './components/FavoriteMovieList'; const App = props => { - const displayFavorites = true; + const { displayFavorites } = props; return (
@@ -48,4 +48,10 @@ const App = props => { ); }; -export default App; \ No newline at end of file +const mapStateToProps = (state) => { + return ({ + displayFavorites: state.favoriteReducer.displayFavorites + }) +} + +export default connect(mapStateToProps, {})(App); \ No newline at end of file diff --git a/src/actions/favoriteActions.js b/src/actions/favoriteActions.js new file mode 100644 index 00000000..acb90acb --- /dev/null +++ b/src/actions/favoriteActions.js @@ -0,0 +1,23 @@ +export const TOGGLE_FAVORITES = "TOGGLE_FAVORITES"; + +export const ADD_FAVORITES = "ADD_FAVORITES"; + +export const DELETE_FAVORITES = "DELETE_FAVORITES"; + +export const toggleFavorites = () => { + return({ + type: TOGGLE_FAVORITES + }) +} + +export const addFavorites = (movie) => { + return({ + type: ADD_FAVORITES, payload: movie + }) +} + +export const deleteFavorites = (movie) => { + return ({ + type: DELETE_FAVORITES, payload: movie + }) +} \ No newline at end of file diff --git a/src/actions/movieActions.js b/src/actions/movieActions.js index 3fb8c9dd..85474920 100644 --- a/src/actions/movieActions.js +++ b/src/actions/movieActions.js @@ -1,5 +1,15 @@ export const DELETE_MOVIE = "DELETE_MOVIE"; +export const ADD_MOVIE = "ADD_MOVIE" export const deleteMovie = (id)=>{ return({type: DELETE_MOVIE, payload:id}); +} + +export const addMovie = (movie) => { + console.log(movie) + + return({ + type: ADD_MOVIE, + payload: movie + }) } \ No newline at end of file diff --git a/src/components/AddMovieForm.js b/src/components/AddMovieForm.js index d8a4d768..15667be1 100644 --- a/src/components/AddMovieForm.js +++ b/src/components/AddMovieForm.js @@ -6,13 +6,15 @@ import { Link, useHistory } from 'react-router-dom'; const AddMovieForm = (props) => { const { push } = useHistory(); + const { addMovie } = props; const [movie, setMovie] = useState({ title: "", director: "", genre: "", metascore: 0, - description:"" + description:"", + id: Date.now() }); const handleChange = (e) => { @@ -23,6 +25,10 @@ const AddMovieForm = (props) => { } const handleSubmit = (e) => { + e.preventDefault() + addMovie(movie) + + push('/movies/') } const { title, director, genre, metascore, description } = movie; @@ -30,16 +36,16 @@ const AddMovieForm = (props) => {
-
+

Add Movie

-
+
-
+
@@ -50,12 +56,12 @@ const AddMovieForm = (props) => {
-
+
- +
@@ -67,4 +73,8 @@ const AddMovieForm = (props) => {
); } -export default AddMovieForm; \ No newline at end of file +const mapStateToProps = (state) => { + return({}) +} + +export default connect(mapStateToProps, {addMovie})(AddMovieForm); \ No newline at end of file diff --git a/src/components/FavoriteMovieList.js b/src/components/FavoriteMovieList.js index 54f4383f..7713c42f 100644 --- a/src/components/FavoriteMovieList.js +++ b/src/components/FavoriteMovieList.js @@ -1,10 +1,11 @@ import React from 'react'; - +import { connect } from 'react-redux'; import { Link } from 'react-router-dom'; +import { deleteFavorites } from '../actions/favoritesActions'; const FavoriteMovieList = (props) => { - const favorites = []; + const { favorites, displayFavorites, deleteFavorites } = props; return (
Favorite Movies
@@ -13,7 +14,10 @@ const FavoriteMovieList = (props) => { return
{movie.title} - remove_circle + { + deleteFavorites(movie.id) + }}>remove_circle
}) @@ -21,5 +25,11 @@ const FavoriteMovieList = (props) => {
); } +const mapStateToProps = (state) => { + return ({ + favorites: state.favoriteReducer.favorites, + displayFavorites: state.favoriteReducer.displayFavorites + }) +} -export default FavoriteMovieList; \ No newline at end of file +export default connect(mapStateToProps, {deleteFavorites})(FavoriteMovieList); \ No newline at end of file diff --git a/src/components/Movie.js b/src/components/Movie.js index 373201e5..ac115b06 100644 --- a/src/components/Movie.js +++ b/src/components/Movie.js @@ -1,17 +1,20 @@ import React from 'react'; import { useParams, useHistory } from 'react-router-dom'; +import { connect } from 'react-redux'; +import { deleteMovie } from '../actions/movieActions'; +import { addFavorites } from '../actions/favoritesActions'; const Movie = (props) => { const { id } = useParams(); const { push } = useHistory(); - const movies = []; + const { movies, deleteMovie, addFavorites } = props; const movie = movies.find(movie=>movie.id===Number(id)); return(
-
+

{movie.title} Details

@@ -35,10 +38,15 @@ const Movie = (props) => {

{movie.description}

- -
- Favorite - +
+ { + addFavorites(movie) + }}>Favorite + + { + deleteMovie(movie.id) + push('/movies') + }}>
@@ -47,4 +55,11 @@ const Movie = (props) => {
); } -export default Movie; \ No newline at end of file +const mapStateToProps = (state) => { + return({ + movies: state.movieReducer.movies, + displayFavorites: state.favoriteReducer.displayFavorites + }) +} + +export default connect(mapStateToProps, {deleteMovie, addFavorites})(Movie); \ No newline at end of file diff --git a/src/components/MovieHeader.js b/src/components/MovieHeader.js index e3443e5f..c14a6a18 100644 --- a/src/components/MovieHeader.js +++ b/src/components/MovieHeader.js @@ -1,9 +1,10 @@ import React from 'react'; import { Link } from 'react-router-dom'; +import { connect } from 'react-redux'; +import { toggleFavorites } from '../actions/favoritesActions'; const MovieHeader = (props) => { - const appTitle = ""; - const displayFavorites = true; + const { appTitle, displayFavorites, toggleFavorites } = props; return(
@@ -11,7 +12,10 @@ const MovieHeader = (props) => {

{appTitle}

-
{ displayFavorites ? "Hide" : "Show"} Favorites
+
{ + toggleFavorites() + }}>{ displayFavorites ? "Hide" : "Show"} Favorites
+ View All Movies Add New Movie
@@ -19,4 +23,11 @@ const MovieHeader = (props) => {
); } -export default MovieHeader; \ No newline at end of file +const mapStateToProps = (state) => { + return { + appTitle: state.movieReducer.appTitle, + displayFavorites: state.favoriteReducer.displayFavorites + } +} + +export default connect(mapStateToProps, {toggleFavorites})(MovieHeader); \ No newline at end of file diff --git a/src/components/MovieList.js b/src/components/MovieList.js index 268c7809..c4ab8c99 100644 --- a/src/components/MovieList.js +++ b/src/components/MovieList.js @@ -1,10 +1,11 @@ import React from 'react'; - +import { connect } from 'react-redux'; import MovieListItem from './MovieListItem'; import MovieFooter from './MovieFooter'; +import movies from '../data'; const MovieList = (props)=> { - const movies = []; + const { movies } = props; return (
@@ -31,4 +32,10 @@ const MovieList = (props)=> { ); } -export default MovieList; \ No newline at end of file +export const mapStateToProps = (state) => { + return { + movies: state.movieReducer.movies + } +} + +export default connect(mapStateToProps,{})(MovieList); \ No newline at end of file diff --git a/src/index.js b/src/index.js index dfc70e99..c1d1f2e1 100644 --- a/src/index.js +++ b/src/index.js @@ -11,7 +11,9 @@ import './index.css'; ReactDOM.render( + + , document.getElementById('root') ); diff --git a/src/reducers/favoriteReducer.js b/src/reducers/favoriteReducer.js new file mode 100644 index 00000000..28387a0d --- /dev/null +++ b/src/reducers/favoriteReducer.js @@ -0,0 +1,34 @@ +import { TOGGLE_FAVORITES, ADD_FAVORITES, DELETE_FAVORITES } from "../actions/favoritesActions"; + +const initialState = { + favorites: [], + displayFavorites: true +} + +const reducer = (state = initialState, action) => { + switch(action.type) { + + case TOGGLE_FAVORITES: + return { + ...state, + displayFavorites: !state.displayFavorites + } + + case ADD_FAVORITES: + return { + ...state, + favorites: [ ...state.favorites, action.payload] + } + + case DELETE_FAVORITES: + return { + ...state, + favorites: state.favorites.filter(favorite => (action.payload !== favorite.id)) + } + + default: + return state; + } +} + +export default reducer; \ No newline at end of file diff --git a/src/reducers/movieReducer.js b/src/reducers/movieReducer.js index 16f33bcd..fa62f5f1 100644 --- a/src/reducers/movieReducer.js +++ b/src/reducers/movieReducer.js @@ -1,17 +1,25 @@ import { ADD_MOVIE, DELETE_MOVIE } from '../actions/movieActions.js'; import movies from './../data.js'; -const initialState = { +export const initialState = { movies: movies, appTitle: "IMDB Movie Database" } -const reducer = (state, action) => { +const reducer = (state = initialState, action) => { switch(action.type) { case DELETE_MOVIE: return { + ...state, movies: state.movies.filter(item=>(action.payload !== item.id)) } + + case ADD_MOVIE: + return { + ...state, + movies: state.movies.filter(item => (action.payload !== item.id)) + } + default: return state; }