├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── images │ ├── films │ │ ├── children │ │ │ ├── despicable-me │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── frozen │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── hotel-transylvania │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── spirited-away │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ └── up │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ ├── drama │ │ │ ├── fight-club │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── kings-speech │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── the-prestige │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── the-revenant │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ └── the-social-network │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ ├── romance │ │ │ ├── a-star-is-born │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── blue-valentine │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── la-la-land │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── the-notebook │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ └── titanic │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ ├── suspense │ │ │ ├── gone-girl │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── prisoners │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── seven │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── shutter-island │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ └── zodiac │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ └── thriller │ │ │ ├── a-quiet-place │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ │ ├── black-swan │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ │ ├── joker │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ │ ├── nightcrawler │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ │ └── the-silence-of-the-lambs │ │ │ ├── large.jpg │ │ │ └── small.jpg │ ├── icons │ │ ├── add.png │ │ ├── chevron-right.png │ │ ├── close-slim.png │ │ ├── close.png │ │ └── search.png │ ├── misc │ │ ├── home-bg.jpg │ │ ├── home-imac.jpg │ │ ├── home-kids.png │ │ ├── home-mobile-1.jpg │ │ ├── home-mobile.jpg │ │ ├── home-tv.jpg │ │ ├── home-tv.png │ │ ├── joker1.jpg │ │ ├── loading.gif │ │ ├── originals1.jpg │ │ └── spinner.png │ ├── series │ │ ├── children │ │ │ ├── arthur │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── dora-the-explorer │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── paw-patrol │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── peppa-pig │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ └── spongebob │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ ├── comedies │ │ │ ├── arrested-development │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── curb-your-enthusiasm │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── family-guy │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── south-park │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ └── the-office │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ ├── crime │ │ │ ├── long-shot │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── making-a-murderer │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── the-confession-killer │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── the-innocent-man │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ └── the-staircase │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ ├── documentaries │ │ │ ├── amanda-knox │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── citizenfour │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── man-on-wire │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── super-size-me │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ └── tiger-king │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ └── feel-good │ │ │ ├── forrest-gump │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ │ ├── good-will-hunting │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ │ ├── juno │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ │ ├── midnight-in-paris │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ │ └── school-of-rock │ │ │ ├── large.jpg │ │ │ └── small.jpg │ └── users │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ └── 5.png ├── index.html └── videos │ └── intro.mp4 ├── screenshots ├── 1.png ├── 2.png └── 3.png └── src ├── App.js ├── components ├── accordion │ ├── accordion.jsx │ └── styles │ │ └── accordion.js ├── card │ ├── card.jsx │ └── styles │ │ └── card.js ├── feature │ ├── feature.jsx │ └── styles │ │ └── feature.js ├── footer │ ├── footer.jsx │ └── styles │ │ └── footer.js ├── form │ ├── form.jsx │ └── styles │ │ └── form.js ├── header │ ├── header.jsx │ └── styles │ │ └── header.js ├── jumbotron │ ├── jumbotron.jsx │ └── styles │ │ └── jumbotron.js ├── loading │ ├── loading.jsx │ └── styles │ │ └── loading.js ├── optForm │ ├── optForm.jsx │ └── styles │ │ └── optForm.js ├── player │ ├── player.jsx │ └── styles │ │ └── player.js └── profiles │ ├── profiles.jsx │ └── styles │ └── profiles.js ├── constants └── routes.js ├── containers ├── accordionContainer.jsx ├── browseContainer.jsx ├── footerContainer.jsx ├── headerContainer.jsx ├── jumbotronContainer.jsx └── profileContainer.jsx ├── context └── firebase.js ├── fixtures ├── faqs.json └── jumbo.json ├── globalStyles.js ├── helpers └── routes.js ├── hooks ├── index.js ├── useAuthListener.js └── useContent.js ├── index.js ├── lib └── firebase.prod.js ├── logo.png ├── logo.svg ├── pages ├── browse.jsx ├── home.jsx ├── signin.jsx └── signup.jsx ├── seed.js └── utils └── selectionFilter.js /.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 | /firebase.json 14 | /.firebaserc 15 | /.github 16 | /.firebase 17 | 18 | # misc 19 | .DS_Store 20 | .env.local 21 | .env.development.local 22 | .env.test.local 23 | .env.production.local 24 | 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Netflix Clone 2 | This is a netflix clone project. It has multiple pages which are linked together including the homepage, login, signup, profile, watchlist, and search. 3 | 4 | ## How To Use 5 | - You can clone the repo, install the dependencies, and run your localhost. 6 | - You can also head over to the live site to see the app. 7 | - Create and account by going to the signup page. 8 | - When you are logged in, you will be taken to the browse page to see the movies. 9 | ## Technologies Used 10 | * [React](https://reactjs.org/) 11 | * [React Router](https://reactrouter.com/docs/en/v6/getting-started/tutorial) 12 | * [Firebase](https://firebase.google.com/) 13 | * [FuseJS](https://fusejs.io/) 14 | * Normalize.css 15 | 16 | ## What I learned 17 | - Custom hooks 18 | - Authentication 19 | - Compound components 20 | - `useEffect`, `useState`, `useContext` 21 | - Routing 22 | - [Git Commmit Conventions](https://raw.githubusercontent.com/legend80s/commit-msg-linter/master/assets/demo-7-compressed.png) 23 | - Effective debugging 24 | - State Management 25 | 26 | ## Notes to remember 27 | - `...restProps` is used to to pass props to the component and its children. 28 | 29 | ## Resources Used 30 | - [npm](https://www.npmjs.com/) 31 | - [Netflix](https://www.netflix.com/gh/) 32 | 33 | ## Demo 34 | I am current having issues with deployments so a live version of the app is not available yet 35 | 36 | ## How it looks 37 | 38 | ![](screenshots/1.png) 39 | ![](screenshots/2.png) 40 | ![](screenshots/3.png) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "netflix-clone", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.4", 7 | "@testing-library/react": "^13.3.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "firebase": "^7.19.1", 10 | "fuse.js": "^6.6.2", 11 | "normalize.css": "^8.0.1", 12 | "react": "^18.2.0", 13 | "react-dom": "^18.2.0", 14 | "react-router-dom": "^5.2.0", 15 | "react-scripts": "5.0.1", 16 | "styled-components": "^5.3.5", 17 | "web-vitals": "^2.1.4" 18 | }, 19 | "scripts": { 20 | "start": "react-scripts start", 21 | "build": "react-scripts build", 22 | "test": "react-scripts test", 23 | "eject": "react-scripts eject" 24 | }, 25 | "eslintConfig": { 26 | "extends": [ 27 | "react-app", 28 | "react-app/jest" 29 | ] 30 | }, 31 | "browserslist": { 32 | "production": [ 33 | ">0.2%", 34 | "not dead", 35 | "not op_mini all" 36 | ], 37 | "development": [ 38 | "last 1 chrome version", 39 | "last 1 firefox version", 40 | "last 1 safari version" 41 | ] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/favicon.ico -------------------------------------------------------------------------------- /public/images/films/children/despicable-me/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/children/despicable-me/large.jpg -------------------------------------------------------------------------------- /public/images/films/children/despicable-me/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/children/despicable-me/small.jpg -------------------------------------------------------------------------------- /public/images/films/children/frozen/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/children/frozen/large.jpg -------------------------------------------------------------------------------- /public/images/films/children/frozen/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/children/frozen/small.jpg -------------------------------------------------------------------------------- /public/images/films/children/hotel-transylvania/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/children/hotel-transylvania/large.jpg -------------------------------------------------------------------------------- /public/images/films/children/hotel-transylvania/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/children/hotel-transylvania/small.jpg -------------------------------------------------------------------------------- /public/images/films/children/spirited-away/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/children/spirited-away/large.jpg -------------------------------------------------------------------------------- /public/images/films/children/spirited-away/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/children/spirited-away/small.jpg -------------------------------------------------------------------------------- /public/images/films/children/up/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/children/up/large.jpg -------------------------------------------------------------------------------- /public/images/films/children/up/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/children/up/small.jpg -------------------------------------------------------------------------------- /public/images/films/drama/fight-club/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/drama/fight-club/large.jpg -------------------------------------------------------------------------------- /public/images/films/drama/fight-club/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/drama/fight-club/small.jpg -------------------------------------------------------------------------------- /public/images/films/drama/kings-speech/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/drama/kings-speech/large.jpg -------------------------------------------------------------------------------- /public/images/films/drama/kings-speech/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/drama/kings-speech/small.jpg -------------------------------------------------------------------------------- /public/images/films/drama/the-prestige/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/drama/the-prestige/large.jpg -------------------------------------------------------------------------------- /public/images/films/drama/the-prestige/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/drama/the-prestige/small.jpg -------------------------------------------------------------------------------- /public/images/films/drama/the-revenant/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/drama/the-revenant/large.jpg -------------------------------------------------------------------------------- /public/images/films/drama/the-revenant/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/drama/the-revenant/small.jpg -------------------------------------------------------------------------------- /public/images/films/drama/the-social-network/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/drama/the-social-network/large.jpg -------------------------------------------------------------------------------- /public/images/films/drama/the-social-network/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/drama/the-social-network/small.jpg -------------------------------------------------------------------------------- /public/images/films/romance/a-star-is-born/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/romance/a-star-is-born/large.jpg -------------------------------------------------------------------------------- /public/images/films/romance/a-star-is-born/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/romance/a-star-is-born/small.jpg -------------------------------------------------------------------------------- /public/images/films/romance/blue-valentine/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/romance/blue-valentine/large.jpg -------------------------------------------------------------------------------- /public/images/films/romance/blue-valentine/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/romance/blue-valentine/small.jpg -------------------------------------------------------------------------------- /public/images/films/romance/la-la-land/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/romance/la-la-land/large.jpg -------------------------------------------------------------------------------- /public/images/films/romance/la-la-land/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/romance/la-la-land/small.jpg -------------------------------------------------------------------------------- /public/images/films/romance/the-notebook/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/romance/the-notebook/large.jpg -------------------------------------------------------------------------------- /public/images/films/romance/the-notebook/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/romance/the-notebook/small.jpg -------------------------------------------------------------------------------- /public/images/films/romance/titanic/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/romance/titanic/large.jpg -------------------------------------------------------------------------------- /public/images/films/romance/titanic/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/romance/titanic/small.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/gone-girl/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/suspense/gone-girl/large.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/gone-girl/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/suspense/gone-girl/small.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/prisoners/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/suspense/prisoners/large.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/prisoners/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/suspense/prisoners/small.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/seven/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/suspense/seven/large.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/seven/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/suspense/seven/small.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/shutter-island/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/suspense/shutter-island/large.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/shutter-island/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/suspense/shutter-island/small.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/zodiac/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/suspense/zodiac/large.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/zodiac/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/suspense/zodiac/small.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/a-quiet-place/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/thriller/a-quiet-place/large.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/a-quiet-place/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/thriller/a-quiet-place/small.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/black-swan/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/thriller/black-swan/large.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/black-swan/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/thriller/black-swan/small.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/joker/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/thriller/joker/large.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/joker/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/thriller/joker/small.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/nightcrawler/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/thriller/nightcrawler/large.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/nightcrawler/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/thriller/nightcrawler/small.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/the-silence-of-the-lambs/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/thriller/the-silence-of-the-lambs/large.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/the-silence-of-the-lambs/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/films/thriller/the-silence-of-the-lambs/small.jpg -------------------------------------------------------------------------------- /public/images/icons/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/icons/add.png -------------------------------------------------------------------------------- /public/images/icons/chevron-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/icons/chevron-right.png -------------------------------------------------------------------------------- /public/images/icons/close-slim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/icons/close-slim.png -------------------------------------------------------------------------------- /public/images/icons/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/icons/close.png -------------------------------------------------------------------------------- /public/images/icons/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/icons/search.png -------------------------------------------------------------------------------- /public/images/misc/home-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/misc/home-bg.jpg -------------------------------------------------------------------------------- /public/images/misc/home-imac.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/misc/home-imac.jpg -------------------------------------------------------------------------------- /public/images/misc/home-kids.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/misc/home-kids.png -------------------------------------------------------------------------------- /public/images/misc/home-mobile-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/misc/home-mobile-1.jpg -------------------------------------------------------------------------------- /public/images/misc/home-mobile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/misc/home-mobile.jpg -------------------------------------------------------------------------------- /public/images/misc/home-tv.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/misc/home-tv.jpg -------------------------------------------------------------------------------- /public/images/misc/home-tv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/misc/home-tv.png -------------------------------------------------------------------------------- /public/images/misc/joker1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/misc/joker1.jpg -------------------------------------------------------------------------------- /public/images/misc/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/misc/loading.gif -------------------------------------------------------------------------------- /public/images/misc/originals1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/misc/originals1.jpg -------------------------------------------------------------------------------- /public/images/misc/spinner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/misc/spinner.png -------------------------------------------------------------------------------- /public/images/series/children/arthur/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/children/arthur/large.jpg -------------------------------------------------------------------------------- /public/images/series/children/arthur/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/children/arthur/small.jpg -------------------------------------------------------------------------------- /public/images/series/children/dora-the-explorer/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/children/dora-the-explorer/large.jpg -------------------------------------------------------------------------------- /public/images/series/children/dora-the-explorer/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/children/dora-the-explorer/small.jpg -------------------------------------------------------------------------------- /public/images/series/children/paw-patrol/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/children/paw-patrol/large.jpg -------------------------------------------------------------------------------- /public/images/series/children/paw-patrol/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/children/paw-patrol/small.jpg -------------------------------------------------------------------------------- /public/images/series/children/peppa-pig/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/children/peppa-pig/large.jpg -------------------------------------------------------------------------------- /public/images/series/children/peppa-pig/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/children/peppa-pig/small.jpg -------------------------------------------------------------------------------- /public/images/series/children/spongebob/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/children/spongebob/large.jpg -------------------------------------------------------------------------------- /public/images/series/children/spongebob/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/children/spongebob/small.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/arrested-development/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/comedies/arrested-development/large.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/arrested-development/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/comedies/arrested-development/small.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/curb-your-enthusiasm/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/comedies/curb-your-enthusiasm/large.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/curb-your-enthusiasm/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/comedies/curb-your-enthusiasm/small.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/family-guy/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/comedies/family-guy/large.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/family-guy/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/comedies/family-guy/small.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/south-park/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/comedies/south-park/large.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/south-park/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/comedies/south-park/small.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/the-office/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/comedies/the-office/large.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/the-office/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/comedies/the-office/small.jpg -------------------------------------------------------------------------------- /public/images/series/crime/long-shot/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/crime/long-shot/large.jpg -------------------------------------------------------------------------------- /public/images/series/crime/long-shot/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/crime/long-shot/small.jpg -------------------------------------------------------------------------------- /public/images/series/crime/making-a-murderer/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/crime/making-a-murderer/large.jpg -------------------------------------------------------------------------------- /public/images/series/crime/making-a-murderer/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/crime/making-a-murderer/small.jpg -------------------------------------------------------------------------------- /public/images/series/crime/the-confession-killer/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/crime/the-confession-killer/large.jpg -------------------------------------------------------------------------------- /public/images/series/crime/the-confession-killer/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/crime/the-confession-killer/small.jpg -------------------------------------------------------------------------------- /public/images/series/crime/the-innocent-man/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/crime/the-innocent-man/large.jpg -------------------------------------------------------------------------------- /public/images/series/crime/the-innocent-man/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/crime/the-innocent-man/small.jpg -------------------------------------------------------------------------------- /public/images/series/crime/the-staircase/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/crime/the-staircase/large.jpg -------------------------------------------------------------------------------- /public/images/series/crime/the-staircase/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/crime/the-staircase/small.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/amanda-knox/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/documentaries/amanda-knox/large.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/amanda-knox/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/documentaries/amanda-knox/small.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/citizenfour/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/documentaries/citizenfour/large.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/citizenfour/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/documentaries/citizenfour/small.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/man-on-wire/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/documentaries/man-on-wire/large.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/man-on-wire/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/documentaries/man-on-wire/small.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/super-size-me/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/documentaries/super-size-me/large.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/super-size-me/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/documentaries/super-size-me/small.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/tiger-king/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/documentaries/tiger-king/large.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/tiger-king/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/documentaries/tiger-king/small.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/forrest-gump/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/feel-good/forrest-gump/large.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/forrest-gump/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/feel-good/forrest-gump/small.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/good-will-hunting/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/feel-good/good-will-hunting/large.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/good-will-hunting/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/feel-good/good-will-hunting/small.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/juno/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/feel-good/juno/large.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/juno/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/feel-good/juno/small.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/midnight-in-paris/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/feel-good/midnight-in-paris/large.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/midnight-in-paris/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/feel-good/midnight-in-paris/small.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/school-of-rock/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/feel-good/school-of-rock/large.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/school-of-rock/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/series/feel-good/school-of-rock/small.jpg -------------------------------------------------------------------------------- /public/images/users/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/users/1.png -------------------------------------------------------------------------------- /public/images/users/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/users/2.png -------------------------------------------------------------------------------- /public/images/users/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/users/3.png -------------------------------------------------------------------------------- /public/images/users/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/users/4.png -------------------------------------------------------------------------------- /public/images/users/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/images/users/5.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Nutiflix 9 | 10 | 11 | 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /public/videos/intro.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/public/videos/intro.mp4 -------------------------------------------------------------------------------- /screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/screenshots/1.png -------------------------------------------------------------------------------- /screenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/screenshots/2.png -------------------------------------------------------------------------------- /screenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/screenshots/3.png -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' 3 | import * as ROUTES from './constants/routes' 4 | import Home from './pages/home' 5 | import Browse from './pages/browse' 6 | import SignIn from './pages/signin' 7 | import SignUp from './pages/signup' 8 | import { IsUserRedirect, ProtectedRoute } from './helpers/routes' 9 | // import { useAuthListener } from './hooks' 10 | import useAuthListener from './hooks/useAuthListener' 11 | 12 | const App = () => { 13 | const {user} = useAuthListener() 14 | console.log(user) 15 | return ( 16 | 17 | 18 | {/* */} 19 | 25 | 26 | 27 | 28 | {/* */} 29 | 35 | 36 | 37 | 38 | {/* */} 39 | 40 | 41 | 42 | 43 | {/* */} 44 | 50 | 51 | 52 | 53 | 54 | ) 55 | } 56 | 57 | export default App 58 | -------------------------------------------------------------------------------- /src/components/accordion/accordion.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | import { createContext, useContext } from 'react' 3 | import { 4 | Container, 5 | Inner, 6 | Title, 7 | Frame, 8 | Item, 9 | Header, 10 | Body, 11 | } from './styles/accordion' 12 | 13 | // Context is a React component that provides the value of the state 14 | const ToggleContext = createContext() 15 | 16 | export const Accordion = ({ children, ...restProps }) => { 17 | return ( 18 | 19 | {children} 20 | 21 | ) 22 | } 23 | 24 | const AccordionContainer = ({ children, ...restProps }) => { 25 | return {children} 26 | } 27 | Accordion.Container = AccordionContainer 28 | 29 | const AccordionTitle = ({ children, ...restProps }) => { 30 | return {children} 31 | } 32 | Accordion.Title = AccordionTitle 33 | 34 | const AccordionFrame = ({ children, ...restProps }) => { 35 | return {children} 36 | } 37 | Accordion.Frame = AccordionFrame 38 | 39 | const AccordionItem = ({ children, ...restProps }) => { 40 | // Managing the state of the accordion item 41 | const [toggleShow, setToggleShow] = useState(false) // accordion is closed by default 42 | return ( 43 | // shares the state with the children (AccordionHeader and AccordionBody) 44 | 45 | {children} 46 | 47 | ) 48 | } 49 | Accordion.Item = AccordionItem 50 | 51 | const AccordionHeader = ({ children, ...restProps }) => { 52 | // We need to use useContext to access the toggleShow state 53 | const { toggleShow, setToggleShow } = useContext(ToggleContext) 54 | return ( 55 | // Onclick, pass the previous state and invert it 56 |
setToggleShow((toggleShow) => !toggleShow)} 58 | {...restProps} 59 | > 60 | {children} 61 | {/* If the state is true, display the close img else display the add img*/} 62 | {toggleShow ? ( 63 | close 64 | ) : ( 65 | add 66 | )} 67 | 68 |
69 | ) 70 | } 71 | Accordion.Header = AccordionHeader 72 | 73 | const AccordionBody = ({ children, ...restProps }) => { 74 | // We need to use useContext to access the toggleShow state 75 | const { toggleShow } = useContext(ToggleContext) 76 | 77 | // If the state is true, display the body 78 | return toggleShow ? {children} : null 79 | } 80 | Accordion.Body = AccordionBody 81 | 82 | // export default Accordion 83 | -------------------------------------------------------------------------------- /src/components/accordion/styles/accordion.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro' 2 | 3 | export const Container = styled.div` 4 | display: flex; 5 | border-bottom: 8px solid #222; 6 | flex-direction: column; 7 | padding: 50px 0; 8 | ` 9 | 10 | export const Inner = styled.div` 11 | display: flex; 12 | padding: 70px 45px; 13 | flex-direction: column; 14 | max-width: 815px; 15 | margin: auto; 16 | ` 17 | 18 | export const Frame = styled.div` 19 | margin-bottom: 40px; 20 | 21 | @media (max-width: 600px) { 22 | padding: 0 20px; 23 | } 24 | ` 25 | 26 | export const Item = styled.div` 27 | color: white; 28 | margin: auto; 29 | margin-bottom: 10px; 30 | max-width: 728px; 31 | width: 100%; 32 | 33 | &:first-of-type { 34 | margin-top: 3em; 35 | } 36 | &:last-of-type { 37 | // margin-bottom: 0; 38 | } 39 | ` 40 | 41 | export const Title = styled.h1` 42 | font-size: 50px; 43 | line-height: 1.1; 44 | margin-top: 1rem; 45 | margin-bottom: 1rem; 46 | color: white; 47 | text-align: center; 48 | 49 | @media (max-width: 600px) { 50 | font-size: 35px; 51 | } 52 | ` 53 | 54 | export const Header = styled.div` 55 | display: flex; 56 | justify-content: space-between; 57 | cursor: pointer; 58 | margin-bottom: 1px; 59 | font-size: 26px; 60 | font-weight: normal; 61 | background: #303030; 62 | padding: 0.8em 1.2em 0.8em 1.2em; 63 | user-select: none; 64 | align-items: center; 65 | 66 | img { 67 | filter: brightness(0) invert(1); //Change the color to white 68 | width: 24px; 69 | user-select: none; 70 | @media (max-width: 600px) { 71 | width: 16px; 72 | } 73 | } 74 | 75 | @media (max-width: 600px) { 76 | font-size: 16px; 77 | } 78 | ` 79 | 80 | export const Body = styled.div` 81 | font-size: 26px; 82 | font-weight: normal; 83 | line-height: normal; 84 | background: #303030; 85 | white-space: pre-wrap; 86 | user-select: none; 87 | overflow: hidden; 88 | transition: max-height 0.25s cubic-bezier(0.5, 0, 0.1, 1); 89 | max-height: 1200px; 90 | padding: 0.8em 2.2em 0.8em 1.2em; 91 | 92 | @media (max-width: 600px) { 93 | font-size: 16px; 94 | line-height: 22px; 95 | } 96 | ` 97 | -------------------------------------------------------------------------------- /src/components/card/card.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext, createContext } from 'react' 2 | import { 3 | Container, 4 | Group, 5 | Title, 6 | SubTitle, 7 | Text, 8 | Feature, 9 | FeatureTitle, 10 | FeatureText, 11 | FeatureClose, 12 | Maturity, 13 | Content, 14 | Entities, 15 | Meta, 16 | Item, 17 | Image, 18 | SpaceBetween 19 | } from './styles/card' 20 | 21 | export const FeatureContext = createContext() 22 | 23 | const Card = ({ children, ...restProps }) => { 24 | const [showFeature, setShowFeature] = useState(false) 25 | const [itemFeature, setItemFeature] = useState({}) 26 | 27 | return ( 28 | 31 | {children} 32 | 33 | ) 34 | } 35 | 36 | const CardGroup = ({ children, ...restProps }) => { 37 | return {children} 38 | } 39 | const CardSpaceBetween = ({ children, ...restProps }) => { 40 | return {children} 41 | } 42 | const CardTitle = ({ children, ...restProps }) => { 43 | return {children} 44 | } 45 | const CardSubTitle = ({ children, ...restProps }) => { 46 | return {children} 47 | } 48 | const CardText = ({ children, ...restProps }) => { 49 | return {children} 50 | } 51 | const CardMeta = ({ children, ...restProps }) => { 52 | return {children} 53 | } 54 | 55 | const CardEntities = ({ children, ...restProps }) => { 56 | return {children} 57 | } 58 | const CardItem = ({ item, children, ...restProps }) => { 59 | const { setShowFeature, setItemFeature } = useContext(FeatureContext) 60 | 61 | return ( 62 | { 65 | setItemFeature(item) 66 | setShowFeature(true) 67 | }} 68 | > 69 | {children} 70 | 71 | ) 72 | } 73 | 74 | const CardImage = ({ ...restProps }) => { 75 | return 76 | } 77 | 78 | // we need the category to access the folders 79 | const CardFeature = ({ children, category, ...restProps }) => { 80 | const { showFeature, itemFeature, setShowFeature } = 81 | useContext(FeatureContext) 82 | 83 | // if showFeature is true, show the feature else return null 84 | return showFeature ? ( 85 | 89 | 90 | 91 | 92 | {itemFeature.title} 93 | setShowFeature(false)}> 94 | Close 95 | 96 | 97 | {itemFeature.description} 98 | 99 | 104 | 105 | {/* If the maturity is less than 13 display PG else display the rating itself */} 106 | {itemFeature.maturity < 13 ? 'PG' : itemFeature.maturity} 107 | 108 | 109 | {/* Capitalising the first letter */} 110 | {itemFeature.genre.charAt(0).toUpperCase() + 111 | itemFeature.genre.slice(1)} 112 | 113 | 114 | {children} 115 | 116 | ) : null 117 | } 118 | 119 | Card.Group = CardGroup 120 | Card.SpaceBetween = CardSpaceBetween 121 | Card.Title = CardTitle 122 | Card.SubTitle = CardSubTitle 123 | Card.Text = CardText 124 | Card.Meta = CardMeta 125 | Card.Entities = CardEntities 126 | Card.Item = CardItem 127 | Card.Image = CardImage 128 | Card.Feature = CardFeature 129 | 130 | export default Card 131 | -------------------------------------------------------------------------------- /src/components/card/styles/card.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | 3 | export const Title = styled.p` 4 | font-size: 24px; 5 | color: #e5e5e5; 6 | font-weight: bold; 7 | margin-left: 56px; 8 | margin-right: 56px; 9 | margin-top: 0; 10 | `; 11 | 12 | export const Container = styled.div` 13 | display: flex; 14 | flex-direction: column; 15 | margin-bottom: 50px; 16 | 17 | > ${Title} { 18 | @media (max-width: 1000px) { 19 | margin-left: 30px; 20 | } 21 | } 22 | 23 | &:last-of-type { 24 | margin-bottom: 0; 25 | } 26 | `; 27 | 28 | export const SpaceBetween = styled.div` 29 | display: flex; 30 | align-items: center; 31 | justify-content: space-between; 32 | position: relative; 33 | `; 34 | 35 | export const Group = styled.div` 36 | display: flex; 37 | flex-direction: ${({ flexDirection }) => (flexDirection === 'row' ? 'row' : 'column')}; 38 | ${({ alignItems }) => alignItems && `align-items: ${alignItems}`}; 39 | ${({ margin }) => margin && `margin: ${margin}`}; 40 | // margin-top: 200px; 41 | 42 | @media (max-width: 1000px) { 43 | // margin-top: 70px; 44 | } 45 | 46 | > ${Container}:first-of-type { 47 | @media (min-width: 1100px) { 48 | // margin-top: -100px; 49 | } 50 | } 51 | `; 52 | 53 | export const SubTitle = styled.p` 54 | font-size: 12px; 55 | color: #fff; 56 | font-weight: bold; 57 | margin-top: 0; 58 | margin-bottom: 0; 59 | user-select: none; 60 | display: none; 61 | `; 62 | 63 | export const Text = styled.p` 64 | margin-top: 5px; 65 | font-size: 10px; 66 | color: #fff; 67 | margin-bottom: 0; 68 | user-select: none; 69 | display: none; 70 | line-height: normal; 71 | `; 72 | 73 | export const Entities = styled.div` 74 | display: flex; 75 | flex-direction: row; 76 | max-width: 100vw; 77 | overflow: auto; 78 | 79 | @media (max-width: 700px) { 80 | } 81 | 82 | &::-webkit-scrollbar { 83 | display:none 84 | } 85 | `; 86 | 87 | export const Meta = styled.div` 88 | display: none; 89 | position: absolute; 90 | bottom: 0; 91 | padding: 10px; 92 | background-color: #0000008f; 93 | `; 94 | 95 | export const Image = styled.img` 96 | border: 0; 97 | width: 100%; 98 | max-width: 305px; 99 | cursor: pointer; 100 | height: auto; 101 | padding: 0; 102 | margin: 0; 103 | min-width: 250px; 104 | 105 | @media (max-width: 700px) { 106 | min-width: 200px; 107 | } 108 | `; 109 | 110 | export const Item = styled.div` 111 | display: flex; 112 | flex-direction: column; 113 | margin-right: 5px; 114 | position: relative; 115 | cursor: pointer; 116 | transition: transform 0.2s; 117 | 118 | 119 | &:hover { 120 | transform: scale(1.3); 121 | z-index: 99; 122 | } 123 | 124 | @media (max-width: 900px) { 125 | &:hover { 126 | 127 | transform: scale(1.05) 128 | } 129 | } 130 | 131 | @media (min-width: 1200px) { 132 | &:hover ${Meta}, &:hover ${Text}, &:hover ${SubTitle} { 133 | display: block; 134 | z-index: 100; 135 | } 136 | } 137 | 138 | &:first-of-type { 139 | margin-left: 56px; 140 | 141 | @media (max-width: 1000px) { 142 | margin-left: 30px; 143 | } 144 | } 145 | 146 | &:last-of-type { 147 | margin-right: 56px; 148 | 149 | @media (max-width: 1000px) { 150 | margin-right: 30px; 151 | } 152 | } 153 | `; 154 | 155 | export const FeatureText = styled.p` 156 | font-size: 18px; 157 | color: white; 158 | font-weight: ${({ fontWeight }) => (fontWeight === 'bold' ? 'bold' : 'normal')}; 159 | margin: 0; 160 | 161 | @media (max-width: 600px) { 162 | line-height: 22px; 163 | padding: .5rem; 164 | background-color: rgba(0,0,0,.4); 165 | border-radius: 1rem; 166 | } 167 | `; 168 | 169 | export const Feature = styled.div` 170 | display: flex; 171 | flex-direction: column; 172 | background: url(${({ src }) => src}); 173 | background-size: contain; 174 | object-fit:cover 175 | position: relative; 176 | height: 360px; 177 | background-position-x: right; 178 | background-repeat: no-repeat; 179 | background-color: black; 180 | 181 | @media (max-width: 1000px) { 182 | height: auto; 183 | // background-size: auto; 184 | object-fit: cover; 185 | background-position-x: center; 186 | 187 | ${Title} { 188 | font-size: 20px; 189 | line-height: 20px; 190 | margin-bottom: 10px; 191 | } 192 | ${FeatureText} { 193 | font-size: 13px; 194 | } 195 | } 196 | `; 197 | 198 | export const FeatureTitle = styled(Title)` 199 | margin-left: 0; 200 | `; 201 | 202 | export const FeatureClose = styled.button` 203 | color: white; 204 | position: absolute; 205 | right: 0px; 206 | top: -3px; 207 | cursor: pointer; 208 | background-color: transparent; 209 | border: 0; 210 | 211 | img { 212 | filter: brightness(0) invert(1); 213 | width: 24px; 214 | } 215 | `; 216 | 217 | export const Content = styled.div` 218 | margin: 56px; 219 | max-width: 500px; 220 | height: fit-content; 221 | line-height: normal; 222 | 223 | @media (max-width: 1000px) { 224 | margin: 30px; 225 | max-width: none; 226 | } 227 | `; 228 | 229 | export const Maturity = styled.div` 230 | background-color: ${({ rating }) => (rating >= 15 ? '#f44336' : '#2f9600')}; 231 | border-radius: 15px; 232 | width: 28px; 233 | line-height: 28px; 234 | text-align: center; 235 | color: white; 236 | font-weight: bold; 237 | text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); 238 | margin-right: 10px; 239 | font-size: 12px; 240 | `; -------------------------------------------------------------------------------- /src/components/feature/feature.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Inner, Title, SubTitle } from "./styles/feature"; 3 | 4 | const Feature = ({ children, ...restProps }) => { 5 | return {children} 6 | } 7 | 8 | export const FeatureTitle = ({ children, ...restProps }) => { 9 | return {children} 10 | } 11 | 12 | export const FeatureSubTitle = ({ children, ...restProps }) => { 13 | return {children} 14 | } 15 | 16 | Feature.Title = FeatureTitle; 17 | Feature.SubTitle = FeatureSubTitle; 18 | 19 | 20 | export default Feature; -------------------------------------------------------------------------------- /src/components/feature/styles/feature.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro' 2 | 3 | export const Inner = styled.div` 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | justify-content: center; 8 | text-align: center; 9 | margin: 0 auto; 10 | height: 100%; 11 | 12 | @media (max-width: 600px) { 13 | padding: 0 20px; 14 | } 15 | ` 16 | 17 | export const Title = styled.h1` 18 | color: white; 19 | max-width: 640px; 20 | font-size: 50px; 21 | font-weight: 700; 22 | margin: 0 auto; 23 | 24 | @media (max-width: 600px) { 25 | font-size: 28px; 26 | } 27 | ` 28 | 29 | export const SubTitle = styled.h2` 30 | color: white; 31 | font-size: 26px; 32 | font-weight: normal; 33 | margin: 16px auto; 34 | 35 | @media (max-width: 600px) { 36 | font-size: 18px; 37 | } 38 | ` 39 | -------------------------------------------------------------------------------- /src/components/footer/footer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Container, Row, Column, Link, Break, Title, Text } from './styles/footer' 3 | 4 | const Footer = ({children, ...restProps}) => { 5 | return ( 6 | 7 | {children} 8 | 9 | ) 10 | } 11 | 12 | const FooterRow = ({ children, ...restProps}) => { 13 | return {children} 14 | } 15 | Footer.Row = FooterRow 16 | 17 | const FooterColumn = ({ children, ...restProps}) => { 18 | return {children} 19 | } 20 | Footer.Column = FooterColumn 21 | 22 | const FooterLink = ({ children, ...restProps}) => { 23 | return {children} 24 | } 25 | Footer.Link = FooterLink 26 | 27 | const FooterBreak = ({ children, ...restProps}) => { 28 | return {children} 29 | } 30 | Footer.Break = FooterBreak 31 | 32 | const FooterTitle = ({ children, ...restProps}) => { 33 | return {children} 34 | } 35 | Footer.Title = FooterTitle 36 | 37 | const FooterText = ({ children, ...restProps}) => { 38 | return {children} 39 | } 40 | Footer.Text = FooterText 41 | 42 | 43 | export default Footer -------------------------------------------------------------------------------- /src/components/footer/styles/footer.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro' 2 | 3 | export const Container = styled.div` 4 | display: flex; 5 | padding: 70px 56px; 6 | margin: auto; 7 | max-width: 1000px; 8 | flex-direction: column; 9 | 10 | @media (max-width: 100px) { 11 | padding: 70px 30px; 12 | } 13 | ` 14 | 15 | export const Row = styled.div` 16 | display: grid; 17 | grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); 18 | grid-gap: 1rem; 19 | 20 | @media (max-width: 1000px) { 21 | grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); 22 | 23 | } 24 | ` 25 | 26 | export const Column = styled.div` 27 | display: flex; 28 | flex-direction: column; 29 | text-align: left; 30 | ` 31 | 32 | export const Link = styled.a` 33 | color: #757575; 34 | margin-bottom: 20px; 35 | font-size: .9rem; 36 | text-decoration: none; 37 | ` 38 | 39 | export const Break = styled.div` 40 | flex-basis: 100%; 41 | height: 0; 42 | ` 43 | 44 | export const Title = styled.p` 45 | font-size: 1rem; 46 | color: #757575; 47 | margin-bottom: 40px; 48 | ` 49 | 50 | export const Text = styled.p` 51 | font-size: .9rem; 52 | color: #DC1A28; 53 | margin-bottom: 40px; 54 | font-weight: 600; 55 | ` 56 | 57 | -------------------------------------------------------------------------------- /src/components/form/form.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Container, Error, Base, Title, Text, SmallText, Link, Input, Submit, } from './styles/form' 3 | 4 | const Form = ({children, ...restProps}) => { 5 | return ( 6 | 7 | {children} 8 | 9 | ) 10 | } 11 | 12 | const FormError = ({ children, ...restProps }) => { 13 | return {children} 14 | } 15 | const FormBase = ({ children, ...restProps }) => { 16 | return {children} 17 | } 18 | const FormTitle = ({ children, ...restProps }) => { 19 | return {children} 20 | } 21 | const FormText = ({ children, ...restProps }) => { 22 | return {children} 23 | } 24 | const FormSmallText = ({ children, ...restProps }) => { 25 | return {children} 26 | } 27 | const FormLink = ({ children, ...restProps }) => { 28 | return {children} 29 | } 30 | const FormInput = ({ children, ...restProps }) => { 31 | return {children} 32 | } 33 | const FormSubmit = ({ children, ...restProps }) => { 34 | return {children} 35 | } 36 | 37 | 38 | Form.Error = FormError 39 | Form.Base = FormBase 40 | Form.Title = FormTitle 41 | Form.Text = FormText 42 | Form.SmallText = FormSmallText 43 | Form.Link = FormLink 44 | Form.Input = FormInput 45 | Form.Submit = FormSubmit 46 | 47 | 48 | export default Form -------------------------------------------------------------------------------- /src/components/form/styles/form.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro' 2 | import { Link as ReactRouterLink } from 'react-router-dom' 3 | 4 | export const Container = styled.div` 5 | display: flex; 6 | flex-direction: column; 7 | height: 100%; 8 | max-height: 660px; 9 | background-color: rgba(0, 0, 0, 0.75); 10 | border-radius: 5px; 11 | width: 100%; 12 | margin: auto; 13 | max-width: 300px; 14 | padding: 60px 68px 40px; 15 | margin-bottom: 100px; 16 | 17 | @media (max-width: 600px) { 18 | padding: 30px 30px 20px; 19 | } 20 | ` 21 | export const Base = styled.form` 22 | display: flex; 23 | flex-direction: column; 24 | max-width: 450px; 25 | width: 100%; 26 | ` 27 | export const Error = styled.div` 28 | background: #e87c03; 29 | border-radius: 4px; 30 | font-size: 14px; 31 | margin: 0 0 16px; 32 | color: white; 33 | padding: 15px 20px; 34 | ` 35 | export const Title = styled.h1` 36 | color: #fff; 37 | font-size: 32px; 38 | font-weight: bold; 39 | margin-bottom: 28px; 40 | ` 41 | export const Text = styled.p` 42 | color: #737373; 43 | font-size: 16px; 44 | font-weight: 500; 45 | ` 46 | export const SmallText = styled.div` 47 | margin-top: 10px; 48 | font-size: 13px; 49 | line-height: normal; 50 | color: #8c8c8c; 51 | ` 52 | export const Link = styled(ReactRouterLink)` 53 | color: #fff; 54 | text-decoration: none; 55 | &:hover { 56 | text-decoration: underline; 57 | } 58 | ` 59 | export const Input = styled.input` 60 | background: #333; 61 | border-radius: 4px; 62 | border: 0; 63 | color: #fff; 64 | height: 50px; 65 | line-height: 50px; 66 | padding: 5px 20px; 67 | margin-bottom: 20px; 68 | &:last-of-type { 69 | margin-bottom: 30px; 70 | } 71 | ` 72 | export const Submit = styled.button` 73 | background: #e50914; 74 | border-radius: 4px; 75 | font-size: 16px; 76 | font-weight: bold; 77 | margin: 24px 0 12px; 78 | padding: 16px; 79 | border: 0; 80 | color: white; 81 | cursor: pointer; 82 | text-align: center; 83 | 84 | &:disabled { 85 | opacity: 0.5; 86 | } 87 | &:hover { 88 | background: #f40612; 89 | } 90 | ` 91 | -------------------------------------------------------------------------------- /src/components/header/header.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | import { Link as ReactRouterLink } from 'react-router-dom' 3 | import { 4 | Logo, 5 | ButtonLink, 6 | Background, 7 | Container, 8 | Feature, 9 | Text, 10 | FeatureCallOut, 11 | TextLink, 12 | Group, 13 | Profile, 14 | Picture, 15 | Dropdown, 16 | Search, 17 | SearchInput, 18 | SearchIcon, 19 | PlayButton, 20 | } from './styles/header' 21 | 22 | // bg prop for dynamic background 23 | const Header = ({ bg = true, children, ...restProps }) => { 24 | // if the header takes a background, set the background, take restProps and pass children else just pass children as object 25 | return bg ? {children} : children 26 | } 27 | 28 | const HeaderFeature = ({ children, ...restProps }) => { 29 | return {children} 30 | } 31 | 32 | const HeaderFeatureCallOut = ({ children, ...restProps }) => { 33 | return {children} 34 | } 35 | 36 | const HeaderText = ({ children, ...restProps }) => { 37 | return {children} 38 | } 39 | 40 | const HeaderTextLink = ({ children, ...restProps }) => { 41 | return {children} 42 | } 43 | 44 | const HeaderFrame = ({ children, ...restProps }) => { 45 | return {children} 46 | } 47 | 48 | const HeaderLogo = ({ to, ...restProps }) => { 49 | return ( 50 | 51 | 52 | 53 | ) 54 | } 55 | 56 | const HeaderButtonLink = ({ to, children, ...restProps }) => { 57 | return ( 58 | 59 | {children} 60 | 61 | ) 62 | } 63 | 64 | const HeaderGroup = ({ to, children, ...restProps }) => { 65 | return ( 66 | 67 | {children} 68 | 69 | ) 70 | } 71 | 72 | const HeaderProfile = ({ children, ...restProps }) => { 73 | return {children} 74 | } 75 | 76 | const HeaderPicture = ({ src, ...restProps }) => { 77 | return 78 | } 79 | 80 | const HeaderDropdown = ({ children, ...restProps }) => { 81 | return {children} 82 | } 83 | 84 | const HeaderSearch = ({ searchTerm, setSearchTerm, ...restProps }) => { 85 | const [searchActive, setSearchActive] = useState(false) 86 | 87 | return ( 88 | 89 | setSearchActive((searchActive) => !searchActive)} 91 | > 92 | search 93 | 94 | setSearchTerm(target.value)} 97 | placeholder='Search films and series' 98 | active={searchActive} 99 | /> 100 | 101 | ) 102 | } 103 | 104 | const HeaderPlayButton = ({ children, ...restProps }) => { 105 | {children} 106 | } 107 | 108 | Header.Feature = HeaderFeature 109 | Header.Text = HeaderText 110 | Header.TextLink = HeaderTextLink 111 | Header.FeatureCallOut = HeaderFeatureCallOut 112 | Header.Frame = HeaderFrame 113 | Header.Logo = HeaderLogo 114 | Header.ButtonLink = HeaderButtonLink 115 | Header.Group = HeaderGroup 116 | Header.Profile = HeaderProfile 117 | Header.Picture = HeaderPicture 118 | Header.Dropdown = HeaderDropdown 119 | Header.Search = HeaderSearch 120 | Header.PlayButton = HeaderPlayButton 121 | 122 | export default Header 123 | -------------------------------------------------------------------------------- /src/components/header/styles/header.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | import { Link as ReactRouterLink } from 'react-router-dom' 3 | 4 | 5 | 6 | export const Background = styled.div` 7 | display: flex; 8 | flex-direction: column; 9 | // If there is an image provided, it will be displayed else the default image will be displayed 10 | background: linear-gradient( 11 | to bottom, 12 | rgba(0, 0, 0, 0.85), 13 | rgba(0, 0, 0, 0.3), 14 | rgba(0, 0, 0, 0.85) 15 | ), 16 | url(${({ src }) => 17 | src 18 | ? `../images/misc/${src}.jpg` 19 | : '../images/misc/home-bg.jpg'}) 20 | top right / cover no-repeat; 21 | border-bottom: 8px solid #222; 22 | height: 97vh; 23 | // overflow: hidden; 24 | 25 | // // @media (max-width: 1100px) { 26 | // position: relative; 27 | // // } 28 | 29 | @media (max-width: 1000px) { 30 | height: 70vh; 31 | } 32 | ` 33 | 34 | export const Container = styled.div` 35 | display: flex; 36 | margin: 0 56px; 37 | height: 64px; 38 | padding: 18px 0; 39 | justify-content: space-between; 40 | align-items: center; 41 | 42 | a { 43 | display: flex; 44 | } 45 | 46 | @media (max-width: 1000px) { 47 | margin: 0 30px; 48 | } 49 | ` 50 | 51 | export const Logo = styled.img` 52 | height: 32px; 53 | width: 108px; 54 | 55 | @media (min-width: 1449px) { 56 | height: 45px; 57 | width: 167px; 58 | } 59 | ` 60 | 61 | export const ButtonLink = styled(ReactRouterLink)` 62 | display: block; 63 | background-color: #e50914; 64 | text-decoration: none; 65 | color: #fff; 66 | width: 84px; 67 | height: fit-content; 68 | border: 0; 69 | border-radius: 4px; 70 | font-size: 15px; 71 | padding: 8px 17px; 72 | cursor: pointer; 73 | box-sizing: border-box; 74 | 75 | &:hover { 76 | background-color: #f40612; 77 | } 78 | ` 79 | 80 | export const Feature = styled(Container)` 81 | flex-direction: column; 82 | align-items: normal; 83 | width: 50%; 84 | position: absolute; 85 | left: 5%; 86 | bottom: 30%; 87 | 88 | @media (max-width: 1100px) { 89 | // display: none; 90 | padding: 0; 91 | flex-direction: column; 92 | width: 90%; 93 | margin: 0 auto; 94 | bottom: 45%; 95 | } 96 | ` 97 | 98 | export const Text = styled.p` 99 | color: #fff; 100 | font-size: 22px; 101 | line-height: normal; 102 | text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); 103 | margin: 20px 0 0 0; 104 | 105 | @media (max-width: 1100px) { 106 | font-size: 16px; 107 | } 108 | ` 109 | export const FeatureCallOut = styled.h2` 110 | color: #fff; 111 | font-size: 50px; 112 | line-height: normal; 113 | text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); 114 | margin: 0; 115 | font-weight: bold; 116 | 117 | @media (max-width: 1100px) { 118 | font-size: 24px; 119 | } 120 | ` 121 | 122 | export const TextLink = styled.p` 123 | color: #fff; 124 | text-decoration: none; 125 | margin-left: 15px; 126 | // if it active, give a font weight of 700 127 | font-weight: ${({ active }) => (active === 'true' ? '700' : 'normal')}; 128 | cursor: pointer; 129 | 130 | &:hover { 131 | font-weight: bold; 132 | } 133 | ` 134 | 135 | export const Group = styled.div` 136 | display: flex; 137 | align-items: center; 138 | ` 139 | 140 | export const SearchInput = styled.input` 141 | background-color: rgba(64, 64, 64, 0.5); 142 | color: white; 143 | border: 1px solid white; 144 | transition: width 0.5s; 145 | height: 30px; 146 | font-size: 14px; 147 | border-radius: 4px; 148 | margin-left: ${({ active }) => (active === true ? '10px' : '0')}; 149 | padding: ${({ active }) => (active === true ? '0 10px' : '0')}; 150 | opacity: ${({ active }) => (active === true ? '1' : '0')}; 151 | width: ${({ active }) => (active === true ? '200px' : '0px')}; 152 | &:focus { 153 | background-color: rgba(0, 0, 0, 0.8); 154 | } 155 | ` 156 | 157 | export const Search = styled.div` 158 | display: flex; 159 | align-items: center; 160 | svg { 161 | color: white; 162 | cursor: pointer; 163 | } 164 | @media (max-width: 700px) { 165 | display: none; 166 | } 167 | ` 168 | 169 | export const SearchIcon = styled.button` 170 | cursor: pointer; 171 | background-color: transparent; 172 | border: 0; 173 | outline: 0; 174 | height: 32px; 175 | width: 32px; 176 | padding: 0; 177 | display: flex; 178 | align-items: center; 179 | justify-content: center; 180 | img { 181 | filter: brightness(0) invert(1); 182 | width: 16px; 183 | } 184 | ` 185 | 186 | export const Picture = styled.button` 187 | background: url(${({ src }) => src}); 188 | background-size: contain; 189 | border: 0; 190 | width: 32px; 191 | height: 32px; 192 | cursor: pointer; 193 | ` 194 | 195 | export const Dropdown = styled.div` 196 | display: none; 197 | position: absolute; 198 | background-color: black; 199 | padding: 10px; 200 | width: 100px; 201 | top: 32px; 202 | right: 10px; 203 | border-radius: 4px; 204 | ${Group}:last-of-type ${TextLink} { 205 | cursor: pointer; 206 | } 207 | ${Group} { 208 | margin-bottom: 10px; 209 | // border-bottom: 1px solid white; 210 | padding-bottom: 10px; 211 | &:last-of-type { 212 | margin-bottom: 0; 213 | } 214 | ${TextLink} { 215 | cursor: pointer; 216 | } 217 | ${Picture} { 218 | cursor: default; 219 | } 220 | } 221 | button { 222 | margin-right: 10px; 223 | } 224 | p { 225 | font-size: 12px; 226 | margin-bottom: 0; 227 | margin-top: 0; 228 | } 229 | ` 230 | 231 | export const Profile = styled.div` 232 | display: flex; 233 | align-items: center; 234 | margin-left: 20px; 235 | position: relative; 236 | button { 237 | cursor: pointer; 238 | } 239 | &:hover > ${Dropdown} { 240 | display: flex; 241 | flex-direction: column; 242 | } 243 | ` 244 | 245 | export const PlayButton = styled.button` 246 | box-shadow: 0 0.6vw 1vw -0.4vw rgba(0, 0, 0, 0.35); 247 | background-color: #e6e6e6; 248 | color: #000; 249 | border-width: 0; 250 | padding: 10px 20px; 251 | border-radius: 5px; 252 | max-width: 130px; 253 | font-weight: bold; 254 | font-size: 20px; 255 | margin-top: 10px; 256 | cursor: pointer; 257 | transition: background-color 0.5s ease; 258 | &:hover { 259 | background-color: #ff1e1e; 260 | color: white; 261 | } 262 | ` 263 | -------------------------------------------------------------------------------- /src/components/jumbotron/jumbotron.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | Inner, 4 | Item, 5 | Container, 6 | Pane, 7 | Title, 8 | SubTitle, 9 | Image, 10 | } from './styles/jumbotron' 11 | 12 | const Jumbotron = ({ children, direction = 'row', ...restProps }) => { 13 | return ( 14 | 15 | {children} 16 | 17 | ) 18 | } 19 | 20 | const JumbotronContainer = ({ children, ...restProps }) => { 21 | return {children} 22 | } 23 | 24 | const JumbotronPane = ({ children, ...restProps }) => { 25 | return {children} 26 | } 27 | const JumbotronTitle = ({ children, ...restProps }) => { 28 | return {children} 29 | } 30 | const JumbotronSubTitle = ({ children, ...restProps }) => { 31 | return {children} 32 | } 33 | const JumbotronImage = ({ ...restProps }) => { 34 | return 35 | } 36 | 37 | Jumbotron.Container = JumbotronContainer 38 | Jumbotron.Pane = JumbotronPane 39 | Jumbotron.Title = JumbotronTitle 40 | Jumbotron.SubTitle = JumbotronSubTitle 41 | Jumbotron.Image = JumbotronImage 42 | 43 | export default Jumbotron 44 | -------------------------------------------------------------------------------- /src/components/jumbotron/styles/jumbotron.js: -------------------------------------------------------------------------------- 1 | // Macro is going to give the name of the component in the dev tools 2 | import styled from 'styled-components/macro' 3 | 4 | export const Item = styled.div` 5 | display: flex; 6 | border-bottom: 8px solid #222; 7 | padding: 50 5%; 8 | color: #fff; 9 | overflow: hidden; 10 | ` 11 | 12 | export const Inner = styled.div` 13 | display: flex; 14 | // Take direction from the props 15 | flex-direction: ${({ direction }) => direction}; 16 | align-items: center; 17 | justify-content: space-between; 18 | max-width: 1100px; 19 | margin: auto; 20 | width: 100%; 21 | 22 | @media (max-width: 1000px) { 23 | flex-direction: column; 24 | } 25 | ` 26 | 27 | export const Pane = styled.div` 28 | width: 50%; 29 | 30 | @media (max-width: 1000px) { 31 | width: 100%; 32 | padding: 0 45px; 33 | text-align: center; 34 | } 35 | ` 36 | 37 | export const Title = styled.h1` 38 | font-size: 3.125rem; 39 | line-height: 1.2; 40 | margin-bottom: .5rem; 41 | 42 | @media (max-width: 600px){ 43 | font-size: 2.2rem; 44 | } 45 | ` 46 | 47 | export const SubTitle = styled.h2` 48 | font-size: 1.5rem; 49 | font-weight: normal; 50 | line-height: normal; 51 | 52 | @media (max-width: 600px) { 53 | font-size: 1.2rem; 54 | } 55 | ` 56 | 57 | export const Image = styled.img` 58 | max-width: 100%; 59 | height: auto; 60 | ` 61 | export const Container = styled.div` 62 | @media (max-width: 1000px) { 63 | ${Item}:last-of-type h2{ 64 | margin-bottom: 50px; 65 | } 66 | } 67 | ` -------------------------------------------------------------------------------- /src/components/loading/loading.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { LockBody, Spinner, Picture, ReleaseBody} from './styles/loading' 3 | 4 | const Loading = ({ src, ...restProps}) => { 5 | return ( 6 | // when use clicks on profile, a loading screen appears before the browse stuff will be shown 7 | 8 | 9 | 10 | 11 | ) 12 | } 13 | 14 | const LoadingReleaseBody = () => {return } 15 | 16 | 17 | Loading.ReleaseBody = LoadingReleaseBody 18 | 19 | export default Loading 20 | -------------------------------------------------------------------------------- /src/components/loading/styles/loading.js: -------------------------------------------------------------------------------- 1 | import styled, { createGlobalStyle } from "styled-components/macro"; 2 | 3 | export const LockBody = createGlobalStyle` 4 | body { 5 | overflow: hidden; 6 | } 7 | ` 8 | export const ReleaseBody = createGlobalStyle` 9 | body { 10 | overflow: visible; 11 | } 12 | ` 13 | 14 | export const Spinner = styled.div` 15 | position: fixed; 16 | width: 100%; 17 | height: 100%; 18 | background-color: black; 19 | z-index: 999; 20 | :after { 21 | content: ''; 22 | position: absolute; 23 | top: 50%; 24 | left: 50%; 25 | background-image: url(/images/misc/spinner.png); 26 | background-size: contain; 27 | background-repeat: no-repeat; 28 | margin-top: -150px; 29 | margin-left: -75px; 30 | width: 150px; 31 | height: 150px; 32 | animation-name: spin; 33 | animation-duration: 1000ms; 34 | animation-iteration-count: infinite; 35 | animation-timing-function: linear; 36 | } 37 | @-ms-keyframes spin { 38 | from { 39 | -ms-transform: rotate(0deg); 40 | } 41 | to { 42 | -ms-transform: rotate(360deg); 43 | } 44 | } 45 | @-moz-keyframes spin { 46 | from { 47 | -moz-transform: rotate(0deg); 48 | } 49 | to { 50 | -moz-transform: rotate(360deg); 51 | } 52 | } 53 | @-webkit-keyframes spin { 54 | from { 55 | -webkit-transform: rotate(0deg); 56 | } 57 | to { 58 | -webkit-transform: rotate(360deg); 59 | } 60 | } 61 | @keyframes spin { 62 | from { 63 | transform: rotate(0deg); 64 | } 65 | to { 66 | transform: rotate(360deg); 67 | } 68 | } 69 | `; 70 | 71 | export const Picture = styled.img` 72 | width: 50px; 73 | height: 50px; 74 | position: absolute; 75 | top: 50%; 76 | left: 50%; 77 | margin-top: -100px; 78 | margin-left: -22px; 79 | `; 80 | 81 | -------------------------------------------------------------------------------- /src/components/optForm/optForm.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Container, Input, Break, Button, Text } from './styles/optForm' 3 | 4 | export const OptForm = ({ children, ...restProps }) => { 5 | return {children} 6 | } 7 | 8 | const OptFormInput = ({ children, ...restProps }) => { 9 | return 10 | } 11 | 12 | const OptFormBreak = ({ children, ...restProps }) => { 13 | return {children} 14 | } 15 | 16 | const OptFormButton = ({ children, ...restProps }) => { 17 | return ( 18 | 21 | ) 22 | } 23 | 24 | const OptFormText = ({ children, ...restProps }) => { 25 | return {children} 26 | } 27 | 28 | // OptForm.Container = OptFormContainer 29 | OptForm.Input = OptFormInput 30 | OptForm.Break = OptFormBreak 31 | OptForm.Button = OptFormButton 32 | OptForm.Text = OptFormText 33 | -------------------------------------------------------------------------------- /src/components/optForm/styles/optForm.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro' 2 | 3 | export const Container = styled.div` 4 | display: flex; 5 | justify-content: center; 6 | // height: 100%; 7 | // margin-top: 20px; 8 | flex-wrap: wrap; 9 | 10 | @media (max-width: 1000px) { 11 | // flex-direction: column; This breaks my code my i am not removing it because i want to figure out why 12 | align-items: center; 13 | } 14 | ` 15 | 16 | export const Input = styled.input` 17 | max-width: 450px; 18 | width: 100%; 19 | border: 0; 20 | padding: 10px; 21 | height: 70px; 22 | box-sizing: border-box; 23 | outline: none; 24 | 25 | @media (max-width: 600px) { 26 | max-width: 350px; 27 | height: 50px; 28 | } 29 | ` 30 | 31 | export const Break = styled.div` 32 | flex-basis: 100%; 33 | height: 0; 34 | ` 35 | 36 | export const Button = styled.button` 37 | display: flex; 38 | align-items: center; 39 | height: 70px; 40 | background: #e50914; 41 | color: white; 42 | text-transform: capitalize; 43 | padding: 0 32px; 44 | font-size: 26px; 45 | border: 0; 46 | cursor: pointer; 47 | img { 48 | margin-left: 10px; 49 | filter: brightness(0) invert(1); 50 | width: 24px; 51 | @media (max-width: 1000px) { 52 | width: 16px; 53 | } 54 | } 55 | &:hover { 56 | background: #f40612; 57 | } 58 | @media (max-width: 1000px) { 59 | height: 50px; 60 | font-size: 16px; 61 | margin-top: 20px; 62 | font-weight: bold; 63 | } 64 | ` 65 | 66 | export const Text = styled.h3` 67 | font-size: 19.2px; 68 | font-weight: normal; 69 | color: white; 70 | text-align: center; 71 | padding: 0 20px; 72 | 73 | @media (max-width: 600px) { 74 | font-size: 18px; 75 | line-height: 22px; 76 | } 77 | ` 78 | -------------------------------------------------------------------------------- /src/components/player/player.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext, createContext } from 'react' 2 | import ReactDOM from 'react-dom' 3 | import { Container, Button, Overlay, Inner, Close } from './styles/player' 4 | 5 | export const PlayerContext = createContext() 6 | 7 | const Player = ({ children, ...restProps }) => { 8 | const [showPlayer, setShowPlayer] = useState(false) 9 | return ( 10 | 11 | {children} 12 | 13 | ) 14 | } 15 | 16 | const PlayerVideo = ({ src, ...restProps }) => { 17 | const { showPlayer, setShowPlayer } = useContext(PlayerContext) 18 | 19 | return showPlayer 20 | ? ReactDOM.createPortal( 21 | setShowPlayer(false)}> 22 | 23 | 26 | 27 | 28 | , document.body 29 | ) 30 | : null 31 | } 32 | 33 | const PlayerButton = ({ ...restProps }) => { 34 | const { showPlayer, setShowPlayer } = useContext(PlayerContext) 35 | 36 | return ( 37 | 40 | ) 41 | } 42 | 43 | Player.Video = PlayerVideo 44 | Player.Button = PlayerButton 45 | 46 | export default Player 47 | -------------------------------------------------------------------------------- /src/components/player/styles/player.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | 3 | export const Container = styled.div``; 4 | 5 | export const Overlay = styled.div` 6 | display: flex; 7 | flex-direction: column; 8 | justify-content: center; 9 | position: fixed; 10 | top: 0; 11 | left: 0; 12 | width: 100%; 13 | height: 100%; 14 | background: rgba(0, 0, 0, 0.75); 15 | margin: 0 20px; 16 | `; 17 | 18 | export const Inner = styled.div` 19 | position: relative; 20 | width: 90%; 21 | max-width: 900px; 22 | margin: 0 auto; 23 | 24 | video { 25 | height: 100%; 26 | width: 100%; 27 | } 28 | `; 29 | 30 | export const Close = styled.button` 31 | position: absolute; 32 | right: 15px; 33 | top: 15px; 34 | width: 22px; 35 | height: 22px; 36 | opacity: 0.3; 37 | background-color: transparent; 38 | border: 0; 39 | cursor: pointer; 40 | 41 | @media (max-width: 700px){ 42 | opacity: .8; 43 | } 44 | 45 | &:hover { 46 | opacity: 1; 47 | } 48 | 49 | &:before, 50 | &:after { 51 | position: absolute; 52 | left: 10px; 53 | top: 0; 54 | content: ' '; 55 | height: 22px; 56 | width: 2px; 57 | background-color: #fff; 58 | } 59 | 60 | &:before { 61 | transform: rotate(45deg); 62 | } 63 | &:after { 64 | transform: rotate(-45deg); 65 | } 66 | `; 67 | 68 | export const Button = styled.button` 69 | background-color: #e50914; 70 | border-color: #ff0a16; 71 | width: 115px; 72 | height: 45px; 73 | text-transform: uppercase; 74 | font-weight: bold; 75 | color: white; 76 | font-size: 18px; 77 | height: 45px; 78 | cursor: pointer; 79 | display: flex; 80 | align-items: center; 81 | justify-content: center; 82 | padding-left: 0; 83 | margin: 20px 0 0 50px; 84 | 85 | &:hover { 86 | transform: scale(1.05); 87 | background-color: #ff0a16; 88 | } 89 | `; -------------------------------------------------------------------------------- /src/components/profiles/profiles.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Container, Title, List, User, Picture, Name } from "./styles/profiles"; 3 | 4 | const Profiles = ({children, ...restProps}) => { 5 | return ( 6 | {children} 7 | ) 8 | } 9 | 10 | const ProfilesTitle = ({ children, ...restProps }) => { 11 | return {children} 12 | } 13 | const ProfilesList = ({ children, ...restProps }) => { 14 | return {children} 15 | } 16 | const ProfilesUser = ({ children, ...restProps }) => { 17 | return {children} 18 | } 19 | 20 | const ProfilesPicture = ({ src, ...restProps }) => { 21 | return 22 | } 23 | const ProfilesName = ({ children, ...restProps }) => { 24 | return {children} 25 | } 26 | 27 | 28 | Profiles.Title = ProfilesTitle 29 | Profiles.List = ProfilesList 30 | Profiles.User = ProfilesUser 31 | Profiles.Picture = ProfilesPicture 32 | Profiles.Name = ProfilesName 33 | 34 | 35 | export default Profiles; -------------------------------------------------------------------------------- /src/components/profiles/styles/profiles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro' 2 | 3 | export const Container = styled.div` 4 | display: flex; 5 | flex-direction: column; 6 | justify-content: center; 7 | align-items: center; 8 | margin: auto; 9 | max-width: 80%; 10 | ` 11 | export const Title = styled.h1` 12 | width: 100%; 13 | color: #fff; 14 | font-size: 48px; 15 | text-align: center; 16 | font-weight: 500; 17 | ` 18 | export const Name = styled.p` 19 | color: #808080; 20 | text-overflow: ellipsis; 21 | font-size: 16px; 22 | &:hover { 23 | font-weight: bold; 24 | color: #e5e5e5; 25 | } 26 | ` 27 | 28 | export const Picture = styled.img` 29 | width: 100%; 30 | max-width: 150px; 31 | height: auto; 32 | border: 3px solid black; 33 | cursor: pointer; 34 | ` 35 | 36 | export const List = styled.ul` 37 | padding: 0; 38 | margin: 0; 39 | display: flex; 40 | flex-direction: row; 41 | ` 42 | export const User = styled.li` 43 | max-height: 200px; 44 | max-width: 200px; 45 | list-style-type: none; 46 | text-align: center; 47 | margin-right: 30px; 48 | &:hover > ${Picture} { 49 | border: 3px solid white; 50 | } 51 | &:hover ${Name} { 52 | font-weight: bold; 53 | color: white; 54 | } 55 | &:last-of-type { 56 | margin-right: 0; 57 | } 58 | ` 59 | 60 | -------------------------------------------------------------------------------- /src/constants/routes.js: -------------------------------------------------------------------------------- 1 | // These are the routes for the application 2 | 3 | export const HOME = '/' 4 | export const BROWSE = '/browse' 5 | export const SIGN_UP = '/signup' 6 | export const SIGN_IN = '/signin' -------------------------------------------------------------------------------- /src/containers/accordionContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import accordionData from '../fixtures/faqs.json' 3 | import { Accordion } from '../components/accordion/accordion' 4 | import { OptForm } from '../components/optForm/optForm' 5 | 6 | export const AccordionContainer = () => { 7 | return ( 8 | 9 | Frequently Asked Questions 10 | 11 | {accordionData.map((item) => ( 12 | 13 | {item.header} 14 | {item.body} 15 | 16 | ))} 17 | 18 | 19 | 20 | 21 | Ready to watch? Enter your email to create or restart your 22 | membership. 23 | 24 | 25 | 26 | Get Started 27 | 28 | 29 | 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /src/containers/browseContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { SelectProfileContainer } from './profileContainer' 3 | import { FirebaseContext } from '../context/firebase' 4 | import { useContext, useState, useEffect } from 'react' 5 | import Loading from '../components/loading/loading' 6 | import Header from '../components/header/header' 7 | import Player from '../components/player/player' 8 | import * as ROUTES from '../constants/routes' 9 | import logo from '../logo.png' 10 | import { PlayButton } from '../components/header/styles/header' 11 | import Card from '../components/card/card' 12 | import { FooterContainer } from './footerContainer' 13 | 14 | export const BrowseContainer = ({ slides }) => { 15 | // creating a default collection to display - series/films 16 | const [category, setCategory] = useState('series') 17 | const [searchTerm, setSearchTerm] = useState('') 18 | const [profile, setProfile] = useState({}) 19 | const [loading, setLoading] = useState(true) 20 | const [slideRows, setSlideRows] = useState([]) 21 | 22 | // Firebase authentication stuff 23 | const { firebase } = useContext(FirebaseContext) 24 | const user = firebase.auth().currentUser || {} 25 | 26 | useEffect(() => { 27 | setTimeout(() => { 28 | setLoading(false) 29 | }, 3000) 30 | }, [profile.displayName]) 31 | 32 | // setting the active slide rows and filtering them based of active collection -series/films 33 | useEffect(() => { 34 | setSlideRows(slides[category]) 35 | }, [slides, category]) 36 | 37 | return profile.displayName ? ( 38 | <> 39 | {loading ? ( 40 | 41 | ) : ( 42 | 43 | )} 44 |
45 | 46 | 47 | 48 | setCategory('series')} 51 | > 52 | Series 53 | 54 | setCategory('films')} 57 | > 58 | Films 59 | 60 | 61 | 62 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | {user.displayName} 74 | 75 | 76 | 77 | { 79 | firebase.auth().signOut() 80 | }} 81 | > 82 | Sign Out 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | Watch Originals Now 92 | 93 | 94 | The Mikaelsons move to New Orleans and form an alliance 95 | with local witches in an effort to rule the city once 96 | again in this "Vampire Diaries" spinoff. 97 | 98 | Play 99 | 100 |
101 | 102 | {/* Extracting and maping over data */} 103 | 104 | {slideRows.map((slideItem) => ( 105 | 106 | {slideItem.title} 107 | 108 | {/* getting the movies based on whether we are in the series or movies section */} 109 | {slideItem.data.map((item) => ( 110 | 111 | 114 | 115 | 116 | {item.title} 117 | 118 | 119 | {item.description} 120 | 121 | 122 | 123 | ))} 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | ))} 133 | 134 | 135 | 136 | ) : ( 137 | 138 | ) 139 | } 140 | -------------------------------------------------------------------------------- /src/containers/footerContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Footer from '../components/footer/footer' 3 | 4 | export const FooterContainer = () => { 5 | return ( 6 |
7 | Questions? Contact Us 8 | 9 | 10 | 11 | FAQ 12 | Investor Relations 13 | Privacy 14 | Speed Test 15 | 16 | 17 | Help Center 18 | Jobs 19 | Cookie Preferences 20 | Legal Notices 21 | 22 | 23 | Account 24 | Ways To Watch 25 | Coorporate Information 26 | Only on Netflix 27 | 28 | 29 | Media Center 30 | Terms of Use 31 | Contact Us 32 | 33 | 34 | 35 | This application was built by Nutifafa Afi Attor 36 |
37 | ) 38 | } 39 | -------------------------------------------------------------------------------- /src/containers/headerContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Header from '../components/header/header' 3 | import * as ROUTES from '../constants/routes' 4 | import logo from '../logo.png' 5 | 6 | export const HeaderContainer = ({children}) => { 7 | return ( 8 |
9 | 10 | 11 | Sign In 12 | 13 | {children} 14 |
15 | ) 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/containers/jumbotronContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Jumbotron from '../components/jumbotron/jumbotron' 3 | import jumbotronData from '../fixtures/jumbo.json' 4 | 5 | export const JumboContainer = () => { 6 | return ( 7 | 8 | {/* Pass the data and direction from the json file to the component */} 9 | {jumbotronData.map((item) => ( 10 | 11 | 12 | {item.title} 13 | {item.subTitle} 14 | 15 | 16 | 17 | 18 | 19 | ))} 20 | 21 | ) 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/containers/profileContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import * as ROUTES from "../constants/routes"; 3 | import logo from "../logo.png"; 4 | import Header from "../components/header/header"; 5 | import Profiles from "../components/profiles/profiles"; 6 | 7 | export const SelectProfileContainer = ({user, setProfile}) => { 8 | return ( 9 | <> 10 |
11 | 12 | 13 | 14 |
15 | 16 | 17 | Who's watching? 18 | 19 | {/* When the user clicks on a profile, set the current profile to the one that was clicked on */} 20 | setProfile({displayName: user.displayName, photoURL: user.photoURL})}> 21 | {/* We are using the randomly assigned image from firebase */} 22 | 23 | {user.displayName} 24 | 25 | 26 | 27 | 28 | ) 29 | } -------------------------------------------------------------------------------- /src/context/firebase.js: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | 3 | export const FirebaseContext = createContext(null) -------------------------------------------------------------------------------- /src/fixtures/faqs.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "header": "What is Netflix?", 5 | "body": "Netflix is a streaming service that offers a wide variety of award-winning TV programmes, films, anime, documentaries and more – on thousands of internet-connected devices.\n\nYou can watch as much as you want, whenever you want, without a single advert – all for one low monthly price. There's always something new to discover, and new TV programmes and films are added every week!" 6 | }, 7 | { 8 | "id": 2, 9 | "header": "How much does Netflix cost?", 10 | "body": "Watch Netflix on your smartphone, tablet, smart TV, laptop or streaming device, all for one low fixed monthly fee. Plans start from £5.99 a month. No extra costs or contracts." 11 | }, 12 | { 13 | "id": 3, 14 | "header": "Where can I watch?", 15 | "body": "Watch anywhere, anytime, on an unlimited number of devices. Sign in with your Netflix account to watch instantly on the web at netflix.com from your personal computer or on any internet-connected device that offers the Netflix app, including smart TVs, smartphones, tablets, streaming media players and game consoles.\n\nYou can also download your favourite programmes with the iOS, Android, or Windows 10 app. Use downloads to watch while you're on the go and without an internet connection. Take Netflix with you anywhere." 16 | }, 17 | { 18 | "id": 4, 19 | "header": "How do I cancel?", 20 | "body": "Netflix is flexible. There are no annoying contracts and no commitments. You can easily cancel your account online in two clicks. There are no cancellation fees – start or stop your account at any time." 21 | }, 22 | { 23 | "id": 5, 24 | "header": "What can I watch on Netflix?", 25 | "body": "Netflix has an extensive library of feature films, documentaries, TV programmes, anime, award-winning Netflix originals, and more. Watch as much as you want, any time you want." 26 | } 27 | ] -------------------------------------------------------------------------------- /src/fixtures/jumbo.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "title": "Enjoy on your TV.", 5 | "subTitle": "Watch on smart TVs, PlayStation, Xbox, Chromecast, Apple TV, Blu-ray players and more.", 6 | "image": "/images/misc/home-tv.jpg", 7 | "alt": "Tiger King on Netflix", 8 | "direction": "row" 9 | }, 10 | { 11 | "id": 2, 12 | "title": "Download your programmes to watch on the go.", 13 | "subTitle": "Save your data and watch all your favourites offline.", 14 | "image": "/images/misc/home-mobile.jpg", 15 | "alt": "Watch on mobile", 16 | "direction": "row-reverse" 17 | }, 18 | { 19 | "id": 3, 20 | "title": "Watch everywhere.", 21 | "subTitle": "Stream unlimited films and TV programmes on your phone, tablet, laptop and TV without paying more.", 22 | "image": "/images/misc/home-imac.jpg", 23 | "alt": "Money Heist on Netflix", 24 | "direction": "row" 25 | }, 26 | { 27 | "id": 4, 28 | "title": "Create profiles for kids.", 29 | "subTitle": "Send kids on adventures with their favorite characters in a space made just for them—free with your membership.", 30 | "image": "/images/misc/home-kids.png", 31 | "alt": "Kids on Netflix", 32 | "direction": "row-reverse" 33 | } 34 | ] -------------------------------------------------------------------------------- /src/globalStyles.js: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from "styled-components"; 2 | 3 | export const GlobalStyles = createGlobalStyle` 4 | html, body { 5 | font-family: 'Hevletica Neue', Helvetica, Arial, sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | background-color: #000; 9 | color: #333; 10 | font-size: 16px; 11 | } 12 | ` -------------------------------------------------------------------------------- /src/helpers/routes.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Route, Redirect } from 'react-router-dom' 3 | 4 | // Check if user is logged in and redirect to browse page if they are. 5 | export const IsUserRedirect = ({ user, loggedInPath, children, ...rest }) => { 6 | return ( 7 | { 10 | if (!user) { 11 | // If user is not logged in, redirect to sign in page. 12 | return children 13 | } 14 | if (user) { 15 | // If user is logged in, redirect to browse page. 16 | return ( 17 | 22 | ) 23 | } 24 | return null 25 | }} 26 | /> 27 | ) 28 | } 29 | 30 | // Protect the browse page from unauthenticated users. 31 | export const ProtectedRoute = ({ user, children, ...rest}) => { 32 | return ( 33 | { 36 | if (user) { 37 | return children 38 | } 39 | if (!user) { 40 | return ( 41 | 47 | ) 48 | } 49 | return null 50 | }} 51 | /> 52 | ) 53 | } -------------------------------------------------------------------------------- /src/hooks/index.js: -------------------------------------------------------------------------------- 1 | // export { default as useAuthListener } from './useAuthListener' -------------------------------------------------------------------------------- /src/hooks/useAuthListener.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect, useContext } from 'react' 2 | import { FirebaseContext } from '../context/firebase' 3 | 4 | const useAuthListener = () => { 5 | // We want to listen to the auth state of the user and how it changes 6 | const [user, setUser] = useState( 7 | // checking if the user is in local storage 8 | JSON.parse(localStorage.getItem('authUser')) 9 | ) 10 | 11 | const {firebase} = useContext(FirebaseContext) 12 | 13 | useEffect(() => { 14 | const listener = firebase.auth().onAuthStateChanged((authUser) => { 15 | if (authUser) { 16 | // if there is an authenticated user, we want to store it in local storage 17 | localStorage.setItem('authUser', JSON.stringify(authUser)) 18 | setUser(authUser) 19 | } else { 20 | // if there is no authenticated user, we want to remove it from local storage 21 | localStorage.removeItem('authUser') 22 | setUser(null) 23 | } 24 | }) 25 | 26 | return () => listener() 27 | }, []) 28 | 29 | return { user } 30 | } 31 | 32 | export default useAuthListener 33 | -------------------------------------------------------------------------------- /src/hooks/useContent.js: -------------------------------------------------------------------------------- 1 | import { useState, useContext, useEffect } from 'react' 2 | import { FirebaseContext } from '../context/firebase' 3 | 4 | // target is the films or series 5 | const useContent = (target) => { 6 | const [content, setContent] = useState([]) 7 | const { firebase } = useContext(FirebaseContext) 8 | 9 | useEffect(() => { 10 | // use firebase and firestore to access collection 11 | firebase 12 | .firestore() 13 | .collection(target) 14 | //here we get the collection 15 | .get() 16 | .then((snapshot) => { 17 | const allContent = snapshot.docs.map((contentObj) => ({ 18 | ...contentObj.data(), 19 | // here we get the id of the content so we can use it as a key 20 | documentID: contentObj.id, 21 | })) 22 | 23 | setContent(allContent) 24 | }) 25 | .catch((error) => { 26 | console.log(error.message) 27 | }) 28 | }, []) 29 | 30 | return { [target]: content } 31 | } 32 | 33 | export default useContent 34 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './app' 4 | import { GlobalStyles } from './globalStyles' 5 | import 'normalize.css' 6 | import firebase from './lib/firebase.prod.js' 7 | import { FirebaseContext } from './context/firebase' 8 | 9 | const root = ReactDOM.createRoot(document.getElementById('root')) 10 | root.render( 11 | // Removing React.StrictMode from here because it is interrupting my routing 12 | // 13 | <> 14 | 15 | 16 | 17 | 18 | 19 | // 20 | ) 21 | -------------------------------------------------------------------------------- /src/lib/firebase.prod.js: -------------------------------------------------------------------------------- 1 | import * as Firebase from 'firebase/app'; 2 | import 'firebase/auth' 3 | import 'firebase/firestore' 4 | // import { seedDatabase } from '../seed' 5 | 6 | 7 | // Configure Firebase 8 | const config = { 9 | apiKey: 'AIzaSyCatg_LS7q5OFdXDjhYYdBSjzs6RVH2Cck', 10 | authDomain: 'netflix-clone-f2579.firebaseapp.com', 11 | projectId: 'netflix-clone-f2579', 12 | storageBucket: 'netflix-clone-f2579.appspot.com', 13 | messagingSenderId: '585476757133', 14 | appId: '1:585476757133:web:a43f12e7f03295946474c4', 15 | } 16 | 17 | // Initialize Firebase 18 | const firebase = Firebase.initializeApp(config) 19 | 20 | // Seed the database once to avoid duplicate data 21 | // seedDatabase(firebase) 22 | 23 | 24 | // Export the database for use by the rest of the app 25 | export default firebase 26 | -------------------------------------------------------------------------------- /src/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/netflix-clone/462b9b6a885dbb4afa3eda8be9caba34915ad790/src/logo.png -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pages/browse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { BrowseContainer } from '../containers/browseContainer' 3 | import useContent from '../hooks/useContent' 4 | import selectionFilter from '../utils/selectionFilter' 5 | 6 | const Browse = () => { 7 | // getting series and films 8 | const { series } = useContent('series') 9 | const { films } = useContent('films') 10 | 11 | // getting the slides 12 | const slides = selectionFilter({ series, films }) 13 | 14 | return ( 15 | 16 | ) 17 | } 18 | 19 | export default Browse -------------------------------------------------------------------------------- /src/pages/home.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { HeaderContainer } from '../containers/headerContainer' 3 | import Feature from '../components/feature/feature' 4 | import { OptForm } from '../components/optForm/optForm' 5 | import { JumboContainer } from '../containers/jumbotronContainer' 6 | import { AccordionContainer } from '../containers/accordionContainer' 7 | import { FooterContainer } from '../containers/footerContainer' 8 | 9 | const Home = () => { 10 | return ( 11 |
12 | 13 | 14 | 15 | 16 | Unlimited movies, TV shows, and more. 17 | 18 | 19 | Watch anywhere. Cancel anytime. 20 | 21 | 22 | 23 | Ready to watch? Enter your email to create or 24 | restart your membership. 25 | 26 | 27 | 28 | Get Started 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 | ) 38 | } 39 | 40 | export default Home 41 | -------------------------------------------------------------------------------- /src/pages/signin.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext } from 'react' 2 | import { useHistory } from 'react-router-dom' 3 | import { FirebaseContext } from '../context/firebase' 4 | import { FooterContainer } from '../containers/footerContainer' 5 | import { HeaderContainer } from '../containers/headerContainer' 6 | import Form from '../components/form/form' 7 | import * as ROUTES from '../constants/routes' 8 | 9 | const SignIn = () => { 10 | const history = useHistory() 11 | const { firebase} = useContext(FirebaseContext) 12 | const [email, setEmail] = useState('') 13 | const [password, setPassword] = useState('') 14 | const [error, setError] = useState('') 15 | 16 | // form validation 17 | const handleSignIn = (e) => { 18 | e.preventDefault() 19 | 20 | // implement Firebase with promise 21 | firebase.auth().signInWithEmailAndPassword(email, password).then(() => { 22 | // redirect to browse page when user is signed in 23 | history.push(ROUTES.BROWSE) 24 | }).catch((error) => { 25 | // If there is an error, set the email and password to empty strings and set the error to the error message 26 | setEmail('') 27 | setPassword('') 28 | setError(error.message) 29 | }) 30 | } 31 | 32 | // If password or email is empty, isInvalid will be true 33 | const isInvalid = password === '' || email === '' 34 | 35 | return ( 36 | <> 37 | 38 |
39 | Sign In 40 | {error && {error}} 41 | 42 | 43 | {/* When the value of input changes, set the email to the current value of the form */} 44 | setEmail(target.value)} 48 | /> 49 | {/* When the value of input changes, set the password to the current value of the form */} 50 | setPassword(target.value)} 56 | /> 57 | {/* Disable button if any of the inputs are not validated */} 58 | Sign In 59 | 60 | New To Nutiflix? {' '} 61 | Sign up now 62 | 63 | This page is protected by Google reCAPTCHA to ensure you're not a bot 64 |
65 |
66 | 67 | 68 | ) 69 | } 70 | 71 | export default SignIn 72 | -------------------------------------------------------------------------------- /src/pages/signup.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext } from 'react' 2 | import { useHistory } from 'react-router-dom' 3 | import { FirebaseContext } from '../context/firebase' 4 | import { FooterContainer } from '../containers/footerContainer' 5 | import { HeaderContainer } from '../containers/headerContainer' 6 | import Form from '../components/form/form' 7 | import * as ROUTES from '../constants/routes' 8 | 9 | const SignUp = () => { 10 | const history = useHistory() // when user clicks on sign up, redirect to browse page 11 | const { firebase } = useContext(FirebaseContext) 12 | 13 | const [firstName, setFirstName] = useState('') 14 | const [email, setEmail] = useState('') 15 | const [password, setPassword] = useState('') 16 | const [error, setError] = useState('') 17 | 18 | const isInvalid = firstName === '' || password === '' || email === '' 19 | 20 | const handleSignUp = (e) => { 21 | e.preventDefault() 22 | 23 | // implement Firebase with promise 24 | firebase.auth().createUserWithEmailAndPassword(email, password).then((result) => { 25 | result.user.updateProfile({ 26 | // set the user's display name to the first name 27 | displayName: firstName, 28 | // set the user's photoURL to a random user image 29 | photoURL: Math.floor(Math.random() * 5) + 1, 30 | }).then(() => { 31 | history.push(ROUTES.BROWSE) 32 | }) 33 | }).catch((error) => { 34 | // If there is an error, reset all the inputs and set the error to the error message 35 | setFirstName('') 36 | setEmail('') 37 | setPassword('') 38 | setError(error.message) 39 | }) 40 | } 41 | 42 | return ( 43 | <> 44 | 45 |
46 | Sign Up 47 | {error && {error}} 48 | 49 | {/* When the value of input changes, set the value to the current value of the form */} 50 | setFirstName(target.value)} 54 | /> 55 | setEmail(target.value)} 59 | /> 60 | setPassword(target.value)} 66 | /> 67 | {/* Disable button if any of the inputs are not validated */} 68 | Sign Up 69 | 70 | 71 | 72 | Already a user? Sign in now. 73 | 74 | 75 | This page is protected by Google reCAPTCHA to ensure you're not a bot. Learn more. 76 | 77 |
78 |
79 | 80 | 81 | ) 82 | } 83 | 84 | export default SignUp -------------------------------------------------------------------------------- /src/seed.js: -------------------------------------------------------------------------------- 1 | export function seedDatabase(firebase) { 2 | function getUUID() { 3 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { 4 | const piece = (Math.random() * 16) | 0; 5 | const elem = c === 'x' ? piece : (piece & 0x3) | 0x8; 6 | return elem.toString(16); 7 | }); 8 | 9 | } 10 | 11 | /* Series 12 | ============================================ */ 13 | // Documentaries 14 | firebase.firestore().collection('series').add({ 15 | id: getUUID(), 16 | title: 'Tiger King', 17 | description: 'An exploration of big cat breeding and its bizarre underworld, populated by eccentric characters.', 18 | genre: 'documentaries', 19 | maturity: '18', 20 | slug: 'tiger-king', 21 | }); 22 | firebase.firestore().collection('series').add({ 23 | id: getUUID(), 24 | title: 'Amanda Knox', 25 | description: 'Amanda Marie Knox is an American woman who spent almost four years in an Italian prison.', 26 | genre: 'documentaries', 27 | maturity: '12', 28 | slug: 'amanda-knox', 29 | }); 30 | firebase.firestore().collection('series').add({ 31 | id: getUUID(), 32 | title: 'Citizenfour', 33 | description: 34 | 'Citizenfour is a 2014 documentary film directed by Laura Poitras, concerning Edward Snowden and the NSA spying scandal.', 35 | genre: 'documentaries', 36 | maturity: '12', 37 | slug: 'citizenfour', 38 | }); 39 | firebase.firestore().collection('series').add({ 40 | id: getUUID(), 41 | title: 'Super Size Me', 42 | description: 43 | "Director Morgan Spurlock's social experiment in fast-food gastronomy sees him attempting to subsist uniquely on food from the McDonalds", 44 | genre: 'documentaries', 45 | maturity: '12', 46 | slug: 'super-size-me', 47 | }); 48 | firebase.firestore().collection('series').add({ 49 | id: getUUID(), 50 | title: 'Man on Wire', 51 | description: 52 | "Filmmaker James Marsh masterfully recreates high-wire daredevil Philippe Petit's 1974 stunt walking on a wire across the Twin Towers.", 53 | genre: 'documentaries', 54 | maturity: '12', 55 | slug: 'man-on-wire', 56 | }); 57 | 58 | // Comedies 59 | firebase.firestore().collection('series').add({ 60 | id: getUUID(), 61 | title: 'The Office', 62 | description: 63 | 'A motley group of office workers go through hilarious misadventures at the Scranton, Pennsylvania, branch of the Dunder Mifflin Paper Company.', 64 | genre: 'comedies', 65 | maturity: '15', 66 | slug: 'the-office', 67 | }); 68 | firebase.firestore().collection('series').add({ 69 | id: getUUID(), 70 | title: 'Arrested Development', 71 | description: 72 | 'The Bluth family, once a prominent name in the business, loses everything after the head patriarch gets convicted for fraud.', 73 | genre: 'comedies', 74 | maturity: '15', 75 | slug: 'arrested-development', 76 | }); 77 | firebase.firestore().collection('series').add({ 78 | id: getUUID(), 79 | title: 'Curb Your Enthusiasm', 80 | description: 81 | 'Larry David, a famous television writer and producer, gets into various misadventures with his friends and celebrity colleagues in Los Angeles.', 82 | genre: 'comedies', 83 | maturity: '15', 84 | slug: 'curb-your-enthusiasm', 85 | }); 86 | firebase.firestore().collection('series').add({ 87 | id: getUUID(), 88 | title: 'Family Guy', 89 | description: 90 | 'Peter Griffin and his family of two teenagers, a smart dog, a devilish baby and his wife find themselves in some of the most hilarious scenarios.', 91 | genre: 'comedies', 92 | maturity: '15', 93 | slug: 'family-guy', 94 | }); 95 | firebase.firestore().collection('series').add({ 96 | id: getUUID(), 97 | title: 'South Park', 98 | description: 99 | 'Four young, schoolgoing boys, Stan Marsh, Kyle Broflovski, Eric Cartman and Kenny McCormick, who live in South Park set out on various adventures.', 100 | genre: 'comedies', 101 | maturity: '15', 102 | slug: 'south-park', 103 | }); 104 | 105 | // Children 106 | firebase.firestore().collection('series').add({ 107 | id: getUUID(), 108 | title: 'Peppa Pig', 109 | description: 110 | 'Peppa, an outgoing preschool pig, participates in many energetic activities. She learns something new every day and has a lot of fun with her family and friends.', 111 | genre: 'children', 112 | maturity: '0', 113 | slug: 'peppa-pig', 114 | }); 115 | firebase.firestore().collection('series').add({ 116 | id: getUUID(), 117 | title: 'Dora The Explorer', 118 | description: 119 | 'Dora, a seven-year-old girl of Latin American descent, embarks upon numerous adventures in the wilderness with her friend Boots, a monkey, and a variety of fun and useful tools.', 120 | genre: 'children', 121 | maturity: '0', 122 | slug: 'dora-the-explorer', 123 | }); 124 | firebase.firestore().collection('series').add({ 125 | id: getUUID(), 126 | title: 'PAW Patrol', 127 | description: 128 | 'Six brave puppies, captained by a tech-savvy ten-year-old boy, Ryder, work together to accomplish high-stakes rescue missions to safeguard the residents of the Adventure Bay community.', 129 | genre: 'children', 130 | maturity: '0', 131 | slug: 'paw-patrol', 132 | }); 133 | firebase.firestore().collection('series').add({ 134 | id: getUUID(), 135 | title: 'Arthur', 136 | description: 137 | 'Bespectacled aardvark Arthur Read demonstrates to kids how to deal with such childhood traumas and challenges as homework, teachers and bullies.', 138 | genre: 'children', 139 | maturity: '0', 140 | slug: 'arthur', 141 | }); 142 | firebase.firestore().collection('series').add({ 143 | id: getUUID(), 144 | title: 'SpongeBob', 145 | description: 146 | 'A yellow sea sponge named SpongeBob SquarePants lives in the city of Bikini Bottom deep in the Pacific Ocean. ', 147 | genre: 'children', 148 | maturity: '0', 149 | slug: 'spongebob', 150 | }); 151 | 152 | // Crime 153 | firebase.firestore().collection('series').add({ 154 | id: getUUID(), 155 | title: 'Making a Murderer', 156 | description: 157 | 'Exonerated after spending nearly two decades in prison for a crime he did not commit, Steven Avery filed suit against Manitowoc County, Wis., and several individuals involved with his arrest.', 158 | genre: 'crime', 159 | maturity: '18', 160 | slug: 'making-a-murderer', 161 | }); 162 | firebase.firestore().collection('series').add({ 163 | id: getUUID(), 164 | title: 'Long Shot', 165 | description: 166 | 'An innocent man is accused of murder, leading his attorney on a wild chase to confirm his alibi using raw footage from a television show.', 167 | genre: 'crime', 168 | maturity: '18', 169 | slug: 'long-shot', 170 | }); 171 | firebase.firestore().collection('series').add({ 172 | id: getUUID(), 173 | title: 'The Confession Killer', 174 | description: 175 | 'Henry Lee Lucas was an American convicted serial killer whose crimes spanned from 1960 to 1983. He was convicted of murdering eleven people and condemned to death for the murder of Debra Jackson, although his sentence would be commuted to life in prison in 1998.', 176 | genre: 'crime', 177 | maturity: '18', 178 | slug: 'the-confession-killer', 179 | }); 180 | firebase.firestore().collection('series').add({ 181 | id: getUUID(), 182 | title: 'The Innocent Man', 183 | description: 184 | 'Henry Lee Lucas was an American convicted serial killer whose crimes spanned from 1960 to 1983. He was convicted of murdering eleven people and condemned to death for the murder of Debra Jackson.', 185 | genre: 'crime', 186 | maturity: '18', 187 | slug: 'the-innocent-man', 188 | }); 189 | firebase.firestore().collection('series').add({ 190 | id: getUUID(), 191 | title: 'The Staircase', 192 | description: 193 | "In 2001 novelist Michael Peterson's wife died, and he claimed she perished after falling down stairs at their home. The medical examiner, however, determined that she had been beaten with a weapon", 194 | genre: 'crime', 195 | maturity: '18', 196 | slug: 'the-staircase', 197 | }); 198 | 199 | // Feel-good 200 | firebase.firestore().collection('series').add({ 201 | id: getUUID(), 202 | title: 'Good Will Hunting', 203 | description: 204 | 'Will Hunting, a genius in mathematics, solves all the difficult mathematical problems. When he faces an emotional crisis, he takes help from psychiatrist Dr Sean Maguireto, who helps him recover.', 205 | genre: 'feel-good', 206 | maturity: '12', 207 | slug: 'good-will-hunting', 208 | }); 209 | firebase.firestore().collection('series').add({ 210 | id: getUUID(), 211 | title: 'Forrest Gump', 212 | description: 213 | 'Forrest Gump, a man with a low IQ, joins the army for service where he meets Dan and Bubba. However, he cannot stop thinking about his childhood sweetheart Jenny Curran, whose life is messed up.', 214 | genre: 'feel-good', 215 | maturity: '12', 216 | slug: 'forrest-gump', 217 | }); 218 | firebase.firestore().collection('series').add({ 219 | id: getUUID(), 220 | title: 'Juno', 221 | description: 222 | "Social misfit Juno protects herself with a caustic wit, but her unplanned pregnancy has the teen getting more involved in the lives of her baby's adoptive parents than she expected.", 223 | genre: 'feel-good', 224 | maturity: '12', 225 | slug: 'juno', 226 | }); 227 | firebase.firestore().collection('series').add({ 228 | id: getUUID(), 229 | title: 'Midnight In Paris', 230 | description: 231 | 'Gil arrives with his fiancee and her family in Paris for a vacation, even as he tries to finish his debut novel. He is beguiled by the city, which takes him to a time past, away from his fiancee.', 232 | genre: 'feel-good', 233 | maturity: '12', 234 | slug: 'midnight-in-paris', 235 | }); 236 | firebase.firestore().collection('series').add({ 237 | id: getUUID(), 238 | title: 'School of Rock', 239 | description: 240 | "Dewey Finn, an amateur rock enthusiast, slyly takes up his friend's substitute teacher's job. Bearing no qualifications for it, he instead starts training the students to form a band.", 241 | genre: 'feel-good', 242 | maturity: '12', 243 | slug: 'school-of-rock', 244 | }); 245 | 246 | /* Films 247 | ============================================ */ 248 | // Drama 249 | firebase.firestore().collection('films').add({ 250 | id: getUUID(), 251 | title: 'The Prestige', 252 | description: 253 | 'Two friends and fellow magicians become bitter enemies after a sudden tragedy. As they devote themselves to this rivalry, they make sacrifices that bring them fame but with terrible consequences.', 254 | genre: 'drama', 255 | maturity: '15', 256 | slug: 'the-prestige', 257 | }); 258 | firebase.firestore().collection('films').add({ 259 | id: getUUID(), 260 | title: 'Fight Club', 261 | description: 262 | 'Discontented with his capitalistic lifestyle, a white-collared insomniac forms an underground fight club with Tyler, a careless soap salesman. The project soon spirals down into something sinister.', 263 | genre: 'drama', 264 | maturity: '15', 265 | slug: 'fight-club', 266 | }); 267 | firebase.firestore().collection('films').add({ 268 | id: getUUID(), 269 | title: 'Kings Speech', 270 | description: 271 | 'King George VI tries to overcome his stammering problem with the help of speech therapist Lionel Logue and makes himself worthy enough to lead his country through World War II.', 272 | genre: 'drama', 273 | maturity: '15', 274 | slug: 'kings-speech', 275 | }); 276 | firebase.firestore().collection('films').add({ 277 | id: getUUID(), 278 | title: 'The Revenant', 279 | description: 280 | 'Hugh Glass, a legendary frontiersman, is severely injured in a bear attack and is abandoned by his hunting crew. He uses his skills to survive and take revenge on his companion, who betrayed him.', 281 | genre: 'drama', 282 | maturity: '15', 283 | slug: 'the-revenant', 284 | }); 285 | firebase.firestore().collection('films').add({ 286 | id: getUUID(), 287 | title: 'The Social Network', 288 | description: 289 | 'Mark Zuckerberg creates a social networking site, Facebook, with the help of his friend Eduardo Saverin. But soon, a string of lies tears their relationship apart even as Facebook connects people.', 290 | genre: 'drama', 291 | maturity: '12', 292 | slug: 'the-social-network', 293 | }); 294 | 295 | // Suspense 296 | firebase.firestore().collection('films').add({ 297 | id: getUUID(), 298 | title: 'Shutter Island', 299 | description: 300 | 'Teddy Daniels and Chuck Aule, two US marshals, are sent to an asylum on a remote island in order to investigate the disappearance of a patient, where Teddy uncovers a shocking truth about the place.', 301 | genre: 'suspense', 302 | maturity: '15', 303 | slug: 'shutter-island', 304 | }); 305 | firebase.firestore().collection('films').add({ 306 | id: getUUID(), 307 | title: 'Gone Girl', 308 | description: 309 | 'Nick Dunne discovers that the entire media focus has shifted on him when his wife Amy Dunne disappears on the day of their fifth wedding anniversary.', 310 | genre: 'suspense', 311 | maturity: '15', 312 | slug: 'gone-girl', 313 | }); 314 | firebase.firestore().collection('films').add({ 315 | id: getUUID(), 316 | title: 'Prisoners', 317 | description: 318 | "When the police take time to find Keller Dover's daughter and her friend, he decides to go on a search himself. His desperation leads him closer to finding the truth and also jeopardises his own life.", 319 | genre: 'suspense', 320 | maturity: '15', 321 | slug: 'prisoners', 322 | }); 323 | firebase.firestore().collection('films').add({ 324 | id: getUUID(), 325 | title: 'Seven', 326 | description: 327 | 'A serial killer begins murdering people according to the seven deadly sins. Two detectives, one new to the city and the other about to retire, are tasked with apprehending the criminal.', 328 | genre: 'suspense', 329 | maturity: '15', 330 | slug: 'seven', 331 | }); 332 | firebase.firestore().collection('films').add({ 333 | id: getUUID(), 334 | title: 'Zodiac', 335 | description: 336 | 'Robert Graysmith, a cartoonist by profession, finds himself obsessively thinking about the Zodiac killer. He uses his puzzle-solving abilities to get closer to revealing the identity of the killer.', 337 | genre: 'suspense', 338 | maturity: '15', 339 | slug: 'zodiac', 340 | }); 341 | 342 | // Children 343 | firebase.firestore().collection('films').add({ 344 | id: getUUID(), 345 | title: 'Hotel Transylvania', 346 | description: 347 | 'Dracula, who owns a high-end resort for monsters, attempts to keep his daughter from falling in love with Jonathan, a human.', 348 | genre: 'children', 349 | maturity: '0', 350 | slug: 'hotel-transylvania', 351 | }); 352 | firebase.firestore().collection('films').add({ 353 | id: getUUID(), 354 | title: 'Despicable Me', 355 | description: 356 | 'Gru, a criminal mastermind, adopts three orphans as pawns to carry out the biggest heist in history. His life takes an unexpected turn when the little girls see him as their potential father.', 357 | genre: 'children', 358 | maturity: '0', 359 | slug: 'despicable-me', 360 | }); 361 | firebase.firestore().collection('films').add({ 362 | id: getUUID(), 363 | title: 'Frozen', 364 | description: 365 | 'Anna sets out on a journey with an iceman, Kristoff, and his reindeer, Sven, in order to find her sister, Elsa, who has the power to convert any object or person into ice.', 366 | genre: 'children', 367 | maturity: '0', 368 | slug: 'frozen', 369 | }); 370 | firebase.firestore().collection('films').add({ 371 | id: getUUID(), 372 | title: 'Spirited Away', 373 | description: 374 | 'In this animated feature by noted Japanese director Hayao Miyazaki, 10-year-old Chihiro (Rumi Hiiragi) and her parents (Takashi Naitô, Yasuko Sawaguchi) stumble upon a seemingly abandoned amusement park.', 375 | genre: 'children', 376 | maturity: '0', 377 | slug: 'spirited-away', 378 | }); 379 | firebase.firestore().collection('films').add({ 380 | id: getUUID(), 381 | title: 'Up', 382 | description: 383 | "Carl, an old widower, goes off on an adventure in his flying house in search of Paradise Falls, his wife's dream destination.", 384 | genre: 'children', 385 | maturity: '0', 386 | slug: 'up', 387 | }); 388 | 389 | // Thriller 390 | firebase.firestore().collection('films').add({ 391 | id: getUUID(), 392 | title: 'Joker', 393 | description: 394 | 'Forever alone in a crowd, failed comedian Arthur Fleck seeks connection as he walks the streets of Gotham City.', 395 | genre: 'thriller', 396 | maturity: '15', 397 | slug: 'joker', 398 | }); 399 | firebase.firestore().collection('films').add({ 400 | id: getUUID(), 401 | title: 'A Quiet Place', 402 | description: 403 | 'The Abbott family must now face the terrors of the outside world as they fight for survival in silence. Forced to venture into the unknown, they realize that the creatures that hunt by sound are not the only threats that lurk beyond the sand path.', 404 | genre: 'thriller', 405 | maturity: '15', 406 | slug: 'a-quiet-place', 407 | }); 408 | firebase.firestore().collection('films').add({ 409 | id: getUUID(), 410 | title: 'Black Swan', 411 | description: 412 | 'Nina, a ballerina, gets the chance to play the White Swan, Princess Odette. But she finds herself slipping into madness when Thomas, the artistic director, decides that Lily might fit the role better.', 413 | genre: 'thriller', 414 | maturity: '15', 415 | slug: 'black-swan', 416 | }); 417 | firebase.firestore().collection('films').add({ 418 | id: getUUID(), 419 | title: 'Nightcrawler', 420 | description: 421 | 'Louis Bloom, a petty thief, realises that he can make money by capturing photographs of criminal activities and starts resorting to extreme tactics to get them.', 422 | genre: 'thriller', 423 | maturity: '15', 424 | slug: 'nightcrawler', 425 | }); 426 | firebase.firestore().collection('films').add({ 427 | id: getUUID(), 428 | title: 'The Silence of The Lambs', 429 | description: 430 | 'Clarice Starling, an FBI agent, seeks help from Hannibal Lecter, a psychopathic serial killer and former psychiatrist, in order to apprehend another serial killer who has been claiming female victims.', 431 | genre: 'thriller', 432 | maturity: '15', 433 | slug: 'the-silence-of-the-lambs', 434 | }); 435 | 436 | // Romance 437 | firebase.firestore().collection('films').add({ 438 | id: getUUID(), 439 | title: 'A Star Is Born', 440 | description: 441 | 'After falling in love with struggling artist Ally, Jackson, a musician, coaxes her to follow her dreams, while he battles with alcoholism and his personal demons.', 442 | genre: 'romance', 443 | maturity: '15', 444 | slug: 'a-star-is-born', 445 | }); 446 | firebase.firestore().collection('films').add({ 447 | id: getUUID(), 448 | title: 'Blue Valentine', 449 | description: 450 | 'Dean and Cynthia are married with a daughter and their marriage is about to fall apart. Both come from dysfunctional families and struggle to make sense of their relationship.', 451 | genre: 'romance', 452 | maturity: '15', 453 | slug: 'blue-valentine', 454 | }); 455 | firebase.firestore().collection('films').add({ 456 | id: getUUID(), 457 | title: 'La La Land', 458 | description: 459 | 'Sebastian (Ryan Gosling) and Mia (Emma Stone) are drawn together by their common desire to do what they love. But as success mounts they are faced with decisions that begin...', 460 | genre: 'romance', 461 | maturity: '15', 462 | slug: 'la-la-land', 463 | }); 464 | firebase.firestore().collection('films').add({ 465 | id: getUUID(), 466 | title: 'The Notebook', 467 | description: 468 | "Duke reads the story of Allie and Noah, two lovers who were separated by fate, to Ms Hamilton, an old woman who suffers from Alzheimer's, on a daily basis out of his notebook.", 469 | genre: 'romance', 470 | maturity: '15', 471 | slug: 'the-notebook', 472 | }); 473 | firebase.firestore().collection('films').add({ 474 | id: getUUID(), 475 | title: 'Titanic', 476 | description: 477 | 'Seventeen-year-old Rose hails from an aristocratic family and is set to be married. When she boards the Titanic, she meets Jack Dawson, an artist, and falls in love with him.', 478 | genre: 'romance', 479 | maturity: '15', 480 | slug: 'titanic', 481 | }); 482 | } -------------------------------------------------------------------------------- /src/utils/selectionFilter.js: -------------------------------------------------------------------------------- 1 | const selectionFilter = ({ series, films }) => { 2 | return { 3 | // Filter films and series by particular genre 4 | series: [ 5 | { 6 | title: 'Documentaries', 7 | data: series.filter((item) => item.genre === 'documentaries'), 8 | }, 9 | { 10 | title: 'Comedies', 11 | data: series.filter((item) => item.genre === 'comedies'), 12 | }, 13 | { 14 | title: 'Children', 15 | data: series.filter((item) => item.genre === 'children'), 16 | }, 17 | { 18 | title: 'Crime', 19 | data: series.filter((item) => item.genre === 'crime'), 20 | }, 21 | { 22 | title: 'Feel Good', 23 | data: series.filter((item) => item.genre === 'feel-good'), 24 | }, 25 | ], 26 | films: [ 27 | { 28 | title: 'Drama', 29 | data: films.filter((item) => item.genre === 'drama'), 30 | }, 31 | { 32 | title: 'Thriller', 33 | data: films.filter((item) => item.genre === 'thriller'), 34 | }, 35 | { 36 | title: 'Romance', 37 | data: films.filter((item) => item.genre === 'romance'), 38 | }, 39 | { 40 | title: 'Children', 41 | data: films.filter((item) => item.genre === 'children'), 42 | }, 43 | { 44 | title: 'Suspense', 45 | data: films.filter((item) => item.genre === 'suspense'), 46 | }, 47 | ], 48 | } 49 | } 50 | 51 | export default selectionFilter 52 | --------------------------------------------------------------------------------