diff --git a/bawan-shna-abdulrahman/package-lock.json b/bawan-shna-abdulrahman/package-lock.json index e39d511e..16488da5 100644 --- a/bawan-shna-abdulrahman/package-lock.json +++ b/bawan-shna-abdulrahman/package-lock.json @@ -4376,6 +4376,11 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, "default-gateway": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", @@ -6439,6 +6444,19 @@ "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -6449,6 +6467,14 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, "hosted-git-info": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", @@ -7974,6 +8000,11 @@ "strip-bom": "^3.0.0" } }, + "load-script": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", + "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=" + }, "loader-fs-cache": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz", @@ -8222,6 +8253,11 @@ "p-is-promise": "^2.0.0" } }, + "memoize-one": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz", + "integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==" + }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -8361,6 +8397,15 @@ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" }, + "mini-create-react-context": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz", + "integrity": "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==", + "requires": { + "@babel/runtime": "^7.5.5", + "tiny-warning": "^1.0.3" + } + }, "mini-css-extract-plugin": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", @@ -10874,6 +10919,11 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.7.tgz", "integrity": "sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==" }, + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -10899,6 +10949,76 @@ "warning": "^4.0.3" } }, + "react-player": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-player/-/react-player-2.4.0.tgz", + "integrity": "sha512-INg6BOPV0ry2Q7e43zU0ePrB81K6HKO5wGovGE6yOt9OYGa33ehAb3gDWllC/vUA0R1ggSTtkkTFak6LWUGgNw==", + "requires": { + "deepmerge": "^4.0.0", + "load-script": "^1.0.0", + "memoize-one": "^5.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.0.1" + } + }, + "react-redux": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.0.tgz", + "integrity": "sha512-EvCAZYGfOLqwV7gh849xy9/pt55rJXPwmYvI4lilPM5rUT/1NxuuN59ipdBksRVSvz0KInbPnp4IfoXJXCqiDA==", + "requires": { + "@babel/runtime": "^7.5.5", + "hoist-non-react-statics": "^3.3.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^16.9.0" + } + }, + "react-router": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", + "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.4.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "requires": { + "isarray": "0.0.1" + } + } + } + }, + "react-router-dom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", + "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.2.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + } + }, "react-scripts": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz", @@ -11081,6 +11201,15 @@ "strip-indent": "^3.0.0" } }, + "redux": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz", + "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==", + "requires": { + "loose-envify": "^1.4.0", + "symbol-observable": "^1.2.0" + } + }, "regenerate": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", @@ -11322,6 +11451,11 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -12531,6 +12665,11 @@ "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", @@ -12782,6 +12921,16 @@ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -13172,6 +13321,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/bawan-shna-abdulrahman/package.json b/bawan-shna-abdulrahman/package.json index 6dad3cc0..3756eee6 100644 --- a/bawan-shna-abdulrahman/package.json +++ b/bawan-shna-abdulrahman/package.json @@ -17,16 +17,20 @@ "react": "^16.13.1", "react-bootstrap": "^1.0.1", "react-dom": "^16.13.1", + "react-player": "^2.4.0", + "react-redux": "^7.2.0", + "react-router-dom": "^5.2.0", "react-scripts": "3.4.1", - "react-simple-flex-grid": "^1.3.21" + "react-simple-flex-grid": "^1.3.21", + "redux": "^4.0.5" }, "scripts": { "predeploy": "npm run build", - "deploy": "gh-pages -d build", - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" + "deploy": "npx gh-pages -d build", + "start": "npx react-scripts start", + "build": "npx react-scripts build", + "test": "npx react-scripts test", + "eject": "npx react-scripts eject" }, "eslintConfig": { "extends": "react-app" diff --git a/bawan-shna-abdulrahman/src/App.js b/bawan-shna-abdulrahman/src/App.js index 3fb7dabd..e7b6bd9e 100644 --- a/bawan-shna-abdulrahman/src/App.js +++ b/bawan-shna-abdulrahman/src/App.js @@ -1,42 +1,31 @@ -import React, { useState } from "react"; +import React, { useState, useContext } from "react"; import "./App.css"; import "bootstrap/dist/css/bootstrap.css"; import Header from "./Components/Header"; import Main from "./Components/Main"; import Footer from "./Components/Footer"; +import MoviePage from "./Components/MoviePage"; +import Info from "./Components/info"; +import { BrowserRouter as Router, Route, Redirect } from "react-router-dom"; +import { StateProvider } from "./Components/StateProvider"; -function App() { - const [isLoading, setIsLoading] = useState(true); - const [query, setQuery] = useState(""); - const [movies, setMovies] = useState([]); - - const handleQuery = (query) => { - setQuery(query); - }; - - const handleMovies = (movies) => { - setMovies(movies); - setIsLoading(false); - }; - +export default function App() { return ( -
-
-
-
+ +
+
+ +
+ + + + + + + +
+
-
-
+ ); } -export default App; diff --git a/bawan-shna-abdulrahman/src/Components/BoxShadow.css b/bawan-shna-abdulrahman/src/Components/BoxShadow.css new file mode 100644 index 00000000..ad7c6c2b --- /dev/null +++ b/bawan-shna-abdulrahman/src/Components/BoxShadow.css @@ -0,0 +1,3 @@ +.shadow-box:hover { + box-shadow: 0px 1px 21px -6px; +} diff --git a/bawan-shna-abdulrahman/src/Components/DropdownCategories.js b/bawan-shna-abdulrahman/src/Components/DropdownCategories.js index ff216cbb..fb75dfb6 100644 --- a/bawan-shna-abdulrahman/src/Components/DropdownCategories.js +++ b/bawan-shna-abdulrahman/src/Components/DropdownCategories.js @@ -10,7 +10,7 @@ export default function DropdownCategories(props) { fetch(SEARCH_URL_CATEGORIES) .then((res) => res.json()) .then((data) => { - if (Boolean(data.genres)) + if (data.genres !== undefined) setCategories([{ id: 0, name: "All" }, ...data.genres]); }) .catch((err) => console.log(err)); diff --git a/bawan-shna-abdulrahman/src/Components/Footer.css b/bawan-shna-abdulrahman/src/Components/Footer.css index e455f291..3acf47db 100644 --- a/bawan-shna-abdulrahman/src/Components/Footer.css +++ b/bawan-shna-abdulrahman/src/Components/Footer.css @@ -1,5 +1,4 @@ .main-footer { - margin-top: 50px; color: white; background-color: #343a40; position: relative; diff --git a/bawan-shna-abdulrahman/src/Components/Footer.js b/bawan-shna-abdulrahman/src/Components/Footer.js index ccd648d5..2ec685ba 100644 --- a/bawan-shna-abdulrahman/src/Components/Footer.js +++ b/bawan-shna-abdulrahman/src/Components/Footer.js @@ -6,9 +6,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; export default function Footer() { return (
- - Developed with ❤ by bawan-shna-abdulrahman - + Developed with ❤ by shna diff --git a/bawan-shna-abdulrahman/src/Components/Header.js b/bawan-shna-abdulrahman/src/Components/Header.js index 068c0aad..ee340043 100644 --- a/bawan-shna-abdulrahman/src/Components/Header.js +++ b/bawan-shna-abdulrahman/src/Components/Header.js @@ -1,28 +1,51 @@ -import React from "react"; -import { Navbar, Nav } from "react-bootstrap"; +import React, { useContext } from "react"; +import { Navbar, Nav, Button } from "react-bootstrap"; import Search from "./Search"; +import { Link, useHistory } from "react-router-dom"; +import { faFilm } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { StateContext } from "./StateProvider"; +import { constructUrl } from "./Api"; +export default function Header() { + const [state, dispatch] = useContext(StateContext); + const history = useHistory(); + + const home = () => { + let SEARCH_URL; + SEARCH_URL = constructUrl("movie/popular"); + fetch(SEARCH_URL) + .then((res) => res.json()) + .then((data) => dispatch({ type: "SET_MOVIES", payload: data.results })); + history.push("/"); + }; -export default function Header(props) { - const { handleQuery, handleMovies, isLoading, setIsLoading } = props; return (
- - - React App - + + {/* */} + + {/* */} - +
diff --git a/bawan-shna-abdulrahman/src/Components/Main.js b/bawan-shna-abdulrahman/src/Components/Main.js index 87496902..8f89de6b 100644 --- a/bawan-shna-abdulrahman/src/Components/Main.js +++ b/bawan-shna-abdulrahman/src/Components/Main.js @@ -1,7 +1,9 @@ -import React from "react"; +import React, { useContext } from "react"; import MovieGrid from "./MovieGrid"; +import { StateContext } from "./StateProvider"; -export default function Main(props) { - const { movies } = props; - return <>{movies.length > 0 && }; +export default function Main() { + const [state] = useContext(StateContext); + + return <>{state.movies.length > 0 && }; } diff --git a/bawan-shna-abdulrahman/src/Components/MovieGrid.js b/bawan-shna-abdulrahman/src/Components/MovieGrid.js index 3b22bcb9..e5f1b0c0 100644 --- a/bawan-shna-abdulrahman/src/Components/MovieGrid.js +++ b/bawan-shna-abdulrahman/src/Components/MovieGrid.js @@ -1,19 +1,25 @@ -import React from "react"; +import React, { useContext } from "react"; import RenderMovie from "./RenderMovie"; import { Container, Row } from "react-bootstrap"; +import { StateContext } from "./StateProvider"; + +export default function MoviesGrid() { + const [state, dispatch] = useContext(StateContext); -export default function MoviesGrid(props) { - const movies = props.movies; return ( - {movies.length > 0 && - movies.map((movie) => ( + {state.movies.length > 0 && + state.movies.map((movie) => ( ))} diff --git a/bawan-shna-abdulrahman/src/Components/MoviePage.js b/bawan-shna-abdulrahman/src/Components/MoviePage.js new file mode 100644 index 00000000..a394bc52 --- /dev/null +++ b/bawan-shna-abdulrahman/src/Components/MoviePage.js @@ -0,0 +1,124 @@ +import React, { useState, useEffect } from "react"; +import { constructUrl } from "./Api"; +import { Link } from "react-router-dom"; +import "./moviePage.css"; +import { + Card, + Badge, + Carousel, + Row, + Col, + Image, + Button, +} from "react-bootstrap"; +import ReactPlayer from "react-player"; + +export default function MoviePage(props) { + const nullPhoto = + "https://image.tmdb.org/t/p/w500/wwemzKWzjKYJFfCeiB57q3r4Bcm.png"; + + let SEARCH_URL; + // let { id } = useParams(); + // let MOVIE_ID = id; + let MOVIE_ID = props.match.params.id; + const [movieItem, setMovieItem] = useState({}); + const [trailers, setTrailers] = useState([]); + const [actors, setActors] = useState([]); + + // fetch each movie + useEffect(() => { + SEARCH_URL = constructUrl(`movie/${MOVIE_ID}`); + fetch(SEARCH_URL) + .then((res) => res.json()) + .then((data) => { + setMovieItem(data); + }) + .catch((e) => { + props.history.push("/"); + }); + }, [MOVIE_ID]); + //fetch trailers + useEffect(() => { + SEARCH_URL = constructUrl(`movie/${MOVIE_ID}/videos`); + fetch(SEARCH_URL) + .then((res) => res.json()) + .then((data) => { + const tmp = []; + data.results.map((trailer) => { + tmp.push(`https://www.youtube.com/watch?v=${trailer.key}`); + }); + setTrailers(tmp); + }); + }, [MOVIE_ID]); + + //fetch actors + useEffect(() => { + SEARCH_URL = constructUrl(`movie/${MOVIE_ID}/credits`); + fetch(SEARCH_URL) + .then((res) => res.json()) + .then((data) => { + setActors(data.cast); + }); + }, [MOVIE_ID]); + + return ( + <> + + +
+ + {movieItem.genres + ? movieItem.genres.map((genre) => { + return ( + + {genre.name} + + ); + }) + : null} + + +

Actors:

+
    + {actors.map((v) => { + return ( + +
  1. {v.name}
  2. + + ); + })} +
+ + + + + {trailers.map((v, i) => { + return ( + + + + ); + })} + + +
+ + ); +} diff --git a/bawan-shna-abdulrahman/src/Components/RenderMovie.js b/bawan-shna-abdulrahman/src/Components/RenderMovie.js index 823caaf1..f0928e88 100644 --- a/bawan-shna-abdulrahman/src/Components/RenderMovie.js +++ b/bawan-shna-abdulrahman/src/Components/RenderMovie.js @@ -1,41 +1,69 @@ import React, { useState } from "react"; - -import { Modal, Button, Card, CardTitle, CardText } from "react-bootstrap"; +import { Card, Badge, Modal, Button } from "react-bootstrap"; +import "./BoxShadow.css"; +import { Link } from "react-router-dom"; export default function RenderMovie(props) { + const nullPhoto = + "https://www.salonlfc.com/wp-content/uploads/2018/01/image-not-found-scaled-1150x647.png"; const [show, setShow] = useState(false); - let toogle = () => setShow((prev) => !prev); + const toogle = () => { + setShow((prevstate) => { + return !prevstate; + }); + }; return (
- - - - {props.title} + + + + + + {`${props.title}`.substr(0, 20)} + {props.title.length >= 25 ? "..." : ""} + + + Popularity:{props.popularity} + + {props.release_date} + + + + - - - - - OverView - - -

{props.overview}

-
- - - -
-
-
+ +
); } diff --git a/bawan-shna-abdulrahman/src/Components/Search.js b/bawan-shna-abdulrahman/src/Components/Search.js index b8de1f8a..12372878 100644 --- a/bawan-shna-abdulrahman/src/Components/Search.js +++ b/bawan-shna-abdulrahman/src/Components/Search.js @@ -1,31 +1,65 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useContext } from "react"; import { Button, Form, FormControl, Spinner } from "react-bootstrap"; +import { useRouteMatch, useHistory, useLocation } from "react-router-dom"; import DropdownCategories from "./DropdownCategories"; import { constructUrl } from "./Api"; +import { StateContext } from "./StateProvider"; -export default function Search(props) { - const { setIsLoading, handleQuery } = props; - const [category, setCategory] = useState({}); +export default function Search() { + const [state, dispatch] = useContext(StateContext); + const [queryInput, setQueryInput] = useState(""); + const [category, setCategory] = useState({}); + const history = useHistory(); + const location = useLocation(); + const parts = location.search.split("&"); + const parts2 = `${parts[0]}`.split("="); + const match = useRouteMatch({ + path: `/`, + strict: true, + sensitive: true, + }); const changeCategory = (category) => { - setIsLoading(true); + dispatch({ type: "SET_ISLOADING", payload: true }); setCategory(category); + // if (category.id == 0) { + // setQueryInput(""); + // } }; - const [queryInput, setQueryInput] = useState(""); const onChange = (e) => { setQueryInput(e.target.value); + history.push({ + pathname: location.pathname, + search: "?query=" + e.target.value, + }); }; + const onSubmit = (event) => { event.preventDefault(); - setIsLoading(true); - handleQuery(queryInput); - fetchMovies(); + dispatch({ type: "SET_ISLOADING", payload: true }); + dispatch({ type: "SET_QUERY", payload: queryInput }); + + fetchMovies(queryInput); + if (!match.isExact) { + history.push({ + pathname: "/", + search: "?query=" + queryInput, + }); + } }; - useEffect(fetchMovies, [category]); - // useless comment - function fetchMovies() { + useEffect(() => fetchMovies(queryInput), [category]); + useEffect(() => { + if (location.search != "") { + fetchMovies(parts2[1]); + setQueryInput(parts2[1]); + } else { + fetchMovies(); + } + }, []); + + function fetchMovies(queryInput = "") { let SEARCH_URL; if (queryInput !== "") { SEARCH_URL = constructUrl("search/movie", queryInput); @@ -35,24 +69,23 @@ export default function Search(props) { fetch(SEARCH_URL) .then((res) => res.json()) .then((data) => { - console.log(data); - if (Boolean(data.results)) { + if (data.results !== undefined) { let movies = data.results; - if (category.id) { - movies = movies.filter((movie) => - movie.genre_ids.includes(category.id) - ); - console.log(movies); + movies = movies.filter((movie) => { + return movie.genre_ids.includes(category.id); + }); } - props.handleMovies(movies); + dispatch({ type: "SET_MOVIES", payload: movies }); + dispatch({ type: "SET_ISLOADING", payload: false }); } }) + .catch((err) => console.log(err)); } return ( -
+ -