Full Stack Netflix Clone in React, Tailwind CSS, Next.JS, Prisma, MongoDB, NextAuth & Vercel (2023)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey there my name is Antonio and in this video I'm going to show you how to create a powerful Netflix clone using some of the latest tech Trends we're going to be using reactor front-end next.js for our server-side rendering Tailwind CSS for our styling Prisma as our data abstraction layer mongodb for our storage needs next out for authentication and to top it all off we're going to learn how to deploy all of that on versal and if that wasn't enough we will also be using typescript and make the entire website fully responsive across all devices so if you're ready to learn some new skills then let's get started alright so I just want to show you a quick overview of the functionalities which we will have in the app so first of all we have the credential login this login works if you have registered using your username email and password method that we are greeted with our profiles our profiles are automatically generated once we register once we visit the homepage app we are loaded with a random movie in this component we will call billboard which is the same thing that Netflix does as well below that you can see a list of trending movies which is basically loading movies from our database we can hover over these movies and we have a really cool netflix-like effect and from here we can add them to our favorites just like that and then below that we have a list of our favorites we can also use this little Chevron down button to open up a model that shows more information about the movie and from here we can also remove it from the favorites we can also trigger the same model from the more info button right here and we can also finally watch the movie on top of that everything is fully responsive and I will also show you that we have implemented the Google or auth login so right now it is my email great so in this part of the tutorial I'm going to show you how to initialize next.js and Tailwind which is going to be crucial for our styling so go ahead and open up your terminal and write MPX okay next at dash dash live script he's going to ask us what is your project named in my case it's going to be Netflix Dash clone in your case it can be whatever you want it's asking us whether we want to use sland with this project for that I'm going to keep the default yes for the source directory I'm going to keep the default note same for the app directory default node for the import Alias I'm not going to write anything I'm just going to press enter and that's going to default to this at sign right here once you get the success message right here I'm just going to go ahead and open my newly created uh folder so Netflix Dash clone open this app in your vs code and you should get something like this so you should have the pages folder you should have the public folder Styles Etc so just to get this running I'm gonna open the terminal one more time and this time I'm just going to write npm run depth and as you can see we got the message saying server started on localhost 3000. so right here I'm going to write localhost 3000 and as you can see I'm greeted with next JS welcome screen beautiful so I'm gonna close this terminal for now and first thing I'm going to do is I'm going to clean up this project so it's an empty state for us to work with so open the pages folder and for now you can remove the documented file entirely you can go into index.js and you can remove everything except the main function like this and for now you can just write Netflix clone in a header element and you can also remove this enter you can also remove all the Imports just like that and you should get a page similar to this one next thing we're going to clean up is the stylus folder so we no longer need the home.module.css so go ahead and remove that and enter globals.css you can just select all and remove as well and you should be greeted with something similar to this and just to show you how easy it is to work with next JS in this Pages folder I'm going to create a new file called test.esx and inside I'm going to create a new small component called my age and this component is going to return an H1 which is going to say hello new page and we're going to export the old my page just like that and since we added this file inside our Pages folder you can actually go into localhost 3000 Dash test and just like that we have our first route you can go ahead and delete this I just wanted to demonstrate you how easy it's going to be to work with next Js and now we're going to set up Tailwind so I opened up a documentation here don't worry we're going to type out everything together I just want to make sure you see this as well so I'm gonna go back into my terminal right here and for now I'm going to close this empty and run Dev and we're gonna run this so npm install Dash capital V Tailwind CSS post CSS and Auto prefixer great once that is that we're gonna run npx Tailwind CSS init p great and I'm gonna close the terminal for now and I'm gonna see what new files we have so first of all we have tailwind.config.js and we also have post css.config.js don't worry you don't have to learn any new languages here for now just open tailwind.config.js file and we're just gonna write this right here so we are not using the source directory if you remember from our setting up project so enter your content and just write exactly what's written here so Dash Asterix Asterix Dash Asterix dot curly braces JS comma TS comma jsx comma TSX and I'm just gonna copy that three times this time four pages and this time for components just like that we're gonna leave the theme uh and plugins the way they are right now we're gonna open this cyber again and I'm gonna enter my Global CSS which it should be in your stylus folder right here and inside I'm gonna write at Tailwind base at Tailwind components and add Tailwind utilities what this is going to do is is going to import Tailwind Styles so I'm going to open up my terminal one more time and I'm gonna run npm run Dev again and if you refresh you should see a completely different styling because by adding this Tailwind components you have actually reset your CSS so just uh for test we're gonna try and add the class name here for example text to excel text green 500. and just like that we have successfully added Tailwind CSS to our project great job great beginning all right so in this part of the tutorial we will be building the auth screen so just make sure you have your project running right here so just run npm run Dev if you haven't I'm going to close this for now and now we're just going to enter our Global Styles right here and I'm just going to add some styling so on our Global body element we're going to add add apply BG sync 900 we're going to give it a full height with the class h-4 and overflow x hidden because of some effects which we are going to be doing and now you should have this cool new Netflix background now on the next element we're going to Target an ID of underscore underscore next very important to have two underscores right here and we're just going to give it an y of H dash pool and in the end we're going to do the same thing for HTML so apply H dash pool like that we can close globals now and what I want you to do next is I want you to create a new folder inside this public folder create a folder called images and what I want you to do next is go into my repository I will leave a link into the description and all I wanted to do for now is go into the public folder right here into images and I want you to download hero and logo for now so open hero save image and I just want you to drag it into images and make sure it's named hero.ybj and do the same thing for logo so save image now let's drag it right here into images again make sure it's named logo perfect now we can go back here and I want you to create a new page inside this Pages folder and that new page is going to be called alph so just write out the DSX here I'm going to write const out I'm going to create a new function and I'm just gonna ask for default out like this and what I want to do now is I want to write a div element right here and I want to give it a background uh that consists of our newly image which we put right here uh hero that ypj so now that after you save this out consonant inside your pages you can actually visit it right here at local slash out great you shouldn't see anything because we haven't put anything yet what I want to do here right now is write the following class names so it's going to be a relative uh element we're going to give it the full height we're going to give it a cool width and we're gonna set a special background using this square brackets method so inside of here I'm going to write URL I'm going to open some brackets and inside these annotations we're going to write slash Images slash hero.ypj great and now you can see we have our hero here but it looks weird it's stretched and it's repeating right here as you can see so we're going to continue and write BG now repeat PG Center BG fixed and BG cover just like that much better looking now next we're going to do we're going to create our navigation with our logo but before we do that I just want to give a small black overlay over this whole image so write another div element open class name and write BG Dash black v Dash full so full with All Height with h-4 and on a large screens I want to give it an a BG Dash opacity 50. great now you can see it looks a bit darkened that's exactly what we want that's exactly what Netflix does as well next open the navigation element right here and what I want you to do is open class name and write px12 py5 and inside open an image element and the source is going to be slash Images slash logo.png and I'm just going to put an ALT here that says logo as well great now it's a bit huge so let's fix that by adding a class name of h12 just like that now it looks much much better now we're gonna write our um container which is going to contain uh the inputs the buttons and the other types of logging in so uh inside this div element write a class name of Plex justify Center and inside that open another div with a class name of BG black EG opacity 70. PX 16 so we want to put packing padding on the x-axis from both sides so left and right 16 by 16 as well Center we want this item to be centered we're going to give a bit of top margin here Now on LG or on large screens I want this to be a height of toothpicks because it just looks right that way on LG we're also going to put Max with MD we're also going to add rounded Dash MD and V equal great you can see our little element right here amazing now here I want to write a title so open up an H2 element right here and for now you can just write sign in you're not going to see anything the text is probably dark yeah so let's style the text in class 9 you should write text that's white text dash for excel mean mb-8 and phone semi-volved great now this is starting to look like something uh next let's go and write another div element this is going to hold our inputs right here so right class name Flex Flex call Gap or this is going to create a flux element which is going to go vertically and it's gonna space out the elements by value of 4 right here or one run great now um what I want you to do is I want you to create a new component right so create a new folder called components right here and inside uh we're going to write our input component so go ahead and write input.dsx for now all we are going to do is say const input we're going to return input as well nothing special and just ask for detailed in total like that and now what I want to do is I want to import this input right here so write input like that and it should Auto Import from here I'm using the add sign if you don't have the add sign you can use the uh dot abbreviation like this so dot dot components dot input but for me the add sign is working so I'm going to use that great now our input is uh here but obviously we need to style it so it looks like the Netflix input and we're actually actually going to add some cool elements here called floating label right so let's go back into our input right here and let's start writing some classes so I'm going to open up class name right here and I'm actually gonna open it like this so you can see better while I'm writing we're gonna have a lot of uh classes right here but trust me it's going to be worth it it's going to be a really cool element so first of all let's write block rounded Dash MD bx6 PT 6 BB 1 we're gonna give it a full width text MD so we're going to increase the text a little bit text is going to be white actually for that we're gonna have to put our BG to neutral 700 appearance is going to be none what is on Focus we're gonna write the outline on Focus we are also going to hide the ring like this by putting ring Dash zero and we're gonna add this very important class right here and that's going to be called here uh the reason for that appear is going to be like a neighbor to another element so I'm going to explain in a bit why we need this but make sure you have peer right here it's gonna make sense I promise uh and that's it for now we can keep it like that and one important thing to add here is add another attribute here called placeholder and I wanna I want you to give it an empty space so make sure not clear empty space that's very important and as you can see it's actually starting to look like something but as you can see it's kind of weird for some reason it's on the bottom but trust me that's what we want we just need to do a bit more modification here great so now I want you to go at the top of your input right here and just create another div and wrap everything inside of that great you can indent it a bit just so it follows the semantics and give it a class name of the relative like that nothing should change right now now we're going to write our label so open up a new element called label right here now let's hard code ideas so I'm going to give this input an ID of uh email right here and html4 is also going to be email just like that so email here and email here and now I'm actually gonna open up last names again like this just so you can see better and I'm going to write the following I'm going to write absolute I'm going to write text MD so it matches the text we're going to have text sync 400 we're going to set duration 150 that is the duration for our animations which is going to be really cool uh we're gonna add the transform class because we're going to do some transforming and now I'm going to write the following class minus Translate minus y minus 3. basically this means uh Translate Y minus three but since we cannot with Double Dash here uh the way you do it in Tailwind is you put it before the class name so if you hover over actually you can see uh how that looks it's a bit complicated so it actually didn't explain much yeah but that's how it works uh then we're gonna do scale 75 because we're going to do some scaling hang on it's going to be really cool top four Z 10 this is DZ index origin Dash open square brackets and write zero left six and now I'm gonna show you why the peer thing was so important so now we can write beer Dash placeholder and write make sure you write this double dot right here and uh sorry here placeholder Dash shown double dot scale 100 uh what this means is that it's going to trigger on this spear placeholder shown so this re this is really cool because we can modify this label element by uh interacting with this input element right here so we're just going to write a couple of more these peer classes and we're going to be done so right here Dash Focus sorry peer Dash placeholder again Dash shown so we're going to have two actions happen once the placeholder is shown first we're going to scale to 100 and second we're going to do Translate y zero and next we're going to do peer Dash Focus so once we focus an input we're gonna do some action here and that action is going to be scale 75. and last we're going to write here Dash Focus minus translate minus y minus three just like that and in the label you can just write email as well great so now we have our label here but once I focus you can see we have this cool hover floating effect right so I can write my name is here and you can see how our place our label is floating in the distance very very cool and now we're just gonna modularize this input a little bit so let's create our interface here so right interface input props and it's going to have an ID which is a type of string it's going to have only change uh which for now you can just put any value it's going to be type of string label is going to be type string as well and type is going to be optional uh and it's going to be type of string as well now go ahead and import react from react and we are going to assign these input props to this input component so react dot functional component open this pointy brackets and write input rocks great and now in this function parameters right here we can open curly brackets and write ID comma on change comma value comma label command type beautiful and now let's assign all of this so our ID is no longer hardcoded to email it is actually ID now uh and the same thing for html4 it is no longer an email it is now binded to our ID now for the value we're going to give it a new attribute here value this value type this type and change is on change great and now we're left with label so for label light here I'm just gonna write label now this should disappear of course and we are finished with the input component that's it you can play around if you want you can create your own effects maybe move this a bit change translate to four maybe scale it a little bit more whatever you want feel free to play with it but we can close the input for now great now I want to focus on this out component right here and you can see typescript is warning us that we are missing some attributes so let's go ahead and let's add them so um the label for this one is going to be email just like that the unchain function for now can just be an empty function uh let's give it an ID of email and let's give it a label oh we actually gave it a label uh already and type is going to be email as well and let's see uh what is missing value is missing for now we can just write an empty value great uh now you're going to notice that we actually kind of type in here so let's solve that um let's create a state for email right here so write const open uh square brackets email comma set email is equal to use state which you can import from react like this and we're going to keep the default empty like that and now we can actually put the value or email and on change we can change that by passing the event right here and we can write set email event the target.value like that and if we actually write we can change our value amazing now what I'm going to do is I'm going to copy this a couple of times so I'm going to create a new one here and this one is going to be called username is going to have an ID of name and type well we can remove that right now great so let's copy this and let's create the exact same one for username sorry the name so let's set name right here and just change set email to set name and value to name as well beautiful and now let's copy this one more time and create the same thing for password so label is going to be password ID is going to be password type is also going to be password and let's create the same thing again so password and set password right here great and change that email to say password great errors right here let's just fix them by saying that event can be any great now let's actually write our button right here so uh I want you to create I want you to go outside this last div right so after this input after this div I want you to write a button and we're gonna give this button a quest name of the following right so go ahead and write BG Dash red 600 ey3 text white rounded MD V who sorry W4 empty 10 and on Hover we want to change the color just a little bit so BG read 700 make it a bit darker on Hover and we're just going to add transition um this is a like a unique uh class name which just makes it a bit smoother and for now I'm just going to write uh login beautiful and you can see how we hover it's actually a changing color amazing um great and now after this I want to create a paragraph right here uh and I want to give it a class name uh or text Dash neutral that's 500 mt12 pick that and for now we're gonna write um first time using Netflix and then we're gonna open a span element right here uh that says create an account like that and we're going to give spam some special styling uh we're gonna give it a text white ml1 so a bit of distance and on Hover we're gonna add the underline effect and we're going to give it a cursor uh pointer just like that so now we have this message asking us if we are using Netflix for the first time so we can click create an account great all right so you might assume what's next and we want to create a toggle between login and register here so oh we're not using password Here uh make sure you're using the password uh instead of email in this last input right there great so now I'm going to go ahead and I'm going to create a variant toggle method so create a new state ratio called variant and set variant and by default uh we're gonna set that the variant is login so we're going to be able to switch between login and create our account next just create a method called toggle variant [Music] uh we're going to use callback for that so import use callback from react right here and we're going to do a very simple uh function here what it's going to do it is going to say set variant and it's going to use current variant callback function from here so current volume and all I'm going to do is I'm going to say if current variant is equal to login in that case I want to toggle it to register otherwise we can leave it at login like that and make sure you add the dependency array right here at the bottom great and now on this toggle variant we're going to use it in this span create an account button right so right on click and you can pass toggle variant right here now if you click on it not much is going to change but we're going to change that right this second so instead of signing right here we're gonna say if variant is equal to login in that case we're going to say sign in otherwise we're going to say create an account like that so if you actually click on it you can see that it changes amazing and I'm actually not going to write create an account I'm going to say register I think it's just better yeah that looks much better okay you can assume what we want to hide next so we have this username input right here and we actually don't want to show it if we are logging in so right variant equal equal register and right and the end oh sorry so open up the variant which is checking for register and end open your braces and just wrap the input inside of that so it should look exactly like this great so now if you click create account uh you can see that it toggles between showing username and not showing it great um now what I want to do is I want to change this button text so if variant is equal to login I want to show login otherwise I want to show sign up beautiful and last thing we have to do is we have to change this toggle actually right so if it's register we want to show a different message so uh let's go right here to first time using Netflix and we're gonna write the following so if Florian is equal to login we want to show this option to change by asking the user hey is this your first time using Netflix otherwise if variant isn't logging we want to give it a different text which is going to say already have an account just like that and you can close the curly braces great so you can see how different it looks right now and we have to do the same thing for this create an account thing so once again open the variant if we are in login we want to ask the user whether they want to create an account right because we are we are proposing an alternative option here but if we are in register we want to tell them an option to log in instead amazing and now you can actually play around and you can try to scale and you can see it's responsive right so how did we make this responsive actually it seems like we didn't do anything on purpose well we actually did uh by adding these classes as you can see uh languages Focus right here so in this div right here we gave it a default background of black but as you can see R is not default black because our has this BG opacity 70 right but what we did uh is we actually no actually we didn't do that yeah sorry I'm looking at the wrong button right here right so uh we gave the default uh background of black but on the large screens we add an opacity so the default is black but on large screens it has an opacity right here sorry for messing it up I was looking at the wrong element right here great I think we did an amazing job and in the next part what we're going to do is we're actually going to connect this to our database to our accounts and we're gonna add Google and GitHub login as well great job all right so last thing we did was we created this beautiful UI for our authentication what I want to do in this part of the tutorial is I want to connect that authentication using Prisma and mongodb so what I want you to do first is I want you to open up your extensions tab right here and I want you to install an extension called Prisma this is going to help you greatly when it comes to formatting and syntax highlighting of our Prisma schema files so just go ahead install and enable this extension right here great what I want you to do now is I want you to open your terminal and what we're going to write is the following we're going to write npm install Dash D Prisma after that I'm going to run a command npx Prisma in it what this is going to do is it's going to create an initial Prisma schema file for us so what you should have right now is this new folder called Prisma and inside you should have a Prisma schema looking just like this and as you can see we have some predefined values here such as postgresql and this environment reading variable first thing I want to change is postgresql to DB because that's what we are going to be working with great great job what I want to do next before we create our mongodb cluster is just create another package for Prisma so open up your terminal again and this time I want you to install and game install at charisma slash client we're going to use this to actually create a new deal which will interact with our database great so npm install at Prisma slash client just like that close this for now and what I want you to do is I want you to create a new folder called lib I accidentally have it here you shouldn't have it so create a new folder called lib just like that and inside create a new file called Prisma db.ts Prisma pb.ts just like that great now I want you to enter that file and I want you to write the following import Charisma client from at Prisma slash client which is the package we just installed now what I want you to do next is create a constant called apply which is going to be equal to the following now I'm going to explain why I'm doing this so just follow along for now global that Charisma DB type new Prisma client all right and I'm just going to write another if Clause right here if process that environment that node environment is equal to production sorry the production we want to set the global dot Prisma DB to client and in the end I just went with export default clients all right so why am I doing this why is this red um what the reason I'm doing this is because of next JS hot preloading um basically hot preloading means that on every code change our code updates and reruns uh what happens with Prisma in that case is that it creates a bunch of this new Prisma client instances right and then it you will get an error saying oh that's too much Prisma instances so what we do is we do a little trick which you can actually find anywhere on Google this is not something I invented this is actually a practice that is done where we save Prisma client in a global file Global files are not affected by hot reloading so that's why it works and in production uh we don't do that so we just make sure everything is normal so just make sure you have a file like this and now let's just fix this Prisma DB error all right so for that you're going to create a new file called global.d.ds [Music] and inside what you're going to do is you're going to write declare global namespace Global this and here you're gonna write War Prisma DB is equal to Prisma client all right now we just have to import this Prisma client so don't forget that you want to import original client from at Prisma slash client just like that and if you actually go back to Prisma DB you will now see that our typescript knows what Prisma DB is great what I want to do next is I want you to close all of this and I want you to go into schema.prisma what we're going to do now is we are actually going to fill this database URL you should also have a newly created.env file right here if you don't you can credit yourself but you should have it and in here as you can see I have this database URL link right now this is a template from Prisma this database does not exist and we are not using password SQL so we're going to go ahead and we're going to create our cluster which is going to give us this URL and I'm going to show you how to do that great so go into Google and you can write mongodb Atlas just like that click on the link right here and now you you're either going to have to create an account or sign in I'm going to sign in I already have an account I'm going to be using Google All Out which is interestingly something we are going to implement in this part of the tutorial as well so great you can actually see how it's going to look and now while I'm in here I will be greeted with this create a database so I'm just going to click build a database you might have a button in this corner or somewhere else but just find build a database button great now what I want you to select is the free option here it's called m0 for you it might be called a shared I think it's going to be shared something like that so just make sure it's free you should have a free option if this is your first time doing this so don't worry and it's probably going to select free options for you you don't have to choose any of this the cluster can be named cluster zero confirm that it's free right here one more time and click on create great now for username I'm just going to put Antonio and for password I'm also going to put Antonio when you're doing this for production I recommend that you use the auto generate secure password or any other method and make sure you click create user just like that and it's right here and for the IP address um it's probably going to add your IP address but you can click the button right here add my current IP address just like that and click finish and close go to databases and once this is done you can click the connect button right here now I want you to be very careful here there is a lot of options we can select from here I want you to click Connect using vs code the reason I want you to click that is because it gives you this kind of link that is supported uh in Prisma you could technically use connect your application but you can see the link is just a little bit different it has these special characters which might break Prisma so again click Connect using vs code and make sure the URL looks something like this just want to make sure you can see this all right so I'm going to copy this now I'm going to go back into my DOT environment file right here newly created and I'm going to replace this database URL with this link I've pasted make sure it's all in one line like this and as you can see here I have my username Antonio and I have my password right here so I have to replace this section with the password I've selected while I was creating my account right here right we have a password setup so I'm just going to replace this password with my password which is Antonio if you remember I recommended you do an auto generated password so just make sure you do something that you can connect with here and test is going to be the name of our database I want to leave that as it is for now perfect now I want you to go into schema.prisma right here and in here what we're going to do is we're going to write all of our models the reason why I want to write all the models right now and not why we need them is because modifying Prisma models and then pushing them to database and then modifying them again as we need might cause some trouble in this tutorial um yes that would be your realistic workflow while you're developing but for the sake of this tutorial I think it's just better that we write out everything at once and I'm going to do my best to explain the relations between each and every one of these models so we are ready to start let's write our first model called user and I started wrong so model user just like this Open brackets and first thing we need to Define in every model that mongodb has is an ID now there are many ways to write your ID but there is a certain way we have to write it using Prisma and mongodb combination and that is because mongodb uses a special type of ID called object ID so we're gonna have to write the following so string at ID at default Open brackets Auto Open brackets so kind of like executing this outer function right here and then we're gonna map Open brackets open annotations underscore ID and that is going to be a type of db.object ID all right I know this looks like much but what this basically means is that it is using the proper object ID uh type uh that mongodb uses in this Prisma orm uh if you're familiar with mongodb this is going to be familiar to you right so we're going to have to write this for every model but that's the most complicated line we're going to write so don't worry and I'm going to prove that by writing the next line which is name which is very simple string that's it now for the image it's also going to be a string but make sure you put question mark at the end that means it's optional we might not have it we might have it so make sure it's just optional otherwise it's going to crash if it doesn't have one next is email which is also a type of string it's also optional because we might log in with some other or out we might have a Google login GitHub login or something like that what's important in the email is that it is unique next we have email verify which is going to be a type of date time which is also going to be optional so just a question mark at the end next we have something called hashed password this is going to be for our credential login so email and password or username email and password right so you can assume that that is also going to be optional because if we use Google or GitHub to login we are not going to have this hash password great and now we have created that which is going to be a type of date time and we can use the default value of that so every time we create the user model we want to put the default value here of now great or the updated ads it's also going to be a type of date time but instead of us manually changing this updated app every time we modify the user we can use a really cool feature from Prisma which is at updated at which is going to do all of that for us great and now I'm going to write favorite IDs favorite ideas is going to be a list of our liked movies if you remember we will have a list of our movies which we liked and we're going to store those IDs in this field right here so name that string which is going to be it's going to actually going to be an array of strings and we need to specify what kind of strings and I mentioned it's going to be array of IDs so make sure you write at DB dot object ID at the end right here great and now I'm going to add two more fields and that's going to be it for the user model we're going to add sessions right here which is going to be a type of session but an array of sessions now it's going to underline this because we have not defined the session type yet but we're going to do that in a moment and you want to do the same thing for accounts so account and a little array at the end what we're going to do next is we are actually going to write this account uh model right here so go ahead and write model accounts and you already know what we're doing right now so you can just copy this ID from right here because we've written it once and it's exactly the same everywhere great and you can see that the underline just went away because we now created this proper account which has an ID so this ID is exactly the same as we've written here you can just copy that because we're going to copy it a couple of times so no point in writing it every single time uh now what I want to do is I want to create a relation between account and user ID and we're going to use that using user ID and we're going to set it to string and we're going to say add db.object ID so pretty much as favorite ID is right but without the array here so make sure it's not an array great now we're gonna have a type which is string we're going to have provider which is also string now we're going to have provider account ID which is also a type of string we're going to have refresh brush underscore token which is also going to be a type of string but it's going to be optional and make sure you write BB dot string right here now for Access token it's going to be exactly the same string question mark DB dot string right here so what is this model why am I writing it this is a model that will be created once we use our Google account or GitHub account that's why we need all of these fields which seem kind of weird but don't worry we're not going to complicate anything with these fields but we need all of them otherwise it's not going to work so next we need expires underscore at which is going to be not a date time as you might assume it's actually going to be an integer don't ask me why um I'm assuming they're using uh that kind of value easier made it for calculation or something and now we need token underscore type which is going to be a type of string which is optional as well we're going to need scope which is a type of string which is optional as well ID underscore token same thing and session underscore State same thing one thing I want you to do is I want you to go back to ID token and just add at VB that string here as well make sure you don't forget that perfect and now just two more things we're gonna add here I promised uh and that is you see we created this user ID relation here and we are using accounts in this user model so we have to create a relation between the two manually and the way we're going to do that is we're just going to write user user as in our user model add relation open up these brackets and write fields array of user ID comma references is going to be again an array of ID this time and one thing we're going to add is this on delete skate so what does this mean well we are connecting our user model with our account model using the field called user ID which is going to reference to user ID right here and on the lead is just a method we are describing what we want to happen once this user is deleted what do we want to happen to this model account well obviously we want to delete it as well so that's what this function does and last thing we're going to write in this account is going to be at at unique open the brackets open square brackets provider comma provider account ID nice and now we can write our session function right here so model session model session again you can copy the ID either from account or from the user you can see it is exactly the same so write that here and what I want you to do right next is session token section token is a type of string which is required and it is going to be unique now again user ID is going to be string at db.object ID so same thing as we did right here it should be exactly the same great and now we're going to set expires and this time to your surprise it's actually going to be date time so yeah it's not exactly consistent but again we are not controlling this session or this account these are a fields for next auth all right and now just like we did here we have to do the same thing here so I'm going to write it one more time because it's complicated I don't want to copy it so user user at relation Open brackets fields user ID comma references ID on delete Cascade so exactly the same as above but I just typed it one more time for you in case you missed something it's important that this is correct all right now we have to write another model here and this one is going to be called Model verification token all right now you can already expect we need an ID so let's do that let's write an ID right here next thing we're going to need is an identifier so identifier is going to be it out of string very simple token is going to be a type of string as well but it is going to be unique and expires is gonna be date time and in the end just write add add unique and inside the square brackets write identifier comma token just like that and finally our last Model I promise no more scheme of writing you're doing a great job so far I know this is a bit of a Hustle but we have to do it model movie again can you guess what's next if you're right we need an ID so copy that as well write a title which is going to be called string sorry it's going to be a type of string description which is going to be a type of string as well video URL which is going to be a type of string as well thumbnail URL again a type of string genre or genre type of string and duration a type of string what is going to be duration well duration is literally going to write something like 15 minutes so that's why I put it as a string um you can kind of play around with this if you want to add I don't know maybe rating of integer you can do that but for now I suggest you just follow exactly what I do um but yeah this is our movie model we are the one generating this so don't worry you can kind of mess up here if you want just make sure you remember what these fields are correctly great we have written out the entire Prisma schema amazing amazing job so far all right what I want you to do now is I want you to open up a terminal and you will write the following function right now so I'm just going to quickly go back into my database right here to show you something so if I browse collections right now uh nothing will happen here because I have no collection so far but we have just created a couple of collections right here and we're going to run npx Prisma DB push amazing and now if I actually refresh this guess what we have account we have movie we have session we have user and we have verification token amazing amazing job we have successfully connected our Prisma with our mongodb don't close this we're gonna need this I suggest you keep it throughout your tutorial or you can just go back to it but for now I'm just gonna roll back into this out screen right here great what I want you to do now is I want you to go into pages into API here you will have a little hello uh file which was left over from our next GS initialization and if you actually want to see what's here you can write slash API slash hello I'm sorry you cannot do that why because we have not started our project so make sure you go into your terminal and actually run mpm run Dev right here so the project is up and running my mistake about that and guess what so you can actually visit slash API hello I'm not sure if you can see this but it's slash API slash hello and you can see exactly what's written here if you change it to John wheel 2 guess what uh if you refresh it's gonna be right here as well all right now let's go back to localhost 3000 slash out this is the screen we are at localhost 3000 slash app and you can actually remove this hello from the API right here and you're going to create a special name file Open brackets and you're going to write dot dot dot max out sitebrackets.ds just like this this is going to be a specially called file which is going to be recognized from our next app great now we're going to write our next of middleware right here so before we begin I need to install some packages again so I'm gonna close this again and I will remember to start it this time so just right for now npm install next dash out just like that all right we're also going to need another uh a file right here so and then install big credit Big Crypt we're going to use this for um credential authentication you're gonna see why we're doing that in a second all right great you can uh close everything for now so go ahead and import next out from next dash out like that and now I want to export the code next out like this Open brackets and open uh curly brackets and inside I wanna I wanna write a attribute called providers right and inside these providers I'm actually going to write credentials you can click enter and it's gonna Auto Import next out Dash providers Dash credentials if it hasn't Auto imported make sure you have to import this all right so you're gonna open up an object in that one and we're going to give it an ID of credentials this idea is important because it's going to Define how we're going to call this in this out page right here that we have so ID credentials name is also going to be credentials uh and now we can actually write an object credentials to Define which credentials we need and for that we're going to use an email which is a uh it's gonna have a label called the email and type is going to be text and next credential is going to be password [Music] so you can write label logically password [Music] and type is gonna be password [Music] all right and now what we're going to do is we are going to write okay just for now I'm going to do I'm going to try and disable this okay that's not it okay we're gonna have to make do with this uh Reds right here all right so after this credentials object I want you to write authorize oh that made the red go away beautiful now what is this authorized function well we're not actually going to write it like this so what you want what I want you to write is asynchronous authorize [Music] like this this is what I want you to write now this authorized function is going to accept credentials what we're going to do is first we're going to check whether we have credentials or not so if credentials that email is missing or if credentials that password is missing we're going to throw new error which is just going to say email and password required great and now what we're going to do is we're going to find the user using email so honest user is going to be equal to a weight and now we have to finally import our Prisma DB so right Prisma EB and make sure you import this so it's not going to throw any errors the reason it's not throwing errors is because we defined it in global right here but make sure you import it how do you import it well very simple import reasonably from at Dash lib if you're not at that slip slash prisoner DB if you don't have ADD you can use dot dot so just make sure that it's working I'm going to use add because it's simpler if you're wondering um where did this prison DB come from uh well from here we create it right here now I noticed a mistake right here I'm not uh using the proper capitalization so make sure you import next out and capital a capital just like this my mistake all right now we're gonna write await Prisma DB dot user you can see how it autofills our user because it knows the model amazing and we're going to write find unique open an object and now write where and we're going to write email is equal to credentials.email perfect so now it's going to find our unique user what I want to do now is I want to check whether this user actually exists right so if there isn't an user or if there isn't user that hash password I want you to throw a new error which is gonna write email does not exist like that and now we're going to do a very simple check to see whether the user written password is correct so const is correct password it's going to be equal to a weight compare now compare is going to be an import from Big Crypt so just go in here write import compare from be Crypt like that now we're going to compare the following values open the brackets and compare credentials that password and compare user with hashed password just like that and okay I'm just gonna collapse this so you can see more nicely what I'm doing all right and now uh if it isn't a correct password we're going to throw another error through new error incorrect password so one thing I want to bring your attention to is this uh uh exclamation sign right here so if you write it like this it's always going to throw indirect password even if you enter it correctly so make sure you write an exclamation before this right so we want to check if the password is not correct amazing very very good job and very simple if the password is correct what we want to do in the end is we want to return user write this user right here which we found using unique email great amazing all right now I want to go to the end of this array of providers which we just opened right here and write a new attribute called pages and in here I'm just going to Define our sign in page it's going to be slash why slash out well because that's where we created this out page ourselves great we have the pages and now we need this is going to be very useful so just write debug process that environment that node environments is going to be triple equal to development so we want to debug it to be on if we are in development this is going to be very useful because you will actually see any errors or any logs in your terminal I promise it's going to be very useful especially in development next we're going to write session now session is going to have a field called strategy and in this strategy uh for my case I'm going to use jvd and I recommend you do the same especially if you want to follow this tutorial so you can modify this you can use different salaries but I'm going to use jvt right here great and now before we write the last two fields we actually have to go into our DOT environment file at one more time right here and what I want you to write here is next of jvd secret for me it's going to be next jvt secret like this and we're going to need another field called Next out underscore Secret and for me that's going to be next underscore Secret so just make sure you add these two new environment variables so next out the jvd secret and next Out secret they are going to be very important and we definitely need them especially uh in the end when we will be doing a production all right so last two Fields here jvt which is an object which has a secret and the secret is going to be process that environment that next out [Music] underscore jvt underscore Secret so make sure this is the last field it's not inside this jvt anymore last field process that environment that next out underscore Secret [Music] beautiful just like that you have completed the entire next Alpha all right uh we don't have types for bcrypt so we're gonna fix that real quick opening up your terminal one more time and just install npm install Dash D at types slash bcrypt and now the error should go away great great great job and now what we're going to do is we're actually going to create some authentication right here so you can close everything up just make everything clear and go back into your pages into your alph right here and now we're going to create uh some login and register functions so before we are able to log in we want to be able to register first so let's create that factor function first const register and open up use callback and make sure it's in asynchronous fallback right here and make sure you write your dependency array and I want to just I want us to use a specific Library called axios because I just think it's the easiest to work with so right npm install axios let's just check if we have our types so import access from axis all right it seems that we have the types and make sure you run npm run Dev to actually move your project here you know I often forget to do this so just refresh to see that it's working it's working amazing all right and now what I'm going to do is I'm going to open the try and catch block right here let's solve the error first so if there is an error all I want to do is console log error for now but in the try uh block what I'm going to write is a weight axis the post slash API slash register great and in here uh in this body element I'm gonna send a couple of builds email name and password great now if we try and run this it's not going to work at the moment the reason it's not going to work is because we have not defined this API slash register controller so we're going to do that real quick it's going to be pretty similar to what with this in the in this next authorized function so go into your out uh sorry into your API and create a new file called register.ps and in here what I want you to do is I want to input and decrypt again from liquid I want you to import next happy request next copy response from next I want you to import Prisma DB from at Libs at slash lib slash Prisma DB again if you cannot use ad just try dot dot dot dot whatever works for you just find the package and now we're going to export our Handler so expert default synchronous function called Handler it's going to have a request which is a type of next API request it's going to have a response which is the type of next API response [Music] and open up the function and inside here I'm going to open um sorry I'm not going to open anything first thing so first I want to limit this Handler to a post call so go ahead and write if requested method is not equal to post we want to prevent anything for to do with this so just write return response that status 405 with n basically what this means is that we only want to allow post calls to this slash API slash register route all right and now we can open our try and catch block and as always let's just uh handle the error so for production for development I just want to log the error here I'm going to return response status 400 and in the error all right now in the try block what I want to do is I want to extract some values which we will need and those values are going to be email name and password and we're going to extract them from request.body and now I'm going to find an existing user using this email you might be wondering why am I looking for an existing user in a register function well we want to check if an email has been taken so write const existing user is going to be away Prisma DB dot user dot find unique open an object right where and just write email just like that this is a shorthand for email comma email right but we can just write email like this if there is an existing user we just want to write response we wanna sorry return response status 42 the Json with an error email taken like that beautiful and now we're going to Hash user password so const password is going to be equal to a weight bcrypt dot hash password 12. so make sure this is an await function because it is asynchronous if you remove the await it is not going to work properly and lastly we want to save this hash password into a new user model so right const user is await Prisma DB dot user dot create [Music] and in here we want to give it some data that data is going to be email name hashed password image which is going to be there's an empty string for now and email verified which is going to be new date beautiful and we want to return return response status 200.json user just like that amazing amazing job you just wrote your first API route and now we can go back into our out Pages file right here great and what I want you to do now actually is I want you to fill this dependency array with email name and password because we need to be in sync so email name platform right here so when are we going to call this register function where we're gonna call it in this uh button right here sorry right here so uh as you might guess we will not always call register uh because depending on the variant we will either call login or register but for now you can just click register like this all right I think it's time to test if this works so I'm just gonna um all right I'm just going to open my network tab right here I'm going to click create an account I'm going to give a username of test I'm going to give an email of test gmail.com and the password of one two three three two one and I'm going to clip it sign up you can see we have successfully called our register function and we get the status to 100 which means if we look at the preview and response we have successfully created our first user amazing job our authentication is working good job and now I want you to go into this mongodb Cloud right here and click refresh and if you go into user you will actually see our first user along with the hashed password amazing amazing job you have successfully completed credential authentication good job now next challenge we have to do is the login so the way we're going to login is we are going to um we're gonna import a function [Music] called sign in from next at sorry from next batch out slash react great sign in just like that and now I want you to create a login function so go ahead and hit const login use callback and just as register is going to be nsynchronous callback make sure you can spell a sync open the dependency array and write email password only email and password because those are the only things we're going to need in a login route for now and what I want to write here is I want to open a try and catch block if there is an error I just want to say console error here and in the try block I'm going to write awake sign in now what type of signing do we want to use well if you remember in our next out we have defined an ID for credentialist called credentials so that is the ID we want to use in this sign in credentials and we're going to give some value to these credentials and the value is going to be email it's going to be a password and now we're just going to give it a a custom modification field called hero redirect pulse callback URL slash amazing and now we're going to try login so we're going to copy this login function right here and in this on click register we're going to modify the bit so we're going to say Orient is log in in that case I want to use login otherwise I want to use register but I misspelled Orient so just make sure you spell it correctly great and now if I log in correctly I should be actually getting redirected to our slash to a root route but I'm just going to open a Netflix here I'm going to click on preserve log just to see if everything's working so fast gmail.com one two three three two one login all right something went wrong all right so I found our mistake I found like this isn't working uh it's my mistake I'm really sorry so we're gonna go back into code it's gonna be a very simple fix um we have this next Alpha file right here but we have not created it in a proper folder so inside this API folder we need to create another folder called alph and I just wanted you to drag and drop this next out into this new Alpha folder so your next out should be inside API inside app great let's try this one more time so I'm gonna clean everything here I'm gonna go to slash health and I'm gonna try our email and password that's the gmail.com one two three three two one amazing just like that we have successfully logged in and now uh I want to add I redirect it to the slash route so what I'm going to do is I'm going to go into out.dsx again make sure you are in auf and we're going to import router from next router so constrada it's going to be used router from next slash router like this and this router is a hook which exports router right here and what I want to do is after successful login so after we await and log in I want to say router that push slash right here and we're gonna have to add router to our dependencies right now all right and one more thing I want to do is after we successfully register I also want to log in so after a way to register I'm just going to write login as well and we have to add login to our list of dependencies as well and just make sure you define login before you define register like that amazing so I'm going to try one more time test gmail.com one two three three two one and as you can see I'm redirected to the Netflix clone amazing alright so now I want to show you how easy it is to add Google and GitHub login so first thing I want you to do is I want you to import a new package called react icons so we're gonna install that package right now in our terminal npm install react Dash icons we're going to use this to add cool icons such as Google and GitHub and other icons we're going to need in the project so make sure you have this package right here and first we're actually going to write the UI for this so make sure you are the localhost 3000 slashed out so you can see the out screen and of course you have to have your project running for that and once this loads what you're going to do is you're going to import the two items you're going to import FC Google from react Dash icons FC and you're going to import fa GitHub from react Dash icons slash fa just like that and now we're gonna scroll down all the way below our login button and we're going to create a new div right here and this div is going to be our container for the buttons so we're going to write Flex Flex row items Center Gap 4. empty eight justify Center and for now you're just going to see a bigger space here and now we're gonna add our button elements so open up class name and you're going to write the following it's gonna have a width of 10 height of 10 is going to have a BG white and now we get a little square here so let's making let's make it a circle with rounded round that Dash pull like that now since it's going to hold an icon we want that icon to be centered so we're gonna say Plex items Dash Center justify that Center nothing should appear now I want to add a cursor pointer this so I'm gonna write cursor Dash pointer because I want it to behave like a button great and I'm just gonna add a hover effect opacity 80. and I'm gonna add the last class transition which is gonna just delay the effect a little bit and now we have a nice hover effect great and inside that div I'm going to import F A sorry FC Google icon just like that and we'll have our Google icon here I'm just going to increase it a little bit by 30. so right size 30 and it should look really nice and now we can copy this whole element along with the icon and now we're going to have two Googles but we want one of them to be f8 it's up great what I want you to do now is I want you to go into your environment file and add some new environments so go ahead in your environment file and we're going to need a couple of new items so right Gates cup underscore ID GitHub underscore Secret Google underscore client underscore ID and Google underscore client underscore Secret just like that and now I want you to go into Pages API out next out right here and we're gonna add two types of providers like we did for credentials we're gonna add Google and itlab and we're going to connect that with a Prisma provider below this debug right here so go ahead and import GitHub provider from next dash out slash providers slash hip show and also import Google Provider from next dash out slash providers slash Google great now let's add GitHub provider and let's open the options here and we're going to write client ID process dot environment that gipshop underscore ID and for the client Secret I'm gonna write process.environment that gives up underscore C2 and just to fix the typescript errors I'm gonna pipe and add an ND string like this you can copy this entire thing and paste it below and rename to Google provider right here again make sure you have both Google and GitHub provider Imports right here I'm going to replace GitHub ID here with Google underscore client underscore ID and GitHub secret with Google underscore client underscore secret great before we move on I want to open Terminal again and I need to install another package here we're gonna install npm install at next dash out slash Prisma Dash adapter I know it looks similar to this but this is a separate package which we need great make sure you run the project again and now you're gonna import Prisma adapter from at next dash out slash Prisma Dash adapter just like that and now you're going to scroll down below your debug and you're going to add adapter Prisma adapter and you're gonna put prismac DB inside the parameters Prisma DB is imported from here already and we are using it in this authorized function right here amazing job all right now it's time for us to actually get these buttons to do something so I want you to create GitHub authentication first so we're gonna go ahead and grab GitHub ID and GitHub Secret so go into your GitHub account and I want you to go into the menu right here and go into settings I'll launch Discord all the way down and click on developer settings in here I want you to select all out apps I have a couple of those uh you can just click on new or out app which is exactly what I'm going to do name your application whatever you want so Netflix clone video home page URL is going to be http localhost 3000. and I'm going to copy that for the authorization callback URL as well why localhost 3000 well because that's where we are running the application in production obviously you're gonna have to change it to whatever your domain name is and just click register application great and now we have our client ID so go ahead and copy this and paste it right here and to get the GitHub secret you're gonna have to click on this generate a new client Secret alright once it's generated make sure you copy it right away and paste it here because if you refresh your screen it's gonna go away all right so now we're actually going to enable this GitHub button so go enter out right here and we're gonna write an on click function for our GitHub div element all right so right on click and write an arrow function which is going to call sign in what type of sign in well gitstar and we're just gonna open up the options object and in here I'm going to write all back URL which is just going to be slash just like that and we can try it out now if we click on GitHub it is asking us whether I want to authorize my Netflix Dash clone Dash video with my account and once I click authorize I'm being redirected to my application and just like that I'm logged in and now let's go into our cluster into our account and see if we have a new account and we do we have a GitHub account which is connected to our user ID and as you can see we have a new user generated here with my GitHub image as the image amazing amazing job and now let's do the same thing for Google great so for Google it's a tiny bit more complicated but don't worry it's going to be very simple go ahead and write Google developer console right here in here I'm not sure if you're gonna have the exact same screen that I'm having what I want you to do is I want you to click on this option right here or just find a way to create a new project name the project whatever you want for me it's going to be Netflix clone video tutorial it can be whatever you want for you you can leave this at no organization and click create wait for a second till it gets created alright once it's created make sure you're actually using it right here so go into this navigation right here and make sure you are using it great what I want you to do now is I want you to go into this search and write in API once you write an API click on apis and services great now I want you to go into oauth consent screen in here I want you to select external and click create for the app name I'm going to put Netflix clone video tutorial you can put whatever you want for the user support email I'm going to select my email you can leave all of this empty for now and just put your email in the developer contact information below and click save and continue now on Step 2 click save and continue again step 3 save and continue and that's it now I want you to go into credentials on the sidebar right here and I want you to click create credentials right here and select all out client ID application type is going to be web application name can stay the same you can leave the authorized JavaScript Origins empty and just click add URI for authorized redirect Uris and in here you're going to write HTTP localhost 3000 but you're not going to leave it like this like we did for GitHub we have to add slash API slash out slash fallback slash Google great and click create and just like that we have our client ID and client secret so go back into your code and open Dot environment file and in here copy the client ID paste it here and copy the secret ID and paste it here as well do not share this with anyone I'm going to delete this after the video but just for now I can share it with you great now go back into your out file and we're going to add the same login on click for Google so just make sure you are at slash Health one more time and in here I'm going to add the same on click sign in but I'm going to modify GitHub with Google the Callback can stay the same and now we can test Google out so let's click and just like that it's asking us whether we want to log in with this email and there we go we have successfully logged in both with Google and with GitHub amazing amazing job and I'm going to check my accounts and as you can see I now have a Google oauth and GitHub or out if we look at users we can see that they still have only two accounts that's because I'm using the same email for GitHub and Google login you might have more accounts here great great job you have finished authentication entirely all right so now I want to show you how we can protect our client routes and our API routes as well using this authentication we've created so make sure you have the projects running and we're going to create a lib so open your sidebar and inside this lid create a new file called server out that's DS in here you're going to import next API request on next and you're going to import get session from next dash out slash react and in here you're also going to need Prisma DB instances so import Prisma PB from at slash lib slash Prisma DB one more time if you don't have ADD if this is not working for you you can use Dash Dash and stuff like that all right and now let's define server out it's going to be an asynchronous function which is going to accept one parameter and it's going to be a type of request and that type is next API request in here I'm gonna fetch our logged in user session and we're gonna do that using this get session so const session is await get session and it needs to accept an object which accepts our request right here so make sure this is an object which accepts our request so the way this is going to work is we're going to use this server out in our API controllers and we're going to pass the request parameter and that request parameter is going to hold the jvt token which this get session can then use to get our logged in user now the problem is this session doesn't have all the fields we need for example we need all of the fields that we have defined in our Prisma so we need ID name image email and stuff like that but our session is something else our session does not have all of these fields so that's what we're doing this so we can use the session to get other fields great so now we're going to check if the session exists so I'm going to check a bit more I'm going to say if exclamation mark session user email so if session or user or email doesn't exist we're going to throw new error which says not signed in like that great and if it exists I'm gonna fetch the current user so const current user is going to be equal to a weight Charisma DB that user that bind unique open an object and write where open an object again and write email is equal to session.user that email like that great and now if we don't have the current user in that case we can also throw new error which says the same thing not signed in obviously the jvt token which we got or the session which we got is not correct maybe the user was deleted at the time so we need to check whether we are able to fetch the user using this logged in session user email great and we're just going to return an object here which is going to hold current User make sure this is an object great and Export default server out just like that great now we have this server out which we are going to use in all of our API routes to check whether we are logged in so we don't have to type this many times all right you can close your lid now and you can go into Pages API not out just API and in here I want to create a new file called current the DS great so make sure it's in API current not in out it's right next on the same level as register like that great in here you're going to import next API request next API response from next and you're going to import This Server out which we just created so server out from add slash lib slash server out one more time if this is not working for you you can always use stuff like this but I'm using add because it's just simpler for me great and now we're going to export default asynchronous function which is going to be named Handler and it's going to accept a request which is type of next API request and it's going to accept response which is type of next API response great open the function and first we're going to limit this function to only get request so right if request that method is not equal to get in that case we're going to prevent this call from going any further and we're going to write return response status 405 which means wrong method and just end the call great and now we can open our try and catch block inside catch we're just gonna log the error production sorry for development and we're going to return response status 400 and end the call because something went wrong great now what I want to do is I want to fetch our current user and how can we do that well we just created this beautiful server out you little which Returns the current user here so we're gonna do exactly that go back into current go into the try block and write const open an object current user is equal to a weight server out and what the server out need well it needs the request like that amazing and all we're going to do is say return response status 200 that Json current user why are we not checking if this current user exists first well because we did all of that in our server out if there is no current user we're going to throw an error and this error is going to be caught right here and we're going to see it logged in our server great so now we have a new route which is going to be localhost 3000 slash API slash current because we defined it right here amazing amazing job all right now I'm going to create another lid which we are going to need for our front-end fetching so create a new file inside this lib folder and call it patcher.ds we're going to use this for react svr so I'm going to use axios for this and we already have axios imported from our auth uh view so import access from axis and just Define the fetcher const Patcher that's an URL which is a type of string and all it does is it triggers axes that get URL and on success it gets the response and just return response to that data that's it export default better beautiful save the file all right and now we're going to create our use current user hook which is going to be used in the front end so we can load the current user so create a new folder called hooks great and inside hooks a new file use current user.es great now we're gonna have to install a new package so open your terminal right here and all you're going to do is npm install svr great make sure you run the project again and import use as we are from svr like that an import Patcher from at slash lib slash Patcher like that and now let's define this use current user Hood so const so const use current user open an object and let's just initiate this svr const which is going to have data it's going to have an error it's going to have this loading and it's going to have new date and we're going to get all of that from use as we are the svr is going to point to slash API current because that's the endpoint we just defined and it's going to use fetcher great so what is svr svr is aversal uh developed package which is really good at fetching data it is something similar as react query so basically what the first time we fetch this API current no matter where we use this hook it is not going to fetch it again if the data already exists basically this way we don't need Redux or any state management for fetching our user which is a really really cool feature and all we're going to do is return all of this right here so I'm going to write return data return error return is loading and return mutate just like that and make sure you export default use current user like that great and now I'm going to show you how we can protect our client routes so right now we can visit localhost 3000 right but we do not want to Able uh we don't want users to be able to visit this if they are not logged in so what I'm going to do is I'm gonna go into our index TSX pages so going to Pages going to index DSX this is the page so Netflix clone one right if I change the text to or Excel this is going to change because we are on that page great and what I want you to add is I want you to create a sign out button from here first so go into import and import sign out from next dash out slash react and we're just going to add a small button here which is going to say log out and on click it's going to call sign out like this great and just let's give it some classes for class 9 B10 uh sorry h10 V o and BG white for example okay just so it's a button we can see great and now I want to show you how we can actually protect this home route right here all right so we're going to add an asynchronous function here and we're going to export it so export I think function get server side props it's gonna accept contacts which is a type of next page context which you can import from next right here all right open the function and in here we're gonna fetch our session but on the client side so we cannot use our server out I know you're thinking maybe we can use our server route no we cannot because this is the client this is separated from that but it's much easier on the client anyway so we're just going to write advanced session oh wait get session from next dash out slash react so the same way we imported sign out is going to be await get session right here and we're just going to paste in context from this parameters right here and we're going to do something if there is no session available we're going to return an object which returns a redirect object which just says destination slash out and one more field permanent false all right and make sure you also return outside of this if block we always need to return something from get server-side props and if session exists it's not going to return anything so we have to make sure that we return an object we just empty props like this great all right so this is already actually working what it's doing right now is it's checking if available session exists and if it doesn't it's going to redirect us to slash out so if I actually click log out here you can see that I'm redirected to slash out amazing and if I actually try and go to localhost 3000 slash it brings me back loud I can no longer access this amazing but if I try my GitHub login for example all right so I was trying to log in and I actually wasn't able to so in case you are getting the same problem in case you cannot log in I want you to go into your terminal and you are probably going to see some errors Like This Server selection timeout no available servers you can see that I kept getting those errors service selection timeout no available servers I did understand why this happened I thought we maybe did something wrong but in fact we did not so I'm going to show you what you have to do go into your um a mongodb cluster right in this screen and go into network access right here on the side and you can see I have my IP address added here but I have a dynamic AP so every time I actually like reconnect to my Wi-Fi and stuff it changes so it completely forbid access to me so just click add IP address and for now I think it's easier to maybe allow access from everywhere so 0.0.0.0 or just click allow access from anywhere and click confirm all right now that it's active I'm gonna go back into my out and I'm gonna go back into my terminal and all I'm going to do is I'm going to start the project again so maybe you don't have to do this at all if you're able to sign in just go ahead and try and Google and GitHub as well if it works then perfect you have a static IP but I accidentally uh added my own IP address here so it forbid me from accessing to the new one that I have right now and I'm going to try and sign it with my GitHub account for example and as you can see I'm actually inside my slash page which I can only access if I'm authorized so if I try one more time and log out I cannot see the slash screen amazing right so I'm gonna just gonna log it back in again so we can see the screen great amazing and now I'm going to show you how we can fetch our user using our use current user hook which we created here for the front end so go into your index file right here and inside home I want you to write const open an object and we're going to use use current user like this and we will import use current user from our at slash hooks Slash use current user again if you don't want to you can just use dot dot like this just get the use current user and in here remember we're gonna have data right and we can create an alias for this data so just put a double dot right here and name it whatever you want in my case it's going to be user great and now what I can actually do is I can actually write a paragraph right here which is going to say logged in as and I'm just going to write user that name for example sorry you have to add user make sure you have this little question mark right here and of course let's now add some color text White and there we go logged in as Antonio which is my name I can also check maybe email logged in as adults dot Antonio gmail.com amazing and if I try and create a new user for example so test name test at best.com and a password and I create a new account and there we go logged in as test at test.com amazing amazing job and now we can actually go in and create our profiles screen great so close all of this up go into pages and create a new screen called profiles that DSX great and for now I just want to write honest profiles and just return a div like this and for now I'm going to write a paragraph here which is class name text white text or Excel which says profiles all right and Export vehicle profiles and now you can visit localhost 3000 slash profiles and there we go we are in our profile so again why is this working why can I just use slash profiles because it is in our Pages folder on the same uh uh directory as auth index profiles and stuff like that great and now go ahead and write export async function get server side rocks we're gonna accept context which is going to be a type of next page context which you can import from next right here on the top open the function and you already know the drill so we are going to get session using away you get session from next out slash react and make sure you add the context to the get session function I forgot to do that and I'm going to do it in a minute if the session does not exist what we're going to do is we're going to say return redirect destination slash alph permanent boss and just remember we always have to return something in the end so return an empty procs just like that all right and now if we try to sign in actually before you try and sign in just make sure that in these profiles get server side props you're actually using this context and pass it in get session right here great and now I'm gonna go back into my out file and I'm just gonna sorry I changed some stuff but I'm gonna bring it back all right so I want to redirect to slash profiles instead of the standard callback URL so you can actually remove this router that push here you can remove the router from the login right here and callback URL just change it to profiles and remove redirect false like that and you can remove use router from here and you can also remove the import all right so this is how your login should look like now login use callback all back URL slash profiles and just remember to also go down and we have these two sign-ins with Google and GitHub and they use callback Euro slash so just make sure you change those to slash profiles as well all right great and now if you actually go ahead and try and enter your profiles it's going to redirect you out but if I log in and redirected to profiles amazing so go into profiles and now let's create our profiles what I want you to do now is I want you to go into my GitHub for the next Netflix tutorial right here and I just want you to go into public and images and I want you to pick one of these default blue default green default red or default slate I'm going to choose default blue and I just want you to download the image since we're going to use that as our default user image great and I want you to drag and drop it into your public images the same way we did with hero and logo in the beginning if you remember right so we have default blue that PNG right here great now go back into profiles and we're gonna do some styling now alright so in this main div I want to add a class name of flex let's sorry Flex items Center H that full and justify batch Center and we can remove this text for now so open another div inside which is going to be last name Lex Flex oh it means column and now we're going to write H1 and H1 is going to be who is watching and inside I want to have a class name of text 3XL on MD I want to have text Excel text white and text Center like that this is already looking familiar just like Netflix great and now we have to add the actual icon below that so create a div and this is going to be our container for our profiles so write Lex items Center justify Center Gap 8mp 10. all right and now you should just see how this text moved up a little bit but nothing yet great create a empty deep here for now which is gonna have an on clicked button right here which is not going to do anything for now all right and in here we're gonna style our actual profile rectangle so create a div and write class name group group is a similar class name to peer which we had in operation of our input so I'm going to explain it in a bit for now just write the group Black slash row with 44 MX outer inside you're going to create another div we're just gonna have a number of class names here we're going to add some cool hover effects here so in here write V 44 w44 h44 it's going to be rounded and the and next class is going to be Flex items Center justify Center order two order transparent and now on group dash power which means when we hover on this parent element right here we want to change some stuff here and that step is going to be cursor pointer it's also going to be group it's also going to change to border White and we're also going to add one more field overflow even like that all right now you're probably weren't going to see anything here either but now we're going to add an image and you're going to be able to see so add an image element and the source is going to be flash Images slash default Dash Blue Dot PNG and just like that it's right here and you can see when I hover I get a cool little white border and for all you can just put profile great great great job and all we have to do is add our name below here so below this div just write another div which is going to have a class name of mt4 text rate 400 text to excel text Center group Dash hover text white great and for now I'm just going to write name great so now when we hover you can see the name is also highlighted great now how do we actually fetch username well we already know how to do that thanks to what we tried in our index uh right here so we're going to do the exact same thing in profiles right cons open an object data which is going to have an alias abuser from use current user like that and you can import current user from add slash hooks use current user that is located in our hooks folder right here and now that we have our user we can actually replace the name with user question mark dot name and just like that I'm new user that's what I named my profile amazing great we are pretty much finished with our profile screen all we want to do is we want to redirect to the root slash on click so we're going to do that now I'm going to add funds Browder use router from next slash router right here and all I'm going to do is on click I'm going to write router that push sludge just like that and if I try there we go I'm logged in and if I log out I'm taking you out great job all right so in this part of the tutorial we will be implementing our navigation bar inside our app so go ahead and just log in in your app again and make sure you're in this index homepage right here so we're actually going to clean this up a little bit so let's go into index.tsx and we can actually well remove all of this here for now we don't need the current user and we won't be signing out using our home page instead what I want to do here is I want to import one component which we are going to create in a moment called navbar like this right now it doesn't exist so let's go into components and let's create a new file called navbar.bsx great for now I'm just going to write navbar and it's going to return a div which is just going to say uh number for now and Export the bulb enough bar like that and now go back into your index file and just import this number from add slash components slash navbar which we just created right here great all right and now let's do some work in the number section so in this main div container we're gonna give it a class actually we're not going to call it div we're going to call it nav because it's a navigation type great so class name vw4 so we use the full with we're gonna make it fixed so it sticks to the top even when we scroll and we're going to give it a z index of 40 because we want it to be above other things great all right now we're going to create another div right here and let's give it let's open up class names and let's start writing some classes so I'm going to give it uh an x-axis padding of four on bigger screens I'm going to give it a px 16. I'm going to give it a py six it's going to be a type of flex element it's going to be a row Flex items Center transition duration 500 which we're gonna need and for now I'm also going to put BG I think 900 BG opacity 90 like this all right now you're not going to see anything but we're gonna add uh our logo in a moment here so go ahead and write image and this image is going to be slash Images slash logo that BNG if you're wondering where we got this from we already imported that when we were creating our uh alt screen great so go back into navbar um and let's just style this logo a little bit last name here I want to give it the hype 4 and an LG on large screens I'm going to give you the height of seven like that I think that looks right and let's give them out of logo as well great now let's add some items here so open another div element here open class name and I'm gonna put flex Dash row ml-8 gap-7 it's going to be hidden but on large it's going to be visible great and in here we're going to use another component which is going to be called navbar item right so for now write it like this even though it does not exist yet we're going to create it in a moment so let's leave this error for now and go into your components and create a new file called number item.dsx great and just do cons not bar now bar item which is going to return an empty div like that and Export default null bar item just like that and then we can go here and we can import navbar item from dot slash navbar item great now let's go into our navbar item and let's create some styling for that so last name is going to be backstage White cursor Dash pointer text Dash sorry we already defined our text swipe on Hover it's going to be text Gray 300 and transition great and let's just write something like home great and now I'm gonna make this a bit more modular so I'm going to create an interface number item props and inside I'm gonna accept something called a label which is going to be a type of string so then we can import react.fc which is going to accept number item rocks and just import react as well import react from react like that and then in these parameters we can accept the label string and instead of home we're going to use that label here and now we're getting it an error here because we haven't passed any label so just pass a label here called home great and now we can copy this a few times and as you can see we have multiple navigation items so after home I'm going to put series because that's how it looks on Netflix then I'm going to put films then I'm gonna say new and popular I'm gonna copy a few more times after new and popular we're going to put my list and lastly we're gonna put browse by languages like that amazing great now after we finish this part of the div we're going to create another one right here on the right side which is going to be our profile menu great so outside this div element create another div element which is going to have a class name of LG hidden so we want to hide it in large screens blacks blacks row items Center Gap to ml8 cursor Dash pointer and it's going to be relative this is actually going to be visible on mobile screens all right wait a paragraph inside and write browse and it's going to have a class name of text white text xn all right you can actually hide this a little bit like this so now you can see that when we are on smaller screens all of our items are hidden and it's replaced by this browse element right here because we want to make this responsive before we move on into the profile thinker so I'm just going to collapse this screen a little bit so we can see what we're working with great all right and now we have to put a little icon here so going to react icons and let's search for maybe Chevron all right I like this BS Chevron down so that's what I'm gonna use so go in here and import BS Chevron down from react Dash iTunes BS like that and let's just paste this BS Chevron down right here and let's give it a class name of backslash White like that I think that that looks a good size but let's give it some more classes I want to give it a width of or maybe actually no need for that so just leave that um and it's gonna have a transition and let's leave it like that for now great and what we're going to do now is we're going to create our mobile menu uh for this list of items right here all right so create a new component here called mobile menu like that and we're gonna get an error because it doesn't exist so just go into your components and create a new file called mobile menu.psx great I'm going to import react from react and we're going to write an interface which is going to say mobile menu crops inside we're going to have a visible prop which is going to be optional and it is a Boolean so mobile menu is a type of react functional components which accepts mobile menu blocks just like that and the parameter it accepts is visible all right and if it isn't visible we're just going to return now otherwise we're gonna open up a div and we're gonna write some classes so last name BG black w56 absolute top eight left zero ey5 blacks call order two order Gray 800 and finally Flex in the end as well great and now another div inside of that which is going to be like a inner container Flex Flex slash call Gap or and now let's write some items inside this div you can write home I'm just going to separate this a bit so you can see better all right and we're gonna style this Home Ex three text Center text White over underline like that all right and let's export default mobile menu all right let's go back into our navigation bar and let's import mobile menu the same way we did the Navigation item like this all right and now we're gonna have to make this mobile menu be actually Dynamic for example I can trigger visible right now and you can see how it shows home this is supposed to trigger once we click on browse so let's create that functionality let's go here and let's create a new state called show mobile menu set show mobile menu and use state is going to be post by default make sure you import your state from reactive like that great and now we're just going to write a simple function called toggle mobile menu it's going to be a type of use callback make sure you put the dependency array and all we're going to do is set the show mobile menu it's going to use current value and we're just going to reverse the current whatever it is great and now um on this div click we can actually trigger the show or hide our menu so unclick toggle toggle mobile menu and visible is no longer going to be hard coded instead I'm gonna write show mobile menu right here so now if we click you can see how it appears but on desktop that's not even going to be an option great that's exactly what we want we want this to be responsive like that uh now let's go into Mobile menu one more time and let's add uh some other classes here so along home I also want to have series I also want to have films I also want to have new and popular and I also want to have my list and I also want to have Browse by languages alright so now if we click on browse you can see we have a much bigger list which is exactly the same as our large screen amazing job all right let's go back into number now uh and after this mobile menu here we're gonna create our profile menu right here so write another div and I'm just going to expand a little bit so we are on large screen all right and in here we're gonna style this dip again we're gonna write Flex Flex sorry Plex Black slash row ml Auto yeah seven items Center all right and inside that div we can create another div called class name text Gray 200 however X grade 300. cursor Dash pointer and transition all right and we can write search and you can see the search appears here now so let's replace this search with an actual icon so I'm just gonna do a little search here to see what we can import all right I like this one BS search so I'm going to import that from BS Chevron down also vs search as well so we can replace search with BS search like this great and you can see we can hover on it it looks really really nice great and just below that I want to copy this exactly so we have two search icons here but we're going to replace one with a bell and I think we can use BS Bell as well so we are consistent all right yes well like that and replace base search will be as well and great now we have a search and we have a bell great and one more element I want to add here is our menu right so this is where our profile is going to be so in this div below the S Bell you're actually going to add last name blacks black slash row items Dash Center yeah Dash 2 cursor Dash pointer and relative because this is also going to be collapsible and hidden on mobile as well all right and now let's create another div inside of that and write a class name of w6h 6 LG with 10. LG height then rounded MD overflow hidden all right you can see we have a little element here but nothing is visible in here yet and now I'm just gonna write an image element in here and it's going to default to slash Images slash people Dash Blue Dot PNG and we already have that imported from our last tutorial where we added profile screen so in public images I have default Dash blue that PNG and you can see it's right here amazing amazing job all right now I want to add a Chevron down you can here as well so I'm just going to copy this Chevron down icon here just like that all right and now we're going to write another um menu called account menu we don't have that yet so as always we're gonna get an error so just let's go back into our components and create account menu the DSX file for now just write count menu and return there you did export City old account menu go back into navigation bar and import you have you need to have navbar item mobile menu and account menu for now and you should not get any errors so go into account menu for now uh and let's go and import some stuff here so let's import sign out from next dash out slash react let's import react from react as well all right let's write our interface interface account menu props it's gonna have a visible optional parameter which is a type of Boolean and account menu is going to be a type of reactive functional component which is going to accept account menu drops right here and in our parameters we're gonna accept visible great and same thing if it's not visible it's going to return now great and now let's style this element so it looks like something so last name PG black w56 absolute position top forward in right zero ey 5 blacks call border Dash 2 border Dash gray Dash 800 Flex all right inside of that another div is going to happen and let's style that Plex Flex Dash call yap-3 all right and now we will create a container for our profile image so last name px-3 group slash item blacks Flex Pro Gap three items Dash Center and wool all right so you've already seen the group thing happen but you probably haven't seen group Dash item group Dash item is just a way that we can Target multiple groups inside another group so group slash item all right and now let's add an image here an image is going to be at images default blue.png great and the class name for this [Music] is going to be W8 rounded Dash MD alright and below that class name we're going to add a paragraph which is just going to be for now username and let's add some flat snap here so text Dash white text Dash SN group Dash hover slash item double dot underline all right and now let's just go into our navbar and let's just put visible right here so we can see what we're working with so this is what we created amazing we can now see uh like a list of profiles right here great uh and now let's add the sign out button right here so create an HR element right here and let's just style this line a little bit so 3G Ray 600 order 0 H pixel M14 all right this looks much much better and one last element right here last name BG gray 600 order oh my bad I was looking at the line above PX3 text Dash Center back stash white text Dash SM hover underline oh and this is a typo it's class name with 2s and just write sign out of Netflix like that and we're gonna write an on click element right here sorry event right here which is gonna trigger the sign out like that and now we just have to trigger this so it actually opens and closes once we click this little icon so let's go back into navbar uh and let's go ahead right here you can just duplicate this code right here instead of show mobile menu it's going to be show account menu and set show account menu you can also copy the toggle mobile menu and just write toggle account menu and change set show mobile menu to set show account menu all right now you're going to use this show account menu in this hard-coded visible account menu param right here like this great and you're gonna add an on click to this element right here let me just separate it a bit so after the Bell we have this div right here and on that element I want you to add an own click which is gonna have toggle account menu like that so if we click and click again you can see it opens and closes great and now what I want to do is I just want to rotate this Chevron when it's opened and rotate it down when it's closed because it's very simple to do so so we have this BS Chevron down right icon right here and I'm just going to replace this string with curly brackets for now and inside I'm gonna put this template literal uh strings great now it should not change anything but one thing I'm gonna add is I'm going to add a dollar sign and I'm going to open curly braces and I'm going to use uh a conditional called show account menu if we are showing account menu I want to rotate the icon for 180 otherwise I want to rotate it back to zero great so if you try now you can see that the icon actually has a very smooth rotation great and I want to do the same thing for our brows right here this one is good but our browse is missing that so I'm going to just go ahead go into BS Chevron down right here and I'm gonna do the same thing I'm gonna open curly braces here I'm gonna add this template with little string I'm gonna open this curly braces with a dollar sign and say show mobile menu question mark rotate 180 otherwise rotate Dash zero great and if you try now we have the exact same effect good job you just finished the navigation bar and now I want to add one more effect in this navigation bar and that is that I want to make it go dark when we scroll right now we can't really see what's going on because we don't have a lot of elements here but we want to make it a bit cooler that when we scroll we want to add like a dark background and otherwise we want to keep it transparent so what I'm going to do is I'm going to add a little constant here con called top underscore offset which is going to be 66. 66 is just the number at where the animation starts to looks good basically is the offset to how much the user is going to scroll down so we want to catch it around 66 and I'm going to add use effect which you can import from react right here don't forget to end your dependency array and what you're going to do here is you're going to write a function called constanto scroll open the function and just write if window that scroll y is bigger or equal than top underscore offset foreign defaults and of course we have to add this as well and you can just copy this and replace show background show background and replace this one with the set show background just like that great and now that we have this handle scroll function right here we need to add our event listeners so right window dot add event listener is going to listen to scroll event and just right handle scroll and very important we also have to remove the event listener on our unmanned function unmanned functions in use effect algorithm like this so return a narrow function and inside you want to write a window that remove event listener scroll and just write handle scroll again perfect amazing job and now we're gonna we're gonna have to use this show background value to change the background of our main div all right so in here I'm gonna replace this with template literals do the same thing like that great and now I'm just going to add a little condition here so I'm going to remove this BG sync and BG opacity here and I'm going to write that in a little so open up these curly brackets and say show background question mark BG Dash sync Dash 900 PG Dash opacity Dash 90. otherwise we don't want any kind of background great alright so I just modified my index just a little bit do not write this you don't have to write this I just want to show you why we did this event listener thing why did we write this use effect well I want you to be able to have a transparent navigation bar in the beginning but when we start to scroll I wanted to get this nice background so that's why we are doing that all right all right so in this part of the tutorial we'll be building our billboard section or our main Hero video which is going to load a random video every time we refresh the page so the way I want to start this is I want you to go into my Netflix repository and you're going to find a file here called movies.json don't worry all of these movies are going to be in our database but I just put it here so you can actually insert them into database right here so openmovies.json in my repository the link is going to be in the description and all of these are going to be our movies which we're going to add into the database right now and if you actually go into our Prisma schema right here and look at the movie model you will see that we actually have the title we have the description we have video URL we have thumbnail URL we have genre and we have duration and of course we are missing the ID because this is Json but ID will be generated by objects all right so have this file opened and now let's go and let's add all of those movies into this movie collection right here so make sure you're not in account for example make sure you select movie right here I'm going to zoom in a bit everything and go ahead and click insert document great now first build we're going to add is going to be title and go ahead here and just copy Big Buck Bunny from here great now add another field to it's going to be called description and just copy the description then another field after that is going to be called the video URL and just copy the video URL mp4 file great great below that we need our thumbnail URL and just copy the thumbnail URL PNG image next are the genre which in this case is comedy and last add duration which is 10 minutes and click insert great now we have our first movie I'm gonna do the same thing for all of this so I'm probably going to speed up this part of the video um but you just follow along and do the same thing so just as we did for Big Buck Bunny you want to do for singtel here's a still an elephant's dream as well all right so I added all four movies in my database and this is what it looks like so pay special attention to video URL and thumbnail URL so when you're copying this make sure you're copying it inside like this and not copy the entire thing because you're gonna add this annotations which might mess up the string so make sure it's just a pure string which ends in dot MP4 and for images make sure it's it ends in dot ypj or PNG whatever it is right it should look something like this so big bug bunny the description video URL that looks like this great so you should have all of that here perfect and now that is saved we have completed our movie models and now I'm gonna create a new route called random so you can close all of this make sure you have your project running all right and go into Pages API and create a new route called random.ds inside Imports next API request next API response from next great then you're gonna import Prisma DB from add slash lib slash Prisma DB and you're gonna import server out from add slash lib slash server out remember we created server out a couple of Parts recently in order to authenticate our routes great so open a Handler right here and it's going to be sorry export default asynchronous function called Handler open parenthesis and type requests which is type of next API request response which is type of next API response and open the function all right first things first we're going to limit this function to only work on get request method so write if sorry if request that method is not equal to get we're going to return the response status 405 and end the call now we can open our try and catch block but before we actually know we can open a try and catch block and inside of that first thing we're going to do is say await server out and we're going to send the request right here great now let's sketch any errors so console.log error and just return response status 400 all right perhaps you might be wondering why are we only doing uh server out and we are not extracting the current user well we don't have to extract it it returns it but all we want to do is I want to check if we are logged in because this is going to throw new error if it cannot find this user and that's exactly what we want here so this is all we have to do and now let's find our random movie that will be loaded every time we refresh the page so first we need to get the movie count so movie count is equal to a weight Prisma Prisma DB dot movie that counts because we want to get accounts of all movies in our database without loading them next we're going to do is we want to create a random index using this movie count so const Random index is equal to net that poor mass that random multiply play movie movie counts like that this is going to generate a random integer from the movie count and now we want to actually find the random movie Object from the database so const Random movies is going to be equal to a weight Charisma DB that movie dot find many we're gonna take only one and I'm going to skip a random index so we're going to be using pagination to make our algorithm for a random movie great and now what we're gonna do is return response status 200.json and now be careful we want to write random movies but this is an array we only want one movie so just pick the only one inside why do I know it's going to be zero the only one well because I explicitly say take only one from this many movies great we have our working random endpoint now which is going to be accessible in API slash random great and now I want to create a new hook called use billboard .ds all right in here we're going to import use svr from svr and import Patcher from add slash lib slash Patcher great and now let's define ohms use billboard and const extract data extract error please loading from use svr which is going to Target slash API slash random and use a Patcher but we're gonna also going to open an options object here and we are going to disable uh re-evalidation here so revalidate if stale is going to be false evaluate on focus is going to be pulse to validate on reconnect is going to be false as well the reason we want to do this is I just want to show you what options svr has for example for this one it's going to be a pretty static data we only want it to load once the user visits the page and not every time they lose focus out of the window and stuff like that if you want to you can completely remove these objects but for now I just want to keep it like this and return data error is loading like that and don't forget to export default use billboard great and now I want you to go into pages index.tsx and right below our nav bar we're going to add a new component called billboard now again this billboard component doesn't exist so let's go ahead and create one in components create a new file called billboard and in this billboard we're going to import react from Korea and for now just write cons billboard and return a bit and Export default billboard like that and now let's just import it right here great now we have our billboard all right so now what I want to do is I want to fetch the data for a random movie all right so just to see if it's working I'm going to stretch this a little bit and I'm going to open my network tab right here and I'm gonna import the hook called use billboard right here and we will have our data so let's see we initialize the random call and as you can see it picked a random movie in this case it's tears of Steel right here all right we can close this now and I'm just going to Center this great now we have some data to work with and now let's style this so it looks like something right so last name is going to be a relative and it's going to be H dash open square brackets 56.25 BW this means it's gonna use the 16.98 aspect ratio which our movies are loaded in all right now inside let's add the video element so video source is going to be uh it's not going to be a string it's going to be data question mark dot video URL like that and as you can see we are actually having a video right here great now I have to add some more Styles so let's add poster which is going to be data question mark dot poster URL sorry thumbnail URL and as you can see we have our thumbnail now great let's collapse this element's a bit just so it's clearer to see all right and let's let's add some more options here so let's add auto play and let's also make sure it's muted and let's also make sure it's playing on a loop great and as you can see it's actually loading a random movie and playing it amazing amazing job this already looks great and now let's add some class names to this so class name and let's write W 4 H dash open square brackets again it's going to be again 56.25 VW object dash cover brightness Dash open square brackets 60 percent great now we added like a little fade over this video great great job now let's add transition and let's add duration in fact actually we don't need this you can just keep it like this great now below this video let's add another div and this div is gonna hold our title and our description so let's style the div first it's going to be an absolute element give it a top uh offset of thirty percent so open square brackets on medium devices it's going to be top 40 percent so it looks a bit better give it an mL of four and on MD mL of 16 like that all right now inside let's write our title so open a paragraph element here and just write data question mark dot title all right you probably cannot see it now but it is right here I'll open the stream but let's style it a bit so last name on the paragraph which says text White text dash one Excel now it looks a bit better on MD we want to use text-5 Excel so it looks even bigger we're going to give it a full height and for the bits we want to give it a 50 percent all right on LG we want to use text Dash 6 XL so it's even bigger we want to use Font Dash bold to make it a bit thicker and I'm also going to add drop Dash Shadow Dash Excel like this and I just want to collapse all of this I want you to see this very nicely so you don't miss anything I know it's a lot of classes but Tailwind allows us to work really fast and make great designs great now this is looking like a title amazing job now let's add the description in the same way so below that open a paragraph and just write data on the score description sorry data question mark dot description and let's style that as well so class name let's add text that's right so now we can see the text let's add a text Dash open square brackets 8px on MD we're gonna say text LG let's give it a margin top of three on medium devices let's give it a margin top of eight let's give it a width of 80 percent on medium devices let's give it a bit of uh sorry we will give it a bit of 80 on medium devices but on mobile devices we're gonna give it 90 like that on large devices we're gonna give the width of 50 percent and we're gonna add drop Dash shadow that Excel great this is looking absolutely amazing all right so now let's go below this and in here we're going to create a button so create a button element like this and write more info all right you probably can't see anything now but it's right here great and now let's give it some class names sorry first let's edit the container of this button so last name is going to be Plex Black slash row item slash Center and the three MD and V or in gap three all right now let's style the button open class name and we have some classes to write BG is going to be white text is going to be white BG Dash opacity is going to be 30 percent it's going to be rounded let's give it a padding y of one but on MD we're going to give it a padding y of two great for PX let's give it two button MD let's give it PX or let's say that looks about nice W is going to be Auto text is going to be extra small but in large screens we're going to use text large all right let's roll the font a bit so font semi bold let's use flex Dash row items Dash Center on Hover we're going to add 3G Dash opacity 20. and transition great now this is looking amazing all right now I want to add a little icon here in this button so just go ahead and add your info and let's see which one I think AI outline info Circle looks great so I'm going to import that so import ant AI outline into a circle from reacts Dash icon slash AI like that all right and before more info I'm just gonna use this AI outline in the circle and let's give it a class name of Mr Mr one great and on MD let's give it actually mr1 is just fine I think this looks good great job uh we have successfully finished our billboard now if you can refresh you see that we're loaded again sometimes the movie is going to repeat because we only have four movies but you can see every time it's a different one good job alright so in this part of the tutorial we are going to create a movie list below our billboard so let's go ahead and let's close everything up and let's go into our Pages API and let's create a new folder called movies and inside create a new file called index.ts great you're going to import next API request next API response from next all right we are also going to need to import Prisma DB from add slash lib slash Prisma DB and we're going to import server out from add slash lib slash server out great now export people asynchronous function called Handler which is going to have a request which is type of next API request and also response which is type of next API response great first let's limit this uh API call to only get request method so if request that method is not equal to get return response status 405 and end the call great now let's open up try and catch block let's console log the error and let's return the response status 400. and great now in our try block first we're going to run server we're gonna write around a weight server out with the request parameter sent great this is going to authenticate this route and now let's load all of our movies so const movies is equal to Prisma DB dot movies sorry that movie that find many that's it I forgot to add a weight in front of this function so make sure you do that I'm gonna find that later on return response status 200 that Json movies excellent we have finished our movies API now let's create another hook this Hook is going to be called use movie list.ts just like this use movielist.ps all right and let's import use svr from svr and let's import pattern from add slash lib slash Patcher great Define the hook const use movie list and export data error and is loading from use as we are which is going to Target you guessed it slash API slash movies it's going to use the fetcher let's open some options and let's disable two too many revalidations here so to validate extale it's going to be false we validate on focus is going to be polished as well and revalidate on reconnect is going to be policies again because we don't need that many API recalls and just return data error and it's loading great don't forget to export default use movie list just like that all right now I want to go back into let's close everything up just so it's a bit clearer and I want to go back into pages index.tsx and in here below the billboard I'm going to add a component called movie list just like that and I'm also going to wrap it in a div right here because we can have multiple movie lists and add the class name to this div called PB -40 great we're going to get an error because movie list doesn't exist right now so let's go ahead and let's create this component movie list.bsx great const movie list and simply let's return it an empty div just to fix the error for now export default movie list all right and let's import movie list from our components and the error should go away great now let's get to importing so import react from react and let's import is empty from low Dash now we don't have loaders so let's go ahead and install that in your terminal write npn install low Dash and also add npm install Dash the capital d add type slash loadage great all right our movie list is going to accept a couple of items it's going to accept data and it's going to accept title so let's write an interface for that interface movie list props is going to be data which for now is going to be a record string comma adding all right and title is going to be the type of string and this actually isn't going to be an object it's going to be an array right so just make sure it's an array all right now let's check with low Dash if our array is empty so if it's empty data and just return you know because we don't want to render any empty data here and let's add this type so react.fc is equal to movie list props like that great and for our title where we're going to use that in a second so let's style this div first class name PX for on medium screens we're gonna have a px 12 margin top is going to be 4 and space is going to be space Dash y space uh Dash 8. that open another div inside and write a paragraph here now our paragraph is going to be our title let's get some classes so class name tax Dash white tax Dash MD MD text is gonna be XL large text it's going to be text 2XL Pond is going to be semi bold and margin bottom is going to be War great great job all right and just below this paragraph I'm gonna open another div element right here and for now what we're going to do is we're just going to say data.map and for now just return an empty div so just like this and you can write movie here and make sure you use the key so for that you can actually you can actually extract and move it here because we are using proper data so use movie and key is going to be movie dot ID like that rate and let's just style this div so last name print grid Dash calls dash for gap-2 all right so now we have to get this data and this title in index so let's go ahead and let's do that so first thing this is missing is the title so let's add title and we're going to say trending now all right and now let's load our movies so cons data and when I get we're going to give it an alias of movies and we're going to make sure that default is just an empty array and we're going to use use movie list our newly created hook make sure you import it from add slash hooks use movie list just like this and now you can use these movies in the data parameter right here all right and the reason we are not seeing anything is because we have to go back into our API movies index.s file right here and we forgot to put a weight in front of Prisma db.movie.pine manic if you put the weight go back here make sure that you are using use movie list and refresh and just like that we have trending now right here as our title and we have this hard-coded or movie columns great now let's turn these movie columns into actual movies with cool Tailwind hover effects all right so let's go back into our movie list component and let's replace this div with movie card component rate and for the key we can put the same movie that ID and for data we're gonna give it all right so movie card movie card doesn't exist for now but we're just gonna go ahead and create it so go into your components and click on your file movie card that DSX great now this component is going to have a lot of classes so I'm going to be very careful and I'm going to make I'm gonna make sure you can see everything right important react react and let's create an interface interface movie called props and let's say data is going to be a record of string any like this all right Bones the movie card is a react functional component which accepts movie card blocks and the parameter it accepts is data all right and now let's write our movie card make sure you export default movie card and for now just return an empty div so we can fix the error here so go back into your movie list component and import movie card foreign all right now let's start writing some classes so on the main div you know write a class name of group BG Dash sync 900 or span relative and H of 12 viewport units like that great now inside we're gonna add an image for the movie so create an image uh element right here and this source is going to be data that thumbnail URL great now we can see your movies really cool all right and let's put an ALT thumbnail okay why thumbnail URL because that's what we added in the database so here we have it thumbnail URL the same way we did video URL for the billboard all right now let's add some styling to this image element open class name and let's write some classes so it's going to have a cursor Dash pointer is going to have object dash cover it's going to have a transition class we're going to give it a duration let's put some Shadow so Shadow XL let's give it some rounded corners great so now you can see we can kind of have this cursor pointer on it and it's kind of rounded very nice and some little Shadows are appearing here all right next let's add group dash cover is going to be opacity 90. now add SM group dash cover opacity is going to be zero delay 300 W or width full and H well you put units great you can see all of our image look bigger now and as you can see when we hover we are actually making them disappear and there's gonna be a reason for that and you're gonna see that in the next div that we are going to create all right so below our image class right here create a new div element and we're going to add some classes here as well so open class name and let's write opacity there's zero absolute top Dash zero transition duration Dash 200 Z 10 invisible SM visible sorry I misspelled visible so SM visible delay 300 W full or full width scale is going to be zero group dash cover we're gonna have this multiple times now so group Dash hover is going to do scale 110 the root touch however is also going to do minus Translate minus y minus six viewport units group Dash hover is also going to do translate without a minus in front so translate Dash x dash two viewport units and we're also going to have group dash cover obesity 100 all right and now we're going to add another image element here and you might be wondering why are we doing this what is this another image element where you're going to see in a second this is going to be the cool hover effect which you saw in the intro video of this tutorial so create another image element right here source is also going to be data dot thumbnail URL alt is going to be thumbnail as well all right and now let's give it some class names as well last name so it's gonna have cursor Dash pointer it's going to have object dash cover transition duration Shadow Dash XL rounded t that's e Dash MD so only on top we're gonna round it W pull or pull width and H is going to be 12 viewport units like that and now if you see we can actually see how it kind of floats above its initial position and it's kind of scaled really cool and now we're gonna add the element below that which is going to display some movie information as you can see it looks really really cool already so hang on and we are almost done with this so below this image create another div element and inside again you guessed it open class name and let's write z index 10 VG sync 100 E-2 LGB four absolute position pull width with W-4 transition shadow Dash MD and rounded Dash B MD rate and now I'm just gonna add some uh I'm we're actually going to fill this bottom element right here and make sure it's not digitsync 100 I think 800 for example yeah this looks better so now you see we have this little space below the card this is where we're going to put the title uh and some buttons great great job so far all right so let's open another div element here I think I can kind of space it out pretty easily so another div element here uh and this one is gonna have a class name of Plex Black slash row item slash Center yeah three inside of that another div element for now we're gonna give it an on click which is going to be empty and let's add some classes so last name is going to be cursor Dash pointer okay I'm going to collapse this so you can see easier cursor pointer w6h6 on large screens it's going to be W10 and then large screens is also going to be h10 background is going to be white it's going to be fully rounded with rounded Dash full it's going to be a flex element it's gonna be justified in the center so just to press sender item Center transition however vg-neutral-300 all right and what I'm going to put inside as you can see we have this empty little icon here and what I'm going to put inside actually is the play button so going to react icons and let's see if we have anything for play uh I think this BS Fill Play is perfect so I'm just gonna copy that and I'm going to import it so import BS Fill Play fill from react icon slash vs like this all right and now let's just add that in this element which is styled like this and as you can see we have our little play button so let's just increase its size a little bit maybe 30. rate I think 30 looks great good job all right create a new paragraph element which for now is going to say new and then give it a span and let's just give it a class name of text that's white 2003 and for the main paragraph we're going to give you the class name of tax Dash green Dash 400 on that semi bulb and mt-4 great so now we have this Netflix style of new 2023 movie great all right below this paragraph create another div element uh and let's style it so class name is going to be collects flat slash row mt-4 Gap Dash 2 and items Dash Center and inside this new div element we're gonna have another paragraph here which is just going to say data dot duration so let's just style the class names here text Dash white text dash 10 pixels but on large is going to be text Dash SM great so now we're actually loading how long these videos last thing which you if you remember is something we loaded in our database here in duration great job all right a couple of more Fields left uh actually exactly one more field app so you can actually copy this now and just paste it here like this and replace data duration with data.genre great you have successfully finished movie cards in next part we're gonna add the actual play button we're also going to add a favorite button and some other stuff good job all right so in this part of the tutorial we're going to implement the favorite button which is going to appear right here next to the play button and we are also going to implement my list below this trending now list which is going to display only the movies which we have favorited great so let's start by creating a new API route in our API folder called favorite so favorite.ts now this route is going to be able to handle multiple types of method requests it's going to be able to handle post request and delete request so that's what we're gonna do start by importing next API request and next API response from next then import without from low Dash which we have imported in last part import Prisma DB from add slash lib slash Prisma DB and import server out make sure you started correctly server out from add slash lib slash server great and Export default asynchronous function called Handler which accepts the request of type next API request and response of the next API response all right open up a try and catch block and let's handle the error first so catch the error log the error and just return response status 400 and for the error all right now first let's handle the post method so if requested method is equal post we're gonna do the following first we need to get our current user so cons current user from await server out which accepts the request parameter like that and then we need const movie ID from request.body great and now let's find the movie using the movie ID so cons isting the movie is equal to await Prisma DB dot movie dot finds unique open up where and inside write ID movie ID like that great if there isn't an existing movie we're going to throw new error which is going to say invalid ID great and now we have to find our user sorry we don't have to find our user we have to update our user and have to push this movie ID in their favorite IDs if you're wondering what that is but we Define that in our Prisma schema right here our user has a list of favorite IDs which contain a string of object IDs great so go back into favorite.vs in API and let's write the following const user is await Prisma db.user.update open an object and write where so first we need to find it and we're going to find it using our email so email current user dot email and just to fix the typescript error in your pipe pipe and the string like that great and now we have to provide the data which we want to update all right and that data is going to be favorite IDs and the way we're going to add them is we're going to use push and what are we going to push well movie ID and just like that this is how we handle uh updating our user and we're gonna return response say this 200.json updated user like that great and now we handled our post request but we also have to handle our delete requests when a user wants to unfavorite a movie so let's do that now if requested method is equal to delete we want to do the following so same thing const current user from await server out which accepts request parameter and const movie ID from sorry from request body like that now again let's find the existing movie const existing movie is equal to oh wait where is my BB dot movie dot find unique where ID is equal to movie ID like that if there isn't an existing movie we're going to you guessed it throw a new error which says invalid ID great and now we have to update our list of favorite ideas so const update favorite sorry updated favorite IDs is going to be a list of our current favorite IDs without this movie ID and the way we're gonna do this is with low dashes without that's why we imported it right here in the beginning so we're going to update the current user dot favorite IDs list and we're going to remove movie ID from that list great all right and now we have to update the user again so cons updated user is going to be await Prisma DB dot user dot update first we have to find the user and we're going to use email for that so email current user email and just to fix the typescript error pipe with an empty string and now let's give it some data to update that data is going to be favorite IDs and it's going to be the list of updated favorite ideas just like that and return response status 200.json and send updated user inside great and in the end so we handle the delete method and we handle the post method but if we get some method which is neither of them we want to go outside this if delete block and just write return response status 405 but n great great job and now this is the API request to trigger and to remove and to add favorite ID into our list now let's create an API route which is only going to load our favorite movies so go into your API and create a new file called favorites.ds still not favorite but favorites that the s and in here again you're gonna import next API Quest next API response from next you're going to import Prisma DB from add slash lib slash Prisma pdb and your import server out from add slash lead slash server app great now export Depot async function called Handler which accepts the request of the next API request and the response of the next API response and now we have we have to limit this route only to get method so if request that method is not equal you get return response status 405 that end great open up a try and catch block and let's handle the error first as always so for development just log it here and return response status 400. like that and in our try catch in a try Block it's going to be much simpler than the favorite one all we're going to do is we're going to get the current user so cons current user from await server app which accepts the request parameter and then const Bay read movies is equal to await Prisma TB that movie dot find many where ID is in current user question mark dot favorite IDs like that so what this is going to do is it's going to find all movies which have a relation to current user favorite IDs list otherwise known as their favorite movie list great now return response status 200 with the Json of the favorited favorite movies just like that great now let's create a hook called use favorites which we're going to use to load this so close everything for now go into Hooks and create a hook called use favorites and in here I'm going to import use as we are from 3r and you're going to import fetcher from add slash lib slash fetchup honest news movies sorry use favorites it's going to be an arrow function which is calling the use svr which in which we are going to get data error is loading mutate wrong use svr which is targeting slash API favorites and it's using capacitor and we're also going to update this list I'm just going to collapse this so you can see better all right and the options are going to be revalidated if they all pulse to validate on purpose faults and re-evaluate on reconnect pause because we do not need to do that many API calls and just return data error is loading a new date and don't forget to export the code use favorites one thing I want to bring your attention to is this route make sure it's slash API slash favorites not favorite but favorites because we have a similar route called favorite but this route is going to be used to add and remove Favorite IDs and favorites is going to be used to fetch all of our favorites great alright and now we're gonna add this button right here all right so let's go into our components and let's create a new file called favorite button PSX great in here we're going to input axios from axis because we are going to do some requests we're going to import react and use callback and use memo from react and going to import use current user from Books use current user and we're going to import our newly created hook use favorites from hooks use favorites like that let's create the interface called favorite button props and all it's gonna have is a movie ID which is a type of string great so cons favorite button is going to be type of react functional component which is going to accept favorite button plots it's going to accept one parameter movie ID and now let's actually style it so return an empty div for now and Export default favorite button like this all right and now let's add this favorite button to our movie card so we can see what we are styling so we need to add it right here next to this um play button so go into your movie card component in your components and you're gonna add the favorite button right after display button so after this div you're gonna add favorites button like this and you're gonna pass movie ID beta that movie ID sorry data Dot ID and just put a question mark right here so data question mark dot ID is going to be a movie ID and the favorite button is going to be imported from favorite button dot slash favorite button because we are in the components folder right here great all right now we can see anything but we're gonna do we're gonna fix that shortly so go back into favorite buttons and let's style this div a little bit all right so class name cursor Dash pointer group slash item W 6 h 6 LG is going to be W10 and LG is also going to be that height 10. border is going to be white border is going to be two pixels with rounded cool so it's a circle we're gonna give it some Flex and now we're going to Center the elements inside of it so justify that sampler item slash Center we're going to give it the transition because we're going to have power border slash neutral slash 300. and if you look we actually have a little uh icon right here amazing amazing job all right and now we have to write have to put an actual icon here so we're going to use the plus icon as our favorite item so let's go into react icons and see what they have in store for us I want to use this AI outline plus icon so I'm going to import that from here import AI outline plus from react Dash icons AI great and I'm gonna add that item here so AI outline Plus great we have the modified little bit so let's give it a class name of text that's right and size of 30. maybe a bit too big let's try 25. all right this looks much much better good job all right and now it's time to actually make this favorite button work but before we do that I want to create a movie list on the bottom so we can see uh once we click on this I want to see I want you to show how it appears in our list below so let's go into our index.js file right here and let's copy this movie list and let's just add my list great so now you're going to see the exact same thing but we're going to change the source from where it gets its movies all right so right here we're gonna change we're going to add this const data is going to be called favorites it's also going to be default array but we're going to use a different hook called use favorites like that and just import use favorites from add slash hooks use favorites great and now you can pass this data right here and it should probably go away because we have no favorites currently great and now let's go back into favorite button so inside your components click on the favorite button and let's add some functionality here all right so what we're going to have to use is we're gonna have to use mutate and we're going to give it an alias mutate favorites and we're gonna get that from use favorites we have imported use favorites right here in hooks slash uh add slash hooks use favorites great now we're going to need our current user so const data give it an alias of current user and also mutate use current user like that and we have imported use current user also from add Slash use current user great now let's create a check variable to see if a movie is favorited or not so cons his favorite it's going to be a news memo which you can import from react right here great and what we can do is we're going to create a list constant right here which is going to be current user question mark dot favorite IDs or I'm gonna pipe it and give it an empty array like that and then we're going to say return list that includes movie ID so we're gonna go and search in our current user in their favorite IDs and we're going to see if the current list includes the passive movie ID and we have to add some things to our dependency array so add current user and add movie ID great all right now let's create a function which is going to toggle uh favorites so const toggle favorites it's going to be a used callback which you can import from react it's going to be an asynchronous error function don't forget the dependency array and inside let's write the following so add response if is favorite we're gonna have response to be await axios dot delete slash API favorite and we're gonna pass data movie ID all right so what are we doing here well once we click the favorites we're going to check if the current movie is favorited if it is we're going to trigger the delete axios request but if it is not favorite so if we want to add it to favorites we're going to change this response to be away axis post slash API favorite again but since this is a post method we don't have to add this explicit data right here you have to do this for the delete request so in axios you have to write data and then movie ID but for post request we can just write movie ID like this great and now just write once updated favorite IDs is response question mark data question mark favorite IDs like that and now we're going to use this mutate function right here so new date we're gonna spread the current user so we don't want to mute it anything else and the only field we want to mutate is favorite IDs which field well updated favorite ideas just like that and just write mutate favorites as well in the end great and you have to add some dependency arrays here so let's add movie ID let's add its favorite let's add current user let's add mutate and let's add new date favorites foreign and now I just want to make this icon Dynamic so it's going to be a plus if we are going to add to favorites but it I want it to be a check mark If we have already added it to favorites so I'm just going to create a new constant here called icon and it is favorite we're gonna add the check icon so let's go into react icons and let's see what they have in store for check and I want to use this AI outline check icon so I'm just going to import right beside AI outline plus I'm just going to import AI outline check here great so if his favorite I'm going to use AI Outlook check otherwise I'm going to use AI um I'm going to use AI outline Plus great and then we can replace this area outline plus with icon great and now we have a dynamic icon great so let's go ahead and let's add an on click event to this div on click and let's say toggle favorites which we have defined right here all right let's try and as you can see we have successfully triggered it to a check State and it's added and automatically loaded in my list amazing amazing job let's try and remove it from the list great job it's working amazing amazing job all right so in this part of the tutorial we're going to implement the actual play button which we're also going to add in this billboard and we're also going to create the uh player route as well so let's go ahead and close all of this and let's go into our Pages API movies in this folder create a new file open square brackets movie id.ts great so API movies movie ID dot DS in square brackets it's very important that this is in square brackets all right so import you already know the drill next API request next API response from next and import Charisma DB from s slash lip slash Prisma DB and import server out Chrome add slash lib slash server out great export default asynchronous function Handler which accepts the request which is a type of next API request and a response which is a type of next API response let's limit this route to the get request so if request method is not equal to get return response status 405 and end the call alright now let's open the try and catch block and as always let's log the error and let's return the response status 400 and end the call as well and now in this try block what I want to do is I want to await server out like this and pass it to request parameter great and now let's grab a movie ID from request dot query so where is this request query coming from well in next JS when you define a route name like this so in square brackets it's going to know that this is going to put that in the request.query in this case we named it movie ID so that's where we know we can search for movie ID here great let's check what type of movie ID we have sent so if type of time if type of movie ID is not equal the string let's throw new error which says invalid ID great and let's also check if we don't have a movie ID in that case also grow new error in load ID all right and now let's find the movie so cons movie is equal to 08 Prisma DB if that movie if that finds unique where movie sorry ID is equal to movie ID promo request parameters amazing and let's just check if the movie exists so if there isn't a movie again throw new error invalid I did one more time otherwise just say return response status 200.json movie great excellent job and now let's create our use movie Hook so go into Hooks and create use movie we've got ES great import use as we are from svr and import fetcher from add slash live faster cons to use movie is an arrow function which uses use svr let's extract data error is loading and let's target slash API slash movies slash and now I made a mistake here we should use template literals right here like this and then you can open dollar sign object ID and it's actually going to accept use movie Hook is going to accept an ID which is optional and it's going to be a type of string like that great so if we have an ID we're gonna fetch this if we don't so just add a one ternary here so ID question mark if we have anything we're going to fetch slash API slash movies ID otherwise we're not going to fetch anything right we're gonna use fetcher and just open some options I'm gonna collapse here so you can see what we are writing all right and the options are going to be revalidate if they opposed revalidate on purpose false and revalidate on reconnect both you can choose not to write this options object but I prefer it this way and return data error is loading great and don't forget to export default use movie great job all right and now let's create our play button component which we are going to reuse a couple of times so that's what we are going to put it in a component great so go into your component and create a new file called play button that is X all right important react from react and let's briefly go into our movie card right here and let's see what we used for play I want to use this exact icon so import BS Fill Play fill from react icon slash BS I'm gonna copy that and paste it here all right and let's also import user router from next slash router great let's create an interface for the play button so play button props it's going to accept movie ID which is a type of string const play button is a react functional component which accepts play button blocks it accepts one parameter movie ID all right let's define the router here use router and now let's just say return and for now let's just put an empty div as always and Export the both play button all right and now I want you to go into the billboard component so we can add it here and look at what we are designing why are we adding those classes so going to your billboard right here and let's find a place for this play button uh let's go below description right here and I think the best place is right before this more info button so empty space here and just put play button like that and you can import it from dot slash play button because they are both in components all right and one thing we are missing is the movie ID so Viet ID is equal to data question mark dot ID all right let's go back into play button right here and let's start styling it so open class name here and let's add some styles it's going to have ABG a white it's gonna be rounded ey1 button MD is going to be vy2 px2 but an MB is going to be PX4 so it looks nice on large screens W Auto text is going to be extra small button large is going to be large we're gonna have the font be semi-old and we're going to Center the items inside of the button so Flex Black slash row item slash Center hover BG Dash neutral 300 and transition all right and now let's write play great and I just want to add an icon next to that and for that we can use the this BS Fill Play fill which we have imported right here like that and let's just style it a bit so on here the size of let's say let's see how 20 looks it already looks better maybe 25 all right that's perfect and class name I just want to give it an MR dash one so it's a bit more space here great and now uh one thing I want to replace is this doesn't have to be a div I think it's better if this is an actual button element so just change that great so now we have this hover cursor pointer on it great and on click I'm going to do a simple thing we're going to open an arrow function which is going to say rather that push open literal strings say slash watch slash open this dollar sign object movie ID great and now actually if I click it's going to redirect us to this 404 not found because we're going to build this player in a minute but for now we have a working play button amazing and now let's just add this router push as well into this button in the cards as well so going to components into movie card and we have defined this on click which is empty right here if you cannot find it just look for the BS Fill Play fill icon which is basically the play icon and what we want to do is we want to import use router so import use router from react sorry from next slash router Define the router before the return here sequence router is use router and you can change the on click to be router and the push and open template laterals slash watch slash open dollar object and just use data question mark ID great and now you can actually try it here and we should get the same thing so we are in a 404 page great now let's create our watch uh component so I want you to go into pages right here and you're going to create a new folder called watch and inside you're going to create a new file again early brackets movie sorry square brackets movie ID dot vs just like this it's very important that it has this the same way it was important in here in movies but this is now in Pages watch so outside of API folder this is a client route right here movie ID all right so let's import react from react and let's import use movie from add hooks use movie make sure react is important as lowercase great and let's define const watch it is an arrow function it uses router so we use router right here let's get the movie ID from router the query I have not imported router sorry so import router from next slash router and now we have our movie ID great and now we need to get our movie so cons data is equal to use movie book which accepts movie ID great and just a fixed typescript as string like this all right we have created this used movie before uh to load the movie right so go back into oh I lost the file all right going to watch movie ID and let's actually style this so return let's create a div yeah make sure that movie ID is not DOT DS it needs to be dot TSX like this all right so for now just open and close the div as we always do and Export default watch great so now if you actually try and click on this play button here you will actually not be redirected to 404 but an empty screen because this exists now so let's go ahead and style it a bit class name age screen which means you're using the full screen height W screen as well so full screen width and let's give it the BG of complete Blackness great now let's create a small navigation bar right here and I'm going to give it some class names so last name is going to be fixed all with it's going to have a padding of four with B4 Z10 it's going to be a flex element let's throw items Dash sander yeah eight BG black BG opacity 70. all right and now I'm going to add an arrow back function so let's see what arrows we have all right I want to use this AI outline Arrow left so import a outline Arrow left one react Dash item slash AI and let's just put it here all right let's add some color last name text White and for size let's try 30 maybe even 40 yeah something like that uh and next to this class I want to add a paragraph which will say which will have another span inside which is going to say watching and outside span is just going to be data question mark dot title like this all right now let's style this phone so span is going to be class name of font dash light and the main paragraph is going to have a class name of text Dash White text dash one Excel but the larger screens is going to have text free Excel and it's going to be font o great so now we have watching elephant's dream okay and outside this nav I'm gonna add a video element and the source is going to be data question mark video URL all right and now let's give it some styles last name H O w and now we have to give it some attributes so auto play and controls all right and just like that we have a working player amazing all right let's just add this back button and let's enable it so uh on click of this AI outline Arrow left I want to bring us back to the main screen so on click open an arrow function and just write router.push and just put an NP slash great and now if I click here I'm back and we can try and play singtel for example he's gonna load Central and we will be watching simple amazing all right and now I just want to add a cursor pointer on this button right here so give it a class name of cursor Dash pointer so now yeah now it has this nice button effect amazing job only one more thing left and that is the info model great job all right so in this part of the tutorial we will be creating our last component which is the info model which is going to trigger on this more info button right here and we're also going to add another button right here which is going to be like an arrow down function like on Netflix which is going to open up a nice little model so let's go ahead and let's close everything up and let's create a new hook called use info model that yes all right in here we're gonna have to import a new package so go ahead in your terminal and run empty install system is a nice label little Global State Management Library if you want you can implement this with react context or even Redux if you want to but I think two stand is just lightweight enough for this so import create from system like this and now let's export the model store interface so expert interface model store interface and it's going to have a movie ID which is optional and it's a type of string is going to have an easy open Boolean and it's going to have open model function which is going to handle movie ID which is going to be a string and it's going to have a closed model function which is just going to be avoid like this great and now let's define the hook so const use info model is going to be create open only brackets and put in model store interface like that and open the function open another function and write set because that is the parameter we have open Arrow function open another function and open an object like this all right so we're going to set the default movie ID which is going to be undefined next we're going to write is open which is going to be false by default next we're going to write open model which is going to accept movie ID which is the type of string and now we're going to use this set parameter which we have right here and we're going to say we're going to open an object and say it's open true movie ID all right this movie ID is a shorthand for movie ID double dot movie ID but you can just write this and let's write on closed which is just going to set everything on default so it's open it's going to be pause and movie ID is going to be undefined like that all right and let's export default use info model all right and we have this uh on close I named it incorrectly it's closed model in the interface and just name it close model right here great now let's create our info model component so go into your components and create a new file called intelmodel.bsx all right now import react and import use callback use it back and use save from react make sure we have this lowercase next we're going to import the close button so go into react icons and let's see what we have under close I want to use this AI outline close so import AI outline closed from react icons slash AI like that all right now we're gonna have the play button so import play button from dot slash play button import favorite button from dot slash favorite button and import use info model from add hooks slash using the model and import use movie from add slash hooks slash use use movie we have created all of this in previous parts of the tutorial great now let's create the interface so interface info model props and it's going to accept visible which is optional and the type of Boolean and it's also going to accept on close for now you can just put any all right now let's write const info model it's a react functional component that accepts info model props all right the parameters which we are going to get in this component is visible and on close and now let's create a state or visible so it is visible set is visible use State and the default value is going to be visible but we have to turn it into a Boolean so just make sure you put a double exclamation points like here like this all right now let's fetch the movie ID cons movie ID where do we fetch the movie ID from well from the use info model right here we have defined the movie ID in This Global state so that's where we're going to fetch it from so use movie ID from use info model like that and let's also fetch some data from the movie so data which is default on empty object from use movie and we're gonna pass in movie ID right here great now let's create a use effect use effect make sure you put the dependency right here and in here I'm just going to put set visible on every new visible change that we get and make sure you put visible in your dependency array great now let's write the handle close function so close handle close it's going to be a use callback make sure you put the dependency array again and let's write the following so set is visible is going to be pulse set timeout this is going to be a little trick so we can play a cool animation in our model so set timeout and actually call the on close function here great and we're going to timeout it for 300 milliseconds great all right and now just remember to put on close in your dependency array okay if it is not visible we're just going to return no but if it is visible we're going to return our info model so for now just return a div and Export default info model great now I want you to go into your pages index DSX and I want you to go right here and import info model great and I want you to import it from add slash components slash info model since it is right here all right and let's give it a default visible option here and for on close let's just give it an empty function for now all right so you're not going to see anything now but we're going to change that in a moment so go back into your info model and let's write some code all right last name first we have to create a big overflow to actually create this model so give it a big Z index update transition duration 300 BG black BG opacity 80. blacks justify Center items Center overflow x given overflow W sorry Auto make sure it's fixed and inset zero all right now let's go let's add and let's create an inner div we're just gonna have the following classes it's going to have relative W Auto MX Auto Max W3 Excel rounded MD and overflow hidden all right now inside let's write another div let's give it a class name of the following so I'm going to change this in just a second so open this curly brackets and write the template literals instead all right and now we're going to use this is visible so it's visible give it a scale 100 otherwise give it a scale zero all right now give it a transform duration 300 relative let's Auto VG think 900 and drop Dash Shadow Dash MD all right and now let's go inside this div and create another div and this div is going to have a class name of relative H dash is six inside this relative h-96 we're gonna implement the video all right and let's give it a source of data question mark dot thumbnail Sorry video URL and let's give it a poster of data question mark dot thumbnail URL like that let's just collapse these elements let's give it some attributes autoplay muted and loop all right and now let's give it some classmates foreign ers Dash open curly brackets open square brackets 60 percent object dash cover H dash four all right now let's just see why uh we are not seeing anything oh all right we're not seeing anything because I have not run my projects ago in the terminal and write npm rundep foreign so now you can see we have our model and we have this little block inside great um all right now let's add a close button uh in after this video here so div let's give it an on click for now it's just going to be an empty click and let's give it some classes last name cursor Dash pointer absolute top Dash three right dash three h-10 w-10 rounded Dash full BG dot black so you can see we have like a little circle right here let's give it an opacity of PG Dash opacity 70. let's give it the flex items the center and justify your Center like that all right and now let's use this AI outline close icon right here to put the icon inside so right here just put AI outline close like this and let's give it a class name of text that's white great and let's also give it a size of net 20 like that great so now if you hover you can see we have this cute little close button right here great all right below this div element which is called holding our close button uh let's open another div and let's give it a class name of absolute bottom Dash ten percent left then all right and inside open a paragraph which is going to say data question mark dot title open class name and write text Dash White text free Excel MD text for excel h o LG text by Excel and B 8. all right and now let's add some buttons so div element below the paragraph in the class name of Plex Black slash row Center foreign which accepts movie ID from data question mark.id and it also includes the favorite button as well great so now we have play and favorite button right here all right now let's go completely outside this div right here with the relative 96 so outside is there write other div we're just going to have a class name of px12 PW sorry by8 this is going to be our model body all right in here I want you to create a paragraph which is going to say new you want to give it the class name of backslash green that's 400 and phone the semi semi low and text LG all right and below that create another paragraph which is going to have data question mark duration here the class name text White text LG and you can copy this a couple of more times since they are exactly the same it's going to have data question mark dot genre and description great now let's actually uh put some data here and let's use this handle close uh button here so we have this handle closed method right here and let's place it in here on click like this great so now go into your index.dsx right here and let's see what do we have to do to trigger this model so visible is actually going to be not hard coded it's actually going to be from our is open close model use info model book you can import using the model Hook from add slash hooks Slash use info model So Right is open for visible right here and for on close just put close model like this great so now you can refresh all right and now let's go back into our billboard so we actually add some action to this more info button so go into billboard all right find the more info button in this case it's right here and I want you to create another function here or pawns handled open model which is going to be a used callback from react make sure you put the dependency array right here and all you're going to do is open model open model data question mark dot ID all right so we are missing the open model so let's just do that real quick right here once open model is equal to use input model book right here you can import it using model Hook from hooks Slash from add slash hooks using the model great all right and now we have to put open model in the dependency array and data on the question mark I did great copy this handle open model function and find the more info button and inside this button create an own click which is going to write handle open model great and now if you click on more info you see we actually have this info model which loads the elephant's dream and if we click play from here uh we are redirected to the player great and we can actually click on plus icon and it's going to turn into favorites and right here it's gonna add into our favorites here great and now we have to add another button into this card so go ahead and close everything and go into your components into movie card right here great all right now we have to import open model here as well so open model from sorry uh news info model you can import using for model Hook from add slash hooks Slash use info model right here and what I want you to add is another button next to this favorite button and the way you're going to do that is create another div element here and give it a class name of cursor Dash pointer ml outer group slash item w -6 h-6 LG W10 LG h10 border that's right border two rounded full sorry round that Dash pool Flex justify Center let's give it items that's Center as well let's give a transition and hover border Dash neutral Dash 300. and I'm just gonna collapse everything here because we have a lot of classes and I made a mistake so it's a group great so now you can see this all right and now I just want to put an icon here so let's go into react icons and let's write Chevron and I want to use this bi Chevron down icon so I'm going to go here and I'm going to import bi Chevron down from react Dash items slash bi all right and now go into your newly created uh div right here and just paste the bi Chevron down button all right let's see how this looks all right we have this new button here uh I just want to give it a couple of classes so class name backslash white group Dash hover slash item text that neutral 300 W4 actually this is enough all right great now let's just give it uh a larger size so size 30 to the right great and what I want to do now is add an on click here which is just going to say an arrow function open model data question mark dot ID so if I try from here you can see it loads big bug bunny excellent excellent job you have successfully finished the entire project good job one thing we missed though we have the username right here so I just want to fix that to load our actual name so go into your components go into uh account menu and in here you're just gonna fetch your current user so current so data used current user like this you can import use current user from hooks current user and just replace username with data question mark dot name if you try now it's writing your own name and you can actually test this out amazing amazing job all right so to end the video I'm going to show you how to deploy this on Virtual so go into your GitHub and create a new repository in my case it's going to be Netflix deploy tutorial you can choose public or private create a repository all right now in here you see I have 19 changes here so make sure you commit all of those so I'm going to go in my terminal git add click permit.m final all right and now since this is an existing repository right here I'm gonna add this origin right here and push everything all right and if I refresh right here you can see I have this Netflix display tutorial right here all right and now in order to deploy inversal we need to not have any warnings in our project but as you can see we have this warning right here for every image that we are not using so I want you to go into slandrc.json right here and we're going to add our own rule so open the rules object and write at next slash next slash no slash image Dash element and just write up all right now let's test our project and see if we have any more warnings so go ahead and run MPN run length foreign great now let's go in in our virtual dashboard now make sure when you create your reversal account you create it with our with gitflop if you don't you're gonna have to connect GitHub additionally so go ahead and click add new project and it's actually going to recommend you this um repository right here if you made it private you might need to do some more options here but just make it public and it's going to be right here click import all right and now we have to add some environment variables right here and if you remember we do have some of them all right so database URL is first so let's copy database URL here and paste it here and click add next out the jvd secret is next let's pay paste that as well next Out secret next paste that as well then we have our GitHub ID paste that we have our GitHub Secret paste that we have our Google client ID make sure you copy the entire and Google client Secret make sure you also copy the entire one all right and now let's click deploy and see if it works all right and just like that we have deployed our project to Virtual so let's go ahead and click here and there we go we have our domain which in my case is Netflix deploy Dash tutorial.personal.app and let's try and log in so new at mail.com123321 and just like that it's working great great job if you finish this entire project I think this is going to be amazing for your portfolio and props to watching this whole video thank you so much and see you in the next one foreign
Info
Channel: Code With Antonio
Views: 205,224
Rating: undefined out of 5
Keywords:
Id: mqUN4N2q4qY
Channel Id: undefined
Length: 253min 20sec (15200 seconds)
Published: Sun Feb 26 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.