├── public ├── robots.txt ├── favicon.ico ├── logo192.png ├── logo512.png ├── images │ ├── misc │ │ ├── tv.png │ │ ├── home-bg.jpg │ │ ├── home-tv.jpg │ │ ├── joker1.jpg │ │ ├── loading.gif │ │ ├── spinner.png │ │ ├── home-imac.jpg │ │ ├── home-tv1.jpg │ │ ├── home-tv2.png │ │ ├── video-tv.m4v │ │ └── home-mobile.jpg │ ├── users │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ └── 5.png │ ├── icons │ │ ├── add.png │ │ ├── close.png │ │ ├── search.png │ │ ├── close-slim.png │ │ └── chevron-right.png │ ├── films │ │ ├── children │ │ │ ├── up │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── frozen │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── despicable-me │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── spirited-away │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ └── hotel-transylvania │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ ├── romance │ │ │ ├── titanic │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── la-la-land │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── the-notebook │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── a-star-is-born │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ └── blue-valentine │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ ├── suspense │ │ │ ├── seven │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── zodiac │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── gone-girl │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── prisoners │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ └── shutter-island │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ ├── thriller │ │ │ ├── joker │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── black-swan │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── a-quiet-place │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ ├── nightcrawler │ │ │ │ ├── large.jpg │ │ │ │ └── small.jpg │ │ │ └── the-silence-of-the-lambs │ │ │ │ ├── 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 │ └── series │ │ ├── feel-good │ │ ├── juno │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── forrest-gump │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── school-of-rock │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── good-will-hunting │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ └── midnight-in-paris │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── children │ │ ├── arthur │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── paw-patrol │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── peppa-pig │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── spongebob │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ └── dora-the-explorer │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── crime │ │ ├── long-shot │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── the-staircase │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── making-a-murderer │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── the-innocent-man │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ └── the-confession-killer │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── comedies │ │ ├── family-guy │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── south-park │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── the-office │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ ├── arrested-development │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ └── curb-your-enthusiasm │ │ │ ├── large.jpg │ │ │ └── small.jpg │ │ └── documentaries │ │ ├── tiger-king │ │ ├── large.jpg │ │ └── small.jpg │ │ ├── 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 ├── videos │ └── bunny.mp4 ├── index.html ├── manifest.json └── 404.html ├── images ├── demo.png ├── demo1.png ├── demo2.png ├── demo3.png └── homescreen.jpg ├── src ├── context │ └── firebase.js ├── hooks │ ├── index.js │ ├── use-auth-listener.js │ └── use-content.js ├── constants │ └── routes.js ├── pages │ ├── index.js │ ├── browse.js │ ├── home.js │ ├── signin.js │ └── signup.js ├── axios.js ├── setupTests.js ├── App.test.js ├── global-styles.js ├── index.css ├── reportWebVitals.js ├── components │ ├── loading │ │ ├── index.js │ │ └── styles │ │ │ └── loading.js │ ├── feature │ │ ├── index.js │ │ └── styles │ │ │ └── feature.js │ ├── row.css │ ├── index.js │ ├── opt-form │ │ ├── index.js │ │ └── styles │ │ │ └── opt-form.js │ ├── profiles │ │ ├── index.js │ │ └── styles │ │ │ └── profiles.js │ ├── footer │ │ ├── index.js │ │ └── styles │ │ │ └── footer.js │ ├── jumbotron │ │ ├── index.js │ │ └── styles │ │ │ └── jumbotron.js │ ├── header │ │ ├── styles │ │ │ ├── header.css │ │ │ └── header.js │ │ └── index.js │ ├── form │ │ ├── index.js │ │ └── styles │ │ │ └── form.js │ ├── player │ │ ├── index.js │ │ └── styles │ │ │ └── player.js │ ├── accordion │ │ ├── index.js │ │ └── styles │ │ │ └── accordion.js │ ├── row.js │ └── card │ │ ├── index.js │ │ └── styles │ │ └── card.js ├── index.js ├── containers │ ├── header.js │ ├── jumbotron.js │ ├── faqs.js │ ├── profiles.js │ ├── footer.js │ └── browse.js ├── request.js ├── lib │ └── firebase.prod.js ├── App.css ├── fixtures │ ├── jumbo.json │ └── faqs.json ├── logo.svg ├── app.js ├── utils │ └── selection-filter.js ├── helpers │ └── routes.js └── seed.js ├── firebase.json ├── .gitignore ├── package.json └── README.md /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /images/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/images/demo.png -------------------------------------------------------------------------------- /images/demo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/images/demo1.png -------------------------------------------------------------------------------- /images/demo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/images/demo2.png -------------------------------------------------------------------------------- /images/demo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/images/demo3.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/logo512.png -------------------------------------------------------------------------------- /images/homescreen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/images/homescreen.jpg -------------------------------------------------------------------------------- /public/images/misc/tv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/misc/tv.png -------------------------------------------------------------------------------- /public/images/users/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/users/1.png -------------------------------------------------------------------------------- /public/images/users/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/users/2.png -------------------------------------------------------------------------------- /public/images/users/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/users/3.png -------------------------------------------------------------------------------- /public/images/users/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/users/4.png -------------------------------------------------------------------------------- /public/images/users/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/users/5.png -------------------------------------------------------------------------------- /public/videos/bunny.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/videos/bunny.mp4 -------------------------------------------------------------------------------- /src/context/firebase.js: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | export const FirebaseContext = createContext(null); -------------------------------------------------------------------------------- /public/images/icons/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/icons/add.png -------------------------------------------------------------------------------- /public/images/icons/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/icons/close.png -------------------------------------------------------------------------------- /public/images/icons/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/icons/search.png -------------------------------------------------------------------------------- /public/images/misc/home-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/misc/home-bg.jpg -------------------------------------------------------------------------------- /public/images/misc/home-tv.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/misc/home-tv.jpg -------------------------------------------------------------------------------- /public/images/misc/joker1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/misc/joker1.jpg -------------------------------------------------------------------------------- /public/images/misc/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/misc/loading.gif -------------------------------------------------------------------------------- /public/images/misc/spinner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/misc/spinner.png -------------------------------------------------------------------------------- /public/images/misc/home-imac.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/misc/home-imac.jpg -------------------------------------------------------------------------------- /public/images/misc/home-tv1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/misc/home-tv1.jpg -------------------------------------------------------------------------------- /public/images/misc/home-tv2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/misc/home-tv2.png -------------------------------------------------------------------------------- /public/images/misc/video-tv.m4v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/misc/video-tv.m4v -------------------------------------------------------------------------------- /public/images/icons/close-slim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/icons/close-slim.png -------------------------------------------------------------------------------- /public/images/misc/home-mobile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/misc/home-mobile.jpg -------------------------------------------------------------------------------- /src/hooks/index.js: -------------------------------------------------------------------------------- 1 | export { default as useAuthListener } from './use-auth-listener'; 2 | export { default as useContent } from './use-content'; -------------------------------------------------------------------------------- /public/images/icons/chevron-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/icons/chevron-right.png -------------------------------------------------------------------------------- /public/images/films/children/up/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/children/up/large.jpg -------------------------------------------------------------------------------- /public/images/films/children/up/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/children/up/small.jpg -------------------------------------------------------------------------------- /public/images/films/children/frozen/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/children/frozen/large.jpg -------------------------------------------------------------------------------- /public/images/films/children/frozen/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/children/frozen/small.jpg -------------------------------------------------------------------------------- /public/images/films/romance/titanic/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/romance/titanic/large.jpg -------------------------------------------------------------------------------- /public/images/films/romance/titanic/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/romance/titanic/small.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/seven/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/suspense/seven/large.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/seven/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/suspense/seven/small.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/zodiac/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/suspense/zodiac/large.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/zodiac/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/suspense/zodiac/small.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/joker/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/thriller/joker/large.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/joker/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/thriller/joker/small.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/juno/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/feel-good/juno/large.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/juno/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/feel-good/juno/small.jpg -------------------------------------------------------------------------------- /src/constants/routes.js: -------------------------------------------------------------------------------- 1 | export const HOME = '/'; 2 | export const BROWSE = '/browse'; 3 | export const SIGN_UP = '/signup'; 4 | export const SIGN_IN = '/signin'; -------------------------------------------------------------------------------- /public/images/films/drama/fight-club/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/drama/fight-club/large.jpg -------------------------------------------------------------------------------- /public/images/films/drama/fight-club/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/drama/fight-club/small.jpg -------------------------------------------------------------------------------- /public/images/series/children/arthur/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/children/arthur/large.jpg -------------------------------------------------------------------------------- /public/images/series/children/arthur/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/children/arthur/small.jpg -------------------------------------------------------------------------------- /public/images/series/crime/long-shot/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/crime/long-shot/large.jpg -------------------------------------------------------------------------------- /public/images/series/crime/long-shot/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/crime/long-shot/small.jpg -------------------------------------------------------------------------------- /public/images/films/drama/kings-speech/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/drama/kings-speech/large.jpg -------------------------------------------------------------------------------- /public/images/films/drama/kings-speech/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/drama/kings-speech/small.jpg -------------------------------------------------------------------------------- /public/images/films/drama/the-prestige/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/drama/the-prestige/large.jpg -------------------------------------------------------------------------------- /public/images/films/drama/the-prestige/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/drama/the-prestige/small.jpg -------------------------------------------------------------------------------- /public/images/films/drama/the-revenant/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/drama/the-revenant/large.jpg -------------------------------------------------------------------------------- /public/images/films/drama/the-revenant/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/drama/the-revenant/small.jpg -------------------------------------------------------------------------------- /public/images/films/romance/la-la-land/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/romance/la-la-land/large.jpg -------------------------------------------------------------------------------- /public/images/films/romance/la-la-land/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/romance/la-la-land/small.jpg -------------------------------------------------------------------------------- /public/images/films/romance/the-notebook/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/romance/the-notebook/large.jpg -------------------------------------------------------------------------------- /public/images/films/romance/the-notebook/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/romance/the-notebook/small.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/gone-girl/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/suspense/gone-girl/large.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/gone-girl/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/suspense/gone-girl/small.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/prisoners/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/suspense/prisoners/large.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/prisoners/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/suspense/prisoners/small.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/black-swan/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/thriller/black-swan/large.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/black-swan/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/thriller/black-swan/small.jpg -------------------------------------------------------------------------------- /public/images/series/children/paw-patrol/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/children/paw-patrol/large.jpg -------------------------------------------------------------------------------- /public/images/series/children/paw-patrol/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/children/paw-patrol/small.jpg -------------------------------------------------------------------------------- /public/images/series/children/peppa-pig/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/children/peppa-pig/large.jpg -------------------------------------------------------------------------------- /public/images/series/children/peppa-pig/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/children/peppa-pig/small.jpg -------------------------------------------------------------------------------- /public/images/series/children/spongebob/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/children/spongebob/large.jpg -------------------------------------------------------------------------------- /public/images/series/children/spongebob/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/children/spongebob/small.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/family-guy/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/comedies/family-guy/large.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/family-guy/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/comedies/family-guy/small.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/south-park/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/comedies/south-park/large.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/south-park/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/comedies/south-park/small.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/the-office/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/comedies/the-office/large.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/the-office/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/comedies/the-office/small.jpg -------------------------------------------------------------------------------- /public/images/series/crime/the-staircase/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/crime/the-staircase/large.jpg -------------------------------------------------------------------------------- /public/images/series/crime/the-staircase/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/crime/the-staircase/small.jpg -------------------------------------------------------------------------------- /public/images/films/children/despicable-me/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/children/despicable-me/large.jpg -------------------------------------------------------------------------------- /public/images/films/children/despicable-me/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/children/despicable-me/small.jpg -------------------------------------------------------------------------------- /public/images/films/children/spirited-away/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/children/spirited-away/large.jpg -------------------------------------------------------------------------------- /public/images/films/children/spirited-away/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/children/spirited-away/small.jpg -------------------------------------------------------------------------------- /public/images/films/romance/a-star-is-born/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/romance/a-star-is-born/large.jpg -------------------------------------------------------------------------------- /public/images/films/romance/a-star-is-born/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/romance/a-star-is-born/small.jpg -------------------------------------------------------------------------------- /public/images/films/romance/blue-valentine/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/romance/blue-valentine/large.jpg -------------------------------------------------------------------------------- /public/images/films/romance/blue-valentine/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/romance/blue-valentine/small.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/a-quiet-place/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/thriller/a-quiet-place/large.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/a-quiet-place/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/thriller/a-quiet-place/small.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/nightcrawler/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/thriller/nightcrawler/large.jpg -------------------------------------------------------------------------------- /public/images/films/thriller/nightcrawler/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/thriller/nightcrawler/small.jpg -------------------------------------------------------------------------------- /public/images/films/drama/the-social-network/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/drama/the-social-network/large.jpg -------------------------------------------------------------------------------- /public/images/films/drama/the-social-network/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/drama/the-social-network/small.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/shutter-island/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/suspense/shutter-island/large.jpg -------------------------------------------------------------------------------- /public/images/films/suspense/shutter-island/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/suspense/shutter-island/small.jpg -------------------------------------------------------------------------------- /public/images/series/crime/making-a-murderer/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/crime/making-a-murderer/large.jpg -------------------------------------------------------------------------------- /public/images/series/crime/making-a-murderer/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/crime/making-a-murderer/small.jpg -------------------------------------------------------------------------------- /public/images/series/crime/the-innocent-man/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/crime/the-innocent-man/large.jpg -------------------------------------------------------------------------------- /public/images/series/crime/the-innocent-man/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/crime/the-innocent-man/small.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/tiger-king/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/documentaries/tiger-king/large.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/tiger-king/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/documentaries/tiger-king/small.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/forrest-gump/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/feel-good/forrest-gump/large.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/forrest-gump/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/feel-good/forrest-gump/small.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/school-of-rock/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/feel-good/school-of-rock/large.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/school-of-rock/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/feel-good/school-of-rock/small.jpg -------------------------------------------------------------------------------- /public/images/films/children/hotel-transylvania/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/children/hotel-transylvania/large.jpg -------------------------------------------------------------------------------- /public/images/films/children/hotel-transylvania/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/children/hotel-transylvania/small.jpg -------------------------------------------------------------------------------- /public/images/series/children/dora-the-explorer/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/children/dora-the-explorer/large.jpg -------------------------------------------------------------------------------- /public/images/series/children/dora-the-explorer/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/children/dora-the-explorer/small.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/amanda-knox/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/documentaries/amanda-knox/large.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/amanda-knox/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/documentaries/amanda-knox/small.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/citizenfour/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/documentaries/citizenfour/large.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/citizenfour/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/documentaries/citizenfour/small.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/man-on-wire/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/documentaries/man-on-wire/large.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/man-on-wire/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/documentaries/man-on-wire/small.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/arrested-development/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/comedies/arrested-development/large.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/arrested-development/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/comedies/arrested-development/small.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/curb-your-enthusiasm/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/comedies/curb-your-enthusiasm/large.jpg -------------------------------------------------------------------------------- /public/images/series/comedies/curb-your-enthusiasm/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/comedies/curb-your-enthusiasm/small.jpg -------------------------------------------------------------------------------- /public/images/series/crime/the-confession-killer/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/crime/the-confession-killer/large.jpg -------------------------------------------------------------------------------- /public/images/series/crime/the-confession-killer/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/crime/the-confession-killer/small.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/super-size-me/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/documentaries/super-size-me/large.jpg -------------------------------------------------------------------------------- /public/images/series/documentaries/super-size-me/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/documentaries/super-size-me/small.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/good-will-hunting/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/feel-good/good-will-hunting/large.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/good-will-hunting/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/feel-good/good-will-hunting/small.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/midnight-in-paris/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/feel-good/midnight-in-paris/large.jpg -------------------------------------------------------------------------------- /public/images/series/feel-good/midnight-in-paris/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/public/images/series/feel-good/midnight-in-paris/small.jpg -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "public", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /public/images/films/thriller/the-silence-of-the-lambs/large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmulajkar/netflix-clone-using-react/HEAD/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/sidmulajkar/netflix-clone-using-react/HEAD/public/images/films/thriller/the-silence-of-the-lambs/small.jpg -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | export { default as Home } from './home'; 2 | export { default as Browse } from './browse'; 3 | export { default as Signin } from './signin'; 4 | export { default as Signup } from './signup'; 5 | -------------------------------------------------------------------------------- /src/axios.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | //base url to make reuests to the movie database 4 | const instance = axios.create({ 5 | baseURL: "https://api.themoviedb.org/3/", 6 | }); 7 | 8 | 9 | export default instance; -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /src/global-styles.js: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from 'styled-components'; 2 | 3 | export const GlobalStyles = createGlobalStyle` 4 | html, body { 5 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | background-color: black; 9 | color: #fff; 10 | font-size: 16px; 11 | } 12 | `; -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Netflix 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /src/components/loading/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Spinner, LockBody, ReleaseBody, Picture } from './styles/loading'; 3 | 4 | export default function Loading({ src, ...restProps }) { 5 | return ( 6 | 7 | 8 | 9 | 10 | ); 11 | } 12 | 13 | Loading.ReleaseBody = function LoadingReleaseBody() { 14 | return ; 15 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from 'react-dom'; 3 | import 'normalize.css'; 4 | import App from './app'; 5 | import { GlobalStyles } from './global-styles'; 6 | import { firebase } from './lib/firebase.prod'; 7 | import { FirebaseContext } from './context/firebase'; 8 | 9 | render( 10 | <> 11 | 12 | 13 | 14 | 15 | , 16 | document.getElementById('root') 17 | ); -------------------------------------------------------------------------------- /src/components/feature/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Container, Title, SubTitle } from './styles/feature'; 3 | 4 | export default function Feature({ children, ...restProps }) { 5 | return {children} 6 | } 7 | 8 | Feature.Title = function FeatureTitle({children, ...restProps }) { 9 | return {children} 10 | }; 11 | 12 | Feature.SubTitle = function FeatureSubTitle({children, ...restProps }) { 13 | return {children} 14 | }; -------------------------------------------------------------------------------- /src/containers/header.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Header } from '../components'; 3 | import * as ROUTES from '../constants/routes'; 4 | import logo from '../logo.svg'; 5 | 6 | export function HeaderContainer({ children }){ 7 | return( 8 |
9 | 10 | 11 | Sign In 12 | 13 | {children} 14 |
15 | ); 16 | } -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /src/pages/browse.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { BrowseContainer } from '../containers/browse'; 3 | import { useContent } from '../hooks'; 4 | import selectionFilter from '../utils/selection-filter'; 5 | 6 | export default function Browse() { 7 | //we need the series and films also we need slides 8 | 9 | 10 | const { films } = useContent('films'); 11 | const { series } = useContent('series'); 12 | //the api works need to work on browse page new timestamp at 4:57:54 13 | 14 | const slides = selectionFilter({ series, films }); 15 | //pass it to the browse container 16 | return ; 17 | 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/components/row.css: -------------------------------------------------------------------------------- 1 | .row { 2 | color: white; 3 | margin-left: 20px; 4 | } 5 | 6 | .row_posters { 7 | display: flex; 8 | overflow-y: hidden; 9 | overflow-x: scroll; 10 | padding: 20px; 11 | } 12 | 13 | .row_posters::-webkit-scrollbar { 14 | display: none; 15 | } 16 | 17 | .row_poster { 18 | width: 100%; 19 | object-fit: contain; 20 | max-height: 100px; 21 | transition: transform 450ms; 22 | margin-right: 10px; 23 | } 24 | 25 | .row_poster:hover { 26 | transform: scale(1.08); 27 | opacity: 1; 28 | } 29 | 30 | .row_posterLarge { 31 | max-height: 250px; 32 | } 33 | 34 | .row_posterLarge:hover { 35 | transform: scale(1.09); 36 | opacity: 1; 37 | } -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as Jumbotron } from '../components/jumbotron/index'; 2 | export { default as Footer } from '../components/footer/index'; 3 | export { default as Accordion } from '../components/accordion/index'; 4 | export { default as OptForm } from './opt-form'; 5 | export { default as Header } from '../components/header/index'; 6 | export { default as Feature } from './feature'; 7 | export { default as Form } from '../components/form/index'; 8 | export { default as Profiles } from './profiles'; 9 | export { default as Loading } from './loading'; 10 | export { default as Card } from '../components/card/index'; 11 | export { default as Player } from '../components/player/index'; 12 | export { default as Request } from '../request'; -------------------------------------------------------------------------------- /src/containers/jumbotron.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import jumboData from '../fixtures/jumbo.json'; 3 | import { Jumbotron } from '../components'; 4 | 5 | export function JumbotronContainer() { 6 | return ( 7 | 8 | {jumboData.map((item) => ( 9 | 10 | 11 | {item.title} 12 | {item.subTitle} 13 | 14 | 15 | 16 | 17 | 18 | ))} 19 | 20 | ); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/request.js: -------------------------------------------------------------------------------- 1 | const API_KEY = "a3862ca74514590e3971df18caf10d15"; 2 | 3 | const requests = { 4 | fetchTrending: `/trending/all/week?api_key=${API_KEY}&language=en-US`, 5 | fetchNetflixOriginals: `/discover/tv?api_key=${API_KEY}&with_networks=213`, 6 | fetchTopRated: `/movie/top_rated?api_key=${API_KEY}&language=en-US`, 7 | fetchActionMovies: `/discover/movie?api_key=${API_KEY}&with-genres=28`, 8 | fetchComedyMovies: `/discover/movie?api_key=${API_KEY}&with-genres=35`, 9 | fetchHorrorMovies: `/discover/movie?api_key=${API_KEY}&with-genres=27`, 10 | fetchRomanticMovies: `/discover/movie?api_key=${API_KEY}&with-genres=10749`, 11 | fetchDocumentaries: `/discover/movie?api_key=${API_KEY}&with-genres=99`, 12 | } 13 | 14 | export default requests; -------------------------------------------------------------------------------- /src/components/feature/styles/feature.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | 3 | export const Container = styled.div` 4 | display: flex; 5 | flex-direction: column; 6 | border-bottom: 8px solid #222; 7 | text-align: center; 8 | padding 165px 45px; 9 | 10 | `; 11 | 12 | export const Title = styled.h1` 13 | color: white; 14 | max-width: 640px; 15 | font-size: 50px; 16 | font-weight: 500; 17 | margin: auto; 18 | 19 | @media (max-width: 600px) { 20 | font-size: 35px; 21 | } 22 | `; 23 | 24 | export const SubTitle = styled.h2` 25 | color: white; 26 | font-size: 26px; 27 | font-weight: normal; 28 | margin: 16px auto; 29 | 30 | @media (max-width: 600px) { 31 | font-size: 18px; 32 | } 33 | `; 34 | -------------------------------------------------------------------------------- /src/lib/firebase.prod.js: -------------------------------------------------------------------------------- 1 | import Firebase from 'firebase/app'; 2 | import 'firebase/firestore'; 3 | import 'firebase/auth'; 4 | import { seedDatabase } from '../seed'; 5 | 6 | //we need to somehow seed the database 7 | 8 | //we need a config here, put your api details here 9 | const config = { 10 | apiKey: "AIzaSyD6rfFIRNC4j0YoRtZGi6vLlJ0M2baoffE", 11 | authDomain: "netflix-react-9480e.firebaseapp.com", 12 | projectId: "netflix-react-9480e", 13 | storageBucket: "netflix-react-9480e.appspot.com", 14 | messagingSenderId: "124358470674", 15 | appId: "1:124358470674:web:e265ab9bc66f7c4e9a3ccb" 16 | }; 17 | 18 | const firebase = Firebase.initializeApp(config); 19 | 20 | //dont uncomment this bcz it will dupliacte the database on firebase 21 | //seedDatabase(firebase); 22 | 23 | export { firebase }; -------------------------------------------------------------------------------- /src/hooks/use-auth-listener.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect, useContext } from 'react'; 2 | import { FirebaseContext } from '../context/firebase'; 3 | 4 | export default function useAuthListener() { 5 | 6 | 7 | const [user, setUser] = useState(JSON.parse(localStorage.getItem('authUser'))); 8 | const { firebase } = useContext(FirebaseContext); 9 | 10 | useEffect(() => { 11 | const listener = firebase.auth().onAuthStateChanged((authUser) => { 12 | if (authUser) { 13 | localStorage.setItem('authUser', JSON.stringify(authUser)); 14 | setUser(authUser); 15 | } else { 16 | localStorage.removeItem('authUser'); 17 | setUser(null); 18 | } 19 | }); 20 | 21 | return () => listener(); 22 | }, []); 23 | 24 | return { user }; 25 | } -------------------------------------------------------------------------------- /src/hooks/use-content.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState, useContext } from 'react'; 2 | import { FirebaseContext } from '../context/firebase'; 3 | 4 | export default function useContent(target) { 5 | const [content, setContent] = useState([]); 6 | const { firebase } = useContext(FirebaseContext); 7 | 8 | useEffect(() => { 9 | firebase 10 | .firestore().collection(target) 11 | .get().then((snapshot) => { 12 | const allContent = snapshot.docs.map((contentObj) => ({ 13 | ...contentObj.data(), 14 | docId: contentObj.id, 15 | })); 16 | 17 | setContent(allContent); 18 | }) 19 | .catch((error) => { 20 | console.log(error.message); 21 | }); 22 | }, []); 23 | 24 | return { [target]: content }; 25 | } -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | } 4 | 5 | .app { 6 | background-color: #111; 7 | } 8 | /* original app.css disabled */ 9 | 10 | /* .App { 11 | text-align: center; 12 | } 13 | 14 | .App-logo { 15 | height: 40vmin; 16 | pointer-events: none; 17 | } 18 | 19 | @media (prefers-reduced-motion: no-preference) { 20 | .App-logo { 21 | animation: App-logo-spin infinite 20s linear; 22 | } 23 | } 24 | 25 | .App-header { 26 | background-color: #282c34; 27 | min-height: 100vh; 28 | display: flex; 29 | flex-direction: column; 30 | align-items: center; 31 | justify-content: center; 32 | font-size: calc(10px + 2vmin); 33 | color: white; 34 | } 35 | 36 | .App-link { 37 | color: #61dafb; 38 | } 39 | 40 | @keyframes App-logo-spin { 41 | from { 42 | transform: rotate(0deg); 43 | } 44 | to { 45 | transform: rotate(360deg); 46 | } 47 | } */ 48 | -------------------------------------------------------------------------------- /src/components/opt-form/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Container, Input, Button, Text, Break } from './styles/opt-form'; 3 | 4 | export default function OptForm({ children, ...restProps }) { 5 | return {children}; 6 | } 7 | 8 | OptForm.Input = function OptFormInput({ ...restProps }) { 9 | return ; 10 | }; 11 | 12 | OptForm.Button = function OptFormButton({ children, ...restProps }) { 13 | return ( 14 | 17 | ); 18 | }; 19 | 20 | OptForm.Text = function OptFormText({ children, ...restProps }) { 21 | return {children}; 22 | }; 23 | 24 | OptForm.Break = function OptFormBreak({ ...restProps }) { 25 | return ; 26 | }; -------------------------------------------------------------------------------- /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-tv2.png", 7 | "alt": "Movie Carousel", 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 | ] -------------------------------------------------------------------------------- /src/containers/faqs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Accordion } from '../components'; 3 | import OptForm from '../components/opt-form'; 4 | import faqsData from '../fixtures/faqs.json'; 5 | 6 | export function FaqsContainer() { 7 | return ( 8 | 9 | Frequently Asked Questions 10 | {faqsData.map(item => 11 | 12 | {item.header} 13 | {item.body} 14 | 15 | )} 16 | 17 | 18 | 19 | Try it now 20 | 21 | 22 | Ready to watch? Enter your email to create or restart your membership 23 | 24 | 25 | 26 | 27 | ); 28 | } -------------------------------------------------------------------------------- /src/components/profiles/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Container, Title, List, Item, Picture, Name } from './styles/profiles'; 3 | 4 | export default function Profiles({ children, ...restProps }) { 5 | return {children}; 6 | } 7 | 8 | Profiles.Title = function ProfilesTitle({ children, ...restProps }) { 9 | return {children}; 10 | }; 11 | 12 | Profiles.List = function ProfilesList({ children, ...restProps }) { 13 | return {children}; 14 | }; 15 | 16 | Profiles.User = function ProfilesUser({ children, ...restProps }) { 17 | return {children}; 18 | }; 19 | 20 | Profiles.Picture = function ProfilesPicture({ src, ...restProps }) { 21 | return ( 22 | 24 | ); 25 | }; 26 | 27 | Profiles.Name = function ProfilesName({ children, ...restProps }) { 28 | return {children}; 29 | }; -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/containers/profiles.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Header, Profiles } from '../components'; 3 | import * as ROUTES from '../constants/routes'; 4 | import logo from '../logo.svg'; 5 | 6 | 7 | export function SelectProfileContainer({ user, setProfile }) { 8 | return ( 9 | <> 10 |
11 | 12 | 13 | 14 |
15 | 16 | 17 | Who is Watching ? 18 | 19 | setProfile({ displayName: user.displayName, photoURL: user.photoURL })} 21 | data-testid="user-profile" 22 | > 23 | 24 | {user.displayName} 25 | 26 | 27 | 28 | 29 | ); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/components/footer/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Container, Row, Column, Link, Title, Text, Break } from '../footer/styles/footer'; 3 | 4 | export default function Footer({ children, ...restProps }) { 5 | return {children}; 6 | } 7 | 8 | Footer.Row = function FooterRow({ children, ...restProps }) { 9 | return {children}; 10 | }; 11 | 12 | Footer.Column = function FooterColumn({ children, ...restProps }) { 13 | return {children}; 14 | }; 15 | 16 | Footer.Link = function FooterLink({ children, ...restProps }) { 17 | return {children}; 18 | }; 19 | 20 | Footer.Title = function FooterTitle({ children, ...restProps }) { 21 | return {children}; 22 | }; 23 | 24 | Footer.Text = function FooterText({ children, ...restProps }) { 25 | return {children}; 26 | }; 27 | 28 | Footer.Break = function FooterBreak({ children, ...restProps }) { 29 | return {children}; 30 | }; -------------------------------------------------------------------------------- /src/components/jumbotron/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Container, Inner, Item, Pane, Title, SubTitle, Image } from './styles/jumbotron'; 3 | 4 | export default function Jumbotron({ children, direction = 'row', ...restProps }) { 5 | return( 6 | 7 | {children} 8 | 9 | ) 10 | } 11 | 12 | Jumbotron.Container = function JumbotronContainer({ children, ...restProps }) { 13 | return{children}; 14 | } 15 | 16 | Jumbotron.Pane = function JumbotronPane({ children, ...restProps }) { 17 | return{children}; 18 | } 19 | 20 | Jumbotron.Title = function JumbotronTitle({ children, ...restProps }) { 21 | return{children}; 22 | } 23 | 24 | Jumbotron.SubTitle = function JumbotronSubTitle({ children, ...restProps }) { 25 | return{children}; 26 | } 27 | 28 | Jumbotron.Image = function JumbotronImage({ ...restProps }) { 29 | return; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { BrowserRouter as Router, Switch } from 'react-router-dom'; 3 | import { Home, Browse, Signin, Signup } from './pages'; 4 | import * as ROUTES from './constants/routes'; 5 | import { IsUserRedirect, ProtectedRoute } from './helpers/routes'; 6 | import { useAuthListener } from './hooks/index'; 7 | 8 | 9 | export default function App() { 10 | const {user} = useAuthListener(); 11 | console.log(user); 12 | 13 | return ( 14 | 15 | 16 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "netflix", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.6", 7 | "@testing-library/react": "^11.1.2", 8 | "@testing-library/user-event": "^12.2.2", 9 | "axios": "^0.21.1", 10 | "eslint": "^7.13.0", 11 | "firebase": "^8.0.2", 12 | "fuse.js": "^6.4.3", 13 | "movie-trailer": "^2.0.7", 14 | "normalize.css": "^8.0.1", 15 | "react": "^17.0.1", 16 | "react-dom": "^17.0.1", 17 | "react-router-dom": "^5.2.0", 18 | "react-scripts": "4.0.0", 19 | "react-youtube": "^7.13.1", 20 | "styled-components": "^5.2.1", 21 | "web-vitals": "^0.2.4" 22 | }, 23 | "scripts": { 24 | "start": "react-scripts start", 25 | "build": "react-scripts build", 26 | "test": "react-scripts test", 27 | "eject": "react-scripts eject" 28 | }, 29 | "eslintConfig": { 30 | "extends": [ 31 | "react-app", 32 | "react-app/jest" 33 | ] 34 | }, 35 | "browserslist": { 36 | "production": [ 37 | ">0.2%", 38 | "not dead", 39 | "not op_mini all" 40 | ], 41 | "development": [ 42 | "last 1 chrome version", 43 | "last 1 firefox version", 44 | "last 1 safari version" 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /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: 1000px) { 11 | padding: 70px 30px; 12 | } 13 | `; 14 | 15 | export const Column = styled.div` 16 | display: flex; 17 | flex-direction: column; 18 | text-align: left; 19 | `; 20 | 21 | export const Row = styled.div` 22 | display: grid; 23 | grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); 24 | grid-gap:15px; 25 | 26 | @media (max-width:1000px) { 27 | grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); 28 | } 29 | `; 30 | 31 | export const Link = styled.a` 32 | color: #b1b1b1; 33 | margin-bottom: 20px; 34 | font-size: 14px; 35 | text-decoration: none; 36 | `; 37 | 38 | export const Title = styled.p` 39 | color: #b1b1b1; 40 | margin-bottom: 40px; 41 | font-size: 15px; 42 | `; 43 | 44 | export const Text = styled.p` 45 | color: #b1b1b1; 46 | margin-bottom: 40px; 47 | font-size: 15px; 48 | `; 49 | 50 | export const Break = styled.p` 51 | flex-basis: 100%; 52 | hieght: 0; 53 | `; -------------------------------------------------------------------------------- /src/components/header/styles/header.css: -------------------------------------------------------------------------------- 1 | .banner { 2 | color: white; 3 | object-fit: contain; 4 | height: 448px; 5 | } 6 | 7 | .banner_contents { 8 | margin-left: 30px; 9 | padding-top: 140px; 10 | height: 190px; 11 | } 12 | 13 | .banner_title { 14 | font-size: 3rem; 15 | font-weight: 800; 16 | padding-bottom: 0.3rem; 17 | } 18 | 19 | .banner_description { 20 | width: 45rem; 21 | font-size: 0.8rem; 22 | line-height: 1.3; 23 | padding-top: 1rem; 24 | max-width: 360px; 25 | height: 80px; 26 | } 27 | 28 | .banner_button { 29 | cursor: pointer; 30 | color: white; 31 | outline: none; 32 | border: none; 33 | border-radius: 0.2vw; 34 | padding-left: 2rem; 35 | padding-right: 2rem; 36 | background-color: rgba(51, 51, 51, 0.5); 37 | padding-bottom: 0.5rem; 38 | padding-top: 0.5rem; 39 | margin-right: 1rem; 40 | font-weight: 700; 41 | } 42 | 43 | .banner_button:hover { 44 | color: #000; 45 | background-color: #e6e6e6; 46 | transition: all 0.2s; 47 | } 48 | 49 | .banner_fadeBottom { 50 | height: 7.4rem; 51 | background-image: linear-gradient( 52 | 180deg, transparent, 53 | rgba(37, 37, 37, 0.61), 54 | #111 55 | ); 56 | } 57 | 58 | .nav_black { 59 | background-color: #111; 60 | } 61 | -------------------------------------------------------------------------------- /src/components/form/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Container, Base, Error, Title, Text, TextSmall, Link, Input, Submit } from '../form/styles/form'; 3 | 4 | export default function Form({ children, ...restProps }) { 5 | return {children}; 6 | } 7 | 8 | Form.Base = function FormBase({ children, ...restProps}) { 9 | return {children}; 10 | }; 11 | 12 | Form.Error = function FormError({ children, ...restProps}) { 13 | return {children}; 14 | }; 15 | 16 | Form.Title = function FormTitle({ children, ...restProps}) { 17 | return {children}; 18 | }; 19 | 20 | Form.Text = function FormText({ children, ...restProps}) { 21 | return {children}; 22 | }; 23 | 24 | Form.TextSmall = function FormTextSmall({ children, ...restProps}) { 25 | return {children}; 26 | }; 27 | 28 | Form.Link = function FormLink({ children, ...restProps}) { 29 | return {children}; 30 | }; 31 | 32 | Form.Input = function FormInput({ children, ...restProps}) { 33 | return {children}; 34 | }; 35 | 36 | Form.Submit = function FormSubmit({ children, ...restProps}) { 37 | return {children}; 38 | }; -------------------------------------------------------------------------------- /src/pages/home.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { JumbotronContainer } from '../containers/jumbotron'; 3 | import { Feature, OptForm } from '../components'; 4 | import { FaqsContainer } from '../containers/faqs'; 5 | import { FooterContainer } from '../containers/footer'; 6 | import { HeaderContainer } from '../containers/header'; 7 | 8 | export default function Home(){ 9 | return ( 10 | <> 11 | 12 | 13 | 14 | Unlimited films, TV programs and more. 15 | 16 | 17 | Watch anywhere. Cancel at any time. 18 | 19 | 20 | 21 | 22 | 23 | Ready to watch? Enter your email to create or restart your membership 24 | 25 | 26 | Try it now 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | ); 39 | } -------------------------------------------------------------------------------- /src/components/jumbotron/styles/jumbotron.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | 3 | export const Inner = styled.div` 4 | display: flex; 5 | align-items: center; 6 | flex-direction: ${({ direction }) =>direction}; 7 | justify-content: space-between; 8 | max-width: 1100px; 9 | margin: auto; 10 | width: 100%; 11 | 12 | @media (max-width: 1000px) { 13 | flex-direction: column; 14 | } 15 | `; 16 | export const Item = styled.div` 17 | display: flex; 18 | border-bottom: 6px solid #222; 19 | padding: 50px 5%; 20 | color: wihte; 21 | overflow: hidden; 22 | `; 23 | 24 | export const Pane = styled.div` 25 | width: 50%; 26 | 27 | @media (max-width: 1000px){ 28 | width: 100%; 29 | padding: 0 45px; 30 | text-align: center; 31 | } 32 | `; 33 | 34 | export const Title = styled.h1` 35 | font-size: 50px: 36 | line-hieght: 1.1; 37 | margin-bottom: 8px; 38 | 39 | @media (max-width: 600px) { 40 | font size: 35px; 41 | } 42 | `; 43 | 44 | export const SubTitle = styled.h2` 45 | font-size: 26px; 46 | font-weight: normal; 47 | font-height: normal; 48 | `; 49 | 50 | export const Image = styled.img` 51 | max-width: 100%; 52 | height: auto; 53 | `; 54 | 55 | export const Container = styled.div` 56 | @media (max-width: 1000px) { 57 | ${Item}: last-of-type h2 { 58 | margin-bottom: 50px; 59 | } 60 | } 61 | `; -------------------------------------------------------------------------------- /src/components/player/index.js: -------------------------------------------------------------------------------- 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 | export default function Player({ children, ...restProps }) { 8 | const [showPlayer, setShowPlayer] = useState(false); 9 | 10 | return ( 11 | 12 | {children} 13 | 14 | ); 15 | } 16 | 17 | Player.Video = function PlayerVideo({ src, ...restProps}) { 18 | const{ showPlayer, setShowPlayer } = useContext(PlayerContext); 19 | 20 | return showPlayer ? ReactDOM.createPortal ( 21 | setShowPlayer(false)} {...restProps}> 22 | 23 | 26 | 27 | 28 | , 29 | document.body 30 | ) : null; 31 | }; 32 | 33 | Player.Button = function PlayerBUtton({...restProps}) { 34 | const { showPlayer, setShowPlayer } = useContext(PlayerContext); 35 | return ( 36 | 39 | ); 40 | }; 41 | -------------------------------------------------------------------------------- /src/utils/selection-filter.js: -------------------------------------------------------------------------------- 1 | export default function selectionFilter({ series, films }) { 2 | return { 3 | series: [ 4 | {title: 'Documentaries', 5 | data: series.filter((item) => item.genre === 'documentaries'), 6 | }, 7 | {title: 'Comedies', 8 | data: series.filter((item) => item.genre === 'comedies'), 9 | }, 10 | {title: 'Children', 11 | data: series.filter((item) => item.genre === 'children'), 12 | }, 13 | {title: 'Crime', 14 | data: series.filter((item) => item.genre === 'crime'), 15 | }, 16 | {title: 'Feel Good', 17 | data: series.filter((item) => item.genre === 'feel-good'), 18 | }, 19 | ], 20 | 21 | films: [ 22 | {title: 'Drama', 23 | data: films.filter((item) => item.genre === 'drama'), 24 | }, 25 | {title: 'Thriller', 26 | data: films.filter((item) => item.genre === 'thriller'), 27 | }, 28 | {title: 'Children', 29 | data: films.filter((item) => item.genre === 'choldren'), 30 | }, 31 | {title: 'Suspense', 32 | data: films.filter((item) => item.genre === 'suspense'), 33 | }, 34 | {title: 'Romance', 35 | data: films.filter((item) => item.genre === 'romance'), 36 | }, 37 | ], 38 | }; 39 | } -------------------------------------------------------------------------------- /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 | padding-top: 80px; 11 | 12 | `; 13 | 14 | export const Title = styled.h1` 15 | width: 100%; 16 | color: white; 17 | font-size: 48px; 18 | text-align: center; 19 | font-weight: 500; 20 | `; 21 | 22 | export const List = styled.ul` 23 | padding: 0; 24 | margin: 0; 25 | display: flex; 26 | flex-direction: row; 27 | `; 28 | 29 | export const Name = styled.p` 30 | color: #808080; 31 | text-overflow: ellipsis; 32 | font-size: 16px; 33 | 34 | &:hover { 35 | font-weight: bold; 36 | color: #e5e5e5; 37 | } 38 | `; 39 | 40 | export const Picture = styled.img` 41 | width: 100%; 42 | max-width: 150px; 43 | height: auto; 44 | border: 3px solid black; 45 | cursor: pointer; 46 | `; 47 | 48 | export const Item = styled.li` 49 | max-height: 200px; 50 | max-width: 200px; 51 | list-style-type: none; 52 | text-align: center; 53 | margin-right: 30px; 54 | 55 | &:hover > ${Picture} { 56 | border: 3px solid white; 57 | } 58 | 59 | &:hover ${Name} { 60 | font-weight: bold; 61 | color: white; 62 | } 63 | 64 | &:last-of-type { 65 | margin-right: 0; 66 | } 67 | `; 68 | -------------------------------------------------------------------------------- /src/helpers/routes.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Route, Redirect } from 'react-router-dom'; 3 | 4 | export function IsUserRedirect({ user, loggedInPath, children, ...rest}) { 5 | return ( 6 | { 9 | if (!user) { 10 | //console.log('user', user); 11 | return children; 12 | } 13 | 14 | if (user) { 15 | return ( 16 | 20 | ); 21 | } 22 | 23 | return null; 24 | }} 25 | /> 26 | ); 27 | } 28 | 29 | export function ProtectedRoute({ user, children, ...rest }) { 30 | return ( 31 | { 34 | if(user) { 35 | return children; 36 | } 37 | 38 | if(!user) { 39 | return ( 40 | 45 | ); 46 | } 47 | 48 | return null; 49 | }} 50 | /> 51 | ); 52 | } -------------------------------------------------------------------------------- /src/components/opt-form/styles/opt-form.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: 1100px) { 11 | flex-direction: column; 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 | `; 24 | 25 | export const Button = styled.button` 26 | display: flex; 27 | align-items: center; 28 | height: 70px; 29 | background: #e50914; 30 | color: white; 31 | text-transform: uppercase; 32 | padding: 0 32px; 33 | font-size: 26px; 34 | border: 0; 35 | cursor: pointer; 36 | 37 | &:hover { 38 | background: #f40612; 39 | } 40 | 41 | @media (max-width: 1000px) { 42 | height: 50px; 43 | font-size: 16px; 44 | margin-top: 20px; 45 | font-weight: bold; 46 | } 47 | 48 | img { 49 | margin-left: 10px; 50 | filter: brightness(0) invert(1); 51 | width: 24px; 52 | 53 | @media (max-width: 1000px) { 54 | width: 16px; 55 | } 56 | } 57 | `; 58 | 59 | export const Text = styled.p` 60 | font-size: 19.2px; 61 | color: white; 62 | text-align: center; 63 | 64 | @media (max-width: 600px) { 65 | font-size: 16px; 66 | line-height: 22px; 67 | } 68 | `; 69 | 70 | export const Break = styled.div` 71 | flex-basis: 100%; 72 | height: 0; 73 | `; -------------------------------------------------------------------------------- /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.5); 15 | margin: 0 20px; 16 | `; 17 | 18 | export const Inner = styled.div` 19 | position: relative; 20 | width: 100%; 21 | max-width: 900px; 22 | magin: auto; 23 | 24 | video { 25 | height: 100%; 26 | width: 100%; 27 | } 28 | 29 | &:before, 30 | &:after { 31 | position: absolute; 32 | left: 10px; 33 | top: 0; 34 | content: ' '; 35 | height: 22px; 36 | width: 22px; 37 | background-color: #333; 38 | } 39 | 40 | &:before { 41 | transform: rotate(45deg); 42 | } 43 | &:after { 44 | transorm: rotate(-45deg); 45 | } 46 | `; 47 | 48 | export const Close = styled.button` 49 | position: absolute; 50 | right: 15px; 51 | top: 15px; 52 | width: 22px; 53 | height: 22px; 54 | opacity: 0.3; 55 | background-color: transparent; 56 | border: 0; 57 | cursor: pointer; 58 | 59 | &:hover { 60 | opacity: 1; 61 | } 62 | `; 63 | 64 | export const Button = styled.button` 65 | background-color: #e50914; 66 | border-color: #ff0a10; 67 | width: 114px; 68 | height: 45px; 69 | text-transform: uppercase; 70 | font-weight: bold; 71 | color: white; 72 | font-size: 18px; 73 | cursor: pointer; 74 | display: flex; 75 | align-items: center; 76 | justify-content: center; 77 | padding-left: 0; 78 | 79 | &:hover { 80 | transform: scale(1.05); 81 | background-color: #ff0a16; 82 | } 83 | `; -------------------------------------------------------------------------------- /src/components/accordion/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext, createContext } from 'react'; 2 | import { Container, Frame, Title, Item, Inner, Header, Body } from '../accordion/styles/accordion'; 3 | 4 | const ToggleContext = createContext(); 5 | 6 | export default function Accordion({ children, ...restProps }) { 7 | return ( 8 | 9 | {children} 10 | 11 | ); 12 | } 13 | 14 | Accordion.Title = function AccordionTitle({ children, ...restProps }) { 15 | return {children}; 16 | }; 17 | 18 | Accordion.Frame = function AccordionFrame({ children, ...restProps }) { 19 | return {children}; 20 | }; 21 | 22 | Accordion.Item = function AccordionItem({ children, ...restProps }) { 23 | const [toggleShow, setToggleShow] = useState(false); 24 | return ( 25 | 26 | {children} 27 | 28 | ); 29 | }; 30 | 31 | Accordion.Header = function AccordionHeader({ children, ...restProps }) { 32 | const { toggleShow, setToggleShow } = useContext(ToggleContext); 33 | 34 | return ( 35 |
setToggleShow((toggleShow) => !toggleShow)} {...restProps}> 37 | 38 | {children} 39 | {toggleShow ? ( 40 | Close 41 | ) : ( 42 | Open 43 | )} 44 |
45 | ); 46 | }; 47 | 48 | Accordion.Body = function AccordionBody({children, ...restProps }) { 49 | const { toggleShow } = useContext(ToggleContext); 50 | 51 | return toggleShow ? {children} : null; 52 | }; -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page Not Found 7 | 8 | 23 | 24 | 25 |
26 |

