Build and Deploy a Full-Stack E-Commerce:

Jio
By -
0

       Next.js 13, React.js, Typescript, Tailwind, Prisma, Stripe


  hello everyone welcome to this course in which we will be creating a full stock e-commerce web app using next3 react typescript T CSS for design Firebase storage for storing images Prisma and mongod DB for handing the data and we will be processing payment using stripe        

        so this is an advanced course I'll expect you to have basic knowledge of working with react and al

        so to have created       me backend apis using any programming language uh maybe no JS and JavaScript or any other at least to have      some knowledge about apis okay this is the application that we will be working on and in this epi

        sode I'll give 


        you a walk through of this application it is a full stack application it has a lot of features but it will really help you to understand how to create full stack applications using react and next3 now we'll call it E

        soP for electronic shop or e-commerce shop at the top here on our Navar we'll have this search bar
        so we are able to search anything in our shop we can search for TV and when I click on search then it will filter down the TVs only can click on all here to get all the products uh we'll have categories
        so we can click on phone and it will get only the fonts we can click on laptop

        so if we don't have any product it will tell us this can click on Watch and

        so on at the top here 


            we'll see how many items that are in our cut and then we'll have an icon here that allows us to log in and al

        so we'll have

        some more links once we are logged in for example viewing our orders right here you can add a banner which is advertising

        something in your shop EG offering a discount and

        so on then down here we'll list our products in cards and we'll show a preview using an image name uh we'll have

        some reviews in our shop

        so we'll be able to show the reviews and the price of the product then at the bottom here we'll have a phoo now once we click a product here we'll be able to see uh the reviews of that product then we'll be able to select multiple colors for the product

         
            we can do it from here or from here which is awe

        some then we can change the amount of quantity that we want to add to cut and we can add to cut we can view the cut using this button and our cut will look like this from the cut we are able to increase or decrease the quantity uh we are al

        so able to remove the product or Cate the cut and we can al

        so continue shopping and it will take us to our list of product let's add a watch let's change the color and we can add two of them although this is out of stock we able to add it to cut but you can make it to be such that U you are not able to add the product cut if it is out of stock

        so in this case we can add it to cut

        so let's just add it to cut and we will go ahead and view the cut right here we can't check out because we are not logged in

        so we are told to click the button to log in and we'll create an old system where we'll be able to continue with Google or we can use an email and password we can log in or we can sign up for an account

        so let's log in with Google here and this will allow us to select one of the accounts that we want I'll select one of my accounts here and we are successfully logged in we see now we are able to check out now one cool thing that will happen is that


                 once we click on this check out it will create at our stripe what we call a payment intent okay

        so as you can see all these have succeeded these are all the payments and once we click this it will create what we call a payment intent and al

        so it will create a new order in our database

        so here we have another link here uh which I can open on a new tab which will take us to our orders for this particular client okay

        so we have all these orders and here let's check out and once we check out these will rad the checkout these are form elements from stripe which will allow us to perform payment without going to a different URL we are still in our eCommerce app now if we check it here and we refresh our payments at stripe you'll see that uh we will have what we call a payment intent which will be created but the payment status is incomplete we are trying to pay 180 and that is what exactly we are trying to pay here 





            now if I come to my orders again and refresh here you will see at the background it was able to create this order but the payment status is al

        so pending

        so let's go ahead here and we can actually be able to modify this order

        so if I come back and we add another product let's say this keyboard let's add two of them and we add to cut and we continue now we have a different amount

        so if we check out uh what this will do it will not create a different order but it will uh update our existing one which has not been paid yet

        so if we come to the orders and we refresh you'll see that this has been updated uh to have all the three products we can view an individual order and you'll see all the three products are here and we added this keyboard

        so it is not uh creating a new one it is updating the existing one and the cool thing is that it will al

        so update our stripe here it will update it and not create a new one

        so it will use use this ID to update it okay 



            which is really cool this prevents us to have a lot of transactions which are incomplete

        so now uh we can continue here to perform a payment uh I'll enter a name an address then down here we can use um a test card just like that a future date and a CVC now I'll perform the payment and payment success and we can view the orders

        so if we come to stripe and we refresh here you'll see that and now the payment has succeeded for this one and this will fire what we call a stripe web hook on the background

        so today I had already added this one

        so if we refresh we'll now have another one right now

        so it will fire this web hook and this web hook will update our order in the database and it will mark it as are paid

        so if I view my orders here you'll see that now here the payment status for this is paid 3 minutes ago

        so it is working okay awe

        some

        so that is how we'll perform the payment and then uh we will be having an admin dashboard for this particular application

        so if I come here we have this admin dashboard right here from here we'll see the total orders the toal paid orders and paid orders total users in the system total products in the system and the total sales that we have made using our system down 


                here we'll have a graph showing the amount we have made each day right here for the last 7 days and then uh we'll have more stuff here like manage orders

        so for manage orders we'll be able to view all the orders in the system using this table and this table is what we call a rich data table it has a lot of stuff for example it has pagination here we can change the number of items that we want per page we can select all products we are able to perform

        some filters right here we can filter with uh ascending descending and

        so on we are able to search

        so here we are able to filter by searching

        so we can write pending and this will only give us the orders whose deriva status is pending we can have derived and this will give us all the derived orders

        so this is very cool um we can change the operation contains equals start with it's a very rich data table


             which we'll create in this particular course uh another thing is that right here we are able to mark an order s disp patched or as derived when an order is pending this Cent is not able to give reviews to those products

        so right now we are not able to give reviews to the products that we bought for example we can go to ritech keyboard uh

        so here at Logitech we have this product we have bought it but since it's not yet delivered we cannot uh perform the review but right now we can mark it as dispatched using this and we can mark it as deriv using this and the cool thing is that now if I come here and refresh 



        since it's now derived we'll be able to rate this product

        so here I can give it five star and I can say um good and then I rate the product once we rate we can only rate it once

        so once we rate it we no longer see that input fi anymore but our review is here and our total review is calculated al

        so here which is awe

        some now we have added that rating okay that is how our uh rating system will work we will have another Rich data table for managing the products

        so we can see the products that are in stock the prices the names of the products and

        so on we will be able to change the status of in stock or out of stock using this button and then here we will have a button which we can use to delete a product then we'll have this one which we can use to view a single product now here we al

        so have adding a product let's add one of the products we can say another iPhone 14 this is a damy product

        so don't worry about the naming a random price then the brand is Apple a random description

        so I can just say short desk then 



            we'll say this product is in stock it is a f we select the category now here the thing we can select multiple colors and we upload an image for each of the colors

        so we have this iPhone 14 white we add it then we have gray we can add that image here

        so we have selected the images but they are not yet added to our fireb storage which we will use for storing the images they will be added once we click add and together with all the details and the links to those images will now be saved to the DB

        so click add and here creating the product and this might take a while we wait and there we go product created now when we go back we will see that we have another iPhone 14

        so we have two we have this iPhone 14 and we have another iPhone 14 here and here you'll see now we have two images they were already added to fire Bas storage and we can add this to cut which is really awe

        some another cool thing is that if we go back to admin dashboard here manage products uh we'll have another iPhone 14 here and we can actually delete it

        so if I click delete deleting the product and the product is deleted and we no longer have it

        so yeah this is the application that 


            we will be working on and I already hope that you will enjoy you learn a lot of stuff from react using the current version of next GS which is next 13 you learn how to use typescript Ty and CSS using Prisma and mongod DB to handle the data and

        so much more as I said before this is an advanced course

        so I'll expect you to have already worked with reactjs

        so you have

        some experience working with State react components react hooks and even more on react al

        so I expect you to already have

        some basic knowledge about apis you have created

        some CR operation apis

        so if you don't know what is Crow operation uh most probably this course is not best for you

        so you might have created this apis using a no JS or any other programming language and then we will be making use of typescript in this course

        so I expect you to have

        some basic knowledge working with typescript

        so if you don't you can just take a crash course on YouTube or go through typescript documentation and then you'll be good to go and proceed with this course 


            I want us to start by creating a nextjs application

        so here I am at next js. org and all you need to do is to click on get started I'll come to installation and right here you'll see there are system requirements of creating an xjs application the first thing that you need to have is not JS version 16.8 or later and if you have been working with react I'll be assuming that you already have this installed but if you don't have all you need to do is to download and install no JS in your machine I recommend going with the recommended for most users here uh because I think it's more stable than the current one now after installing NOS all you need to do is to come right here and we need to run this Command right here to create the next Js application now right here we have at latest and this will give you the latest version but I recommend going with the version that I'll be using in this entire course uh

        so that things don't break for you which works for me okay but



             if you will be able to handle the versions uh well you can proceed with this Command right here which says a trest for me I'll straightly uh change that command uh

        so that you can install the version that I'll be using in this entire course okay

        so what I need to do is to come to this folder which I already created called eShop this will hold our application and I'll open this folder with Visual Studio code which is my preferred code editor

        so you can use the same if you want to have the same experience as me or if you want to follow along

        so right here I'll type CMD and what this will do is that it will open this path on command prompt

        so I am on Windows here and from this command prompt I can use this command to open uh this folder on Visual Studio code

        so this is how I usually do it but there are other ways of doing it uh you can click on file then you can click on open folder to proceed okay

        so you should have empty space like this and I'll open a terminal I'll be using this inbuilt terminal here npx then create then hyphen next then hyphen up but right here I'll not say a trest but I'll paste um this version here

        so for me this is the current version uh 



         I recommend that you run this command as well

        so that you work with the version that I'll be using in the entire course

        so that if things are working for me they al

        so working for you

        so if you use the latest version uh things might not work the same but al

        so if you'll be able to handle the versions and

        so uh any bugs that will occur then uh I recommend you can as well go with the latest version okay

        so this will be up to you

        so here I'll click on enter

        so I need to give my application or project a name and I'll use a period here

        so this will take the name of this folder as the name of the project

        so I'll hit enter would you like to use typescript I'll say yes would you like to use yes rint I'll say yes would you like to use T CSS I'll say yes would you like to use SLC directory I'll go with no will you like to use app router which is recommended

        so this is the current version now uh which makes use of server components and the app folder with a new routing system

        so I'll say yes will you like to customize the default import allias I'll go with the yes here and what import Alliance would you like to configure I'll go with it now this will fire up an xjs application and then it will install all the dependency that are required for our application to run

        so this might take

        some time

        so give it

        some time to install uh as I will be doing here

        so mine has successfully installed all the dependencies and you can see now we have all these files and if I come to package.j

        son file you'll see all the dependencies that were installed and here are the scripts for working with our application and to run the application we'll be making use of this Dev script here

        so to start our next JS application I'll just say npm run Dev and this will start our application on Local Host uh 3000 okay

        so here I'll just hit control and then hit this Local Host 3000 and here we go now our next 1 application is successfully running here and we have successfully created an xjs App all we need to do is to start working on our e-commerce application we'll start to explore our next3 application which we have already created and we'll start by checking at this app folder and later on we'll be adding many folders and Pages inside this app folder and we'll see how we'll do it but for now let us check at this layout.


 TSX file and in this file you'll see that we are uh defining a component called root layout and every next 1 application we'll have this root layout because this is the start of the application this is where we Define the major tags like HTML and the body tag right here and then for us to Define

        some title tags description tag for SEO purposes you'll see here we are exporting an object called metadata and this object has the title and the description here and you can edit these properties for them to fit your page needs

        so right now the title says create next app now this create next app it's at the top here this is the title of the page

        so I am in a position to edit it for example I can say that this one be e uh hyphen shop and once I save you'll see that these will update at the top here eShop and you'll see it's here and if I inspect this page and come to elements uh okay let me scroll down here right here you'll see our title and then you'll see a meta tag with the description and the description says generated by create next app

        so that is this description right here which you can as where edit

        so can say e-commerce app just like that and then save and once it reloads you'll see that now the content changes to e-commerce app and here you can add even more properties for SEO purposes but will not go through each property now later on we'll be creating nested layouts and for each nested layout you are in a position to al

        so Define a meod data object for each of them now here we are passing children prop and then this children prop we are using it down here we pass it inside our body now this children prop is our different pages in the application and we'll be seeing how we will create different pages in the application but for now we already have one page this page right here which is our home page as you can see it's defined here as home and here we already have

        some content and this is all the design that we see right here at our app it is designed using Terin CSS and we will be using Terin CSS in the entire course but for now we don't need all these okay

        so what I can do I can just highlight right here and we can remove everything okay and I can say here main we'll be perating it later with our own content and I can say e Dash and then shop I save and then if I come back here you'll see now we have edited everything and we al

        so have this dark mode and this dark mode um it's because of our glo. 


        CSS Styles

        so we have this Styles we have this uh directives for working with d and CSS and then we have all these others

        so what I'll do I want to start a brething from scratch

        so I can just remove all those other styles and remain with this

        so I'll go ahead and save and now we don't have any Styles uh the dark mode is gone

        so here you'll see we have explored our globo do CSS file it will only have those directives we have the layout here we have explored different properties here let me change this to Capital letterer and then uh we have the root layout with the HTML and the body tag which accepts our children and our children is the different pages in the application and one of the page is this one although we will be adding more now we al

        so have this image component we'll be taking a look at it later on uh but for now we are not using it


         

        so I'll just remove it okay and I'll save that file want us to see how we can add our own fonts in an x13 application

        so I'll go back to the layout folder here and I think I can zoom it a little bit here and from here you'll see that we are creating this constant called inter

        so this will be an object which is created by calling a function here enter and this enter is coming from next stroke font stroke Google

        so next3 already integrates Google fonts

        so right now I want us to uh add a font called popins

        so for now let's remove this enter and we will bring in popins and you can see it's suggested here and then right here these popins that we are importing here will be a function

        so we call it right here and we pass this subsets to be Latin but now this one expects us to al

        so pass

        some more properties and that is the font weight

        so we need apart from subsets uh we need to add font weight

        so right here I'll add a comma and then we will say wait a full column and we include this square bracket then we will add 400 and maybe uh 700 for bold



         

        so here I'll say 400 then 700 will be bold one you can even add more font wids in that array okay now once we do this you'll see down here for us to apply the font uh we were calling iner do class name

        so this object that we create right here has a property called class name and that will apply our font uh to uh any element that we target

        so in this case instead of saying enter we will say popins

        so popins right here and when you check at this font it will straightly change if I save this file

        so I'll go ahead and save

        so uh the change was minimal but it definitely uh actually changed the font here okay

        so that is how we are able to add our own fonts from Google fonts in next 13 we'll talk about our application layout

        so if we come to this one this is the the r website you'll see at the top we have our Navar and then we have categories and then uh in here at the middle we'll have our content and then at the bottom we'll have our footer

        so I want us to get this basic layout done uh before we get to more complex uh stuff

        so we need to create a enough bar we need to create a footer and

        so on

        so to add components in the next starting app you can add components uh at each page level uh because when adding pages we'll be creating folders for each of the page

        so you can add components at each page level or you can add a folder called components for different components that you might want to have and structure them there inside folders uh it will be basically up to you

        so in this case I'll just add a new folder inside the app called components and then insert this fold folder I'll add yet another folder called na

        so here is where we'll create our different components for the Navar

        so let's go ahead and inside the now folder add now a file and we'll call it Navar uh DSX 



            

        so we are using typescript and then right here I'll say sfc and hit enter and this will create a small snippet here which I can use to fill our component

        so I'll say n bar

        so for you it might not work the same because I am using an extension called Simple react Snippets

        so if you want to make use of that shortcut sfc you can just go to extensions then search for simple uh react Snippets this one here and then you install it and then you'll be able to make use of that shortcut uh right let me show you where it is this one here it basically creates a state R functional component okay here we need to return

        something and we can say div and we can say this is our na bar

        so I'll save inside components I can add another folder called footer and then inside this fter folder I add a new file and I'll call it footer and then do TSX and I'll use our sfc and I'll say foter now right here I'll go ahead and add a div that says footer

        so we have created two components the footer and the Navar and we can now make use of these components inside our layout. TSX file here we had body and here we had children

        so what I'll do I'll just hit enter and I wrap these children with a main tag

        so I'll basically say Main and I'll pass this children right here

        so I'll Tab and paste the children here and uh I can save

        so if I come here we al

        so head main

        so let's change this to just a simple div okay




             

        so that you only have one main at the layout okay now back to our layout I'll hit enter here and here I can add our n component above the main I can say n bar here and it will be Auto imported at the top from our components n n Bar and then down here we'll have our footer uh I didn't Auto Import it I can come back here and end here before clossing hit control space and then I'll have the suggestion to Auto Import it and we autoimport it like that okay

        so now if I save and come back to our E

        soP you'll see now we have Navar E

        soP and footer but we need the footer to be at the very bottom Nar to be at the very top i

        sop to be at the middle now for that we need to add

        some styles for this three and since we'll be adding more components in this particular file we can wrap this three inside a div

        so that we add styles for those only okay

        so here I'll add like this and then I'll save and right here I can add a class name and I'll add

        some teres classes

        so we will display Flex then we'll change the flex direction to column and I'll set the mean height uh for this div to be screen

        so this main height screen means that it will occupy the viewport height uh to be the minimum okay and then if I save you'll notice that nothing's happened but to make it work we need to come to the main here which will be our main body and here we'll add a class name and we will set Flex uh hyphen grow like that for the main to grow okay and





             once I save now you'll see we have nav at the top then we have E

        soP

        so E

        soP will be right here then we have footer

        so if I happen to give this main a BG color you'll see where our main is okay

        so BG uh I can just say black and save and look the whole of these is our main and this is why we'll be having our main content

        so we'll be adding content rator for now let's just have that

        so I'll save and I have just removed the background color

        so yeah this is how our layout will look like now I don't want to use toal black for our Pages uh therefore I can come at the board here I can use um back here because I want to add

        some more class names and then I'll use the money sign to call our variable here then use blackets

        so here I'll just say text hyphen straight hyphen 700 and then I will save now this will not be uh total block cool we need to create a container component that we will reuse throughout the application for different pages if I come to our nextjs here and expand this you'll see that our app starts it's a certain point here and it is like inside a container and even if I uh zoom out you'll see that everything is inside a container even the footer the content and

        so on

        so here I can just expand and I'll do that inside our app components and I'll do it at the root of the components because we'll be reusing it in different parts of the application in pages and al

        so in other components

        so I'll add a new file container. TSX we can create it sfc and I'll say container uh we return a div and this div will be accepting children okay

        so here I'll say children and this children we will be receiving it as plops

        so here we can add children but we need to define the types for these children remember we are using typescript

        so to Define the types uh we can go up here and we Define an interface of container props and here we will be having children and the type for this will be react dot uh react node and then we can make use of this container props I can just copy it and we'll make use of it here I use a full coron and I'll say that this is a react do functional component FC and then we use this angle blackets and we pass our container props right there and you see now that error has disappeared

        so basically what we have done we have passed this children props right here and defined an interface for that okay now we need to pass different styles for this container therefore I'll be making use of a class name

        so here I'll say class name and I can just enter here

        so that you see what I'm typing clearly 



             we'll have a Max a hyphen width of uh maybe 1920 PX

        so this will be the max WID okay

        so 1920 PX and then here margin along the x axis will be outo

        so what this will do will make the container to be at the center and then here we can Define

        some responsiveness uh I'll say XL uh this is extra large screen we'll have a padding along the X AIS of 20 and then we'll do MD and we reduce this

        so PX for this one uh will be just two this will be equivalent to 8px

        so this is padding along the x axis now here I'll just add a default PX

        so this is for the smaller screens and

        so on uh hyen 4 and I'll save

        so this is our container and we can make use of it in different parts of the application let us work on our Nar component

        so we want it to be like this we will be having E

        soP here we'll be having a search component we'll be having this component then we'll be having this we need to have a parent div which is this one and we can add

        some styles for this

        so I'll say class name and then right here um this will be a sticky Nar

        so whenever I scroll you see it remains at the top but when it's at the top it's uh positioned relatively meaning that it's occupying the space there that's what a sticky mean

        so when we Inc INE sticky we must include another property which is top and we set it to zero now here we will want the width of this to be full and then we'll have a BG of St and then Dash 200 and then we can add a zed index of 30 we can have a small Shadow on it if I come back here if I save this and come back here uh we have this right here I hope you can see it this straight background there for our n

        so let's remove this nve I'll start by adding another div and for this div we'll use it to set our padding

        so here

        so padding along the y axis of four and then the Border here uh to be bottom and al

        so I'll just say one PX

        so I enter a custom value here of one PX

        so that will just give padding to our nve bar and al

        so create a border at the bottom a small line okay now here we will use our container because we want to enter the content for our naar container uh make sure to import it from this container 

            we'll have content in here

        so I'll add another div and inside this div we will have our E

        soP logo and that E

        soP logo will will be a link

        so I'll use a link component from next uh JS right here I say eShop in here this link component expects us to pass a hre property and we will set this to go to our homepage I can save and we see this i

        sop right here and we are able to click it for it to go to the homepage okay

        so after the link we will have our search bar but we will will not be adding the search bar right now okay but we can just add a press holder and I'll say search I'll add another div

        so we are just adding the basic structure of our Navar

        so here I'll just say cut uh count and then down here we'll have our user menu okay I save

        so for this div we will add a class name and we can add the Styles right here we'll display Flex

        so by default the flex direction will be in Arrow

        so if I happen to save that you can see everything have changed into Arrow items will be Center uh we'll justify the item P between and then we'll add a gap here of three and finally 





                We'll add MD uh to have a gap of uh zero now down here if I save you'll see that these are not arranged nicely these two

        so we come here we can add a class name and we'll say flex and then we'll say items Center and then right here we'll have a gap of uh 8 MD full coron to have a gap of 12 and

        sorry here we should have added full coron as well

        so I'll save and there we go

        so we have cut count user menu search bar will be here E

        soP is here okay now for this search bar will not show it on smaller screens

        so what I'll do I'll just add a class name and then I'll say hidden by default but on larger screen from MD to have a display of block

        so from hidden to block I'll save and if I minimize the screen here you see search is hidden but if we come back it's there okay that's good now this eShop I want it to look like this this styling uh if you have an image you can add it but for me I just changed the font

        so in

        some few videos ago I showed you how to add the font uh from Google

        so here we need to import our font uh function

        so I'll say import and it will come from next Google font and now right here I can define a constant for it

        so I can say con red dress to be equal to Red dressed uh we invoke it we pass subsets here

        so subsets full colum to be Latin and then it expects us to al

        so pass uh the font we like we did with popins

        so here I'll say wait and full colum per

        son only 400 and we can now make use of this red dress at our logo here

        so I can say class name and here we say red addressed then do class name now I'll save and there we go it has changed we use the D sign like that okay

        so that we are able to add more Styles here and I'll say font to be bold

        so font hyphen bold and space I want the text to be arage

        so I'll say text hyen I'll say to Exel and I'll save and there we go now we have our logo there and we have created our basic Navar right there we'll be adding this components as we move we will get our foot out of the way uh because it's static these links are not functional it's just a UI uh we'll use

        some icons here and for this icons we'll be making use of react icons

        so we need to install that Library this one

        so we need to run this command

        so I can just copy it and back to our app here uh what I'll do uh I'll bring our terminal and add a new terminal using this plus um and install that

        so npm install react icons D Das save I'll hit enter as that installs um let me cross all this and we minimize everything app components we will work on our footer

        so we will have a component called footer list and what fooa list will do is that it will help us to uh list these different links or items

        so right here at footer I'll add a new file and I'll call it footer list

        so footer list. TSX and I'll hit enter

        so this will be a stess functional component and and I can say foter list just like that then right here can say div uh we can use Terin CSS to stud it I'll just add a class name and we can add different styles I'll start with the width will be full uh on small screen we'll have a width which will be 1 / two 1/ two then we enter on medium screen we'll have width which will be 1 over4 on large ones we'll have width to be 1 / 6 we'll have margin to the bottom of six and then we'll have Flex Flex column then we'll have a gap of two and that will be it

        so we need to include children here I'll include a tab and I'll say children

        so we'll receive this children as props here

        so I D structure children like that uh we need to Define the types let's define an interface which will be footer list props and here we'll have children full column react dot uh react node all like that then we include that right here

        so react. 



                    FC we include our angle bracket and we include our footer list plops

        so I save now this will high save us

        sometime when creating those RIS

        so back here at our footer instead of div I'll say footer

        so footer we'll have

        some class name we'll include a background color

        so BG straight and then this will be 700 we'll have text St to be 200 and then we will have text to be small and margin to the top will be about 16 that is about 64 PX inside the footer we need to wrap our content with the container component we created area

        so here I'll go ahead and say container and Auto Import it from container right there and right here okay like that now inside the container uh we can add a div and this div will help us to to organize our content it will have this this this this let's add a class name and for this class name we have Flex Flex column MD we'll have a flex of row justify between padding to the top of 16 and padding to the bottom of 8 okay and then right here we can have our footer list component it expects us to pass

        some children we will start with a H3 and for this H3 we'll say shop categories I can just copy and paste this one right here and then right here I'll make use of the link component

        so link from next link right here we can include our content

        so the first one will be fonts and right here we include our hre to be just hash it won't go anywhere just hash

        so okay I can use the quotes then hash

        so this is our first link when I save uh it format I'm using PR here okay I will duplicate this

        so I can use alt shift and then the bottom Arrow

        so we'll have one for laptops we'll have one for Des desktops uh watches TVs and acces

        sories and this one uh two acces

        sories uh just like that now when I save we can preview that uh I refresh and here we have it okay it's already resisting them nicely uh we just need to sell these shop categories right here uh to be bold okay okay

        so that is this heading we will add a class name we'll just say text to be a bit little bit bigger

        so text will be base and then we'll have font to be bold bold and then we will add margin to the bottom of two and I will save 



                

        so this is now bold awe

        some now we need a similar thing for custom services

        so this will be easy we just need to duplicate the all of these

        so alt shift bottom Arrow we'll duplicate it then we'll still have a heading that will say customer service

        so I can paste it here and then here we'll have contact us here we'll have shipping policy okay here I had included watches but we don't need that I'll just add FAQs

        so I'll remove the rest and save and now we come back here and we have it here okay it's coming along now we'll need this and this

        so let's do that I div I class [Music] name and width will be full but for MD uh width will be one over three and then margin to the bottom will be six and then MD margin to the bottom will be zero we'll have our heading it will be similar to this one

        so I'll copy that one paste it here and change that to about us

        so about us then after heading we will have a paragraph

        so I'll say P tag uh which will have a class name class name and we'll include margin to the bottom of two and we copy this copy I'll paste it here and I can include that full stop and we'll have another paragraph for the art sign we'll use this end and then I'll say copy and I'll include a semicolon like that

        so that will create the art sign

        so if I save this one come here now you'll see we have that sign at the bottom there

        so let's come back here I'll use

        some JavaScript here we'll just say new date at the end here do get full year and then we invoke it as well and that will get us the year and then right here I include

        some space I'll say e uh and then I'll use this tier sign shop uh full stop reserved and I'll save awe

        some

        so one last thing is this one uh after this div after this one uh we can include our footer list let's include it as a component

        so that we get a suggestion for it

        so putter list like this then in here we will have a heading similar to this one

        so I'll copy it and paste it here and right here we can change this to follow us like that and then down here we'll have a div for the icons and right here we can include a class name for them to be aligned horizontally we say F and we include a gap of two okay cool now right here we need to include them as Rings such that you can click them

        so I'll copy one of the links here like this one copy and I'll use it right here like that uh but instead of text we will use icons okay

        so here for example we will say MD and Facebook

        so this is the Facebook icon um it is not suggesting an outo import

        so we'll import it Manu but for now we can al

        so include a plop called size like this of 24

        so for the first icon we need to import it manually here

        so here let's say import we D structure MD Facebook and this will come [Music] from react hyphen icons and then uh stroke 



                 MD and I save

        so if I come back let it reload ah there we go we have this icon there

        so we'll have more icons let's duplicate this one three more times Al shift bottom Arrow three more times okay for this one we'll not use an MD icon we'll say AI we'll say F uh Twitter Circle we need to import this one manuary

        so I can duplicate this one then here I'll P this one but this will come from a different module which is AI I'll save and come back at the bottom and there we go now this has changed to Twitter awe

        some

        so we need to do a similar thing for these ones I'll copy this Instagram and I'll add it here then I'll come back copy this YouTube [Music] and add it here

        so AI Feel YouTube is not there they supposed to be small and this is supposed to be small okay there we go awe

        some

        so if we check this will be our footer and our footer just make our shop to look nice awe

        some I want us to create this burner right here I'll just go to components then add a new file uh we can call it home burner

        so home banner. TSX I'll say the functional component and then home burner

        so we can return a div this div is the parent div for the burner but we'll have another div for this content right here

        so here we'll be having another div and then inside this div is when we having two sections this one here for text and this one here for the image

        so this is the structure of our banner and all we need to do is to fill everything with content and add the Styles

        so let's start with the styles for the parent div here you just need to say class name we'll make sure that the banner is positioned relative the BG will be gradient

        so I'll say BG uh gradient I'll say to write from sky this is sky blue color 500 and then to Sky 700 and we'll add a margin to the bottom of eight and then I'll add

        some class names for this second div here

        so I'll say class name we'll say MX AO

        so this will position it at the center and you'll have a padding along the X AIS of eight and then we'll have a padding along the Y AIS of 12 and we'll display Flex for small screens will the flex direction will be column



             

        so Flex column we can add a gap of two and then for medium screen and above we'll have a flex direction of row and items will be at the center here we can justify content to be evenly

        so that is this section right here

        so on small screens the text will be at the top the image at the bottom

        so that is the Corum then on medium screen and above then they will be side by side that is when you are changing the FX Direction here to row now we have this div right here and this is for this text

        so first of all we can add the text here we will be having a H1 this will say that this is a sum sale we will be having a paragraph enjoy uh discounts un selected items al

        so you'll have another paragraph get uh 50% off

        so that is the content for there and let's save and actually let's Now hook this up to our page

        so that we can see it

        so I'll come here and we'll come to this page right here

        so here we didn't have much we just had this eShop

        so we can just remove it I will wrap everything with our container component

        so I'll say container now in this case I can wrap this in a div and I'll say that we are passing our home Banner just like that at the parent div right here I'll add a class name and I'll say let's have a padding of eight

        so that will be for this main content okay and I save now if now we go to our app here and preview we already have this

        so we will come right here at this div

        so for this one we'll add margin to the the bottom of eight for medium screen and above margin to the bottom will be zero text will be Center

        so here let's al

        so add a class name and we'll make the text to be 4 XL and then MD we will make the text to be uh 6 XL and then font will be both we can change the color text will be white and finally margin to the bottom uh just for



             

        so I'll save there we go now we have this summer sale we go to the paragraph here we add a class name and here text will just be large LG then MD text uh will just be extra large text will be white and finary margin to the bottom will be two for this one

        so I save and we get the settings for enjoy discounts on selected items now finally get 50% off we add a cross name this will be a bit bigger than the previous paragraph

        so text here will be two uh Exel MD text will be 5 XEL then the color for this one will be yellow 400 and then font should al

        so be bold

        so I save and there we go get 50% off now finally we need to create the other part here for the image we'll set the width for this one to be 1 over three and then the position for this one will be relative and we'll have an aspect ratio of a video for the image image now in here we will use the image component from next uh JS image this will come from next image it should be a self Crossing tag like that and we need to add

        some props here

        so the first one is the SLC prop if the image is in the public directory right here uh we will consider this as the root

        so here we just need to pass the path stroke the name of that image it will be called bner do image and then PNG

        so I don't have that image yet we'll be adding it in a few in this public folder

        so let's continue right here we will say fill and then alt can be bner image we'll have a class name we'll just include object hyphen contain



                

        so I'll save that to the format and here we don't see the image

        so what we need to do is to add it you can add any image you want but if you want to add the same image as me you can go to this URL uh github.com stroke CHS stroke eShop assets

        so visit this rink then you'll get this Banner image and you can download it from here

        so here this is the image that I'm using and you can just click download what I'll do I'll drag and drop it ins the public folder here

        so if I click on my downloads I can drag and drop it on public

        so after adding the image at our public folder still it doesn't show we must have messed up maybe the naming yeah here it should be hyphen

        so let's save again and after

        some time it shows now awe

        some now when I expand this look

        so we have gotten our basic layout for this homepage going we have added this na the banner the footer uh which is awe

        some now we'll start uh getting to more interesting stuff on us to start working on our products

        so we will list the products and then after that uh we'll be able to create these product cards and uh create a page for each of the products for more details and then after completing working with our products we'll move on to the shopping cart and for now we'll be working with u

        some dami data and then data on in the course I'll show you how we can add products to the database and al

        so get them from the database and we will replace the D data with the actual data


 

        so I have prepared

        some D data for you to work with and if you go back to this uh URL here uh github.com stroke chart stroke E

        soP uh assets you'll see that I have added this file just 3 minutes ago just now and this file has

        some D data that we can work with okay

        so what I need you to do is to visit that link then click on products. TSX and uh you can click on this copy this right here copy row file and then we will go ahead and create this file in our project

        so to create this file we can do it out here just click on ADD folder and you can call it utils we'll be using it for different stuff uh and here we can add a new file you can say products. TSX and then in here we paste what we copied okay and it's an example of five products maybe we can preview how each product data looks like okay

        so this is an array of objects okay and for each of the object

        so this is one of the object here and we can see what it has uh it has an ID ID of the product it has a name of the product description of the product price brand category whether the product is in stock or not and then we have an images array for the images array We'll have each image in form of an object and here we'll have the color uh for the image whether it's white green or whatever and then we'll have the color code and the image link this is coming from Firebase storage okay

        so I'll be showing you how to upload images in Firebase al

        so we have here reviews and I don't know if there is the one with reviews uh okay we have this one with the reviews and you'll see the details for each of the review uh for the for the review we have ID user ID product ID the rating comment then when review was created and the user who added that review

        so that is the data for the review

        so let's use this data to list our products here

        so to start with we'll go to app then we will go to page here and this is where we will list our data and al

        so here is where later on we'll be fetching the data uh after the home Banner we'll come here and we will add a new div and then right here is where we will map through our Pro products

        so right here we can just say products we Auto Import it from our utils we will say dot map and here we will get a product at a time and for now we can say that this has a type of any will be fixing that datat as we proceed the course and then right here we just use an arrow function and we should return

        something

        so here let's return for now I can just return a div and for now let's just return the product name

        so I can say product dot name and I save

        so if I save those products are listed here we have all these names right there

        so

        some names are too long and we'll need to figure out a way of making them shorter

        so we can create a helper function to help us uh tranet the text

        so back to the utils we can add a new file and we'll say tranet um text dots and right here we will export const then you'll say tranet text these will receive a string and can give it a type of string it will be another function and in here we will check the string Ren

        so we'll say if the Str str. rength um is rest than 25 then we will just return that string

        so WR return that string then else down here we will trate that string okay

        so here we will return our string but we call our substring array method we invoke it

        so we'll have a string long from 0 to 25 five and then here we will join that string with dot dot dot

        so showing that it's longer than that and this is a help P now uh function right here

        so we can come back to the page and instead of just saying product name we'll say tranet we have this one here it is auto imported from our utils and then uh we call this and we wrap the product name like that

        so I'll save now right here the long string are truncated and we add three dots at the end okay awe

        some

        so we'll be reusing that function uh in many presses

        so we will need to organize our products this way

        so we can use a CSS grid

        so let's do that and then in the next epi

        sode we'll go ahead and create this card okay the product card itself right here at this div we need to add

        some class names

        so I'll say class name and we will display grid grid uh hyphen calls will be two

        so for very small screens you'll have two columns then here you can say SM for small screens we can change the grid here to be calls three and then for larger screens we can have grid of hyphen calls uh hyphen 4 and for extra large screens we can add grid again then hyphen calls and then hyphen 5

        so here it should be a full column and let's add the last one of uh 2 XL or very large screens we'll have grid and then hyphen calls and then iph six uh here we remove this Gap cool and then we add a gap between all our products to be eight and that should do it

        so I'll save and we are just making it to be responsive

        so for this one you see it's three columns we have this this and this and I'll assume that is for this small screen here

        so if we go extra small screens we'll have two columns

        so let's minimize this further this one further

        so small screens you see it's two columns and then uh when our screen gets bigger three now we have four now we have five

        so if our screen is very big we'll have another one here okay cool this is working well on to create a product card which will look like this one to do this I'll go to our components here

        so app components and I'll add a new folder for our products

        so I'll say products and inside this we'll create a new file and we can call it uh product card. TSX and Theus functional component here and we create our product card we'll have a div and we'll have more content in here this component will be a client side component it will be rendered on the client and this page here is a server component remember this is al

        so a component but it's a server component meaning that it's rendered on the server

        so server components uh makes our pages to be faster because they are pre-rendered on the server but we still need uh the client components because we have uh interactivity in client components like on click event and whenever you make use of

        some hooks um you definitely know that that should be a client side component because of the interactivity but how do we differentiate them how does nextjs know which is a server component which is a client component we add use client and this will tell next JS that this particular component is is a client component and we'll be exploring more on client versus server side components as we move on with the cost okay

        so for now just know that this product card is a server component because we have that onclick event that when we click we move

        somewhere else

        so right here uh we need to plan how we will show our our card here okay

        so first of all we'll have app parent div we'll have another div in here for the content and and inside that div we'll have the image we'll have the div here for the name we have rating these one to show how many reviews are there and this one right here

        so here we'll have another div for the content and then for our content we'll have a div that will have the image in here and after that we'll have a div for the name you can make it al

        so a paragraph we will have a div for the rating and here we will have a div for how many reviews we have and al

        so here we'll have another div for the price

        so if I save we have this div which is our container then this for the content then this one is the actual content

        so let's start with this div right here and we will add a class name we will say call a hyphen span of one that means that it will occupy one of the grid uh sections only one it will occupy only one column we'll have a CA of pointer we'll have border and we'll make it custom

        so we use this Square blackets here of 1.2 PX

        so I think we can list them downwards because they are many you can just do this

        so I think this is more readable right for you actually

        so here we we'll have another border and we'll set the color for the border now to be straight 200 we enter we'll have BG to be straight 50 we'll have rounded to be small

        so this means that it will have a border radius and we'll have a padding of two and now look whenever we hover it pops

        so we need to add

        some that animation

        so we can start by saying transition and then on Hoover we will say scale by 105 that is like 1.05 and then right here text will be Center then text will be small okay awe

        some then we'll have this div we'll add a class name we can enter

        so that it's al

        so readable for this and for this one we'll say Flex Flex column items Center width will be full and gap of one okay awe

        some now here we need to add our email uh this component will be receiving our products

        so here we'll be having our data

        so we need to destructure data and al

        so uh we need to Define the types for this

        so for now we can just uh use any because the types that we'll be using here will be coming from Prisma okay

        so we will be fixing them later on we'll have a section where we get to fix the types

        so first of all I Define an interface of data and I'll say let this data be just any and we need to add it here full coron and I'll say react. FC and we will have our product props here in angle blackets awe

        some

        so this data is the one that will have a URL for our image

        so that's why I added it first inside here we will have the image component from nextjs

        so image make sure it's this one

        so that it's Auto imported then we self cross it we'll sa F uh we'll add a class name and for this one we'll have a width to be full then we'll have height to be full then we will have object contain uh we will have an S see here for the path we'll just say data do images

        so by default we will show the first image remember the image is an array

        so we'll say the first image we say image image is the URL to that image okay cool then here we'll have an ALT for the alt we can give the name of the product

        so we can just say data. name cool now here we'll al

        so have

        some classes

        so I'll add class name and we'll add an aspect ratio this is like the container for the image and we'll add aspect of square then overflow will be hidden relative here and finally width will be full and I save for now we won't see anything because we need to bring this product right here

        so instead of saying div we will pass our product

        so here we'll say product card which is AO imported like that it expects us to pass the data plop and we will pass our product right here product and save and now if we come back here we should see the images at list okay we don't see the image

        so we should configure this in next config

        so I'll minimize everything we need to go to next config here we need to configure the

        source of our images which is this one Firebase storage Google ji.com

        so I will copy that and then uh when you open next config here you'll come right here and you'll say images and then full colum We'll add an object and right here we'll say domains and full column we will add uh the square brackets and we'll add this right there in form of a string and I'll save now once we do this for these to take effect we will have to stop and restart our application

        so I'll pop the terminal here it actually stopped by itself

        so we need to actually start it again

        so here I'll just say npm run Dev

        so once it's up we refresh and I can just cross this one and there we go we have this cards and we load the images in there you see awe

        some it's coming along

        so let's go back to the card here and we don't have gap between them I think we must have messed up

        something here Gap should be hyphen 8

        so I save and we should have gap between them there we go awe

        some now let's continue with the rest of the details for this card it's already coming along well just after the image we will show the name of the product and remember we had already created that um util function called tranet to help us trunet the name

        so we'll call that function again tranet text and then here we'll pass data do name

        some we need

        some Styles here we'll add a class name all we need to do is to add

        some margin to the top of uh four I save and we should have the name showing up there we go we have the name showing up and for a large name we have three dots at the end al

        so now the next one is rating and for the rating we'll be using a component from Material UI

        so we need to install material UI just go to m.com then copy this install command and pop your terminal here and right here you can paste it

        so you will run npm install at mui stroke material at emotion stroke react at emotion stroke styled and I'll hit enter and that will install uh material UI in our application and al

        so we will be using it later on in our dashboard okay

        so you can install it right now awe

        some

        so let's skip for this right now as that installs and we go to this one here and here we will have how many reviews we have and that will be data do reviews and we'll say do length

        so this will give us uh how many reviews we have for this particular product and at the end here we will say reviews now here we will include the price but we need to format it

        so we can create a help function for that

        so I'll come here at utils and what I'll do I'll add a new file and I'll say format price. TS right here we will export const format price it will receive the amount here

        so I'll say amount this amount will be a number

        so let's add number and we will return uh we have a builtin method in Java Script for formatting the prices

        so here we'll just say new then in NL DOT number format uh the first parameter we'll say that this is N US Engish us that is the first parameter the second parameter is an object

        so we'll say the style for the for the number format is currency and the currency that we are going to use is USD and then at the end here after calling this we'll say dot format and we pass our amount that we want to format

        so amount

        so this is that function right there and now in our product card right here we will just call that function

        so format price this one we invoke it and we pass our data do price just like that now when you save and come back here you see it formats the price to be in dollars and al

        so include a decimal awe

        some zero reviews awe

        some now this price we want it to pop

        so here we can add a class name and then right here we will say font to be semi bold [Music] we save and it should show

        so now here we can make use of our rating component from Material UI assuming that it has successfully installed

        so here you'll need to Auto Import it at the top I think mine already imported from Material UI and this will accept a value and this value will be a number

        so here if I set the value to be let's say five and save you'll see that all our products will have a rating of five

        so you'll see that all these have a rating of five

        so here we need to add another property called uh read only and save and that way it it will prevent you from selecting the rating if you add a rating of four shows only four if you add a rating of three show only three

        so this is very easy to use and uh if we have like 3.2 it will default it to the nearest uh whole integer

        so in this case it's still three but if we go to five then it will show for

        so it rounds off to the nearest okay as you can see now it's four awe

        some

        so now we need to pass our products rating here and to do that if I show you the products um like here we have the reviews we have this rating and we have this rating we need to find the average for each of the product uh for their ratings okay and to do that I'll just come right here and I'll say const product rating will be equal to uh we will go through all the reviews and then we will use a redu array method to get the average okay

        so here what I'll do I'll say data and then do reviews and then we'll use the reduce array method

        so reduce we will have an item at a time and al

so this accepts what we call an accumulator it's the first uh parameter then we'll have our item and then here we can return using another function
        

so what we will return is item do rating then we add our accumulator just like that
        

so we will divide the entire of these with our review Ren
        

so at the end here we will be having uh data do reviews and then do length
        

so
        

so this will give us the sum of all the reviews and then we divide by the number of those reviews and this will therefore give us the average I hope that makes sense now this accumulator usually have a default value after our logic here if we include zero this will be the default value for this accumulator and therefore it will start like this initially accumulator will be zero item do rating will be the rating let's say the rating is four
        

so we'll have item do rating plus 0
        

so this will be 4+ 0 and the first pass will be four the second pass accumulator will now be four
        

so this will be four then this we will add the item do rating
        

so let's say the next time item do rating is two
        

so we'll take two and we add accumulator which is now four and gives us six and we continue now accumulator will be six
        

so it will continue like that now the rea
        

son that we have these errors is because we don't have the types and uh they'll be re
        

solved whenever we add the types here correctly but for now this will be number and this one we can just say any type and this will give us this product rating and this product rating is what we will now pass right here let's use our product rating and I save and fingers crossed it works
        

so this is five this is five this is nil this is nil this is nil and on large screen it looks like that we'll start to work on our product Details page
        

so whenever I click on one of these you'll see that we are getting to a different route right here and from this we have the images we have details here and we can switch colors we have quantity we are increasing and decreasing quantity and then we have product reviews but before we do that we need to learn how we can create different routes and pages in our application
        

so we'll see how we can create normal pages and uh Dynamic pages in this particular video Let's jump into our code here and we see how we can create just a normal page and we'll try and create these cut page right here and to create normal Pages which are not Dynamic it's very easy we just need to click on app then add a new folder and then you give this folder a name in this case it will be cut and this cut now will be the name of our route okay
        

so this is this will be the name of that appears here okay and then in here we create a new file a t one file which is mandatory which is the page. TSX file and then we create a component for it St functional component and right here we can just say cut and we return
        

something let's return a div and we'll say this is the cut page and I save and this is how we can create a noral route and that way we can go to uh stroke cut and you'll be able to load this particular component
        

so let's see if it works
        

so if I come here at cut okay not this one this is the complete one if I come to the one we are working on on Local Host and then we go to cut okay uh currently I can't click but right here I can navigate manually I can say stroke cut and I hit enter you'll see that we get here to our cut page awe
        

some
        

so to create a dynamic page we just need to click on up again we add a new folder and in this case let's create the product Details page which will be dynamic
        

so we give this folder name and I'll say product and then in here we create another folder and in this case we will use square brackets and in this square brackets we will give our ID a variable name
        

so we'll call it product ID and we hit enter and then now you see it's two folders product and then another folder but the way we name it we use square brackets now we now add a new file inside this product ID here and this file must be called page. TSX it can be TS it can be JS whichever you want and then right here State functional component and we can call this product and in here we can go ahead and say that this is the product page
        

so let's say product page
        

so I save if I go to stroke products we won't get anything
        

so if I go to stroke product I don't get anything this page is not found but if we add an ID which makes it Dynamic like that one a random ID uh we get to the product page
        

so it doesn't have to be a r ID for now it can be even be just stroke one and that will still get us to the product page now that we are in this page how can we access this ID in this particular page we need to accept uh the params prop right right here okay
        

so here we'll be having params but we need to define the type for this
        

so we can create an interface here
        

so I'll say interface and I params and right here we'll have our product ID and this can be optional
        

so I'll use optional it will be a string like that and then the these are params I can pass it right here like this
        

so I can use full coron here and I can say params type will be I params re that and now this params uh will give us access to that ID of the product or the page
        

so right here we can log it the con
        

sole
        

so I can say con
        

sole. Rog of our params
        

so remember this page is a server component
        

so this con
        

sole log will not appear on the browser but on the server
        

so when I save we should check our vs code terminal and not our browser
        

so here you can see params and we have product ID as one
        

so that's how we can access this ID and we'll be later using it to fetch our products from the database okay okay cool now how can we navigate uh whenever we we create a product from here and we move to our Dynamic page
        

so we just need to include a route to our onclick event
        

so what we will do we will go to the product card
        

so we had components then we had products then product card
        

so we'll come to the product card and we will make the entire of this card clickable by using our use router hook
        

so this is this is how we will do it
        

so before defining product rating right here uh I can say const router will be equal to and I'll make use of use router and this will come from our next navigation which is not being suggested for now I'll click on this one but it will not come from next router it will come from next stroke navigation like that and then here I'll make sure that I am calling this like that now we can make use of this router right here we add an onclick event
        

so I'll say onclick and then right here I pass an arrow function and we can return our router do push and right here I'll make use of btic I'll say stroke product now this will be our product path and then stroke now right here we need to add the ID Dynamic
        

so I include these the money sign and the car brackets and then we say data. ID and I go ahead and save now whenever we click on any of this card we will be able to navigate to uh that page for that particular product
        

so here I click on on this page and look we get to this particular ID which ends with an a now if I click on this one the previous was ending with an a this doesn't and if we check at our params here you'll see that we have all this and we are able to get a specific product right there
        

so for us to be able to work on this page we need to have
        

some data and later on in the course we'll be fetching this data from our database using the product ID but in this case we can use uh Dam data or example data
        

so from our utils then products we had this products array now I want to just take one of the products from here and then we will use that data to work on our page and I'll take this iPhone 12 right here because it has most of the uh details that we need
        

so I'll click here then I'll scroll up to here uh before I click I make sure to use shift hold on shift and then click
        

so it will select the entire of that section and then I can copy it
        

so since this is a rot of details to include in our file we can create a separate file for it but later on will just be removing it
        

so right here I'll just add a new file and I'll say this is our actually I think I had created this uh I already have this file called Product here
        

so create a file called product. TS
        

so we will say export uh product like that then we paste everything okay export const yeah there we go
        

so I save and now we'll be able to import this product in our page here
        

so this is inside our product product ID page
        

so maybe if you if I say product here we get this
        

so if I click on it it's Auto imported right here awe
        

some
        

so now we have this product and we can create a new component for our product details
        

so for that component I'll come back here let minimize everything
        

so I'll go to up then product product ID here I expand it and I can actually create that component in here you can do it on the components folder or you can do it on the individual pages
        

so let's just do it in here
        

so I'll say this is the product details component stess functional component product details like that and here let's have a div we will bring this product details in our page here
        

so right here instead of product page let's remove that and uh before we add it let's wrap everything with our container component
        

so I'll bring in container from this one remember not to confuse with the material one
        

so bring this one here now I'll be able to Now call our product details component and uh I can self cross it just like that al
        

so here I'll add a class name and I'll add
        

some padding around our page of eight and I'll save
        

so for this product details we will pass this product as a prop
        

so right here we'll say product and we'll set it to be equal to product but it complains because our product details doesn't expect to receive any props
        

so let's come to product details and we fix that
        

so here we will define an interface
        

so I'll say interface and this will be our product details props and right here we Define our prop product and for now we'll say any the types for this will be coming from Prisma which we will cover later on during the course then right here let's say that this is a react. fc component and square brackets we pass our product details props right there and then right here now we'll be able to receive our product we destructure it from props and I save cool now another thing is that this product details will be a client component it will not be a server component now to Define that this is a client component remember we use use client right here cool now let's come right here and Define the structure of our page
        

so we will use grid remember we have um two main sections for each of the page we have this images section section then we have this section with all the uh content
        

so here let's add a class name uh display grid then for small screens we will have only one column
        

so I'll say grid then hyphen calls one and we can see that whenever I minimize this one
        

so the more I decrease we get one column only the image is at the top details at the bottom but when we get on bigger screens then we get two columns
        

so by default grid calls is one uh MD grid calls will be two
        

so grid hyphen calls will be two Al
        

so let's add a cap of 12 and I save now inside here uh remember we'll be having two columns
        

so the First Column is for the image
        

so here I say div and here we'll be having the images and then we'll be having another div and here is where we'll be having the details
        

so details let me save to Auto format this
        

so we have two Dives in here images and details now if we preview this you see we have images on this side we have details here and if we go to a small section we have we have images at the top details at the bottom
        

so that is coming along well uh we will add this images for now we will work on this details part cool because it's easier to get started with now here we will start with maybe a heading
        

so here we will be having the product do name and if I save we should be seeing it there we go Apple iPhone 12 64 GB but this should be big
        

so let's add crass name and text will be three Exel and then font will be medium then we can change the text color
        

so text here straight 700 and that will do it
        

so if I save now this is big awe
        

some
        

so that is the heading for the image then we come down here the next thing will be rating
        

so for rating we will be using the the rating component
        

so here I can just say div we'll bring in the rating component from our material UI just like that and this rating component will expect us to pass various prop uh the first one is the value and then the other one is the read only because we don't we don't want this to be editable
        

so for this value at the product card we had calculated the rating for each of the products I will go and reuse that
        

so products product card and here we had calculated this product rating I'll just copy this
        

so copy that one you can include it at utils and you'll be able to export it in different files but since I'm using this only on two presses then I can I can just copy and paste it right here before our return statement we will paste it and instead of data we will say product and instead of data here we will say this is the okay product I save now this product rating is what we will pass right here you can see our app is already complaining
        

so I pass it here and save and that Comal go and there we go
        

so we have this rating there awe
        

some
        

so it's working now here uh we'll have a div and here we should display the number of reviews that we have
        

so all I will do is that I'll take our product dot reviews and then dot length and then out here we can say reviews like that and we add a class name here
        

so I'll say class name
        

so we want them to be side by side right now when I save you'll see reviews is down here
        

so to make them side by side we will display flex and then items should be Center then here gap of two and I save and now they are in one line
        

so right here we don't see a gap between them
        

so that is because right here we should add a class name
        

so we can display f and we'll make sure that the flex direction is column and then we will be able to add a gap of one
        

so this will automatically create space between our items and we can add the text straight of 500 we don't want it to be too dark and we'll make our text to be small
        

so I'll save all right now the next one will be the description of our product
        

so right here after this div where we have our rating we add another div and this will show the description
        

so here we can just say product. description uh if I save we'll actually see all the description there awe
        

some
        

so what I want to do is to just justify the text
        

so here I can just say text hyphen justify and I save
        

so if I justify you'll see it's all in one line here awe
        

some now there is one cool thing that I al
        

so added these small lines here between each section
        

so to add those lines I'll actually Define a small component outside our product details right here which we can reuse within this page that's why I'm creating it al
        

so within this page uh we don't need to create it anywhere else it's a small component which I'll call horizontal we pass another function and here we return all we need to do is to pass
        

some cross name here and here I'll say the width will be uh 30%
        

so it will be small you can make it big this will be up to you and then margin to the top will be two and margin to the bottom will be two
        

so in this case what we can do is just say margin along the Y AIS is two
        

so that will be top and bottom and now we have this horizontal component and we can use this horizontal component uh between our different sections of the product details
        

so after our reviews here I can just say horizontal here and we self cross this component and once I save we should have a line here but it's going through all the way
        

so this blacket should be here like that I save and right here
        

so we'll have horizontal like that I save and we'll have another one at the bottom here we will have a div for our category
        

so I'll say div and then here we will start with a span we'll just say category in caps full colum and then out here we will be having the product category like that
        

so we will make this category which is in caps to be bold
        

so I'll say class name font uh actually say semi bold and I save
        

so that will be our category you can see category is phun now I will duplicate this section alt shift bottom arrow and here instead of category we will be having brand and here product. brand I save there we go I'll say div and here we'll say product do instock we'll use this tary operator If the product is in stock then we will show in stock text else we will say that this product is out of stock and I sh up the entire of this section with this carry bracket
        

so instead of including it here I'll cut that and include it at the very end here okay
        

so if I save now we'll be able to see that this product is in stock but we al
        

so want to differentiate the colors
        

so if the product is in stock we show it in green else we show it in Red
        

so here we add a class name and we will dynamically display the class name I'll do a similar thing I'll ask product do in stock and we use a question mark there
        

so if it's in stock we will display text to be till 400 else we will display the text to be reddish color
        

so I'll say text Rose 400 and I save and now this is green else it will be red after our colors we separate that with our horizontal component the next next thing will be to show
        

some button to add the product to cut like this and al
        

so we will show uh color selection and al
        

so quantity
        

so we won't do it right now we'll do it them Epi
        

sode by epi
        

sode
        

so that it's easier for you to follow
        

so for now we can just include
        

some press holders okay
        

so basically uh I can duplicate these two more times one two and then after this first one we will be having our color then here after this let's use a div we will be having the quantity and then after that we'll be having this button to add product cut
        

so div uh add to cut and I'll go ahead and save
        

so if I come back here this is what we have and uh we will create each of these in their own separate videos
        

so that it's easier for you to follow
        

so I'll see you in the next one in this epi
        

sode we will need to create
        

some form of state
        

so whenever this page RADS we will default
        

some values of this product to be instate and then we will be able now to maybe change the color change the quantity and
        

so on
        

so the rea
        

son why we can't use this product directory is because first of all it lacks
        

some properties it doesn't have the quantity al
        

so we will not be including all the images but only the selected image uh together with each color and al
        

so we will not be including reviews when adding our product to cut
        

so we'll create State and then we will default
        

some of these properties and add new ones
        

so to do that we just need to go to the product details and we will start by defining the type of that particular state
        

so here uh export type we will call it cut product because this is the product that we will be adding to cut
        

so cut product and first of all we'll be having an ID which will be a string okay here I missed an equal sign
        

so when defining a type we must include an equal sign here but for interface we don't need to we have an IDE of string name will be string description will be string will'll be having category which is al
        

so a string most of these are strings then you'll be having brand string will be having selected image IMG and we'll set this to a type of selected image
        

so we need to Define that type just right here
        

so we can just say export uh type selected IMG which will be equal to these properties for a single image we have color which is a string and then we have color code which is al
        

so string and finally we have an image
        

so this is al
        

so a string uh I can start with this one with a caps right here and I say selected image type and then I will copy this one and use it here and al
        

so you can say cut product type awe
        

some we add the quantity we can use qty and this will be a number and finally we'll have price and al
        

so this will be a number for
        

some rea
        

son I just like using the full name
        

so we can still go with quantity here
        

so now we have this type and for this type we have the quantity which is not available on our product we have selected image which is a single image while for our product we have multiple images and yeah I think that's the main difference between the two but now we will be able to change the quantity from this and we'll be able to change this one and the rest remains
        

so what I'll do I'll create
        

some form of state right here and whenever you are using state or any kind of hook you must Mark that component as a client component by using this use client okay and that is one of the way that you can be able to differentiate between a client component and a server component because current components are interactive and they will be rendered on the browser okay now here uh I'll set const square brackets cut product set cut product and we set this one to be equal to use state and now right here I can use the angle blets and we pass the type for cut product right here
        

so we say cut product type and this is what we have just defined right here at the top and then here we invoke use State and we pass
        

some default vales right here
        

so the default values will be similar to these ones
        

so we paste them here the only difference is that we are not defining the types but we are including the actual values okay
        

so I'll select all string then use control D to select all this and I remove and now we will set the values for each of them uh here we'll have the product. ID that will be the default value then here we will have the product do name then here we will have our product do description then here we will have a product dot category here we have a product do brand and here we will have a default uh select for this one and how we will do it we will spread product dot uh images
        

so I have not spread this one use three dots here
        

so we get to product. images and then we use the square bracket and we select the first image
        

so when uploading images we'll make sure that we have at least one image for each product
        

so we are sure that these exist at any time and here we will have our product quantity okay we don't have product. quantity but we can default this one to one okay and then the price product do [Music] price and I save
        

so now we have a default product that can be added to cut
        

so at our button whenever we load this page we can directly add this to cut and al
        

so we are able to change the image and al
        

so we'll be able to change the quantity
        

so we haven't implemented the functionality for this uh but we are going to in a few uh now in the next epi
        

sode let's see how we will be able to change this selected image
        

so when we change the selected image that means that we are al
        

so changing the color
        

so the image and the color are like going hand in hand okay don't get confused
        

so I'll see you in the next one
        

so let's finalize working on our color here in this particular epi
        

sode
        

so what I'll do I'll go files then components products and I'll create a new file and for this file I'll say that it's set color. TSX stat functional component then set color and right here we can be able to return just a div this will be a client component and we can Define that it's a curent component by saying use client at the top here use client this component will receive several props
        

so here we will set the interface for this one
        

so let's say interface and we say Set uh color props and the first one is that we'll receive all the images for this particular product and the type for this one can be our selected image type which we get from product details and here we say that this now will be an array okay and then right here we will be having our cut product and this will be having our cut product type
        

so cut product type which you al
        

so get from our product details we will be passing a function called handle color select from our product details value here and this value will be of type selected image type and it will return void
        

so it will not return anything awe
        

some
        

so this we set it to this one
        

so full Colum here and we say that this is a react functional component we use angle brackets here and we pass our set color props
        

so we can receive all this right here
        

so I destructure them from props images cut products cut product that is its one product then handle okay this is supposed to be handle
        

so we add l e there and this one is now handle color select let's hook this component in our product details right where we had our color here
        

so here I'll just say set color this one it expects us to pass the various blops
        

so here let's pass our cut product which will be equal to our cut product we al
        

so pass our images
        

so images which will be equal to our product dot images and finally we al
        

so pass a function which we will call handle color select and here we will call this function handle uh color select but we haven't created this function yet
        

so let's go ahead and create it I'll copy that and we come at the top just before our return here we can Define that function
        

so I'll say const I paste we can use I use call back hook for optimization
        

so instead of defining it directly like this I can just say use call back and then I invoke this one this will expect us to pass an AR function in here and al
        

so to pass a dependency array
        

so I include a dependency array right here we will be receiving a value and this value will be of type the selected image type awe
        

some and right here the dependency for this we will depend on the uh cut product selected image
        

so cut product dot selected IMG
        

so we'll come back to this to fill the body here
        

so for now let's go back to our set color here and we are now passing all these plops right here and we can start by starting it
        

so we'll have this and then we'll have this for changing the colors and they al
        

so switch the image as you can see we need to create a wrapper for this
        

so this will be span this will be in a div
        

so let's do that
        

so here I'll add another div and here we will have a span that will say that this is the color
        

so we can use caps color full column and then down here we will have a div that will have these different colors okay
        

so for now let's add styles for this one first
        

so I'll add a class name and we will display F we'll have a gap between them
        

so gap of four and then we will have items at the center
        

so items Center and now for this color let's include al
        

so
        

some Styles
        

so I'll add a class name and we just need to make it bold
        

so font semi bold will do and if I save you should be able to see
        

something here there we go we have color already awe
        

some
        

so we move on to this one
        

so for this one we will display all the different colors that are available for our image
        

so we need to Mark through them okay
        

so here I include the Cur brackets and we will re use our images dot map uh we invoke this one and we will have an image at a time
        

so image and we can use that to display more about it
        

so here we will return a div okay I can include brackets and just say return like that and now for this div we will only be having mainly Styles okay
        

so this the first one here will be the ring one that is the green one there and then we'll have another div inside it that will show the color
        

so here we'll have two Dives but they won't have any content just the Styles okay
        

so I save to Auto format everything TR and now for this rer div we can add
        

some class names okay
        

so for this one uh because we will be using
        

some JavaScript in here let's make sure that we are using the back ticks and for the back tick let's al
        

so wrap it with uh these car brackets and now we can add the Styles right here
        

so first of all the height will be seven the width will be seven
        

so that it's Square then it will be rounded
        

so I'll say rounded to be full and then we will have border to be hyphen till hyphen 300 awe
        

some
        

so that is the green border we'll display FX and we'll make sure that our div that is inside this wrapper it's at the center
        

so items will be Center and then justify hyphen Center we will use
        

some JavaScript
        

so I'll use the money sign and these C brackets and we will dynamically display this border for the selected image okay
        

so we'll know the selected image by checking at the state
        

so this state here we have this selected image I'll say cut uh product dot selected image and then dot color if that color is equal to our image do color
        

so we are comparing our cut product that is in State uh we compare the selected image color with the color of this image that we are mapping through remember here we'll have multiple
        

so we'll go through each of them then we'll compare with the selected one if they are equal then we will show this ring if they are not then we will not show it okay
        

so after this we use a question mark and this means if the io will now show the border and we'll just include its value here it's withth and I'll say PX else we will not show it
        

so we'll say border to be none
        

so if I save and we come back here you see we see the this ring already
        

so setting the Style by T1 CSS um it was messing up everything
        

so here I'll just use the inline style for the CSS directory
        

so I'll use the style property and I'll set the background for this one
        

so backround full colum to be image then dot color code remember we have color and we have color code
        

so
        

so set color code okay
        

so that will be the background but al
        

so we can add a class name here and for this class name this will help us to set the the height the width and
        

so on
        

so here let's go on and say height now will be smaller than this one this was seven this one will be five and then the width here will be five and then uh rounded al
        

so will be full and uh here the Border for this one we can set it to be 1.2 PX
        

so 1.2 PX and here we will set the Border color
        

so border color to be straight then hyen uh 300 this is not supposed to be full stop but hyen awe
        

some and finally let the ca B pointer let's save and see what we have look we have all this we have set the background color using this style then the styles for the height and the width
        

so let me tab here and save at this div before we map everything at this div we need to add a class name and we will just display FX and we'll add a gap of one let's save and there we go they organized nicely awe
        

some we need to come to this div here after we map the first div and we need to add more stuff here the first one is the key and we will set the key to be our image do color and then here we'll al
        

so have an onclick event and this on click event we call our handle uh color select okay
        

so here we will call our handle color select and we pass the current image that we we are at
        

so whenever we click this we will pass this image
        

so remember this image has both the image and the color
        

so don't get confused they are almost the same thing maybe you can name it image color or you can just choose one
        

so in this case I chose image
        

so what will happen is that we'll receive this image uh let me save first we will receive this image that is selected to our handle color select here is the value okay which is the selected image type and then now we can use this value to update our cut product state
        

so we update this one here okay
        

so let's do that here we'll simply call set cut product which invoke it and here we will have access to the previous uh selected uh cut product okay and here we can pass an arrow function and we can use this previous to update the state here
        

so here it expect us to return
        

something and whatever we will return is we spread our previous state and then we update our selected image and we'll update that selected image to our value the value that we get from here when we select okay
        

so now I save
        

so these should work fingers crossed and let see now we select these blue and we are able to change that image
        

so right here we can just come down here and we'll say con
        

sole do Rog of our cut product like that and I save
        

so let's expand this one we inspect this and we come to color select let's refresh we have
        

some errors okay they are gone
        

so by default we have this image selected as our cut product as you can see we have the selected images black but when I click on Blue now we expand this and we come to selected image look we have blue al
        

so the URL changes to the blue one we select on red and that will change to red like that awe
        

some
        

so our feature here is working rly let us handle selecting the quantity what we need to do is to go to app components products and a new file and we can call this one ass set quantity do TSX stess functional component and you'll say set quantity and here we will return a div we will receive uh several props
        

so let's define an interface for our props right here al
        

so we should make this one to be a client component by using use client we can use interface and we will Define our set q t y props the first one we'll say cut counter and this will be an optional Boolean
        

so since I want to use this count this counter component twice uh this flag will help us to determine whether we are at our product or at our cut
        

so if we come to this one we have this counter here which has this name quantity and if we come to this one we have this one here which doesn't have even that name
        

so this cut counter will help us to differentiate where we are and then right here we will have our cut product of type cut product type
        

so here we'll pass handle Q Ty increase this will receive nothing and we return nothing
        

so void I can just duplicate this down here and now these will be decrease we set those props here
        

so react. FC we include the angles here and we say set qti props right here we should receive our plops here
        

so cut product we al
        

so have cut counter we al
        

so have handle decrease and handle increase
        

so now we need to add the Styles and and we can include a class name we'll display FX and we'll have a gap of eight and al
        

so we will have items at the center now here we will have another div and this div will be for this quantity but I want to dynamically display it depending on whether we are at the page here or at the cut
        

so here I use
        

some C brackets and we'll use our cut counter to determine that
        

so if this is true we display null that means that we are at the cut else we are at the product page and therefore we display a div and here is where we will be having our quantity okay let me make it caps We'll add
        

some class name and we'll make this to be font hyphen semi bold let's save
        

so this is just the title here awe
        

some let's now add another div that we will have this counter on
        

so here we'll have another div and right here uh we'll have a button this will be for decreasing I include a minus then here we'll have a div here we'll have the count
        

so we can just say cut product do quantity and then right here we'll have another a button and this will be plus
        

so leted style this one here we'll add a crass name we can use flex we'll have a gap between them of four and then here we can set them to be at the center using item Center then the text will be base that is the size of the text awe
        

some
        

so for each of the button here here we will have an onclick event for this one
        

so onclick and we'll handle quantity decrease then al
        

so this one we will have an on click and we will handle quantity increase awe
        

some
        

so we need the styles for this button and this button and this Styles will be similar
        

so we can create a constant and then we can reuse those styles
        

so at the top here I can just say const BTN uh Styles will be equal to and I include these quotes
        

so we'll have border to be 1.2 PX space we have border to be straight hyphen 300 and then we'll have padding along the x axis of two and they will be rounded
        

so this BTN Styles we can reuse them right here
        

so here I just add a class name and I use this car brackets and I pass our BTN Styles there we do the same for the other button right here
        

so I can copy that and I can paste that here now I save awe
        

some
        

so let's hook this set quantity to our product details
        

so down here where we had quantity instead of this div we will pass our set quantity we click on this one to Auto Import it and al
        

so we self close it but al
        

so we should be passing several props here
        

so I think we should pass our cut product which is our cut product we need to pass a handle quantity increase uh which will be handle quantity increase
        

so I I copy that and paste it here I can duplicate it then instead of increase I use contrl D select these and this and we say here decrease
        

so we don't have these functions
        

so let's create them
        

so you can say const handle quantity increase to be equal to I'll make use of use call back and I'll invoke this we pass an arrow function which al
        

so expects us to pass a dependency array
        

so I duplicate these R Al shift bottom arrow and we change this to decrease
        

so for now we should be able to see the Styles let's check let's wait for it to refresh there we go
        

so we already see these quantity Styles but they are not increasing nor decreasing the quantity
        

so let's write the logic for but for increasing and decreasing the quantity that will be inside these Curry brackets
        

so here we just need to set our cut product we invoke it we pass an arrow function here here we will receive the previous state
        

so I can say previous and we can use that previous right here we will return we spread the previous state
        

so previous we will update our quantity
        

so which take the quantity and we set it to uh Plus+ previous dot uh quantity
        

so we take the previous quantity and we add one to it that is what Plus+ means here let's save and try to increase
        

so we can increase awe
        

some up to whichever point you want now we will do a similar thing for decrease
        

so I'll copy this and here we should pass uh that this is depending on our cut product right there and al
        

so this one is depending on our cut product right there and in here I copy this set cut product and I'll paste it here let me include space between them there and now here instead of plus plus we include minus minus and I save
        

so now we can be able to minus all the way now you see that we have negative values
        

so we want to prevent negative values
        

so here we can perform a simple check okay
        

so we'll say if and I invoke this cut product dot uh quantity is equal to one
        

so we immediately return here
        

so that would prevent us from executing this code here
        

so if I happen to refresh this page and click on negative it's not working but if we go to four and we subtract it is not going less than one because we have used return here
        

so we can do a similar thing for our uh increase here
        

so here I paste this and what we will check if if this is uh above a certain value or if it is equal to a certain value
        

so if cut product quantity you can set to be maybe 99 to be maximum and here you simply return
        

so if you go above that value then uh it won't work don't know if I'll be able to click this up to 999 here I have skipped the video up to 90 and if we get to 999 we don't get above that
        

so you can set a threshold if you want I want us to create this button for add to cut and we will create it as a usable button
        

so that we can use it in other parts of the application uh when we want to I'll come to files then I'll go to app components and I can create it at the root of our components
        

so right here we can have our button. TSX stat functional component we can say that this is a button
        

so this will be a client component
        

so I can use use curent right here here we can return a div we can define various props that we will be uh receiving
        

so let's create an interface
        

so you'll say interface uh button props and the first one will be the label
        

so a button we have a label which will be a string and the button can be disabled or not
        

so disabled this will be an optional borean
        

so use a question mark there full colum we will have an outline which is a Boolean
        

so it can have an ultr not can have a small button and a large button this is al
        

so a Boolean al
        

so add here custom
        

so it's al
        

so optional and this is a string icon uh but it will al
        

so be optional uh we will be using react icons and we have a type from react icons called icon type this one here and this will come from react icons like that one last thing is that we will be having an onclick event
        

so we'll be passing an onclick function to this button and this will receive an event which is of type react then dot mouse event angle brackets HTML button element yep like that
        

so I save to Auto format and al
        

so cross these ones then this is what we receive
        

so this should be an arrow function that returns void
        

so we won't return anything from that now I save and there we go awe
        

some
        

so let's hook this props here react. FC angle brackets and here we go with our Buton props
        

so this should receive all the props row disabled out rine then here we'll have small we'll have custom icon and on click and I save here I'm receiving all the props that we have defined on our types here and we will use them to dynamically show this button okay
        

so when we pass small we will show a small button when we pass out train we'll show an out trained button and
        

so on okay
        

so right here instead of a div let's return a button the content for this uh will depend on whether we have an econ or not and then we al
        

so show the label
        

so here we'll have the label and then here we show an icon
        

so we'll perform a check does icon exist
        

so we say icon and end and here we now show the icon component from react icons and here we show the icon that we pass in
        

so
        

so this uh we should change it
        

so we'll say R have icon is icon
        

so we use we start with the Cs there as icon
        

so that we can use these as a component when we start with a small letter react will not know that that is supposed to be a component we have icon it is a self Crossing one and we have the size prop and we can default the size to 24 right here Okay cool
        

so let's have a class name and instead of this we will use the car brackets and the backs here and now we rest them right here
        

so if our button is disabled we will show an opacity of 70 and to make this button disabled We'll add a plop to it
        

so we'll just say disabled and we set this to be equal to disabled
        

so this is the value that we passed through here if our button is still disabled we show a CA of not around
        

so Casa we have this one here not around we'll make our button to be rounded MD we can have hover when we on this button Let's uh change the opacity to 80 okay
        

so avoid raving the space between this
        

so this should be one thing this one al
        

so and this one one al
        

so uh we'll have transition and we can set the width for this one to be full and the border for this one to be straight 700 and then we can sty these items to be side by side using FX boox
        

so we'll display F then we'll have items at the center
        

so items hyphen Center and then we will have justify Center al
        

so and a gap of two uh we will have now the dynamic Styles
        

so here we use the Mone sign and the carry brackets and then we'll check if we have the outr property and if we do here we'll show a background of white else we will show a background of straight 700 this background will be similar to this border color here
        

so it will show a
        

solid button else this will be white and then it will show this border therefore it will be outr button okay then here still if we have outr
        

so we perform another check now here let's change the text
        

so if we have outline the text will be straight or 700 else the text will be white and we are done with outline let's go to small here you'll have small we can start by changing the text size
        

so if small exist then text will be small else text will be MD that means that it's bigger small again we'll have padding along the y axis as one and then we'll have padding along the x axis as two then here we will have padding along the Y AIS as three and padding along the x axis as four
        

so here we can have text small and al
        

so we can have font as light and then here you can have text MD and al
        

so we can have font as semibold I think we can al
        

so add
        

some combinations here here I can add border 1px and al
        

so here I add border of two now last three what I'll add is a custom right [Music] here and uh we pass our custom Styles
        

so this will be in form of a string else it will be just null okay
        

so if we don't have we pass nothing I save and uh hopefully everything is fine let's use this button on our product details right here at add to cut
        

so here I will remove that and I'll just say button uh make sure to Auto Import it from up components there then this will be a self Crossing button component and it will expect us to pass
        

some props
        

so
        

some props are mandatory like the label here and the on click are a must
        

so here let's pass the label and we pass add to cut and then right here we al
        

so pass the on cck event for now we can just pass an arrow function that has nothing because the logic for adding the item to cut will do it later I save and here we should see now the button and there we go we have this button when I expand it expands all the way to the end and we can test the various props that we added
        

so small save yeah it's small out train save and now it's out train let's remove small there we go
        

so it's good it's working well what I'll do is that I don't want this button to stretch all the way
        

so in this div I can al
        

so add a class name and I can limit the size of this div
        

so I can say let the max width for this one be just 300 PX and I save and there we go
        

so even if it's on a big screen the button will be this size I want us to work on this images part right here if we come to this one which is complete uh you'll see that we have two sections for the image we have this one here where we can even click different uh colors for the image and we have this one that is showing the selected image I'll just minimize this one here and from here I'll just close this and we can create a new component I'll do it at app components products
        

so I add a new file and I can say product image here product images or image do TS SX hit enter here we'll have stat functional component and I'll say product image and here for now we can just say div and I click save
        

so again this will be a client component
        

so use client one thing that I can tell you is that when you create a component like this and hook it to another component that is already labeled as client component uh that component will directly be considered as a client component but I just like to include uh use client to any client component but uh it is not mandatory for each component
        

so if the parent is a client component then the child will be considered a client component as well
        

so this will receive several props and for that let's Define the types for those props I'll create an interface here and we'll say product image props and here we'll have cut products or rather cut product it's a single product and we pass the type for this product cut product type this one here and it's Auto imported from our product details awe
        

some then here we will have the actual product okay we didn't Define the types for the actual product because the type will be coming from Prisma
        

so in this case I can just say any any type and I'll fix it later when we create the Prisma types and the Prisma data models
        

so here we'll be passing a function handle color select
        

so remember when we select a different image we are selecting a different image with a different color
        

so I'll pass this function which will help us to switch between the images and it will receive a value of the selected image type this on here but it will return void
        

so here return nothing like that I save let's hook that here we use angle blacket and I'll pass our product image props like that and here we should destructure them
        

so I destructure cut product i d structure product i d structure handle color select and Save cool now we can make use of these props that we get here to render our images
        

so if we check at this we have this section and this section
        

so first of all this will be the rapper div and we can use CSS grid we will display grid we'll have a grid calls of six and then we will have a gap of two we'll have H full Max hyphen h of 500 PX and mean hyphen h of 300 PX on small screen the mean hyphen H 400 PX
        

so here we have six columns that we are creating but we'll give this to occupy more columns than this okay
        

so this is the rapper div let's have here two Dives now the first div will be this one the second div will be this image now let's style this first section where we have different images
        

so we add a class name uh we display Flex for that and the flex direction will be column items will be at the center
        

so items hyphen Center justify Center gap of four CA will be pointer we'll have a border H will be full and let's have Max hyphen H actually I'll just go ahead and copy all this and repace here okay cool inside here here we will display different images I use the car brackets
        

so I can say product do images and then map I invoke that and we pass an arrow function here that will return a div and for this Arrow function we will get an image at a time
        

so I say image selected image type right here we will display the image component from next Js from next image here it expects several crops SLC we will say that the image do image we al
        

so need to have an alt and we can give the alt to be the image color
        

so image do color okay I'll say F here and I'll add a class name and this class name will be object contain and I save to Auto format everything and for this div we should be having a key and the key can be image do color al
        

so we'll be having more properties we'll be having the onclick event
        

so when we click on the image we will be changing
        

something and here we will simply call our handle color select and we pass the image in there just like we did with our colors here awe
        

some now I will be adding several class names here
        

so class name now this is the rapper for our image
        

so I'll say here relative and then we will have with hyphen to be 80%
        

so this this means that it will not touch the walls for this border it will be
        

somewhere in here this is a custom one
        

so make sure to WRA it we'll have an aspect ratio of square it will be rounded we'll go with the default then we have a border for it and it will be till hyphen 300 and now uh right here I'll change this to back tick
        

so that I can conditionally render this okay
        

so I have added this car brackets and the back ticks here
        

so for the selected image then we will show this greenish border or tail border else we will show nothing okay here now I raise the money sign and I'll say cut product and Dot selected IMG and then do color
        

so if this selected color is equal to the current image do color then what we will do is to dynamically show the border
        

so here we'll show border to be 1.5 PX we'll do else I use a full column then we'll have border to be none and I save
        

so we have completed this first part here this one here but we al
        

so have this one here which shows this particular image
        

so for now I think we can hook this to our product details and see if it will show anything
        

so here we had this images
        

so I will remove that and I can say product image component I click that to to import and we close it it will expect us to pass several props we have cut product
        

so we pass cut product al
        

so we have the product itself and we give it the product itself and then finally we al
        

so have handle color select and we give it handle color select
        

so this function is the one that we al
        

so created area right here when we were working with our colors since it's receiving the same details and it will be able to change the image accordingly
        

so I save and this is our component there
        

so if we check here look we now already have this we we can select this we can select this we can select this we are able to show the different images awe
        

some now we just need to show the selected image right here as a bigger image
        

so we will do that in here in this second div I'll start by adding a class name we'll span the image through five columns
        

so we'll say call span hyphen 5 and then we'll say relative and then we'll set the aspect ratio of square
        

so in here we will now make use of the image component from next
        

so image will be self closing it expects us to pass several props
        

so first of all I'll say fill and I'll set a class name here uh width will be full can hit enter
        

so that I include more then height will be full then object will be contained then uh I'll come right here I'll select all this I'll copy and I'll paste them here awe
        

some
        

so those are the classes we can include SLC
        

so here we'll show the selected image and that will come from our cut product remember cut product is our state
        

so cut product do selected IMG then do IM do image then we can have an ALT cut product do name the name of the product I save and now this is our component and once I save it should show here right there like that full image awe
        

some that's really nice because I think we have completed that component and if I expand look we have an entire full image right here I can switch the color from here I can switch the color FL here pretty nice right I want us to show a a list of ratings down here and then after that we'll start working on our shopping cart
        

so we'll go to up then we'll go to product here and here we had this page in this page right here we listed the product details and I'll list the rating uh below this product details
        

so here I'll simply add a div here we'll be having two things the first one will be add rating but we'll cover the this later on during the course and then we'll al
        

so have another one here and here is where now will having a list of rating okay
        

so here we can add
        

some styles for this display Flex then Flex call margin to the top will be 20 and we'll have a gap of four between the two and I save awe
        

some we need to create a component that will help us to list the rating we can create it just right here
        

so I'll just add a new file and I'll say list rating do TSX I hit enter Str functional component list rating for now let's say div here and I'll make this to be a client component and we'll receive several props
        

so let's use an interface here and we'll say list rating props we will receive just the product for this for now let's just say any right here we destructure the product but we should al
        

so pass our interface here
        

so react. FC angle brackets then list rating props
        

so the first thing here is that we'll be having a heading and for this I want to create a new component that we will reuse across the application
        

so at our components I can just come at the root and add a new file and I call this file heading. TSX
        

so from this we'll have an interface this will be the heading props let's define this props we'll have a title which is a string and then we will have Center and this will be optional
        

so it will be Boolean like that let's come right here we create this component sfc and we'll say this is the heading it will receive those props then here fullon react do FC we pass our heading props in the inside the angle blackets in here we receive those props we destructure them we structure title then we D structure Center then we can use that right here I'll use a div we'll have a H1 and right here we will pass our title like that then right here we can have a class name that is Dynamic
        

so I use this we'll say does Center exist
        

so if it does we'll show text Center else we will show text at the start then for this heading let's save uh and I can minimize this actually and then right here let's have a class name and font will be bold and al
        

so we'll have a text size of 2 XEL and I save awe
        

some
        

so now we can make use of this heading right here
        

so I'll say heading I click on it to Auto Import but it expects us to pass the title and we can say this is the product space review like that if I happen to save we don't see any we just see list
        

so we can hook this rist rating right here at our list instead of this div we will say list rating it expects us to pass a prop which is product and we pass our product and we save
        

so now there we go product reval now here I have a div where we will map through uh the different reviews
        

so first of all let's add a class name for this and I'll make text to be small and al
        

so margin to the top of two and in here now I'll use car brackets we will check if our product. reviews exist
        

so product. reviews and end we now take our product again do reviews and we call map me here we pass an AR function that will return
        

something here
        

so return a div now this aror function will now be able to get a review at a time
        

so review and I know it will complain about the type for now we can set it to any and for this div it expects us to have a key and we can use the review ID
        

so review. ID then we'll have a class name we will set the max width for our review to be 300 PX and we will be having two parts of the review
        

so if we come to this one you see we have this section where we show the name and the time then we have this section where we show the rating and the comment
        

so right here let's start with the user profile
        

so here I'll have a div
        

so for now I'll add a press holder We'll add an avatar in the next then after that Avatar we will be having another div that will have the username
        

so here let's get the username from review do user.name
        

so we can use this to make sure that uh if the user doesn't exist then we don't show it then right here you'll have a div here we will show the time that that review uh was created
        

so here we will use moment uh I don't think we have installed moment yet
        

so I'll say npm I moment and hit enter that will install moment in our application and we can use it to format the dates
        

so I'll hide that and now right here I'll say moment make sure it's being Auto imported there we call it and here I'll pass the review date
        

so review. created date and then at the end here Dot from now and I invoke that from now and save
        

so right here you should be able to see when that review was created and we see two reviews this one and this one
        

so here I'll add a class name and we'll display FX we'll have a gap of two and then we will have items at the center like that I save now they should show this way awe
        

some
        

so for this one uh we'll work on thater on for this one let us add a class name and we'll set the font to be semi bold and I save and this is semi bold this one will make it light
        

so here let's add a class name and and we'll make the font to be light the next thing is to show the actual reviews
        

so make sure that you are after this div right here you add another div we can start by adding a class name and we'll set margin to the top of two and then in here Al tab we will use the rating component from Material UI
        

so bring that in and we show the rating for this uh particular review
        

so value will be review do rating actually this is rating um and then we have read only I save and that should show there we go
        

so for this we have this after rating we should show the comment itself
        

so I'll use a div and here we just say review do comment and we add a class name margin to the left of two and I save and there we go good enough and
        

so on
        

so the spacing is not okay and what I'll do is that right here I'll add a separator and I'll add a HR tag
        

so HR I'll add
        

some Styles include
        

some margin to the top of four and that will create good spacing and margin to the bottom of four as well and that way we'll individually see each comment there we go
        

so now we see this one and we see this one but we don't have the Avatar yet
        

so let's create that in the next epi
        

sode and then we will wrap up this section for working with the product later on we'll come back work on this add rating component here to create the rating
        

so there we'll be working with the DB that's why I'll ignore it for now let's show this Avatar component
        

so for that let's come back here I'll click on app components I can add it at the root here because we'll be reusing it later on at the user menu it will be a similar thing
        

so here I add a new file at the components and I can say avatar. DSX stess functional component avat okay here let's start with a div as a press holder now obviously this will receive several props uh mainly it will receive the SLC for the image let's define an interface and we'll call this Avatar props we receive an SLC which will be optional and it can be a string or it can be null or it can be undefined
        

so
        

so right here we'll destructure that SLC but our component don't know about it
        

so let's make sure that it Knows by adding react. FC here angle brackets and we pass our a props
        

so before we return anything we will perform a check does this SLC exist did we pass this particular SLC if we did then we will return image component from next next
        

so image now here we'll be able to pass our SRC as SRC we can pass the alt as avat we'll set a class name to be rounded a hyphen full we'll set a height to be 30 and al
        

so a width to be 30 like that I save now this is when we have the SLC we show the this image component else we will return right here an icon this icon from react icons called fire user Circle
        

so I can copy that and that is what we will use here
        

so I paste it like this and we should import it from react icons
        

so the way we do that if I come to the very top this way I can copy that import and paste here and give the name of that icon here for user Circle and here uh we can pass a size and for now let's say 24 let's hook this at our list rating where we had avat now
        

so I will remove that and I'll say this is the avat it's coming from components don't confuse it with this one
        

so it is self closing
        

so for now I'll save and we'll see if we don't pass SLC what we have and there we go
        

so we have this
        

solid icon I think it looks good uh to my opinion now let's pass an SLC
        

so SLC here and we pass the review do user do image save okay it doesn't change
        

something is wrong for this we didn't include return
        

so we say return and save we have an issue with the host name
        

so the image is coming from Google
        

so this link right here host name you can copy that and then you go to next config and here we had added domains one was fire base
        

so we need to add another one here which is now this which is coming from Google
        

so this will be coming from the Google profile uh profile images for the Gmail
        

so let's pop our terminal and I'm sure our application has stopped
        

so let's start it again uh npm randev
        

so after
        

some time it has raded and when you come you see now we have the actual profile images right here
        

so
        

so yeah that is it hello everyone and welcome back
        

so in the last section we were able to work on our product and we were able to list the products and al
        

so uh displayed a dynamic page for more details about that product now in this particular section we'll be working on our shopping cart
        

so the shopping cart will look like this and we'll be able to add items to cut remove items from Cut uh al
        

so you'll be able to design this calcul sub total and
        

so on
        

so before we proceed right here at our product reviews I see that this stretches all through the way but I didn't want that I wanted it to be short and therefore in our list rating uh component what I need to do is to come right here and make sure that I include angle brackets right here
        

so I missed this and save and now look this looks good to me after that uh what we will work on is to create uh a hook called use cut
        

so we'll create a hook called use cut hook
        

so right here you can go ahead and say use cut. TSX like that to begin with is to create a cut context and then we'll use that uh to export it with our hook
        

so whenever we call the hook we'll be able to access uh all the properties that we need from our cut context
        

so right here what I'll do I'll start by creating a cut context I'll say export and we'll say con cut context which will be equal to let me minimize this one I'll say create context and this will come from react
        

so if I click this it's Auto imported awe
        

some now I'll invoke these and I'll pass null
        

so by default cut context will be null but I need to al
        

so Define the types that will be passing to this cut context
        

so after the UT here I can define a type
        

so I'll say let type cut context Type U be equal to and to begin with I can just Define one type uh for it not just to be empty and I'll say cut total qty and I'll set this one to be a number now we can pass this C context type right here like this
        

so I'll include angle brackets and I'll paste it here and we'll be having this cut context type or we will be having null and here we have our cut context now the next thing that we should create is our cut context provider and I'll say export const cut context provider and this will be like a normal component
        

so here we'll set set it to be equal to an arrow function and we do like this here we should return
        

something and what we will return is our cut context right here do provider
        

so here I'll say cut context. provider it expects us to pass a value plop
        

so here I'll pass a value and I'll set it to Value
        

so we can Define this value right here which will be an OP object
        

so right here I can say const value will be equal to an object and for now we can pass a cut total quantity
        

so I'll say cut total qty which is not defined yet and we can say const I'll have cut toal quantity and then we can have set cut total quantity let's make sure that this starts with a capital there and we set this to be equal to use State hook uh that comes from react and we invoke it by default we'll have value of zero
        

so we have created this cut context provider and inside this cut context provider we are returning cut context. provider remember we have created our cut context right here provider and we pass this value prop which is mandatory and al
        

so we pass the values that will be in our value here
        

so this will be an object and here we'll be able to pass different properties like the state here for cut total we'll be able to pass different functions like handle add product to cut remove product from Cut and
        

so on right here and we'll be able to Define all the types right here okay
        

so
        

so far
        

so good for this cut context provider we will be having
        

some props
        

so here we'll have props and we will pass the type for this as props and we can Define this interface
        

so right here I'll say interface props and right here we'll make it to accept uh any kind of a plop that it will be receiving and this is how we can do it
        

so we'll say a prop name here
        

so this is like a press holder and this prop name must be a string and then it will be of any type
        

so this way our cut context provider will be able to accept any props now at this cut context provider I spread this props right here
        

so what I'll do I'll just destructure like this and I'll say dot dot dot and I'll pass props
        

so one last thing that remains is to create this use cut hook at the bottom here
        

so we will export and we'll say const use cut and we'll set it to be equal to an arrow function like that we'll say const context will be equal to use context and we invoke this and we pass our cut context right here
        

so this way we we are able to receive all the properties that we include at our value right here at our context okay right here we'll make sure that this context is not null
        

so I'll say if our context is equal to null uh we will return an error
        

so here we will draw a new error draw new error we invoke these and we'll say use cut must be used within a card context provider
        

so if we access this use cut hook at a component that is not wrapped with our cut context provider this error will show now at the end here we will simply return our context
        

so whenever we call use cut we'll be able to access this context which will have our different values I hope that makes sense
        

so I'll save to autof format everything and now this is the basic structure of our use cut hook and we'll be working on this file to write different Logic for our cut but before we do that we need to wrap our up with this cut context provider and let's do that in the next epi
        

sode
        

so in the last epi
        

sode we were able to create our cut context and the use context hook and in this epi
        

sode I want us to wrap our app with this cut context provider
        

so that we can be able to access these values in any part of our application now to do that I'll come at the root here and I'll create a new folder called providers
        

so I'll say providers and right here I'll create a new file and I'll call this one cut provider. TSX and we'll create this component as a client component because remember this cut context provider makes use of the use State hook and uh other form of interactivity uh which makes it to be a client component and when we hook it up to our cut provider which is a client component it will al
        

so be considered as a client component and we can be able to make use of all those uh use hook and
        

so on
        

so here I'll call this one use client
        

so we include this directive to make sure that this is a client component we will have an interface a cut provider props and right here we'll accept children children and this children will be the different components in our application therefore there will be type of react dot react node and right here let's create our component and I'll say the functional component and this will be our cut provider component like that uh which will now accept these children
        

so here we will destructure our children like that but let's make sure that it knows about this
        

so therefore here we say react do FC and pass our cut provider props and now it's aware of these children and this children we will wrap them with our cut context provider right here we'll do this then you can use control space to import it from from hooks use cut and then we call it like this and right here we'll be able now to pass our children
        

so I save and now this way we just need to take this cut provider then we go to our layout let's come to layout here and we will wrap this one right here with our card provider component
        

so here I'll say cut provider and I pass this div in here and save and now all these components uh that are in here the Navar the footer and even our main application uh will be passed as children to our card provider
        

so we will receive it here and then we'll wrap this children with our cut context provider which we defined at our use cut file right here and that way all those components will be able to access our uh value right here by making use of this use cut hook remember in this use cut we are exporting our context which accesses the values from Cut context and we can test this one out
        

so we can go to one of the files and try to access our uh cut total quantity
        

so what we will do uh I can minimize everything I'll go to up and we can go to products uh we can even do it at product details right here
        

so I can minimize this one and at the top here remember use cut is a hook
        

so we should do it at the top of the file
        

so maybe before everything we can say const and here we can destructure the different vales from our cut context and one of the value that we included was the cut total quantity you can see it's suggested and we said this to be equal to use cut like read this one here which we created this one comes from hooks use cut and we make sure to invoke this
        

so we make sure to invoke part and we can log this cut total quantity to the con
        

sole
        

so instead of product here I Rog the cut total quantity and I save now if we inspect this and go to con
        

sole let's refresh everything you'll see that we have this uh zero here which represents our cut total quantity uh okay we have this uh warnings for the images warnings are not that bad just make sure that you don't have any errors you can can try to fix them but for now I'll just proceed because that was not the goal for this particular video and if I come back to use cut here you see that zero is this one right here
        

so if we change this default value and save you'll see that it will update here to 10 and we are accessing this on our product details
        

so if we go to a different page like the homepage you see we don't see that 10 we don't see that 10 because now we are on a different route
        

so this uh it's working and now we'll easily be able to access the values that we export right here uh from anywhere in our application
        

so for now I'll just remove all this this was just for demonstration purpose
        

so I can remove them and I'll save and now in the next epi
        

sode let's see how we can add a product to our cut
        

so in the last two epi
        

sodes uh we were able to create this use cut hook and al
        

so we worked on our cut provider and now in this epi
        

sode I want us to see how we can add a product to cut
        

so to do that we'll need to have two things we'll need to have cut items or cut products and then we will create a function that will help us to add items to that list of cut product to begin with let's come here and Define
        

some type and we'll have cut products
        

so you can name it cut products or cut items
        

so in this case I'll say cut products and then we'll give it a type it will be of cut product type uh which we had already defined in product details
        

so I'll import that from product details and this will be an array
        

so it will be an array of cut product type and al
        

so if the cut is empty this can al
        

so be null we'll have handle add product to cut and this will be a function that will return void but it will receive uh a product here
        

so you'll say product and then here this will be of type cut product type now let's create this cut products uh state
        

so we'll do that right here we will say const we will have square brackets cut products and we set cut products to be equal to use state
        

so here we will specify the type and we will say cut product type array
        

so cut product type here and here you al
        

so say it can al
        

so be now n and then we invoke our US state and initially our cut will be null
        

so these types that we have defined here remember they are being passed at our cut context and now these uh will specify the vales that we will be exporting from our cut context
        

so you can come here and see cut context. provider and you can see the value is shouting because it expects us to pass this cut products and al
        

so this handle add product to cut now that we have defined this cut products we should al
        

so add it at our value here
        

so here we can al
        

so say cut products and it will al
        

so expect us to pass handle add product cut
        

so I can copy that and I'll pass it here but we have not defined this function yet
        

so we should Define that function inside our cut context provider
        

so here you'll have const uh handle add product cut and we'll set it to be equal to we'll make use of use call back to optimize it then we invoke that here we can pass an arrow function and this expects us to have a dependency array
        

so our value no longer comint because we have this cut product with which we have defined here and we have this handle add product cut which we have defined here and we Define the types for here right here okay awe
        

some
        

so let's work on this function here I'll enter here this use call back will receive a value of product
        

so here I'll pass product and remember this product is of type cut product type and then we can make use of that product in here
        

so what I'll do is that when we add a product cut uh what we simply mean is that we are adding that product to this array of cut products or cut items and when we remove a product from Cut we are simply removing a product from this array of cut product
        

so we we should make use of this set cut products right here and I'll say set cut products and I'll invoke it now here we are able to pass an arrow function that receives the previous state
        

so here we have the previous state and in this case the previous state will be null but when you add a product cut now the previous state is that the cut will have at Le one product and
        

so on and uh this expects us to return
        

something at the bottom but before we return I want us to update the state
        

so here I'll say let uh up updated cut uh be just nothing undefined and then at the bottom here we'll say if we have previous state remember previous state can be null or it can have
        

some values
        

so if it has
        

some values we'll set our updated cut to be equal to an array we spread the previous state which is an array of items and we add our product
        

so here product and this product is the one that we are receiving here uh through this function and then right here we'll have else
        

so if we don't have the previous state we will simply set our updated cut to be equal to the product
        

so we set it to an array and we add our product like that and then down here we will simply return the updated cut just like that
        

so I can save that and this is how we can add that product to the state
        

so now let's see how we can make use of this function uh we are already adding it to our value
        

so when we call use cut we'll be able to get that function in our context we will go to app then product details and right here at the top we can say const which D structure handle add product cut and al
        

so we will destructure cut products from use cut hook
        

so we call use cut this one and we make sure to invoke it and remember I think we had already imported it at the top from our hooks okay
        

so here we have now this function and we have our different products
        

so we'll go at the bottom where we had this button that says add to cut and we'll make use of it right here we will simply return handle add product to cut and we invoke it and we pass our cut product and this cut product is the one that we already be in state right here now we'll be able to receive that product in our handle add product card function first of all let me save this file
        

so we receive it and we get it here as product then we either add it to cut like this or we add it to cut like this awe
        

some
        

so one last thing to make sure that it's working is to rck this to con
        

sole
        

so let's come here and say con
        

sole. Rog of cut products cut products not product remember we have this cut product and this cut product
        

so here it's cut products
        

so let's save and go to our app and see if it works awe
        

some
        

so here we will come to this one we inspect come to con
        

sole and Let me refresh
        

so right now you'll see that our cut is null and we come here click on add to cut and oops nothing happens I checked this issue and we have an issue with our button here and the issue is that we didn't add an onclick event in our button
        

so here we passed onclick we al
        

so passed it at our plops but we didn't add it right here
        

so right here all we need to do is to say unclick and then we pass on click and I save that file now let's see
        

so we have this null and this null here we come here add to cut now and look we are able to add an item to our cut and we are logging it to the con
        

sole here really awe
        

some now the funny thing is that when I click add to cut again add to cut uh we will get two products here which are the same products and it should not duplicate it we should only have one of it okay let's test
        

some few more things here I refresh and that will create the state
        

so if I select blue then let's add the four of them and we add to cut let's see if those property is are being added and we have quantity as 4 and here color can you see the color okay we have this selected image as blue
        

so that is working well and uh let me see you in the next one in the last epi
        

sode we were able to add an item to cut and we had an issue
        

so if I add add to cut again you'll see that we are duplicating that product instead of maybe increasing its quantity
        

so that is one of the
        

solution but the other
        

solution is that we can just show a different button here of view cut once we add the product cut and I'll go with the second
        

solution of showing view cut right here
        

so I think that is easier
        

so what I'll do I'll come back right here and what we will do here is to add
        

some form of state that will help us decide whether we already have this product in cut or not
        

so we'll say con we will say is product in cut and we'll set is product in cut and here I set this toal to use State we invoke it and by default we'll have false now we should be performing
        

some checks for us to update this state uh whether the product is in cut or not
        

so what we'll do we'll come right here and we'll make use of the use effect hook
        

so whenever the component RADS uh we'll be able to check if that product is already in cut or not
        

so I invoke this we pass an arrow function and it expects us to al
        

so pass a dependency array and the dependen area for this one will include our cut products now right here to begin with we'll make sure to reset our is product in cut by coding set product in cut and we set it to false and then right here we'll perform a check do we have cut products now if we do we'll go ahead and write
        

some logic right here we will use an array method to check if this product is already in our cut products
        

so and the method that we will use is the find index we will find the index of that product in our cut products if we find a value that is greater than1 that means that it exist else it doesn't exist
        

so here we say const existing index will be equal to our cut products do find index and we invoke this
        

so here we pass an arrow function that will receive a product at a time we can call that product an item and we return the index of the item if the item do ID is equal to the current product do ID if this does not exist what we will do is that this method will return1 if it doesn't find any index okay
        

so here we now have an existing index and we'll perform another check if the existing index is greater than -1 that means that we have an item in the cut
        

so here we will update our state of set is product in Cut to true and I save
        

so this is our logic of checking whether we have that item in cut or not and now our state will able to tell us whether we have it or not
        

so I'll copy this is product in cut and we will use that to dynamically display our UI uh we will hide set color we'll hide set quantity and the button here if we have that product in cut and therefore after our horizontal here I'll reuse these car brackets and I'll say is product in cut and we'll use a question mark here and here we will display a button that says view cut and maybe
        

some other UI like product added cut
        

so here we'll have that else we'll have
        

some more react fragments like that
        

so I want to include all this right here up to our button I cut all that to be inside here
        

so if product is in Cut we hide all this I save and here we will show
        

something else
        

so right now it should actually be able to hide let see
        

so look if we refresh we have them if if I click add we hide awe
        

some it's working actually
        

so here we just need to show
        

some different UI okay
        

so here we'll have a paragraph to start with and this paragraph will have two things an icon and a span
        

so let's start with a span the span will say a product added to cut and right here we'll have an icon
        

so I'll say MD we'll say check Circle
        

so I'll click this Auto Import it from react icons
        

so this one here awe
        

some let's come back right here we cross this one it can accept a prop of size and I'll set this one to 20 and al
        

so it can accept a class name and we'll set the Cara to text of till 400 which is greenish and al
        

so this paragraph right here we can add
        

some
        

some crass name and we'll add margin to the bottom of two and then we'll change text color to text straight 500 we'll Flex the items and we'll make sure that we align them nicely
        

so items Center and then let's have a gap of just one now this is only the text and if I save we should see a message here product added to cut with this icon now we can add a button that says view cut
        

so down here after our paragraph we'll have a div and here we will show our button component
        

so button and this expect us to have a r and you'll say view cut we can option pass and outline it expects us to have an onclick event and for this on click we'll make use of react router to navigate our cut
        

so first of all let me cross this button using this and this then uh have we defined a router before we haven't
        

so after our state here I can say const router will be equal to use router and that will come from our navigation and we invoke it now we can make use of this router down here I can include this brackets and I'll say router. push and we make sure that it goes to our stroke cut like that and I save
        

so we already have this cut page
        

so it will take us there awe
        

some
        

so let's see what we have and there we go it is stretching all through
        

so we can minimize that by adding a crass name here similar to this one
        

so let's just copy this one and paste it here and I save now let's see it's shorter awe
        

some okay now this is our page here let's refresh we can select car and quantity add to cut and look we change the UI to product added to cut and we have view cut
        

so I click view cut and we get to our cut page
        

so here you'll be able to list the different items okay now before we list them I want us to add persistency of our items in the cut
        

so we will do that using the local storage and let's do that in the next epi
        

sode
        

so in the last few epi
        

sodes we're able to add Logic for adding a product cut but uh when we add a product cut like this we have it here now that that means that it's already in our cut aray but when we refresh here you'll see that we lose it
        

so we want to add persistency for us to have it even when we refresh the page and we can make use of the local storage for that
        

so this is how we will do it at our handle add product cut once we add it to cut right here we can add it al
        

so to our local storage
        

so I'll tab here we already have the builtin method which is our local storage do set item and we invoke it and here we pass a key the key will be maybe eShop cut items and then we pass a value and we can use J
        

son do stringy we invoke this one and we pass our updated cut like that
        

so now when we add a product cut we will update this eShop cut items to our updated cut and let's save and test that one out
        

so if I come back right here uh you can go to more here and click on application and here you'll see we have local storage we already have all this because uh of my previous application and I can actually clear and now you should have empty uh you should have anything if I happen to refresh my app here
        

so here we don't have anything okay now here I can select an item add uh maybe two of them and then click add to cut and look now we have eShop cut items when I click on this one you can see more details about it right here and we have it added to our uh local storage but still we need to do more because when we refresh we should be seeing that this product is already in cut
        

so we'll make use of the uh use effect hook
        

so here I'll say use effect like that I invoke it we pass another function and here we pass a dependency array now right here we will get the items that are in our card whenever we refresh the page
        

so here I can say const and we can say cut items we can say of type any and I'll set it to be equal to loc storage. getet item and we invoke these and here we will get our eShop cut items and this key must be the same as this one okay
        

so if you miss even a single letter then you won't get your items and then um right here I'll now say our cut product uh will be remember this is a J
        

son string that that's why I just included type P but now here we can Define the type for our cut products here and actually I can say const const cut products of cut product type cut product type and make sure that it's an array or it can al
        

so be null
        

so here it can al
        

so be null and we set it equal to now we pass our J
        

son string
        

so I'll say J
        

son dot pass and we include this cut items there
        

so we pass our cut items right here I invoke that and pass our cut items now we have these cut products and we can now use it to update our state
        

so here we can now say set cut products to be cut products now this cut product is this one right here yeah remember we have this and we have this maybe to remove the confusion you can just say C product here okay now this is this one and let's come back and look whenever I refresh now it's able to get the item from our local storage and show that we already have that item to our cut okay which is awe
        

some
        

so in the next epi
        

sode I want us to add react hot toas
        

so that we can show
        

some toast messages which is really cool for example whenever we add an item to cut remove item from Cut we'll be showing
        

some toast messages
        

so I'll see you in the next one in this epi
        

sode I want us to add react hot toast in our application for the awe
        

some toest messages that we will be having when interacting with our cut and other actions right on in the application especially in the dashboard
        

so here just go to the documentation and you'll see here you have npm install react H toast just cop that from here pop your terminal go to the one that you're not using or the one that is not running the application or you can add a new one here and install the react hot toast Library you can go to app then go to layout
        

so this is the root of the application and we'll make it to be available uh everywhere in the application
        

so we'll do it here
        

so these already completed I can just hide it using control J right here we will get a component from react hot toast inside our body here but before our cut provider I'll just say Toaster and this one here from react hot toast like that self Crossing component and here we'll pass
        

some toast options because I want it to be dark and I include an object and in here I'll include Style full colum I pass car brackets and we'll have background background now full column I pass a string this will be LGB I invoke it like that and here we will pass 51 this is a dark color space 65 space 85 and then here I include a comma and I'll include a color and I'll pass a white color
        

so hash FFF I save and now we have configured our library all we need to do is to create
        

some toasts
        

so we can go to the use card here
        

so here I'll say import ID structure toast and this will come from react H toast like that then down here now before our local storage I can now say toast then do success and we include the message in here I'll say product added to cut like that I save and we can test it out
        

so I come back to the application
        

so we already have this product in cut and uh for all the other products we al
        

so show the same product because remember we had coded this
        

so it will still show that it's already in cut
        

so for us to remove this now from Cut we'll have to al
        

so clear the local storage
        

so here I'll click on here right click then clear now if I go here and refresh we won't have it in Cut okay now let's click add to cut add to cut and there we go product added to cut
        

so our toast message is working now that we are able to add a product to cut I want us to start working on our cut UI before we continue with the rest of the logic because we'll need these buttons for example to remove an item from Cut to increase quantity decrease quantity I'll clear the cut
        

so what I'll do I'll just come to up then I'll go to cut and we have this page right here and I remove everything here I can start with a class name and I'll include padding to the top of it and then in here we will wrap our content with the container component and this will come from components container and then here uh I'll create a new component that we will include right here and I'll call this component a cut client let's add a new file and I can say cut client. TSX and I'll hit enter stess functional component cut client let's return a div I save that file and here we will include that cut client and I close it and now I save that file and I can close this file
        

so now let's work on this cut client right here
        

so at the top here we can start by getting our cut product
        

so I can just say const I D structure cut products from use cut hook
        

so I set this to be equal to use cut we to import that and I invoke it before we return write perform a check if no cut products all cut products. rength is equal equals to Z what we will do is that we'll display a message of an empty cut
        

so right here we can go ahead and return immediately and we can return a div we'll have another div that will say your cut is empty and then we'll al
        

so have another div here that will show a link this link will come from next link inside here you'll have two things an icon and a span let's start with a span and the span will say start shopping and for this link it expects us to have a h ref and we will include home uh link where we have the list of our product and al
        

so we'll have a class name and we can style uh whatever we have here we have span but al
        

so we'll be having an icon we will be having MD Arrow back
        

so this will come from react icons MD
        

so make sure it's imported
        

sometimes it doesn't Auto Import and we self cross this one like that
        

so I save to Auto format here let's add the Styles here
        

so for this we'll have text as straight 500 we'll display F we'll make sure items are at the center enter gap of one and margin to the top of two I save and those are the Styles there we come to the top here we add
        

some styles for this
        

so I'll say class name we'll display Flex uh Flex will be column we will have items at the center we will make this to be big
        

so we can al
        

so have a class name here text will be 2 XEL now we done with this part okay and you can see it's actually complaining because we BL in use cut but we didn't mark this as a client component
        

so here use client and we save there we go
        

so you can say stroke cut hit enter okay for a moment we see this your cut is empty start shopping
        

so when I refresh you'll see for a moment we see our design there but it disappears because we already have an item in the cut
        

so yeah I won't uh keep removing it because we need it to see how it you look like
        

so let's just proceed at the bottom here to start with we'll have this heading and I can say heading this was expecting a title and we can say uh shopping cart uh I save and we should be able to see it here there we go shopping cart we can pass a center plop I save and now it's at the Center we'll have a div here and for this div now we'll have this section here we'll add this title where we have product price quantity total and we will use CSS grid to divide it into those sections
        

so first of all let's add those headings
        

so right here I'll say div and we'll have product we will have price we will have quantity and we'll finally have total let's add the styles for this
        

so I'll say class name we'll display grid we'll create five columns
        

so I'll say grid uh hyphen calls uh hyphen 5 and then we'll say text to be Xs and then you'll have a gap of four and then then we'll have a padding to the bottom of two and finally here we'll have items to be at the center now here we have created five columns but the columns that we add here they are four
        

so we'll make this to occupy two of The Columns
        

so right here we add a class name and we'll say call hyphen span 2 and then we will justify self to the start then here we'll add a class name we'll justify self to the center we'll do the same for quantity
        

so I'll copy that come here and paste and for the total we'll justify to the end
        

so justify self end [Music] here like that I save and now we should have those being listed right here okay they are right here like that product price quantity total now you can see that this heading is
        

so close to this one we can add margin to the top here
        

so margin to the top of eight I save and now this should come down there we go awe
        

some
        

so now we'll able to list our items next
        

so after this title right there we now have our different items after this div this one we come right here and we'll have another div and right here we'll map our cut products
        

so cut products and if we have it we can say cut products then do map we invoke this one we pass another function that will return
        

something for now we can return a div like that and right here we'll get an item at a time and and here we'll be having a key which will be our item. ID and for now let's just show item do name
        

so like that I save and here you should have a t to an item and we have it there
        

so I wanton to design the design for this one right now we'll do it on the next epi
        

sode uh for now I want us to complete the design at the bottom here where we have this subtotal and this clear cut and then the next epi
        

sode we'll just work on this one and then move on from there
        

so after this div let's come right here we'll have a div and inside this div we'll have a button to clear the cut
        

so I'll add a div again and then we'll show the button in here
        

so button this will come from our component button and it's self closing it expects us to pass a label and we'll say [Music] clearcut and then it expects us pass an onclick right here on click and for now we'll just pass an empty function it does not do anything
        

so I save we have this clear cut now it's very big but uh uh I want it to be both small and outlined
        

so I'll say small and then outline and then right here at this div we'll add a class name and we'll add a width of 90px
        

so it will not be more than that
        

so I save and it should show a small button on this side there we go
        

so we now have this clear cut awe
        

some
        

so this is our button here at the bottom here we'll now be having being the other side right here where we have subtotal and
        

so on we'll add a div inside this div we'll have a div inside this div uh we'll have a span and we'll say [Music] subtotal and then right here we'll have a paragraph and this will say taxes and shipping [Music] calculated at checkout like that let's add
        

some Styles
        

so you see this shows at the bottom here
        

so we can start adding the styles from this div here before our button here this one
        

so here we had a class name we can start by showing a border to the top
        

so border hyph T and we'll include a custom one 1.5 PX and right here we'll have our border as straight 200 and then padding along the Y AIS of four and then flex and we just F between and have a gap of four now when I save the sub toal should move on this side like that and we should have this border right there
        

so after our button we move to this div right right here and we add
        

some Styles right here uh we'll add a crass name we'll make the text to be small and we'll show Flex then Flex call then we'll have a gap of one and items will'll be at the start I save
        

so this styles are for this section Right Here leted style our subtotal right here
        

so for this subtotal we'll be having two things um you be having the title here and the amount here
        

so I can wrap this span with another div
        

so I can say div and I'll move the span right there we will add another span right here for the amount
        

so here we'll have span and here we will show the price okay I can just show a custom price of maybe $1,000 I save to Auto format uh actually we should be having two things we should be having this one and this one
        

so I will remove one of this Raper div okay
        

sorry
        

so I remove one of this rer div and save now we have two things inside this div here we have this and we have this now let's add classes here
        

so I say class name we will Flex We Will justify a between we will have a width of four and text will be a bit big
        

so text will be base and font will be semi bold like that I save and now look sub total then the price on this side then we have this paragraph all we can do for this paragraph is to change its color
        

so we can have a class name and we'll say text to be straight 500 and I save
        

so it's a bit pale awe
        

some now we'll add this checkout button and this continue shopping link
        

so now after our paragraph here that has taes we will have a button we say button and it is self closing we pass a label uh for now we'll say check out but later when we add authentication we will dynamically uh show this particular button then it expects us to have an on click for now we pass a function that does nothing like that I save and it should show at the bottom here and there we go we have checkout after this button we will have a link component uh we will show an arrow like the one we had shown at the top this one and this one uh actually I think everything here will be the same
        

so I can just copy this link and I make use of it here but instead of start shopping we will say continue shopping I save and there we go continue shopping
        

so now we have uh sted the basic structure of our shopping cart uh the only thing that we should do is to sell each of these products and let's do that in the next epi
        

sode in the last epi
        

sode we started St our shopping cart but we didn't complete because we didn't correctly design our items and I want to do that in this particular epi
        

sode
        

so all I'll do is that I'll be creating a new component called item content that we'll use to display the item content by including it here
        

so I'll come back right here I'll create a new file inside our cut and I can call it item content do TSX I hit enter stess functional component and I'll say item content and here we will be having our item design
        

so I'll save and then I'll come back right here and instead of passing a div we will be passing that item content
        

so I will remove that and we say item content it will be save in and right here it expects us to pass a key and the key will be item. ID and then it al
        

so expects us to have an item actually it doesn't know we should because we haven't defined the uh type
        

so interface but let's pass it anyways
        

so we pass item as item I save let's come back to item content and before we proceed we will define an interface for for this one
        

so we'll say interface uh will be equal to item content props and here we'll have an item of type cut product type
        

so we make sure to import this one and then we pass these right here using react. FC and angle brackets and here we pass our item content prop we destructure the item from here and now we can use this item to show um the different properties let's al
        

so Mark this component as a client component
        

so I make use of use client for this div we can say class name and we will be using grid to display it in different sections like we did for this uh title or heading right there
        

so let's do this and I'll say grid we'll say grid hyen calls hyphen 5 we show five columns then text hyphen XS this means extra small then MD the text will be small small is bigger than x small then Gap here will be four then we can have a border a custom one of 1 .5 PX and here we'll set the border to be uh straight 200 let's make sure that this border is at the top
        

so here include hyen T hyen and padding along the Y AIS of four
        

so that we have
        

some good spacing and items will be at the center now we come in here uh we will have a div here
        

so this div will show these item detail details
        

so you'll have the image we'll have all this Smartwatch black and whatever and then the next div is the one that will show the price this one and then we'll have another div for quantity
        

so here we'll have another div and finally another div for total like that okay uh we had created a function that helps us show the price from components product product card we can see where we displayed the price uh we use this format price then we passed data do price
        

so I'll copy from here and that is what I'll show for Price here but now instead of data do price we will show item do price we make sure to import this format price at the top like this
        

so I used control space to get that suggestion for import awe
        

some
        

so I save this file and let's see what we have and there we go we have this $40 awe
        

some and for this we'll have a class name let's include it like this we'll have call span of two
        

so that it occupies two of The Columns we'll have justify self to the start we'll Flex the items We'll add a gap of two and then MD I'll say gap of four uh make sure not to leave the spacing here awe
        

some
        

so right here we'll have two parts we'll have the image part and the content part and we'll make both the image here and this title here to be clickable
        

so that when you click on it it takes you to more details about that product
        

so let's come here and we'll have a link it expects to have a href with we will use
        

some btics
        

so we'll set it to be equal to
        

some btics we'll have product stroke and we read the ID of the product right here from item. ID and that will make it to be dynamic and in here we can pass a div
        

so this is complaining we should import it
        

so import it from next link like this and now we have this one as the first element the second element will be a div and for this div will be for this content right here we can add a class name here and we'll display flex and then we'll have Flex hyphen column and we'll justify between and then in here is where we'll be having the different properties for the product
        

so that includes the name and we will WRA the name with the link component
        

so this expects to have a hre which will be similar to this one
        

so I can copy that one paste it on the first one and in here we will show the name that is Tran we had created the tranet text helper method
        

so tranet uh text right here we invoke it and we pass our item. name like that now if I save we should be seeing this item. name from here and we have the name there awe
        

some we come down here we have a Dave here this will show the color of the image these will be available in item do selected image do color I save and that should show the color okay awe
        

some and then down here we'll have a button to remove an item from cut
        

so I'll add another div we will have a class name and for this class name we'll have a width of 70 PX
        

so this is custom let's make sure we wrap it with the square brackets like that and then in here we can show our button
        

so I'll add a button here we'll say remove we can add
        

some Styles here I'll say class name we'll have a text of straight hyphen 500 and we'll have it underlined and now here we have this remove and it is underlined
        

so we'll al
        

so be having an onclick event
        

so onclick and for this on click for now we will pass an empty function later on we'll work on it actually we'll be working on that on the next epi
        

sode how to remove an item from Cut awe
        

some
        

so we didn't complete this one here it is still empty here
        

so let's complete that one we will be having an image component remember to import it from next image and here SLC will be item do selected IMG do image it expects us to have other properties like alt item do name and then we can have fil and we can have a class name that says object contain uh I save it will show a very large image
        

so we should add
        

some class name to this div here and we will display relative and we'll make it to have a Max width of 70 PX these will be custom we'll have an aspect of square aspect ratio I save and now this should be fixed there we go we have a small image and we have this here awe
        

some I feel like we are missing
        

something
        

so this should be called span not calls
        

so I save
        

so that to occupy two columns right here like that awe
        

some now let's go to this price I think there is an issue there we should add a class name and we will justify self to the center
        

so justify self to the center I save and now this should be pushed right here like that awe
        

some now we are add the quantity al
        

so for this one will have this class name
        

so I can copy that and paste it here like that uh for this one we'll have a similar class name but now this will say justy to the end and al
        

so we'll make the total price to be font uh semi bold okay now let's come back to this one and show the quantity and we had ear created a component called set quantity
        

so here we will use that component set quantity
        

so I click on this one it will have uh several props
        

so the first one will be cut counter and we'll set this one to be true actually if we just pass it uh by default it will be true but you can al
        

so specify like this uh we will have our cut product and we'll pass as the item it expects us to pass handle uh increase for now we can pass an empty function like this and al
        

so it expects handle decrease
        

so handle decrease and for now we will pass this function as empty like that I save and look now we have this it's showing the quantity here but increase and decrease are not not working we'll work on that logic later on let's show the total I'll include the C brackets and I'll take the item price
        

so I can include in this brackets I can say item. price and I will multiply this with the item do quantity I can use this format price right here
        

so I can say format price and let's save and see what we have and there we go have 80
        

so for a single item it's 40 but because we have two of them we multiply this and this and we get 80 for this subtotal we'll calculate it later on but for now I can see that our design for a single item has uh come along and when I expand we have it like that now in the next epi
        

sode let's see how we can remove an item from cut
        

so in the last epi
        

sode we were able to design our item content right here and in this epi
        

sode I want us to see how we can remove an item from cut
        

so to do that we just come right here uh we'll go back to our hooks then use cut hook here and area we had added a function like this one for adding a product cut and we will add another function like that for removing item from cut
        

so I'll say const handle remove you can say remove product remove item
        

so in this case I'll just remove product from Cut I know it's a long name but it's a descriptive which is good
        

so here I make use of use callback hook and we invoke it it expects us to pass two things a function right there and a dependency array and the dependency array will contain our cut products
        

so this use callback will receive a single product we can say here product and this will be of type cut product type
        

so cut product type like that now we can write the logic right here and first of all we'll perform a check we will make sure that we actually have cut products before we remove anything do we have cut products if we do let's go ahead and remove one of the product that we pass right here
        

so in this case I'll make use of the filter array method
        

so right here I can just say const filtered products and I set this to be equal to our cut products. filter I invoke it we will pass an item at a time and WR here
        

so we will return item. ID is not equal to product. ID
        

so uh when we click on this product and we get that product then the IDS are equal we will not include that product in the filtered arrays and then we'll use this filtered uh product product array uh to update our state
        

so down here all we need to do is to call our set cut products and we invoke it and we set it to our filtered products and then down here we can update the local storage and al
        

so we can update a a toast message
        

so we can copy this right here I copy all that then paste here the toast message will be product removed then local storage we target the eShop cut products and we update with the filtered products we update the local storage with this and I save now we have our method here we should include it in our value and al
        

so you can make sure to define the type for that right here
        

so I can use alt shift bottom Arrow these will be handle [Music] remove product from Cut and we'll save a product it will return void
        

so I save awe
        

some now let's go to our item content right here uh we will say const we destructure handle uh remove product from cut this one we'll get this from our use cut right here and we invoke it now this handle remove product from Cut we will use it on our remove button this one
        

so right here I will return that uh function and I'll call it and I'll make sure to pass our item and I save
        

so that is our on click
        

so let's test it out let's refresh now I click on remove here remove and look product removed we go back shopping remember we can only add one product because we had coded the product inside of all this like the details are the same but we'll be fixing that later on
        

so I click add product add to cut view cut and look we have our product remove and it's working very well now in the next epi
        

sode let's see how we can increase and decrease the quantity from right here
        

so right now it's not working
        

so I'll see you in the next one
        

so in the last epi
        

sode we were able to remove an item from our cart and in this epi
        

sode I want us to work on this button for increasing the quantity uh for a product that is already in the cut
        

so I'll come to our use cut file here and below our handle remove product from Cut I'll create a new function right here
        

so here you can just say const handle cut uh qty increase
        

so cut quantity increase and we'll set this to be a use call back we invoke it we pass an arrow function right here it al
        

so expects us to have a dependency array the dependency array here uh will contain our cut products and this use call back will receive an item
        

so it will be similar to this
        

so I'll say product of type cut product type and then in here we can write our rogic
        

so to begin with we can set a threshold of a maximum value that our product quantity can be
        

so I can say uh product do quantity is equals equals is equals to 99 that is the maximum you can set it to 20,000
        

so this is up to you or the client
        

so now right here here we will return immediately and we will toast an error using toast. error and we pass a message and we can say oops uh maximum reached
        

so at the top here I'll create a variable that will help us to update the state and I'll say let uh updated cut like that it will be undefined and you'll be able to use it at the bottom here let's perform a check of whether we already have cut uh product
        

so if we have cut products let's proceed down here and we will set our updated cut to be equal to these cut products
        

so I can spread the cut products like that now the next thing that I want to know is the index of this product that we want to update in our cut products array we can use the find index array method and we had used it area and I'll go and copy it
        

so I'll open our fire Explorer then let's minimize everything I'll go to app then uh product product details here in a use effect we had used this uh particular method here
        

so I'll copy this logic and I'll come back here and I'll paste it here now this will be the index of our product right here that we are trying to to increase its quantity inside our cut products array and we can use this index to increase the quantity for this particular product but first of all uh we'll make sure that this exist
        

so if existing index is greater than -1 that means that um the product exist in our array else it does not
        

so here we'll say if existing index is greater than -1 then that product exists
        

so
        

so right here we can go ahead and increase its quantity and how will I do that I'll say updated cut and then we will get that product then right here we will get its quantity and we will set that to be Plus+ and we access this again
        

so I'll copy that and I paste it in front of our Plus+
        

so this way this will increase the quantity of that particular product that we are TR trying to update and now the only thing that remains is to update our cut products right here using our set cut products and we invoke this and we pass our updated cut
        

so I'll al
        

so come down here and I'll update the local storage
        

so we'll say local storage. set item and we invoke this we pass our key which is eShop cut items and right here we pass our j
        

son. stringy and we invoke it we pass our updated cut
        

so this is it okay I hope this makes sense
        

so now all we need to do is to take this handle cut uh content increase uh we will Define its type at the top here it will be similar to this one
        

so I can duplicate this one alt shift bottom Arrow then then I take this I remove it and paste what I copied that way now our value expects us to pass this function
        

so down here you see value com prints we come here and we pass handle cut quantity increase and I save now let's hook it up to this button
        

so we come here at our item content we bring in handle cut quantity increase and then we go to this button plus button okay we had already added this handle quantity increase and right here we paste our handle cut quantity increase we invoke it and we should pass our cut item I save and let's see
        

so here I click this does nothing here look it increase its quantity and al
        

so the totals here are updating decrease is not yet working
        

so in the next epi
        

sode let's work on our increase
        

so in the last epi
        

sode we were able to handle increase of quantity of a cut item and in this epi
        

sode want us to handle decrease now that we already worked on this one this decrease will be straightforward and it will take us about a minute or two because most of this logic will be the same
        

so what I'll do I'll just write all this function for increase I copy come down here and paste we will change the name here to decrease we will receive the product we will have a variable then here instead of setting a maximum we will set a minimum
        

so the minimum will be one
        

so if we get uh less than that then we draw an error and we can say oops uh minimum reached then here we make sure that we have our products we set updated to those products we get the index of our product we make sure that um that product Exist by performing the check of this index it must be greater than1 then here we access that product and then we access the quantity and we set that to minus minus instead of Plus+ to this
        

so we take the existing quantity we subtract and then here we update our state and we al
        

so update our local storage All That Remains is to pass that to our value and Define the type
        

so we make sure that that is in our type here I duplicate this one we change increase to decrease then let's copy this one come down here and we pass that function to our value here
        

so I save now that should be accessible now from our use cut hook
        

so here we access our handle quantity decrease and from this we copy that and we will use it on our minus
        

so from handle quantity decrease here we paste it there okay
        

something is wrong I copied the wrong thing
        

so I'll copy this and I'll paste it here but now this should be decreased we invoke it and we pass our item now that should decrease the quantity
        

so I save Let's test it out right now it's 19 18 and when we get to one that's the minimum we can get
        

so if you want to just remove the item from Cut you can click on remove and it's working awe
        

some start shopping
        

so that is now working well and in the next epi
        

sode let's work on clear cut in this epi
        

sode let's work on clear cut
        

so this will be pretty easy uh we just need to reset everything in our cut
        

so right here we can create a function const uh handle clearcut and we set this to use callback we invoke that it expects uh two arguments a function and a dependency array
        

so we pass the dependency array as our cut products we will receive nothing in our use callback and here we can just reset everything in our cut
        

so we will set our cut products to null
        

so that will clear everything we should set uh the cut total quantity to null
        

so I'll set that one to zero last three we will uh reset our local storage
        

so I can copy this local storage it can be still set item you can say remove item but it can still be set item E
        

soP then we set this to null
        

so it won't have anything and now this is our function for clearing the cut we should pass it right here and al
        

so Define its type
        

so right here at our cut context type we Define each typee here we will have handle clear cut it will be a function that receive nothing and returns nothing just like that void I save and now we come to our cut client is where we have clear cut button
        

so in our cut client let's look for clear cut
        

so here we will simply call handle clear cut we invoke it and that is all we need to do but we should get this from use cut
        

so at the top let's make sure we are D structuring our handle uh clear cut right here
        

so that one we are calling it right here and it should work
        

so I save and now when I click clear cut it should create everything clear cut there we go
        

so it's working well the last thing thing that remains here is to work on this subtotal okay
        

so this subtotal will work well whenever we have um multiple products here and we get the totals for each
        

so we'll see how we'll handle that in the next epi
        

sode in this epi
        

sode I want us to calculate the sub total and al
        

so the total cut quantity and that total cut quantity is whatever we'll show right here at our cut count and uh before we do that I want us to Al have different products in our cut ear in the course we had taken a shortcut of including the same product for The Details page but we can easily change this
        

so we'll start by changing that
        

so that we show the correct product whenever we click here you need to go to your products folder then to page and this is where we are passing this product and this product we are getting it from utils
        

so actually what I'll do I'll just remove that product now and if we go to our utils
        

so utils here and this product we can actually uh remove it completely
        

so I'll go ahead and Del it and what we will do is that we will make use of this products right here these products since we already have the ID of the product whenever we click it in our params
        

so right here we will say const product will now be equal to and we get all our product
        

so it's a product and now this will come from our util the list of products and we use the find array method and here we will pass an arrow function we will get an item at a time and we'll perform a check we'll return the product whose item right here ID is equal to our params do product ID then this product will be able to pass it here and here
        

so I save and that should get us our product let's see if it works uh we click on this one iPhone 14 okay it's still showing the old one let's refresh everything and it gives us this new product now let's test again let's click this keyboard there we go now it's giving us the correct product for each uh which is really cool and what this means is that we can now be able to add multiple products in our cart
        

so first of all already in our cart we have a product I think uh let's add another one let's add rch keyboard two of them add view cut and look now we have two products here we can increase the quantity we can decrease the quantity and we can remove a product uh
        

so this is really nice okay
        

so now All That Remains is when working on this product product is to get them from our DB when we actually get there which will really be cool
        

so now we can now be able to calculate the sub tootal the sub total is this amount added by this amount added by any other amount that will be there and then the total cut quantity now is this quantity added to this quantity okay
        

so we'll do that in our use cut and we'll do that every time our page roads or whenever our cut products changes
        

so from the top I'll come right here after this use effect I'll al
        

so do this in a use effect
        

so I'll say use effect and I will invoke this
        

so This expects us to pass this function and a dependency array
        

so we al
        

so pass those brackets there and we pass our cut products as the dependency
        

so in here is where we'll do our magic
        

so we can start by by defining a function
        

so I'll say const get uh totals which will be equal to an arrow function and we make sure to call this function down here
        

so still inside the use effect
        

so we invoke it down there we now do everything in this function we will be using the reduce array method we will call our cut products and we'll say do reduce and we invoke it this will accept two things an arrow function here and then it al
        

so accepts
        

some defaults and the defaults here will be an object this object will have total and we'll set this total to zero and then it will al
        

so have qty and we'll set qti to zero
        

so this total will be our total amount and this qty will be our total cut quantity
        

so this object that we pass here is our default and this default is called the accumulator and for this function that we passed the first one here usually accept uh two parameters right here uh that will be the accumulator
        

so we can say accumulator and al
        

so the current item that we are mapping through
        

so here this object will now be our accumulator here and then we have this item the item is each item that we are going through
        

so right here the first thing that we will get is the item total con uh item total will be equal to
        

so the item total it's uh the item price times the quantity
        

so it should give us this value here
        

so that is what we are calculating here
        

so item total will be the item do price uh we multiply by item do quantity that way we get our item total and then down here uh to get the uh total cut quantity the total price we will take the accumulator total then we add to this item total
        

so we'll say accumulator do total uh we add to this item total
        

so we can do this using a short hand we can say plus is equals item total
        

so what this means is that accumulator total is equals to accumulator total plus item total okay then we can calculate the total uh cut quantity by taking the accumulator quantity qty Y and we add this to our item qti or quantity item do quantity and then down here we will return accumulator accumulator now we have both Total and quantity
        

so we return accumulator like that okay and you see now this eror disappears because it expected us to return
        

something now I save and we can set an equal sign here and we get the accumulator from there
        

so we'll say const we destructure the values of the accumulator and that is the total and the uh qty
        

so it's complaining okay before we perform all this to get rid of that ER we should make sure that we have our cut products
        

so right here we say if our cut products exist let's go ahead and do all this
        

so I copy this up to this point then we take it to the top using alt and but top arrow and you'll see this disappears because now it's certain that cut products exist okay now down here uh what we will do is to update our state
        

so right here uh we already had Set uh cut total quantity and now we'll set this one to qy and right here we didn't have the state for cut total amount
        

so we can create that state we can say const cut total amount and set cut total amount and we set this one to be equal to use State and to begin with the value will be zero
        

so we take this set cut to to amount and we use it right here I tab I paste and we'll set the total amount here to be our total this total is the one that we destructure from our accumulator right here
        

so right now the only way to test this is to log these values to the con con
        

so con
        

sole uh Rog uh we will have qty and this will be our cut total quantity let's duplicate this I'll shift bottom Arrow here let's say amount and this will be cut total amount and actually um we didn't say amount we said amount
        

so I think it's good to spell this correctly amount amount uh is there
        

somewhere else we need to change now
        

so we save this and we come to our app con
        

sole okay let's refresh everything con
        

sole okay this is crazy first of all is 10 Mount zero oh this time is the default value that we had set earlier
        

so let's remove that default here we had said a default of 10
        

so let's remove Z that and set it to zero I save and let's refresh again now to begin with all this are zero when our cut rolls and updates the total quantity for our cut is five and then the total amount is 400 which makes sense
        

so if we take this 300 and we add to 100 we get 400
        

so this 400 value is the one that we will show here but we'll format it using the format price and if I increase here we get now total here is six the amount changes from 400 here to 511 and 511 makes sense because it's this plus this
        

so if we go back here and we add another product let's add 70
        

so we take this mouse and we add to cut view cut now we have a total of 4 6 7 and we get total here and then the total amount here will be 5111 + 70 581 perfect
        

so our shopping cart is working well All That Remains now is to show the total here and al
        

so we will show the uh quantity here
        

so I'll see you in the next one for that
        

so in the last epi
        

sode we were able to calculate our totos that is the sub total and the total cut quantity but in this epi
        

sode I want us to show the on the UI
        

so first thing uh let's export our cut total amount and our cut total quantity using our value
        

so here here we already have cut total quantity let's include our cut total amount this will be number okay I save that let's come to the bottom here we have cut total quantity we are al
        

so expected to have our cut total amount
        

so we pass that we include a comma and we save awe
        

some
        

so now we can go to our cut client and we will receive that cut total amount here
        

so cut total amount we get that we come to the bottom here where we had our sub total and here we remove this we include our carry brackets we will use our format price um method
        

so format price from our utils we invoke it it expects us to pass a number and we'll pass our card total amount right here we save and this should be formatted there we go now we get this amount there amazing now we need to show our cut count here
        

so for cut count we will do that on our Navar
        

so we go to up then components Navar
        

so we we had only Navar here
        

so we will add a new file for this particular component called a cut count
        

so it'll say cut count and then TSX
        

so here uh State rest functional component cut count we return a div and we'll do
        

some stuff here okay let's start with a class name it will be relative we'll have a CA of pointer
        

so whenever we click on our cut count it will be taking us to our shopping cart
        

so that means that we will need to have an onclick event we pass this AR function and here we will have our router uh do push and we will push to our stroke cut we don't have this router defined
        

so let's come here before our return statement and we'll have con router uh will be equal to use router from next uh navigation we invoke it and whenever we do this whenever we use a hook uh this should now be a client component
        

so here we pass use client
        

so I save to AO format and this is now what we have
        

so far we will get our cut a total quantity
        

so we'll say con we D structure cut total quantity and this will come from now our use cut hook
        

so use cut and we invoke that and now we'll use this cut quantity to show the number awe
        

some
        

so now inside this div uh we'll have two things we'll have an icon and and let's include that icon inside this div and we'll say that this is CI shopping cart it's not being suggested I cross it uh we should import this
        

so let me copy then at our Imports uh we'll say import we D structure CI shopping cart these will come from react icons then stroke CI now here we'll have a class name and we will increase the size for this to be 3 XL extra large okay
        

so I save to Auto format and now below this we will have the cut counter we will include it in a span we will say cut total quantity there now we'll have
        

some Styles class name name and this will be ab
        

solute to our parent div which was relative
        

so here this will be ab
        

solute and we'll have a top which will be a custom value of 10 PX we will have right we'll have al
        

so a custom value of10 PX we'll have BG as straight 700 we will have text S white we will have height of six we'll have width of six
        

so this is a circular counter
        

so let's make it to be rounded full Flex items to the center um justify Center and then the text will be small I save that now we have this component let's go to our Navar and instead of showing cut counter we'll show that component here
        

so here I get our cut counter from our cut counter like that we save and it should show here let's see and there we go look really awe
        

some
        

so we have included this uh circular label with seven there using this span then the icon is this one right here and we ab
        

solute repositioned this one to be at the top there and I hope now it makes sense now if I decrease here this is al
        

so changing six look five 6 7 if we remove four and this is working now awe
        

some now from here we'll go to a whole new section uh because when we click on checkout uh we should actually be able to go to the checkout page but we should al
        

so make sure that the user is there and is logged in
        

so we don't have a user in our application and in the next section of this course we will be working on authentication
        

so I'll see you in the next section now the next step is to add a user in the system
        

so that we can proceed with checkout and for that we will be working on uh an authentication system where we can sign up user login user using email and password and al
        

so using Google sign up but before we do that I want us to create a reusable input field in this particular epi
        

sode and then we'll be able to reuse it uh in different sections of our application
        

so we'll create an input field uh that looks like this and before we proceed I want to remind you if you need the
        

source code for that entire application or all this entire course it's available on my patreon and here it is you just need to unzip it
        

so I'll leave a link to it at the description section below uh and you just need to join for $3 per month and you'll al
        

so get access to other uh
        

source codes for my videos here on YouTube
        

so if you scroll you'll see we have uh a lot of other
        

source codes including Paypal payment um including real time chart app including another eCommerce site where we used Redux and
        

so much more
        

so join my patreon uh to Simply support my content and uh what you get back you get back all the
        

source code for my videos here on YouTube and you just need to join for just uh $3 per month and al
        

so you can give me direct DMS to ask me any questions about the course and I'll give your messages a higher priority now we will be making use of a react hook form to create our input field
        

so we need to install this
        

so I'll copy this one and I'll jump into vs code here here um I already have a terminal open but I'll add a new one
        

so that I can install that Library
        

so here I'll paste npm install react hook form and I'll hit enter
        

so this completed installing
        

so we'll go to app then components and right here we can create a new folder and we will call it inputs inside our inputs let's add a new file and we will call it input and then TSX I hit enter stat functional component we say input and right here uh we can return a div and let's define an interface for this input
        

so at the top here uh first of all we can say that this is a client component by saying use client then here we will define an interface and we will say input props right here we'll have an ID which will be a string we will have a label which will be a string and we will have a type
        

so for this type we are able to say whether uh this input field is a text input field a number an email and
        

so on
        

so we'll have a type which will be a string uh we will have disabled and now this will be a Boolean this should be optional we'll have required which will be optional it will be a Boolean we'll have register and this will be for react hook form to register this input field and uh this will be of type use form register this will come from react hook form
        

so click on that to Auto Import it from react hook form and then here we will use angle blacket and we'll pass here fi vales and al
        

so this will come from a react hook form it's not being Auto imported
        

so we can do it here manually field values like that then here we'll have errors and these will be filled errors and al
        

so this will come from react hook form
        

so we can import it right here uh like that
        

so this is the interface
        

so we take this input props and we use them here
        

so here I'll just say react then FC angle brackets and we pass our input props right here we should destructure the different props uh we have ID comma uh we have label comma we have type comma we have disabled we have required okay we have yes we have register we al
        

so have required finally we'll have errors like that I save
        

so we'll use all these props to work on our input uh field
        

so here for this div let's add a class name and we'll have a width which will be full uh we'll have relative
        

so right here we can add an input element
        

so I'll say input and this element will be self crosing like that and then right here we'll be having a label and HTML for here will be ID and for this Rebel what we will show here is our label there's one which we bring in Via plops
        

so we have an input field and we have these label
        

so all we need to do is to add
        

some class names uh to make our input field look good
        

so the goal is to make it look like this one here okay I'll add a class name we'll say here we'll have a width to be full we'll have padding of four we'll have padding to the top of six we will have an outline of n BG will be white font will be light we'll have a bard of two it will be rounded
        

so this is the Border radius we say rounded MD uh we'll have transition and when it's disabled we will decrease the opacity
        

so we'll set opacity to 70 and then here if it's al
        

so disabled uh set the cur
        

sor uh to not allowed since we have
        

some Dynamic Styles we need to convert this to use back ticks okay like that
        

so now we can be able to make use of
        

some Dynamic Styles and here I'll make use of the money sign and right here we'll check if we have the errors
        

so I'll say errors then use this full column ID these errors will be coming in form of an array and then we access the error for this this particular field using the ID and if that error exist then we'll show these Styles we'll say the border is Rose then 400 this is a reddish color
        

so it will show that you have an error else if we don't have the error we will show a border of straight 300
        

so straight 300 like that
        

so here alt shift bottom Arrow we check if we have errors if we have errors here we'll set Focus full column and and we'll say border row 400 and right here we'll say Focus full column border straight 300 awe
        

some and these are the STS for our input okay apart from the class name here we need to add more plops
        

so we can add autocomplete I don't like it autoc completing
        

so I'll set this one to off then here we'll say the ID is ID then here I'll set disabled to be disabled
        

so these are the values that we pass through uh plops we'll see how we'll be using them
        

so right here let's register our input field we just need to say dot dot dot then here we call register and this is a functionality for react hook form and we register our ID then we set this field to be required
        

so if we try to submit this input field uh when it's not filled then it will draw an error then with these Styles we will show that we have an error then here the Press holder uh will be empty and here the type we use type like that and that's it for this input
        

so I saved Auto format and these are the various props these are the VAR crass names and then here we have this label we need to add styles for it uh the label is this particular name that we show here okay
        

so as you can see on focus it moves up a bit decreases in size out of focus it comes back
        

so a really nice style there we'll come here and we'll add a class name and we'll say ab
        

solute
        

so it will be ab
        

solute to this div remember here we had set this to be relative
        

so now the label will be ab
        

solute to that div and then I can make them to appear downwards here for clarity we'll have a curer of text we say text is MD uh duration uh this will be for the animation
        

so duration here will be 150 then let's add transform then here we will translate along the Y AIS
        

so Translate hyphen Y and this one will be three and then red set top here to be five let's set a zed index of 10 we'll set an origin of zero we will set a left of four and here it'll say p and then hyphen press holder hyphen shown we scale to 100 I can duplicate this alt shift bottom Arrow and P press holder shown and we translate along the Y AIS
        

so we'll set translate to zero
        

so y here to zero and then down here uh we'll say p Focus here we scale down
        

so we'll scale to uh 75 and then here P Focus we will translate along the Y AIS
        

so translate and we'll set this one to four
        

so here translate is 1 n now what this means is that when we are on Focus we will scale down our label and move it up
        

so when we are on Focus like this look we scale it down and move it up then when it's not on Focus then it will show like this it will scale to 100 and it will be at its original position uh to test it let's uh see on the next epi
        

sode uh when we work on our register form
        

so I'll see you on the next one
        

so in the last epi
        

sode we started to work on our forms and in this particular epi
        

sode let's work on the design for our sign up form
        

so back to our app we created this input field and now we'll be able to reuse it on different parts uh let's come right here and I'll go back to up and I'll go to components and at the root I'll create a new uh file called form WP I'll say the functional component and I'll call this one form WP uh it will receive only one prop which is the children right here instead of defining an interface you can do this you can just say children and then right here you can use a full column and you say the type for the children will be react and then dot react node like that and now we receive this prop called children awe
        

some
        

so right here uh I'll have a div inside this div I'll have another div inside this div is where I'll include our children plop
        

so children and then right here we can have
        

some class name and for this we'll set the mean height to be fet H to be full uh Flex items Center justify a center padding to the bottom of 12 padding to the top of 24 and and then for this one we will add a class name and this is where we will set a Max hyphen width of 650 PX
        

so this will be the maximum uh width for our forms
        

so let's include that we can have a width to be full we'll display Flex Flex will be column we'll have a gap of six uh items to the center then we'll have a shadow XL then the color for this Shadow will be slate 200 it will be rounded MD and padding of four and finally for rarer screen padding will be eight avoid this space between this okay this is our form wrap right there now let's come back here let's minimize everything and I'll go to up and we'll create a new page how do we create a new page we add a new folder we give this one a name we will call it register and this is the name that will show on the route and then right here we add a new file and we can say page. TSX like that we say the TR functional component we will call this page register we will return the container component
        

so container we had created area during the course and here you can see we have one from Material UI and one from our components make sure it's the one from our component then let's cross start right here now we use our for form wrap
        

so here I say form and then wrap from our components again and I pass this right there and here we'll be passing another component and that component it's now our register form
        

so inside our register we'll create a new file and we'll call this one register form
        

so this our register form. TSX St functional component and we create our register form and let's work on it this one this will be a server component this is where we'll get any data that we want EG the user and here this will be a client component because it will have interactivity like on click and States
        

so let's have use client here and then right here I can include react fragments make sure it's react fragments
        

so that our rapper here will be able to flex all the items that we include in a column okay
        

so here let's add a heading and this will come from our components is self closing it expects one plop which is the title which is mandatory I'll have a HR element HR here and I can include
        

some Styles I'll say class name and BG will be slit and then uh hyphen 300 we'll have a width which will be full H will be PX okay uh for now let me save and then let's use this register form right here I'll say uh register form let's self cross it okay I save this is what we are working on where we have Local Host here and I'll go to this page now register
        

so register and we should at least have a heading and a line and there we go
        

so you can see our form WP here is having this Shadow and now we have this sign up for eShop and this line awe
        

some now down here we'll be able to add our input field our first input field
        

so let's make use of the input that we created in the last epi
        

sode
        

so make sure it's coming from components inputs input now this expects various plops it needs to have an ID and the ID here will be name then here it expects to have a label and the label here will be name and then here uh we will make it disabled when our our submission is loading
        

so here we'll be having an EAS loading state like that we don't have it let's add it
        

so here we will say const is roading and we say set is roading and this one we make use of the use State hook
        

so use state from react we invoke it uh by default it will be false
        

so this is roing is the one that you pass here when our submission is rading we disable the input field awe
        

some we have register and we'll make it to be register which we don't have yet and then here we'll have errors we will make errors to be errors which we don't have yet and then here we will have required now for register and errors we will get this from react hook form
        

so at the top here we will we will get them from our use form Hook from react hook form we'll say here const and we will destructure uh register this one we will get our handle submit which we'll use to submit the form we'll get our form State and we'll set this to be errors and all this will come from uh we'll set use form it's not being suggested but we will import it we will say here field vales in angle brackets
        

so that is the type that we are passing then we will invoke this and pass
        

some defaults
        

so this use form will come from react hook form
        

so here let's import the things that were not being suggested
        

so we'll say import and we destructure field values let's first say that this is from react uh hook form and then let's get here submit HRA let's al
        

so get our use form hook this one uh like that now this has an error means that maybe we missed the sparing yes we did
        

so this should be filled values uh let me save
        

so here we are simply calling our use form hook and this field values is just defining the types and here we get register here we get hand of submit and get form state from form State we are able to get our errors and here we can pass
        

some default values and I'll say default values full colum and we include them here we'll say email will be empty then here we'll have password which will be empty let's make sure that we have this comma here al
        

so for register we have a name
        

so we'll say name which will be empty awe
        

some and you can see this is showing up but it St is off uh
        

so I'll go back to the input field and uh make sure that we are doing the correct thing
        

so I'll come back right here and make sure that everything is fine
        

so a few things that I see we messed up first of all this is uh BG uh BG and then down here uh for this translate we should include a negative here negative translate y4 as well as this one negative translate Y3
        

so uh let me save that one and see if that uh makes it work well
        

so now I click on this it goes up and down now I don't want this CER to be disabled the it is disabled right now
        

so
        

something is wrong we should not include space between these two okay make sure this is not having that space and I save and now if I click now it's up and down awe
        

some it's working now well uh al
        

so you can see the text for this is not black
        

so we should fix the text for this one that is our label
        

so at the bottom here uh we should dynamically display the text depending on whether we have an error or not
        

so for that here I'll include the curry brackets and atic and at the bottom here I remove this one I include the car bracket and atic and here we can perform a check actually I'll copy one of these one and then I'll come right here and I'll paste it now this we will say if we have the errors instead of focus here and Border we'll say text will be row uh 500 or 400 uh this is the text we can make it uh more brighter 500 and then for this one we will change this if we don't have an error then the text will be straight uh about 400 I save again and there we go now look looks good
        

so when we have an error when we try to submit this form when it's empty we will show all of these as red now this is one of the input field
        

so I can use alt shift bottom Arrow twice
        

so this one will be for email
        

so I remove this one I say email and then here I say email
        

so this register will be able to make use of this ID to register this input field we'll take the password
        

so password and REO will be password now here disabled we'll have that register we will have errors we have required but al
        

so uh we'll add a type here
        

so the type for this one will be password
        

so that will hide it
        

so let's save and we should now have three input Fields like this for password it hides the content after this input we'll be having a button
        

so I'll say button and for this button it expects us to pass a label and we'll dynamically show this label
        

so we'll set this to be equal to we'll say EAS it it loading is our form loading
        

so if it's loading we will set this button as loading then right here if it's not loading we will say sign up and then this button al
        

so expects us to have an onclick event
        

so here we will have onclick and whenever submitting this form what we will call is our handle submit and that hand submit it's the one that we get from our use form hook
        

so this handle submit I'll copy it and I'll paste it here and for this H submit as well I'll invoke it and we will pass a function called on submit
        

so on submit we are going to create it in a few this button let's make sure we are importing it from our components like that let's create this on submit at the top here and here we'll say const on submit and we'll set the type for this to be submit HRA
        

so I call submit HRA and that we get it from here and then here we said this is the field values the type that will be received by this on submit is the field values and here we set it to Be an Arrow function that will receive the data now this data is our field values and before we do anything we will be setting the is roing state to True here okay and then right here let's rock this data the con
        

sole
        

so con
        

sole. Rog of our data and we see what we will be having Okay cool
        

so we'll take this data and we'll submit our form right here to uh register the user and save the data in the DB and
        

so on
        

so this is our unsubmit function which is not yet complete but we pass that to our under submit right here okay and now let's test this
        

so if I click here go to con
        

sole clear the con
        

sole now here right now we don't have any data we haven't filled anything and it should throw an error and let's try to sign up now look everything is red uh this is because in our input we said that this input should be required and we passed that prop right here for each of them and because of our Styles everything uh is turning to be red because of these Styles here awe
        

some now if we include the name look the error disappears for the name if we try to include the email it disappears for the email and
        

so on okay
        

so let's see if we are having values I'll say Chia and then here I'll say Chia at gmail.com then here I'll say uh password then I sign up and look at our data where we are submitting our form here con
        

sole log data we get our data we get the name we get email we get password which is awe
        

some
        

so this is working well
        

so right here after our button I'll include a paragraph This paragraph will say already have an account uh if you do we will show a link
        

so this will be a component from our next Link in here we will say login then it expects us to have a href and you'll take the user to the login page which we haven't created yet
        

so
        

so we'll work on that later on
        

so here we say log uh the only class name that I'll add here is an underline
        

so I'll say underline and then for this paragraph we'll al
        

so add a class name and we'll say that the text here is small
        

so I go ahead and save
        

so after saving we have this down here I already have an account login awe
        

some
        

so that is cool and this is now our signup form awe
        

some now one last thing we need to include this sign up with Google
        

so at the top here after our heading we should have included a button
        

so I'll say button it will be out Tred and we'll have a label that will say uh sign up with Google uh we'll have an icon and we'll include AI uh outline Google this one it's Auto imported then here we will have an onclick event for now we include an a function that has nothing okay
        

so I save then let's come here and see if it's there now look looks good now in the next epi
        

sode let us work on our login form it will be similar to this one
        

so that one will be shorter awe
        

some
        

so in the last epi
        

sode we were able to work on our signup form and in this epi
        

sode let's work on our login form minimize everything here come to up then I'll create a new folder and here we'll say login inside this folder let's create a new file and this will be page. TSX create another file as well inside login and this one will be our login form. TSX awe
        

some now inside the page we create this component using stat functional component we'll say log and in here we will return the container component component
        

so let's say container this will come from our components let's make sure it's from our components inside this container we'll have a form WP
        

so we use the form WP component uh it will come from our components and let's make sure we cross like that and right here we'll pass our login form let's create our login form component here stess functional component and you'll say login form uh for now I will return the react fragments just like that and let's pass our login form right here
        

so login form uh okay I missed an angle sign there then we Auto Import it and we self cross it I save it's Auto formatted this is all we have at the page for now now let's jump into our login form here now most of the things that we included in our register will al
        

so be available in our login okay what I'll do I'll actually copy everything from here I'll paste in our login form and we'll go step by step correcting everything okay okay
        

so here let's go to login stroke login
        

so we don't have anything for now and uh let's start at the top top here
        

so instead of register form we'll say that this is the login form
        

so you can highlight this then use control D to select even at the bottom here to make sure that we are exporting the correct thing
        

so here I'll say log let's go back at the top now here we'll al
        

so have the loading State we'll al
        

so have all these but for the default values we'll not be having an name
        

so we remove the name okay we will have an onsubmit function like this and then we come here for the return
        

so for the heading we will say uh sign in to E
        

soP and then for the button we can say continue with Google instead of sign up
        

so continue with Google here then we'll have HR we won't have this input
        

so we remove that one then we'll have an email we'll have a password we'll have a button saying loading all login and then here you have a paragraph will say um do not have an account uh do not have an account sign up then here instead of login we'll say register okay I save and we should have our login form right here there we go
        

so sign in continue with Google then email password login if we don't have anything Els then we have don't have an account sign up
        

so if I click on sign up we go to our sign up page
        

so I'll see you on the next one hello everyone
        

so in the last epi
        

sode we were able to work on our signin form and in
        

some previous epi
        

sodes uh we al
        

so worked on these input Fields together with the registration form and now I want us to start writing the logic for our authentication and for authentication we will be making use of our next op and al
        

so we'll be making use of Prisma and mongodb uh for data storage
        

so to get started with in this particular epi
        

sode we will create the schema uh using Prisma for our user at our next o.org we can go to the documentation and see how we can get started on that
        

so here I'll just click on get started and then you can go to adapters here and from adapters you'll see that we have Prisma
        

so click on Prisma if you following along with me and then from here you'll see that we need to install
        

some dependencies first
        

so here I'll copy the first line here contrl copy then go to vs code then you can pop a terminal I'll paste that command and I'll al
        

so add next hyen o and then I'll hit enter
        

so that command will install those three dependencies al
        

so you can see we need to install Prisma as a Dev dependency
        

so you can copy this one I'll control copy and uh yeah we can install it after this complete but as this installs uh there is an extension that you can install
        

so here you can search for Prisma uh there one here
        

so install Prisma mine says that I need to reload and this will help to highlight our code when creating the Prisma schema
        

so this is a vs code extension if you're using vs code okay now this completed installing and I can go ahead and install Prisma as a Dev dependency I'll hit enter now as start installs we'll come to our files and and we need to create a new file and at the root here we will create a new folder and we can call it Prisma and then inside this Prisma folder I'll create a new file and we will say schema. Prisma I hit enter now let's come back to all JS here actually from here you can see we have this create the Prisma schema from scratch I can click on it and this will give uh details on how we can create this Prisma schema for our user for this schema it's meant to be for postgress SQL but it will be
        

so similar to our mongod DB1
        

so we need to define a data
        

source we need to generate a client and then right here we will create a account model then down here another thing that we will do is to create a user model and there are just a few differences between these models and one that we will be using for mongod DB you can come here and click on mongod DB support and you'll see we will be changing things like ID and we will be mapping our ID since mongodb uses an underscore ID
        

so we need to map that ID
        

so that we just use ID here and then uh just other few things like the user ID refresh token we need to do
        

something like this access token and ID token
        

so I'll come back to the top and I'll copy I'll come to my vs code and I'll paste everything here I will remove this verification token I will remove this session now we have account we have user we have client and we have this DB
        

so let's start from the top uh to fix uh stuff and al
        

so you can type them out if you didn't copy
        

so there is no problem with that okay we will set a provider to mongod DB
        

so remove post address and set this to uh DB then we'll have URL and we'll read this from the environment variable that is okay uh we won't have this
        

so remove that click that and now this is our data
        

source okay for client we go to provider here and we'll set Prisma client JS as our client and we won't have this
        

so remove this one and there we go now we come to account we'll be having ID we will change from C ID and we will set this to AO and then at the end here we will map this ID to our underscore ID
        

so we'll say at map we invoke this we incude this quotes use double quotes uh I saw that a single quote has an issue
        

so and then I ID there and then at the end here I'll say at DB doob ID and this right here is the same same that we saw when we go to Mongol DB support here this one right here and then you can see we have user ID but here we have it as just string
        

so we need to add these right here at DB object ID
        

so space then include this and then here we'll have refresh token this will be an optional string but at the end here instead of at DB text we will say at DB string and if you check the documentation you'll see that here refresh token is where we are setting this as Deb string
        

so we need to do the same for Access token and ID token
        

so you can see all this is in the documentation
        

so from here at access token we'll say at DB do string we'll have ID token as string which is optional but then here we'll al
        

so have this as string
        

so let's come to our user model the ID here will be the same as this one
        

so we can copy this one then come right here and replace this we will have account as account but we won't have session since we removed this one
        

so I'll go ahead and remove that one we will add more properties here because we will be hashing the password we will add a hashed password and we'll set this to be an optional string we can add uh created at when the user was created this will be date time and at default will be now
        

so this will generate the date uh automatically when we create uh the user al
        

so we can have it updated art and this can be date time and the time will be at updated art one last thing that we will add here is the role and the RO will be of type rooll and the default will be user in caps
        

so this type R we need to create it
        

so at the bottom here we will use inam and we'll say roll and right here we'll have user or we'll have an admin
        

so here we need to include at default that's why it's shouting and there we go
        

so I save and this will be our Prisma schema for our user
        

so I'll see you in the next one
        

so in the last epi
        

sode we were able to work on our Prisma schema and in this epi
        

sode all us to work on
        

some Logic for our next O
        

so coming back to the documentation still at our all stroke Prisma schema if you go to the very top after installing the dependences you'll see here we have the setup
        

so what we need to do is to create this particular file okay
        

so we'll create a new folder called Pages then we'll create a folder called API a folder called o and a file called blackets Next o
        

so let's do that first and then we'll continue
        

so we just need to come here let's minimize everything and at the root we will create a new folder and we'll call it pages
        

so if you familiar with the past versions of nextjs uh you are then familiar with this Pages folder
        

so I hit enter I'll create another folder called API I'll hit enter inside the API folder I'll create another folder called o and I'll hit enter and then inside the all folder is where we will create a new file I'll use the square blackets like that and then we will spread this using three dots and I'll say next of and out here we'll say TS since we'll be using typescript and I hit enter
        

so coming back to the docs you can see how we integrate uh Google provider
        

so we have providers like this then Google provider it's an array
        

so that means that you can include multiple providers you can have Google you can have Facebook you can have GitHub you can have credentials for email and password and I'll show you how to add that one
        

so what I'll do I'll copy the cont contents of this file I'll go ahead and copy and I'll paste it here
        

so as you can see we have
        

some issues here we have this adapter is complaining is coming from o Prisma adapter now uh in my previous application I used a different dependency from this one
        

so I think we should use the same right here you can just say npm install then at next of then stroke Prisma adapter hit enter to install once it completes what you need to do is to change right here from o to next o
        

so add next hyphen o and then you'll see that this error disappears and then we have this Google provider this is complaining and you can see it's an issue with type
        

so type string or undefined is not assignable to type string
        

so here we will Road our process. EnV uh do Google current ID as string like that and then client secret will do the same
        

so right here just add as string like that and those disappears as well awe
        

some now one thing that I want us to do is to be able to uh load our Prisma client globally
        

so we'll change how we are getting our Prisma client let's do it right now right here at the root add a new folder and you can call it Libs and inside this folder we will create a new file which is Prisma db. DS and in here uh we will import our Prisma Cent
        

so Prisma Cent from at Prisma Cent and then we'll declare a global variable called Prisma
        

so here we'll declare Global we'll say variable Prisma will be of type Prisma client or it can be undefined we will load our client we'll say const client we check first if Prisma is available globally
        

so we'll say Global this do Prisma
        

so if that exist we will set the client to that Global Prisma else if it doesn't exist we will create a new one and we'll just use this L here new Prisma client
        

so I can cut that and remove this completely then right here we will add it there and then right here let's perform a check
        

so if uh process. EnV and then do not environment
        

so if this is not set to production like that
        

so now we Define this particular variable we'll set it right here to be our client and then at the bottom we can now export our client
        

so we'll say export default client okay
        

so this is all we need to do in this file and now we should import this uh client in our next or
        

so instead of Prisma client I'll just remove that uh we'll say import Prisma and this will come from uh at Libs and then stroke uh Prisma DB and remember this Prisma is whatever we exported here as client okay
        

so here now we use this Prisma at our adapter awe
        

some
        

so I Sav that now here we are configuring one of the providers but we will al
        

so add our credentials provider
        

so here we'll add credentials uh provider we invoke it and we pass an object al
        

so we should be importing this it's not being suggested but we should be importing it uh I can say here alt shift bottom Arrow we duplicate the one for Google and here we get our credentials Provider from credentials then we use it here credentials provider we will pass name here will be credentials then we'll say credentials we pass an object we'll have email label will be email uh type will be text then we'll have password right here comma password we'll have a label which will be password and we have a type which will be password we have
        

some issues here but they'll disappear after we write the next line but
        

so far you should be having the name as credentials then credentials here you set a new object you should be having email with label and type then you should be having password with label and type now after this credentials object right here include a comma then hit enter Then you write a sync and write this method called authorize and invoke it and you'll pass credentials here and then right here we can work on
        

some Logic for logging in a user using email and password
        

so right here we'll first check if we have an email and if we have a password and we'll do that by using this credentials
        

so we can access them like this credentials um. email and credentials. password
        

so we'll say if we don't have uh credentials. email all if we don't have credentials. password we will throw an error
        

so here we throw an error we pass our message and we can say invalid email or password they supposed to be caps like that then down here we can find a user using Prisma
        

so we can say const user we will await here we will use Prisma dot user and then Dot find unique
        

so this we try to get a user from our DB but we have not set up the DB yet but we'll do
        

so in the next epi
        

sode
        

so let's just proceed here and here we can say where email is our credentials. email now let's perform a check
        

so here I'll say if we don't have a user or if we don't have a user that has a hashed password then we will throw an error again
        

so here we can just copy this one and paste it here let's continue down here now here we check if the password is correct
        

so if this step passes then we have a user but now we check if the password is correct okay
        

so for that uh we will be hashing and unhash the password using bcrypt
        

so we need to install bcrypt
        

so I'll pop the terminal here and I'll say npm install bcrypt and al
        

so I think we should install the types
        

so at types uh stroke bcrypt
        

so I hit enter once it completes we can come right here we'll say con is correct password we set this to be equal to a wait and we will await bcrypt do compare
        

so we should be importing this bcrypt it's not being suggested
        

so let's import it manually here import bcrypt from bcrypt then down here we await bcrypt uh. compare we invoke this one and here we will pass two things the password that the user enters which is available in our credentials. password and then the hash password which is in the DB
        

so user do password
        

so bcrypt will be able to compare them and if it's correct it will return true else it will return false
        

so now here we check if his correct password is true or false
        

so we'll say if is correct password is false then we'll draw an error we draw an error again and we will say the same thing invalid em or password
        

so I paste it here and finally if we have a user and the password is correct we will return the user
        

so here we return user and now you see this error right here disappears and I save after our providers array uh we'll provide
        

some more settings right here we'll say pages and right here we'll say sign in we include log in here after Pages we'll have debug here we will say process EnV and then dot nde environment development and then right here you'll set a session strategy will be JWT and here you'll provide our secret key will be available in process uhv then next uh allore secret now I'll go ahead and save that file
        

so I'll see you in the next epi
        

sode where we will get to set up our mongod DB
        

so in the last epi
        

sode we were able to work on our next of Fire Light here and in this epi
        

sode I want us to start by setting up mongodb
        

so that we can get this database URL
        

so you'll go to your browser and then you'll visit mongod db.com and if you don't have an account you'll create one and then you'll create an organization and then you'll create a project
        

so right here at projects I'll go ahead and create a new project and I can call it next uh eShop maybe I can add t for tutorial since I have another E
        

soP
        

so I go ahead ahead and create next right here do we have other members no I'll go ahead and create project once you create the project you'll be uh required to create a cluster uh I'll click on here create a deployment and here you can see we have this one which is free
        

so I'll click on free then here I'll go with the defaults and I'll click on create then I'll come down here and we should choose a username and a password that can access the cluster
        

so here I'll go with a very simple username and password can just use this name chiao the same for password and I'll create the user
        

so I click on finish and close go to overview awe
        

some
        

so here it's roading the overview uh I think what you can do now is to come right here go to security then go to network access and from here you can click on ADD IP and you can click on allow access from anywhere
        

so it will give you this particular IP address and you can confirm
        

so that way you can be able to access from anywhere
        

so here it's still pending I don't know if I refresh it will come through there we go now it's active awe
        

some
        

so go to database now you can see you have all this you can click on connect then you can come right here mongodb for vs code then you'll get this connection string
        

so I'll copy that connection string and I'll go back right here we will create an environment variable
        

so at the root add a new file and you can say EnV you'll have the string that we copied from mongodb but you'll set that to this one
        

so here before the string we can paste this then set equal sign to these and you can either leave it that way I think or you can include it in
        

some quotes
        

so we should replace this with password
        

so we'll have chiao and chiao that was the password in my case you'll come right here and you can add a database name
        

so here I'll say E
        

soP and don't use my string because I'll be dting this DB down go ahead and create your own okay
        

so that one I'll go ahead and save awe
        

some now if I come back and close you can go to blowe collections here this is where you'll see your databases and you can see we don't have anything okay uh
        

so now that we have added this DB URL at ourv we can come to the terminal and you can say npx Prisma DB push then hit enter
        

so environment variable roaded here you'll allow access and let's see what happened
        

so it has loaded the environment variable from EnV then Prisma schema loaded from Prisma schema your database indexes are now in sync with the Prisma schema
        

so now if you come back here and you click on refresh you'll see that we have a database called E
        

soP and that name is coming from our connection string right here this one and then here we have now account and we have user
        

so that means that our Prisma and mongodb connection is working we can go ahead and create an API that will allow us to create a user
        

so let's see how we can do that I'll minimize everything
        

so to create an API next3 we need to come to up then you'll create a new folder and you'll call it API inside this folder you'll create another folder and we can call this one register inside register now we can create a file and you must call it route. TS uh first of all we will bring in bcrypt
        

so we will need BPT to Hash the password then we will import Prisma
        

so import Prisma from at stroke Libs and then stroke Prisma DB and then right here we will import next response and this will come from next server like that
        

so these are the three inputs that we need and right here we will need to export a function
        

so we'll say export a sync and then right here we will say post
        

so we will be performing a post request then here we'll have request and the type for this one will be request
        

so in here uh we'll be having a body and we can get it from our request this way
        

so we can say const body and we can get it from our request by calling await request do J
        

son and we invoke that and then now down here we can get the various um properties that we get from the body
        

so we D structure them we'll be having a name for register we'll be having an email we'll be having a password and all this will come from our body and then down here we can create a hashed password
        

so I can say con has password will be equal to we await uh bcrypt doh and right here we will pass a password and and here we will pass a default value of 10 now that we have this hatched password we can go ahead and create a user
        

so here I'll say const user will be equal to a wait then we can now use Prisma and we'll have dot user and then we'll have dot create and we invoke this we will pass an object we can Define our data as name email and hashed password now instead of password now that we have a user uh what we should do down here is to return this user using next response which we imported at the top
        

so I'll say next response. J
        

son here and we will pass our user
        

so now we have an API route for creating a user and now what we will do is to call this API pass the various data and be able to create the user and we'll do this in our register form
        

so I'll minimize everything we'll go to up go to register register form here we had created the form and we were able to get the data right here at our own submit
        

so to perform the request I'll be making use of axio you can make use of fetch if you want but I like axio
        

so I'll go ahead and install it npmi axus I'll hit enter
        

so once it's done let's hide the terminal and let's come here
        

so Aus let's click on it to Auto Import it make sure it's imported right here then here we will make a post request
        

so we'll say post we invoke this one we pass our API endpoint which will now be stroke API then stroke register
        

so this will hit our API here then stroke register and it will get our route and since here it's a post request then it will Road this function which we created here okay then here let's pass the data now this data will be now our body
        

so it will be accessed right here and we can distruct your name email and password from data since this is an async action we can tap the dot then method
        

so we can do10 this will be called when that request is successful we pass an arrow function and here we will toast a message
        

so we'll say toast. success account created we will log in the user after we successfully create uh the account
        

so we will call signin method and this method uh will come from next o
        

so it's not being suggested
        

so let's go ahead and import it manually we will import with d structure sign in and this will come from next hyphen of then here stroke react like that
        

so here we invoke this we will sign in using credentials that is the first parameter the second parameter we call an object and we pass the credentials
        

so we'll have email here and the email is data. email we will have the password the password will be data. password we will set redirect as false now once this sign in with credential is called at our next o it will make use of this logic to sign in the user back to our register form
        

so this is al
        

so an async action and we can tap a do then method right here we pass an arrow function this one will have access to a call back and right here you'll check if our call back. okay is true
        

so if this exists it means that we successfully logged in the user and now we can redirect the user using router. push and we can take them to our shopping cart and then right here we can call router. refresh and right here we can toast a message
        

so toast then do success and we'll say that this user is now logged in then we can check for the error
        

so after our if statement here we can perform another check we'll say if our callback do error we toast an error
        

so we'll say toast then here we'll pass callback do error and this error can be any of this invalid email or password invalid Emil or password or or any other error that might occur
        

so you can see here this router is complaining since we don't have it we haven't defined it yet
        

so right here we can say const router is equal to use router not user use router this will come from next navigation
        

so let's click on this one to Auto Import it and we invoke it and that error should disappear uh we have another error here okay we should include this outside the router
        

sorry
        

so let's take this out here and save aome
        

so this is it now one last thing that we should do is to handle the error for this post request here
        

so after this do then method here at the bottom here we should have a DOT catch okay
        

so here we should say do catch we invoke it we pass an arrow function right here and we can toast
        

something
        

so we'll say toast. error we invoke it and we'll say
        

something went wrong
        

so make sure it's before this C bracket we'll al
        

so have do finary and here we will reset our loading state
        

so we will say set is loading we invoke this one and we say false and this should be inside an arrow function
        

so I forgot to do this and pass this one in here let me save to Auto format
        

so that you can see everything
        

so this is our finary this is our catch awe
        

some
        

so I think this is what we need to register a user and log them in once they are registered
        

so let's try to create an account and uh see if it works
        

so I'll go back to the browser to the shop here refresh I expand here then here I can say stroke register
        

so here let's have Charles let's have email as Charles at gmail.com let's have password is Charles at I go ahead and sign up loading account created awe
        

some logged in okay there we go it took
        

some time but it's working
        

so whenever we deploy the application it will be much faster because um uh in this case on development it tries to rebuild the page each time
        

so let's go to our database we refresh here at the user look now we have one user we have Charles and then we have Charles at gmail hash password is here cre that R is user which is really cool now for account it's I think it's still empty this will apply when we make use of a third party login EG Google
        

so we'll have that later on awe
        

some let's work on this user menu I'll go to up and we go to components Navar and we'll add a new file we'll call this one user menu TSX stess functional component we'll say user menu let's have react fragments let's come back to the na bar and we will replace these user menu with our user menu component
        

so here user menu uh I save now right here we will have a div and we'll be having another div
        

so let's add a class name and we will set this as relative we will set a z index of that for this one we will be having an onclick event
        

so onclick and that means that if we have an onclick event we should Mark this component as a client component
        

so use client there and right here we will toggle open
        

so toggo open uh we don't have this function but we can create it
        

so right here let come and say const to open will be equal to we will make use of the use call back hook and we invoke this you pass an arrow function like that and here it should be having a dependency are for us to work on this to go open we'll be having
        

some form of state
        

so right here let's create the state we'll be having is open and al
        

so set is open and right here we'll set this to be equal to use State we invoke this and by default we'll have it as false let's make sure that we are importing this use state from react awe
        

some now inside here we can write
        

some logic and all we will do we will be coding set is open we invoke it we will have access to our previous state and right here we'll be able to use exclamation previous
        

so basically it will toggle the it from false to True from True to false and vice versa awe
        

some
        

so now we have this to open we pass it right here at our on click
        

so here for this div we'll be having
        

some class names as well and al
        

so in here we will be having two things we will be having an avatar
        

so here we will be having an avatar we had created this component before
        

so we bring in avatar the other thing that we will have is an icon a I feel Carr down like that you see what we have here the icon for Avatar and this Carr down awe
        

some
        

so we can add
        

some crosses to St this section
        

so here we will have a class name padding will be two border of 1 PX border is straight 400 we will Flex We Will Flex in a row we'll have items at the center Gap will be one rounded will be full or you can use MD you'll have a Cura is pointer we'll have Hoover we'll set the shadow as MD we'll include
        

some transition and finally we'll have text and is straight um 700
        

so I save and this should be arranged nicely there we go uh we don't see the border
        

so what did we do wrong okay it's there now it took
        

some time to Road
        

sorry
        

so we have this and we are able to click it and whenever we click it whatever it's doing it's uh changing the state for this is open
        

so now we can use this state to show um
        

something right here
        

so after our div here right here we will conditionally render our menu we will include the C brackets and we'll say is open and and we include this brackets hit enter and here you can include a div class name it will be ab
        

solute now we will have rounded as MD we will have Shadow as MD fixed width of 170 PX we'll set BG of white overflow will be hidden uh let's have right of zero let's have top of 12 uh R of text is small let let's have F let's have FX Corum let's have CA as pointer
        

so whatever we are creating here is this menu right here this one okay
        

so when we click this we open this particular menu we'll al
        

so have a backdrop this area where which you click it al
        

so closes the menu
        

so let's proceed down here I will include a div here and the links that we include here will be for our log when we are logged in we will see the these links we'll pass a link component from next link it expects us to have a h drive we'll start with the orders here
        

so we can create a reable component that we can use right here
        

so what we can do we'll come to the Navar we will create a new file called menu item. TSX stess functional component and we can call it menu item uh it will be able to receive
        

some props
        

so here we can define an interface uh it will receive children and for children this will be react dot react node it will receive on click and for this one it will be void
        

so it won't return anything and we'll receive them right here but first of all we shall make it to be aware of of the props
        

so react. FC here angle brackets and we pass our menu item props we destructure children and unclick and in here we will return a div this div will have children here then here we will have our on click and we pass on click this is menu item I messed up there
        

sorry
        

so let me save to Auto format here and we will al
        

so have
        

some class name a few of them
        

so padding along the x axis will be four and padding along the y axis will be three and on Hoover we'll change the BG to neutral 100 we'll have
        

some transition I save
        

so this is it now for our menu item we'll make use of that component right here at our link
        

so here let's have menu item from menu item for the children here we will pass your orders is the text then here it expects to have an on click and we'll pass our toggo open the method that we created at the top
        

so like that make sure this menu open is being imported like this awe
        

some
        

so right now I think we should be having
        

something
        

so if I come here click this you see we have your orders awe
        

some when I click it closes when I click it opens
        

so alt shift bottom Arrow these will take us to the admin uh if we are logged in as admin
        

so we'll say uh stroke admin al
        

so here we should have S stroke orders like that then here we will have admin dashboard I save and if I happen to click here we see admin dashboard uh after this we will just pass menu item without a link because we won't be going anywhere we will be logging out a user
        

so here we'll have menu item we'll simply say log out for the onclick we will make use of an arrow function we pass like this and we'll pass two functions in here we'll have to open and al
        

so we will sign out
        

so sign out we have a method from our next out
        

so when we call this method we will sign out the user we invoke it like that and make make sure you bring it in like this awe
        

some now this links will show when we are logged in but we have other links that will show when we are not logged in
        

so after this div we can group them in another div
        

so let's group them div
        

so this will be simple we can copy one of this and we'll have only login and register
        

so I'll paste to it save let's fix each of them here we will be having login and here we will simply go to login for this one we'll be having register and here we can simply say register
        

so this will show when we are not logged in
        

so we'll dynamically display them later on we need to create what we call a backdrop
        

so you see when we click out here we are closing this but here when we open when we click here it does nothing
        

so let's create that backdrop back right here at our nav We'll add a new file uh I'll call this one back drop. TSX stess functional component back drop
        

so here we return a and it will have nothing but just the Styles but al
        

so we'll be having
        

some props
        

so at the top here let's have an interface backdrop props will only receive the on click and for this on click we return void let's include it here then we will be able to receive the on click as a plop we will have that on click
        

so when we click on this but drop we will call on click we will have
        

some class name we will have a z index of 20 we will have a BG uh straight 200 we'll have opacity uh is 50 we'll have a width of screen we'll have a height of screen uh we'll have fixed here we'll have top s z Z and then we'll have left s0 that is it I save then I'll come back to our user menu and uh before we even close this I'll perform a check of is open
        

so we'll say is open I can use tary and I'll display the back drop if our menu is open we pass our on click plop and we'll pass our toggle open else at the end of this here before the C blacket we include full colum will show n okay I save and we open and look now we have this back drop like there and when I click here it closes awe
        

some I want us to be able to sign in the user and al
        

so to be able to get the user from the DB
        

so first of all I want you to log out by clicking on log out okay uh for
        

some rea
        

son it's giving me this uh redirect log out
        

so let's go to our next o right here we had included this next o secret this should be a JWT secret key
        

so let's come here at the EnV file and we add it here you can just name it anything in this case I'll say E
        

soP JWT you can make the key as uh complex as possible but in this case for Education purpose it can be a Simple Start back to our next o um whatever we included in this next o function it's called o options this particular object and we will be needing this particular object to get our user from the DB
        

so you can highlight this object that is in here then you cut it then right here we will export it export and we'll say con right here we'll say all options like that and these will be of type all options of um options and these will come from next all is the type there we set this to be equal to we paste that object okay
        

so look we export con all options we set it to that object then down here this next o still expects us to have this object
        

so we can just say all options right here and it will still work as it is required right here I'll go to the login
        

so up login then go to the login form and we can login a user we write
        

some Logic for logging in a user right here we will be having a method from next o called sign in we invoke it and we say here we are signing in using credentials and then at the end here we pass an OP object dot dot dot data and then we include a comma and here we'll say redirect and we'll set this as false and then after this sign in we will have a do then method
        

so uh dot then we invoke it we'll have an arrow function we'll have the call back here we can reset is roading
        

so set is roading to false then here we'll perform
        

some checks these checks will be similar to those we included to our register
        

so we can go and steal from there
        

so here we had this and this I will copy those then I'll come here and I'll paste here
        

so if okay that means that we are logged in therefore we push the user to the cut or the homepage we flesh and we log them in al
        

so if we have an error we tost an error we don't have this router we can Define it right here
        

so con router will be equal to use router and this will come from next navigation remember we have next router and next navigation make sure you are calling the right one
        

so we call that we al
        

so have this toast use control space here and you will Auto Import it from react hot toast
        

so I save and that should allow us to log in awe
        

some let's see if we can log in we we will go to the login page now since we have a menu here to work with here we'll have email we area included Charles at Gmail and I think the password was Charles at here we paste and we log in loading logged in and you are redirected to the card
        

so that means that it's working now how can we get the user once we are logged in right here at the root of the application we create a new folder called actions and here we will be writing logic to get data from the DB and in this case we want to get the currently logged in user
        

so here we'll add a new file and we'll say get current uh user dots okay in this particular file we will not be creating an API but we will be interacting with the database directory by using Prisma export a sync and we will Define a function get session for the parameters it will have nothing
        

so I will remove this this that was Auto completed we will return a wait and here I will call a function from our next o called get server session I invoke it and here I'll pass o options and these are the O options that we exported from our next o file at the pages awe
        

some now this will get us a session whenever we call this get session
        

so right here let's create another function now and it will al
        

so be a sync function get current user let's include a try and catch block here we'll be able to get our session
        

so const session and this will be coming from get session this function that we created there
        

so we set this to be equal to a wait get session and we invoke this get session like that now we have this session and this session have details about the currently logged in user H including the email
        

so we can check if that email exists
        

so we say if uh we don't have session then here uh do user then do email uh that means that we currently don't have a user logged in therefore we'll simply return null okay
        

so if we have this email then we can try to get more details about the user from the database
        

so what we'll do here we'll say const current user will be equal to and now we will await our Prisma call
        

so here we will use Prisma import Prisma here and this will come from at Libs uh okay at stroke Libs like that we'll have stroke Prisma DB now this this Prisma is the one that we are using here
        

so we can await Prisma do user and then dot uh find unique I invoke it I pass an object where full colon then here we say email will be session we will access this simply
        

so I can copy that and we paste it there now we check if this current user is there
        

so we perform a check we say if we don't have current user we return our other bottom here I'll al
        

so return I will spread our current User it's all the dates I'll change them to Strings and this is how I'll do it
        

so here for example created art we'll change this to be the current user do created art and then we convert this to I
        

so string
        

so we invoke that like that I'll do the the same for updated Art current user do updated art and let's check this current user I realize this updated art is uh giving a t as a full yeah
        

so this is small those suggestions that we get are actually from our user here
        

so current user. updated art and then here dot to I
        

so string and we invoke that and finally email uh verified fullon we have current user and then dot email verified uh and then right here we'll say dot like that and I'll go ahead and invoke it and this email verified can al
        

so be null
        

so all null now you can see this is shouting here and this is because we updated our Prisma you need to call npx Prisma DB push
        

so uh it's still not working close the application entirely and then open it again after closing the entire application and opening again you can see that error disappeared it's a bad developer experience but uh it had to do that
        

so what I'll do here is to restart my application using npm run Dev okay now we have this function this function will enable us to get the user from anywhere in our application let's test this and see if it works
        

so what I'll do I'll come right here I'll go to the app layout right here before our return statement we can say const current user uh will be equal to we await get current user this now it come from our actions get current user and we invoke that now right here we can log this to the con
        

sole con
        

sole. Rog of current user we can say user then let's include this just to easily locate it and here I pass my current user like that now I save now remember that this rout is a server side component
        

so when checking this con
        

sole you will not see it on the browser but you'll see it on your server and our server in this case is at our terminal
        

so I'll pop the terminal let's go ahead and refresh here
        

so I can see our user is null
        

so let's try to log in and see if it will work out
        

so I'll say Charles at [Music] gmail.com then here we include the password log logged in but we still have users null
        

so
        

something is wrong cannot read property of undefined reading to I
        

so string
        

so it was
        

so hard to find out where the eror was first of all I included this con
        

sole log and then I check the DB and since we had updated this from capital T to small T our DB had the previous capital T here
        

so I think that is the main issue here al
        

so I changed this from to string to to I
        

so string what we should do uh we have this next this is usually the cacher
        

so what I want us to do is to remove it
        

sotr D you can remove that uh and then I want us to run the command uh npx Prisma DB push again and uh I'll hit enter
        

so the database is already in sync I will start the application npm run Dev and let's the DB actually and we'll create a new user just to make sure that everything is okay
        

so I delete this current document here
        

so document deleted and from the app here I'll al
        

so click log out and uh let's go to register let's register the user again
        

so I'll go with Charles then password I want
        

something that I can remember for the tutorial sign up let's see account created and logged in and now look we are able to get our user
        

so now I would like us to dynamically display these links depending on whether a user is logged in or not
        

so since our Navar is a server component I can use this particular function directory there
        

so from the layout I'll just remove this save that file and exit then I'll come to the nav and before my return I can paste it here and we make sure to import this get current user from our actions and there we go
        

so I can remove the con
        

sole log and we should pass this user to our user menu
        

so here we can have current user prop to be equal to current user then we should make this user menu to accept that PL
        

so by the way if I hit control and click on this it gets me to the user menu component okay
        

so here we'll be accepting the current user but we should Define an interface for this one
        

so here we'll have interface user menu props here we will have our current user here we could have used the types from Prisma which is user but this will not work at our get current user we changed
        

some of these types here to string and in Prisma they were dates
        

so we can create a separate type that we can replace right here to do that we can come to the root of the application we create a new folder can call it types we can create a new file I'll call it index.ts
        

so here we will export type we can call it safe user to be equal to we will call Omit angle blacket we will pass our user from Prisma I use a comma and here we will omit these fields created art we use a pipe here updated at we use a pipe here email verified and then out here and we add these types now we will have created art and we'll set this to a string here we will have updated art we set this to a string email verified we set this to a string as well and I go ahead and save now in our user menu instead of using user here we can use Save user from our types and here we'll have react. FC hle blackets and we pass our user m new props
        

so now we have our current user here and we can make use of this current user to dynamically display these links after we call is open and then after this first div right here is where I'll dynamically display them and we'll have our current user
        

so if this exist we want to show those links that should be there when we are logged in and we had already divided them in into two Dives
        

so this first div is for logged in and I can cut that and include it here else
        

so we use a full column here we include these links that are for a logged out user
        

so I cut those and I paste them there now I save and uh if I preview this should change since you are logged in we have now your orders admin dashboard and log out awe
        

some and another thing that I will add uh before our log out here I'll add a HR
        

so here we'll have a HR which will be self Crossing tag and that will create a line um right here there we go
        

so now we know this is log out then this app here you can have even more links like profile and
        

so on but in this case we have this this is awe
        

some
        

so na is complaining why uh
        

so for email verified we should have said string or null that's why I think it's complaining uh al
        

so in the user menu I should have said save user all null okay why is it still complaining now there is one mess that I did and if I check this you can see here we have updated art as string and here we have up date art as date
        

so in my Prisma I had Mis mistyped this to update art instead of updated art
        

so uh basically we can change this value for Prisma and uh again it will give us a rout of issue we'll have to create a new user and
        

so on
        

so that to correctly update the types
        

so at the moment I think I'll just ignore it and change the value here to update art instead of updated art and then
        

so here we change to update art and al
        

so here we omit update art that was like a typo awe
        

some
        

so now it's working there and the next thing that we can do is to protect our routes
        

so for example we should not be able to access the login page or the register page when we are already logged in
        

so let's do that I can just cross every everything and then here let's start with maybe um the login page
        

so we'll go to up and then login then we have the page here we just call const current user uh to be equal to we await our get current user and we invoke that if we do this it expects us to have an async function here
        

so we change this to a sync we will pass this user to our login form
        

so here we'll have current user and we set this to be equal to current user
        

so I save this file it comence since it doesn't expect that plop
        

so we can go ahead and make it aware of the plop
        

so here we will define an interface login form plops and we will accept the current user full colum this will be a safe user all it can be null we pass it here react. FC angle blackets and we pass our login form props we destructure our current user just like that and now before we return anything right here which check if we have the current user
        

so if we have our current user let's go ahead and return immediately here and we will return a paragraph here we will say logged in and we can include a message of redirecting then here we can include a class name and we will say text to be at the center I'll save and you see when we are logged in it will call this logged in redirecting now we must make this redirecting to work and for that we can make use of a use effect
        

so at the top here U maybe after our hooks we will call our use effect
        

so we invoke it we pass an AR function right quick and at the end here we should pass the dependency array and now this when the page first RADS we will check if we have our current user if we do have the current user we will go ahead and perform a router dot push and we'll push the user to either the homepage or the cut I like to push them the cut and then they can start shopping from there and then right here router do refresh and we save
        

so it will say redirecting and then it will take us to a different page which is the cut you see we are at the cut
        

so if we try to access login here I'll say login it will say logged in redirecting
        

so we can't see those login form which I think it's better and we can do the same for our register
        

so at register here
        

so this is the register form but we should al
        

so have this register page
        

so from the register page we get the user like this
        

so I'll copy this one and at the register I'll get the user let's make sure that this is coming from actions let's make sure that this is an async function let's pass the current user as a prop
        

so current user and we set this as a prop here current user
        

so the type here will be similar
        

so I copy that come to register form at the very top after our Imports I Define the interface now this will be register form props
        

so we say register and then this will be safe user and it comes from our types then here we include react. FC we'll have now the register form props and we can successfully receive our current user when we get the current user we can check for if the user exists
        

so at the form here first of all I'll save this one and I'll go ahead and cross it then at the bottom here before our return statement in our register form we check if we have the user then we'll say logged in redirecting and we'll al
        

so include the use effect to redirect the user if they are logged in
        

so I'll copy that and I'll come at the top after our router we paste that use effect we make sure to import this use effect from react
        

so I'll save and yeah that should work I guess
        

so let's go to register here it's roading
        

so logged in redirecting
        

so we can see those forms that are in our register form now the next thing that want us to do is
        

something really cool and that is Google or
        

so right now let's log out for us to implement uh sign up with Google or continue with Google we need to set up
        

some environment variables
        

so in our Pages next of right here we were passing the Google client ID and right here we are passing the Google client secret
        

so we need this two and I can copy uh the two of them and we will include them at our environment variable
        

so go to your Dov file and right here we will have the Google client ID and the Google client secret
        

so to get this we need to go to Google con
        

sole
        

so Google Cloud con
        

sole search for that then uh click on that and then from here you can see I'm already working on this issue shop here but I want to create a new project to demonstrate this
        

so I'll create new and we can say eShop to I'll go ahead and create
        

so this is creating wait a moment now we can select this particular project and you can see now we are viewing the i
        

sop to here
        

so we can click on this side nve here and you click on more products when you scroll down you'll see we have API and services
        

so click on all content screen right here we'll go ahead and create an all uh consent screen
        

so I'll click on external then I'll create here we should set up a name I can just say eShop uh to we'll do then here uh support email uh these others are optional uh at the bottom developer contact information I'll set up the email then I'll go ahead and save and continue There here save and continue and save and continue now we have this information there for our app now all you need to do is to click on credentials and we will create credentials and from here we will go to or of client ID application will be web application you can set up a name and we will create an authorized redirect URL
        

so from here right now we are working at Local Host
        

so we'll take this but if you host or deploy your application you'll have to change this later on but for now we'll have Local Host here and we will add stroke API here then stroke of then stroke call back then stroke Google
        

so this will be our authorized our redirect URL and we'll go ahead and create
        

so once it's created you'll see it's providing you with the client ID and the client secret and you can always access this from the credentials in API stroke Services you can as well always search at the top here
        

so here I'll copy the client ID then go to vs code here and you can see here we have now Google client ID and I'll hit space and paste that there then here we have client secret I'll copy that and I'll come back here and space uh paste that there
        

so I'll go ahead and save ourv file we need to go to our app then go to login uh you can go to the login form where we have the button for continue with Google
        

so I'll scroll down here and right here we will simply call sign in from next op
        

so I invoke that and then here we will just specify that we are signing in with gole
        

so I'll do the same for register I'll go ahead and save that I'll go to register and and here we head this button and I'll just paste that and here we can just say I think continue with Google and now at sign up we click on continue with Google and it's ring and look
        

some emails are listed like that now I can click on one of these
        

so I'll click on this one and this will now create a new account using this uh Google details
        

so it's rading and logged in and it's now redirecting and there we go awe
        

some
        

so since we are logged in I think we can check our mongod DB and see what we have
        

so here I'll click on view database deployment we can go to blow Collections and now at our account you can see we have One account here and now the type is oop provider is Google and we have all these other details like access token expires art and
        

so on and at our user now we have two accounts we have this one which is now from our Google and we now even have this image which we can use to show at our menu here
        

so let's do that
        

so we can just go to the Navar go to components n bar then user menu and from here I think we had added an avatar at this Avatar since we have our current user and our current user now can either have the image or not we can just call slrc and right here we'll call our current user and we'll say do image and I'll go ahead and save now that Avatar will show here for that Google icon
        

so it's loading and there we go we have that Avatar right there showing that we are logged in
        

so I can log out and I can continue with Google at any time
        

so that is it for Google or and uh from here now we can work on this checkout and process payment using stripe
        

so once we are logged in right here as a user we'll be able to see this checkout button and what will happen is that when we click on check out it will be able to create what we call a payment intent in our stripe dashboard if I go ahead and click on checkout this will rad the stripe forms but al
        

so it will do
        

something whenever we visit this page it will create a payment intent to begin with
        

so if I refresh right here it will create what we call a payment intent and you'll see here we have 18 and another thing that it will do is that it will create an order in our own database
        

so if I come to my orders here this is on another page but uh still in our application I will refresh at my orders here uh we will be working on this don't worry but now right here you can see a few seconds ago we created this order of 180 right here and I can view more details about it where we can be able to see all the products that we ordered uh the deriv status and
        

so on
        

so this is really amazing then another thing that will happen is that whenever we complete uh feeding this page and processing the payment then our order in the database will be marked as uh paid right here and then our payment status here now will be completed at stripe or succeeded
        

so let's see how this will work out
        

so here let's use
        

some dami data and I'll use a f card which is provided by stripe for testing
        

so 42 42 42 42 a future date and CVC like that and I pay now it's processing and you can see check out success now when I check my payment intent here and uh I refresh here you'll see that now this payment is succeeded and then when I come to the orders here and we refresh this page you'll see payment status is completed
        

so this is really amazing and we will be doing this using stripe
        

so are you ready uh let's get started to begin with uh I'll start by creating an API that will help us to create what we call a payment intent and al
        

so update that payment intent when we want to
        

so that is the first thing that we will do uh before we continue creating the payment page
        

so to create this API uh we just need to uh minimize everything here then go to up API and here is where we were creating our different apis
        

so here you just need to create a new folder inside API
        

so make sure API here is underlined okay not register
        

so when API is underlined create a new folder and we will call this one create hyphen payment hyphen in intent hit enter Then inside this folder we create a new file called route. TS and we hit enter
        

so in order to create a payment intent we will need to have installed stripe in our application
        

so right here go ahead and say npmi stripe then hit enter and this will install stripe in our application I can start by importing uh that stripe
        

so I'll say import then stripe and these will come from stripe we will al
        

so bring in Prisma
        

so we will import Prisma and these will come from we say at stroke Libs stroke Prisma DB import uh next response from next server and down here we can start by loading stripe
        

so we can say con stripe will be equal to new stripe we invoke this uh the first thing that we will do here is to rad our secret key from the environment variable
        

so here you say process Dov stripe underscore secret underscore key and we'll say here as string
        

so this will be the first parameter and the second parameter we will pass an object and in this object we'll just call Api version we'll set this two this one and I go ahead and save now down here I'll go ahead and calculate a total order amount
        

so we had done this area when calculating the subtotal here but we need to do it again on the server because on the server it's more secure and we don't want anyone to manipulate the amount uh before they purchase anything on the client
        

so we have to do this again on the server
        

so here we'll have an AR function and right here we will receive our items okay
        

so these will be all the cut items and then right here we can Define the type the type will be uh cut product type this one right here and it will be an array we can use these items to get our uh total price
        

so can say const total price will be equal to uh here we will get our items and we use the reduce array method like we had done before and this will receive an arrow function here just like that it al
        

so expect a default value now since we are only calculating the total amount we will use zero here
        

so here we'll be having accumulator and item we will calculate the item total
        

so we'll say const item uh total will be equal to item. price here and we multiply this by item dot quantity we return the total now which will be our accumulator and we add our item total uh we should finally return this total from this function
        

so after this we go ahead and return our total price and I save
        

so now let's export here an async function which will handle our post request
        

so we invoke this we will receive a request of type request and in here we can write our Logic for this API now
        

so first things first we need to check if we have a user
        

so we load a current user
        

so we'll say on current user uh will be equal to we await get uh current user this will come from our actions and we invoke that down here we perform a check we say if we don't have this current user we can return an error
        

so we immediately return um response. J
        

son right here we can invoke and we can actually pass two objects one for the error and we can say an authorized and then the second parameter al
        

so an object and these can have the status code of 41 meaning that unauthorized now that is just to check if we have a user or not if we have a user then we will proceed down here
        

so here first of all let's say con body will be equal to we await and we'll say uh request do J
        

son we invoke that then down here we destructure whatever is is in our body items we will al
        

so be passing a payment intent id and this will be coming from our body to clarify things this payment intent id we will either be having it or not uh once we create the payment ID we will be storing it in the local storage and then when we perform an update of our shopping cart we can make use of that payment ID to update our payment intent in stripe therefore we won't have to create uh many payment uh intents in stripe
        

so with time you'll understand how this works
        

so let's continue down here we can get our total amount
        

so we'll say cost total will be equal to calculate order amount and we pass our items after getting them from the body and here we will multiply this by 100 and the rea
        

son is because uh stripe takes the payment in cents let's create an object that we will represent our order
        

so here we will say order data we will have a user we will set to an object we'll say connect full colum and here we'll pass the ID of the user and we'll get the ID from our current user. ID uh we will have the amount we'll set this to our total we want the currency to be in USD then right here we'll have the status to begin with these will be pen pending we will have delivery status uh to begin with these will be pending we will have payment intent id and we'll set this to our payment intent id that we get from the body we will have products we'll set these as items this represents the data that we will be saving in our database for our order
        

so in stripe we'll be creating the payment intent and then in our database we'll be creating the actual order and we should have the payment intent id
        

so that we can be able to update this order whenever we make a change on our payment intent
        

so down here we'll check whether we have the payment intent id or not we'll say if payment inent ID exists
        

so this is the ID that we get from the body
        

so if this exist what we will be doing here is to update the order then here we have else this means that we don't have the payment intent if the payment intent does not exist
        

so what we will do here we will create the payment intent then we'll al
        

so create the order make sense
        

so let's start with this one here since by default we don't have the payment intent
        

so here we will start by creating the payment intent and you'll just say con payment intent will be equal to we await and we use our stripe here do payment intent. create we invoke this one and then we pass an object we will have the amount and we'll set this to the total amount we will have the currency we'll set this to USD we will have automatic uh payment methods we will say enabled we'll set it to true
        

so this is how we can simply create the payment intent awe
        

some and then down here now we will create our order in order to create this order we will need to have order schema in Prisma
        

so I think we can go ahead and create that order schema
        

so let's save this file and leave it for a while as we go to our rout here go to Prisma then click on Prisma here we need to create the order schema right here after our user uh we will say model order and and in here we'll start by having an ID the ID will be having this
        

so I'll copy this one up to this point and I'll paste it here then we'll be having a user ID and for the user ID this will be a string and we'll say at DB do object ID we'll be having the amount I'll set it as float currency this one will be a string will be having status this one will be string uh we will be having deriv status it will be an optional string
        

so string and include a question mark there created date this will be date time and at the end here we'll set a default of now we'll be having the payment intent id and we'll set this one to a string which should be unique we'll be having our products now this will be an array of our cut products we don't have it yet
        

so we should be creating it okay
        

so here we'll have address and we'll set this to an optional address we don't have it we should create it then here we should be having user it will be similar to this one I can copy this one then down here can paste it
        

so we create this type and we had created this type on our front end let's go to product product details uh it will be similar to this one
        

so let's copy this cut product type and we add it here
        

so the thing is we don't need to say export we need to change the formatting we just need to say type here and then we should not have the full columns and this should be starting with a capital and then right here we should not be having the uh semi colon and al
        

so remove this equal sign
        

so we need to do all this formatting what I can do I can select these full colum use contrl d 1 2 3 4 5 6 up to this point then remove it all together then select this semicolon 1 2 3 4 5 6 7 up to this point remove that now to format this I can select all strings then here I remove the small s include the capital S for the selected image we need to change this to image we will create a type for the image then the quantity we can use int here instead of number then the price here will be float now we have another problem here for the image let's create that type we'll say type image will be color a string then we'll have color code will be a string now we'll have the actual image which will be a string
        

so now this error disappears and this error disappears we set an address right here we'll have type we will have address and right here we'll have a city which will be a string we'll have country will al
        

so be a string we'll have ADD address line one this will be a string we'll have address line two this will be a string which can be optional actually optional string for line two we'll have a postal underscore code we'll have a string and then we'll have the state and this one will be a string
        

so we have created this type this type this type and use them on our model here
        

so this is complaining because once we use the user here here our user should al
        

so have the order like we did here we included the user here and we included the accounts in the user
        

so the same once we include the user in the order we include order in our user
        

so here you'll just say orders uh space uh maybe tab up to this point for formatting then order and we use an array like that now when we come down here this is no longer having an error awe
        

some I save
        

so now I think everything is fine let's go to our route
        

so right here since we now have our order in our Prisma uh we can use that order model to create our our order in the DB but this is not in sync yet with our DB database
        

so we need to make it in sync
        

so we have to run npx then then Prisma DB push we hit enter
        

so now right here before we create our order we'll update the payment intent that is at our order to be equal to payment intent do ID and then right here now we use Prisma to create the order
        

so we await and we'll say do order and then here do create
        

so once you do this you'll see that uh this in your case might be underr and that is because Prisma is not yet detecting our order although we had put that in sync with our mongod DB
        

so what you need to do is to cross and open your vs code again and then uh hopefully it will work out
        

so try that uh it worked for me
        

so here I'll go ahead and add data and we'll set this to be our order data and then right here we will return payment intent we make use of next response. J
        

son and we return our payment intent like that okay now this is for the case when we don't have a payment intent id meaning that we don't have a payment intent and therefore we go ahead and create one
        

so what of here where we already have a pay payment intent id that means that we have a payment intent and in that case first of all we can update the payment intent using our new total amount
        

so here we'll say const uh we say current intent will be equal to we await and we will await stripe do payment intent. retrieve and we invoke this and we retrieve the payment intent using the payment intent id that we get from the body if this current intent exist we'll go ahead and update it
        

so we'll say const updated uncore intent will be equal to we await and we will await stripe. payment intent. update and here we will pass our payment intent id as the first parameter second parameter will be an object and we will update only the amount to be total okay now down here we should update our order and we will do two things we will get our existing order and al
        

so we will update the order if it's there
        

so we'll say const here we will destructure the existing underscore order we will destructure updated order and we'll destructure this from I'll make use of a wait we will use promise. all and here we'll perform two requests
        

so we invoke that and we pass an array
        

so we are simply destructuring this and this from this array and this array should be having two requests the first one should get us the order
        

so Prisma do order do find First we invoke this we pass where payment intent id is our payment intent id this is the first request to get the order then here we perform another one do update and we invoke this we pass an object and we'll say where payment intent id is payment intent id this expects a second parameter of data and this this is now the updated data
        

so we'll set amount to total and then we will set products uh to be items make sense we are simply getting the order here the one that exist and then here we are updating here now we have the existing order and the updated order first of all we check if this existing order exists
        

so if we don't have the existing order we an error
        

so here we will return next response. J
        

son we invoke it we will pass the error invalid payment intent and then the other parameter here will be an object of status and here the status will be 400
        

so if we don't have this existing order we draw an error if it exist we will go ahead and we will return the payment intent
        

so I'll copy this line here and that is what we will return return here if we have the order that means that uh we even updated the order
        

so we pass the payment intent here as the updated intent okay
        

so here we have an error it can't access our updated intent and that is because we remitted this to this if statement while we could have included all this logic inside here
        

so after our payment intent right here we should have included all this logic right here in there
        

so I use the alt top Arrow to move it up there I save to Auto format and now down here you should be having two car brackets before else and then you should be having this return because this logic is inside our if statement there make sense
        

so that is how we can uh create and update the payment intent after creating our route uh we can cross all this and we need to go to our hooks folder here use cut and we'll do
        

some stuff here we need to handle the state for our payment intent I'll say const payment intent set payment intent this will be equal to use State we invoke this we pass the types can either be string or it can be null and to begin with we will not be having a payment intent therefore it's null uh I can remove this con
        

sole log and right here at our use effect we will be saving this payment intent to the local storage and once we complete payment we clear it if we don't complete payment and come back again we update it by getting it from the local storage saving it again when whenever we make a change to our order
        

so here we will get it from the local storage
        

so const we can say eShop payment intent we set this to be equal to local storage dot get item we invoke it and we pass the key the key can be eShop payment intent
        

so I'll copy that and paste it here I will pass this using J
        

son
        

so we can have another con we'll set this to be equal to j
        

son. pass we invoke it and we pass our E
        

soP payment intent once we have the payment intent we update our state
        

so here we'll go ahead and set payment intent to be our payment intent uh this is for the case when we just want to get the payment intent from the local storage but how do we store this in our local storage
        

so down here we'll clect another function that will help us to uh add that payment intent to our local storage before the value this can be equal to use call back we invoke that we pass an arrow function the dependency array I'll set it as the payment intent we will set payment intent we invoke these
        

so the value will be getting it right here
        

so here we can have value the value uh will either be a string or it will be null and al
        

so we simply update the local storage
        

so local storage. set item we invoke this i
        

sop payment intent then the second parameter we have j
        

son. stringify we invoke it and we pass our value
        

so now we have this function which will help us to set the payment intent now we need to export this payment intent and the function that we just created
        

so at the top here we first need to define the type we will be having payment intent it can either be a string or it can be null now we'll al
        

so have handle set payment intent and this will receive a value which can either be a string or it can be null and and it will return void now down here our value expects us to have the payment intent and al
        

so handle set payment intent I save awe
        

some
        

so we need to create a new page for checkout you can close this minimize everything go to app then we create a new folder and here we'll say check out we add a new file page TSX we will be having another one which we will call checkout client. TSX
        

so in page. TSX stess functional component we can say check out we will return
        

some stuff let's copy this one crl a copy come to checkout client paste here then let this be checkout client and this one client I save that okay back to page here uh we'll be having a div and we'll have a class name and we'll set the padding to be eight then in here we'll make use of our container component make sure it's from our components and then in here we will have our form WP from our components again and then right here we can now load our checkout client which we have just created a few seconds ago we pass it like that in our checkout client the first thing that we can do is to get um whatever we have at our use cut like cut products payment intent and handle set payment intent and then once we make use of a hook we should Mark this component as a client component
        

so here let's say use client for now I'll not be doing much right here I'll just say check out we'll create the UI rater on right now what I want us to do is to create a payment intent by making a call to our API endpoint
        

so right here I call use effect I invoke it like that and in the dependency array we will be calling this again whenever our cut product changes and whenever our payment intent changes
        

so here we'll check if we have cut products
        

so do we have cut product if we do we proceed in here and at the top here I can create two states one for error and one for loading State I save to format then right here now if we have cut products we will set loading to true
        

so roading to True we'll set the error to false
        

so I'll say fetch and we invoke this we pass our endpoint which will be API then create payment intent that is the first parameter the second parameter will be having an object we specify the method here and we are performing a post request and then we'll be having headers s here we'll say content type is application J
        

son we can now have our body we will use j
        

son. stringy uh we invoke it and we pass our data in here
        

so whatever our route expects at the body is items and payment intent id
        

so right here we will pass the items as card products that we get from our use card then we will set our pay payment uh underscore intent id as our payment intent
        

so after performing this request we can tap a then method
        

so do then we invoke this we will receive a response inside an arrow function
        

so let's pass an arrow function like this we will be having a response uh we will set roading here to false and then right here we'll perform a check if response. status uh is equal to 41 that means that you are unauthorized to perform the request therefore we can send this user to the login else if this is not having an error we will return here uh response. J
        

son we invoke that now let's define this router we just need to come here and we'll say const router will be equal to use router and we make the one from the next navigation and we invoke that now this doesn't have an issue now here we return response. J
        

son and this will give us back the data uh that we get from this API and what do we get from there the payment intent
        

so right here after this dot then we will tap another dot then and and in this case we will get the actual data from our API
        

so here we will get the data and then once we get the data what we want to do is to get and set our payment intent client secret and we'll be using that uh to process the payment
        

so right here we can add a new state
        

so we'll say const and we will say client uh secret set client secret this one will be equal to use State and we invoke this we pass an empty string
        

so we'll say set client secret we will get this from data dot payment intent do client secret then down here we can now set our payment intent id using handle set payment intent and here we'll get this from data Dot payment intent uh do ID now after this do then we'll have catch we invoke it we pass an aror function and here we will have access to the error object we will set error to true
        

so set error to true you can al
        

so toast the error here right here
        

something went long I will import that from react hot toast
        

so this is our logic here perform a fetch from our API endpoint and once we make a request to this it will be a post request whatever we do if we don't have a payment intent we create it and return it if we have a payment intent we update it and return the payment intent and once we do that uh we will come right here we get the client uh secret which will help us to complete the payment and then here we set the payment intent at our local storage or rather we update it and then right here we withraw any errors that are there we need to see if this works for that we need to al
        

so set up our stripe the first thing is to set up an environment variable
        

so at our route here you'll see that we had added this uh process. EnV stripe secret key this should be an environment variable
        

so you can copy that one and then go to your EnV file right here and we will add this stripe secret key we will be getting this from stripe
        

so you can open your browser and right here I already have my stripe open
        

so what you need to do if you don't have an account just visit stripe.com and then create an account and if your location is not supported you can actually choose any location uh for learning purposes and then once you are logged in you'll go to your dashboard and you'll go to developers right here at Developers pass you'll go to API keys and you'll see your secret key right here
        

so you just need to rev it I think they'll ask you for a password or not
        

so copy that key and you'll paste it right here
        

so I'll go ahead and save that file now at checkout client I am logging payment intent right here to the con
        

sole and al
        

so I can log this client secret to the con
        

sole as well one last thing that you need to do is to make sure that your Prisma is in sync with your database
        

so I know we had already run this command for orders and
        

so on but uh I think you can run it again npx Prisma DB push hit enter uh allow access and you should be able to see this message the database is already in sync with Prisma uh I don't know why this comes here I don't like it let me try to run this command again npx Prisma DB push I don't know if it's that Windows popup that comes
        

sometimes it doesn't
        

so let's see it's still there uh I I'll be checking on this error later on and I hope it's nothing serious okay you will run your application
        

so make sure you have at least one item at the shopping cart and we will check at this price this payment should show at our dashboard uh where we have payments here all payments and and it should come as a payment intent all these incomplete payments are payment intents we were trying to pay for
        

something but we didn't complete the transaction
        

so we should see uh this value 102 uh coming right here once we visit the checkout page
        

so right here we will go to the checkout page uh we are at checkout we will check the con
        

sole at the con
        

sole we should be having a payment intent id and a secret key curent secret
        

so you see we have this Cent secret key we have this payment intent id at the local storage we should be having the payment intent id
        

so go to here then application then here we have uh I think this is pay E
        

soP payment intent yes this one and it ends with bu
        

so if we go to stripe we don't see it immediately but once we refresh we should be able to see it
        

so I refresh and look we have it here bu and we were trying to pay for 10299
        

so this is our payment intent we are trying to pay for
        

something but the transaction is not yet complete now if you go to the database you will be having an order created
        

so refresh your database and go to order now look here we have this order created currency us D status pending delivery status pending this status here is for payment status
        

so it's not yet paid uh and then here we have payment int ID we have products
        

so if we expand this we have one product which is ritech MX Keys which we are trying to pay for and each amount here al
        

so we have all these even the images and
        

so on
        

so we are having the order and the products that we tried to pay for uh and this order can act now as an abandoned cut when the state is pending
        

so this is awe
        

some this is working nice and uh we can test if the order will update once we change our shopping cart and still use the same payment intent
        

so back to our shopping cart let's change the order by adding three of them
        

so we should be having 300 here and we visit the checkout page again currently we are not able to use this we'll work on this button uh later on but for now let's use at the top here visit checkout again and see if our order will update and we actually have an error
        

so
        

something went wrong we have an invalid integer that might be the issue
        

so I think we need to cut this to two decimal points because stripe is not supporting it at our calculate order totals uh instead of returning total price maybe we can have another constant here const price we set this to be equal to our total price do to fixed and here we'll say two
        

so it will be into two uh decimal points and then right here instead of returning total price we will return our price and I think I'll just say any right here
        

so I'll save that file back to our app I will refresh this page and hopefully we won't get any errors uh let [Music] see we still have this era here I'll scroll here uh why is this still this wrong
        

so here I'll use ma. flow since this to fixed is not working this is an issue with the decimal point
        

so if you have a better
        

solution I think you can try it on your side
        

so here I'll pass the total price and I save let's see if it behaves the same okay
        

so I refresh again here uh now I don't see any errors which I think it's a good sign okay
        

so let's check our payment intent if it was updated to three atast 300
        

so here I will refresh and here we have 308 . I'll take that it's good
        

so it updated the payment intent and let's check our mongod DB it should have now the amount here updated I will refresh and now here we have 380 now the problem with the mother. FR is that uh we won't have these points as 99 uh
        

something like that or 58
        

something like that it should always be 0 since I used math. flow
        

so if you have a better
        

solution I recommend that you change this to uh a better one okay because we are using those points now the next big thing that we will do is to complete the transaction
        

so uh let's do that next
        

so now that we are able to uh create a payment intent all us to complete the payment by creating this form and we we'll be making use of a stripe form elements to create it and then we'll be able to process the payment and once we process the payment our payment intent will be marked as succeeded uh for us to do that I have already opened
        

some documentation here if you go to this link right here stripe.com stroke docks uh stroke payments stroke quick start uh you'll find yourself here you can make sure to click on react and Nod or you can click on nextjs here
        

so react and node and al
        

so nextjs they are
        

so similar
        

so there is no much difference
        

so here at server.js uh we already did this I already showed you how we can create a payment intent we started by calculating the total order amount and then we created the payment intent and amazingly we al
        

so added more logic about our order which is cool
        

so that we can save
        

some data to our own database and then here we have have app.js and this is now on the front end this will be basically be our checkout client or checkout page
        

so from here what we do we make use of the use effect here to make a call to the uh create payment intent endpoint and we create the intent once the page loads and then now uh after that what we'll make use of is uh
        

some stripe form elements
        

so the form we will call these components from stripe to create it and you can see here we have a checkout form and you can al
        

so follow these instructions uh to work on it
        

so most of this code will be similar to what we will be doing the first thing that we need to do uh we installed stripe already now we need to install uh stripe react uh stripe JS and at stripe stripe Js and this will give us the different form elements that we need
        

so I'll copy this link I'll open my app here I'll go to the terminal that I'm not using and then I'll will install those two
        

so it completed installing here and again this is what you need to install npm install uh D- save at stripe stroke react hyen stripe hyphen JS and at stripe stroke stri stripe hyph JS
        

so I'll cross that terminal now
        

so now from here we should start by loading stripe
        

so if you check the documentation you can see we are creating this stripe promise and we are calling load stripe and this road stripe will come from one of the libraries that we just installed and then we will pass here a publishable key as you can see here
        

so here uh we'll say const stripe promise then load stripe let's include this part of the code just before our component here just like that we will invoke this and we should import this from at stripe stroke stripe JS just like that then here it expect us to pass what we call a publishable key we will store this in an environment variable
        

so here we will say process. EnV and then dot next underscore PB underscore stripe underscore pable underscore key and here we will say as string
        

so we should create this environment variable I'll copy this
        

so that I make sure that the sping is the same
        

so here we had already added the stripe secret key now we should add these next uh underscore pcore stripe publishable key and we added this next fabric because we are adding this key on the client not the server
        

so you need to do this okay now back to my browser I'll go to my dashboard and if you go to your developers here then API Keys you'll see we have this publishable key you just need to copy that and you will include that right here okay go ahead and save that file then you can go back to your component
        

so now we have this stripe promise and it will help us to create our stripe elements
        

so down here uh before we return we will create
        

some options here you can say const options these uh will be equal to an object
        

so I can Define the type here uh the type will be stripe element option this one and we can add them right here we will pass our client secret
        

so client secret the first parameter and then we will pass appearance object here and we will set the them to stripe labels to floating uh at the top we should create
        

some state to help us know whether uh the payment has succeeded or not
        

so here we'll see say uh const payment success and we'll have set payment success this will be equal to use State and I invoke this and right here I'll pass false now down here we'll create a helper method and we can say con a handle set payment success we set this to be equal to use call back we invoke this we should pass here an AR function and we should be having a dependency array now right here all we will do is to update our payment uh success state by cing Set uh payment success we invoke this and we pass a value now this value we will be receiving it here as aoran
        

so value will be buan we will make this to be a div
        

so we return a we can add a class name we will set the WID to be full uh we will return an elements uh component from stripe
        

so if I come back right here we have this elements we are passing our options uh and then we are passing stripe uh promise and in there we are passing a form
        

so what I can do I can actually copy this right here
        

so I'll copy that and I'll paste it right here here
        

so we want to show these elements if we have the client secret and al
        

so if we have uh our product
        

so here I'll say do we have cut products and and we load this from stripe
        

so I'll bring it in from uh stripe react stripe JS and for this checkout form we should create it uh let's come here at check out add a new component and we'll say checkout form do TSX stus functional component here we'll say check out form this one for now we can return
        

some react fragments and for this checkout form here uh we will pass
        

some props
        

so I'll Define an interface for it at the top here
        

so I'll say interface uh checkout form props Al
        

so let's mark this as a client component
        

so use client and then right here we will be receiving a client secret this will be a string al
        

so we will be receiving handle set payment success
        

so here we will pass our react. FC anger blackets and we pass our checkout form props here we destructure Cent secret
        

so client secret and al
        

so handle set payment success
        

so for now I'll save that file then I'll come back to our checkout client and we should now import this from checkout form I'll pass the client secret and these will be coming from our client Secret which is in state and then uh right here we should have handle set payment a success and we should pass handle asset payment success
        

so I save that and now this is our check out form here
        

so after this check I'll come down here and we will check the various States and display the various U eyes
        

so for example we'll check if our page is loading and here if uh the payment intent is still loading we will say that checkout is loading uh loading checkout we can add
        

some classes we'll just say text Center you can add more if you want now what of error
        

so here if we have an error we will display a div as well
        

so I can copy this one paste it here and text will be Center but we'll set text here to be row 500 or 400 we'll do and then here we display the message can say
        

something went wrong now what about when we have a successful payment
        

so here we'll have payment success and and uh we will have a div and in here uh I'll pass two more Dives
        

so here I'll have div
        

so we have this parent div then we have this two div the first one will just show a message payment [Music] success that and this one will be having a button button and this button can come from our components we'll say that the label is view your orders we'll have an onclick event
        

so here we can say router do push uh we invoke that and we pass order make sense now here let's style this one we will add a class name and we'll say that the text is till 500 and then we'll say text hyen center now right here we add class name first then we'll say a Max hyphen width um hyphen a custom width of 220px uh and then here you'll say with hyphen full we come here we'll add a class name and we'll say Flex here we'll set items to the center here we will Flex call and we will have a gap of four
        

so when our payment is is successful we'll be able to see this when we have an error when our payment intent is loading we will see loading this one now let's go to our checkout form and we create the various parts of this form
        

so here we can say const we destructure the cut total amount actually at the end here you can start by saying now use cut you invoke that uh we make sure to import it and now right here you'll be able to get all the cool suggestions like the cut total amount here
        

so that is what we will be paying then here we'll have handle uh clear cut
        

so we get the suggestion and handle uh set payment intent
        

so we get those from use cut okay and then here we'll say con stripe will be equal to use stripe uh we invoke that and we make sure to import this
        

so we don't have suggestion for this one uh but we'll get this from react as stripe JS
        

so at the top here let's import it we'll say import we D structure uh use Stripe from uh add stripe react strip JS and we get it here we will al
        

so get our elements we'll say const elements will be equal to use elements again it's not being suggested but these will al
        

so come from react stripe .js
        

so use elements uh here we can al
        

so set a loading State now let's come down here we will load our formatted price uh by calling our function format price
        

so const uh formatted price uh will be equal to we call format price that was suggested at R and we want to format our cut total amount we will call A use effect we invoke it we pass an arrow function
        

so this will be equal to an arrow function we need to have a dependency array for this dependency array we will have stripe
        

so we have this use effect right here
        

so we'll perform
        

some checks in here we'll make sure that we have stripe we have the client secret uh I think basically that then down here we'll create a hand submit function that will help us to submit the form and you'll see down here we are simply creating the form
        

so that's all we will do in this file okay in here we perform a check if we don't have stripe we will return immediately
        

so we will call return that is all we need there we check if we have our client secret
        

so if we don't have our client secret we will al
        

so immediately return here'll say handle set payment success and we'll s these to fals this is all we need to do at this use effect
        

so I'll save now down here as you saw we can create a constant that will help us to process the payment now and we'll say CLE submit and then right here we we will have an A sync call we will receive an event and this will be react then do form event that is the type and in here we can write
        

some Ric we can prevent the form from reloading prevent default we make sure that we have both stripe
        

so here I'll check for stripe or the elements
        

so if any of this is false we will immediately return
        

so if we don't have stripe or we don't have elements we'll just say return okay then right here we'll Now set loading here to true and now we can call stripe do confirm payment and I pass an object we will have elements here and then we will call redirect and we'll set these two if required after this we will tap a do then method we will have access to results or result and we can call an arrow function on this one like this
        

so here we'll say if um we don't have result. error what we will do is to toast a success message
        

so we'll say toast Dot uh success and here we will say check out success
        

so check out success all payment successful
        

something like that we can clear the card
        

so we will call hand clear card now since we have already paid for this product then we can call handle set payment success to true and then we'll be able to show
        

some nice message and a button to take us to our order and we will set our payment intent here to n
        

so when we call this it will reset our state and al
        

so our local storage
        

so we'll no longer have a payment intent and when we try to perform another payment it will create a new payment intent and uh we perform a payment on that one a new payment intent and al
        

so a new order and since here we head set loading to True uh we can come down here uh after this and we can set it to false I save to Auto format and this is our logic
        

so stripe will get the payment data from this elements right here
        

so we will return a form and here we will have on submit on submit it will call this function that we just created
        

so I'll copy that and I'll pass it right here this form can have an ID and we'll say payment form the content of the form to begin with we can have a heading
        

so I'll call a div
        

so here we'll have a class name and we'll add margin to the bottom of six and then right here we will have a heading it expects to have a title and we can say enter your payment details uh to complete checkout
        

so that will be our heading
        

so this is this heading after the heading uh I can have a simple H2 and we'll say that you will enter your payment information
        

so we have the address information and we have the payment information
        

so the payment information is basically maybe the card and
        

so on
        

so payment information and here we can add a class name font can be semi bold and margin to the top can be four margin to the bottom can be two
        

so I Sav that and you should see it on the screen now right here we have another component from stripe and this is now called the payment element
        

so payment element it is not being suggested again I hate when it doesn't and this will come from uh stripe react stripe here
        

so from this we will get a payment element uh we will al
        

so be getting our address element
        

so we can al
        

so import it here like that I save now here we get our payment element you can see we already see the card here which is cool we can add
        

some props like an ID and we can say payment element and then we'll have options I add an object in there and I say layout is tabs now I save above this we can have the address information before our payment
        

so above it let's add a h to the stes will be the same as this
        

so I think I can copy and I paste then I will remove margin to the top top since we already have this one here margin to the bottom and then right here we will have now our address elements
        

so address element and we already imported it we can pass options here we pass an object and in this object we'll have mode we'll say it's shipping and then here allow countries
        

so you can pass the different countries that you want to ship to here I'll pass us and I'll al
        

so add here K I save and now you should see that we will have address information look we have address information payment information uh buing address is same as shipping address if I unmark this it tells you to select the country this is really cool and if you add address R it will al
        

so show address R to address R uh City poster code awe
        

some
        

so here I'll pass a div and we can say total will be H remember we had added formatted price
        

so we display our formatted price here we can make this to be bold and maybe big
        

so I'll add a class name padding along the Y AIS will be four then text will be at the center
        

so text Center text will be straight uh 700 text will be uh large
        

so text for Exel and then font will be bold
        

so we show the total there that you are about to pay uh I think for XL it's too big
        

so we can reduce this to XL I think yeah that is good enough now we add a button that will help us to submit the form
        

so button and it can be self Crossing this pattern can come from our components and here we should pass a rable for this label we will dynamically display the text depending on the state of is loading
        

so here is loading if it's true then we'll show processing and then here we'll say pay now it expects us to have uh disabled uh this will al
        

so depend on whether the form is submitting or not we check the state of is loading uh
        

so here you'll say all no stripe or no elements we should add an onclick event
        

so onclick I'll just pass an arrow function that has nothing
        

so by default the button will submit the form okay
        

so I save and there we go
        

so we have created our form right here that will submit our payment information
        

so now let's test it it shows now all these Tri paraments we are about to pay this amount at payments let's refresh this and see if we will see uh this price 411 we refresh the payments here this is what we are supposed to look for
        

so we have this other payment intent and uh I created this from our liveb site here
        

so it got mixed up okay
        

so what we should check for is this one right here below 180 if we complete this form it should be marked as paid okay
        

so let's fill in the details
        

so here I'll choose
        

some dummy information uh we have a test card from stripe use 42 42 42 42 42 until the end until you can't add anymore 4444 for expiration then 4444 for CVC this can be any future date this can be any three numbers now right here let pay processing and check out success view your orders payment success
        

so if we come to stripe we should pay attention to these line light here down here I hope you can see
        

so I refresh and let's see if it succeeds
        

so you see now at the top we have this succeeded and this is actually working our payment intent has been marked as paid now the only issue is that now at our orders uh it will not be marked as paid because we didn't Implement Logic for that and for that uh we will be making use of stripe web hooks
        

so that we can update our order once a payment has succeeded
        

so let's update this checkout button
        

so uh I'll open this uh we will go to app then we'll go to cut I guess uh here cut client and here we have our button here we should dynamically display this depending on whether we have a user or not
        

so we should be receiving a user in this particular component reactor. FC and here we will destructure our current user now down here we can make use of this current user
        

so for the text it should be dynamic
        

so I use the carry brackets here and then right here we'll say do we have a current user
        

so if if we do we will show uh check out and if we don't
        

so here we will show uh log to check out that is the label uh we will do a condition for onclick let's define this router
        

so at the top just right here you can say const router will be equal to use router from our next navigation and we invoke that okay here we say out rine awe
        

some
        

so that is our button we are conditionally rendering it now we need to pass the current user to this component
        

so at the page right here we should Mark this as an async function async and then right here here we can now say const current user will be equal to get current user from our actions we invoke that and now we can pass this current user right here as a prop
        

so current user and this will be equal to current user okay here I didn't pass our cut client props and come back here I'm still getting this error okay here I al
        

so missed a wait
        

so now let's test our app we are logged in
        

so we see check out we click on check out loading checkout
        

so it take us to check out and here it will create a payment intent of 40 you see 40 uh that's that's okay now let's go back let's log out once it's log out you'll see here we have login to check out
        

so when we click on this uh instead of taking us to check out it will take us first to login uh there we go it took
        

some time as well again on develop is because it tries to rebuild each page that's why it loads much now the next thing is that uh we will try to update our order once we successfully perform a payment
        

so now uh we are able to perform the payment using stripe but we are not updating our order for a successful payment and I told you we'll make use of stripe web hooks for that if we go back to our browser to the stripe dashboard you can can see here you click on developers you'll see we have API Keys then right there you'll al
        

so have web hooks
        

so for web hooks you can either add a hosted endpoint and this is for a site that is live and usually this is easier to add but you can al
        

so add for local leners when you are developing your application
        

so we will do both we will start with this and then later on when we post our application online or deploy it we will cover hosted endpoints
        

so right now if you come to local listeners and you click on ADD local listener here you'll have instructions on how you should go about it
        

so right here we have a sample endo and this is in no JS although we will be doing this in uh next JS
        

so it will be similar but we'll need to change
        

some stuff
        

so all we need to do is to create an event and we'll create an event using this method here and we pass our request body now the thing is this request body should be row data okay and we pass a signature we pass an endpoint secret and then after we get our event we'll be able to use that event to check each type
        

so if payment is succeeded we can do
        

something uh right here uh if we have a charge succeeded we can do
        

something and
        

so on okay
        

so to begin with we will create this endo and then now later on I'll show you how to run it okay
        

so let's go back to our vs code and we will do that in pages I tried to create the API on our app folder but I just got a lot of issues
        

so let's do it on pages like we did with our next op or add a new file we can call this on stripe hyen web hooks. TS I hit enter npm micro
        

so this will help us to read the rad data that we need to pass when creating the event okay
        

so I install that library and then at the top here we will start by adding a config
        

so you'll say export const config we'll set this to be equal to we'll say API and here we will say body pass is false we create a function
        

so we'll say const uh stripe will be equal to we load our stripe like uh we did before
        

so this will be new stripe uh which we should import from stripe we invoke it we pass process do EnV then dot I pass a stripe underscore secret underscore key and we'll say here as string the API version and we include the current version of uh 2022 we export nowra
        

so here we'll say export default and we'll say async function HRA uh I invoke this and we'll do stuff in here we will receive a request of type next API request and then I receive a response of next API response all this will come from next now in here I'll call const Buffer or buff and this will be equal to a wait buffer we invoke this and we pass our request this buffer will be coming from micro
        

so we are able to read the row data now right here I'll get the signature and this will be available in our headers
        

so request uh do headers and then I include this square brackets and we'll access the stripe signature and the request to this API will be made by stripe automatically whenever a payment has been made or an event has occurred
        

so
        

so we'll be able to call and do all this
        

so we get the signature uh like that now let's make sure that we have this signature
        

so if we don't have the signature we will come right here and we will return response do status 400 we will say do send missing the uh stripe signature right here we say let event be of type stripe event and then down here uh we can now try to create the event
        

so we'll use a try and catch broke
        

so here now we'll have the event and this will be equal to stripe um dot web Hooks and then dot construct event we invoke it we will now pass our buff and then here we pass the signature and we pass our environment variable which is a variable in process.env do um stripe web hook secret and here you can use an exclamation mark
        

so I save now this is how we have registered our event now here in case of an [Music] error at the end here I add error now once we have the event now we can use a switch statement to check for the different events
        

so we'll say switch and then we get our event. type and right here we are already interested in only one event here which is the charge succeeded
        

so here we will say if the case is charge uh do succeeded we'll say const charge uh will be equal to event do data doob and we'll say as stripe. charge we will confirm if we have this charge by checking the payment intent
        

so if uh we have type of charge do payment intent being equal to a string right here we will await Prisma and then do order then we update the order and we'll make use of this charge. payment intent
        

so here we have an issue uh I think we can Define the type of this charge right here is any and this should be type off like that uh let me see if this any has any effect actually it doesn't invoke this we pass an object where we will set the payment intent id to be charge dot payment intent and then it expects now first pass the data and what we want to Mark is the status of payment is complete
        

so here we will update the status to complete
        

so complete and you can al
        

so now add an address to our order
        

so address and here we'll add charge do shipping and then here dot uh address address that was used during the payment okay this is complaining I can just say this to be any and this will update our order it will add the status and the address after that if statement we will break at the end here we will set a default and here we can just con
        

sole. Rog and we can say unhandled event [Music] type I save to Auto format and now after this uh switch statement at the end here you must now return
        

something
        

so let s. J
        

son we can just pass a message here of received and we set it to true
        

so there we go this is our web hook end point
        

so whenever we perform a a payment this charge will be called and we will update our database we need to have a stripe web hook secret and run the web hook rocker in our machine later on when we deploy I'll show you how to uh run it when it's live okay
        

so right now right here are include this and let's see how we can set up stripe web hooks locally in our machine we need to follow these steps here first of all we download stripe CLI
        

so you can visit this link and from here you'll see uh we have different ways of installing stripe CLI you can use home Brio you can use AP you can use all this I'm on Windows and I'll use scope
        

so scope here I'll open it on a new tab here and you just first need to install scope if you don't have it
        

so
        

so in scope. sh you can copy this command and we need to do this on Powershell
        

so here I'll search for Powershell and open Windows Powershell and then right here I'll paste that command and hit enter and you'll see mine has already told me that scoop is already installed and I don't need to install it again
        

so now once scoop is installed you can run this command to install stripe
        

so
        

so I can copy this and most probably this is al
        

so installed for me but I can run it again
        

so scope and stripe bucket already exists
        

so you can see this is al
        

so existing for my case but for your case you need to install it awe
        

some now back to um the dashboard here we need to log to stripe by calling stripe login
        

so you can do this on your normal terminal I think
        

so here CMD and right here I don't know if you can see let me Zoom we will say stripe login this will ask your credentials I guess I press enter to open the browser and this is my pairing code there
        

so I'll allow access access granted and there we go and then right here I come back here this is how we can forward an event or start our web hook okay locally and this has to be running for the payment in our order to be marked as paid but once you host you'll just leave a link here and it will always uh check for event okay we just need to copy this command here and I'll paste it here now we need to forward this to our uh API endpoint
        

so that is this stripe web hook API and Point uh
        

so right here I'll say Local Host 3000 and then it will be stroke API then it will be stroke stripe web hook
        

so stripe hyphen web hook then I will remove this last part
        

so let's run this and fingers crossed it works
        

so I'll hit enter and you can see uh it it has run and it has given us a web hook signing uh secret
        

so we need this key up to this point make sure copy it well without white spaces at the end copy that key and then in the EnV file you need to paste it here okay save this file and now whenever we perform a payment uh our web hook here is listening to this particular API and it will fire the uh various events and then those various events will be received by our endpoint here and for charge succeeded we will be able to mark these as paid in our own database okay now let's test this uh let me put this side by side with what we are doing here now let's pay this and see if the events will be fired here and if it works or if we will get any error
        

so I pay and look charge succeeded has been fired and we have an error right here of 44 uh but you can see this charge succeeded event was fired although we have an error
        

so we have to figure out what the issue is
        

so right here you can see it's four for error meaning that it didn't find this end point and one mistake that we did is that we included this outside the API folder
        

so what I want to do is to move this inside the API folder
        

so I move it inside the API folder move uh but it should be outside the O here
        

so we move that we should perform another payment to see now if it works okay include a number 42 42 42 42 42 42 444 444 I pay now and see if our post end point will be called there we go we have this being called successfully charge succeeded this is successful
        

so that means that our database was updated by this uh stripe web hook it's listening to event and it's sending requests uh directly once we uh uh process the payment
        

so let's see if it worked we go to stripe let's cancel there and go to payments we should have our s here is succeeded let's go to our database uh at the orders and let's refresh we should have a t one order marked as paid
        

so we refresh and now the one that has 70 uh right here it's 700 because it's in uh cents remember we had multiply by 100 but look right here we have status is complete which is really awe
        

some our order is being updated in the database uh through stripe web hooks
        

so we will create an admin dashboard like this one we will have a summary section uh to show
        

some uh summary data then at the bottom here we al
        

so have a graph for the last 7 Days sales and then we will be able to add products or create products and we'll be saving the details in our mongod DB but for images we'll be uploading the images in fire base storage
        

so right here maybe we can try to create a demo product
        

so demo product and then the price let it be 45 brand let it be uh maybe Apple description apple right here then I can say desk for description we say that the product is in stock then uh what are we selling we can say it's a laptop then amazing here we can select the different colors that we want in this case I'll upload a black one I can click on this one just a demo image now this is the banner that I used at the homepage and right here we can add the product creating the product it might take a while
        

so we wait uh it's creating still loading okay product created and and now if we go back to our home we should see a product like that and this is it here you can see demo product then all these right here really cool you can increase decrease quantity we can add to cut view cut and there it is al
        

so we can remove it
        

so we will see how we can create the product using this form and then we will be able to manage the products using a rich data table like this one
        

so we can select stuff uh I think we can al
        

so filter we can do a complex filter here in
        

sort and
        

so on and right here we can be able to mark whether a product is in stock or out of stock we can be able to view that particular product
        

so I can't see the product that we added okay it's at the bottom here demo product and we can view it and uh you see we get that product then we can al
        

so be able to delit a product
        

so deleting product product deleted really awe
        

some okay we will have orders and for orders we'll be able to mark them as uh dispatched uh we can al
        

so be able to mark them as derived we can view the order and here it is awe
        

some we will al
        

so work on our own orders
        

so we have your orders here we will create this table right there another cool thing is that uh after we create products uh we will now al
        

so create this bar right here for the different categories
        

so that we can filter our products depending on the categories okay and then we'll al
        

so work on this search right here
        

so that we can search for anything for example let's search for phone then search and it filters only the phone um maybe we see this right here because it has a phone
        

somewhere maybe in its description uh that's why it shows up because we al
        

so check even the description and you can see at the description here we have phone okay that's why the watch showed up another thing that we will do is to work on our product reviews right here because we haven't worked on it yet
        

so yeah uh basically we are going to complete the application in this particular video and then we'll al
        

so deploy it to verel for free
        

so I'll show you how to do that okay
        

so the first thing that we can do is to create this admin page and then we will work on this uh navb here and it's a nested NV because we have the top one and al
        

so this one
        

so this is the complete application but here is the uh ongoing one
        

so this is what we are working on
        

so when I go to admin dashboard it doesn't exist it's 44
        

so let's start with that one back to the files here uh what you need to do is to open the app and then you'll just add a new folder here called admin and by that it has already created that route but this needs to have a file and the default file here is Page Dot TSX it can be TS it can be JS stess functional component here and we can say this is the admin right here we return
        

something for now we can return a div and we will say admin page let's go ahead and add a class name and we'll give it padding to the top of eight
        

so I Sav that one uh now we should be be able to see that page when we go to admin I refresh and there we go now our admin page loads and you can see here we have admin page
        

so how do we create the nested Navar
        

so the good thing with the next 13 we can Nest our routes and we can have nested layouts
        

so we have the default layout right here this one which have even the top and half bar the main content and the footer but we can al
        

so have nested layouts at page level
        

so that is what we will make use of
        

so at admin here we'll add a new file and we will call it a layout uh TSX
        

so here we should al
        

so be exporting a component and we can call it admin layout then right here we will have a div to wrap everything and and here is where we will show our Nave
        

so here let me just add a press holder we will have a nav there but we should al
        

so include children and the children are uh uh Pages or the rest of our content
        

so here I include this and I'll get children from props and we can give this a type
        

so children again this will be of type react dot uh react node and now here we show the children and the children will involve this page right here
        

so here we say children
        

so for each of the nested layouts it can have its own metadata because this is like a completely new section
        

so we can al
        

so export here con metad data
        

so we can have title eShop admin and al
        

so you can have a description for this let me just copy this eShop just takes time to write that one and here we'll have this as admin uh dashboard and I save
        

so let's see what we have now I open the app and here you see nav
        

so nav will show for uh all the children that we'll be having okay for other pages okay the first one is this one
        

so it will be available for all of them another thing is that you notice at the top here now we have E
        

soP admin and that comes from um these metadata that we have added right here
        

so let's work on this nav
        

so at components we can add a new folder called admin and we can add a new file and I can call this one admin nav do TSX here stat functional component and we'll have as admin n let's render a div let's have with as full Shadow small top hyphen of 20 we do and then border uh 1 PX
        

so let's include these as border at the bottom finally I can add a padding to the top of four and then right here we will make use of our container component which we created in previous videos
        

so container now it's Auto imported there and we have it like that in here we will have another div
        

so div and in this div is where we will list a different links
        

so we will have this links right here summary add product manage product and the rest
        

so rest sty the way those Rings will show
        

so here we will display FX the Rings will show in a row
        

so Flex row then let's have items to the center then let's have justify uh between for MD let's have justify to the center
        

so medium screen and above then let's have a gap of eight then MD let's have a gap of 12 and overflow here x of outo
        

so go to x outter FX we have no wrap just like that now for our items uh since we have a lot going on like the icon the text uh we can create a component for it and then we can reuse it
        

so let's create a new file inside admin here and we can call it an admin nav item DSX the functional component we'll have admin nav item we will be returning div and we will have an interface because we'll be accepting
        

some props
        

so let's create that interface we can say interface admin nav item props we will have a property of is these item are selected
        

so let me show you
        

so if it's selected we'll have this underline it will be more dark you see
        

so we know that we are at that particular uh route then here we will have an icon of type icon type and these will come from react icons
        

so ion type make sure to import it like that we'll have a label this is now like the text
        

so this will be a string let's make sure that our component know about these uh
        

so we destructure the various props we'll have selected we'll have icon and we'll have the label
        

so this icon should be a component
        

so we can rename it to Icon they should be inside brackets uh just like that right here we'll have a class name use this and then backs because we will concate strings or join them and let's start with flex here and then items to the center then we'll have justify Center text to the center then we'll have a gap of one a padding of two border um bottom of two and we'll have a hover text hyphen straight hyphen 800 and then we will transition CA will be pointer and we'll say if it's selected we will show
        

some Styles here else we will show others there we'll have a border bottom and these will be straight uh hyphen 800 will do and then right here uh we'll have border as transparent
        

so it's not visible al
        

so here the text will be straight hyphen 800 and for this one it will be 500
        

so text straight 500
        

so it will be a bit pale okay
        

so those are the class names let's get inside this div here we will be having our icon we can have the size prop and we can set this one to 20 the second thing we should show the label
        

so here we will be having the label and for this div we'll al
        

so have a class name we will change the phone here to medium text will be small text will be at the center and we'll say break hen normal and basically uh that will be it not unless we made a mistake
        

somewhere I hope not
        

so let's come back now to our na bar and inside this container is where we will make use of our admin n item
        

so remember these are links
        

so let's add a link here and this um can come from next Link in here is where we will have our admin nav item component
        

so it will be available there for this link it expects us to have a href we can push this user to stroke admin this expects us to have a label and for this one we will say summary
        

so at stroke admin that is like the home we will have the summary there we need to have an icon and this will be MD dashboard hopefully it is suggested here it will come from react icons and then right here res set selected we can perform a check on the path
        

so here we need to get access to the path and we can make use of a hook called uh use path name
        

so here before our return statement you can have con path name will be equal to use path name and this comes from next navigation
        

so make sure it's imported from next navigation and make sure to al
        

so invoke this one
        

so this will give us the current path that we are at and we can perform a check here to know whether we are currently there or not
        

so here we'll say if our path name is equal to the route that we added
        

so equal equal to admin
        

so I save and right now we should be having uh a na with at least one item let's check and see if we made progress okay we should hook these at our layout
        

so instead of this Nave we should have our admin navve now I save and we should be having
        

something now let's refresh Manu
        

so we have an issue use path name only works in current components
        

so let's uh make sure that we mark this particular component as a client component at the very top
        

so
        

sorry I had forgotten about this but the good thing is that our nextjs has reminded us
        

so let's see and look amazing we have this now nve here with one item saying summary and it's underlined working like magic let's add more links now
        

so alt shift bottom arrow that will duplicate it and we can add like how many three
        

so that is one 2 three let's come to this one now this will be stroke admin stroke add hyphen uh product and then here we'll have the label as add products icon is MD Library ad uh selected here will be add hyphen product that's it
        

so this will be stroke manage hyphen product label will be manage product then down here uh we'll have a stroke manage hyphen products and then here uh the last one let's have manage orders now we didn't change the icons this one will be MD uh DNS this one will be MD format list this one format list bued okay
        

so we have those I save and let's see
        

so yes we have all this um when we visit them we are getting for fors because those routes or those paths uh does not exist
        

so how can we fix that it's pretty easy actually at our app make sure you are in admin and in admin you have layout and page
        

so here we will add a new folder and now this will be like the nested routes we can start with add a hyphen products enter for each of these we will be having a page
        

so page. TSX stess functional component then we can say add products and let's have a placeholder here can say div and we'll say add products I save
        

so now when I visit other products we should be able to see these component being roded
        

so let's come back uh uh click back here we click on add products and there we go
        

so you can see here add products now this does not become active uh we need to fix that here we should be having stroke admin and now it should be active this should be the same as this and for all of them make sure they the same basically and there we go it's there now look we can go to summary we can go to add products now we just need to create these other two pages
        

so uh again app admin add a new folder there this one will be manage ERS let's create another folder okay it must be at the root of the admin there
        

so make sure you add correctly manage here product for each of them we should be having a page let's create page. TSX stat functional component manage orders that will have our manage orders let's come to this one this folder which is empty add a new file page. TSX stess functional component manage products we return a div of manage products just like that I save Let's test all the routes now and as you can see this is the structure of our admin dashboard there we have these different pages then we have this default page which will Road uh all the summary and we have our layout awe
        

some
        

so manage products I might take a minute to load because um on dev it has to rebuild each page okay there we go
        

so all of them are active and you can see the content here is changing and that is how we can simply create a nice uh admin Nave like that you can al
        

so consider creating a side nve for the admin whichever style you want okay okay cool now the next thing that I want us to do is to cover add products okay let's start with the this one for us to be able to successfully create the product we will need to have Firebase storage set up because uh we will be using that for storing images
        

so right here uh I would like you to visit uh firebase.com and then uh log in or create an account okay you can proceed with Google and now right here I'll just add a new project I can say eShop vid because it's for the video and uh here I'll continue I will disable analytics and create the project this should take a minute or and then we will click on continue
        

so once we are here we will create a web project
        

so click on web uh give the project a name a nickname
        

so again I'll say E
        

soP vid I'll just register I don't need to uh add hosting
        

so I'll register there and here you'll see instructions uh first of all we will have to install Firebase
        

so just copy that command and you can install Firebase
        

so I'll paste it and make sure to add it to my project uh and then we have this information right here or configuration just copy that configuration and from the root here at our ribs uh we can add a new file
        

so we have this Prisma dbts let's add a new file and we can call it Firebase uh dots and all we need to do here is to paste uh whatever we copied down here I'll say export uh default we can call it Firebase app uh it doesn't exist
        

so I will replace this app with uh that Firebase app
        

so this is complaining because uh I think it needs to complete installing there
        

so I'll save that file for now and then I'll go back here and we continue to con
        

sole here we need to set up our Firebase storage click on build then click on storage click on get started yes we can start in production mode there next select allocation I'll just go with the default now you can see that our fire baser storage here has been uh set up we need to go to rules and we need to allow access to uh everyone
        

so here just uh allow uh read right then publish the rules okay awe
        

some
        

so we'll use these for storing images um it's uh very uh easy to use okay
        

so this has completed installation which is awe
        

some and this eror has disappeared awe
        

some
        

so now uh let us first set up the product schema
        

so at our Prisma schema. Prisma uh you can come here and maybe before the order or after the order uh you can start working on the product schema here
        

so I'll have model product we'll be having an ID ID will be a string then we'll have at ID then we'll have at default we call that and we pass Auto and we call it again then outside here we will have at we map our ID uh mongodb idore ID out here we'll say at DB doob ID we'll have a name for the product which will be simply a string we will have a descript destion which will be a string we will have price which can be flot a brand uh which will be a string category uh this will be a string instock this will be Boolean image
        

so we can have more than one image
        

so this will be an array of image
        

so this image I think we had created it uh before at the bottom here awe
        

some let's have reviews and we'll have our review like that
        

so down here let's create a model for the review
        

so we'll say review the ID will be similar to this one I copy this and I paste it here down here we will have a user ID for this one it will be a string and at DB do object ID uh this should start with a capital there we'll have the product ID this will be a string and at DB doob ID rating this will be an integer we'll have comment and this will be a string let's have created date or created art whichever you want and this one will be be date time and at uh default we'll set this one to now
        

so as you can see this is still complaining
        

so down here we should uh make sure to refer it
        

so right here we'll have a product we will say product uh at uh ration here we'll have a Fields product ID reference will be ID can see there disappeared al
        

so we will pass a user and the type here will be user then add duration and here we will have Fields uh user ID we'll have reference as ID we will add on D will be Cascade okay
        

so we need to go to the user and al
        

so refer to this review at the user here we need to say reviews can tab maybe up to this point where we have them and here we'll say riew is an array of uh type review
        

so I'll go ahead and save that file I'll stop the running application
        

so contrl C then I'll say npx uh Prisma DB push
        

so that we update our DB together with the model we put them in sync
        

so I hit enter my database indexes are now in sync awe
        

some I go ahead and start the application using npm R Dev let's create an API route that will handle uh creating a product
        

so at app we need to go to API we'll create a new folder we can say this is product in that folder we'll have route. TS we can copy one of our routes okay let me use this one because it's shorter
        

so at our product route I'll paste this register route and then we modify it as we go uh starting at the top here we don't need bcrypt
        

so remove that one uh we need to have this Prisma we need to have this next uh response
        

so here we will import another uh function get current user from we had cre this at actions
        

so at stroke actions then stroke get current user now here we export an async function it is a post request we will have the request like that then here we can get the current user before anything else
        

so here I'll say const current user uh will be equal to we await our get uh current user and we invoke that
        

so import it like a default UT like that awe
        

some if a user is not an admin and uh if a user does not exist they should not be able to create the product
        

so here we perform a check
        

so if we don't have current user or the current user uh dot R is not equal to admin then let's immediately return
        

so here we will return and we'll say next response. uh error down here we get the body from request. J
        

son then here we can get all the properties that we need from the body we will need the name then we'll need the description price brand category in stock array of images
        

so all that we will get from the body we don't need to create a hashed password
        

so we remove that one we will have const product is equals to await then we'll have Prisma do product. create
        

so here we'll have product
        

so if it doesn't complain means that our sync was successful then here we add the description brand category we add in stock we add images price and for Price here will be pass fro and we pass the price we have an at this meaning that I included image instead of images at our Prisma schema yep we said image
        

so I'll go ahead and change this to images that's the best we can do there and uh still it will not recognize it
        

so we need to stop the app and run it again just do that quickly uh actually before you run it again make sure to run npx Prisma DB push and then after that we start the app and U yeah I think after that everything will be fine
        

so you see there disappeared then I can run that up again
        

so we have created the product and all we need to do is to take this product to the user
        

so here we just pass our product and that is our API route uh pretty simple right now we have our backend set up where we have created the model we have created the AP route we have set up our storage
        

so let's work on ADD product form we need to do that at app admin then we had this add product this is our product page for adding a product
        

so here we add a new file we can call this add product form. TSX
        

so this will be a client component
        

so use client let's go ahead and create this component the functional component and we'll say add uh product form then um for now we return only the fragments or ad div maybe and I save that file
        

so I'll come back to the page because uh this is the beginning of stuffff and and these will remain to be a server component we need to bring in our add product form okay before we do that let's do
        

some stuff here we add a class name and we'll say padding generally will be it and then right here let's remove that we will return the container component that will come from our components like that wait a minute I check
        

something where did we create the admin N I feel like we used the container did we import it from the correct stuff oh no
        

so this should have come from our app not not Material UI I had a feeling that we messed up there we should have brought that from uh this one here
        

so I save that although it worked well uh but let's still use our own we need have the form wrap from our app like that because now this is a form and we pass now our add product form let's click on that to al
        

so Auto Import it and we have that now
        

so con current user this will be equal to a wait get current user and we invoke that now this comprint because we should Mark this function as an a sync function like that now we perform a check here we'll say if we don't have the uh current user or if the current user dot R is not equal to admin uh then we immediately return right here we can create a component that will help us to return the errors whenever we need to
        

so at components Let's uh create a new file and we can call this one Nar data. TSX uh it will have an interface of Nar data uh props we will only have the title it will be uh string now down here const Nar data and we pass our Nar data props like that uh we set this to be equal to an Arun function uh that will accept the title prop
        

so title and here we have the arrow now we will return a div inside the div we will have a paragraph that will include our title like that then here we can have a class name and width will be full height will be 50 VH we flex and items will be Center then here justify Center text will be XL MD text will be to XL we'll have another class name we'll set this font to be medium now down here let's go ahead and Export default component which is null data and I save I go back to page now
        

so null data and we make sure to import it we should pass the title because it expects it and and we'll say oops uh access denied awe
        

some
        

so if we check and try to access add products you see we have access denied
        

so we have kind of protected this route now we need to be admins for us to get this
        

so how do we become admins uh we need to go to mongodb and uh log in if you're not logged in
        

so I will browse Corrections at my database then I'll go to user and uh from here we can be able to change this from user admin okay
        

so from user here and I can only do this from the uh database okay
        

so I changed that to admin yeah
        

so let's refresh the app now and uh we should be able to see this box here that means that it work we no longer see this error it is roing our add product form we see nothing because our add product form has nothing okay now let's handle this form this form will be massive but we will uh finally complete it
        

so starting with the return here actually I return our react fragments and let's enter in here we will have a heading to begin with we already have this component
        

so heading it expects to have title and we'll say add a product and here we can put it at the center
        

so let's confirm that we are seeing that heading uh it should show here there we go add a product we will have an input field
        

so the good thing we have already created
        

some of these components
        

so let's have input now these will have several props the ID will be named label as name disabled uh it will be disabled if we have is loading as true
        

so we don't have that property right now let's go ahead and add it
        

so const here we include square bracket is loading and set is loading and right here we have our use State and that will come from react this should be false okay
        

so here it's rading Now does not have an error we will have register and this register will be register and this will be coming from react hook form
        

so we don't have it we will add it let's have errors and this will be equal to errors we don't have it we add it let's al
        

so make it to be required
        

so to
        

solve this and this R come here we will say const we will destructure
        

some stuff there and we will be getting this stuff from our use form hook which is coming from react hook form we can make sure to invoke that right here we will have filled vales as the type this will come from al
        

so a react hook form fill vales then here we can include
        

some default uh properties
        

so we'll have default uh vales uh the name will be just empty uh description will be empty
        

so this is actually the list that we included at our API I feel like just going and copying it from there because uh why not let's copy them then name description then I paste this okay
        

so brand here now will be empty category will be empty in stock abuan false images uh we will include an empty array and then we have price let it be empty
        

so these are the default uh values now here we'll be able to distract uh register we'll be able to get our hand submit we'll be able to get Set uh value watch and al
        

so reset and finally here we will have form State and from form State we will be able to get the errors object I save okay now down here we have our input doesn't have any errors anymore cool let's check if that input shows and it's refreshing and there we have our input field as name awe
        

some
        

so let's add more we'll have input and uh why do I feel like we should have just copied these and uh just change stuff
        

so remove one of these we have price as price label is uh price uh disabled is roading register register errors errors required and uh for Price rat have the type here is a number let's proceed we'll have another one these will be for brand
        

so
        

so let's have brand and here theable will be brand
        

so one thing this ID should match your default one here
        

so that they uh work together then disabled register errors required okay that's good the next one should be a text area and uh did we create a text area really let's see components input we only have input here but we will add a new file and we'll call this one uh text area do TSX
        

so this text area will be
        

so similar to our input here
        

so I'll go ahead and copy this input come to the text area and paste it
        

so at the top we import all this this will now be text area props um we'll have ID label we don't need the type we we have disabled required we have register we have errors then right here or instead of input we will have text area and then react right here we have a text area then here we remove the type yes let's scroll down uh we will change now this input to be a text area we can remove auto comete here um you'll have ID disabled register ID required press hold um type is not there we remove it we can set
        

some height okay Max hyen height to be 150 PX the remain hyphen height to be 150 PX as well all this will be fine errors will be fine then we come to the uhb
        

so for the label everything will be the same right here let's export this component text area I save now back right here we copy one of this paste it here and this now will be our text area this one let's make sure it's al
        

so imported now this will be for the description description label description is roading register errors required cool I save let's see how it looks like look we have our form there awe
        

some now we need to include this checkbox then we will add this select a category then we will uh come to adding an image here we will be having a checkbox
        

so at our inputs let's add a new file and we will say custom checkbox. TSX stess functional component custom checkbox
        

so for this one let's do everything from scratch use client here then we will need props
        

so let's create an interface for the props interface check custom checkbox props then here we'll have ID which will be a string um we'll have a label uh a string we will have a disabled which will be Boolean and this can uh actually be optional
        

so question mark there finally here we will have register this one we will make use of use uh form just this will come from react hook form uh it will be of typ fi various let's hook our interface here react. FC angle brackets custom checkbox props let's pass the props here now ID label disabled and register we will be returning a div and an input right here uh type will be the checkbox let me save to outo format and we work on this
        

so here we'll have a class name and withth will be full Flex it Flex La Flex Pro Gap will be two items will be at the center this input let's cheat a bit let's come here and copy all this copy and we come back custom checkbox and paste here okay let's remove auto complete we will have the ID we will have disabled then we will register the ID let's remove this part where we required then we'll have press holder is empty uh the type we already included that
        

so let's remove that save Auto format
        

so this is it then down here let's have a class name and we'll say CLA here is pointer just like that okay we need to have a label right here
        

so label and we'll simply show the label like that and here we can have HTML for and we pass the ID here
        

so
        

so that when you click the label al
        

so the check box will be checked and then here we'll have a class name and um red font B medium and CA B pointer do you see pointer there and that's it okay
        

so let's save right here now we pass our custom uh checkbox and here we'll have ID and we'll say in stock then here we will add register to be register then finally here we'll have reable to be uh this product is in stock we have this one here okay cool amazing
        

so now we need to add the select a category section let's do that
        

so for that one I'll just add a div here and we'll do everything right here we'll have another div and this is where we'll say select a category let's add
        

some class names because we need to make use of those awe
        

some T CSS classes to make it look nice do you agree or not
        

so with full font medium then here we'll have another one and for this one we will have margin margin to the bottom of two font will be bold
        

so font um we can use semi bold works best cool now right here let's have another div now and this is where we will be having all those cool selections and you can see the way we have we have them like this in three sections these are three grids
        

so we'll make use of um grid here to organize them nicely
        

so let's say grid then we include the number of columns
        

so grid Das calls Dash uh two
        

so this is two columns these will be for the small screens but for medium and above then we'll have grid Das calls -3 make sense and and then here we will have a Max height and here we'll say 5050 VH if they overflow let them um scroll okay
        

so overlow y outo um right here we should map through the different categories which we don't have
        

so we should create them
        

so I'll save this file first of all and then uh minimize everything here go to and add a new file and right here I'll say categories dot TS and we will al
        

so be using these categories at our top na uh for this complete app uh we'll al
        

so use them here okay
        

so we are using them here and al
        

so we are using them at our admin right here okay
        

so let's add this this data it will help us a lot
        

so here we'll basically export uh const categories and we'll set this to be an array and we'll be having the different uh objects for each of the category we'll be having a label and here we'll have all okay then here we'll have an icon and we will say MD to front like that it will come from react icons MD that is one we will have several
        

so let's duplicate this one about six times and you can add as many categories as you want or as few as you want depending on your use case but I I guess this is for learning purpose use alt shift bottom Arrow uh then we'll have 1 2 3 4 5 5 six uh maybe those should be enough if not we will add or if they are excess we remove
        

so here we'll have the phone category and here we should include a phone icon
        

so I say a i f phone that is from react icons AI okay then here we will have a laptop again from AI out train then uh [Music] laptop down here we will have desktop let's have
        

something that looks like a desktop AI out train uh desktop let's come here watch then let's have MD uh watch um here TV MD TV
        

so I had like Care Free checked all these icons
        

so if you don't find them attractive you can go and explore others there are
        

so many icons at react icons let's finally have acces
        

sories here and we'll say MD um let's have a keyboard to repres present the acces
        

sories I save
        

so we are exporting that array of categories ae
        

some Let's cross start come here we will make use of it here we'll have uh categories dot map this will give us an item at a time and here we pass an arrow function car brackets and uh let's check if uh item do label is equal to all all categories uh we don't want to show that
        

so we return Nar
        

so return Nar then down here um we return we'll have a div
        

so we have that and right here we will be returning a single category at a time and uh create a component for that because it has
        

some simple Logic for selecting and uh
        

so on
        

so uh for that again we will go to app components inputs
        

so let's add a new file and we'll say category uh input. TSX I hit enter stess functional component and and here we can have category uh input okay at the top we'll have
        

some props
        

so let's define an interface here and we'll have category input props we will have selected and this will be a Boolean let's have a label we can have this as string an icon and we can have this says icon type okay it should come from react icons let's have an onclick and here we'll have a value when we click which will be a string and it will be returning void we'll have react do FC and here we pass our uh category input props I save okay it doesn't Auto format because here we should be returning
        

something and we'll be returning a div I save now and at the top since we have
        

some unclick events this should be marked as a client component
        

so use client here here we distracted the different props we will have selected we will have label we will have icon and we can set this as I on we will have onclick I save to AO format like that then right here at the div we will show an icon
        

so we will have an icon and it will accept a size prop and uh we can set this on to 30 the other thing that this accepts is a label we'll set a label here inside a div label then we'll have a class name here and font uh will be medium here at this div we will have an onclick and we will be calling on click here and we pass theall here we add a class name and now we style our specific item or category
        

so these will be rounded XEL we'll have a border of two padding of four of f is call uh we'll have items to the center we'll have a gap of two over full column border hyphen straight hyphen 500 when we H then let have a transition finally here can have CA as pointer and we will change the cell depending on whether this is selected or not
        

so I'll change whatever we have at the ends and include backticks uh I'll open the blacket here and close it here
        

so right here we can have Dynamic styles using selected like that and here if it's selected we'll have border uh hyphen straight hyphen 500 and then right here border hyphen straight hyphen 200
        

so I save now now we have this category input let's make use of it in our form here we will return our category input it's self closing and it expects uh several props we will have on click
        

so when we click here uh we will receive a category we will set a custom value and we provide a key which will be category and we will set these to be category let's come at the top before our return here we'll say const category uh will be equal to uh watch and here we invoke and we pass category we'll make use of this return at the bottom again we'll say ected we'll set this to be equal to category and if this category is equal to item do label now right here we'll have a label item. label here we'll be having an icon and the icon will be item do icon um this is complaining this should be custom value
        

so we don't have it yet uh let's define it I'll come at the very top first of all I remove this input which was a mistake and below this let's have con custom value okay set custom value not custom value and here we'll set this to be equal to we will be receiving an ID which will be a string and here we'll be receiving a value uh which will be any
        

so this is the category that we pass here and this is the value that we get okay I said this to Be an Arrow function here set value now this is coming from our react hook form right here and we are now setting the category value
        

so that it updates uh in our form data we will pass the ID and we pass the value and right here we pass
        

some options
        

so we'll say should varid dat and we'll set this to True uh should diry we'll set this to true and should touch we'll set this to true and uh yeah now at the bottom we have this category input which is custom right here and the key can be the label because it's Unique
        

so item do label and uh right here we'll have a class name and the CL name can be called hyphen span okay
        

so why is this throwing an error I misspelled I save
        

so at this point we should be able to see our categories because we are passing the REO and
        

so on
        

so let's see what we are working on here and there we go we have these categories there uh they don't have a gap we can select look um we can add a gap of three I save and there we go awe
        

some now we have that section the next big section is this one for selecting images
        

so let's handle it why not I'll add another div we will have two sections here we'll have a div where we have the description and we have a div here again now right here we'll have a crass name and with will be full Flex it Flex will be column let's add a flex uh wrap and let's add a gap of four okay now for this first part let's have a div class name here font hyphen bold
        

so I can copy the text from here we'll have another div here can come here copy that paste there I can have a class name uh text small I save there we go
        

so now let's work on selecting uh an image uh we might need to create several components and al
        

so
        

so we need the colors I'll go back to utls here and I'll create a new file called colors TS and here we will export con colors to be equal to these we pass an object here and we'll have a color for each color we'll al
        

so have the color code for this one let's have a comma there let's have a comma here and we'll have an image this will be null
        

so this is how how one color will look like we need several you can add like eight of them let's have 3 4 5 6 78 here let's have silver color code c0 c0 c0 let's have gray 8080 8080 let's have red ff0000 gold ffd 70 let's have blue 00 0 00 0 FF let's have uh graph fight
        

so these are like the common colors when it comes to electronics like mobiles uh and
        

so on
        

so let's add white
        

so that they are eight
        

so white can actually start it's a very popular color FF FF FF I save now we have the colors and we will need to map through them let's come back here we had this div here we will map through the colors here
        

so we'll say colors do map and we invoke that we'll be passing the item and the index and here we will be having an arrow function that returns
        

something
        

so return we will return a component for now let's have react fragments this cars let's bring it in from our utils and here for this div let's have a class name and here we'll say grid grid calls will be two and a gap of three okay fix this div here I'll go ahead and save
        

so for now we are not returning anything but we should return a component and I'm going to call this component select color go to app components inputs and add a new file I'll say uh select color do TSX uh let's have an interface here of Select Cola props here we will be getting an item and this item will be of Type image type
        

so we don't have this type uh let's create it at our add form
        

so right here let's add
        

some types there we will export Type image type this will be equal to um color of type string color code this will al
        

so be of type string and amazingly we al
        

so have the image here which will be of type file or it can be null now this is the image type that we select but we will al
        

so have the one that we have uploaded
        

so here let's have another one of um uploaded image type uploaded image type color will be string color code will be string now here we'll only be getting the string from our DB or from Firebase storage okay
        

so now we have those now back here we can import this image type from our add product form like that and we'll have a function called add image to State and for this one it is a function therefore we use an arrow function here that returns void and here we'll have a value it will be of image type now here we'll al
        

so have remove image from State this will have a value and image type and we return void as well here we'll have his product created and this will be a Boolean this should have void I save this is just the props and their types
        

so right here select H Color let's pass the props or the interface
        

so here react do f see angle blackets our select color props let's pass or D structure the different props the item they add image to State they remove image from State and is product created
        

so here for now let's have an empty fragment like that
        

so before our return statement let's create
        

some state
        

so const we will have is selected and set is selected false here let's import this one from react and another state that we will add file and set file and right here we will simply say use State and we include each type it can be a file or it can be null and we invoke our use State initially the file will be null now here let's have a use effect and for this use effect we'll be checking whether the product has already been created or not
        

so if the product has been created uh then we reset our state okay
        

so here uh let's have that and we must have a dependency array and we will check for is product created right perform a check if his product is created let's reset our state
        

so set is selected and we'll set that to false and al
        

so let's reset our file and we'll set this one to null let's save that one to the format now down here I am going to create
        

some helper uh methods that we will use
        

so const and we will call handle a file change
        

so I make use of use call back to optimize it just like that uh remember use callback always has
        

some dependency array al
        

so here and here we will be receiving a value and the value here will be the file
        

so here it will be off type file and then here we will be having set file
        

so we update our state now here we are resetting the state here we are updating the state and we will set this two value al
        

so we we'll call add image uh to state we'll create this function later on
        

so here we'll have the item and image will be having a value
        

so remember with color we are handling both the color and al
        

so the image
        

so here let's spread the item and we add the image
        

so here we have handled a file change
        

so let me create a function here called handle uh check and here we can al
        

so make use of use callback we will set is selected we'll call e. Target uh do checked
        

so this will tell us whether the checkbox is checked or not and then we can conditionally uh render our UI
        

so here we are receiving an event and the event is of type react do change event and then angle blacket we pass HTML input element
        

so when we check uh we will show this right here and this will help us to appro a file okay as all select one and then when we uncheck we want to clear it
        

so that we can appro again we will perform an if uh statement if we get an event and what we get is that e. Target um do checked is false that means that we have checked all we want to do is to clear the state
        

so set the file uh to null and here we will remove the image from state
        

so we simply remove it from the data that we will save in the database
        

so this and these will be manipulating our form data this one this data Okay cool
        

so it will make sense once we complete it
        

so now we have those functions that will really help us and we can continue at the bottom here we will return a div we'll have another div and let's add the class name for this one
        

so class name grid let's say grid hyphen calls hyphen one it will be one column but for MD we will be having two columns
        

so grid hyphen calls hyphen one and then here we'll have an overflow of Y to be outer we'll have border a custom one 1.2 PX we'll have a border color
        

so border straight to be 200 and items Center and padding of two
        

so that is the parent div we have all those classes I saved AO format then we have this div now and we will have a class name for this one we will flex and flex will be in a row let's have a g up of two let's al
        

so have items at the center a height which will be a custom height of uh 60 PX okay now here we will add this part where we have this checkbox input it will have an ID of item do color we'll be having the type will be checkbox we'll check if is checked
        

so if it's checked we will say here is selected
        

so it's a controlled uh input
        

so here we'll al
        

so pass handle check we'll have a class name and we will say casa pointer and then we'll have a label and the label will be having the item do color another thing is that yeah we will be having HTML 4 and and these will be for item do color let's have a class name and we'll have font as medium CA as pointer after the REO we have this div after that div now
        

some react fragments and for this react fragments uh we will perform
        

some checks we'll say is selected
        

so this checks if the input is selected if the there is no file
        

so if it's selected and there is no file then we will proceed and and we will show
        

something right here and whatever we will show now it's a div
        

so if I select now that div will show this section here where we have uh the image selection
        

so we will do that in each separate component
        

so for now let's have a class name here we'll have a call hyphen span of two and then text will be at the center now let's create a component that will select the image and then we will add it here
        

so at our inputs and we'll say select image. DSX let's make this to be a use client uh let's start with an interface here here we'll have items optional then these will be of image type okay not items but item
        

so we get an item we will al
        

so pass handle file change
        

so it will receive the value and the value here will be the file
        

so type file but it will be returning void now here let's create that component the TR functional component and we will say select image we pass the interface here then right here let's destructure our props here right and handle file change let's have a div
        

so here we will make use of a library called react Drop Zone uh we need to install it
        

so you can copy that and install and then you can read documentation on how it's used but basically we just need to import this use Drop Zone from react drop zone
        

so we'll basically need that to import it we import that hook and then um we will have this on drop and then we will do
        

something there and then we'll get all these get root props get input and uh yeah and uh we'll make use of them right here
        

so let me copy
        

some of these I'll paste before our return statement let's import Port use call back let's add the types for accepted uh files this will be an array of file and we will do
        

something right here
        

so once we drag and drop we'll check if our accepted files do length is uh greater than zero we only need one
        

so we will take the first one
        

so here we'll have handle file change this should be hand that's why I'm getting errors here we get the first file by getting our accepted files and we access the first one
        

so we pass the file to handle file change that will be received at our here then that will later be passed to our parent right here
        

so we haven't created add image to state but we will
        

so let's continue here we have all this uh we'll have on drop and then we can specify the kind of files that we want
        

so here we can add accept and we'll say full column object
        

so image like that and then we say athetic then full column and this full column should be out here JPEG and all.png
        

so if you appro a different uh file form then it will not work
        

so I save and this is now our used Drop Zone like that now let's come to our return
        

so right here we will use card bracket and then we will spread get root props and we invoke that in here we will have an input uh which is self crosing we will pass
        

some props get uh input props like that and we invoke it
        

so those props will be automatically added right here we will perform a check using is drag active
        

so if we are dragging uh then we can specify where we want you to drop the image we will have a paragraph that and we can say drop uh the image here then here we'll have else if we are not dragging we will show the plus button
        

so let's have a paragraph here we'll say plus then item do color here image
        

so I save we need to style this box
        

so let's have a class name and right here we'll have a border of two then border can be straight hyphen 400 um padding will be two then we'll have a border dashed CA will be pointer text will be small uh font will be normal text will be uh straight and then here 400 then Flex res have items to the center and we justify to the center awe
        

some
        

so those are the styles for uh this particular box and we export our select image
        

so that is it all we are doing here is making use of use Drop Zone to drag and drop an image Al to select the image file now that we have this let's come back to our select color and we should use it here select uh image from select image uh it accepts the item or it expects us to pass the item it expects us to pass handle file change and this will be handle file change and this function here it's the one that is here after this let's check if we have the file
        

so if file exist we show a div like that and here we will show the uh name of the file
        

so to make sure that they can confirm that the file has been selected
        

so file uh dot name we show the name of the file then right here we will show a button to cancel that file
        

so here we will have a button remember we already created a button component in previous um uh epi
        

sodes this expects us to have a label and we can say cancel and then right here when we click this um we will simply call this AR function and it will reset the file
        

so it will set the file to null and right here it will remove the image from the state
        

so it will remove the image from the state we pass the item this will be a small button and al
        

so it will be outlined it's okay let's come here and add
        

some classes
        

so class name we will Flex Flex here will be in a row and then we'll have a gap of two and text will be small call hyphen span will be two and items will be at the center we justify between awe
        

some let's al
        

so add a class name here and we will say that the width here is uh 70 PX I save and that is our select color component now we need to hook all this
        

so our select color we need to hook it up at our add product form now here we will return done a single component which is our select color component from our app like that let's add various props it needs to have a key and let that be the index then it require us to pass the item that will be the item that we are mapping through remember we have this cars then we have each color at a time then here we will have ADD image to State we don't have this function
        

so for now let's pass this function that returns nothing we al
        

so need to have remove image from state
        

so these are functions that we don't have yet
        

so uh let's see first of all how it will look like and then here we have is product created let's for now say true or false okay false but here we should pass
        

something that is dynamic
        

so I save and that is our select color right there if I come here go here um there we go and they are all displaying downwards look I can select um let's try to drag and drop a file here
        

so I try and drag look dropped the image here and it's selected and it cancels awe
        

some it's working well but now it's not updating the data up there at our form dat another thing I I think this is not what we wanted we wanted two cor and I found that we added a comma here
        

so just remove that and save now there we go we have two of them awe
        

some and if you check here it select color I don't know why I added this because it's one column anyways
        

so it's still two and works very nice okay
        

so
        

so now we need to complete uh image selection and adding it to state by uh defining this particular functions
        

so let's create these functions uh
        

so at the very top right here we have is roading let's al
        

so add const images then set images and right here use State and we pass our image type like that all null then we invoke that I save AO format then here we will be having con uh is product created then we'll set is uh product created we will have use State we invoke it and pass false the default okay now this is product created is the one that we will pass down here to check whether product is created or not now maybe after use form hook here we can create an effect
        

so use effect and then inside here we will call set custom value
        

so set custom value like we called it at the bottom like we called it here we called the key category and the value
        

so we are doing the same we will call this the custom value and we will set uh images that is the key and then here we pass images from the state
        

so if images changes then we al
        

so update our state another thing once we create the product we want to create everything
        

so we make use of a use effect here and here we will check for is product created once a product is created um we want to reset our input fields and al
        

so to create other states
        

so here you'll say if is product created let's check if it's true if it's true then we reset our input Fields reset like that remember we have reset from here
        

so it will help to reset it we set images to null we uh set is product created now to false cool I save now let's create our helper functions we can create them uh before the return statement right here
        

so we'll say const add image to State uh we make use of the use call back hook then we will obviously have this and instead of me keeping on typing this one we can duplicate it
        

so alt shift bottom arrow and this will be uh remove image from State and remember the state is the one that we have here of these images and when the image change this use effect will update it to our react hook form data I hope that cycle makes sense okay okay here to add it's easy
        

so we'll set images we invoke and here we can usually pass an arrow function and we'll have access to our previous state then here we will check we will check if we don't have the previous state
        

so if previous state is null then we will simply return the new state which is an array of our value and our value it's the uh selected image
        

so value here then image type the type okay now down here uh else if if we already have
        

some previous state then we will just spread the existing one
        

so we will take the previous value and we add our new value and that is how we can simply uh add an image to our state
        

so I'll copy that and this is what we should pass here add image to state
        

so now let's remove image from state right here again here we'll get the value and it will be of image type and then right here we again call set images same cycle we get the previous state we can make use of it uh right here at the bottom we return previous then right here let's perform
        

some checks
        

so if we have previous state if we have previous State filter out the image that we want to remove using the filter array method
        

so we'll say const filtered images will be equal to previous dot filter we invoke this and this will give us an item at a time and in here we can return the item do color that is not equal to Value do color and uh now down here we simply return uh the filtered images now we pass this remove from State uh right here okay cool let's Rog con
        

sole. Rog of images uh right that let's just specify images
        

something like that okay
        

so let's test it out let's open the con
        

sole here let's go to con
        

sole now you see images undefined let's select there then let's select an image let's take that one open who it's not working uh actually it's working I just refreshed the page and you can see it's adding the images here to state
        

so white color and then the image file right here this is coming from our use react Drop Zone then here let's let's appro the same thing but now black here and look now we have two of them two images now if I uncheck this uh it's not logging to con
        

sole uh but it should remove it
        

so it should not have this AR function but pass it directly like that
        

so we can test it now uh I will refresh and let's select an image this one open let's select another one
        

so that we clearly see what is happening
        

so we have to then we uncheck then we have one awe
        

some it's working and when we cancel we have zero
        

so that is good because we are able to uh select the images and multiple images here and All That Remains is to take all the data from here and submit it
        

so let's add a submit button uh at the very bottom before this fragment we can have a button this comes from our components it grow and it accepts AO we will dynamically display this
        

so is ring
        

so if it's roing Theo will be loading or it will be add product and the then here uh we can have an onclick and we pass hand submit and here we'll pass on submit this on submit we haven't created it yet but we will in a minute and uh yeah this is this is our button there now let's come at the top that handle submit comes from our this one our react hook form now after the effects we can come right here and here we'll create a function that will help us to submit that form
        

so we'll say const and uh we'll say on submit and full column this will be of uh type submit HRA from react hook form then we pass field values here
        

so Field Val and then right here uh we set this to be equal to and here we'll be able to receive the data from react cook form now to test this let's con
        

sole. Rog this data
        

so con
        

sole. Rog of our form data and here we pass our data I save and now these are disappeared and let's see what we have
        

so look we have ADD button
        

so let's remove this images log since we are no longer using it where is it this one
        

so that our con
        

sole is just clean I save now and we clear con
        

sole let's try to submit without anything F
        

so we try to add and look all these are required awe
        

some and for these ones we will be adding checks before we even submit the data
        

so that you don't uh submit empty form uh this is good
        

so let's test let's say this is an iPhone any price it's
        

so expensive and then brand
        

so you can specify the price is in dollars or
        

something like that okay brand um Apple then description Apple phone called iPhone that's a good enough description in in stock let's select this is a phone uh let's select let's upload an image here black and uh we will have an example image our Banner image now if we try sub submit it should uh show us the data here
        

so add and look okay we are not yet creating everything but we have this
        

so look we have brand is Apple categories phone description in stock through name price and image
        

so we are getting all the data when we click the submit button All That Remains is to come here and what we will do is to First appro images to Firebase uh FB for Firebase and then uh once it's successful we'll save product to mongod DB
        

so saving the product to mongodb is an easy part uh while this might involve
        

some uh workout but uh the documentation is clear
        

so nothing to worry about uh for example uh if we come right here and search for Firebase image upoad uh everything is uh online on the documentation you'll see you have upload files with cloud storage and here you have different ways of uploading the files blob file ATC uh we have right here manage uploads and here you can be able to see when uplo is on when it's post and
        

so on and this is what I want us to use right here uh when upload has completed we will be able to get the download URL uh from Firebase and then that download URL is the one that we save on our mongod DB
        

so we will uh be working on a code like this it will look similar to this we will get the storage Storage R we'll get appro task um and then we will have this uh upload task. on then we will have uh upload progress eror and when it's done we'll get that URL and we'll use that URL to save the image information to our own database okay let's try this and see how it goes
        

so to begin with set loading to true and then we will create a variable we will say let uh uploaded images be equal to an empty array and the type for this one will be uploaded image type and this will be an array of that okay
        

so it will be an array of strings
        

so once we upload the image successfully we will be able to update uh this particular array uh make sense and then now down here let's perform a check on categories
        

so if we don't have data do category uh let's go ahead and uh throw an error here or return an error
        

so we will set loading to false because we are no longer uh creating the product because we have this error and then right here we can immediately return
        

so it won't execute the code below toast do error and right here we will have now the error and we can say category uh is not selected
        

so we don't want to have a product that don't have a category
        

so let's bring that in and then we will do the same for images
        

so if we don't have any image then we draw an error
        

so here we'll say if we don't have data do images and we can say all if data do images and then here do length um is zero we don't have even one image then we return we must have at least one product image
        

so we set is loading to false and we immediately return here
        

so we return toast. error and we can say that no selected image okay now after that we come right here and we will create a function we can say const handle image uploads this will be an async function and we can set it to Be an Arrow function just like this and um at this point we can let the user know that we are creating the product because uploading images especially if they are big ones it might take uh
        

sometime
        

so we can say creating uh product
        

so we toast that now in here we have to uplo uh each image at a time remember we have multiple images let's first have a try and catch block then we start with try here and we need to Loop over all the images
        

so that we upload each at a time
        

so here you'll say for const item off then we'll have data do images
        

so we get an item each time we'll say if item uh do image remember this data do images uh each image has color color code and image
        

so we get the image if we have that image then we'll go ahead and start now working with Firebase right here and uh we can get the file name and we want the file name to be unique therefore we'll say this const our file name will be equal to and we construct a new date
        

so new date we invoke that and we get the time get time we invoke that we conate strings or join them we can use a hyphen and right here now we include the actual name of the image item do image do name uh
        

so why do we do this
        

sometimes a per
        

son might have images with the same names
        

so we don't want the names to CDE at fireb storage therefore we add this to make the name unique okay
        

so we get the file name like that and then here we get the Firebase storage
        

so we'll do this by saying storage uh is equals to get storage and right here we pass our Firebase up
        

so this get storage should come from uh Firebase but it's not being suggested
        

so let's just import it manually cuz uh why not I can just say import and we will destructure
        

something from then we'll have Firebase stroke uh storage and what are we getting from here get storage
        

so we get the Firebase storage then uh let's go back right here I'll get a storage reference
        

so I'll say con storage ref will be equal to we use a ref uh function from Firebase storage now that is auto imported make sure yours is imported too and we pass the storage uh comma and then right here we pass the path that we want our uh product to be saved it
        

so we we want it to be inside the products folder
        

so right here let's use back ticks
        

so that we can uh later on read a variable in here
        

so we'll have products
        

so this is the um path that will be at our Firebase storage
        

so we will have a folder called products and then inside that folder we will be creating a new file uh with the file name
        

so here we pass the file name
        

so file name uh just like that now we have the storage ref for uh that particular file now right here we'll say const we will get an object called upload task and we'll set this to be equal to uh upload uh byes resumable and then we invoke that and we pass our storage ref like that and then we include a comma there and we'll say item uh dot image okay
        

so we'll create a promise and I'll say await a new promise like this and we'll say here it's a void we invoke and we pass an arrow function just like this and here we will have re
        

solve and reject
        

so when appro is successful we will call re
        

solve when we have an error we will call reject and we won't proceed to creating the product because there was issues while creating the images okay
        

so here now let's do this we will now use upload task this logic is actually at our docks here we want to have
        

something like this load task. on state changed then we will have a snapshot and we will track the progress if we have an error we show the error if it's successful we will be able to get the image URL
        

so that's basically it that's what we are doing here now
        

so upload Doon and then we invoke this one uh the first parameter here is State changed and right here uh snapshot and here we pass an arrow function and we can be able to track the progress using this snapshot actually I'll just copy this code here I'll copy that and I can paste it here
        

so here we have this const progress and you are seeing snapshot uh byes transferred stroke snapshot uh. byes then we get the percentage then this will log the percentage of the upload on our con
        

sole uh uh snapshot. State uh if it's post if AO is post you can do
        

something there if it's running you can do
        

something there then after this snapshot we will have uh a part where we have the error and that is basically this one here
        

so I can copy that and paste it here and if we have an error we want to do
        

something right here
        

so for unsuccessful uads we want to reject
        

so we want to reject the promise
        

so we'll say reject then we pass the error there and then right here uh we can say con
        

sole uh do Rog and we'll say error uploading image and right here we pass the actual error
        

so you can see that on the con
        

sole the last part is this one right here where now if it's successful uh we handle successful uploads
        

so here I'll just copy this one and and I'll make use of it here
        

so I think we should bring this in
        

so we import it from Firebase storage and here we'll be able to get the URL let me just remove this message there when it's successful we want to re
        

solve
        

so we call re
        

solve and and then right here we want to uh update our array right here right here
        

so we update our uploaded images uh array uh right here uh we will have now uh Ed images
        

so we'll say push because it's an array and what do we push here
        

so we will push an object and we spread the existing item
        

so this is the current uh item which has the color the color code and the image but we will change the value of the image now to be a string and the string will be now our download URL and this URL is simply a link to our uploaded image okay
        

so we do that we can log this to the con
        

sole we re
        

solve uh you can see here we are tapping at do then
        

so after this do then we can al
        

so tap do catch we will have the error here we can reject
        

so we'll call reject and we pass the error here uh we can log
        

something to the con
        

sole error getting the download URL
        

so this is how we are getting the download URL okay I hope all this uh method here makes sense
        

so that is our method and al
        

so we have these uh promise that we are creating
        

so yeah that's basically it we had this try right here that will'll try to upload the images
        

so we al
        

so have the catch right here
        

so let's complete this cut right here we can set is roading here to false and right here we will con
        

sole Rog uh we can say error handing image approachs and right here we have the error Co now right here we can al
        

so return and we will toast a message toast. error we can say and error card uh actually you can just say error huning image approach as well
        

so just like that and now we have completed this particular function from the very top this handle image appro okay
        

so we tost this to let the users know that this will take time then we try if it fails we catch down here and then right here we Loop over each of the images and if we have the image then we go ahead and get all these functions from uh Firebase and
        

some we create like the file name for uniqueness and here we create a new promise
        

so that uh everything else uh Waits uh for this to complete and we have this approv task. on and it will check when the state is changed when it's in progress when it's post and
        

so on if you want to know or to have a load out or
        

something like that you can make use of this if you have an error then we reject the promise if it's successful we accept the Promise by calling re
        

solve but al
        

so we update our array of uploaded images now all we need to do is to call this particular function and then test it
        

so after this function below here uh still within our on submit function I know these brackets might be confusing that's why I'm trying to be just um clear here uh we will await now we will call await our handle image uploads and we call that one and now here if it's successful we will be able to have our uploaded images and therefore here let's have product data to be equal to we spread the existing data but we update our images to be our uploaded images
        

so uploaded images like that now right here we can just rug these product data to the con
        

sole and see if it works
        

so we'll say con
        

sole uh. Rog of our product data I save and now we can test and check the product data and al
        

so see if the image is uploaded
        

so back here uh let's go to our app let's call a refresh there now I'll come to storage here and see if the images that we upload will be added right here
        

so there is no fire right now okay
        

so here let's create a dummy product watch price of this watch is $100 uh brand I don't know Brands uh any description any description it's in stock we want to have a watch and let's upload a white watch
        

so we click on the bner image it's just for testing all this nothing serious now we should pay close attention to the con
        

sole when I click add product add product creating product PR weight and you can see appro 0% done uh appro is 22% done 66% 98% 100% done uh upo is running and then here we get the product data at the end of it all and al
        

so we get this file available at uh this particular storage and if I visit this storage or if I visit this link open in a new tab we get to that particular image and there it is
        

so I think it was successfully uploaded if we check our product data you'll see we have images and array and if I expand we have the color as white the color code and al
        

so we have the image link and this product data is now what we will save in our own DB
        

so now if you go to storage here let's refresh the page I guess
        

so let's refresh here we should have uh the product added here there we go we have products and when we click on this one uh we will have one image and it's our own image and you can see here we have this Tim stamp then Banner hyphen image uh because we added this Tim stamp using the date now it's Unique right there
        

so this is awe
        

some because we are able to upload images and update our product data now all we need to do is to call axios and call our own backend API in order to save this product data in our own mongodb database and that is pretty easy we just need to say here axio dopost and we invoke that we need to pass the end point stroke API and then stroke product then right here we pass our product data and now we can tap the do then method and we invoke like that now here we will toast a message toast uh do success the product was created and then right here we will say uh set is product created and we'll set this one to True when it's true it will create the form State awe
        

some and then right here we can call router do refresh and we invoke that now uh we don't have this router
        

so I'll come at the top here we should create it we just say const router uh will be equal to use router from next navigation we invoke that and let this be at the top there awe
        

some back to our axus call here we refresh and uh we can al
        

so call the dot catch method
        

so here do catch then here we'll have our error and we can do
        

something with it right here
        

so we will toast an error toast do error uh we'll say
        

something went wrong okay now right here we can have do finary and we can set is roading to false
        

so here let's call this and we set is roading to false I save
        

so we can test it out and see if our mongod DB saving Works TV uh price $1,000 LG LG desk that one then TV let's say this is now a great image we select the image we add it there then we add loading creating product bre weight it's there it's running it's running and uh fire available at that uh still loading and product created awe
        

some
        

so that means that now we have that product in our mongod DB and let's go to mongod DB and check
        

so here mongod DB another thing that we should do is to test whether it's uploading multiple images
        

so let's create another product for Price $1,000 iPhone iPhone 14 it's a phone let's upload a white image uh white image we can just select glare and have the glare One open
        

so we want to see if it will be able to upload the two images
        

so let's upload and uh fire uploaded it completed the first one then it started the second one and finished
        

so it's working this is awe
        

some
        

so now if we go to mongod DB here if we click on products here um you'll see we have the TV LG images object and it has a Firebase URL awe
        

some and then we have this phone iPhone the one that we added now then here we have two of them this one and this one very cool now this is working well and if we go to our Firebase storage now we should have four Images
        

so let's refresh there and let's see look we have four Images we have this iPhone 14 white iPhone 14 gray you have the banner image and the banner image
        

so this is all working well and uh that is how we can handle image approachs and how we can create our product okay now I want us to work on our reach data tables
        

so we will work on manage products uh and al
        

so we will work on manage orders okay um to begin with we need to be able to get our products from the database and al
        

so to be able to get our orders from the database
        

so we will create
        

some helper functions that will help us do that
        

so in our our code we need to go to actions
        

so here we'll say get products dots and for this get product uh we will al
        

so make use of it at our home because we will use it to get our product remember we were using a dami array for all these products right here
        

so we need to be able to get the products and uh we will al
        

so be able to filter them uh depending on the category that we will be selecting here
        

so we need to consider that uh while creating our function
        

so let's move on here the first thing is to import Prisma now here we will export an interface right here we'll call it I product uh param and here we will pass category and it will be optional string and it can al
        

so be null we'll have a search term which is optional string it can al
        

so be null now down here let's export a default sync function called get products and we will be receiving a parameter
        

so we'll say params here and here they will be of type i product params and then we come in here
        

so let's try and catch this one
        

so try catch if we have an error we will we'll simply throw an error
        

so we'll say throw a new error to be error error can be of type any and then we come in here now we will get the category and the search term from our params
        

so we say const we destructure the category and al
        

so search term and all this will come from params uh this is complaining because we we need to include an a right there we can say let search string be equal to our search term
        

so here we'll check if we have the search term and we'll say if the search term is empty
        

so if we don't have uh the search term here we'll set the search string uh to be an empty string okay and then right here we will create a variable called let query initially this will be just an empty object and it can be of type any and if we have a category we will update our query object
        

so here we'll say if we have a category we will come right here and we will set query do category to be category our query object will no longer be empty it will be having uh a category in it
        

so down here this is how you can get uh the products we'll say const products will be equal to uh we await Prisma uh do product uh do find many we invoke that we pass an object and here we will say where we spread our query object and then right here we pass or we pass an array we include the logic for the search
        

so we will check the name when uh doing the search and right here we'll say if the name will contain the search string and the mode will be insensitive
        

so whether you include with Caps or um small letters will still get uh that particular product then we'll al
        

so want to check our description
        

so description and we'll have the same same properties right here if the desp description contain the search string and insensitive cool now after H right here we'll include a comma and we'll say include when getting the product let us al
        

so include the reviews for this product
        

so include reviews and for the reviews let's include the user because we want to know the user who created that review
        

so user true and al
        

so we can order by right here order by we would say created date descending before now our error before we get out of this block let's return our product just like that okay
        

so we have written the logic for both the search and query and we are getting the product depending on whether we have the query and al
        

so whether we have the sear string awe
        

some now that is for the products uh let's create another one here for the orders I'll add a new file and we'll say get orders dots we will start by bringing in Prisma
        

so import Prisma from uh at Libs and then Prisma DB we will export a default a sync function called get orders we invoke it and do
        

something right here we try and catch um we'll have const orders uh to be equal to we await we'll say Prisma uh do order. find many we invoke that and we pass an object and we'll say include the user
        

so user will be true we will say order by and we can say created date descending desk and we simply return it
        

so here return orders pretty easy right I save that function I can cross these files minimize everything you can go to app admin then we go to manage products right here let's create a new file and we can call it manage products client you can include client or not
        

so TSX stess functional component manage products or client and then at the very top let's make sure to include use client like that here let us return a div manage products I save that file for now then go to page here and from here instead of these we will return our component here now in this particular file is where we will get our uh products
        

so let's say const product will be equal to and we simply await get product we get it from there and we should invoke it and remember we should pass category here and we'll set it to null now right here we'll have a sync
        

so that these are it doesn't throw an error al
        

so we can get our user current user will be equal to await and we'll call our get current user and we invoke that right here we can check whether we have a user
        

so I can just go to add product then page and then I'll copy this logic copy come here and I'll paste it here we import this null data component and there we go
        

so for this product we'll pass it as a plop to manage product client
        

so uh products uh will be equal to and right here we pass our product and that is all we need to do at this file for the page
        

so let's go to manage products client this is throwing an error because we haven't defined an interface
        

so right here let's add an interface and we'll say manage products uh client props and in here products the type will be product from Prisma and right here we make sure that it's an array
        

so I go ahead and save let's include a full column and it will say react FC and we pass our manage uh product current props right here let's destructure that
        

so products okay
        

so we have created our default skeleton now we need to create our data table right here for us to move first and create a very nice data table uh we will make use of material UI
        

so if you go to the browser search for material UI I want us to make use of this particular library to create our our data tables
        

so if you go to docs we can click on material UI here and we have installation we need to run this command to install everything I'll click on that uh pop the T using control J or command J and then right here I'll go on this one and paste
        

so I'll install all these at mui material at emotion stroke react at emotion stroke styled and hit enter as this installs uh we can come back here we can search for data table right here or search for table if you search for table we get this and look we have the basic table you scroll down we have this now data table uh I think this is what we want and this is a very rich data tables because you can do a bunch of stuff you are able to filter you are able to select here
        

sort ascending and
        

sort we are able to manage columns hide
        

some of them and show
        

some of them uh let me show you and
        

so on look we can hide the ID column right there you can show it and this is really cool
        

so this is what we will use
        

so we already have the code right here on how we can do it
        

so just copy this code and then I come back right here and I'll paste that code right [Music] here
        

so let's go ahead and import this
        

so I'll say import I'll destructure data grid uh these will come from X hyphen data hyphen grid uh
        

so the thing is we al
        

so need to install this at mux data grid
        

so just copy that and I'll say npm I and I paste that I don't know why it shows at the bottom here but if I hit enter it will still install
        

so install at mui stroke X hyphen data hyphen grid and that should get rid of this error
        

so once it completes you can see uh that error has disappeared
        

so now the error that we have is for the rows and columns
        

so first of all I'll save to Auto format that file and then we can work on these two
        

so before our return statement we will check if we have the products
        

so we'll say if we have the products we will go ahead and do
        

something right here let's create a variable for our rows
        

so I'll say let rows of type any be equal to an empty array
        

so initially rows will be an empty array and then right here we can update our rows if we have the products
        

so we'll say our rows will be equal to products dot uh map we invoke this here we will get a product at a time and we can return
        

something right here we will return an object the object will have an ID the ID will be our product. ID then we will be having a name product. name we will be having price product. price and actually we should format the price
        

so we had a util for format price we can call it right here
        

so format uh price we import it and and we pass this product do price in there next uh will be category product do category next we will have the brand let's have product do brand and then right here in stock we'll have product do in stock images and we'll have product do images like that really
        

so I save to Auto format for each of the row we'll be having an ID a name a price category a brand an in stock and an image the next step is to add the columns
        

so after this if statement right here I'll say const columns will be Creed call def this will come from our mux data grid
        

so bring in that one
        

so Columns of type this one and it will be an array will be equal to an array
        

so to begin with we will be starting with the ID
        

so we'll say field is ID header name will be ID in caps we can specify the width and the width here will be 220 after that we'll be having the name okay here we should be having a comma and this field should be the same as the ones that you included here the properties that you included here are the keys
        

so field ID should be same as this one name should be the same as this one
        

so that under this field we'll be showing that particular product name okay or under this column we show that particular product name under this column we show that particular product ID and
        

so on
        

so we'll have the columns for each of these properties okay
        

so down here the width will be 100 I want us to add
        

something different right here and that is because we want to include
        

some styles to our price
        

so if I check the complete one right here we want the price here under it to be bold and for us to add the Styles we need to uh use
        

some T CSS for this particular uh column
        

so this is the column here
        

so what we can do is to add property here called render cell and we will be having an AR function just like this right here we'll be able to receive params and then right here we can be able to return We invoke that and we can pass a div in here now to show the actual data let's use car brackets and we will use params here dot row then dot price
        

so we get the price like that and now we are able to add
        

some styles for this one
        

so we can add a class name and we can say font hyphen bold and then text straight we will say 800
        

so that is for price we get these we include this render cell
        

so that we can display a custom styled data there
        

so let me copy this one here and we will have category after that
        

so contrl V and we'll al
        

so Al have brand
        

so let's do this this will be category this will be category let's say 100 header name will be uh brand the width 100 uh the next one it's whether a product is in stock or not I can just duplicate that as well here we will have in stock header name in stock and the width here can be 100 or maybe about 120 and we will al
        

so call render sell
        

so let me copy this one from here
        

so I copy that one and here now we'll have a comma and paste that render sell let me first save out of format and right here we will show ad devs but for the content we will check ps. doino and if this one is true we'll be able to return
        

something right here we can say in stock else we'll say out of stock okay for now let's have that we'll come back and style it nicely now lastly we'll have another field for our actions right here
        

so for this one we'll say it's action actions uh width can be 200 and uh al
        

so we'll have render cell
        

so let's copy this one and use it here paste this is render let me save Auto format and for this render cell uh for now let's just remove this and we can say action here
        

so this is where we can have d a product and
        

so on
        

so we'll come back to it al
        

so we can remove this class name from there as well as from here and I save uh
        

so right now we should be able to have
        

something and then maybe we can make it better okay let's go on admin dashboard manage products and we get get an error when trying to get the product
        

so here you can see unknown argument contain did you mean contains
        

so let's check that okay this is contains this is contains let's save hit a refresh and look we have a table with our current products that are in our database which is really cool and you can see under price these are in bold we can filter and we can hide columns for example let's hide uh price we can show we can show all
        

so this is really cool
        

so we just need to make this look like this one
        

so we'll add
        

some actions like these ones for in stock will show
        

something like this and we can be able to switch whether the product is in stock or not like that uh really cool and then we al
        

so decrease its size
        

so that it fits nicely uh starting with our data grid you can control the page size using these options
        

so if you want to show uh up to 20 products you can do that and if you want for them to be more right here by default uh you can do that and then right here you can set a page size of nine refresh uh look we have row per page is nine and we can go up to 20 and then let's add a header
        

so I'll add a div and I'll include the heading component from our app component right here we'll have the title as manage products and then we can Center everything here okay that is good let's add a class name here
        

so we'll have class name and margin to the bottom will be four and then right here margin to the top will be eight let's wrap this data grid with a div
        

so right here say div and our data grid will go in there saved Auto format and then right here actually I'll add an inline style here we'll set the height uh to be 600 and then here we'll set the with uh to be 100% like that for this parent div let's add a class name we will say Max hyphen width
        

so the maximum width for this data table will go up to um 11even 50 PX then here we'll say margin AO and text will be XL I go ahead and save
        

so let's check it out we have a maximum width and al
        

so uh we have a height for the data table up to this point that will occupy up to nine items
        

so now for us to show this status we will create a new component um that we can reuse let me go to app components and I can create it at the root here I'll say status. DSX status functional component and we'll say status interface status props we will be receiving the text whether it's in stock or out of stock
        

so this will be a string we'll be receiving an icon of type icon type from react icons this one okay cool and then we'll be receiving the background color for these particular status
        

so I'll do it like that and al
        

so I'll be receiving the color and I'll do it like that here let's make sure that these knows of our uh interface
        

so react. FC and right here we pass the uh status props let's come here and destructure uh the text let's al
        

so destructure the icon and we set these are to Icon let's al
        

so have the BG and the color we will return a div and in here we'll have the text and at the end here we will show the icon which can have a prop of size
        

so let's have size here we set this to 15 for this div let's add a cross name
        

so right here um we can read the BG using the money sign then car brackets BG we can al
        

so read the Cara in the same way then we'll add
        

some few more Styles uh padding along the xaxis will be one then it will be rounded then we'll Flex the items items will go to the center and uh let's have a gap of one and that's all for this particular component I saved AO format and let's make use of it now at our manage products
        

so right here where we had in stock and out of stock uh instead of that we will return the status component
        

so status from our app component
        

so I import it and right here it expects us to pass the text will be in stock they al
        

so want us to have the icon and for this one we'll use MD done from react icon
        

so click on it to Auto Import and then the BG uh will say BG till 200 and the color here will be text text till 700 I save to Auto format we'll have a similar one
        

so I'll copy that one paste it here and whatever we will do is change this to be out of stock then these will be MD close make sure to import it then this one will be Rose instead of tier
        

so contrl d [Music] row and that's it
        

so let's save and see if it came along look in stock this one didn't work out well
        

so okay there we go
        

so it has updated
        

so we have in stock and out of stock let's work on our actions
        

so for actions we'll create a new component at our components
        

so I can minimize everything up components and we add a new file we can call this one action BTN do TSX we'll al
        

so be having an interface for this one
        

so let's add an interface of action BTN props and right here we'll have an icon of Icon type from react icons and then we'll have onclick these will be having an event of type react uh do mouse event HTML button element and it will return void okay um this one should not be there but here and we return void we'll al
        

so have disabled Boolean optional like that sfc and we'll say action BTN we will receive those props first of all let's let's pass our interface here action BTN props then here we'll have icon which can be icon we'll be having on click we'll be having disabled we will be returning a button um the text all the content will be our icon
        

so we'll only be having an icon with a size of um 18 and then right here I cross it like that and I save now for this button um I'll add a class name we will FX items will be at the center justify will be Center it will be rounded we'll have Cura as pointer width will be 40px height will be 30px text will be straight 700 will be having a border straight 400 We'll add disabled we can say the end end we'll have an opacity of 50 CA not allowed
        

so that is the button but uh we still need to add an on click here on click will be on click and then disabled will be disabled and I save that is our action BTN let's make use of it right here
        

so here is where we had action and we had this div here
        

so here for this div we'll have a class name we will Flex We justify between then we'll have a gap of four and width will be full right here we will have our action BTN let's pass an icon we will say MD cached it expects us to have an on click let's just pass this like that and I can duplicate it two more times for this one will have a different icon MD D
        

so make sure to import it and for this one MD remove for view
        

so let's see how it looks like and look we have our actions we have this we have this awe
        

some looks much better now when I click on any of these button you can see it's selecting the check box
        

so what you can do down here
        

so disable row uh selection on click that one add that property
        

so that when I click on this it stop checking the check box awe
        

some
        

so now we need to add functionality for this Togo for this dedit and a router to take the user to that product before our return statement we will create a new function
        

so con handle uh toggle stock this will be equal to use call back and we invoke it we pass an arrow function here and al
        

so it expects us to have a dependency array
        

so for this one we will receive the ID of the product
        

so the ID will be a string al
        

so we will receive in stock this will be buan and in here we will make a call an axus call
        

so here we'll say axus and then we will use dop put because we want to update
        

some re
        

source in our database then we invoke that we pass the end point it will be at stroke API and then stroke product that is the first parameter the second parameter is this object we'll pass the ID and we will pass in stock we will negate in stock because we are doing a tog
        

so if it was true then it will be false now if it was false then it will be true we will tap a do then method and we will have a response uh we can do a toast toast. success invoke these and we'll say product status changed I'll al
        

so say router uh do refresh we don't have this router
        

so let's create it it's easy we can say const router will be equal to use router from navigation next navigation and we invoke it let me save to Auto format let's come back to our function here we catch the error
        

so here dot catch we invoke that we will have our error there now right here we can toast an error
        

so toast. error
        

something uh went wrong we can con
        

sole do shock the error and I save for this one we'll have now handle a too stock we will pass the first parameter which will come from params row. ID and then a comma then the second parameter is par do row do instock like that
        

so I save right now it will not work because uh we don't have this particular API
        

so let's create it at app API product we already had this route and for this one we were doing a post request and we want to have one for put request we will add a new function
        

so we will export uh a L function we'll say put then right here we will have a request of type request and in here we get the current user
        

so we can copy this one al
        

so we can make sure that we have this
        

so I'll copy those paste them there then right here we will get whatever is in our body
        

so con body will be equal to a wait request. J
        

son and we destructure our properties from the body
        

so const ID here in stock and we set this to be equal to body now use the ID and in stock to update our product uh state
        

so const product uh would be equal to a weight and then here we'll say Prisma then dot uh product then dot update we invoke this and right here we pass where and full colum we say ID here is ID then we'll have data and we pass in stock then we return the product
        

so I save and there we go
        

so we have that functionality now and we hit this end point by saying Aus dop put from our manage products right here dop put API stroke product and we pass the necessary uh body properties now let's test it
        

so here um this is in stock this is out of stock let's toggle this one and product stus changed and these updates okay you can al
        

so add a loading spinner maybe you can make this to you know uh load
        

something like that
        

so that we know that the process is in progress but I don't want to waste
        

so much time on it
        

so let's move on to theit
        

so theit will al
        

so need to create its own API route and al
        

so make a call to that API
        

so here I'll say con handle d and we'll set this to use call back again we invoke that we pass an arrow function here we al
        

so pass a dependency array we will simply receive the ID it will be a string and then we will have images of any array we can start by adding a toast uh delting product please we because it might take a while we are delting re
        

source from two places one Firebase storage and the other one from our own database
        

so we will start by deleting the image once it completes we will go on to deleting the product let's have const handle image dedit and we set this to an a sync function and we invoke that and then right here we try and catch
        

so try catch block if we have a catch then we will return con
        

sole. Rog of dirting image error and we pass the error here and then right here we'll go through the images
        

so we'll say const item of images we get an item at a time or each image at at time and if the item has the image property let's go ahead and delete that image we get the image reference
        

so const image uh ref will be equal to ref and this is from Firebase storage we pass the storage from Firebase storage again we will import it manually okay then here we pass the item. image this is the URL to that image
        

so let's import this image storage actually we would import it directly we need to say here con storage is equal to get storage now this is what we want from Firebase storage and we invoke that
        

so I come back down here here this is not eror but error
        

so I save first to Auto format this should be an aror function here
        

so I save now and it's formatted we'll have the ID awe
        

some
        

so now we have this dat here and first of all we handle image D here we get the refence to our Firebase image and then we await we call the uh object from Firebase storage we invoke it and we pass our image ref then here we can al
        

so log
        

something con
        

sole Rog of image deleted just to know we deleted it and right here we pass item do image okay now after this function right here we await it
        

so we say um await handle image D and we invoke it and then we make this to be an async function
        

so here let's add a sync
        

so that it doesn't throw an error and then now once we delete the images we we go ahead and delete the product from our database
        

so right here we'll have axos then do dedit I'll make use of btic to create this string and we'll have stroke API then we'll have stroke product then here you'll have stroke and I pass ID here
        

so the ID will be in our URL we will say dot then okay we invoke it uh actually it will be similar to our DOT then here
        

so we'll have a response and a toast
        

so I can copy that and include it here and um the toast can say product deleted uh router. refresh I save to Auto format there after do then we can have al
        

so uht catch and I invoke that here we will pass the error and we can return
        

something from that and I save
        

so now we have this helper function handle delete that will help us to delete a product we delete images then we delete from our own database
        

so let's make use of this handle the right here
        

so I'll say handle the we invoke it we pass params do row. ID then comma we pass params again do row do images I save we don't have the API route for delete this one we don't have this
        

so let's create it inside the app API product
        

so inside the product we will create this part id id part okay and it is dynamic
        

so we add a new folder and just use these square brackets and pass the ID there and then inside there we create a new file called route. DS we hit enter
        

so let's delete the product from the mongodb database here and here we just need to export and we'll say a sync function we say D um we invoke it and right here we'll have request of type uh request uh we include a comma right here we will al
        

so destructure params the params will be of type params which is an object having the ID of string and then here we do
        

something we'll have the user
        

so con Uh current user will be equal to we await get current user we invoke it we shall check if this user is an admin uh next response. error we import it from next ser and I saved to format now down here ID will be available in our params ID
        

so we can just go ahead and direct this product using the ID
        

so you can say const product will be equal to a we Prisma dot product then dot uh dedit then we pass H here and we will say here ID is params do ID just that down here we return um next response uh do J
        

son then we pass our product
        

so I go ahead and save pretty nice and look we have an error we should pass our Firebase up right here
        

so Firebase up
        

so I save now and let refresh
        

so there we go we have our products and we want test the functionality of delit
        

so let's open the con
        

sole as well
        

so that we can catch the errors as they come
        

so let's try to D TV
        

so I'll click on dedit dting product pres image deded awe
        

some uh product DED and it gets out of our list
        

so the functionality of the is working well awe
        

some let's finally complete this by working on our eye there
        

so that should be easy we don't have any functions or apis that we are creating it's just a redirect to a different page
        

so we use router. push and we invoke that al
        

so we use btics we'll say that we are going to our product then stroke here and we we use this and that and we'll say here parms do row. ID just that I save
        

so right now we might not get the product because our products from the uh product page are not the same from the database
        

so we haven't put them in sync but let's see what happens if we click it
        

so I click and the URL here should change our product then this is the product but we get 44
        

so we'll fix that uh as we move uh next let's work on manage orders
        

so for manage orders it will be easy because uh we will just be copying what we did on our manage products
        

so at our code here I'll copy everything at manage products client contrl a copy then we go to manage orders here then create a new file and we can call it manage orders client. TSX and I hit enter now from here we can just paste everything and we will change manage products C use contrl D to select even at the very top uh control D again to select this one and this one and after all of them you can change this to manage orders and once I come to the very top this is now manage UST client plops manage UST client and
        

so on uh
        

so we should hook this up to our page we can come to um manage products page this one and copy everything from here then go to manage orders page and replace here we can change this name here to manage orders and I save
        

so here instead of products we should be getting orders we'll have our orders and we should await get orders from here
        

so get orders and we don't have any category for orders
        

so I remove that one let's import this one
        

so I'll click on that to to import and remove this one get products from there we get our current user and we check if Uh current users there and whether they are admins or not then here we should pass our orders right here
        

so here I'll pass orders and then right here we should have orders
        

so this component doesn't know about the ERS prop
        

so we should go to our manage orders client and we should create an ERS plop
        

so here we'll have ers and type extended order we don't have it yet
        

so we can create it down here and we'll say type extended order will be equal to our order type from Prisma client and here we'll say and we include an object and will set user to user
        

so we should al
        

so bring this from Prisma client and and now we have our type like that
        

so here we will be bringing in our orders
        

so let's have that orders
        

so here we'll have the router we won't have the storage since we are no longer working with images we will still have our rows then here we should create our rows Now using our orders and we'll have orders here and we get an order at a time and I can just highlight this use contrl D to select these these these all of these and we'll say order
        

so order doesn't have have
        

some of these properties
        

so we should go one by one changing them here instead of a name we can have the customer instead of saying price we will say amount and the amount will be uh format price order do amount we divide by 100 since we changed this by multiplying by 100 uh when processing stripe payments now for this one it will be order. user.name and here we can have payment status it will be order do status um we can have a date we can use moment for the date
        

so we'll say moment we import it from moment we invoke this we pass order dot created date and then right here you'll say um from now and you invoke that um we can al
        

so have the deriva status here
        

so deriv status and we set this to order uh do deriv status that's the last one
        

so we remove the image since we don't have images in our order now we come to the columns uh the first one will be id id 220 second one will be customer here
        

so we remove that we say customer the header name will be customer name
        

so customer name we can set the width to one uh 30 then we come here instead of price we can say amount you can al
        

so use price if you want then this can be amount in USD amount then with um can be 130 renter sell here uh we'll still have font bold text straight 800 then uh prms do. [Music] amount this can be payment status and this one will be payment space status 130 uh then after that um we won't have the brand
        

so I remove that uh next we will have deriv status and we can have the header name as uh deriv uh status here it will be 130 and we will have this render cell we will have a div then we'll check params do row. deriv status we'll check if the status is pending
        

so if this is pending if it's pending we show this status and we'll say the text here is pending uh the icon we can say MD access time then fi like that the BG will be uh straight 200 color will be text straight 700 um we come down here else we check the deriver status again here
        

so we will copy this one copy we paste it there then we include another uh question mark there if this one is dispatched then we will show a status like this one we will say dispatched then here we will have a MD deriv dining then this one will be purple and this one will be purple
        

so I select both and I say purple after this before we have the Cur brackets we include a full column we can perform another check if the derivative status is deriva
        

so here we say if this is now derived we include a question mark we will to these
        

something like this
        

so I paste there else at the end here full colum we can show null or have empty fragments like that
        

so this one is for the case when it's deriv
        

so we say der then this one will be MD done the colors will be green showing success
        

so green
        

so I save and um this is for derivery status for payment status we should al
        

so have
        

some render sales or rather we can just duplicate this section let's duplicate it use alt shift top Arrow then we remove this one uh let's copy the payment status here copy there and we paste here you copy here and you paste here um let's copy this one again because we will use it here
        

so I use contr D to remove this three deriv status and paste okay now remove this field and let's customize this one further um the first one we will check whether the payment status is pending then we will show this that is okay then next one we'll check if the payment status is marked as complete if it's
        

so then we will say here completed we will have a different icon MD done we won't have these one here from this full column to this full column I'll remove that part okay actually I should include a full column there
        

so I save we have the if none of these matches one should be there at least though okay
        

so just a l up we have ID customer amount payment status we have now a delivery status uh which has this render sell and then action
        

so before we go to action we should be having a date here and after that we have now the action the stating is the same here then we'll have this action BTN the icon will be MD deriv dining
        

so this will be for marking an order as dispatched then here we will have handle dispatch we'll just pass the row ID
        

so I remove this part we'll have one for MD done for Maring an order is deriv
        

so MD done this will be handle deriva then we al
        

so pass the ID
        

so I remove that section right there Then here we have the last one which will have the I and it will take us to stroke order uh stroke that one now let's create these two functions we will remove 100 it
        

so we remove the entire of this part 100 it then for this one we we can call it handle dispatch we will have use call back which will receive just the ID
        

so we remove this in stock we'll call aios then we'll put at API stroke order then we'll have the ID and we will Mark here derivery status we will mark it as dispatched then here we toast order dispatched
        

so this is it for Hing the dispatch for deriva it will be similar
        

so we just this function and down here we can just paste it
        

so handle deliver we will receive the ID we hit this API end point then we will Mark the order as derived then here Order derived for
        

something that went wrong cool
        

so we move on down here to this table here we'll just say manage orders we'll have our data grid rows I think everything else will be the same and I save that file
        

so we have created our table and we can check it out and see if it works
        

so let's remove
        

some of these unused inputs just like [Music] that I save okay we have more here let's just remove [Music] and save okay
        

so let's see look we already have this but for completed here it should not be this color
        

so that is one thing um we don't have the deriva status showing here
        

so let's check them out we check if uh the payment status is complete we use now here a green color instead of purple
        

so that is the fix for that
        

so contr D and I say uh green I save
        

so it changes to green and that's good now
        

so we should be seeing the deriva status we see none
        

so we must have made a mess now maybe our rows change this to deriv status here save that should fix it let's see and there we go
        

so they are pending awe
        

some let's work on this action button
        

so that we see if these will change
        

so we actually worked on them and included the functions the only thing that we are missing is this API uh endpoint
        

so we should create that uh you can minimize everything go up then API here we had product and we created an end point to update our product
        

so let's copy whatever is in our product copy of that then inside the API here we'll create a new folder and we will call it order inside the order we create a new file and we can call it route uh. TS we paste whatever we have in our products we don't need to post
        

so I remove this post function okay then here current user we await the current user if we have an issue with the user we return the error then here the body we will get only the ID and the uh deriv status
        

so here you get the deriv uh status from the body then here we will have the product
        

so control D for all three product there and replace with order
        

so we AIT Prisma order. update date where ID is ID and we change the uh data here we will only pass the deriv status
        

so we pass the deriv status and that's it that's it
        

so I save now we have our API endpoint or rather we are hitting that API endpoint and we can see if it works
        

so here we mark an order as dispatched by clicking this one and Order dispatched and the state changed to dispatched here we click on this one under dispatched although the payment is pending uh then you can click on this one order derived and for order derived we see nothing meaning that we have an issue
        

so we come back here let me copy this one I think this paing is wrong is it yes I save
        

so that's the only issue and it should show here as derived um
        

so it's still not showing because we already have the previous wrong data saved
        

so let's click it again and it should Mark it as deriv and you should see it now yeah there we go uh that is awe
        

some now this ey I think it takes us to the order details when I click on it that page does not exist
        

so we should be working on that particular page next uh
        

so now let's just create that order page for now I'll cross everything there and we can go to up um then from up we'll create a new folder for our single order
        

so here we will say order and for this order we will create another folder that will have the square brackets and here we will be passing the order ID
        

so we'll be using this ID to get a single order and this ID will be uh gotten from our URL
        

so inside this order ID I'll create a new file and I can call it page do DSX status functional component uh actually I think I'll take the one that we have at our page here let's copy everything then inside here we will paste and we can just change the name of the component to order
        

so we have a lot of product there what should we do go one by one or change out of them I'll just changer of them to order but
        

some should be Capital like these should be a component
        

so we should be having order details then that should be coming from here Order details from order [Music] details uh what else should be Capital this [Music] one this here uh is here um we don't have this
        

so let's remove that one we won't do this
        

so let's remove this one let's remove the params ah let's create this order details component
        

so here I'll add a new file called order details. TSX status functional component and I'll say order details we return empty fragments and then we should be able to get our order
        

somehow we will use uh our actions folder right here create a new file and we'll call this one get order by ID we will import U Prisma from at uh stroke ribs stroke Prisma DB we will create an interface I params and here we will create an order ID which will be optional and we'll have it as a string we create export uh default we'll say a sync function uh we call it get order by ID we invoke it and we'll have it as this we pass our params and there'll be of type I params we get the ID from this params in here first of all we should have a try and catch block
        

so I click on that one and down here if we have an error we will draw it now in our try we can be able to get the ID from our param
        

so we can say const we'll say order ID will be equal to params once we have the order ID we can be able now to get the order using it
        

so here we'll say const order will be equal to and we await Prisma do order uh dot find unique we pass an object and we'll say where full column we pass an object ID is order ID once we do that we will have our order
        

so let's check if we have the order if no order we return null else we return the order now we have our function there that will help us to get the order from our database
        

so we save we come back to page and now we can use that function here to get the order
        

so here we'll have our const order will be equal to we await and we get order by ID we invoke that and we pass our params since we use it here this should be an async call
        

so we use async here what else we remove this list rating uh actually we don't need this entire section now in our order details we just need to say that we are receiving the order and these are will clear up
        

so order details here we'll be receiving the order and we should create an interface uh this will be a client component
        

so use client we create an interface we make use of the interface here
        

so react do FC angle brackets and we pass our order details props we'll have a router
        

so const router which will be to use router and we invoke it we return here ad div
        

so let me show you what we are actually working on
        

so that you have a clear idea before we proceed and look this is what we want to create order details the order ID total amount the status the products that were ordered who ordered them you can add as many details as you want right here
        

so for now I'll just be adding on with this let's start by adding a class name and we'll say Max hyphen width will be uh 1150 PX and and then here I'll have M as outo Flex then Flex is column then we'll have a gap of two we'll be having a heading
        

so I'll add a div and in here I'll add a new component of our heading like that it will be a self Crossing one but we'll add Title Here here is order [Music] details here we'll have a simple class name and we'll set margin to the top of eight and I saved to a format there then let's come here and I'll add a div and we'll have the order um ID full column and here we will pass the order do ID then here we'll have another div we can have the total uh amount full column and here I'll use a span to display the amount like that and we will use the format price U function
        

so uh format price down here from our utils I invoke that and we pass our order do amount
        

so the rea
        

son we added this is
        

so that you can add a crass name to this one and we will just say font is bold I save to format and after that div we show the various payment status I'll have a div uh I'll have another div it will say payment status uh full column then down here we will show the the payment status depending on the status
        

so we'll have a div and we'll perform a check
        

so here we'll say order do status we'll say is this equal to pending if this is true then we will show the status ponent right here we will be having several props this is for the case when it's pending then we can do this then you'll say order do status equals equals is equals to complete then we come right here and we'll have it again after complete we use a question mark and after our status here we use a full column and let's have the empty fragments I saved out a format and and for the second one we should change now this to if it's complete we change this to completed completed then this will be MD done then this will be [Music] green MD done we should import it from react icons okay uh this order is complaining still and I think this is because
        

sometimes the order can be null
        

so here before we pass it we should be able to return an error here
        

so here it'll say if we don't have an order then we will be turning
        

something here
        

so I save
        

so the error disappears you can include a better error message there back order details we will [Music] say class name we will Flex we'll have a gap of two we'll have items to the center uh the next one is actually deriver status which will be
        

so similar to this payment status we can highight the enti of this div where should it end uh this one here up to this point you should have to Crossing div at the bottom there then you duplicate it alt shift bottom Arrow then here the same Styles here the name will change to deriv status then here we'll check order. deriv status
        

so contrl D I'll remove those two and I'll say do deriv status if pending then it will be this one if dispatched it will be dispatched then here we will use MD uh deriva dining then we use purple we can perform another check for uh completed I can copy this part here from here to here uh copy and right here you paste and I saved to format
        

so here we will check for derad and here we'll now have deriv MD done [Music] make sure to import that then this [Music] green like that I save
        

so actually right now we should be having
        

something
        

so if we come back to the site go to what we are working on click on one of these like this one oops we get nothing for this one it should be outside the admin
        

so let's go to app admin my name orders here let's check that click button
        

so I just included a forward SL right here and when I do that uh it takes us to this page but we have this other error here saying next router was not mounted
        

so what I can do add our order details this one okay let me try to remove it first and see if it will work
        

so let's refresh and we get our order details
        

so you can see but I still want to test it from our admin
        

so let's go back to admin where we had manage orders and then I click on one of the orders and see yeah there we go
        

so you can just remove this right here if you're not using it okay
        

so just remove and I save and right now you can see we have our order details being listed thir
        

so after our deriv status div here you should have another div and you can say the date full column and here we will have moment we invoke that we should pass our order dot creat date and at the end here we say from now and we invoke that as well
        

so make sure to import this moment at the top okay there we go
        

so that's it for the date now the next thing is to display a list of products that were ordered
        

so here we can have a H2 and uh we can say uh products ordered okay and right here we can have a class name
        

so class name and we'll have font as semi bold then we'll have margin to the top of four and al
        

so margin the bottom of two right here we'll have a div and we can add
        

some class names for it
        

so class name uh will show grid we show uh grid uh hyphen calls uh hyen five this will be like a similar style that we had for our shopping cart
        

so text here will be small extra small that is Gap will be four then we'll have padding to the bottom of two then items will be at the center okay then in here um we'll have the heading uh all the column for the heading
        

so I'll say div and we'll say product products or the product we'll have a class name we'll say call a hyphen span of two then will justify self uh to the start you duplicate like four times then just remove the call span for the other three
        

so contrl D remove that and then here this is the first one the second one here will be uh price and here it will be justify self Center this this and this will be Center
        

so here Center this one two is Center and for this one we'll be having it as QT y or quantity then right here this will be end and it will be the total amount
        

so I save and we should be having that in a grid right here and there we go we have product ordered then you have product here price quantity total then we show the product bu
        

so we should be mapping through the product
        

so after this particular div will come right here Order dot products we'll say end and we will have order dot products do map we invoke this we'll have an item at a time and right here we will be able to return
        

something
        

so for now I'll pass this empty react fragments but we should be able to create an order item component
        

so right here let's add a new file and uh right here we'll say order item uh dot TSX here say the TR functional component and you'll say order item I save and let's come back to order details and we pass this order item right here
        

so order item and uh for this one it will be having a key the key will be item id we should be able to pass the individual item as a plop
        

so I'll pass the individual item as a plop to our order item let's import this order item and it's imported but this has an error because our order item component doesn't know about the item let's create an interface for that item here we make sure that we pass react do FC then order item props here now we destructure the item and you can see the error from this file disappeared now we can use this item to show it on the UI
        

so here we will return a div this div will have a class name and the class name here will be grid
        

so grid uh hyphen calls hyphen 5 then text will be extra small XS um then MD full C text will be uh SM Gap will be four then border um to the top will be 1.5 uh PX okay border here will be straight uh 200 then padding along the Y AIS will be for and items will be at the center uh now down here we'll list the different properties for this div it will have the image
        

so in here we'll have another div and it will have the image we get this image from next it will be self closing for this image we'll have the SLC the item do selected image do image we will al
        

so have an alt which will be now be equal to item. name we will fill and al
        

so we'll have a class name of object contain then here we'll have a class name for this image container and we will say relative we will al
        

so say withth is hyphen 70px
        

so this is a custom make sure to include it inside the square brackets and then right here we'll have aspect ratio aspect ratio of square then here we'll have a call span
        

so let's add a class name first then we'll say call hyphen span of two meaning that it will take two columns then we'll justify uh self to the start then Flex Gap will be two then this should be having a space there MD Gap will be four
        

so I save and for now we should be able to see the image there we go we have the image there then we'll have another div this is where we will show the name
        

so we'll have the div for the name and we will use the tranet helper function that we created at ours folder to trate the text and we'll pass item do name right here now the next thing down here we will have the item uh selected color
        

so here we'll have the div uh we'll have the item dot uh selected image do color let's sty both of those
        

so we add a class name and we will Flex them then we'll say Flex will be in a column and finally we'll have a gap of one between them I save and we should be seeing those two uh right here and there we go we add the price now after this div now after the enter of this div then you'll add another div and right here we will format the price yeah now we should be having a class name we'll justify hyphen self the center you can use alt shift bottom arrow and then here we pass the item quantity
        

so instead of formatting the price I'll say item dot quantity uh one last one and we are done with this particular component that is the total amount
        

so here we will set this to the very end
        

so justify here end and then we will al
        

so have font as semi bold and right here we will take the quantity then we multiply with the price
        

so we get the total and these two include them in normal blackets
        

so here that one and this one
        

so that at the end here I can say dot two fixed uh we invoke that and we pass to there then at the front here you can include the money sign and I save that will be the total
        

so let's see for each of the item and look one of them we multiply by one we get this and that is how you can list the product for each of the of those
        

so I can go back you can click on uh this one to see the items that were there and you can see this one
        

so if I'm a normal user I should be able to see my own orders the things that I have ordered uh like this and then I can be able to view the details for each of them uh easily
        

so this will be easy because we already have a data table for our orders we just need to customize it and remove
        

some actions everything else I think will remain the same
        

so at the root of our app we'll create a new folder and we'll call it orders we should have a page. TSX file and and I'll create another one called order uh client. TSX
        

so let's go to admin here manage orders page let's copy everything from here
        

so contrl a copy we paste we can just say orders instead of manage orders contrl D and I'll say orders
        

so we should be able to get the orders by user ID
        

so I will remove this one then we'll get the current user and the only thing that we will check if if we have a user
        

so remove the admin part and then for the orders Let's uh create a function right here we create and we'll say uh get orders uh by user ID dots I'll come to get orders and I'll copy everything from from this one then come to this one and paste it here
        

so from here we'll export get orders uh by uh user ID right here we'll be able to receive the user ID and we will have the string there and then here we will try and catch
        

so we'll get orders we AIT Prisma find manyu and here you can include the user and and al
        

so you can have order by that and you can have a filter right here now
        

so we'll say where full colon user ID is user uh ID just start and then you'll get the orders for that specific user
        

so I'll cancel that now I'll come back to the page here and after we check if we have the user that is when we will be able to get our orders con orders uh will be equal to we await and we will get orders by user ID it's imported here
        

so remove the other one there and we invoke this and we just need to pass the current user do ID then down here you can check if you have the order or not
        

so because it can be null
        

so here you can say if we don't have the order the orders then uh come right here and say no orders yet
        

something like that we'll receive those orders on the client here and then we'll use those ERS to create the table
        

so let's just copy the table from our mm app at the top there up manage orders client copy everything from there come back right here and paste scroll to the top let's change the name remove this manage
        

so contrl D remove that and save we can have it as ERS client or order client here we included ERS client okay uh what is this from order client the name of the file we included as just on the client
        

so save that come back and now we already have that table at here we come here our own orders here we are
        

so we have this for a user but the user should not be able to perform these actions they should not mark their own orders as dispatched or let this and I think we we missed
        

some uh
        

some other process the same way and then we check if the user is an admin
        

so this should be returned
        

so that this error c yeah that
        

so just copy this logic right there save that file and you can as well update other routes that we worked on
        

so back to API here uh you can check the route for product there we had this where we were creating a product make sure you update that because if we have a user they will be able to create a product even though they are not admins you can do the same for the rest
        

so I'll just show you that this three here wait I removed even the user just this portion there
        

so you can do this updates uh
        

sorry for all this but for only the admin routes
        

so that should be the product route here and here and then the order route and did we work on this the same way this is automatic actually only those yeah that's good that's good
        

so now let's cross those routes
        

so for the order just go to actions remove the handle dispatch and handle derad UI remove those al
        

so remove these functions because we no longer need them here remove handle deriva al
        

so remove handle dispatch save and that should be it for our own orders and uh yeah it's a shorter table you can decrease its width if you want but I'll leave it at that
        

so yeah
        

so far
        

so good we can see our own orders we are able to see the order details if I click on that uh taking time to load there we go if I come here and go to dashboard we are able to manage the orders we are able to manage the products we are able to add a product
        

so this is a very huge progress and uh we are almost done with our application
        

so what remains is working on our summary then we will work on our categories
        

so that we are able to select the various categories of products uh then we will work on the search right here and finally we will work on product reviews
        

so we still have a bit of a journey to go but we will get there uh this was a very huge cost but uh before we even get summary there is one important thing that we are not doing we are not getting our products for our e-commerce web app from the database uh this was the dumy data that we used which is static
        

so I would like to get the products from the database now that we are able to add a product in the database
        

so let's just uh Dive Right In minimize everything then you will open open app then you'll go to the page at the root of our app and this is the beginning of our application here and here you'll see here we were bringing in products from our utils we no longer want this we want to get the products from our database and if we check at our actions you'll see we already created this particular function for getting the products which al
        

so filters the them depending on the search string and the query string at the page we will call this particular function and we need to make this to be an async function
        

so we'll say export default async function async keyword will be here and then in here we will now say con our products will be equal to we a wait get products we invoke that let's create an interface for our search params or home props
        

so let's destructure those props right here and we'll say here it's search params I missed the spelling here I think there is an a there we can use full colum here and say this will be of type home props then right here we'll pass our search params we should Auto Import it another thing is that I don't want them to always show in the same order I want them to be random especially at the homepage
        

so we will create a small algorithm that will randomize uh those particular products
        

so here first of all I perform a check
        

so if our products uh do length uh isal is equals to zero
        

so if we don't have any products then we will go ahead here and return our null data component and let's import this component
        

so that it stops complaining okay now right here let's create our algorithm
        

so what this will be doing is to uh Shuffle our products before displaying them every time we refresh the page
        

so that user is not bored by seeing the same product on our UI
        

so what we are doing here is a swap
        

so product which is at position uh I we are setting it to be at position J and that product which is at position J we are setting it to be at position I
        

so product at position I we set it to product at position J product at position J we set it to product at position I
        

so we shuffle them okay and then at the end of this we will return our array
        

so here let's uh get our shuffled products
        

so we'll say con uh shuffled products will be equal to we call our Shuffle array and we invoke that and we pass our product this is what we will pass as our product right here instead of mapping through the products we map through our uh shuffled products and then we save
        

so right now if we visit our app we should be having at least one product and there we go we have this one product from our database as you can see it doesn't even have a lot of details
        

so if I click it okay it takes us here we have an eror we don't have one where we are getting a product by ID
        

so we will add it
        

so that we can be able to get product from our our database using the ID
        

so here let's add a new file and we'll say get product by ID do TS
        

so right here we will bring in Prisma
        

so import Prisma and this will come from at stroke Libs stroke Prisma DB let's create an interface and we'll say I uh params here we'll be having the product ID which will be of type string and these can be optional we'll say export and and we'll say default uh a sync uh function get product uh by ID will be the name of our function and U we invoke this here we will receive uh params of type I params which we have defined at the top there let's have a try and catch block
        

so try and catch the error here will be of type any
        

so inside our try we will get our product ID from the params
        

so you'll say const uh product ID will be equal to params
        

so we D structure it out of params then we use that to get the product okay then here we say that we want to include the reviews for this product
        

so we'll say include right here we'll say we include reviews pass an object and for the views we will include the user
        

so we'll set user uh to True like that then right here uh comma we order by and we'll say created date to be descending
        

so desk I save and that is how we can get the product once we get the product let's come down here and we perform a check do we have this product
        

so if we don't have a product we'll go ahead right here and we will return n and I save awe
        

some we will use this function inside our product
        

so go to product folder then product ID page
        

so remove this we will make this to be an as sync function
        

so I think I will remove that params and right here we will now say const uh product uh will be equal to we await and we will get product by ID we invoke it and we pass our params I save
        

so let's see if we get the product
        

so it's refreshing okay still we have an issue at our product details we'll check if we don't have the product we will not return the BAU code
        

so we will return the null data uh component
        

so return here I save what is that error
        

so here we get oops product with the given ID does not exist
        

so it's like we are not getting the product we will return our product now I save and let's refresh the page and see if that error has gone uh amazingly we have our product there awe
        

some and we are able to even switch the colors which is really cool we are able to add it to cut view cut uh here is our cut it al
        

so has
        

some previous product from the local storage
        

so can just clear everything and this is what we have now let us add a nav bar here for the categories open up then components right here we will go to nav and inside the nav add a new file we will call this one categories. TSX we call the component categories these categories we will hook it at our Navar after this div right here we will pass our categories component and we save there we go we have these categories here and we will return a div here with a class name of uh BG white and then in here we'll have a container
        

so we will use our container component from container inside our container we'll have another div we will have a class name for this class name padding to the top will be four it will be Flex We Will Flex row items will be at the center and justify will be between then right here we will have an overflow X of outo and in here we will be able to map through our different categories and these categories are available at our utils
        

so import them from the utils and we'll say uh dot map we invoke this we pass an function here we will get a category Ed at time we can call it an item and in here we'll be able to uh return basically we can use normal brackets here and remove the Cur bracket
        

so it will return directory like this and right here we will be able to pass another component
        

so let's pass ad div for now we have returned a div for now but we will return another component let's create it here and we will call this component category
        

so category one category. DSX and here stat functional component and we will be able to call this one category let's define
        

some props
        

so we will have an interface and we will call it category props we will have a label which will be a string right here we'll have an icon which will be an icon okay it should be icon type from react icons then we'll have selected which will be optional this one and it will be borean
        

so this one this one will tell us which categor is selected basically then let's pass that right here this will be react. FC and right here we will be able to destructure the different categories theable we will able to get the icon from uh icon then here we'll be able to get selected okay all of them has issues why didn't we complete here and there we go we will have this div and it will have a class name
        

some of the class names here will be dynamic use square brackets and btics then you'll say Flex items will be Center
        

so here you'll say icon and these will have a size prop of 20 and then we can self cross it like that
        

so here we'll have a div the div will only show the label
        

so font for this one will be medium text here will be small now let's come here
        

so we style these two we Flex them and we align them to the center then we justify the center as well text Center gap of one padding of two border okay border bottom of two and we'll have hover full column to be text okay when we hover we'll have text uh to change color to slate 800 and we will add transition here CA will be pointer
        

so I can hit enter and right here we'll have
        

some Dynamic style
        

so we will check if this particular category is is selected
        

so we'll say selected and if this is selected then we'll have these Styles here we'll have a border B of straight 800 we will change the text color
        

so text will be straight 800 as well for the case when it's not selected we will have border as transparent [Music] text uh will be straight uh hyphen 500 will do
        

so at the top here we will create a function that will handle the click for this particular category
        

so that we can change the url change the query params and refret the products
        

so that we get new products uh depending on the category that we have creck
        

so right here we will be having an onclick event we will have handle click
        

so right here we will say con handle click uh will be equal to we call use call back hook we invoke it we pass an arrow function in here and it expects us to have a dependency array and then at the top here get our router
        

so const router and we'll set this to be equal to use router and we invoke that one then at the end here we will get our params
        

so we'll say const params and we have a hook called use search params
        

so use search params and we al
        

so invoke that one and now in here we will write our Logic for when we click a certain category
        

so first of all we check if they clicked on all
        

so here we'll say if the label is equals to all then we will go ahead and push them to the home page we create our URL
        

so here we will say router. push and we create our URL by pushing them to the home like that without any else in our URL and then right here say else if they click
        

something else apart from all then we will update our query
        

so right here you say let current query be equal to just an empty object and then right here we will say if we have uh the params we will update our current query here to be equal to and we will create a query string um using a library called query string
        

so Qs this will be an object from rary called query string uh pass and right here we will pass our params uh dot to string we invoke that
        

so with we don't have this Qs and right here it'll say npmi and we'll say query hyphen string we install that package okay I messed up uh this is query
        

so npmi query string install that one and then now right here let's see if it will Auto Import and we get this click on that one
        

so it will be import query string from query string you can use the full name or you can use Qs for query string after this if statement down here we will say con updated query will be equal to it will be an object this will be of type any we will spread our query and we will add our label
        

so we'll set our category here uh to be label
        

so I can use a small cap
        

so what we have simply done we have taken the existing uh query and we have added our own
        

so we update this object from our param
        

so this is the existing quy string we update it with the new one which we click like this
        

so now right here we construct our URL now const URL will be equal to we will make use of the query string which we have just installed do stringify URL like that we invoke this one in here we will pass the first object the base URL here is home and then we will add the query now
        

so we take the default URL then we add the different queries that are now there I'll add another object we'll say skip null and we'll set this one to true now after we construct our URL using the queries we will come right here and we will take the user to that particular new URL
        

so router. push and we take them to the URL this one which we have constructed from the query awe
        

some and this should be it actually
        

so here it's just pass the different dependencies when the REO change we should be able to call this function again when params change we should be able to call this function again and when router changes I save
        

so this is now our category component
        

so we just need to display this on our nve
        

so here once we map through the different categories I can remove that one and we will show the category component now uh Closs it and we pass the various props we will check our category from the params
        

so category and if this category will be equal to item R then that uh category will be marked as active
        

so we don't have this we should be getting it from the params
        

so at the top here we'll say const params will be equal to use search params and we get to invoke that and then right here we will say that our category uh will be equal to params this can be there or not do get then we will get our category
        

so we get the category from the params or from the URL if that category is equal to the current item T then we will Mark that particular category on our categories as active Okay and then right here if it's at our home uh that means that we won't be having the category therefore we should Mark all as the active uh category
        

so here we'll say or pass these uh brackets and we'll say if category is equal to null then here you'll say end end item. uh is equal to all
        

so if we don't have a category and item. T is all then we will Mark selected as true and then at the top here we will check if we are at the main page
        

so we'll say const path name and we can get path name from a hook called use path name and we invoke that and then right here const is main page will be equal to path name us is equals to home
        

so if we are not on main page
        

so is main page here uh we'll go ahead and return n
        

so we won't show the categories if we are not at the homepage okay we have a server component that Imports next router instead of next router we will say next uh stroke navigation I save okay another issue we used a hook and we didn't mark that component as a client component use client and we should do the same for this one
        

so save this file and come to this
        

so I save okay let's see now if we still have another issue refresh okay now we are able to load awe
        

some and lo look we have listed our different categories like that let's click on phone and see if we still get the phone and there we go this is highlighted and you can see now here we constructed our URL and we added category is equals to phone click on laptop we get nothing
        

so oops no products click all to clear filter let's click on all and the filter is cleared there there
        

so once we add other products with desktop or watch they'll be fetched depending on that category since we know phone works then that means the rest will al
        

so work okay cool now the next thing that we will do is to complete our product okay
        

so if I click on product we should be able to add rating and show the rating right here
        

so let's work on that next and then after completing that we will work on our search bar and finally we will come to the dashboard and complete our summary and then we will be done with the cost after deploying it okay and for adding a rating we will need an API route okay and al
        

so we will need the Prisma model for a review
        

so if we check our Prisma schema and we scroll here did we add a review
        

somewhere we did this one
        

so we already did this and now all we need to do is to make use of it uh to create a review for a certain product okay
        

so minimize everything then you will go to app API and right here you can add a new folder and you will call itating insert there you can add a new route called route TS now in here we will create our function we can start by creating our function down here and we'll say export a sync function these will be a post request you invoke this we will have a request of type request here we'll start by getting our current user
        

so uh con current user will be equal to we await get current user we autoimport it from our actions and we invoke it here we will check if we have the user
        

so if we don't have the user then here we will draw an error down here we get whatever will be at our body
        

so con body first of all will be equal to await request. J
        

son then we destructure now a user should not be able to add a rating if they have they don't have the order all the that particular product delivered we will check if the order is delivered we use our current user orders do sum
        

so here you'll see that property orders does not exist
        

so what we can do is to go to get current user get current user and here we filtered with the email and we will make the user to al
        

so come with the orders included
        

so here I'll say include and we will invoke these and we'll say orders and we'll set that to true
        

so include full column
        

so we include even the orders when we are getting the user and then from here we can get the orders from the user and then we perform
        

some filtering using the sum array method to get the derived orders only um one thing is that when a per
        

son has an order they might have many products ordered at the same time okay I will get the order products
        

so order do products right here I'll say do find we invoke this now
        

so we have a loop inside a loop it's not good for performance but it will work for now
        

so here we will have an item and right here we will have an item. ID and we'll check if this is equal to our product uh do ID and and this particular product ID is the one that we are trying to rate
        

so we check if that particular product is available on these um orders okay and al
        

so here we make sure that this particular order is delivered
        

so here we'll say end and order do deriv status is equals is equals to deriv okay I hope that makes sense okay now another thing is that we will check if these particular user has already rated this product
        

so they can't rate a product twice
        

so if this is true that means that this user has already rated this particular product
        

so right here we will perform a check
        

so if user review
        

so if they have already reviewed this particular product or if this particular product is not derived then we should draw an error here we will return and we will return next uh response resp do error and we invoke if they try to review then they'll get an error now right here let's go ahead and create this review
        

so con review will be equal to a wait we say Prisma do review then we say do create we invoke this and we pass our review data
        

so data will be uh comment we will have rating we will have uh product ID and this will be product. ID
        

so product. ID and finally here we'll have the user ID
        

so once we create that review we will return the review to the user
        

so right here we will say return next response uh dot J
        

son and we pass our review okay this should work but um you can al
        

so wrap it in a try and catch Brock
        

so now let's go back to our product and try to make use of this particular API route
        

so minimize everything go up then we have this product then we should add a new one and we will call this one uh add rating
        

something like that add rating. TSX we will have an interface we will say add rating props we should be getting the product as a prop
        

so we say this is of type product and here we will say end we add the review here we will say reviews and we say this will be an array al
        

so
        

so we have the type for the review which is awe
        

some all these are now coming from Prisma uh we will include these and we will say safe user and we will pass an object we will say orders uh full column of type order this will come from Prisma client and this can al
        

so be null
        

so we say null let's create this component sfc and we will say add a rating like that then we come here with we will have the different uh props we'll have product we will have user let's make sure that we pass our interface
        

so react do FC and here we will pass our add rating props okay we should not have this let's remove that now right here we will have a div I'll save for now I'll come right here to the page now here we will have our add rating component and it expects us to pass the product
        

so we'll say that product is product and al
        

so it want us to pass the user
        

so we'll say user is user we don't have the user but we can get the user from our actions
        

so here we'll say const user will be equal to we await get current user like that and we invoke that one and we pass everything now
        

so I save and now all we should do is to work on these add rating component
        

so let's start with before our return statement uh right here we'll have const uh is roading
        

so we create a state here and set is loading and this will be equal to use a state and we invoke it we pass false not user state but use State let's make sure we import that from react we will have a router
        

so const router will be equal to use router from next navigation and we invoke that we will make use of a react hook form
        

so here we'll say const we will destructure
        

some stuff we have done this before and this will be coming from use form and use form is coming from react hook form we will be invoking this we will be passing
        

some default values there and this use form will be having a type and that will be the field values
        

so you pass field values right here now right here when you call register you'll get
        

some cool suggestions like under submit you will have set value uh we will have a reset then we will have a for form state for this form State we will destructure errors from it
        

so errors then right here we can have default vales full coron and here we will have the comment and the rating
        

so by default comment here will be an empty string let it start with a small and then the rating will be zero or rather it should be one okay you can't have a zero rating the lowest should be one maximum should be five and don't know this is just the default anyway now down here
        

so set custom value and we'll make use of the set value function here this function will have an ID of type string value of type any and right here set value we'll pass ID and we will pass value and then we will pass right here an object should touch uh to be true should D true should validate to be true here we will say const on submit of type submit HRA from react hook form here we'll have filled values we will get data here and this will be an async function now let's work on our UI then we'll come back here and make the API request we should be having a class name we will flex and we'll Flex column and then we'll have a gap of two Max um width will be 500 PX we will be having a heading component the title will be rate this product here let's import this heading from components we will show a rating component right here let's use control space It should come from Material UI
        

so this has an unchange event we will pass an arrow function right here this will receive the event and the new value and then we can use those right here to set our new rating
        

so set custom value and we invoke these here we will say rating and this rating will be our new value
        

so right now if we save we should be having this particular uh component there
        

so we should Mark this component as a client component
        

so use client
        

so I click on the product and look we have these here which we can click on and it will change the rating depending on where we have clicked
        

so we should have an input field for adding a comment
        

so Below the rating here we will say input it will expect us to have several uh stuff okay we will have a button to submit the rating we will al
        

so have an onclick event handle submit we will invoke this and we will pass our own submit let's import this from our app component and save now if we check we have this you have that awe
        

some
        

so if I inspect we type
        

something let's go to con
        

sole and if we submit we should be seeing
        

something now look we have comment as this rating as this if we update to hello we update here rate rating is four hello it's working awe
        

some
        

so that con
        

sole log is the one that we have here at our on submit
        

so all we should do here is to make a HTTP request we save that information in the database
        

so here we'll set is roading to True uh if the rating is zero
        

so you can rate zero we will return immediately
        

so we won't save this information in the DB
        

so toast. error and here we will import the toast awe
        

some const rating data to be equal to we D structure here our data but al
        

so we will be adding the user ID to this particular data
        

so the per
        

son who is writing these particular product will be user ID and al
        

so we will be passing our product to this particular data
        

so product will be our product we will now make our anxious request we will say axio uh dopost we pass our API endpoint which will be at API and we'll say rating and we pass our rating data we will be able to tap to the dot then method here and we invoke this we pass another function and we can do
        

something in here like toast a success message al
        

so here we can refresh our router and we can call reset
        

so reset we reset our values from the form uh actually today I think the code is not aof formatting uh I had disabled prettier for
        

some rea
        

son
        

so that's why it's longer than normal but I hope um you are able to follow along now right here we will catch
        

so if there is an error we should be able to do
        

something with it we'll say finary and for finary we will set his roading to fals once we get here and I save now right here if we don't have a user or if no product we will return n to show this particular component we should al
        

so be making a check like we did right here we check if it's delivered and if we have a user review and based on that we decide whether to show the component or not now here instead of current user we will say [Music] user
        

so we can copy that logic and then now right here okay if we already have a user review and if we don't have the product is derived or the order is derived then we will not show the UI for adding a review
        

so we return null
        

so right now I believe we should see null because because we don't have this product as deriva or
        

something like that
        

so we should comment it out first
        

so that we test and then we will return it later and test again if we need to Let's refresh
        

so once we refresh and try to call rating product here then comment you'll be having
        

something
        

so we say uh good product then we rate again not rating selected we must select
        

something here good product we give it a four and uh we should Mark these status fall
        

so that we no wrong road if we get to this point let's use carry brackets here
        

so that we can enter in a new R here and we return the state here as false
        

so we save I refresh again okay
        

so let's give give it a for and we say good product and I rate now roading
        

something went wrong on our route here these will prevent us from rating the product
        

so let's let's rate it without these first
        

so that we see if it will work out al
        

so remove these one
        

so let's save and come back we select a form and the message and we call R product
        

so it's loading and there we go rating submitted once it's submitted we should be able to see it at the bottom here and there we go look good product awe
        

some
        

so it's working well al
        

so this this did not clear but once we already read the product the entire of these UI will hide will be hidden
        

so right now if we return this and these
        

so now I will return that and I'll save okay let's see
        

so you see that section is hidden and we have this one review there uh good product
        

so if we don't have a review let's not show this heading let's go to rest rating uh in here before the return statement let check if we have the product reviews we will return n
        

so I save and these should not show you see now we don't have that annoying heading without the data
        

so let's uh order this particular watch
        

so I'll click on Silver there two of them add to cut view cut we are at cut we go to check out um I don't have my web hook started therefore this will not Mark the order is paid but we can still pay it using stripe and it will create the order actually it has already created the order only that it's still pending uh the status for the paid it's pending okay but it will work for testing the general stuff
        

so let's just pay now it's processing and it's paid but remember it will not Mark order is paid
        

so if I view my orders here okay we get 44 we worked on this page didn't we where did we get 44 okay stroke orders it should be stroke orders here it's orders
        

so orders
        

so I save that file basically it should have taken us to orders not order
        

so we have updated that next time it should work and you'll see at our orders now we have this one 3 minutes ago and it's pending everything is pending although we paid uh my web Hook is not on there for payment status was not marked is complete okay uh if I come to the dashboard and if we go to manage orders
        

so right now we should not be able to rate that product because it's not deriva
        

so first of all let me check if we are able to or not
        

so right now we are not able to rate it
        

so here uh let's mark it as deriva here even though it's not paid yet order delivered and there we go it took
        

some time to update I don't know why once it's derived look our UI updated and we are able to rate this product let's give it a five and we can say amazing watch and I rate the product it's roading rating submitted and look we hide the UI and now we have this product as rated here a few seconds ago amazing watch
        

so our functionality is working and our app we can consider it actually as Complete because the only thing that remains is this search bar and our summary
        

so let's work on that next
        

so the search bar will be easy uh right here I can close all the tabs you need to go to app you'll go components right here we will add a new component we can call it search bar stess functional component and this will be search bar let's take this component into our nav bar
        

so here instead of search we will have search B this one let's click it
        

so that we al
        

so Auto Import it just like that
        

so I'll save and let's just expand here go to search right here we'll just say use client we can actually start with the UI here we will be having a div this div will have a class name let's flex and then say items to the center now inside this div we will be having an input field and a button let's add class name
        

so we'll have class name we will have padding of two border then the color of the Border will be gray 300 it will be rounded but on the left and here you'll say MD we can say on Focus let's out try none on Focus Focus we will have a border of size 0.5 PX al
        

so here on Focus again we will have the Border color to be straight 500 and width will be 80 those are the class name for the input
        

so here we will have press holder and we can say expr e shop type will be text and then we will remove auto complete and we'll set this to off
        

so that is basically the input now for the button leted save and we should be having an ice UI already
        

so right here look now this should be rounded to the right only
        

so that it looks nice right there
        

so it's rounded on this end but this end it's not now we have a nice search bar just like that but it's not functional
        

so let's make it functional
        

so let's use react hook form we will destructure
        

some stuff from use form which comes from react hook form invoke that we should pass fi vales let's make sure to import this one from react hook form we will have the default values we will have uh a search term and it will be an empty string from this use form we'll be able to get several stuff here we will be able to get register um handle submit we'll be able to get the reset al
        

so we will be able to get the form State and from form State we will have our errors we will register this input field here we will spread register and then we invoke it and we will pass sear term now let's create a function that will help us to submit the form uh on submit okay this will be an async function which will receive data add the type here like that and we have our data there for now let's just say con Rog of data at the botton we will have an onclick event and we will say handle submit we invoke this one and we'll pass on submit
        

so once we click we'll be able to log the inputs for that on the con
        

sole let's open the con
        

sole and now we can say nothing and we get the search term right there what we will do we will just update our URL or the param and then it will fetch the data again um using different query we need to make use of our router and we can bring it here
        

so const router will be equal to use router and we bring it from next navigation
        

so we invoke that we will perform a check first make sure that we have a search term
        

so we'll say if there is no data do search term what we will do is to return immediately and we'll say router. push and we take this user to the homepage now right here we will construct our URL
        

so we'll say const URL will be equal to we will make use of the query string from query string dot stringify URL invoke this we pass an object and we will pass to object actually
        

so comma and another object there
        

so the last one we'll just say skip null and we'll set that to true but for this one we will say the URL is the default and then we will change our query okay
        

so now we have uh constructed our new URL depending on the search term and right here all we will do is to push this user to that URL
        

so router. push URL then we reset the input field
        

so you can reset or you can write it there
        

so I save and actually this should work let's test it let's search for watch
        

so right here say watch click on search and nothing happens
        

so what have we missed or maybe we might have messed up the spelling search ter yes this one it's good now I think it will work
        

so let me just remove the log there
        

so watch search and there we go we only get the watch and our URL now has this search down we search for phone it changes the search ter to phone and we get the phone we will work on our very last section now uh which is our summary we will need to go to admin then this page here is our admin page and this is the default this is the summary now this should be the summary let's create a new component here we will say summary TSX stess functional component summary here for now let's have a div it will be a client component
        

so here we will use client and then we will define an interface for our plops
        

so we have those awe
        

some
        

so I save and then inside our page we will bring in our summary right here and we pass our various plops
        

so this will be having products and we'll set this to products and it comint there here we'll have react. FC and we pass our summary props now if we come back we'll have products from products here we'll have orders from our orders we will have users from our users right here we'll be having const products and these will be equal to a wait get uh products we invoke this and um this expects to have a category and we'll pass n
        

so we mark this function as an async function all this component let's get orders we'll say con orders will be equal to
        

so for users I don't think we have a function where we are getting all the users do we
        

so let's create an action for getting our users and you'll simply say get users. TS I save and that's our function for getting users very easy to use and here we just say uh const users to be equal to a wait get users we have gotten all the data for now that we need and here we'll go ahead and uh add this to be inside a container
        

so container from components container and we wrap our summary in there I don't have pretti Auto format
        

so I'm kind of forced to format that manuary and yeah we passed all the data to summary and WR work on summary now we'll be able to get those various props or do uh products users I'll set
        

some form of State I'll say const summary data and we will set summary data we'll set this to be equal to use State and here we will pass a type and we will be passing
        

some default values here first of all let's define this type
        

so right here we will say type summary data type for each of the data we will be having a key and the key will be a string and then right here full coron uh we should set an equal sign here for type
        

so key string then here a label which will be a string a digit which will be a number here we pass our summary data type like that let's define the data now we can have the sale we will say label is total sale and then here comma we will say digit zero we will duplicate this several times
        

so alt shift bottom Arrow we'll have four products we'll have another one for uh orders paid orders unpaid orders and users here we include total orders paid orders we can say paid orders and paid orders users total users
        

so this is the default data and it's in our state
        

so we can use this set summary data to update the different stuff okay
        

so to update these data we will make use of the use effect right here whenever component loads now at the dependency array we'll have orders products and users is the dependencies
        

so when any of this change our use effect will run again and here we will simply call set summary data and then we invoke it here we will get the previous state of our summary data I'll just call it PR and we will use that to update everything in here
        

so right here I'll say let uh our temp data temporary data be equal to our previous state
        

so I spread the previous state like that and then at the end here we are required to return
        

something and we will be returning our temp date we need to do more here we need to update our total sale we need to update paid orders unpaid orders and all those okay let's calculate our total sale
        

so we say const total sale will be equal to we will get all our orders and we will use reduce
        

so here we will have an accumulator and we will have an item here we are passing an arrow function and at the end here we'll pass the default of zero then we will do the calculation in here we will check if the status of our item is complete
        

so item do status is equal complete
        

so that means that this item has been paid for
        

so if they have paid for this item we'll go ahead and return accumulator plus item do amount we will say else we will just uh return the accumulator and then here I'll say con paid orders will be equal to we will take all our orders and we will filter them
        

so do filter here we'll have an order and here we will return order do status
        

so we will only take the orders that are complete again we will get the unpaid orders we will check for pending these will be our unpaid orders now here we can simply update our temp data
        

so we'll say temp data um do sell. digit
        

so we update the digit part of it we'll set this to our total sale and then we'll say temp data again do orders then here dot digit we'll set this to all ERS uh do rent then temp data dot paid orders uh basically most of the rest will be almost same
        

so alt shift bottom arrow that will be for paid orders unpaid orders products users
        

so let's just update those one by one now let's start with this one
        

so this will be paid uh orders dig it it will be um paid orders. length then this one will be for unpaid orders
        

so [Music] unpaid orders then this one will be and paid orders. rent this one will be for products and here we will have product and this one will be for users and here we will have users
        

so basically we update this data with a correct digits or number and that's how we can update that now let's work on displaying them
        

so right here this div will have a class name and we will say Max height and width will be uh 1150 BX and then margin Auto then right here we will have another div and we'll have a heading here let's have title and we'll say starts then let's Center let's have a class name and we'll set margin to the bottom of four and margin to the top of eight let's come down here we'll have a div we can add a class name here
        

so class name grid let's have two columns
        

so grid calls to let's have a gap between them of three let's have a Max height of 50 VH let's overthrow along the Y to be outo now right here we will map through our data and as you can see our data is in form of an object
        

so we can map an object
        

so we need to convert
        

somehow these into an array
        

so we can extract the keys sale products orders like that from that particular state
        

so how can we do that we'll come right here and we'll say const summary keys will be equal to we will use object uh do Keys We invoke that and we pass our summary data and this will get our summary keys right here as an array and then we can map through that
        

so here we will map through our summary Keys we will say if we have our summary Keys then end and let's then go ahead and say summary keys. map we invoke that here we'll get a key at a time and we can use that to do
        

something we need to return and we will return a div like that this div need to have a key the key can be this one now is this one now this will be having a class name it will be rounded to be XL border will be two padding will be four Flex Flex to the call items will be Center and we'll have a gap of two then we will transition looks good now here we'll have another div and let's first work on the class name for this one we'll have text as XL MD text will be for XL Xtra R for Exel font will be bold we will now show our data we will perform a check to check if this is um if it's a price or just a number and the only price we have is the sale
        

so here we will say summary data and then we will use a key to get the data we will have label and if this is equal to our total sale
        

so summary data. key
        

so we access like this summary data. key
        

so summary data if the KE is sale then we'll be able to receive this object and here we'll check if the label is total sale and if it's total sale we will use aary operator and here we will show the data in a certain format else we will show the data in a different format and right here we want to show the price we call format price we invoke that just copy this part here and that is what I will include here then here I'll say dot digit and then right here this is just a normal number and I can copy this all of it I will copy and I'll paste it here we don't want to use format price but we'll create a new helper function to format the number
        

so at our utils We'll add a new file and you'll say format number do TS
        

so this will format our number and we can use that function right here
        

so instead of format price we'll say format number and we import it from there now after this div down here we will add AEL
        

so we'll have a div again we will have our summary key we access the label this should be summary data and there we go
        

so hopefully we have
        

something beautiful now and let's check it out
        

so I come here and this is what we have
        

so at least you are getting the total products total paid orders users unpaid orders total orders total sale
        

so
        

so far it's good but not the best we are missing
        

something to do with colors and borders
        

so we misspelled the B here
        

so border let's see and there we go
        

so we have that border for our section I think it's
        

so wide right here
        

so this should be having the square bracket there then remove that save much better now it will not be wider than that ever
        

so if I happen to zoom out it looks good on all screens the next thing that we will be having at the bottom here is a graph showing sales for the last 7 days
        

so let's work on that next uh
        

so now finally I want us to work on our graph for the last 7 days and I think the hardest part about that is uh getting the graph data from the DB
        

so right here what I'll do I'll paste a function uh that will uh help us to get the data and then I'll try to explain the steps that are happening okay
        

so let's see here we are defining a new function called get graph data and it's inside our actions
        

so you can add it and you can copy things as they are right here yeah just make sure that you don't have
        

some sparing mistakes or punctuations things like that
        

so the first thing that we are doing here we are are getting the start and the end dates for the data range
        

so we want to get the data for the last 7 days
        

so right here we get the start date to be uh the current date and we subtract uh 6 days from that and we get it from the start of the day and this one the seventh day will be today and all we are doing here now is to query our database using Prisma but we have to group the data in a certain way
        

so we group our data by created date
        

so we will get the orders uh for each of the day and we sum all the amount for that particular day
        

so right here we Group by create date and then right here we filter
        

so we want the data for the last seven days to begin with to be greater or equal to the start day and to be less or equal to the end date
        

so we get between that range and we make sure that the orders payment status is complete and then right here we sum the orders for each of the days
        

so we get the total amount for uh that particular day okay and we want the data to be in a certain format
        

so right here we initialize an object that will hold this kind of data
        

so each day for example Monday we'll have the data in this format we will have the day which is now Monday we will have the date for that day and then we will have the total amount for that particular day uh which will be basically this total amount which we already calculated here uh using our Prisma but now we want to update each day we don't know the days we only know the date okay
        

so here we use a hoil loop and we get the current date here we call the current date and we use the hoil loop to be between the range the current date okay this is like the last seven days and I think it's it's wrong naming the end date is today
        

so we get that range the range for the seven days and right here we get the day in this particular form basically we get the name of that day whether it's Monday Tuesday Wednesday Thursday uh
        

something like that
        

so we get it and then we take our object here we take that date we add that date as a key and we add its data
        

so the data now will have day the date will be this one and the total amount current will be zero
        

so we haven't updated the total amount yet and then right here we will move to the next day okay now the next step is to update this total amount
        

so we uh take the result the result is this one the one from the database we take that result ROP through it and we will take the amount for each of the day first of all we determine which day it is uh for that particular amount
        

so here it's entry. created date and then we get the amount for that day the total amount for that day and now we update our aggregated data we specify the day we take the total amount and we set it to our amount right here remember this is zero
        

so we will just be adding the amount that we get from here it can either be the sum or else it will be zero
        

so basically we update our amount that we get from our result here which is already summed for that particular day and then after that we will convert our aggregated data into an array and the array will be
        

sorted by date
        

so we get a
        

sorted array right here which we return
        

so we will use that array to create our graph and that is basically it
        

so you can copy this function as it is
        

so I'll go ahead and save that file you need now to go to up then you'll go to admin and right here at the admin we will add a new file
        

so this one we will call it bar graph uh do TSX and this will be a client component
        

so use client we will be making use of a third party Library called react chartjs uh to create our chart
        

so let me show you you can just search for it uh react chartjs this is it you can open it like that and you see you'll need to install chartjs and react chartjs
        

so from npm here I'll copy that and I'll just go ahead and install those two packages right here okay
        

so for now let's copy this code like like that which is here and we we come right here and we will paste it here we will create a stess functional component and we can call it by graph uh for now let's just have uh react fragments let's import chart is uh chjs then here we will get bar element not AR but bar element like that we will al
        

so be getting category scale we will be getting linear scale we'll al
        

so be getting tool tip and we'll be getting Legend like that from chartjs and then right here we will register all those
        

so weister bar graph category linear scale copy them and paste them right there okay and then right here we won't use this one
        

so remove that one we will al
        

so not import Donut from here but we will import bar from react JS okay
        

so like that for this particular bar graph we will be having an interface down here we will say type graph data this will be an object it will be having a DAT the day will be a string and then it will be having date will al
        

so be string it will be having the total amount and the total amount will be number okay and then let's pass that right here
        

so here we will have react. FC and we pass our bar graph props now right here we will destructure our data like that and right here let's log the data to the con
        

sole and I save we come back here we'll go to the page and here we should add our graph
        

so let's have a div and in here we will show our bar graph component which we just created and it will be self closing this bar graph component expects to have data and this data will be our uh graph data okay we don't have this graph data
        

so we get it
        

so right here we'll say const graph data will be equal to we await and we'll say get um graph data we invoke that we pass it here and we will get it right here
        

so let's first complete here here we will be having a class name margin to the top to be four then MX will be outo and then we let have a Max width for this one
        

so that it's not too big
        

so
        

so we'll have 1 uh50 PX and I happen to save that the data we receive it right here and we are logging it to the con
        

sole
        

so let's see if we get any data and I don't think we have any completed orders
        

so we might get nothing
        

so let's see um here we will inspect and con
        

sole
        

so actually you have the data and it's for the last seven days but we have zero sales for each of the day
        

so as you can see it has organized the data depending on the days and if I check here you'll see today is Thursday for me and you'll see Thursday is the last day here
        

so it has calculated for the last 7 days and the total amount is zero
        

so what we can do is to mpate the database and complete the orders manually we will have
        

some of them as complete
        

so that is what I'll currently do I'll just go to mongod DB
        

so here I am in mongodb and we have the orders right here I have several orders uh
        

some I'll complete but I guess they'll pass the date I don't know which are recent I think this one is recent
        

so I'll just Mark all of them is complete
        

so here we can edit this click on this edit status to complete make sure the sparing is correct um I'll update that document that is from the bottom there and we al
        

so have this as complete okay I think this is the most recent one right here and let's see if it's included in our data
        

so if I happen to refresh it should get the data from the DB and uh calculate the data
        

so we have this look yesterday this is the order that I did and we have
        

some data awe
        

some
        

so we can create another order and then update it manually here
        

so that we have two of them
        

so here let's go to shop and we will add these two
        

so I'll purchase one watch and one phone
        

so that should be 1, uh 90
        

so we add that cut we view the cut
        

so90 we check out
        

so once we click the check out the order will be created in the DB
        

so we we actually don't have to complete the payment for now uh all I will do is that I'll go to the DB here here and I will refresh because I think we now have the order we just complete it manually right here
        

so we have this 1,90 we were adding this to Z because in stripe the amount is usually in sense
        

something like that basically I just want to set this pending to be complete and we update now this is for today this is for yesterday you need to scroll to the very bottom for the lest one and if I come back here go to con
        

sole let's clear and we go to admin dashboard we should be able to get now the data for even today
        

so seven and look for today it updated to this one this is yesterday if this we had sales they would al
        

so update
        

so our data is updating fine we just need to make use of it right here we will say con labels we will get labels from our data map here we'll get an item atent a time but what we will return is item. day
        

so we get the days in an array there then here we'll have con amount or amounts will be equal to data do map and here we will get an item at a time and we will return item do to total amount okay then right here we will say const chart data is equal to we create an object it will have labels and labels will be labels it will have data sets the data sets will be an array of this kind
        

so we pass an object uh the label the label will be sale amount the data will be amounts
        

so this is amounts or amounts okay amount does it have plural or is it just amount I don't know
        

so here we will have background color we will set it to this value lgba invoke that 75 okay 192 192 and and here opacity of 0.6 and then here we will have border color then right here we will have the Border width is one okay
        

so we get the data set and our chart data has reel sent data set okay now right here after this one we will create a another object called options
        

so con options will be equal to an object and right here we'll say scales and we'll say y begin at zero will be true then here this is an object Y is a key
        

so we create that options for y y AIS okay now right here we will simply return the bar component that we get from react chartjs and here data prop will be our chart data then here we'll say options and options will be options there we go I save and we should be seeing our graph now we refresh and look amazing we have now this graph there sale amount our amount here when and I think this amount is in cents
        

so you can format it to be in dollars I think it's in cents but you get the point on how to create a bar graph this should be at the center
        

so at the page uh margin X AO Max hyphen width hyphen save should be at the center here uh there we go
        

so look very nice you can change the colors if you want you can change the colors using this right here background color Buddha color uh
        

so now that we completed our application I want to take you through the last step of deploying this application
        

so we will use use Vel to deploy it
        

so first things uh first is that I want to take you through
        

some issues that I fixed first uh before I deploy the application else uh you might face issues after deploying and the first one is from page. TSX file
        

so this is the homepage okay
        

so if you go to up then this one here um from here I included a key uh when we are mapping through our data
        

so add a key plop like this and then at the top of the file I added this line revalidate zero and
        

sometimes you can al
        

so export con Dynamic and I think you force Dynamic uh it just have issues when generating
        

some pages and uh this is the
        

solution that I found if there is a better one you can just uh let everyone know at the comment section below and then the other one is at our route and that is create payment intent to be specific
        

so I changed how I am returning the errors and I am using these right here next response uh. error and I'm doing this for all of our next response. error
        

so this is the first one here where we check if we have a current user then I think we have others we have this one if we don't have an order and uh finally at the very bottom I added this right here um to return an error if the checks that you're doing here fails okay
        

so we have this if statement if all these checks fail uh we are returning the error
        

so make sure to return an error at the very end as a default
        

so this is the route. TS where we have the crate payment intent uh file and then uh the next thing that I did is at package.j
        

son file I added this right here post install then Prisma uh generate
        

so at scripts make sure to add this particular line at line 10 and then last three um I had to upgrade my next JS version to the latest version because uh I was facing issues with the previous one when trying to deploy and uh it was breaking at build time
        

so to upgrade to the latest version you can go to uh getting started with nextjs installation then you will come right here where we have in install next at ratest react atest and react D at latest and then you just copy that command and you will paste it at your terminal and you hit enter to upgrade
        

so if you check now my version for next I don't know if I can see it is 13.5
        

so probably when you are doing yours it will be even higher but I found that that fixes
        

some uh compatibility issues and
        

so on or gives you better error messages during build time
        

so you can try that or you can upgrade your next 13 together with react and react doome okay okay
        

so those are the changes that I did
        

so now let's deploy and to deploy we need to take our application at GitHub and funny enough I already have this application on GitHub
        

so what I'll do is that I will cut the connection between this app and my GitHub by removing this dogit file uh I think there is
        

some way in which you can hide I'll show it uh right now I'm not sure where it is hide items okay yeah there it is
        

so if you want to see that git dogit file or folder we have this hidden items if you show it it appears if you hide it doesn't
        

so I'll go ahead and delete that one and that um will just remove the connection between my GitHub and this file
        

so that we begin from scratch
        

so what I'll do now is to go to my GitHub account and I'll create a new repository I'll go to my repositories and I'll create a new one
        

so here I'll say eShop I can say prod I'll make it private because it's just for showing you how to deploy and I'll create the repo here we have instructions on how we can go about it creating a new repository pushing an existing repository
        

so we want to create a new repository and push it
        

so here I'll pop the terminal I guess let me put them side by side we just need to say g in it to initialize an empty Repository and that will give us this dogit folder right here um we need to add all the files you can see we have all these changes
        

so we need to add them
        

so I'll say G add and I'll use AA and that will add all the changes then we will commit them
        

so I'll say GE commit minus M and I'll enter the message right here um I can say next 13 up and I hit enter you can enter anything there and then we create the main branch
        

so get Branch minus M and I'll say main I'm just following what we have here then we connect this with our remote repository just copy this one right here I'll copy and we link them by calling that command and then we push to uh our origin main
        

so G push minus U origin Main and that will link this remote repo with our lock one and the code here will be pushed to our remote one now it completed
        

so if we refresh we should be seeing our code here and there we go
        

so once the code is in our GitHub repository all we need to do is to go to Vel
        

so create a Vel account if you don't have one one and I think you can continue with GitHub if I'm not wrong then I'll make sure that I click on the name
        

so here okay we need to create a project actually
        

so I'll click on project and we will import from a g repository this is the one that we want
        

so I'll click on import we can leave that as the name
        

so we will come here at environment variables
        

so what you need to do is to just go to your EnV file and here you'll copy everything copy and you click on here and contrl V once you do that you'll see all the environment variable are added at the bottom here which is really cool and right here you'll click deploy it's it's building you can click on this to see the build process and fingers crossed uh it works uh it might fail but hopefully it works because I had already done it and fixed the issues the one that I showed you
        

so uh let's be hopeful
        

so it's building 44 seconds we have warnings uh warnings are not that bad but you can try to fix them most of them are about dependencies um Dynamics server usage page could be rendered statically because it used headers
        

so we have this red issues there are a lot of them um I don't know if they are major errors but uh generally our nextjs still works
        

so there we go it completed building buing uh you just deployed a new project and it's drive
        

so it worked although there are all those red erors they just telling us that
        

some pages were not generated statically uh we can click on the project I guess and it should open our app and there we go
        

so it's deployed now you can see it right here we try the different categories they seem uh like they are working there we go awe
        

some we can try to register here Charles and the email uh I'll use this as the password and I will sign up it's loading
        

something went wrong oops
        

so what went wrong it failed to register let's refresh refesh and try again uh Charles maybe I already had the account or
        

something I'm not sure let me say 0 one and here I'll say at gmail.com and let this be the password sign up account created awe
        

some logged in
        

so it's working and we are now logged in we can be we can add items to cut and see if they are being added
        

so here we can change color change quantity add to cut view cut and there we go
        

so our app is deployed now only a few things that you will need to fix
        

so I log out here uh one we need to allow this continue with Google
        

so for that you need to go to Google gole con
        

sole
        

so go to Google con
        

sole and I'll click on Google Cloud con
        

sole and right here I'll copy this um domain name that we are given there for free
        

so here we had
        

some API keys and secret keys for Google
        

so I'm looking for the one that has these QQ zq uh client secret uh it might be this i
        

sop
        

so I'll go to API and services and from here I'll go to credentials and I'll click on web client you can confirm the key right here if this key is the same as the one that you have at your environment variable then you know that you are on the right application and then you'll need to add a URL here okay
        

so I'll add this URL which is the one that we were given E
        

soP prod Vel do app
        

so you'll use yours and then you make sure to add this extension stroke API stroke all stroke call back stroke Google
        

so you'll copy that and you'll paste there and you'll save
        

so that you allow uh Google sign up and Google uh sign in
        

so once that is saved you can test it
        

so I can refresh here uh I don't think I need to but I'll still do that and then continue with Google and you'll see here it will give you different accounts that you can continue with and you'll be able to log in with Google right here
        

so if I go to admin dashboard we can see if that works and it works even all this can see if we have ADD product and uh manage orders here we can click on check out to see if it loads check out and it does
        

so this is really cool another thing that you can do is to go to stripe and uh connect a web hook to you uh this particular application the last thing uh you can go to stripe let's try do doing that
        

so once you are logged in you can go to developers then you'll go to web hooks then right here you'll add an endpoint
        

so endpoint URL
        

so it will be this but we should add our web hook end point uh which was at Pages then stripe web hook
        

so here it should be stroke I think API then stroke stripe hyphen web hook and then listen to event on your account version we select events
        

so which event uh are we rening to
        

so if we come to stripe web hooks you can check we want charge succeeded that is the only event that you're listening to
        

so we have charge here uh click on this drop down then we want to recent charge succeeded then we will add that event and we will add the end point
        

so here it's enabled charge succeeded whenever we make a payment it should uh come here but you need to do one more thing you need to add this signning secret to to be your key
        

so I'll copy this one and then you'll go to verel to this application
        

so I'll click continue here I guess and uh how can we update our environment variables okay I'll click on home here then we have this project I'll click right here I think I can go to settings we have this and now okay we have here environment variables stripe web hook secret
        

so we want to update this one edit
        

so change this key to the one that we copied from stripe and you go ahead and save okay it came at the top here updated just now
        

so here um I'll click on any data D data enter a card number you can use this one 42 42 42 42 any future date any CVC and I'll pay it's processing uh check out success let's view our order and uh payment is pending okay let's refresh now give it
        

some seconds and refresh and still it's pending
        

so our web hook uh it's not working okay
        

so let's check stripe let's refresh
        

so here we have charge succeeded but it failed to deliver the event
        

so it will try to deliver again in like an hour
        

so after several trials I was able to re
        

solve our stripe web hook error and what you need to do is to redeploy your project once you update your environment variables
        

so to redeploy you can actually click on the project um and then you can click here on deployments and right here you can come come to the profile and you click on redeploy okay
        

so once you redeploy you can test out if it's working by coming right here and resending the request
        

so you can click on any and resend and you'll see if now here it will be checked as you can see I made a lot of Trials right here for my case it actually uh stopped showing this error 400 and it started showing this error right here 45 method not allowed
        

so I realized that this error comes from uh our API
        

so if you click on logs you'll be able to see your production logs and you can see we have this s here 45 and it was saying that Prisma is not defined okay
        

so I fixed that by importing Prisma I don't know how this happened because area it was working on locally
        

so make sure you have Prisma imported or any other errors that you might have right here once you do that you uh push to your GitHub uh repository and then it will automatically redeploy your application and you'll wait okay
        

so you'll go to projects I guess CH
        

so once you click on the project you'll confirm if it has completed redeploying again you'll need to give it
        

some time like two or 3 minutes and then now you'll come back and retest your uh test here
        

so you will click on any of the charge here and you resend
        

so if I resend that it has resend and if I refresh it should be marked as succeeded if it's not then uh there is still an issue uh which needs to be fixed and as you can see now that is succeeded now if I come back to my eShop here I had created these two orders right here and if I refresh you'll see now that the payment status should be paid
        

so we have this one is paid okay it worked for this one but not for this one anyway let's try to purchase
        

something now and uh see if it will work
        

so I can buy three of these
        

so here we add a line a number then I pay check out succeeded let's check if it's f fired here yeah it succeeded okay let's check our orders and look it succeeded payment status
        

so a few seconds ago
        

so it's working now and now we are finally done with our course uh I know it was a huge one but we have created a complete e-commerce using and next 13 making use of the app router uh T CSS typescript and
        

so much more we created even the admin dashboard and processed payment using stripe al
        

so worked on our o even Google or
        

so I hope it was worth it
        

so if you really liked my content please make sure to leave a thumbs up al
        

so um subscribe and share with your friends and if you need to support my content father you can find me on patreon at CH Charles and I'll leave a link at the description section below
        

so uh I'll be seeing you on the next course 
        

Post a Comment

0Comments

Post a Comment (0)