├── .firebase
└── hosting.YnVpbGQ.cache
├── .firebaserc
├── .gitignore
├── README.md
├── debug.log
├── firebase.json
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── screenshots
├── 1.PNG
├── 2.PNG
├── 3.PNG
├── 4.PNG
└── 5.PNG
├── src
├── API
│ └── index.js
├── App.css
├── App.js
├── App.test.js
├── assets
│ ├── amazonIcon.png
│ └── amazonIcon2.png
├── axios.js
├── components
│ ├── AllContent
│ │ ├── index.js
│ │ └── styles.scss
│ ├── Episode
│ │ ├── index.js
│ │ └── styles.scss
│ ├── Header
│ │ ├── index.js
│ │ └── styles.scss
│ ├── Home
│ │ ├── index.js
│ │ └── styles.scss
│ ├── HoverScreen
│ │ ├── index.js
│ │ └── styles.scss
│ ├── MediaScreen
│ │ ├── index.js
│ │ └── styles.scss
│ ├── Movie
│ │ ├── index.js
│ │ └── styles.scss
│ ├── Slideshow
│ │ ├── index.js
│ │ └── styles.scss
│ └── TV
│ │ ├── index.js
│ │ └── styles.scss
├── homeRequests.js
├── index.css
├── index.js
├── logo.svg
├── requests.js
├── serviceWorker.js
├── setupTests.js
└── tvRequests.js
└── yarn.lock
/.firebase/hosting.YnVpbGQ.cache:
--------------------------------------------------------------------------------
1 | favicon.ico,1592292975688,d96ddbc4933b04e12c738ab39f469573143949ca2c39eda0a49d16f83d40c319
2 | logo192.png,1592292975688,3ee59515172ee198f3be375979df15ac5345183e656720a381b8872b2a39dc8b
3 | logo512.png,1592292975688,ee7e2f3fdb8209c4b6fd7bef6ba50d1b9dba30a25bb5c3126df057e1cb6f5331
4 | manifest.json,1592292975688,aff3449bdc238776f5d6d967f19ec491b36aed5fb7f23ccff6500736fd58494a
5 | robots.txt,1592292975688,bfe106a3fb878dc83461c86818bf74fc1bdc7f28538ba613cd3e775516ce8b49
6 | asset-manifest.json,1606393864276,eb9cf6548f9af132c62978a284cbe702a349a4564a8978b1037ec19c5761e4a4
7 | precache-manifest.02afa5a67b00d8c9452f8dc9c02a7d0d.js,1606393864276,331f39c2d28b5d4548f35c3135e748cde752f4e18b4f2487479105f6e9537b41
8 | index.html,1606393864276,d5c4a5d16f1c841e2e231bc241c771541c981664fe68b397d92fec133483dc39
9 | service-worker.js,1606393864276,15e20de7e532f6ea31df3b10eec6b0e1f26b86b61e0f840be3554a56702cb66b
10 | static/css/main.794d03c8.chunk.css,1606393864276,aca71f8baf6f01fa6f1f8bda3cc5ebcc870f67c07cf78e4e4cebbc2c912260fe
11 | static/js/2.9206692c.chunk.js.LICENSE.txt,1606393864283,9222236c29af6e341c37a506e8fd6756969d4d711183fb4832efc33e0e16537c
12 | static/css/main.794d03c8.chunk.css.map,1606393864278,b686dd86b832ef2e4fe4c01fa7cc0c1f1e0f9436d3a7017dd6b0f39f83eb7b11
13 | static/js/main.2a0d8dcf.chunk.js,1606393864279,5b3ca6e8b7c626cbf7f312df7cf4c8af0b6f609f373dd7e2d46f0bb40c3e9fa3
14 | static/js/runtime-main.a123e81e.js,1606393864279,e18d7e8668aa67b52c28f132dcbb695d641007ac529903d6ed11fa1ef727659c
15 | static/js/runtime-main.a123e81e.js.map,1606393864307,d9747a0c8a0853ace29d16375cb2f134ff3ab51c2207a23fb140e92cceb39fc5
16 | static/js/main.2a0d8dcf.chunk.js.map,1606393864283,9d1671433c777ad15bb796c2fc7b8d704cfc273ac583e3941fad2841002cf37e
17 | static/js/2.9206692c.chunk.js,1606393864283,a81a93cf713b29e31c2dab01c89f99ae2ec09fef5f6809dde9480671767611ec
18 | static/js/2.9206692c.chunk.js.map,1606393864307,9a883cbe52f16a401031b3632f407b6201317205fb171896b97e5812134fbc30
19 |
--------------------------------------------------------------------------------
/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "default": "prime-clone-e1de6"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Amazon Prime Clone
2 | This project is a Amazon Prime Clone. You can run the below commands to see the project on your local system.
3 | Hosted on Firebase at https://prime-clone-2fcfe.web.app/
4 | This is the version 1 of the project. (Desktop View Only).
5 | For getting Data I have used TMDB API.
6 |
7 | ## If you like it please give it a star 😊
8 |
9 | ## Note For Developers
10 | For running the App locally you will have to generate your own API_Key and substitute in all requests files and App.js files.
11 | You can check out other ReactJs projects as well in other repositories deployed on firebase.
12 |
13 | Icons from Material UI library have been used. Link is https://material-ui.com/components/material-icons/
14 |
15 | #### Technologies Used:
16 | 1. ReactJS
17 | 2. NodeJS
18 | 3. MaterialUI for icons
19 |
20 | ## Don't use it for any commercial purposes.
21 |
22 | Screenshots of the App:
23 |
24 | 
25 |
26 |
27 | 
28 |
29 |
30 | 
31 |
32 |
33 | 
34 |
35 |
36 | 
37 |
38 | #### Contact Details: Email id => peeyushgoyal154@gmail.com
39 |
40 | ## Featured
41 | https://freesoff.com/t/160-open-source-clones-of-popular-sites/88788
42 |
43 | ## Available Scripts
44 |
45 | In the project directory, you can run:
46 |
47 | ### `npm install`
48 |
49 | This command installs all the required dependencies for running the App.
50 |
51 | ### `npm start`
52 |
53 | Runs the app in the development mode.
54 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
55 |
56 | The page will reload if you make edits.
57 | You will also see any lint errors in the console.
58 |
59 |
--------------------------------------------------------------------------------
/debug.log:
--------------------------------------------------------------------------------
1 | [1014/164122.072:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3)
2 |
--------------------------------------------------------------------------------
/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "hosting": {
3 | "public": "build",
4 | "ignore": [
5 | "firebase.json",
6 | "**/.*",
7 | "**/node_modules/**"
8 | ],
9 | "rewrites": [
10 | {
11 | "source": "**",
12 | "destination": "/index.html"
13 | }
14 | ]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "prime-clone",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@material-ui/core": "^4.11.0",
7 | "@material-ui/icons": "^4.9.1",
8 | "@testing-library/jest-dom": "^4.2.4",
9 | "@testing-library/react": "^9.3.2",
10 | "@testing-library/user-event": "^7.1.2",
11 | "axios": "^0.20.0",
12 | "firebase": "^9.0.1",
13 | "react": "^16.13.1",
14 | "react-dom": "^16.13.1",
15 | "react-pure-lifecycle": "^3.0.0",
16 | "react-redux": "^7.2.2",
17 | "react-router-dom": "^5.2.0",
18 | "react-scripts": "3.4.3",
19 | "react-youtube": "^7.13.0",
20 | "redux": "^4.0.5",
21 | "redux-thunk": "^2.3.0",
22 | "sass": "^1.54.4"
23 | },
24 | "scripts": {
25 | "start": "react-scripts start",
26 | "build": "react-scripts build",
27 | "test": "react-scripts test",
28 | "eject": "react-scripts eject"
29 | },
30 | "eslintConfig": {
31 | "extends": "react-app"
32 | },
33 | "browserslist": {
34 | "production": [
35 | ">0.2%",
36 | "not dead",
37 | "not op_mini all"
38 | ],
39 | "development": [
40 | "last 1 chrome version",
41 | "last 1 firefox version",
42 | "last 1 safari version"
43 | ]
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peeyush14goyal/AmazonPrime-ReactJS-Clone/c609202a897af2e062d00b4f8c77ab619b5b7417/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peeyush14goyal/AmazonPrime-ReactJS-Clone/c609202a897af2e062d00b4f8c77ab619b5b7417/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peeyush14goyal/AmazonPrime-ReactJS-Clone/c609202a897af2e062d00b4f8c77ab619b5b7417/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/screenshots/1.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peeyush14goyal/AmazonPrime-ReactJS-Clone/c609202a897af2e062d00b4f8c77ab619b5b7417/screenshots/1.PNG
--------------------------------------------------------------------------------
/screenshots/2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peeyush14goyal/AmazonPrime-ReactJS-Clone/c609202a897af2e062d00b4f8c77ab619b5b7417/screenshots/2.PNG
--------------------------------------------------------------------------------
/screenshots/3.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peeyush14goyal/AmazonPrime-ReactJS-Clone/c609202a897af2e062d00b4f8c77ab619b5b7417/screenshots/3.PNG
--------------------------------------------------------------------------------
/screenshots/4.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peeyush14goyal/AmazonPrime-ReactJS-Clone/c609202a897af2e062d00b4f8c77ab619b5b7417/screenshots/4.PNG
--------------------------------------------------------------------------------
/screenshots/5.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peeyush14goyal/AmazonPrime-ReactJS-Clone/c609202a897af2e062d00b4f8c77ab619b5b7417/screenshots/5.PNG
--------------------------------------------------------------------------------
/src/API/index.js:
--------------------------------------------------------------------------------
1 | export const API_KEY = "989a8027930013244e3c2af17088dcac";
2 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | font-family: "Arial";
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 | .gap {
40 | height: 400px;
41 | }
42 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./App.css";
3 | import Header from "./components/Header";
4 | import Home from "./components/Home/index";
5 | import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
6 | import AllContent from "./components/AllContent";
7 | import Movie from "./components/Movie/index";
8 | import requests from "./requests";
9 | import tvrequests from "./tvRequests";
10 | import homeRequests from "./homeRequests";
11 | import TV from "./components/TV/index";
12 |
13 | function App() {
14 | const api_key = "989a8027930013244e3c2af17088dcac";
15 | return (
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | (
30 |
35 | )}
36 | />
37 | (
41 |
46 | )}
47 | />
48 | (
52 |
57 | )}
58 | />
59 | }
63 | />
64 | }
68 | />
69 | } />
70 |
71 |
72 |
73 |
74 | );
75 | }
76 |
77 | export default App;
78 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/src/assets/amazonIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peeyush14goyal/AmazonPrime-ReactJS-Clone/c609202a897af2e062d00b4f8c77ab619b5b7417/src/assets/amazonIcon.png
--------------------------------------------------------------------------------
/src/assets/amazonIcon2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peeyush14goyal/AmazonPrime-ReactJS-Clone/c609202a897af2e062d00b4f8c77ab619b5b7417/src/assets/amazonIcon2.png
--------------------------------------------------------------------------------
/src/axios.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | const instance = axios.create({
4 | baseURL: "https://api.themoviedb.org/3"
5 | })
6 |
7 | export default instance;
--------------------------------------------------------------------------------
/src/components/AllContent/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import "./styles.scss";
3 | import axiosR from "../../axios";
4 | import axios from "axios";
5 |
6 | const AllContent = ({ API_KEY }) => {
7 | const urlParams = new URLSearchParams(window.location.search);
8 | const genre_id = urlParams.get("genre");
9 | const heading = urlParams.get("title");
10 |
11 | const [allcontent, setContent] = useState([]);
12 | const base_url = "https://image.tmdb.org/t/p/original/";
13 |
14 | useEffect(() => {
15 | const request1 = axiosR.get(
16 | `/discover/movie/?api_key=${API_KEY}&with_genres=${genre_id}`
17 | );
18 | const request2 = axiosR.get(
19 | `/discover/movie/?api_key=${API_KEY}&with_genres=${genre_id}&page=2`
20 | );
21 | const request3 = axiosR.get(
22 | `/discover/movie/?api_key=${API_KEY}&with_genres=${genre_id}&page=3`
23 | );
24 | const request4 = axiosR.get(
25 | `/discover/movie/?api_key=${API_KEY}&with_genres=${genre_id}&page=4`
26 | );
27 | async function getData() {
28 | axios.all([request1, request2, request3, request4]).then(
29 | axios.spread((...responses) => {
30 | const response1 = responses[0].data.results;
31 | const response2 = responses[1].data.results;
32 | const response3 = responses[2].data.results;
33 |
34 | setContent(response1.concat(response2, response3));
35 | })
36 | );
37 | }
38 | getData();
39 | }, [genre_id, API_KEY]);
40 |
41 | return (
42 |
43 |
44 |
{heading}
45 |
46 |
47 | {allcontent.map((item) => {
48 | return (
49 |
50 |

55 |
56 | );
57 | })}
58 |
59 |
60 | );
61 | };
62 |
63 | export default AllContent;
64 |
--------------------------------------------------------------------------------
/src/components/AllContent/styles.scss:
--------------------------------------------------------------------------------
1 | .contentTitle {
2 | font-size: 18px;
3 | color: gray;
4 | margin-left: 15px;
5 | }
6 | .contentGridDisplay {
7 | display: grid;
8 | grid-template-columns: repeat(5, 2fr);
9 | margin: 0 auto;
10 | margin-left: 10px;
11 | grid-gap: 8px;
12 | overflow-x: hidden;
13 | }
14 | .gridImg {
15 | height: 130px;
16 | object-fit: contain;
17 | }
18 |
--------------------------------------------------------------------------------
/src/components/Episode/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./styles.scss";
3 | import PlayCircleFilledWhiteIcon from "@material-ui/icons/PlayCircleFilledWhite";
4 |
5 | const Episode = ({ index, episode }) => {
6 | const base_img_url = "https://image.tmdb.org/t/p/original/";
7 | return (
8 |
9 |
10 |

15 |
16 |
17 |
18 |
25 |
26 | {index}. {episode.name}
27 |
28 |
29 |
30 |
{episode.air_date}
31 |
32 |
{episode.overview}
33 |
34 |
35 |
36 |
37 |
38 | );
39 | };
40 |
41 | export default Episode;
42 |
--------------------------------------------------------------------------------
/src/components/Episode/styles.scss:
--------------------------------------------------------------------------------
1 | .EpisodeDiv {
2 | display: grid;
3 | grid-template-columns: 2fr 9fr 1fr;
4 | min-height: 200px;
5 | background-color: #0f171e;
6 | color: gray;
7 | }
8 | .episodeImg {
9 | max-height: 201px;
10 | max-width: 268px;
11 | }
12 | .episodeTitle {
13 | display: flex;
14 | font-size: 20px;
15 | color: white;
16 | }
17 | .paddingInfoDiv {
18 | padding-left: 25px;
19 | }
20 | .playButtonEpisode {
21 | margin-top: 0px;
22 | transform: scale(1.5);
23 | }
24 | .episodeTitleText {
25 | margin-top: 5px;
26 | margin-left: 15px;
27 | }
28 |
--------------------------------------------------------------------------------
/src/components/Header/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./styles.scss";
3 | import PrimeIcon from "../../assets/amazonIcon.png";
4 | import SearchOutlinedIcon from "@material-ui/icons/SearchOutlined";
5 | import AccountCircleOutlinedIcon from "@material-ui/icons/AccountCircleOutlined";
6 | import { Link } from "react-router-dom";
7 |
8 | const Header = () => {
9 | return (
10 |
11 |
12 |

13 |
14 |
15 |
16 |
21 |
22 |
23 |
TV Shows
24 |
25 |
26 |
31 | {/*
*/}
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
53 |
54 |
55 | );
56 | };
57 |
58 | export default Header;
59 |
--------------------------------------------------------------------------------
/src/components/Header/styles.scss:
--------------------------------------------------------------------------------
1 | .header {
2 | height: 72px;
3 | width: 100%;
4 | top: 0;
5 | position: fixed;
6 | background-color: #0f171e;
7 | font-size: 17px;
8 | line-height: 24px;
9 | padding: 16px 35px;
10 | display: flex;
11 | z-index: 6;
12 | }
13 | .primeIcon {
14 | height: 50px;
15 | position: relative;
16 | top: 2px;
17 | background-position: left 0;
18 | object-fit: contain;
19 | color: #0f171e;
20 | filter: invert(1);
21 | }
22 | .iconDiv {
23 | left: 0;
24 | }
25 | .navBarDiv {
26 | display: flex;
27 | color: rgba(242, 244, 246, 0.9);
28 | padding-top: 10px;
29 | font-size: 17px;
30 | min-width: 250px;
31 | align-content: space-between;
32 | }
33 | .navLinks {
34 | color: rgba(242, 244, 246, 0.9);
35 | margin: 8px;
36 | }
37 |
38 | .inputOuterDiv {
39 | border: 1px solid gray;
40 | width: 220px;
41 | height: 40px;
42 | margin-top: 10px;
43 | cursor: pointer;
44 | }
45 | .inputOuterDiv:hover {
46 | border: 1px solid whitesmoke;
47 | }
48 | .inputBox {
49 | border: none;
50 | outline: none;
51 | background-color: #0f171e;
52 | color: white;
53 | margin-left: 5px;
54 | line-height: 20px;
55 | font-size: 15px;
56 | padding: 0px;
57 | }
58 | .inputBox::placeholder {
59 | color: darkgray;
60 | }
61 | .inputDiv {
62 | padding: 9px;
63 | display: flex;
64 | margin-right: 5px;
65 | }
66 | .searchIcon {
67 | filter: invert(0.8);
68 | }
69 | .searchIcon:hover {
70 | filter: invert(1);
71 | }
72 | .headerAlignEnd {
73 | position: absolute;
74 | right: 100px;
75 | display: flex;
76 | }
77 | .account {
78 | filter: invert(0.7);
79 | width: 30px;
80 | object-fit: contain;
81 | margin-left: 20px;
82 | margin-top: 13px;
83 | }
84 | .account:hover {
85 | filter: invert(1);
86 | cursor: pointer;
87 | }
88 | a {
89 | text-decoration: none;
90 | color: rgba(242, 244, 246, 0.9);
91 | }
92 | a:hover {
93 | .textLink {
94 | color: white;
95 | }
96 | .navLinks {
97 | border-bottom: 2px solid white;
98 | cursor: pointer;
99 | }
100 | }
101 | a:active {
102 | .textLink {
103 | color: white;
104 | }
105 | .navLinks {
106 | border-bottom: 2px solid white;
107 | cursor: pointer;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/components/Home/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import MediaScreen from "../MediaScreen";
3 | import Slideshow from "../Slideshow";
4 | import "./styles.scss";
5 |
6 | const Home = ({ api_key, requests, slideShowUrl }) => {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 | {requests.map((mediaShow) => {
14 | return (
15 |
23 | );
24 | })}
25 |
26 |
27 | );
28 | };
29 | export default Home;
30 |
--------------------------------------------------------------------------------
/src/components/Home/styles.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peeyush14goyal/AmazonPrime-ReactJS-Clone/c609202a897af2e062d00b4f8c77ab619b5b7417/src/components/Home/styles.scss
--------------------------------------------------------------------------------
/src/components/HoverScreen/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import "./styles.scss";
3 | import PlayCircleFilledWhiteOutlinedIcon from "@material-ui/icons/PlayCircleFilledWhiteOutlined";
4 | import AddOutlinedIcon from "@material-ui/icons/AddOutlined";
5 | import ChatBubbleIcon from "@material-ui/icons/ChatBubble";
6 | import axios from "../../axios";
7 | import { Link } from "react-router-dom";
8 |
9 | const HoverScreen = ({ item, api_key, media_type }) => {
10 | let hours = 0,
11 | minutes = 0;
12 | const [media, setMedia] = useState({});
13 |
14 | useEffect(() => {
15 | async function getData() {
16 | const response = await axios.get(
17 | `/${media_type}/${item.id}?api_key=${api_key}`
18 | );
19 | setMedia(response.data);
20 | return response;
21 | }
22 | getData();
23 | }, [item, api_key, media_type]);
24 |
25 | const base_url = "https://image.tmdb.org/t/p/original/";
26 | if (media.runtime && media.runtime > 0) {
27 | hours = Math.floor(media.runtime / 60);
28 | minutes = media.runtime % 60;
29 | }
30 | return (
31 |
32 |
36 |

41 |
42 |
53 |
54 | {item.title ? item.title : item.original_name}
55 |
56 |
57 | {item.overview.length > 90
58 | ? item.overview.substr(0, 89) + "..."
59 | : item.overview}
60 |
61 |
62 |
63 | {hours > 0 ? `${hours}h ` : ""}
64 | {minutes > 0 ? `${minutes}min` : ""}
65 |
66 |
67 | {item.release_date ? item.release_date.substr(0, 4) : ""}
68 |
69 |
70 |
71 |
72 |
{item.adult ? "18+" : "ALL"}
73 |
74 |
75 |
76 |
77 | );
78 | };
79 |
80 | export default HoverScreen;
81 |
--------------------------------------------------------------------------------
/src/components/HoverScreen/styles.scss:
--------------------------------------------------------------------------------
1 | .mediaHoverImg {
2 | height: 160px;
3 | width: 300px;
4 | margin-top: 10px;
5 | border-radius: 0%;
6 | z-index: 2;
7 | }
8 | .hoverScreen {
9 | position: relative;
10 | color: white;
11 | width: 300px;
12 | transform: scale(1.1);
13 | transition-property: transform;
14 | transition-delay: 2000ms;
15 | transition-duration: 3s;
16 | top: -30px;
17 | opacity: 1;
18 | z-index: 2;
19 | margin-bottom: 20px;
20 | text-decoration: none;
21 | }
22 | .hoverData {
23 | position: relative;
24 | background: linear-gradient(rgba(27, 37, 48, 0), #1b2530 48px);
25 | padding: 30px 30px;
26 | padding-bottom: 5px;
27 | margin-top: -45px;
28 | z-index: 2;
29 | text-decoration: none;
30 | }
31 | .playButton {
32 | color: white;
33 | transform: scale(1.3);
34 | }
35 | .playButton:hover {
36 | background-color: blue;
37 | border-radius: 50%;
38 | outline: none;
39 | }
40 | .playtext {
41 | text-decoration: none;
42 | margin-top: 5px;
43 | font-size: 14px;
44 | font-weight: bold;
45 | }
46 | .playDiv {
47 | display: flex;
48 | justify-content: space-between;
49 | height: 30px;
50 | width: 65px;
51 | }
52 | .playIcon {
53 | width: 40px;
54 | }
55 | .addIcon {
56 | color: white;
57 | }
58 | .hoverHeading {
59 | text-decoration: none;
60 | display: flex;
61 | justify-content: space-between;
62 | }
63 | .title {
64 | margin-top: 10px;
65 | font-weight: 700;
66 | font-size: 14px;
67 | text-decoration: none;
68 | }
69 | .overview {
70 | margin-top: 5px;
71 | font-size: 11px;
72 | text-decoration: none;
73 | }
74 | .releaseYear {
75 | font-size: 11px;
76 | color: gray;
77 | margin-bottom: 15px;
78 | }
79 | .runTime {
80 | color: darkgray;
81 | font-size: 11px;
82 | }
83 | .footerScreen {
84 | margin-top: 10px;
85 | display: flex;
86 | justify-content: space-between;
87 | width: 200px;
88 | }
89 | .messageIcon {
90 | color: darkgray;
91 | max-height: 18px;
92 | }
93 | .rated {
94 | border: 1px solid darkgray;
95 | color: darkgray;
96 | font-size: 9px;
97 | padding: 3px;
98 | height: 10px;
99 | }
100 |
--------------------------------------------------------------------------------
/src/components/MediaScreen/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import "./styles.scss";
3 | import axios from "../../axios";
4 | import ChevronRightIcon from "@material-ui/icons/ChevronRight";
5 | import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
6 | import HoverScreen from "../HoverScreen";
7 | import { Link } from "react-router-dom";
8 |
9 | const MediaScreen = ({
10 | heading,
11 | fetchURL,
12 | API_KEY,
13 | genre = -1,
14 | moveCount,
15 | media_type,
16 | }) => {
17 | const [data, setData] = useState([]);
18 | const base_url = "https://image.tmdb.org/t/p/original/";
19 | var count = 0;
20 |
21 | useEffect(() => {
22 | async function fetchData() {
23 | const response = await axios.get(fetchURL);
24 | setData(response.data.results);
25 | return response;
26 | }
27 | fetchData();
28 | }, [fetchURL]);
29 |
30 | const scrollToLeft = () => {
31 | document.getElementById("bannerDiv" + moveCount.toString()).scrollBy({
32 | left: -800,
33 | });
34 | };
35 | const scrollToRight = () => {
36 | document.getElementById("bannerDiv" + moveCount.toString()).scrollBy({
37 | left: 800,
38 | });
39 | };
40 |
41 | const setPosition = (item) => {
42 | var x = document.getElementById(`1${item.id}`);
43 | var divItem = document.getElementById(`2${item.id}`);
44 | const ele = document.getElementById("bannerDiv" + moveCount.toString());
45 | if (divItem) {
46 | divItem.style.position = "absolute";
47 | divItem.style.top = x.offsetTop + "px";
48 | divItem.style.left = x.offsetLeft - ele.scrollLeft + "px";
49 | }
50 | };
51 |
52 | const shuffleData = (arr) => {
53 | for (var i = arr.length - 1; i > 0; i--) {
54 | var j = Math.floor(Math.random() * (i + 1));
55 | var temp = arr[i];
56 | arr[i] = arr[j];
57 | arr[j] = temp;
58 | }
59 | };
60 | if (data.length > 0) {
61 | shuffleData(data);
62 | }
63 | return (
64 |
65 |
66 |
{heading}
67 | {genre > 0 ? (
68 |
69 |
see more
70 |
71 | ) : (
72 |
73 | )}
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | {data.map((item) => {
82 | return (
83 |
84 | {item.backdrop_path ? (
85 |
{
89 | setPosition(item);
90 | }}
91 | >
92 |

97 |
98 |
99 |
104 |
105 |
106 | ) : (
107 |
108 | )}
109 |
110 | );
111 | })}
112 |
113 |
114 |
115 |
116 |
117 | );
118 | };
119 |
120 | export default MediaScreen;
121 |
--------------------------------------------------------------------------------
/src/components/MediaScreen/styles.scss:
--------------------------------------------------------------------------------
1 | .headingBanner {
2 | color: white;
3 | font-size: 19px;
4 | margin-left: 20px;
5 | display: flex;
6 | justify-content: space-between;
7 | }
8 | .banner {
9 | display: flex;
10 | left: 10px;
11 | overflow-y: hidden;
12 | overflow-x: scroll;
13 | scroll-behavior: smooth;
14 | justify-content: space-between;
15 | z-index: -1;
16 | }
17 | .banner::-webkit-scrollbar {
18 | display: none;
19 | }
20 | .leftIconDiv {
21 | left: 0px;
22 | max-height: 166px;
23 | z-index: 1;
24 | width: 30px;
25 | color: gray;
26 | position: absolute;
27 | margin-top: 10px;
28 | -webkit-transition: opacity 0.25s ease, background-color 0.25s ease;
29 | transition: opacity 0.25s ease, background-color 0.25s ease;
30 | background-color: rgba(15, 23, 30, 0.5);
31 | }
32 | .leftIcon {
33 | min-height: 160px;
34 | }
35 | .leftIconDiv:hover {
36 | .leftIcon {
37 | color: white;
38 | transform: scale(1.5);
39 | }
40 | }
41 | .rightIconDiv {
42 | margin-top: -180px;
43 | right: 0px;
44 | min-height: 166px;
45 | z-index: 1;
46 | width: 40px;
47 | color: gray;
48 | position: absolute;
49 | -webkit-transition: opacity 0.25s ease, background-color 0.25s ease;
50 | transition: opacity 0.25s ease, background-color 0.25s ease;
51 | background-color: rgba(15, 23, 30, 0.5);
52 | //background-color: black;
53 | cursor: pointer;
54 | }
55 | .rightIcon {
56 | min-height: 160px;
57 | margin-left: 0px;
58 | padding-top: -200px;
59 | }
60 | .rightIconDiv:hover {
61 | .rightIcon {
62 | color: white;
63 | transform: scale(1.5);
64 | }
65 | }
66 |
67 | .mediaScreen {
68 | margin-top: 5px;
69 | z-index: 0;
70 | }
71 |
72 | .mediaDiv {
73 | position: static;
74 | width: 100%;
75 | cursor: pointer;
76 | z-index: 0;
77 | padding: 10px 0px;
78 | padding-top: 5px;
79 | .displayhoverScreen {
80 | display: none;
81 | position: absolute;
82 | z-index: 5;
83 | padding: 1px;
84 | min-height: 400px;
85 | transform: scale(1);
86 | }
87 | &:hover > .displayhoverScreen {
88 | //
89 | display: block;
90 | position: absolute;
91 |
92 | // padding: 1px;
93 | //z-index: 3;
94 | }
95 | }
96 | .mediaImg {
97 | height: 160px;
98 | object-fit: cover;
99 | margin: 5px;
100 | border-radius: 4px;
101 | z-index: 0;
102 | visibility: visible;
103 | }
104 |
105 | .mediaDiv:hover {
106 | padding: 0px;
107 | .mediaImg {
108 | height: 0px;
109 | width: 284px;
110 | visibility: hidden;
111 | // margin-top: -10px;
112 | }
113 | }
114 |
115 | .moreButton {
116 | color: lightblue;
117 | font-size: 14px;
118 | margin-right: 15px;
119 | cursor: pointer;
120 | text-decoration: none;
121 | }
122 | .moreButton:hover {
123 | color: white;
124 | }
125 |
--------------------------------------------------------------------------------
/src/components/Movie/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import "./styles.scss";
3 | import axios from "../../axios";
4 | import ChatBubbleIcon from "@material-ui/icons/ChatBubble";
5 | import PlayCircleFilledWhiteIcon from "@material-ui/icons/PlayCircleFilledWhite";
6 | import ChangeHistoryIcon from "@material-ui/icons/ChangeHistory";
7 | import GetAppIcon from "@material-ui/icons/GetApp";
8 | import Button from "@material-ui/core/Button";
9 | import MediaScreen from "../MediaScreen";
10 | import CancelIcon from "@material-ui/icons/Cancel";
11 | import IconButton from "@material-ui/core/IconButton";
12 | import YouTube from "react-youtube";
13 |
14 | const Movie = ({ api_key }) => {
15 | const [credits, setCredits] = useState();
16 | const [movieDetails, setDetails] = useState();
17 | const [videos, setVideo] = useState();
18 | const [detailShow, setShow] = useState(1);
19 | const [YoutubePlay, setYoutubePlay] = useState(false);
20 | const [trailer_id, setTrailer_id] = useState();
21 | const base_url = "https://api.themoviedb.org/3/movie/";
22 | let detailsLoaded = false;
23 | let creditsLoaded = false;
24 | let hours, minutes;
25 | let director = [];
26 | let crew = [];
27 | let writing = [];
28 | let production = [];
29 | const opts = {
30 | width: "100%",
31 | minHeight: "200%",
32 | paddingTop: "56.25%", // Percentage ratio for 16:9
33 | position: "absolute",
34 | playerVars: {
35 | autoplay: 1,
36 | listType: "user_uploads",
37 | },
38 | };
39 |
40 | const urlParams = new URLSearchParams(window.location.search);
41 | const movie_id = urlParams.get("id");
42 |
43 | const image_base_url = "https://image.tmdb.org/t/p/original/";
44 |
45 | useEffect(() => {
46 | async function fetchDetails() {
47 | const response = await axios.get(
48 | `${base_url}${movie_id}?api_key=${api_key}`
49 | );
50 |
51 | setDetails(response.data);
52 | return response;
53 | }
54 | async function fetchCredits() {
55 | const response = await axios.get(
56 | `${base_url}${movie_id}/credits?api_key=${api_key}`
57 | );
58 |
59 | setCredits(response.data);
60 | }
61 | async function getVideo() {
62 | const response = await axios.get(
63 | `${base_url}${movie_id}/videos?api_key=${api_key}`
64 | );
65 |
66 | setVideo(response.data.results);
67 | }
68 | fetchCredits();
69 | fetchDetails();
70 | getVideo();
71 | }, [base_url, movie_id, api_key]);
72 |
73 | const playVideo = () => {
74 | if (videos) {
75 | setYoutubePlay(true);
76 |
77 | setTrailer_id(videos[0].key);
78 | } else {
79 | setYoutubePlay(false);
80 | }
81 | return trailer_id;
82 | };
83 |
84 | if (movieDetails) {
85 | detailsLoaded = true;
86 | }
87 | if (credits) {
88 | creditsLoaded = true;
89 | credits.crew.map((person) => {
90 | if (person.known_for_department === "Directing") {
91 | director.push(person.name);
92 | } else if (person.known_for_department === "Production") {
93 | production.push(person.name);
94 | } else if (person.known_for_department === "Writing") {
95 | writing.push(person.name);
96 | } else if (person.known_for_department === "Crew") {
97 | crew.push(person.name);
98 | }
99 | return person.name;
100 | });
101 | }
102 |
103 | if (detailsLoaded && movieDetails.runtime && movieDetails.runtime > 0) {
104 | hours = Math.floor(movieDetails.runtime / 60);
105 | minutes = movieDetails.runtime % 60;
106 | }
107 |
108 | return (
109 |
110 | {detailsLoaded ? (
111 |
112 |
113 |
114 | {movieDetails.title
115 | ? movieDetails.title
116 | : movieDetails.original_name}
117 |
118 |
{movieDetails.overview}
119 |
120 |
121 | IMDb {movieDetails.vote_average}
122 |
123 |
124 | {hours > 0 ? `${hours}h ` : ""}
125 | {minutes > 0 ? `${minutes}min` : ""}
126 |
127 |
128 | {movieDetails.release_date
129 | ? movieDetails.release_date.substr(0, 4)
130 | : ""}
131 |
132 |
133 |
134 | {movieDetails.adult ? "18+" : "ALL"}
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
151 | }
152 | >
153 | Play
154 |
155 |
156 |
157 | }
161 | onClick={() => {
162 | playVideo();
163 | }}
164 | >
165 | Watch Trailer
166 |
167 |
168 |
169 |
176 |
177 |
178 | }
183 | >
184 | Download
185 |
186 |
187 |
188 | {creditsLoaded ? (
189 |
190 |
Director
191 |
{director}
192 |
Starring
193 |
194 | {credits.cast.map((person) => {
195 | let str = "";
196 | if (credits.cast.indexOf(person) < 11) {
197 | str = `${person.name}, `;
198 | }
199 | return str;
200 | })}
201 |
202 |
Genres
203 |
204 | {movieDetails.genres.map((genre) => {
205 | let str = `${genre.name}, `;
206 | return str;
207 | })}
208 |
209 |
210 | ) : (
211 |
212 | )}
213 |
214 |
215 |

220 |
221 |
222 |
223 |
224 | ) : (
225 |
226 | )}
227 |
228 | {YoutubePlay ? (
229 |
230 |
231 | {
235 | setYoutubePlay(false);
236 | }}
237 | color="primary"
238 | className="closeIconButton"
239 | >
240 |
241 |
242 |
243 |
244 |
{
248 | alert("Youtube Not working");
249 | }}
250 | />
251 |
252 | ) : (
253 |
254 | )}
255 |
256 |
257 |
258 |
{
260 | setShow(1);
261 | }}
262 | className={detailShow === 1 ? "activeRelated" : ""}
263 | >
264 | Related
265 |
266 |
{
268 | setShow(0);
269 | }}
270 | className={detailShow === 0 ? "activeDetails" : ""}
271 | >
272 | Details
273 |
274 |
275 | {detailsLoaded && detailShow === 1 ? (
276 |
282 | ) : (
283 |
284 |
285 | {production.length > 0 ? (
286 |
Production
287 | ) : (
288 |
289 | )}
290 | {production.length > 0 ? (
291 |
292 | {production.map((person) => {
293 | let str = `${person}, `;
294 | return str;
295 | })}
296 |
297 | ) : (
298 |
299 | )}
300 | {writing.length > 0 ? (
301 |
Writing
302 | ) : (
303 |
304 | )}
305 | {writing.length > 0 ? (
306 |
307 | {writing.map((person) => {
308 | let str = `${person}, `;
309 | return str;
310 | })}
311 |
312 | ) : (
313 |
314 | )}
315 | {crew.length > 0 ? (
316 |
Crew
317 | ) : (
318 |
319 | )}
320 | {crew.length > 0 ? (
321 |
322 | {crew.map((person) => {
323 | let str = `${person}, `;
324 | return str;
325 | })}
326 |
327 | ) : (
328 |
329 | )}
330 |
331 |
332 | )}
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 | );
342 | };
343 | export default Movie;
344 |
--------------------------------------------------------------------------------
/src/components/Movie/styles.scss:
--------------------------------------------------------------------------------
1 | .movie_image {
2 | width: 950px;
3 | position: absolute;
4 | right: 0px;
5 | object-fit: contain;
6 | z-index: -1;
7 | top: 100px;
8 | }
9 | .imageDiv {
10 | position: absolute;
11 | z-index: 0;
12 | right: 0;
13 | top: 0;
14 | height: 510px;
15 | overflow: hidden;
16 | width: 950px;
17 | padding: 0px;
18 | }
19 | .divImage1 {
20 | position: absolute;
21 | top: 0;
22 | width: 950px;
23 | height: 600px;
24 | right: 0;
25 | background: linear-gradient(90deg, #0f171e 10%, rgba(15, 23, 30, 0));
26 | }
27 | .divImage2 {
28 | position: absolute;
29 | top: 0;
30 | width: 950px;
31 | height: 600px;
32 | right: 0;
33 | background: linear-gradient(0deg, #0f171e 0, rgba(15, 23, 30, 0) 50%);
34 | }
35 | .movieInfo {
36 | position: absolute;
37 | left: 0;
38 | color: white;
39 | margin-left: 30px;
40 | z-index: 2;
41 | }
42 | .title2 {
43 | font-size: 40px;
44 | margin-top: 10px;
45 | font-weight: normal;
46 | }
47 | .overview2 {
48 | // position: absolute;
49 | // margin-top: 40px;
50 | //z-index: 2;
51 | margin-top: 20px;
52 | width: 600px;
53 | font-size: 16px;
54 | line-height: 1.5;
55 | }
56 |
57 | .moviereleaseYear {
58 | font-size: 15px;
59 | color: gray;
60 | margin-bottom: 15px;
61 | }
62 | .movierunTime {
63 | color: darkgray;
64 | font-size: 15px;
65 | }
66 | .moviefooterScreen {
67 | margin-top: 15px;
68 | display: flex;
69 | justify-content: space-between;
70 | width: 300px;
71 | }
72 | .moviemessageIcon {
73 | color: darkgray;
74 | max-height: 18px;
75 | }
76 | .movierated {
77 | border: 1px solid darkgray;
78 | color: darkgray;
79 | font-size: 12px;
80 | padding: 3px;
81 | height: 10px;
82 | }
83 | .movierating {
84 | color: darkgray;
85 | font-size: 15px;
86 | }
87 | .people {
88 | //position: absolute;
89 | min-width: 500px;
90 | max-width: 70%;
91 | display: grid;
92 | grid-template-columns: 1.3fr 10.7fr;
93 | text-align: left;
94 | margin-top: 40px;
95 | //z-index: 2;
96 | grid-row-gap: 7px;
97 | line-height: 1.5;
98 | }
99 | .peopleHeading {
100 | color: gray;
101 | font-weight: bold;
102 | }
103 | .peopleVal {
104 | color: rgb(6, 167, 196);
105 | }
106 | .buttonGroup {
107 | display: flex;
108 | justify-content: space-evenly;
109 | // z-index: 2;
110 | //position: absolute;
111 | margin-top: 30px;
112 | width: 750px;
113 | padding: 0 auto;
114 | }
115 |
116 | .trailerIcon {
117 | transform: rotate(90deg);
118 | }
119 | .moviePlayText {
120 | color: white;
121 | margin-left: 8px;
122 | //font-size: 20px;
123 | //margin-left: 10px;
124 | }
125 | .moviePlayIcon {
126 | transform: scale(2);
127 | background-color: white;
128 | border-radius: 50%;
129 | //margin-bottom: 30px;
130 | }
131 | .movieButton {
132 | height: 50px;
133 | }
134 | .playmovieButton {
135 | transform: scale(1.5);
136 | }
137 | .relatedMovies {
138 | position: absolute;
139 | top: 650px;
140 | width: 100%;
141 | }
142 | .tabHeading {
143 | display: flex;
144 | justify-content: space-between;
145 | min-width: 250px;
146 | text-align: center;
147 | margin-left: 40%;
148 | top: 800px;
149 | color: gray;
150 | font-size: 25px;
151 | cursor: pointer;
152 | }
153 |
154 | .activeRelated {
155 | border-bottom: 2px solid white;
156 | color: white;
157 | }
158 | .activeDetails {
159 | border-bottom: 2px solid white;
160 | color: white;
161 | }
162 | .detailsCrew {
163 | margin-left: 30px;
164 | }
165 | .playTrailerVideo {
166 | position: absolute;
167 | top: 0;
168 | left: 0;
169 | z-index: 10;
170 | min-height: 100%;
171 | min-width: 100%;
172 | background-color: rgba(220, 220, 220, 0.5);
173 | transition: background-color 1s ease-in;
174 | padding-top: 100px;
175 | }
176 | .closeButtonDiv {
177 | margin-left: 90%;
178 | }
179 | .closeIconButton {
180 | transform: scale(2);
181 | }
182 |
--------------------------------------------------------------------------------
/src/components/Slideshow/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import axios from "../../axios";
3 | import "./styles.scss";
4 |
5 | const Slideshow = ({ fetch_url, api_key }) => {
6 | const [sshow, setSshow] = useState([]);
7 | const base_url = "https://image.tmdb.org/t/p/original/";
8 | var startSS = 0;
9 | var temp_int;
10 | const automaticSlideshow = () => {
11 | const x = document.getElementsByClassName("ssDiv");
12 |
13 | var i;
14 | if (x.length === 0) {
15 | clearInterval(temp_int);
16 | }
17 | for (i = 0; i < sshow.length && x.length > 0; i++) {
18 | if (i === startSS) {
19 | x[i].style.display = "block";
20 | x[i].style.width = "100%";
21 | } else {
22 | x[i].style.display = "none";
23 | x[i].style.width = "0%";
24 | }
25 | }
26 | startSS++;
27 | if (sshow.length > 0 && startSS === sshow.length) {
28 | startSS = 0;
29 | }
30 | };
31 |
32 | temp_int = setInterval(automaticSlideshow, 5000);
33 |
34 | useEffect(() => {
35 | async function fetchData() {
36 | const response = await axios.get(fetch_url + `?api_key=${api_key}`);
37 |
38 | setSshow(response.data.results);
39 | return response;
40 | }
41 | fetchData();
42 | }, [fetch_url, api_key]);
43 |
44 | return (
45 |
46 | {sshow.map((item) => {
47 | return (
48 |
49 |
50 |

55 |
56 |
57 |
58 | {item.original_title
59 | ? item.original_title
60 | : item.original_name}
61 |
62 |
{item.overview}
63 | {/*
64 | Media Type:{" "}
65 | {item.media_type === "tv"
66 | ? item.media_type.toUpperCase()
67 | : item.media_type.charAt(0).toUpperCase() +
68 | item.media_type.slice(1)}
69 |
*/}
70 |
71 |
72 |
73 | );
74 | })}
75 |
76 | );
77 | };
78 |
79 | export default Slideshow;
80 |
--------------------------------------------------------------------------------
/src/components/Slideshow/styles.scss:
--------------------------------------------------------------------------------
1 | .SSdescription {
2 | position: absolute;
3 | color: white;
4 | margin-top: 200px;
5 | font-size: 35px;
6 | width: 500px;
7 | font-weight: bolder;
8 | line-height: 1.5;
9 | //background-color: rgba(223, 217, 217, 0.5);
10 | }
11 | .ssDiv {
12 | display: none;
13 | position: relative;
14 | min-height: 900px;
15 | max-height: 1000px;
16 | }
17 |
18 | .ssOverview {
19 | margin-top: 10px;
20 | opacity: 1;
21 | font-size: 20px;
22 | color: darkgray;
23 | font-weight: normal;
24 | margin-left: 40px;
25 | }
26 | .ssTitle {
27 | opacity: 1;
28 | margin-left: 40px;
29 | }
30 | .ssVote {
31 | margin-top: 15px;
32 | margin-left: 40px;
33 | font-size: 23px;
34 | color: whitesmoke;
35 | }
36 |
37 | .slideshowImg {
38 | position: absolute;
39 | display: block;
40 | width: 100%;
41 | object-fit: cover;
42 | max-height: 900px;
43 | opacity: 0.5;
44 | // margin-bottom: 50px;
45 | }
46 |
--------------------------------------------------------------------------------
/src/components/TV/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import "./styles.scss";
3 | import axios from "../../axios";
4 | import ChatBubbleIcon from "@material-ui/icons/ChatBubble";
5 | import PlayCircleFilledWhiteIcon from "@material-ui/icons/PlayCircleFilledWhite";
6 | import ChangeHistoryIcon from "@material-ui/icons/ChangeHistory";
7 | import GetAppIcon from "@material-ui/icons/GetApp";
8 | import Button from "@material-ui/core/Button";
9 | import MediaScreen from "../MediaScreen";
10 | import CancelIcon from "@material-ui/icons/Cancel";
11 | import IconButton from "@material-ui/core/IconButton";
12 | import YouTube from "react-youtube";
13 | import Episode from "../Episode/index";
14 |
15 | const TV = ({ api_key }) => {
16 | const [credits, setCredits] = useState();
17 | const [movieDetails, setDetails] = useState();
18 | const [videos, setVideo] = useState();
19 | const [detailShow, setShow] = useState(1);
20 | const [YoutubePlay, setYoutubePlay] = useState(false);
21 | const [trailer_id, setTrailer_id] = useState();
22 | const [episodes, setEpisodes] = useState();
23 | const [seasonCount, setseasonCount] = useState();
24 | const base_url = "https://api.themoviedb.org/3/tv/";
25 | let detailsLoaded = false;
26 | let creditsLoaded = false;
27 | let hours, minutes;
28 | let director = [];
29 | let crew = [];
30 | let writing = [];
31 | let production = [];
32 | const opts = {
33 | width: "100%",
34 | minHeight: "200%",
35 | paddingTop: "56.25%", // Percentage ratio for 16:9
36 | position: "absolute",
37 | playerVars: {
38 | autoplay: 1,
39 | listType: "user_uploads",
40 | },
41 | };
42 |
43 | const urlParams = new URLSearchParams(window.location.search);
44 | const movie_id = urlParams.get("id");
45 |
46 | const image_base_url = "https://image.tmdb.org/t/p/original/";
47 |
48 | useEffect(() => {
49 | async function fetchDetails() {
50 | const response = await axios.get(
51 | `${base_url}${movie_id}?api_key=${api_key}`
52 | );
53 |
54 | const temp = response.data.number_of_seasons;
55 | var tempArr = [];
56 | for (let i = 1; i <= temp; i++) {
57 | tempArr.push(i);
58 | }
59 |
60 | setseasonCount(tempArr);
61 | setDetails(response.data);
62 | return response;
63 | }
64 | async function fetchCredits() {
65 | const response = await axios.get(
66 | `${base_url}${movie_id}/credits?api_key=${api_key}`
67 | );
68 |
69 | setCredits(response.data);
70 | }
71 | async function getVideo() {
72 | const response = await axios.get(
73 | `${base_url}${movie_id}/videos?api_key=${api_key}`
74 | );
75 |
76 | setVideo(response.data.results);
77 | }
78 | async function getDefaultEpisodes() {
79 | const response = await axios.get(
80 | `${base_url}${movie_id}/season/1?api_key=${api_key}`
81 | );
82 |
83 | setEpisodes(response.data.episodes);
84 | }
85 | fetchCredits();
86 | fetchDetails();
87 | getVideo();
88 | getDefaultEpisodes();
89 | }, [base_url, movie_id, api_key]);
90 |
91 | const playVideo = () => {
92 | if (videos) {
93 | setYoutubePlay(true);
94 |
95 | setTrailer_id(videos[0].key);
96 | } else {
97 | setYoutubePlay(false);
98 | }
99 | return trailer_id;
100 | };
101 |
102 | async function getEpisodes() {
103 | const temp = document.getElementById("selectIdTag").value;
104 | const val = temp.substr(7, 8);
105 | const response = await axios.get(
106 | `${base_url}${movie_id}/season/${val}?api_key=${api_key}`
107 | );
108 |
109 | setEpisodes(response.data.episodes);
110 | }
111 |
112 | if (movieDetails) {
113 | detailsLoaded = true;
114 | }
115 | if (credits) {
116 | creditsLoaded = true;
117 | credits.crew.map((person) => {
118 | if (person.known_for_department === "Directing") {
119 | director.push(person.name);
120 | } else if (person.known_for_department === "Production") {
121 | production.push(person.name);
122 | } else if (person.known_for_department === "Writing") {
123 | writing.push(person.name);
124 | } else if (person.known_for_department === "Crew") {
125 | crew.push(person.name);
126 | }
127 | return person.name;
128 | });
129 | }
130 |
131 | if (detailsLoaded && movieDetails.runtime && movieDetails.runtime > 0) {
132 | hours = Math.floor(movieDetails.runtime / 60);
133 | minutes = movieDetails.runtime % 60;
134 | }
135 |
136 | return (
137 |
138 | {detailsLoaded ? (
139 |
140 |
141 |
142 | {movieDetails.title
143 | ? movieDetails.title
144 | : movieDetails.original_name}
145 |
146 |
147 | {/* {movieDetails.overview.length > 90
148 | ? movieDetails.overview.substr(0, 89) + "..."
149 | : movieDetails.overview} */}
150 | {movieDetails.overview}
151 |
152 |
153 |
154 | {seasonCount.length > 0 ? (
155 |
168 | ) : (
169 |
170 | )}
171 |
172 |
173 | IMDb {movieDetails.vote_average}
174 |
175 |
176 | {hours > 0 ? `${hours}h ` : ""}
177 | {minutes > 0 ? `${minutes}min` : ""}
178 |
179 |
180 | {movieDetails.first_air_date
181 | ? movieDetails.first_air_date.substr(0, 4)
182 | : ""}
183 |
184 |
185 | {movieDetails.adult ? "18+" : "ALL"}
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
202 | }
203 | >
204 | Play
205 |
206 |
207 |
208 | }
212 | onClick={() => {
213 | playVideo();
214 | }}
215 | >
216 | Watch Trailer
217 |
218 |
219 |
220 |
227 |
228 |
229 | }
234 | >
235 | Download
236 |
237 |
238 |
239 | {creditsLoaded ? (
240 |
241 |
Director
242 |
{director}
243 |
Starring
244 |
245 | {credits.cast.map((person) => {
246 | let str = "";
247 | if (credits.cast.indexOf(person) < 11) {
248 | str = `${person.name}, `;
249 | }
250 | return str;
251 | })}
252 |
253 |
Genres
254 |
255 | {movieDetails.genres.map((genre) => {
256 | let str = `${genre.name}, `;
257 | return str;
258 | })}
259 |
260 |
261 | ) : (
262 |
263 | )}
264 |
265 |
266 |

271 |
272 |
273 |
274 |
275 | ) : (
276 |
277 | )}
278 |
279 | {YoutubePlay ? (
280 |
281 |
282 | {
286 | setYoutubePlay(false);
287 | }}
288 | color="primary"
289 | className="closeIconButton"
290 | >
291 |
292 |
293 |
294 |
295 |
{
299 | alert("Youtube Not working");
300 | }}
301 | />
302 |
303 | ) : (
304 |
305 | )}
306 |
307 |
308 |
{
310 | setShow(2);
311 | }}
312 | className={detailShow === 2 ? "activeRelated" : ""}
313 | >
314 | Episodes
315 |
316 |
{
318 | setShow(1);
319 | }}
320 | className={detailShow === 1 ? "activeRelated" : ""}
321 | >
322 | Related
323 |
324 |
{
326 | setShow(0);
327 | }}
328 | className={detailShow === 0 ? "activeDetails" : ""}
329 | >
330 | Details
331 |
332 |
333 |
334 |
335 |
336 | {detailsLoaded && detailShow === 1 && (
337 |
343 | )}{" "}
344 | {detailsLoaded && detailShow === 0 && (
345 |
346 |
347 | {production.length > 0 ? (
348 |
Production
349 | ) : (
350 |
351 | )}
352 | {production.length > 0 ? (
353 |
354 | {production.map((person) => {
355 | let str = `${person}, `;
356 | return str;
357 | })}
358 |
359 | ) : (
360 |
361 | )}
362 | {writing.length > 0 ? (
363 |
Writing
364 | ) : (
365 |
366 | )}
367 | {writing.length > 0 ? (
368 |
369 | {writing.map((person) => {
370 | let str = `${person}, `;
371 | return str;
372 | })}
373 |
374 | ) : (
375 |
376 | )}
377 | {crew.length > 0 ? (
378 |
Crew
379 | ) : (
380 |
381 | )}
382 | {crew.length > 0 ? (
383 |
384 | {crew.map((person) => {
385 | let str = `${person}, `;
386 | return str;
387 | })}
388 |
389 | ) : (
390 |
391 | )}
392 |
393 |
394 | )}
395 | {episodes &&
396 | episodes.length > 0 &&
397 | detailShow === 2 &&
398 | episodes.map((episode) => {
399 | return (
400 |
401 | );
402 | })}
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 | );
412 | };
413 | export default TV;
414 |
--------------------------------------------------------------------------------
/src/components/TV/styles.scss:
--------------------------------------------------------------------------------
1 | .movie_image {
2 | width: 950px;
3 | position: absolute;
4 | right: 0px;
5 | object-fit: contain;
6 | z-index: -1;
7 | top: 100px;
8 | }
9 | .imageDiv {
10 | position: absolute;
11 | z-index: 0;
12 | right: 0;
13 | top: 0;
14 | height: 510px;
15 | overflow: hidden;
16 | width: 950px;
17 | padding: 0px;
18 | }
19 | .divImage1 {
20 | position: absolute;
21 | top: 0;
22 | width: 950px;
23 | height: 600px;
24 | right: 0;
25 | background: linear-gradient(90deg, #0f171e 10%, rgba(15, 23, 30, 0));
26 | }
27 | .divImage2 {
28 | position: absolute;
29 | top: 0;
30 | width: 950px;
31 | height: 600px;
32 | right: 0;
33 | background: linear-gradient(0deg, #0f171e 0, rgba(15, 23, 30, 0) 50%);
34 | }
35 | .movieInfo {
36 | position: absolute;
37 | left: 0;
38 | color: white;
39 | margin-left: 30px;
40 | z-index: 2;
41 | }
42 | .title2 {
43 | font-size: 40px;
44 | margin-top: 10px;
45 | font-weight: normal;
46 | }
47 | .overview2 {
48 | // position: absolute;
49 | // margin-top: 40px;
50 | //z-index: 2;
51 | margin-top: 20px;
52 | width: 600px;
53 | font-size: 16px;
54 | line-height: 1.5;
55 | }
56 |
57 | .moviereleaseYear {
58 | font-size: 15px;
59 | color: gray;
60 | margin-bottom: 15px;
61 | }
62 | .movierunTime {
63 | color: darkgray;
64 | font-size: 15px;
65 | }
66 | .moviefooterScreen {
67 | margin-top: 15px;
68 | display: flex;
69 | justify-content: space-between;
70 | vertical-align: middle;
71 | width: 400px;
72 | }
73 | .moviemessageIcon {
74 | color: darkgray;
75 | max-height: 18px;
76 | }
77 | .movierated {
78 | border: 1px solid darkgray;
79 | color: darkgray;
80 | font-size: 12px;
81 | padding: 3px;
82 | height: 10px;
83 | }
84 | .movierating {
85 | color: darkgray;
86 | font-size: 15px;
87 | }
88 | .people {
89 | //position: absolute;
90 | min-width: 500px;
91 | max-width: 70%;
92 | display: grid;
93 | grid-template-columns: 1.3fr 10.7fr;
94 | text-align: left;
95 | margin-top: 40px;
96 | //z-index: 2;
97 | grid-row-gap: 7px;
98 | line-height: 1.5;
99 | }
100 | .peopleHeading {
101 | color: gray;
102 | font-weight: bold;
103 | }
104 | .peopleVal {
105 | color: rgb(6, 167, 196);
106 | }
107 | .buttonGroup {
108 | display: flex;
109 | justify-content: space-evenly;
110 | // z-index: 2;
111 | //position: absolute;
112 | margin-top: 30px;
113 | width: 750px;
114 | padding: 0 auto;
115 | }
116 |
117 | .trailerIcon {
118 | transform: rotate(90deg);
119 | }
120 | .moviePlayText {
121 | color: white;
122 | margin-left: 8px;
123 | //font-size: 20px;
124 | //margin-left: 10px;
125 | }
126 | .moviePlayIcon {
127 | transform: scale(2);
128 | background-color: white;
129 | border-radius: 50%;
130 | //margin-bottom: 30px;
131 | }
132 | .movieButton {
133 | height: 50px;
134 | }
135 | .playmovieButton {
136 | transform: scale(1.5);
137 | }
138 | .relatedMovies {
139 | position: absolute;
140 | top: 650px;
141 | width: 100%;
142 | }
143 | .tabHeading {
144 | display: flex;
145 | justify-content: space-between;
146 | width: 300px;
147 | text-align: center;
148 | margin-left: 40%;
149 | top: 800px;
150 | color: gray;
151 | font-size: 25px;
152 | cursor: pointer;
153 | }
154 |
155 | .activeRelated {
156 | border-bottom: 2px solid white;
157 | color: white;
158 | }
159 | .activeDetails {
160 | border-bottom: 2px solid white;
161 | color: white;
162 | }
163 | .detailsCrew {
164 | margin-left: 30px;
165 | }
166 | .playTrailerVideo {
167 | position: absolute;
168 | top: 0;
169 | left: 0;
170 | z-index: 10;
171 | min-height: 100%;
172 | min-width: 100%;
173 | background-color: rgba(220, 220, 220, 0.5);
174 | transition: background-color 1s ease-in;
175 | padding-top: 100px;
176 | }
177 | .closeButtonDiv {
178 | margin-left: 90%;
179 | }
180 | .closeIconButton {
181 | transform: scale(2);
182 | }
183 | .selectTag {
184 | width: 140px;
185 | height: 40px;
186 | text-align: center;
187 | color: white;
188 | background-color: #425265;
189 | outline: none;
190 | border: none;
191 | font-size: 18px;
192 | padding-left: 20px;
193 | cursor: pointer;
194 | overflow: scroll;
195 | }
196 | .selectTag:hover {
197 | background-color: #0f171e;
198 | opacity: 0.7;
199 | :fullscreen {
200 | opacity: 0.2;
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/src/homeRequests.js:
--------------------------------------------------------------------------------
1 | const API_KEY = "989a8027930013244e3c2af17088dcac";
2 |
3 | const homeRequests = [
4 | {
5 | title: "Comedy",
6 | url: `/discover/movie?api_key=${API_KEY}&with_genres=35`,
7 | media: "movie",
8 | },
9 | {
10 | title: "Action",
11 | url: `/discover/movie?api_key=${API_KEY}&with_genres=28`,
12 | media: "movie",
13 | },
14 | {
15 | title: "Horror",
16 | url: `/discover/movie?api_key=${API_KEY}&with_genres=27`,
17 | media: "movie",
18 | },
19 | {
20 | title: "Adventure TV Shows",
21 | url: `/discover/tv?api_key=${API_KEY}&with_genres=12`,
22 | media: "tv",
23 | },
24 | {
25 | title: "Popular in your Region TV Shows",
26 | url: `/discover/tv?api_key=${API_KEY}®ion=IN`,
27 | media: "tv",
28 | },
29 | ];
30 |
31 | export default homeRequests;
32 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | background-color: #0f171e;
9 | }
10 |
11 | code {
12 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
13 | monospace;
14 | }
15 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 | import { initializeApp } from "firebase/app";
7 | import { getAnalytics } from "firebase/analytics";
8 | // TODO: Add SDKs for Firebase products that you want to use
9 | // https://firebase.google.com/docs/web/setup#available-libraries
10 |
11 | // Your web app's Firebase configuration
12 | // For Firebase JS SDK v7.20.0 and later, measurementId is optional
13 | const firebaseConfig = {
14 | apiKey: "AIzaSyDO0WWJhETy25tIVwRrhFtt52msxFKMis8",
15 | authDomain: "prime-clone-e1de6.firebaseapp.com",
16 | databaseURL: "https://prime-clone-e1de6.firebaseio.com",
17 | projectId: "prime-clone-e1de6",
18 | storageBucket: "prime-clone-e1de6.appspot.com",
19 | messagingSenderId: "536067131178",
20 | appId: "1:536067131178:web:f9642c8a945f59209c4053",
21 | measurementId: "G-ELR0K1QTZ4"
22 | };
23 |
24 | // Initialize Firebase
25 | const app = initializeApp(firebaseConfig);
26 | const analytics = getAnalytics(app);
27 |
28 | ReactDOM.render(
29 |
30 |
31 | ,
32 | document.getElementById('root')
33 | );
34 |
35 | // If you want your app to work offline and load faster, you can change
36 | // unregister() to register() below. Note this comes with some pitfalls.
37 | // Learn more about service workers: https://bit.ly/CRA-PWA
38 | serviceWorker.unregister();
39 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/requests.js:
--------------------------------------------------------------------------------
1 | const API_KEY = "989a8027930013244e3c2af17088dcac";
2 |
3 | const requests = [
4 | {
5 | title: "Discover",
6 | url: `/discover/movie?api_key=${API_KEY}`,
7 | media: "movie",
8 | },
9 | {
10 | title: "Comedy",
11 | url: `/discover/movie?api_key=${API_KEY}&with_genres=35`,
12 | media: "movie",
13 | },
14 | {
15 | title: "Action",
16 | url: `/discover/movie?api_key=${API_KEY}&with_genres=28`,
17 | media: "movie",
18 | },
19 | {
20 | title: "Adventure",
21 | url: `/discover/movie?api_key=${API_KEY}&with_genres=12`,
22 | media: "movie",
23 | },
24 | {
25 | title: "Science Fiction",
26 | url: `/discover/movie?api_key=${API_KEY}&with_genres=878`,
27 | media: "movie",
28 | },
29 | {
30 | title: "Horror",
31 | url: `/discover/movie?api_key=${API_KEY}&with_genres=27`,
32 | media: "movie",
33 | },
34 | {
35 | title: "Drama",
36 | url: `/discover/movie?api_key=${API_KEY}&with_genres=18`,
37 | media: "movie",
38 | },
39 | {
40 | title: "Popular in your Region",
41 | url: `/discover/movie?api_key=${API_KEY}®ion=IN`,
42 | media: "movie",
43 | },
44 | {
45 | title: "Will Smith's Hits",
46 | url: `/discover/movie?api_key=${API_KEY}&with_people=2888`,
47 | media: "movie",
48 | },
49 | {
50 | title: "Thriller",
51 | url: `/discover/movie?api_key=${API_KEY}&with_genres=53`,
52 | media: "movie",
53 | },
54 | {
55 | title: "Crime",
56 | url: `/discover/movie?api_key=${API_KEY}&with_genres=80`,
57 | media: "movie",
58 | },
59 | {
60 | title: "Short Films",
61 | url: `/discover/movie?api_key=${API_KEY}&with_runtime.lte=70`,
62 | media: "movie",
63 | },
64 | ];
65 |
66 | export default requests;
67 |
--------------------------------------------------------------------------------
/src/serviceWorker.js:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.0/8 are considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | export function register(config) {
24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
25 | // The URL constructor is available in all browsers that support SW.
26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
27 | if (publicUrl.origin !== window.location.origin) {
28 | // Our service worker won't work if PUBLIC_URL is on a different origin
29 | // from what our page is served on. This might happen if a CDN is used to
30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
31 | return;
32 | }
33 |
34 | window.addEventListener('load', () => {
35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
36 |
37 | if (isLocalhost) {
38 | // This is running on localhost. Let's check if a service worker still exists or not.
39 | checkValidServiceWorker(swUrl, config);
40 |
41 | // Add some additional logging to localhost, pointing developers to the
42 | // service worker/PWA documentation.
43 | navigator.serviceWorker.ready.then(() => {
44 | console.log(
45 | 'This web app is being served cache-first by a service ' +
46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
47 | );
48 | });
49 | } else {
50 | // Is not localhost. Just register service worker
51 | registerValidSW(swUrl, config);
52 | }
53 | });
54 | }
55 | }
56 |
57 | function registerValidSW(swUrl, config) {
58 | navigator.serviceWorker
59 | .register(swUrl)
60 | .then(registration => {
61 | registration.onupdatefound = () => {
62 | const installingWorker = registration.installing;
63 | if (installingWorker == null) {
64 | return;
65 | }
66 | installingWorker.onstatechange = () => {
67 | if (installingWorker.state === 'installed') {
68 | if (navigator.serviceWorker.controller) {
69 | // At this point, the updated precached content has been fetched,
70 | // but the previous service worker will still serve the older
71 | // content until all client tabs are closed.
72 | console.log(
73 | 'New content is available and will be used when all ' +
74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
75 | );
76 |
77 | // Execute callback
78 | if (config && config.onUpdate) {
79 | config.onUpdate(registration);
80 | }
81 | } else {
82 | // At this point, everything has been precached.
83 | // It's the perfect time to display a
84 | // "Content is cached for offline use." message.
85 | console.log('Content is cached for offline use.');
86 |
87 | // Execute callback
88 | if (config && config.onSuccess) {
89 | config.onSuccess(registration);
90 | }
91 | }
92 | }
93 | };
94 | };
95 | })
96 | .catch(error => {
97 | console.error('Error during service worker registration:', error);
98 | });
99 | }
100 |
101 | function checkValidServiceWorker(swUrl, config) {
102 | // Check if the service worker can be found. If it can't reload the page.
103 | fetch(swUrl, {
104 | headers: { 'Service-Worker': 'script' },
105 | })
106 | .then(response => {
107 | // Ensure service worker exists, and that we really are getting a JS file.
108 | const contentType = response.headers.get('content-type');
109 | if (
110 | response.status === 404 ||
111 | (contentType != null && contentType.indexOf('javascript') === -1)
112 | ) {
113 | // No service worker found. Probably a different app. Reload the page.
114 | navigator.serviceWorker.ready.then(registration => {
115 | registration.unregister().then(() => {
116 | window.location.reload();
117 | });
118 | });
119 | } else {
120 | // Service worker found. Proceed as normal.
121 | registerValidSW(swUrl, config);
122 | }
123 | })
124 | .catch(() => {
125 | console.log(
126 | 'No internet connection found. App is running in offline mode.'
127 | );
128 | });
129 | }
130 |
131 | export function unregister() {
132 | if ('serviceWorker' in navigator) {
133 | navigator.serviceWorker.ready
134 | .then(registration => {
135 | registration.unregister();
136 | })
137 | .catch(error => {
138 | console.error(error.message);
139 | });
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/src/tvRequests.js:
--------------------------------------------------------------------------------
1 | const API_KEY = "989a8027930013244e3c2af17088dcac";
2 |
3 | const tvrequests = [
4 | {
5 | title: "Discover TV Shows",
6 | url: `/discover/tv?api_key=${API_KEY}`,
7 | media: "tv",
8 | },
9 | {
10 | title: "Comedy TV Shows",
11 | url: `/discover/tv?api_key=${API_KEY}&with_genres=35`,
12 | media: "tv",
13 | },
14 | {
15 | title: "Adventure TV Shows",
16 | url: `/discover/tv?api_key=${API_KEY}&with_genres=12`,
17 | media: "tv",
18 | },
19 | {
20 | title: "Popular in your Region TV Shows",
21 | url: `/discover/tv?api_key=${API_KEY}®ion=IN`,
22 | media: "tv",
23 | },
24 | ];
25 | export default tvrequests;
26 |
--------------------------------------------------------------------------------