404

27 |

Page Not Found

28 |

The specified file was not found on this website. Please check the URL for mistakes and try again.

29 |

Why am I seeing this?

30 |

This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html file in your project's configured public directory.

31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /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/containers/footer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Footer } from '../components'; 3 | 4 | export function FooterContainer(){ 5 | return ( 6 |
7 | Questions? Get to know us more 8 | 9 | 10 | 11 | FAQ 12 | Investor Relations 13 | Ways to Watch 14 | Corporate Information 15 | Netflix originals 16 | 17 | 18 | 19 | 20 | Help Center 21 | Jobs 22 | Terms of Use 23 | Contact us 24 | 25 | 26 | 27 | 28 | Account 29 | Reedem Gift 30 | Privacy 31 | Speed Test 32 | 33 | 34 | 35 | 36 | Media Center 37 | Buy Gift Cards 38 | Cookie Preferences 39 | Legal Notices 40 | 41 | 42 | 43 | Netflix India 44 |
45 | ); 46 | } -------------------------------------------------------------------------------- /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 | `; 7 | 8 | export const Inner = styled.div` 9 | display: flex; 10 | padding: 70px 30px; 11 | flex-direction: column; 12 | max-width: 750px; 13 | margin: auto; 14 | `; 15 | 16 | export const Item = styled.div` 17 | color: white; 18 | margin-bottom: 10px; 19 | max-width: 760px; 20 | &:first-of-type { 21 | margin-top: 3em; 22 | } 23 | `; 24 | 25 | export const Header = styled.div` 26 | display: flex; 27 | justify-content: space-between; 28 | cursor: pointer; 29 | margin-bottom: 1px; 30 | font-size: 25px; 31 | font-weight: normal; 32 | background: #303030; 33 | padding: 0.8em 1.2em; 34 | user-select: none; 35 | align-items: center; 36 | 37 | img { 38 | filter: brightness(0) invert(1); 39 | width: 24px; 40 | 41 | @media (max-width: 600px) { 42 | width: 16px; 43 | } 44 | } 45 | 46 | @media (max-width: 600px) { 47 | font-size: 19px; 48 | } 49 | `; 50 | 51 | export const Body = styled.div` 52 | max-height: 1200px; 53 | transition: max-height 0.25s cubic-beizer(0.5, 0, 0.1, 1); 54 | font-size: 22px; 55 | font-weight: normal; 56 | line-height: normal; 57 | background: #303030; 58 | padding: 0.8em 2.2em; 59 | white-space: pre-wrap; 60 | user-select: none; 61 | 62 | @media (max-width: 600px) { 63 | font-size: 18px; 64 | line-height: 22px; 65 | } 66 | `; 67 | 68 | export const Frame = styled.div` 69 | margin-bottom: 40px; 70 | 71 | `; 72 | 73 | 74 | export const Title = styled.h1` 75 | font-size: 50px; 76 | line-height: 1.1; 77 | margin-top: 0; 78 | margin-bottom: 8px; 79 | color: white; 80 | text-align: center; 81 | 82 | @media (max-width: 600px ) { 83 | font-size: 30px; 84 | } 85 | `; 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/components/loading/styles/loading.js: -------------------------------------------------------------------------------- 1 | import styled, { createGlobalStyle } from 'styled-components'; 2 | 3 | export const LockBody = createGlobalStyle` 4 | body { 5 | overflow: hidden; 6 | } 7 | `; 8 | 9 | export const ReleaseBody = createGlobalStyle` 10 | body { 11 | overflow: visible; 12 | } 13 | `; 14 | 15 | export const Spinner = styled.div` 16 | position: fixed; 17 | width: 100%; 18 | height: 100%; 19 | background-color: black; 20 | z-index: 999; 21 | :after { 22 | content: ''; 23 | position: absolute; 24 | top: 50%; 25 | left: 50%; 26 | background-image: url(/images/misc/spinner.png); 27 | background-size: contain; 28 | background-repeat: no-repeat; 29 | margin-top: -150px; 30 | margin-left: -75px; 31 | width: 150px; 32 | height: 150px; 33 | animation-name: spin; 34 | animation-duration: 1000ms; 35 | animation-iteration-count: infinite; 36 | animation-timing-function: linear; 37 | } 38 | @-ms-keyframes spin { 39 | from { 40 | -ms-transform: rotate(0deg); 41 | } 42 | to { 43 | -ms-transform: rotate(360deg); 44 | } 45 | } 46 | @-moz-keyframes spin { 47 | from { 48 | -moz-transform: rotate(0deg); 49 | } 50 | to { 51 | -moz-transform: rotate(360deg); 52 | } 53 | } 54 | @-webkit-keyframes spin { 55 | from { 56 | -webkit-transform: rotate(0deg); 57 | } 58 | to { 59 | -webkit-transform: rotate(360deg); 60 | } 61 | } 62 | @keyframes spin { 63 | from { 64 | transform: rotate(0deg); 65 | } 66 | to { 67 | transform: rotate(360deg); 68 | } 69 | } 70 | `; 71 | 72 | export const Picture = styled.img` 73 | width: 50px; 74 | height: 50px; 75 | position: absolute; 76 | top: 50%; 77 | left: 50%; 78 | margin-top: -100px; 79 | margin-left: -22px; 80 | `; -------------------------------------------------------------------------------- /src/components/row.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import axios from '../axios'; 3 | import "./row.css"; 4 | import YouTube from "react-youtube"; 5 | import movieTrailer from "movie-trailer"; 6 | 7 | const base_url = "https://image.tmdb.org/t/p/original/"; 8 | 9 | function Row({ title, fetchUrl, isLargeRow }) { 10 | const [movies, setMovies] = useState([]); 11 | const [trailerUrl, setTrailerUrl] = useState(""); 12 | 13 | useEffect(() => { 14 | async function fetchData(){ 15 | const requests = await axios.get(fetchUrl); 16 | setMovies(requests.data.results); 17 | return requests; 18 | } 19 | fetchData(); 20 | }, [fetchUrl]); 21 | 22 | const opts = { 23 | height: "390", 24 | width: "100%", 25 | playVars: { 26 | // https://developers.google.com/youtube/player_parameters 27 | autoplay: 1, 28 | }, 29 | }; 30 | 31 | const handleClick = (movie) => { 32 | if(trailerUrl) { 33 | setTrailerUrl(''); 34 | } else { 35 | movieTrailer(movie?.name || "").then(url => { 36 | const urlParams = new URLSearchParams(new URL(url).search); 37 | setTrailerUrl(urlParams.get('v')); 38 | }) 39 | .catch(error => console.log(error)); 40 | } 41 | }; 42 | 43 | return ( 44 |
45 |

