diff --git a/client/package.json b/client/package.json index 584db298e..60fe14101 100644 --- a/client/package.json +++ b/client/package.json @@ -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", diff --git a/client/src/App.js b/client/src/App.js index 888babb50..faa04262a 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -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 ( <> - + Add movie + { + return ( + + ); + }} + /> { - return ; + return ( + + ); + }} + /> + { + return ( + + ); + }} + /> + { + return ; }} /> > ); }; -export default App; +export default withRouter(App); diff --git a/client/src/Movies/AddMovieForm.js b/client/src/Movies/AddMovieForm.js new file mode 100644 index 000000000..84d578dd8 --- /dev/null +++ b/client/src/Movies/AddMovieForm.js @@ -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 ( + { + return ( + + + Director + + + + Title + + + + Metascore + + + ( + + {props.values.stars && props.values.stars.length > 0 ? ( + props.values.stars.map((star, index) => ( + + + arrayHelpers.remove(index)} // remove a friend from the list + > + - + + arrayHelpers.insert(index, "")} // insert an empty string at a position + > + + + + + )) + ) : ( + arrayHelpers.push("")}> + {/* show this when user has removed all friends from the list */} + Add a star + + )} + + )} + /> + Submit + + ); + }} + /> + ); +} diff --git a/client/src/Movies/Movie.js b/client/src/Movies/Movie.js index 3baccbe95..194c09689 100644 --- a/client/src/Movies/Movie.js +++ b/client/src/Movies/Movie.js @@ -1,6 +1,9 @@ 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); @@ -8,40 +11,51 @@ export default class Movie extends React.Component { 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 Loading movie information...; } - + return ( Save + + Update + + this.onClickToDeleteMovie(this.state.movie.id)}> + Delete + ); } diff --git a/client/src/Movies/MovieList.js b/client/src/Movies/MovieList.js index b553fb1b0..67002cb7b 100644 --- a/client/src/Movies/MovieList.js +++ b/client/src/Movies/MovieList.js @@ -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 ( - {this.state.movies.map(movie => ( + {this.props.listMovies.map(movie => ( ))} diff --git a/client/src/Movies/SavedList.js b/client/src/Movies/SavedList.js index 5ccf15db2..cf75ec8e4 100644 --- a/client/src/Movies/SavedList.js +++ b/client/src/Movies/SavedList.js @@ -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); diff --git a/client/src/Movies/UpdateMovieForm.js b/client/src/Movies/UpdateMovieForm.js new file mode 100644 index 000000000..2aee9a13f --- /dev/null +++ b/client/src/Movies/UpdateMovieForm.js @@ -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 ( + + { + return ( + + + Director + + + + Title + + + + Metascore + + + { + return ( + + {props.values.stars.map((star, index) => { + return ; + })} + + ); + }} + /> + Submit + + ); + }} + /> + + ); +} \ No newline at end of file diff --git a/client/yarn.lock b/client/yarn.lock index e4d3fbbd7..43eff3648 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -1441,7 +1441,7 @@ arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" -asap@~2.0.6: +asap@~2.0.3, asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -2313,6 +2313,11 @@ core-js@3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.1.4.tgz#3a2837fc48e582e1ae25907afcd6cf03b0cc7a07" +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= + core-js@^2.4.0: version "2.6.9" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" @@ -2358,6 +2363,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" +create-react-context@^0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.2.3.tgz#9ec140a6914a22ef04b8b09b7771de89567cb6f3" + integrity sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag== + dependencies: + fbjs "^0.8.0" + gud "^1.0.0" + cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -2656,6 +2669,11 @@ deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" +deepmerge@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" + integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== + default-gateway@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" @@ -2917,6 +2935,13 @@ encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= + dependencies: + iconv-lite "~0.4.13" + end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" @@ -3395,6 +3420,19 @@ fb-watchman@^2.0.0: dependencies: bser "^2.0.0" +fbjs@^0.8.0: + version "0.8.17" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" + integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.18" + figgy-pudding@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" @@ -3558,6 +3596,21 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +formik@^1.5.8: + version "1.5.8" + resolved "https://registry.yarnpkg.com/formik/-/formik-1.5.8.tgz#eee8cd345effe46839bc748c7f920486f12f14b0" + integrity sha512-fNvPe+ddbh+7xiByT25vuso2p2hseG/Yvuj211fV1DbCjljUEG9OpgRpcb7g7O3kxHX/q31cbZDzMxJXPWSNwA== + dependencies: + create-react-context "^0.2.2" + deepmerge "^2.1.1" + hoist-non-react-statics "^3.3.0" + lodash "^4.17.14" + lodash-es "^4.17.14" + prop-types "^15.6.1" + react-fast-compare "^2.0.1" + tiny-warning "^1.0.2" + tslib "^1.9.3" + forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -3882,7 +3935,7 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^3.1.0: +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b" dependencies: @@ -4023,7 +4076,7 @@ https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" -iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" dependencies: @@ -4401,7 +4454,7 @@ is-root@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" -is-stream@^1.1.0: +is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -4451,6 +4504,14 @@ isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -5132,6 +5193,11 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +lodash-es@^4.17.14: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" + integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ== + lodash._reinterpolate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" @@ -5522,6 +5588,14 @@ no-case@^2.2.0: dependencies: lower-case "^1.1.1" +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + node-forge@0.7.5: version "0.7.5" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" @@ -6757,6 +6831,13 @@ promise@8.0.3: dependencies: asap "~2.0.6" +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + prompts@^2.0.1: version "2.2.1" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.2.1.tgz#f901dd2a2dfee080359c0e20059b24188d75ad35" @@ -6764,7 +6845,7 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.3" -prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" dependencies: @@ -6951,6 +7032,11 @@ react-error-overlay@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.1.tgz#b8d3cf9bb991c02883225c48044cb3ee20413e0f" +react-fast-compare@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" + integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== + react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4: version "16.9.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb" @@ -7542,7 +7628,7 @@ set-value@^2.0.0, set-value@^2.0.1: is-plain-object "^2.0.3" split-string "^3.0.1" -setimmediate@^1.0.4: +setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -8156,7 +8242,7 @@ ts-pnp@1.1.2, ts-pnp@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.2.tgz#be8e4bfce5d00f0f58e0666a82260c34a57af552" -tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.10.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" @@ -8205,6 +8291,11 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" +ua-parser-js@^0.7.18: + version "0.7.20" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098" + integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw== + uglify-js@3.4.x: version "3.4.10" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" @@ -8550,7 +8641,7 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" -whatwg-fetch@3.0.0: +whatwg-fetch@3.0.0, whatwg-fetch@>=0.10.0: version "3.0.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"