{title}

46 | 47 |
48 | 49 | {movies.map(movie => ( 50 | handleClick(movie)} 53 | className={`row_poster ${isLargeRow && "row_posterLarge"}`} 54 | src={`${base_url}${isLargeRow ? movie.poster_path : movie.backdrop_path}`} alt={movie.name} /> 55 | ))} 56 |
57 | 58 | {trailerUrl && } 59 | 60 |
61 | ) 62 | } 63 | 64 | export default Row 65 | -------------------------------------------------------------------------------- /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 | min-height: 660px; 8 | background-color: rgba(0,0,0,0.80); 9 | broder-radius: 5px; 10 | box-sizing: border-box; 11 | width: 100%; 12 | margin: auto; 13 | max-width: 450px; 14 | padding: 60px 68px 40px; 15 | margin-bottom: 100px; 16 | `; 17 | 18 | export const Error = styled.div` 19 | background: #e87c03; 20 | border-radius: 4px; 21 | font-size: 14px; 22 | margin: 00 16px; 23 | color: white; 24 | padding: 15px 20px; 25 | `; 26 | 27 | export const Base = styled.form` 28 | display: flex; 29 | flex-direction: column; 30 | max-width: 450px; 31 | width: 100%; 32 | `; 33 | 34 | export const Title = styled.h1` 35 | color: #fff; 36 | font-size: 32px; 37 | fonr-weight: bold; 38 | margin-bottom: 28px; 39 | `; 40 | 41 | export const Text = styled.p` 42 | color: #737373; 43 | font-size: 16px; 44 | font-weight: 500; 45 | `; 46 | 47 | export const TextSmall = styled.p` 48 | margin-top: 10px; 49 | font-size: 13px; 50 | line-height: normal; 51 | color: #8c8c8c; 52 | `; 53 | 54 | export const Link = styled(ReactRouterLink)` 55 | color: white; 56 | text-decoration: none; 57 | &: hover { 58 | text-decoration: underline; 59 | } 60 | `; 61 | 62 | export const Input = styled.input` 63 | background: #333; 64 | border-radius: 4px; 65 | border: 0; 66 | color: white; 67 | height: 50px; 68 | line-height: 50px; 69 | padding: 5px 20px; 70 | margin-bottom: 20px; 71 | 72 | &:last-of-type { 73 | margin-bottom: 30px; 74 | } 75 | `; 76 | 77 | export const Submit = styled.button` 78 | background: #e50914; 79 | border-radius: 4px; 80 | height: 50px; 81 | font-size: 16px; 82 | font-weight: bold; 83 | margin: 24px 0 13px; 84 | padding: 16px; 85 | border: 0; 86 | color: white; 87 | cursor: pointer; 88 | 89 | &: disabled { 90 | opacity: 0.5; 91 | } 92 | `; -------------------------------------------------------------------------------- /src/pages/signin.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext } from 'react'; 2 | import { useHistory } from 'react-router-dom'; 3 | import { FirebaseContext } from '../context/firebase'; 4 | import { HeaderContainer } from '../containers/header'; 5 | import { FooterContainer } from '../containers/footer'; 6 | import { Form } from '../components'; 7 | import * as ROUTES from '../constants/routes'; 8 | 9 | export default function Signin() { 10 | const history = useHistory(); 11 | const { firebase } = useContext(FirebaseContext); 12 | const [emailAddress, setEmailAddress] = useState(''); 13 | const [password, setPassword] = useState(''); 14 | const [error, setError] = useState(''); 15 | 16 | const isInvalid = password === '' || emailAddress === ''; 17 | 18 | const handleSignIn = (event) => { 19 | event.preventDefault(); 20 | 21 | // firebase work here! 22 | firebase.auth() 23 | .signInWithEmailAndPassword(emailAddress, password) 24 | .then(() => { 25 | //push to the browse page 26 | history.push(ROUTES.BROWSE); 27 | }) 28 | .catch((error) => { 29 | setEmailAddress(''); 30 | setPassword(''); 31 | setError(error.message); 32 | }); 33 | }; 34 | 35 | 36 | return ( 37 | <> 38 | 39 |
40 | Sign In 41 | {error && {error}} 42 | 43 | 44 | setEmailAddress(target.value)} 46 | /> 47 | 48 | setPassword(target.value)} 50 | /> 51 | 52 | 53 | SignIn 54 | 55 | 56 | 57 | 58 | New to Netflix? Sign up now. 59 | 60 | 61 | 62 | This page is protected by Google reCAPCTHA to ensure that you are not a bot. Learn more. 63 | 64 |
65 |
; 66 | 67 | 68 | ); 69 | } -------------------------------------------------------------------------------- /src/pages/signup.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext } from 'react'; 2 | import { useHistory } from 'react-router-dom'; 3 | import { FirebaseContext } from '../context/firebase'; 4 | import { HeaderContainer } from '../containers/header'; 5 | import { FooterContainer } from '../containers/footer'; 6 | import { Form } from '../components'; 7 | import * as ROUTES from '../constants/routes'; 8 | 9 | export default function Signup() { 10 | const history = useHistory(); 11 | const { firebase } = useContext(FirebaseContext); 12 | const [firstName, setFirstName] = useState(''); 13 | const [emailAddress, setEmailAddress] = useState(''); 14 | const [password, setPassword] = useState(''); 15 | const [error, setError] = useState(''); 16 | 17 | const isInvalid = firstName === '' || password === '' || emailAddress === ''; 18 | 19 | const handleSignup = (event) => { 20 | event.preventDefault(); 21 | 22 | // do firebase stuff 23 | firebase.auth() 24 | .createUserWithEmailAndPassword(emailAddress, password) 25 | .then((result) => 26 | result.user.updateProfile({ 27 | displayName: firstName, 28 | photoURL: Math.floor(Math.random() * 5) + 1, 29 | }) 30 | .then(() => { 31 | history.push(ROUTES.BROWSE); 32 | }) 33 | ) 34 | .catch((error) => { 35 | setFirstName(''); 36 | setEmailAddress(''); 37 | setPassword(''); 38 | setError(error.message); 39 | }); 40 | }; 41 | 42 | return ( 43 | 44 | <> 45 | 46 | 47 |
48 | Sign up 49 | {error && {error}} 50 | 51 | 52 | setFirstName(target.value)} 55 | /> 56 | 57 | setEmailAddress(target.value)} 60 | /> 61 | 62 | setPassword(target.value)} 65 | /> 66 | 67 | 68 | Sign Up 69 | 70 | 71 | 72 | Already a user? Sign in now 73 | 74 | 75 | 76 | This page is protected by Google reCAPTCHA to ensure you're not a bot. Learn more. 77 | 78 | 79 |
80 |
81 | 82 | 83 | ); 84 | } -------------------------------------------------------------------------------- /src/components/card/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext, createContext } from 'react'; 2 | 3 | import { 4 | Container, 5 | Group, 6 | Title, 7 | SubTitle, 8 | Text, 9 | Feature, 10 | FeatureTitle, 11 | FeatureText, 12 | FeatureClose, 13 | Maturity, 14 | Content, 15 | Meta, 16 | Entities, 17 | Item, 18 | Image, 19 | } from './styles/card'; 20 | 21 | export const FeatureContext = createContext(); 22 | 23 | export default function Card({ children, ...restProps }) { 24 | const [showFeature, setShowFeature] = useState(false); 25 | const [itemFeature, setItemFeature] = useState({}); 26 | 27 | return ( 28 | 29 | {children} 30 | 31 | ); 32 | } 33 | 34 | Card.Group = function CardGroup({ children, ...restProps }) { 35 | return {children}; 36 | }; 37 | 38 | Card.Title = function CardTitle({ children, ...restProps }) { 39 | return {children}; 40 | }; 41 | 42 | Card.SubTitle = function CardSubTitle({ children, ...restProps }) { 43 | return {children}; 44 | }; 45 | 46 | Card.Text = function CardText({ children, ...restProps }) { 47 | return {children}; 48 | }; 49 | 50 | Card.Entities = function CardEntities({ children, ...restProps }) { 51 | return {children}; 52 | }; 53 | 54 | Card.Meta = function CardMeta({ children, ...restProps }) { 55 | return {children}; 56 | }; 57 | 58 | Card.Item = function CardItem({ item, children, ...restProps }) { 59 | const { setShowFeature, setItemFeature } = useContext(FeatureContext); 60 | 61 | return ( 62 | { 64 | setItemFeature(item); 65 | setShowFeature(true); 66 | }} 67 | {...restProps} 68 | > 69 | {children} 70 | 71 | ); 72 | }; 73 | 74 | Card.Image = function CardImage({ ...restProps }) { 75 | return ; 76 | }; 77 | 78 | Card.Feature = function CardFeature({ children, category, ...restProps }) { 79 | const { showFeature, itemFeature, setShowFeature } = useContext(FeatureContext); 80 | 81 | return showFeature ? ( 82 | 83 | 84 | {itemFeature.title} 85 | {itemFeature.description} 86 | setShowFeature(false)}> 87 | Close 88 | 89 | 90 | 91 | {itemFeature.maturity < 12 ? 'PG' : itemFeature.maturity} 92 | 93 | {itemFeature.genre.charAt(0).toUpperCase() + itemFeature.genre.slice(1)} 94 | 95 | 96 | 97 | {children} 98 | 99 | 100 | ) : null; 101 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The stack that is being used: React (custom hooks, context, portals), Firebase (Firestore/auth), Compound & Styled components! 2 | 3 | Hey! I finally finished this Netflix clone (took me more time than I expected 😅). My idea was to make everything static (movies, series, tv shows, ...) but then I found this really cool TMDB API which you can pull most popular movies, top rated shows, what's trending, collections, lists and muuuch more. Really worth checking the effort made. 4 | 5 | First use the Firebase App api key of your's as the project's api keys has been removed and you can add them in /lib/firebase.prod.js file and tmdb api key also needs to be changed, which is present in request.js file under the project directory. 6 | 7 | 8 | 9 | 10 | 11 | With Youtube Trailers Embeded 12 | 13 | 14 | 15 | 16 | # Getting Started with Create React App 17 | 18 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 19 | 20 | ## Available Scripts 21 | 22 | In the project directory, you can run: 23 | 24 | ### `npm start` 25 | 26 | Runs the app in the development mode.\ 27 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 28 | 29 | The page will reload if you make edits.\ 30 | You will also see any lint errors in the console. 31 | 32 | ### `npm test` 33 | 34 | Launches the test runner in the interactive watch mode.\ 35 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 36 | 37 | ### `npm run build` 38 | 39 | Builds the app for production to the `build` folder.\ 40 | It correctly bundles React in production mode and optimizes the build for the best performance. 41 | 42 | The build is minified and the filenames include the hashes.\ 43 | Your app is ready to be deployed! 44 | 45 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 46 | 47 | ### `npm run eject` 48 | 49 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 50 | 51 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 52 | 53 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 54 | 55 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 56 | 57 | ## Learn More 58 | 59 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 60 | 61 | To learn React, check out the [React documentation](https://reactjs.org/). 62 | 63 | ### Code Splitting 64 | 65 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 66 | 67 | ### Analyzing the Bundle Size 68 | 69 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 70 | 71 | ### Making a Progressive Web App 72 | 73 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 74 | 75 | ### Advanced Configuration 76 | 77 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 78 | 79 | ### Deployment 80 | 81 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 82 | 83 | ### `npm run build` fails to minify 84 | 85 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 86 | -------------------------------------------------------------------------------- /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 Group = styled.div` 29 | display: flex; 30 | flex-direction: ${({ flexDirection }) => (flexDirection === 'row' ? 'row' : 'column')}; 31 | ${({ alignItems }) => alignItems && `align-items: ${alignItems}`}; 32 | ${({ margin }) => margin && `margin: ${margin}`}; 33 | 34 | > ${Container}:first-of-type { 35 | @media (min-width: 1100px) { 36 | margin-top: -100px; 37 | } 38 | } 39 | `; 40 | 41 | export const SubTitle = styled.p` 42 | font-size: 12px; 43 | color: #fff; 44 | font-weight: bold; 45 | margin-top: 0; 46 | margin-bottom: 0; 47 | user-select: none; 48 | display: none; 49 | `; 50 | 51 | export const Text = styled.p` 52 | margin-top: 5px; 53 | font-size: 10px; 54 | color: #fff; 55 | margin-bottom: 0; 56 | user-select: none; 57 | display: none; 58 | line-height: normal; 59 | `; 60 | 61 | export const Entities = styled.div` 62 | display: flex; 63 | flex-direction: row; 64 | `; 65 | 66 | export const Meta = styled.div` 67 | display: none; 68 | position: absolute; 69 | bottom: 0; 70 | padding: 10px; 71 | background-color: #0000008f; 72 | `; 73 | 74 | export const Image = styled.img` 75 | border: 0; 76 | width: 100%; 77 | max-width: 305px; 78 | cursor: pointer; 79 | height: auto; 80 | padding: 0; 81 | margin: 0; 82 | `; 83 | 84 | export const Item = styled.div` 85 | display: flex; 86 | flex-direction: column; 87 | margin-right: 5px; 88 | position: relative; 89 | cursor: pointer; 90 | transition: transform 0.2s; 91 | 92 | &:hover { 93 | transform: scale(1.3); 94 | z-index: 99; 95 | } 96 | 97 | @media (min-width: 1200px) { 98 | &:hover ${Meta}, &:hover ${Text}, &:hover ${SubTitle} { 99 | display: block; 100 | z-index: 100; 101 | } 102 | } 103 | 104 | &:first-of-type { 105 | margin-left: 56px; 106 | @media (max-width: 1000px) { 107 | margin-left: 30px; 108 | } 109 | } 110 | 111 | &:last-of-type { 112 | margin-right: 56px; 113 | @media (max-width: 1000px) { 114 | margin-right: 30px; 115 | } 116 | } 117 | `; 118 | 119 | export const FeatureText = styled.p` 120 | font-size: 18px; 121 | color: white; 122 | font-weight: ${({ fontWeight }) => (fontWeight === 'bold' ? 'bold' : 'normal')}; 123 | margin: 0; 124 | @media (max-width: 600px) { 125 | line-height: 22px; 126 | } 127 | `; 128 | 129 | export const Feature = styled.div` 130 | display: flex; 131 | flex-direction: row; 132 | background: url(${({ src }) => src}); 133 | background-size: contain; 134 | position: relative; 135 | height: 360px; 136 | background-position-x: right; 137 | background-repeat: no-repeat; 138 | background-color: black; 139 | 140 | @media (max-width: 1000px) { 141 | height: auto; 142 | background-size: auto; 143 | ${Title} { 144 | font-size: 20px; 145 | line-height: 20px; 146 | margin-bottom: 10px; 147 | } 148 | ${FeatureText} { 149 | font-size: 14px; 150 | } 151 | } 152 | `; 153 | 154 | export const FeatureTitle = styled(Title)` 155 | margin-left: 0; 156 | `; 157 | 158 | export const FeatureClose = styled.button` 159 | color: white; 160 | position: absolute; 161 | right: 20px; 162 | top: 20px; 163 | cursor: pointer; 164 | background-color: transparent; 165 | border: 0; 166 | 167 | img { 168 | filter: brightness(0) invert(1); 169 | width: 24px; 170 | } 171 | `; 172 | 173 | export const Content = styled.div` 174 | margin: 56px; 175 | max-width: 500px; 176 | line-height: normal; 177 | 178 | @media (max-width: 1000px) { 179 | margin: 30px; 180 | max-width: none; 181 | } 182 | `; 183 | 184 | export const Maturity = styled.div` 185 | background-color: ${({ rating }) => (rating >= 15 ? '#f44336' : '#2f9600')}; 186 | border-radius: 15px; 187 | width: 28px; 188 | line-height: 28px; 189 | text-align: center; 190 | color: white; 191 | font-weight: bold; 192 | text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); 193 | margin-right: 10px; 194 | font-size: 12px; 195 | `; -------------------------------------------------------------------------------- /src/components/header/styles/header.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | import { Link as ReactRouterLink } from 'react-router-dom'; 3 | 4 | export const Background = styled.div` 5 | display: flex; 6 | flex-direction: column; 7 | background: url(${({ src }) => 8 | src ? `../images/misc/${src}.jpg` : '../images/misc/home-bg.jpg'}) 9 | top left / cover no-repeat; 10 | 11 | @media (max-width: 1100px) { 12 | ${({ dontShowOnSmallViewPort }) => dontShowOnSmallViewPort && `background: none`}; 13 | } 14 | `; 15 | 16 | export const Group = styled.div` 17 | display: flex; 18 | align-items: center; 19 | `; 20 | 21 | export const Container = styled.div` 22 | display: flex; 23 | margin: 0 56px; 24 | height: 30px; 25 | width: 90%; 26 | padding: 18px 0; 27 | justify-content: space-between; 28 | align-items: center; 29 | position: fixed; 30 | z-index: 1; 31 | transition-timing-function: ease-in; 32 | transition: all 0.4s; 33 | 34 | a { 35 | display: flex; 36 | } 37 | 38 | @media (max-width: 1000px) { 39 | margin: 0 30px; 40 | } 41 | `; 42 | 43 | export const Picture = styled.button` 44 | background: url(${({ src }) => src}); 45 | background-size: contain; 46 | border: 0; 47 | width: 32px; 48 | height: 32px; 49 | cursor: pointer; 50 | `; 51 | 52 | export const Link = styled.p` 53 | color: white; 54 | text-decoration: none; 55 | margin-right: 30px; 56 | font-weight: ${({ active }) => (active === 'true' ? '700' : 'normal')}; 57 | cursor: pointer; 58 | 59 | &: hover { 60 | font-weight: bold; 61 | } 62 | 63 | &:last-of-type { 64 | margin-right: 0; 65 | } 66 | `; 67 | 68 | export const Dropdown = styled.div` 69 | display: none; 70 | background-color: black; 71 | position: absolute; 72 | padding: 10px; 73 | width: 100px; 74 | top: 32px; 75 | right: 10px; 76 | 77 | ${Group}:last-of-type ${Link} { 78 | cursor: pointer; 79 | } 80 | 81 | ${Group} { 82 | margin-bottom: 10px; 83 | 84 | &:last-of-type { 85 | margin-bottom: 0; 86 | } 87 | 88 | ${Link}, ${Picture} { 89 | cursor: default; 90 | } 91 | } 92 | 93 | button { 94 | margin-right: 10px; 95 | } 96 | 97 | p { 98 | font-size: 12px; 99 | margin-bottom: 0; 100 | margin-top: 0; 101 | } 102 | `; 103 | 104 | export const Search = styled.div` 105 | dsiplay: flex; 106 | align-items: center; 107 | 108 | svg { 109 | color: #111; 110 | cursor: pointer; 111 | } 112 | 113 | @media (max-width: 700px) { 114 | display: none; 115 | } 116 | `; 117 | 118 | export const SearchIcon = styled.button` 119 | cursor: pointer; 120 | background-color: transparent; 121 | border: 0; 122 | padding-top: 20px; 123 | 124 | img { 125 | filter: brightness(0) invert(1); 126 | width: 16px; 127 | } 128 | `; 129 | 130 | export const PlayButton = styled.button` 131 | box-shadow: 0 0.6vw 1vw -0.4vw rgba(0, 0, 0, 0.35); 132 | background-color: #e6e6e6; 133 | color: #000; 134 | font-weight: bold; 135 | border-width: 0; 136 | padding: 10px 20px; 137 | border-radius: 5px; 138 | max-width: 130px; 139 | font-size: 20px; 140 | margin-top: 30px; 141 | cursor: pointer; 142 | transition: background-color 0.2s; 143 | 144 | &: hover { 145 | background-color: #ff1e1e; 146 | color: white; 147 | } 148 | `; 149 | 150 | export const SearchInput = styled.input` 151 | background-color: #44444459; 152 | color: white; 153 | border: 1px solid white; 154 | transition: width: 0.5s; 155 | height: 30px; 156 | font-size: 14px; 157 | margin-left: ${({ active }) => (active === true ? '10px' : '0')}; 158 | padding: ${({ active }) => (active === true ? '0 10px' : '0')}; 159 | opacity: ${({ active }) => (active === true ? '1' : '0')}; 160 | width: ${({ active }) => (active === true ? '200px' : '0px')}; 161 | `; 162 | 163 | export const Profile = styled.div` 164 | display: flex; 165 | align-items: center; 166 | margin-left: 20px; 167 | position: relative; 168 | paddding-top: 20px; 169 | 170 | button { 171 | cursor: pointer; 172 | } 173 | 174 | &:hover > ${Dropdown} { 175 | display: flex; 176 | flex-direction: column; 177 | } 178 | `; 179 | 180 | export const Logo = styled.img` 181 | height: 32px; 182 | width: 108px; 183 | margin-right: 40px; 184 | padding-top: 20px; 185 | 186 | @media (min-width: 1449px) { 187 | height: 45px; 188 | width: 167px; 189 | } 190 | `; 191 | 192 | export const ButtonLink = styled(ReactRouterLink)` 193 | display: block; 194 | background-color: #e50914; 195 | width: 84px; 196 | height: fit-content; 197 | color: white; 198 | border: 0; 199 | font-size: 15px; 200 | border-radius: 3px; 201 | padding: 8px 17px; 202 | cursor: pointer; 203 | text-decoration: none; 204 | box-sizing: border-box; 205 | 206 | &:hover { 207 | background-color: #f40612; 208 | } 209 | `; 210 | 211 | export const Feature = styled(Container)` 212 | padding: 150px 0 500px 0; 213 | flex-direction: column; 214 | align-items: normal; 215 | width: 50%; 216 | 217 | @media (max-width: 1100px) { 218 | display: none; 219 | } 220 | `; 221 | 222 | export const Text = styled.p` 223 | color: white; 224 | font-size: 22px; 225 | line-height: normal; 226 | text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.45); 227 | margin: 0; 228 | `; 229 | 230 | export const FeatureCallOut = styled.h2` 231 | color: white; 232 | font-size: 50px; 233 | line-height: normal; 234 | font-weight: bold; 235 | text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.45); 236 | margin: 0; 237 | margin-bottom: 20px; 238 | `; -------------------------------------------------------------------------------- /src/components/header/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { Link as ReactRouterLink } from 'react-router-dom'; 3 | import "./styles/header.css"; 4 | import axios from '../../axios'; 5 | import Row from '../row'; 6 | import requests from '../../request'; 7 | import { Background, ButtonLink, Container, PlayButton, Search, SearchIcon, SearchInput, Logo, Dropdown, Profile, Picture, Group, Feature, Text, FeatureCallOut, Link } from './styles/header'; 8 | 9 | export default function Header({ bg = true, children, ...restProps }) { 10 | return bg ? {children} : children; 11 | } 12 | 13 | 14 | Header.Banner = function HeaderBanner({ children, ...restProps }) { 15 | 16 | const [show, handleShow] = useState(false); 17 | const [movie, setMovie] = useState([]); 18 | 19 | useEffect(() => { 20 | async function fetchData() { 21 | const request = await axios.get(requests.fetchNetflixOriginals); 22 | setMovie ( request.data.results[Math.floor(Math.random() * request.data.results.length - 1)] 23 | ); 24 | return request; 25 | } 26 | fetchData(); 27 | }, []); 28 | 29 | console.log(movie); 30 | 31 | function truncate(str, n) { 32 | return str?.length > n ? str.substr(0, n-1) + "..." : str; 33 | } 34 | 35 | // useEffect(() => { 36 | // window.addEventListener("scroll", () => { 37 | // if (window.scrollY > 100) { 38 | // handleShow(true) 39 | // } else handleShow(false); 40 | // }); 41 | // return () => { 42 | // window.removeEventListener("scroll"); 43 | // }; 44 | // }, []); 45 | 46 | return ( 47 | 48 |
55 |
56 |

57 | {movie?.title || movie?.name || movie?.original_name} 58 |

59 | 60 |
61 | 62 | 63 |
64 | 65 |

66 | {truncate(movie?.overview, 150)} 67 |

68 |
69 | 70 |
71 | 72 |
73 | 74 | 75 | 76 |
77 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
88 | 89 |
90 | ); 91 | } 92 | 93 | 94 | Header.FeatureCallOut = function HeaderFeatureCallOut({ children, ...restProps }) { 95 | return {children}; 96 | }; 97 | 98 | Header.Feature = function HeaderFeature({ children, ...restProps }) { 99 | return {children}; 100 | }; 101 | 102 | Header.Profile = function HeaderProfile({ children, ...restProps }) { 103 | return {children}; 104 | }; 105 | 106 | Header.Picture = function HeaderPicture({ src, ...restProps }) { 107 | return ; 108 | }; 109 | 110 | Header.Search = function HeaderSearch({ searchTerm, setSearchTerm, ...restProps }) { 111 | const [searchActive, setSearchActive] = useState(false); 112 | 113 | return ( 114 | 115 | setSearchActive(searchActive => !searchActive)}> 116 | Search 117 | 118 | setSearchTerm(target.value)} 119 | placeholder="Search films and series" 120 | active={searchActive} 121 | /> 122 | 123 | ); 124 | }; 125 | 126 | Header.Dropdown = function HeaderDropdown({ children, ...restProps }) { 127 | return {children}; 128 | }; 129 | 130 | Header.Text = function HeaderText({ children, ...restProps }) { 131 | return {children}; 132 | }; 133 | 134 | Header.TextLink = function HeaderTextLink({ children, ...restProps }) { 135 | return {children}; 136 | }; 137 | 138 | Header.PlayButton = function HeaderPlayButton({children, ...restProps}) { 139 | return {children} 140 | } 141 | 142 | Header.Frame = function HeaderFrame({ children, ...restProps }) { 143 | return {children}; 144 | }; 145 | 146 | Header.Group = function HeaderGroup({ children, ...restProps }) { 147 | return {children}; 148 | }; 149 | 150 | Header.ButtonLink = function HeaderButtonLink({ children, ...restProps }) { 151 | return {children}; 152 | }; 153 | 154 | Header.Logo = function HeaderLogo({ to, ...restProps }) { 155 | return ( 156 | 157 | 158 | 159 | ); 160 | }; -------------------------------------------------------------------------------- /src/containers/browse.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-nested-ternary */ 2 | import React, { useContext, useState, useEffect } from 'react'; 3 | import Fuse from 'fuse.js'; 4 | import { FirebaseContext } from '../context/firebase'; 5 | import { SelectProfileContainer } from './profiles'; 6 | import { Card, Header, Loading } from '../components'; 7 | import * as ROUTES from '../constants/routes'; 8 | import logo from '../logo.svg'; 9 | import { FooterContainer } from './footer'; 10 | import Player from '../components/player'; 11 | 12 | 13 | 14 | export function BrowseContainer({ slides }) { 15 | 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 | const { firebase } = useContext(FirebaseContext); 23 | const user = firebase.auth().currentUser || {}; 24 | 25 | useEffect(() => { 26 | setTimeout(() => { 27 | setLoading(false); 28 | }, 3000); 29 | }, [profile.displayName]); 30 | 31 | 32 | useEffect(() => { 33 | setSlideRows(slides[category]); 34 | }, [slides, category]); 35 | 36 | useEffect(() => { 37 | const fuse = new Fuse(slideRows, 38 | { keys: ['data.description', 'data,title', 'data.genre'], }); 39 | const results = fuse.search(searchTerm).map(({ item }) => item); 40 | 41 | if(slideRows.length > 0 && searchTerm.length > 3 42 | && results.length > 0 ) { 43 | setSlideRows(results); 44 | } else { 45 | setSlideRows(slides[category]); 46 | } 47 | 48 | }, [searchTerm]); 49 | 50 | return profile.displayName ? ( 51 | <> 52 | {loading ? 53 | : } 54 | 55 | 56 |
57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | {user.displayName} 71 | 72 | 73 | 74 | firebase.auth().signOut()}>Sign out 75 | 76 | 77 | 78 | 79 | 80 | 81 |
82 | 83 | 84 | 85 | 86 | {/*
87 | 88 | 89 | 90 | setCategory('series')}>Series 92 | 93 | setCategory('films')}>Films 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | {user.displayName} 106 | 107 | 108 | 109 | firebase.auth().signOut()}>Sign out 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | Watch Joker Now 118 | 119 | Forever alone in a crowd, failed comedian Arthur Fleck seeks connection as he walks the streets of Gotham 120 | City. Arthur wears two masks -- the one he paints for his day job as a clown, and the guise he projects in a 121 | futile attempt to feel like he's part of the world around him. 122 | 123 | 124 | Play 125 | 126 |
*/} 127 | 128 | {/* 129 | {slideRows.map((slideItem) => ( 130 | 131 | {slideItem.title} 132 | 133 | {slideItem.data.map((item) => ( 134 | 135 | 136 | 137 | 138 | {item.title} 139 | {item.description} 140 | 141 | 142 | ))} 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | ))} 153 | */} 154 | {/* */} 155 | 156 | ) : ( 157 | 158 | ); 159 | } 160 | 161 | //new timestamp 7:53:08, need to work on Player test and overall performance -------------------------------------------------------------------------------- /src/seed.js: -------------------------------------------------------------------------------- 1 | export function seedDatabase(firebase) { 2 | function getUUID() { 3 | // eslint gets funny about bitwise 4 | /* eslint-disable */ 5 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { 6 | const piece = (Math.random() * 16) | 0; 7 | const elem = c === 'x' ? piece : (piece & 0x3) | 0x8; 8 | return elem.toString(16); 9 | }); 10 | /* eslint-enable */ 11 | } 12 | 13 | /* Series 14 | ============================================ */ 15 | // Documentaries 16 | firebase.firestore().collection('series').add({ 17 | id: getUUID(), 18 | title: 'Tiger King', 19 | description: 'An exploration of big cat breeding and its bizarre underworld, populated by eccentric characters.', 20 | genre: 'documentaries', 21 | maturity: '18', 22 | slug: 'tiger-king', 23 | }); 24 | firebase.firestore().collection('series').add({ 25 | id: getUUID(), 26 | title: 'Amanda Knox', 27 | description: 'Amanda Marie Knox is an American woman who spent almost four years in an Italian prison.', 28 | genre: 'documentaries', 29 | maturity: '12', 30 | slug: 'amanda-knox', 31 | }); 32 | firebase.firestore().collection('series').add({ 33 | id: getUUID(), 34 | title: 'Citizenfour', 35 | description: 36 | 'Citizenfour is a 2014 documentary film directed by Laura Poitras, concerning Edward Snowden and the NSA spying scandal.', 37 | genre: 'documentaries', 38 | maturity: '12', 39 | slug: 'citizenfour', 40 | }); 41 | firebase.firestore().collection('series').add({ 42 | id: getUUID(), 43 | title: 'Super Size Me', 44 | description: 45 | "Director Morgan Spurlock's social experiment in fast-food gastronomy sees him attempting to subsist uniquely on food from the McDonalds", 46 | genre: 'documentaries', 47 | maturity: '12', 48 | slug: 'super-size-me', 49 | }); 50 | firebase.firestore().collection('series').add({ 51 | id: getUUID(), 52 | title: 'Man on Wire', 53 | description: 54 | "Filmmaker James Marsh masterfully recreates high-wire daredevil Philippe Petit's 1974 stunt walking on a wire across the Twin Towers.", 55 | genre: 'documentaries', 56 | maturity: '12', 57 | slug: 'man-on-wire', 58 | }); 59 | 60 | // Comedies 61 | firebase.firestore().collection('series').add({ 62 | id: getUUID(), 63 | title: 'The Office', 64 | description: 65 | 'A motley group of office workers go through hilarious misadventures at the Scranton, Pennsylvania, branch of the Dunder Mifflin Paper Company.', 66 | genre: 'comedies', 67 | maturity: '15', 68 | slug: 'the-office', 69 | }); 70 | firebase.firestore().collection('series').add({ 71 | id: getUUID(), 72 | title: 'Arrested Development', 73 | description: 74 | 'The Bluth family, once a prominent name in the business, loses everything after the head patriarch gets convicted for fraud.', 75 | genre: 'comedies', 76 | maturity: '15', 77 | slug: 'arrested-development', 78 | }); 79 | firebase.firestore().collection('series').add({ 80 | id: getUUID(), 81 | title: 'Curb Your Enthusiasm', 82 | description: 83 | 'Larry David, a famous television writer and producer, gets into various misadventures with his friends and celebrity colleagues in Los Angeles.', 84 | genre: 'comedies', 85 | maturity: '15', 86 | slug: 'curb-your-enthusiasm', 87 | }); 88 | firebase.firestore().collection('series').add({ 89 | id: getUUID(), 90 | title: 'Family Guy', 91 | description: 92 | '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.', 93 | genre: 'comedies', 94 | maturity: '15', 95 | slug: 'family-guy', 96 | }); 97 | firebase.firestore().collection('series').add({ 98 | id: getUUID(), 99 | title: 'South Park', 100 | description: 101 | 'Four young, schoolgoing boys, Stan Marsh, Kyle Broflovski, Eric Cartman and Kenny McCormick, who live in South Park set out on various adventures.', 102 | genre: 'comedies', 103 | maturity: '15', 104 | slug: 'south-park', 105 | }); 106 | 107 | // Children 108 | firebase.firestore().collection('series').add({ 109 | id: getUUID(), 110 | title: 'Peppa Pig', 111 | description: 112 | '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.', 113 | genre: 'children', 114 | maturity: '0', 115 | slug: 'peppa-pig', 116 | }); 117 | firebase.firestore().collection('series').add({ 118 | id: getUUID(), 119 | title: 'Dora The Explorer', 120 | description: 121 | '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.', 122 | genre: 'children', 123 | maturity: '0', 124 | slug: 'dora-the-explorer', 125 | }); 126 | firebase.firestore().collection('series').add({ 127 | id: getUUID(), 128 | title: 'PAW Patrol', 129 | description: 130 | '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.', 131 | genre: 'children', 132 | maturity: '0', 133 | slug: 'paw-patrol', 134 | }); 135 | firebase.firestore().collection('series').add({ 136 | id: getUUID(), 137 | title: 'Arthur', 138 | description: 139 | 'Bespectacled aardvark Arthur Read demonstrates to kids how to deal with such childhood traumas and challenges as homework, teachers and bullies.', 140 | genre: 'children', 141 | maturity: '0', 142 | slug: 'arthur', 143 | }); 144 | firebase.firestore().collection('series').add({ 145 | id: getUUID(), 146 | title: 'SpongeBob', 147 | description: 148 | 'A yellow sea sponge named SpongeBob SquarePants lives in the city of Bikini Bottom deep in the Pacific Ocean. ', 149 | genre: 'children', 150 | maturity: '0', 151 | slug: 'spongebob', 152 | }); 153 | 154 | // Crime 155 | firebase.firestore().collection('series').add({ 156 | id: getUUID(), 157 | title: 'Making a Murderer', 158 | description: 159 | '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.', 160 | genre: 'crime', 161 | maturity: '18', 162 | slug: 'making-a-murderer', 163 | }); 164 | firebase.firestore().collection('series').add({ 165 | id: getUUID(), 166 | title: 'Long Shot', 167 | description: 168 | '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.', 169 | genre: 'crime', 170 | maturity: '18', 171 | slug: 'long-shot', 172 | }); 173 | firebase.firestore().collection('series').add({ 174 | id: getUUID(), 175 | title: 'The Confession Killer', 176 | description: 177 | '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.', 178 | genre: 'crime', 179 | maturity: '18', 180 | slug: 'the-confession-killer', 181 | }); 182 | firebase.firestore().collection('series').add({ 183 | id: getUUID(), 184 | title: 'The Innocent Man', 185 | description: 186 | '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.', 187 | genre: 'crime', 188 | maturity: '18', 189 | slug: 'the-innocent-man', 190 | }); 191 | firebase.firestore().collection('series').add({ 192 | id: getUUID(), 193 | title: 'The Staircase', 194 | description: 195 | "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", 196 | genre: 'crime', 197 | maturity: '18', 198 | slug: 'the-staircase', 199 | }); 200 | 201 | // Feel-good 202 | firebase.firestore().collection('series').add({ 203 | id: getUUID(), 204 | title: 'Good Will Hunting', 205 | description: 206 | '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.', 207 | genre: 'feel-good', 208 | maturity: '12', 209 | slug: 'good-will-hunting', 210 | }); 211 | firebase.firestore().collection('series').add({ 212 | id: getUUID(), 213 | title: 'Forrest Gump', 214 | description: 215 | '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.', 216 | genre: 'feel-good', 217 | maturity: '12', 218 | slug: 'forrest-gump', 219 | }); 220 | firebase.firestore().collection('series').add({ 221 | id: getUUID(), 222 | title: 'Juno', 223 | description: 224 | "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.", 225 | genre: 'feel-good', 226 | maturity: '12', 227 | slug: 'juno', 228 | }); 229 | firebase.firestore().collection('series').add({ 230 | id: getUUID(), 231 | title: 'Midnight In Paris', 232 | description: 233 | '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.', 234 | genre: 'feel-good', 235 | maturity: '12', 236 | slug: 'midnight-in-paris', 237 | }); 238 | firebase.firestore().collection('series').add({ 239 | id: getUUID(), 240 | title: 'School of Rock', 241 | description: 242 | "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.", 243 | genre: 'feel-good', 244 | maturity: '12', 245 | slug: 'school-of-rock', 246 | }); 247 | 248 | /* Films 249 | ============================================ */ 250 | // Drama 251 | firebase.firestore().collection('films').add({ 252 | id: getUUID(), 253 | title: 'The Prestige', 254 | description: 255 | '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.', 256 | genre: 'drama', 257 | maturity: '15', 258 | slug: 'the-prestige', 259 | }); 260 | firebase.firestore().collection('films').add({ 261 | id: getUUID(), 262 | title: 'Fight Club', 263 | description: 264 | '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.', 265 | genre: 'drama', 266 | maturity: '15', 267 | slug: 'fight-club', 268 | }); 269 | firebase.firestore().collection('films').add({ 270 | id: getUUID(), 271 | title: 'Kings Speech', 272 | description: 273 | '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.', 274 | genre: 'drama', 275 | maturity: '15', 276 | slug: 'kings-speech', 277 | }); 278 | firebase.firestore().collection('films').add({ 279 | id: getUUID(), 280 | title: 'The Revenant', 281 | description: 282 | '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.', 283 | genre: 'drama', 284 | maturity: '15', 285 | slug: 'the-revenant', 286 | }); 287 | firebase.firestore().collection('films').add({ 288 | id: getUUID(), 289 | title: 'The Social Network', 290 | description: 291 | '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.', 292 | genre: 'drama', 293 | maturity: '12', 294 | slug: 'the-social-network', 295 | }); 296 | 297 | // Suspense 298 | firebase.firestore().collection('films').add({ 299 | id: getUUID(), 300 | title: 'Shutter Island', 301 | description: 302 | '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.', 303 | genre: 'suspense', 304 | maturity: '15', 305 | slug: 'shutter-island', 306 | }); 307 | firebase.firestore().collection('films').add({ 308 | id: getUUID(), 309 | title: 'Gone Girl', 310 | description: 311 | '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.', 312 | genre: 'suspense', 313 | maturity: '15', 314 | slug: 'gone-girl', 315 | }); 316 | firebase.firestore().collection('films').add({ 317 | id: getUUID(), 318 | title: 'Prisoners', 319 | description: 320 | "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.", 321 | genre: 'suspense', 322 | maturity: '15', 323 | slug: 'prisoners', 324 | }); 325 | firebase.firestore().collection('films').add({ 326 | id: getUUID(), 327 | title: 'Seven', 328 | description: 329 | '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.', 330 | genre: 'suspense', 331 | maturity: '15', 332 | slug: 'seven', 333 | }); 334 | firebase.firestore().collection('films').add({ 335 | id: getUUID(), 336 | title: 'Zodiac', 337 | description: 338 | '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.', 339 | genre: 'suspense', 340 | maturity: '15', 341 | slug: 'zodiac', 342 | }); 343 | 344 | // Children 345 | firebase.firestore().collection('films').add({ 346 | id: getUUID(), 347 | title: 'Hotel Transylvania', 348 | description: 349 | 'Dracula, who owns a high-end resort for monsters, attempts to keep his daughter from falling in love with Jonathan, a human.', 350 | genre: 'children', 351 | maturity: '0', 352 | slug: 'hotel-transylvania', 353 | }); 354 | firebase.firestore().collection('films').add({ 355 | id: getUUID(), 356 | title: 'Despicable Me', 357 | description: 358 | '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.', 359 | genre: 'children', 360 | maturity: '0', 361 | slug: 'despicable-me', 362 | }); 363 | firebase.firestore().collection('films').add({ 364 | id: getUUID(), 365 | title: 'Frozen', 366 | description: 367 | '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.', 368 | genre: 'children', 369 | maturity: '0', 370 | slug: 'frozen', 371 | }); 372 | firebase.firestore().collection('films').add({ 373 | id: getUUID(), 374 | title: 'Spirited Away', 375 | description: 376 | '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.', 377 | genre: 'children', 378 | maturity: '0', 379 | slug: 'spirited-away', 380 | }); 381 | firebase.firestore().collection('films').add({ 382 | id: getUUID(), 383 | title: 'Up', 384 | description: 385 | "Carl, an old widower, goes off on an adventure in his flying house in search of Paradise Falls, his wife's dream destination.", 386 | genre: 'children', 387 | maturity: '0', 388 | slug: 'up', 389 | }); 390 | 391 | // Thriller 392 | firebase.firestore().collection('films').add({ 393 | id: getUUID(), 394 | title: 'Joker', 395 | description: 396 | 'Forever alone in a crowd, failed comedian Arthur Fleck seeks connection as he walks the streets of Gotham City.', 397 | genre: 'thriller', 398 | maturity: '15', 399 | slug: 'joker', 400 | }); 401 | firebase.firestore().collection('films').add({ 402 | id: getUUID(), 403 | title: 'A Quiet Place', 404 | description: 405 | '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.', 406 | genre: 'thriller', 407 | maturity: '15', 408 | slug: 'a-quiet-place', 409 | }); 410 | firebase.firestore().collection('films').add({ 411 | id: getUUID(), 412 | title: 'Black Swan', 413 | description: 414 | '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.', 415 | genre: 'thriller', 416 | maturity: '15', 417 | slug: 'black-swan', 418 | }); 419 | firebase.firestore().collection('films').add({ 420 | id: getUUID(), 421 | title: 'Nightcrawler', 422 | description: 423 | '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.', 424 | genre: 'thriller', 425 | maturity: '15', 426 | slug: 'nightcrawler', 427 | }); 428 | firebase.firestore().collection('films').add({ 429 | id: getUUID(), 430 | title: 'The Silence of The Lambs', 431 | description: 432 | '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.', 433 | genre: 'thriller', 434 | maturity: '15', 435 | slug: 'the-silence-of-the-lambs', 436 | }); 437 | 438 | // Romance 439 | firebase.firestore().collection('films').add({ 440 | id: getUUID(), 441 | title: 'A Star Is Born', 442 | description: 443 | '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.', 444 | genre: 'romance', 445 | maturity: '15', 446 | slug: 'a-star-is-born', 447 | }); 448 | firebase.firestore().collection('films').add({ 449 | id: getUUID(), 450 | title: 'Blue Valentine', 451 | description: 452 | '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.', 453 | genre: 'romance', 454 | maturity: '15', 455 | slug: 'blue-valentine', 456 | }); 457 | firebase.firestore().collection('films').add({ 458 | id: getUUID(), 459 | title: 'La La Land', 460 | description: 461 | '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...', 462 | genre: 'romance', 463 | maturity: '15', 464 | slug: 'la-la-land', 465 | }); 466 | firebase.firestore().collection('films').add({ 467 | id: getUUID(), 468 | title: 'The Notebook', 469 | description: 470 | "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.", 471 | genre: 'romance', 472 | maturity: '15', 473 | slug: 'the-notebook', 474 | }); 475 | firebase.firestore().collection('films').add({ 476 | id: getUUID(), 477 | title: 'Titanic', 478 | description: 479 | '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.', 480 | genre: 'romance', 481 | maturity: '15', 482 | slug: 'titanic', 483 | }); 484 | } --------------------------------------------------------------------------------