Let's Build 3 Full Stack Projects with Next.js 14

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
we are about to build not one not two but three full stack projects with NEX js14 okay we're going to start it off by creating this fully functional e-commerce website then we're going to make this beautiful job listing website and last but not least we're going to create this quiz website for developers with leader boards and Stat tracking you'll also learn how to use Prisma mongod DB tailwind and and much more so let's get started on these three full stack projects here's the homepage let's create an account so we can have access to all of the features I'm going to click on this user icon and click on sign up and now I'm going to create me an account so apparently I'm already a member so I'm just going to go ahead and sign in and we get authentication successful now let's add some items to my shopping cart I really like this stack Overflow shirt so I'm going to add it to cart but it says I must choose a size first I'm going to click on small add it to cart and we get the confirmation that has been added also like this looking for someone who can commit shirt size large that's been added and I think I might get a shirt from my friend I'm going get this debugging shirt small add that to cart as well all right so I'm going to go ahead and view my cart now and I'm actually going to increase the quantity of the stack Overflow shirt to four and also increase the GitHub shirt to three and I'm going to go ahead and click check out and before I put in my payment details I'm actually going to go and check the mongod DB database where all this is being tracked so we got my order ID my user id amount the currency the status which is a weit and payment because I didn't put in my payment details yet created date and also the payment intent id and also if I head over to my order page where I can track all my orders we got my order here with my order number my status my items and also my total so now let's actually go check out click on check out type in a fake card number click on pay now and it's processing and now my card is empty payment successful and now we should be pushed back to the homepage so now inside of the mongodb database my status changed to payment successful and also if we head over to my order page the status changed to payment successful we can also add items to our wish list so if we hover over a shirt and click on this heart icon we can add an item to our wish list if we try to click it again we'll get a error message saying that it already exists in our wish list so I'm going add a few items to our wish list I'm going add that one and I'm going to come down here and add these two add that one and that one and then click on this heart icon now that it's red so it's showing red because we got items in our wish list and from here I can add some items to my cart so I can go ahead and add this stack Overflow shirt to my cart and it shows that it's been added to my cart I'm go and click on it and now it's in my cart so if you don't see a shirt on the homepage that you would like you can click on view more and here you can view all the shirts that we have available you can also sort by Price low to high and price high to low and from here you can add to favorites if you want and you can also add the cart but you must choose a size first so that is all let's go ahead and get started on this project all right so we're going to start off by creating our project with nextjs so inside of the terminal in vs code we're going to type in npx create next app at latest and I'm going to do a DOT after mine because I want it to be created in a folder that I'm currently in and it's going to ask us a few questions so we are we will be using typescript in this project es lint no Tailwind yes Source directory no app router yes and um the customize import Alias this is optional um I'm going to use it you don't have to and I'll be using the at symbol all right give this a second and then we're going to clean up some files and then install all of our packages and get our database connected and um set up Prisma and stuff and let's see what it gave us so we could clean up some of these files so inside of public let's get rid of this next and versal SVG I'm going go and delete those and it's focon I'm going to delete this and inside of page I'm going to select all delete it and then just export a page if my Sni if my snippet works there we go all right nice and we could change this to home just so we know export default home like that all right cool so now let's go ahead and install Prisma Prisma client nexo just so we can have all of that installed already so let's open up the terminal again and we're going to type first we're going to install NEX off so it's going to do a mpm i next Das off and and then the next packages we're going to install is Prisma client and uh Prisma adapter so we're going to do mpm install at Prisma SL client and then space at off/ Prisma SL adapter I mean Dash adapter and now uh we need to install Prisma as well so we're going to do a mpm install Prisma D- save-dev install that all right and let's head over to our package Json and make sure everything is in here so we got ni off we got Prisma client Prisma adapter and we also have Prisma here as well with types script and Tailwind all right cool and now let's go ahead and run a command inside of our terminal to generate a Prisma schema Forest um so we'll be using mongodb so we're going to do a MPX Prisma in it space Das Das data source Das provider then we're going to do space mongodb so mongod DB and then press enter and it should create us a Prisma schema folder a Prisma folder inside of the um root so let's go and take a look at that as you can see we got our schema here so we can remove this and keep everything else database client perfect so it also created us aemv file as well so this is where our marod DB database URL is going to go so I say we go ahead and head over to mongodb Atlas and create an account and get our database set up so head over to your browser and head over to um mongodb Atlas and create an account if you don't have one all right so once you're signed in or if you just created an account you want to head over to where it says new project so here's my old projects to explore X so I'm going to click on new project and we're going to my computer's going so slow right now so for the project name I'm going to name this Dev Das threads click next and the permission is going to be me create project so now we're going to head over to database click on database and we're going to do build a database uh we're going to do a free one we don't need to pay for anything uh you can keep the names cluster zero if you want and then just uh the region could be the default region and click on create all right so for the username and password so this is really important so for the username make sure you remember the password that you put here uh obviously if you was looking to deploy this you would want to make a a password that nobody can um know so I'm just going to put uh for this practice project I'm just going to put admin and then for the password I'm just going to do admin and now I'm going to do create user all right and then scrolling down um get rid of this actually I'm going to remove my IP address cuz your IP address should show up there and um for the IP address we just going to do 0.0.0.0 and we going to do add entry um and I believe that is it we can go ahead and finish and close and then click on go to overview and now what we want to do is we want to click on connect and we're going to click on drivers and we don't need to install mongodb cuz we're using Prisma but we do need this um our database URL so we're going to need this here so let's copy that and we can close out of this and I believe that's all we need for now so we could just close out the BR browser so here we just going to paste that URL right here and here's the trick so as you can see it says password here so make sure you put the password that you made here so I'm going do admin I don't know okay that was weird do admin and then after this slash here so right in between this slash in this uh question mark I'm just going to put store so just you could put anything there I'm just going to put store all right and just give that a save all right nice so now let's head over to our schema and actually start writing our schema out all right so to help out with our schema a little bit we're going to head over to our browser and then head over to off js. deev and once you're on this page going to click on get started and on the left side you should see database adapters scroll down and we're looking for Prisma adapter and inside of there set up they they're using the Google uh provider we'll be using credential provider so you can just ignore that part for now scroll down to the schema and here uh we're going to copy over a few things so um I say that we copy over the account copy over this and also if you notice they're using pogress SQL um so we will get some errors copying this over but we're going to change over a few things so we got account let's head over to our um vs code and we're going to paste that in here and as you can see we're getting some errors here um but we're going to fix those here in a second that's our account and where's my mongod DB okay perfect head back over to our browser we're going to do take this session and we're going to copy this as well I'm going to paste it here right and then last but not least we can ignore user we're going to create our own user schema we're going to take this verification token and paste that in as well so we're getting some errors so one thing first thing first I'm surprised we're not getting errors for this here because um when you use a mongod DB you can't use DB Tex you only can use DB string so let's change that to DB string I'm going to change this one to DB string I think I'm zoomed in a little bit too much maybe maybe that helps all right I'm going to change this one as well to DB string all right and also when you use a magod DB um whenever you're doing the ID string you got to make sure you add um at map and then inside of the inside of here you want to do underscore ID like that all right so we got user user relation field user ID on delete Cascade okay and the reason why we're getting error cuz we don't even have a user schema yet but we're going to we're about to make that but I just want to make sure we get all the errors done before we before we do that so um inside of this one since we're using mongod DB we got to make sure we do at map inside here _ ID right uh so there and for the verification token so each schema has to have an ID when you use a mongod DB so inside of here you got to make sure you do ID and then we're going to do string and then same thing at ID at default and in here we're going to do CU ID and then outside of here we got to make sure we do our mapcore ID all right perfect and let's go and make our user schema now so we're going to do a model user and we're going to take in an ID CU like I said you got to have an ID for each model and so with mongod DB plus we need a user ID anyway do add default CU ID and then we got to make sure we add the app map _ ID all right so we got that and we're also going to take in a name which is going to be a string make sure you add a question mark after it and we going email which is also going to be a string um and the email is going to be unique right and we're going to do we don't need to add email verified going to do image and the image is going to be a string and then we're going to have a hash password hash password and that's going to be a string as well and we also going to have a created at that's going to be date time and the default is going to be now all right Sav that make sure that perfect and as you can see once we saved it it's popped up we got account and sessions that just popped up automatic um but we're going to switch this up a little bit so for account I'm going to do account I'm going to change this to account like that and then session sessions can stay like that all right so underneath this created at we're going to do orders and that's going to equal orders with an array so we don't have that that model yet let me just scroll up make sure we got everything all right perfect let's go and make that order model now all right so model order and let's go ahead and get we got to get rid of this s there all right so have a ID which is going to be a string and we're also going to take in a user and that's going to be user so our user schema so we're got to make sure we add a relation and the relations will the FI is going to be user ID and now I need a reference which is just going to be ID all right save that and now we need our user ID D which is going to be a string we need the amount which is going to be a float currency it's going to be a string status which is going to be a string we need to create a date this is going to be date time and the default is going to to be now uh payment intent id so payment intent id like that that's going to be a string make sure you add a question mark after it and make sure this is unique because each payment attent ID has to be unique give that a save and last but not least inside of our order model we're going to do items and that's going to equal order item like that so we got to make a Model A order a order item model and we got to make sure we give it the right relations so underneath this order going do a model order item and here same thing we going do the ID string and now we need to pass it our order ID it's going to be a string and then order this is where we're going to add that relation in do relation then a Fields is going to be order ID and then a reference is going to be oh I messed up sorry comma after the after that and I'm going to do reference and then ID like that all right and now um scroll down some so inside of our order item so this is basically each product we're going to save that inside of our database and it's going to be tied in to that specific order and user so all of this is got kind of going to like feed off of each other it's pretty cool um so we got our name it's going to be a string so that's going to name of the product uh the quantity [Music] quantity and it's going to be integer int and then price it's going to be float uh image it's going to be a string and then the size it's going to be a string so the size of the shirt that we're selling and then we also need to add unique tag at the bottom so do two add signs unique and then we do order ID and then name like that all right I think we are complete with our schema so um what we can do now is open up our terminal and then we're going to run an MPX Prisma generate so anytime you make any changes to your schema just make sure you run this command uh so it can update your whole entire project with the schema uh so and I also think it updates the database as well so we're going to MPX Prisma generate press enter give it a second uh so all I see is green so got the check mark so we're all good there perfect so um there's another package that we have to install so keep your terminal up we're going to install bcrypt so we're going to do it mpm because we're working with passwords uh cuz like I said we're doing credentials so we're going to make sure we install this so we're do npmi D- save-dev at types SLB Crypt let me zoom in some so you guys can see scroll down then press enter all right cool all right nice nice so let's close out of everything and let's get started man uh first things first inside of our app folder we're going to create another folder and we going to do parentheses off so this is where all of our authentication stuff's going to go our authentication components our sign up form our signin form everything that deals with authentication is going to go inside this folder so inside here first we're going to make a AP API folder all right and inside of this API we're going to create another folder and we're going to do brackets dot dot dot next off then make sure you close the bracket all right and inside of that folder we're going to do a file and it's going to be called routes.js or TS forgot we're using typescript all right so now let's go ahead and set up our next off um to connect with our database and everything uh so let's go ahead and we're going to import a few things going to import bcrypt uh bcrypt I wonder why it's not autocompleting let's see if this works bcrypt okay all right and then we also going to import nexo that's coming from nexo um not SL NEX from Nex off like that and we're also going to import off options like that and I'm going to import credential provider credentials provider and and Prisma adapter right and we're also going to import Prisma but that's going to be coming from our lib folder uh because if we just import Prisma and um inside directly inside of this Pro uh file we're we're going to be getting a lot of Errors saying that we call them Prisma too much so to fix that uh inside of our root we're going to create a folder and it's going to be called lib all right and inside of this folder we're going to create a file it's going call Prisma dbts all right so let's go ahead and do this so we're going to do an import Prisma client from Prisma client and then we're going to do a declare Global in here we're going to do VAR Prisma press my client or undefined all right this is all inside of the docs as well and um on stack Overflow so do a cons client and it's going to equal Global this that Prisma then we going to do new Prisma client all right then we're going to do if our process. EMV EMV sorry I can't type tonight that nodecore EMV is not equal to production we're going to do Global this Prisma equals client all right and then we want to export default client so export default client all right give that a save and we shouldn't have to go in this file anymore so we can go and close out of that head back over to our um API our route and now we can go ahead and import that inside of here so we're going do an import Prisma it's going to be coming from our lib folder so at slash lib SL Prisma DB Perfect all right so just to save us a little bit of time I'm should go Ahad and just paste in the rest of this code in this file but uh this will be inside of the gist in uh GitHub gist inside of the description so just go ahead and just copy and paste this file uh it's not too long I will explain what each line means uh just just to save us a little bit of time um cuz I know you guys are ready to start building out these components we're going to start with the nav bar so um I'm just going and paste this over here and as you can see we are getting some errors so we got credentials and that's because we put brackets here for credential provider so let's go and get rid of that and we are getting an air for adapter um in the project that I made uh I believe I'm using uh let's go to package locked uh Prisma adapter 1 Point version 1.010 so um and this one I'm using 0.14 uh 0.14 so um we could just leave this error here for now I am going to see about fix this error because um not sure what it could be causing it so we're going to come back to that but I'm going to go over and explain some of this code um most of this is inside the docks um um especially this part here which I'm starting to think we don't need because we will be creating our own sign in and signup form for for our website and if you guys never used nexo before you can use their built-in um sign up sign up for or sign in form I um they I believe they have their own signin page and sign out pages that you can use and I believe that's what this is for so I'm not sure we even need this uh but we're going to keep it for now but down here is where all the magic happens for our custom form so uh the first thing we're going to do is this if check uh we're basically just checking to see if the email and password are provided and if they're not we're just going to throw in air s invalid credentials and then here um this cons user basically just retrieving the user from the database uh based on the email that's like that they provided and then um here is the hash password uh we're basically just checking to see if the user or the hash password um is available or I mean if not if it's not available and if they're not we're just going to throw an error and uh correct the password uh we're just comparing the provided password which is this credential password so whatever whatever password the user types in and we're going to compare that to the password inside of our database and and um we're saving that inside of a is corrected variable and uh basically here um we're checking to see if the corrected password if it's not correct we're just going to throw an error and last but not least we're just returning the user and down here we got our Pages uh signin page like I said we're doing our own custom signin form and sign up form so this is basically just telling next off that we're doing our own form and go suck it we're not using your um and uh down here is our session if you guys don't know what JWT stand for it's believe it stands for Json web token um and uh down here is our secret which we didn't write inside of our NE EMV yet but we will be let just basically just um give it make a we're just making a NEX off secret and now we're just exporting some stuff down there and to fix this eror here what we're going to do is open up our terminal and we're going to type in mpm I next o SL Prisma adapter so I believe I had you guys install o/ Prisma adapter which was working fine on my project but um after doing some research um there's an issue going on with type script or something with this adapter so the workaround is to install next off SL Prisma adapter and then all we got to do is just change this up here this import to next off so next Das off Prisma adapter and that should get rid of that error nice so now it's time to start our nav bar let's go and close this close everything up and let's go CL let's close out everything thing and let's open up the app folder and inside of the app folder we're going to make a folder and this is going to be called actually outside of the app folder we're going to make a folder so inside of our root it's going to be call components all right and inside of this folder we're going to have another folder in here it's going to say UI this is where our button and our input is going to go and let's go to make the nabar file so Navar TSX nice just going to export it and head over to our layout this is where we're going to import it and we're going to fix up everything in here as well but I say we go ahead and start the nav bar just going to import the nav bar and over top our our our children right inside of our body I have nav bar perfect so I'm going to go ahead and open up the another window and resize all of my windows so we guys can see the browser and the vs code so give me one second all right so I got the browser open now and I went to Local Host 3000 I haven't started up the server yet because there's a package that I want us to install first head over to your terminal and I'm going to type in mpm I react Das ions space-- saave going to use a bunch of react icons in this project so whenever that finish we can go ahead and start up our project now we're going to do mpm runev right close out of that and let's give this page a refresh so while that is loading let's head over to our the root of our project and we're going to create a folder and it's gonna be called constants and inside this constants folder we're going to create a file called index.ts if you guys follow any one of my projects you know you guys know what what's going to go in here it's just basically our links so that way inside of our nav bar we can just map through these links instead of writing each each link one by one uh just save some time and save some space inside of the files so um inside of the description there's going to be a GitHub gist or you can head over to the GitHub repository and just copy over this file like I said it's just links it's not or you can just pause the video and just copy and uh type all this out right quick it's not too much so we got our main links here and we got our user links there so we go and close out of this and then we're going to head over as you can see our project um is black we got white text uh we forgot to clear out this global CSS here so head over to the global CSS and get rid of that let's give that a save and should turn to normal while we're here we're actually going to add in a style that we're going to be using a bunch and it's going to be like a little custom container that I created it's going to do at layer do Styles and we do dot main container you can name this whatever you want I just named it main container the reason why I couldn't name it container is because CS uh Tailwind has a container uh styl in class already may we probably could have overd it inside of the Tailwind config but rather just do it like this so main container and do apply width 90% And then we're going to do a Max width of 1,400 pixels and then we're going to do MX a Auto right give that a save and we can goe and close this out now and head over to our nav bar and let's go ahead and get started so components nav bar we should see our nav bar there with our page nice all right let's go and get started let's do our Imports first things first though we got to make this a used client got to make this a client component and we're going to import some stuff so we're going to import use state state from react uh we're going to import link from njs make some space here cuz there's a bunch of imports all right and we're going to import sign out uh I think this goes in Brackets sign out this is going to be coming from next off SL react all right and then we're going to import our links now so we're going to import main links and then user links all right and I going to make some some um like a comment there and this is going to be all our icons just to organize it a little bit we're going to be using AI outline user AI outline shopping cart and AI outline heart from react icons SL Ai and then we're also going to be using fi menu fi menu and this is going to be coming from react icon slfi and we're doing MD close it'll be better if I just copy and paste all of this MD close and then we're going to be using TB brackets angle all right uh there's a few other Imports that we haven't created yet but um we're going to come back and import that but for now let's get some let's get some styl and done eras some jsx so inside of this our return we're going to have a nav let me come down some and then we have a div our div is going to have a class name of main Das container have a border border bottom sorry a border One Flex justify [Music] between item Center a py of two and position relative give that a save and we should see our border there as you can see perfect inside of this div we're have a going to do our logo which is going to be a link right and whenever you're useing nextjs link you got to make sure you're add the H here and it's just going to take us back to home like that all right and inside of this link we have a div with a class name of flex a gap of one item Center a text XL a font medium and a text block all right take a quick look oh you didn't put anything inside this div all right so in this inside of this div we're going to have H1 and it's going to be called uh Dev Dash threads all right and this H1 is going to it's not going to have a class name but underneath this H1 this is where we're going to have that TB brackets angle TB brackets angle like that all right perfect um all right so underneath this link tag this way we're going to map through our main links we're going to do a UL this Ur is going to have a class name of flex Gap 10 and on Max on medium screens and Below it's going to be hidden all right and let's go to map through our main links so we're going to do main links map and do link and we're return a jsx so make sure you do parenthesis uh and do link we return in a link for each um link and then we're going to do hre and the hre is going to be link. rout and right in between this link um tag we're going to do a Li and we going to have our link. label here like that give that a save nice all right so underneath this UL we're going to have a div and it's going to be a with a class name of flex gap of five a text XL and we're going to do a little trick here we're going to do brackets the N symbol the greater than symbol the star and then make sure you close it and then we're going to do cursor pointer like this if you guys don't know what this is this is basically just selecting all of the children inside of this div and applying this style into to it that's a little trick and Tailwind so um we're going to have our car icon oh actually we didn't create this car icon yet so let's just go ahead and do um uh AI outline cart shopping cart like that and underneath here going to do our AI outline heart and then and underneath these so let's go and get that a save right quick and see where we're at all right nice um and then underneath this here I'm going to have a div with a class name of Max MD hidden Max MD in all right when you zoomed in it's like hard to even operate on here and um here let's just keep this div like this for now all right so we got our icons there perfect um so inside of here this is going to be where our um hamburger menu is going to go whenever we hit medium screens so um but before we we do that we need to make we need to make some State let's head up here and inside here we're going to do const open mobile menu and then set open mobile menu and by default it's going to be false and since we're here let's go ahead and do the user menu as well we're going to do a con open user menu and then set open user menu and same thing by default it's going to be false all right going to save okay and underneath here um let's go ahe and do our mobile menu Handler and our used menu Handler going to do a const mobile menu Handler and in here we're just basically just going to set open mobile menu to toggle open mobile menu right and then same thing with the user menu do cons user menu Handler and same thing we just going to set open user menu to toggle open user menu all right perfect let's head down here now and inside of this div actually on this div where this is where we're going to have our on click at for our um open our mobile menu Handler so we're going to do onclick and do mobile menu Handler like that and inside of this div this is where we're just going to do open so if it's open mobile menu question mark we're going to show MD close which is the close the little X icon but if it's not we're going to show fi menu which is our hamburger menu fi menu is that simple to to create a responsive nav bar it's really that simple all right uh let's take a quick look and see if this works so let's go to inspect oh it's right there all right I don't think we is supposed to show though on here oh okay let see what what we did wrong here we put Max MD hidden we just need MD hidden MD and up in all right let's take a quick look inspect whenever we resize our screen and there we go we got our menu and as you when we click it it shows X let's open close open close nice all right so now let's create our um our user menu down here so underneath this div so this div here we're going to do I'm going to put comments here let's do user menu like that just so that way we can know everything all right so underneath here we're going to do brackets so we only want to show this when our user menu is open so we're going to do open user menu we do NN parenthesis and then we're going to have a div with a class name of zindex 10 position absolute a right of zero a top of 40 pixels a width of 28 a BG of gray 700 Shadow MD rounded ND pattern of four text white a Max MD hidden [Music] and I got to scroll over so much freaking um so much styling all right it's one more so we just going to do a text Center like this all right and before we write anything in this div I think I forgot something so we need our actual user icon there we forgot to put that it's right over top of this div so right underneath this AI outline heart we're actually going to have another the div here and this is going to have the same thing a class name of this one's going to have a Max MD hidden all right and then we also want our on click on here so we're going to do on click and this one's going to be our user menu Handler all right and inside of this div this is where we're going to render our AI outline user that us save and we should see our user there nice when we click it it should we should have see something there we go we got our little menu there that shows perfect but we don't have anything inside here inside of this div um this is where we're going to render out so when we click on this we want to show initially if you're not logged in we want to show log in and sign in but when we are signed in we want to show you know orders our favorites which is our wish list and we also want to show sign out so what I'm going to do since we don't we didn't we haven't passed in the users or created our G user action yet what I'm going to do we're going to create some State up here so we're just going to do const user authenticated and then we going to do set user authenticate and it's just going to Bea it's just going to be false State false that simple all right so down here um all right cool actually what we should do is instead of user authenticated let's just change it to user and then set user I think that's a little bit too much right user authenticated like got to type that in every time um so underneath here inside of this div uh we're going to render out so if is if we are a user to do brackets so we're not a user actually so we're not a user question mark parenthesis we render out a UL no class name on it it's going to be a link and hre is going to lead us to our signin page that we haven't created yet so let's do Dash sign in I mean sign Dash in have Li it's going to say log in like that let's take a quick look so we are getting the error here oh we forgot to okay we forgot to put um our else that's why we're getting the error uh for now we could just put null I just want to see if this works but we are going to write a different l statement's click on it all right so log in nice um and right underneath here we have we can actually just copy this whole entire link like I said it's going to be two buttons or two links one's going to be sign in and one's going to be sign up so slash sign up sign up make that give that a quick save nice all right and so now we need our El's or else so we can get rid of that n or else make sure you do parenthesis have a ul and this is where we're going to map do our user links and do user Links at map link all right and in here have a link and I have hre the same thing as the top this just going to be our link. route and inside of this link this where we're going to have our Li and it's going to have our link. label all right give that a save all right so we shouldn't see it because we're currently in our with our state it's we're currently not a user so let actually switch this to true and let's see if that changes nice we got our orders and now we got our wish list and we need our sign out button so right underneath this UL actually we can keep it stay inside this ul and we could just do a Li and give this a class name of cursor [Music] pointer and we're going to do a onclick and we're just going to return the sign out that we imported from Nex off sign out like that and inside this Li we could just do sign out right may we go perfect all right and like I said so we got this fake State here um we can actually just comment that out for now we got it working uh we're actually going to pass in a real user and once we create our um sign up forms and stuff but we need our mobile menu now because we don't have our mobile menu yet so right underneath all of this let's see where we're at all these deals be get it's confusing sometimes we got our UL closing UL we got our div there um so right underneath actually no not that one so we got our UL we got our closing div got this div all right nice right underneath this div here this where our mobile menu is going to go so I'm just going to do mobile menu like that all right and I don't know if I'm zoomed in a little bit too much I'm going to go back and look at the footage here in a second maybe I can zoom out a little bit more like that maybe all right we're going to do open so this open mobile menu in in parentheses going to return a div with a class name of MD hidden all right and then inside this div we're going have another div and it's going to have a class name of absolute a right of five a width of 48 BG grade not 100 actually we should do [Music] 700 I believe that's what we did for our uh user menu a py a five a shadow ND around it MD a padn a four text white uh text Center and then here's the funny part we got to do a zindex of 9999 it's you guys going to see why I put that there uh in a few um all right so inside of this div we're going to have a UL which is going to have a class name of flex Flex call and a gap of five all right and now we can go and map through our main links again main links actually we could just go up here and just copy this save save us a little bit of time let's copy this here come down here and paste it in here right so after we map through there we're going to do brackets again and same thing if we're not a user we're going to show in login sign up and if we are a user we're going to show our um our links our user links so we can actually copy this here and I'm going to paste that down here like that all right let's take a quick look at this I'm going to inspect open up and as you can see it's all bunched up of we probably got to add some style in there um all right cool let's see what let's see what's up with that user links we are a user so that's that's it's showing the right links right link you will I mean what we can do is probably just here we do a class name of flex Flex call and then a gap of five let's see if that works inspect all right perfect each one has a gap of five and let's see let's make user false false and we got our login ass sign up all right so we got our uo here which is our whole thing then we got a uo inside of a uo okay that's that's what the issue is okay so I copied over the wrong Cod so let's actually get rid of that and we're going to do fragments all right let's get rid of this here as well and let's do fragments like that and now let's save it and as you can see now I got that styling that we have on this U here okay now it makes sense all right Perfect all right so so our Navar styling is complete uh we actually have to change our font though cuz we're not using this font so let's head over to our layout and we're going to switch over our font a little bit uh so instead of enter going to do Railway rail way and this my first time using this font and all I can say is it's I like it really like it going to change that to rway and change this enter to railway like that so we need to tell it what um weights we're going to be using um going go and just import them all so and after this lightting we're going to do a comma and then make some space there just do weight and do 200 300 400 500 600 700 and 900 I don't know why I don't have 800 on here but I guess we didn't use it uh for the metadata um we could change this to Dev threads let's do Dev Dash threads and just going to do Ecommerce site e Commerce website all right and so we got to change this to railway down here let's skip that a save all right nice okay and since we're here um now I say we actually go ahead and pass our actual user inside of our Navar um cuz we were just using the fake state for now but we're actually going to pass in our user but before we do that we got to create a file inside of our context folder that we didn't create yet soide of the root we're going to create a folder context and inside of here where is it there we go going to create a file and this is going to be called off context do TS you can do TSX if you want all right and in here we're going to do a use client and then we're going to import session provider session provider that's going to be coming from NY off/ react and then we going to export interface this typescript do off context props and it's going to do CH we're going to take in the children and that's just basically a react. react node right then we got to do our export default function so export default function of context and we're taking in ch our children uh children going to add our interface to this and then do off context props all right and then in here we're just returning our session provider and it's going to wrap around all of our children like that all right nice so we can go and close this out head over to our layout and we got to import that in here uh so underneath our nav bar going to go to import off context now we got to wrap our whole entire application up with this so right underneath our body and do off context and paste that in here all right so we are getting error here um and I I think I know why we're getting this error so let's head over to our terminal let's hopefully this is a fix and let's go and close out our server and we're going to type in mpm I bcrypt right give that a start and hopefully that get rid of that error there and now let's go to start our server and hopefully that works all right nice so that got rid of that error so now let's go ahead and create our actions to retrieve our user session and to get our current user that's currently logged in so what I'm going to do is close out everything and like I said before everything that deals with authentication is going to go inside of our off folder so open that up and we're going to create a folder in here called actions all right inside his actions the first one we're going to create is our git user session action I'm just going to do. TSX right so this is a short file we're going to do import um we going to do get server import G server session it's coming from Nex off and then we're also going to import our Au options Au options so make sure you do the one with the lowercase a and this is basically our alt options coming from our API route that we created earlier all right and then we're just going to do a export default async function get user session we're just going to return turn wait get server session we're going to pass it in our Au options all right nice and now let's create our next one this is going to get current user going do get current user. TSX right so in this one we got to import Prisma and it's going to be coming from our lib folder so SL lib always got to type it out whenever I'm importing Prisma from my lib folder I don't know why going do import and we're going to import our git user session action that we just created and now let's create our function so cons get current user your current User it's going to be async and we're going to do a try catch so first we're going to try going do a concession that's going to equal a wait get user session all right so if our session. user. email all we're going to do is return all all right see we are getting an error Rec session actually put a exclamation point in front of it and I spell email wrong could be the issue there as well session I user email session is possibly undefined H uh all right let's keep going here maybe we can fix that here in a second and we do a cons current user and that's going to equal await Prisma user and once you click that you should have access to a bunch of Prisma uh methods uh I use some of these um but some of these I haven't used before like aggravated aggre aggregate raw don't know what that is but the one that I use the most is definitely fine unique all right and we got to tell it where to find it so where to find this user we want this we want it to find find it by the user email new session. user. email and this is going to be a string so as a string all right after that we're going to do if current so if it's not current user we're just going to return null and down here we got to return the current user like that and since we're doing a try we got to make sure we do a catch so we got to do a catch and we're going to just catch a error it's going to be any and we're just going to return all all right and we got to make sure we do a export down here I'm going export default get current user like that all right so we're getting an error it says session. user is possibly undefined all right let's see what this issue could be so we got our user. email um okay so maybe put a question mark there because it's possibly undefined so all right perfect so we got our get current user so now we can actually use this inside of our layout head back over to our layout and right underneath here we can just do import get current user and we actually got to make this a async function now so exper default async function root layout and it's this easy all we got to do now since we got those actions we just got to do cons user and that's just going to equal a wait get current user like that all right nice and now we can pass our user inside of our nav bar so user that as you can see we're getting a error here all we got to do is do a exclamation point there and uh we're probably going to airror because we're not accepting a prop inside of our nav bar either so let's actually head over to our Navar component and let's take in this prop we're not going to do anything with it yet because we want to create our now our sign up and signin forms and do user like that all right perfect we are getting airor let's see oh okay just because we have user here okay all right let's just we're set in a user State let's just get rid of that and uh let's see we got three errors is showing oh now showing one nice let's go and save that and I should get rid of that eror there all right so as you can see we got some typescript errors here cuz user can be um has a any type right now uh let's just go Ahad and fix that right quick uh up here we're going to go ahead and import make sure you do brackets going to import a user and this is going to be coming from Prisma SL client and then underneath these Imports right outside of our Navar um component I'm going to do interface nav bar props and we're just going to do user is equal to user the user that we just imported from um Prisma client and now down here going to do react FC brackets Navar props like that all right nice nice so we're not signed in currently so that's why it's showing our login and sign up and but uh we do have our user passed in to our Navar so now I say we create our sign up and signin form so that way whenever we are signed in it shows the actual user menu so let's do that now inside of our off folder we're going to create a folder called sign dashn and in this folder we're going to make a file and it's going be called page. TSX okay and we're going to create another folder inside of the off folder it's going to be sign Das up and same thing we're going to create a page that TSX file TSX all right so let's go ahead and Export both of these that and a sign up page as well all right cool and uh we could keep it like this for now what I want to do is um create our UI components that we're going to be using in these Pages we're going to be using an input and a button so let's go and close out of these for now and then inside of our components UI folder that we created we're going to create two files the first one is going to be input. TSX and the second one's going to be called button. TSX all right so we can go ahead and start off with the button uh first we're going to make it a use client a client component and we're going to import use form status from react D we going do a cons button and we're going to take in some props props we're going to take in going take in a type we going to take in children taking an on click we also going to take in if it's disabled which is going to be a Boolean so if it's the disabled or not and let's go ahead and write our return so we do a cons pending that's going to equal to use form status that all right canor these errors for now we're going to take care of those in a second all right uh underneath here let's write our return statement so we're going to return a button and disabled is going to equal to disabled onclick it's going to be on click type is going to be type and we're going to do ARA dis labeled a little bit of accessibility in here that's going to equal to pendant and we also give it a class name of BG gray 700 BG gray 700 going do a text white a py of one a px of three a shadow and rounded MD okay and inside of this button this is where we're going to have our children like that all right let's go and fix these typescript errors now scroll over some window interface button props and we going to do type make it optional so we got to do button or it can be type submit submit or it can be reset or it can be undefined un defined all right and after that we're going to do our children and that's just a react that react node right and then on click which is also optional our children is optional as well that's going to be a react. mouse vent Handler you got to do brackets we're going to do HTML button element like that all right and last but not least disabled which is going to be a Boolean all right and all we got to do now is add it to our components we going do react FC brackets button props like that all right so we're getting one error type uh let's make sure so we got button submit re oh wait let's see what the ER is all right so what I think is happening unless you remove undefined for now for now but it's going to make us add it once we um add our types and send over the props so but for now we could just keep it like this just so we don't have any errors and have a nice clean project for now all right so let's go ahead and do our input and in this one we're going to we actually got to install a package so I'm going to close out the server and we're going to do a mpm I CSX all right so let that install and then we're going to start back up the server mpm runev close that out we can go ahead and give this a refresh and now we're going to import that new package that we just installed import clsx from clsx all right cons input and this one's going to take props as well we're going to take in a label takeing an ID and take in a type we also want to take in disabled as well just like our button all right let's do WR our return statement and we're going to return a div no class name on the div but after this div we're going to return a label HTML 4 that's going to be for our ID that we get from our props we also going to have a class name on this label which is going to be block text small a font medium and a leading six right so after that go inside of here this is where we going to have our label that we get from our props all right after that label we're going to do a div this div is going to have a class name of margin top 2 and inside of this div this where we're going to render out our input that and this is going to be a self closing tag it's going to take a bunch of stuff so disabled it's going to be disabled which is going to be a Boolean name it's going to be our ID that we get from our props we're going to make this required ID is going to equal to ID our type it's going to equal to type and autoc complete it's going to equal to our ID and last but not least let's do our class name but before you write anything inside of the class name we're going to remove the quotes and we're going to do brackets CL LSX and then do parenthe um parenthesis and now we're going to do back ticks and I got actually got to scroll over so this is going to be a bunch of bunch of Class A bunch of class names for this one all right so uh let me make some space here all right so inside here I wonder if I can take this and all right just trying to make this look as pretty as I can make it all right so we're going to do block with the full around it MD a border zero a px of one a py of 1.5 a text Gray 900 a shadow small a ring one ring in set a ring gray 300 and then we're going to edit the placeholder so you just do that and then do put placeholder let me scroll over some long class name all right the placeholder it's going to be text Gray 400 and then we're going to edit the focus state so Focus going to be ring two and then Focus again that's going to be ring and set and then Focus one more time that's going to be we got to change the color of the Ring going do ring gray 500 and then small it's going to be Tex small and then on small screens and up we're going to do a leading of six leading of six all right nice all right so now after this we got to add a comma cuz now we want going to edit the disabled state of this um input so make sure you add a comma there and now we're going to do if it's disabled do the Ann opacity want the class name to be opacity 50 and then we're going to do cursor default like that all right um I think I go over this every time I do a project so this is called I think this is called short circuiting um like short circuiting uh technique basically um you you could write it out as a turnar operator so if it's disabled do a question mark then run this um these class names and then you do your else which you could just probably return like null or something but with when you do the NN basically if it's disabled that's when the second half of this um is going to fire it's going to um it's going to render out but if it's not disabled that's when it's just going to Short Circuit out and don't even run this um these class names so that's little cool little method there all right so we need uh our interface interface and do input props and a label is going to be a oh label is going to be a string id id is oh man ID is going to be a string our type is going to be a string and then disabled it's going to be optional that's going to be a Boolean right let's go and add it to our component react. FC brackets input props nice all right so we got our label I mean we got our input and we got our button UI components so now let's go ahead and start our sign in and sign up forms okay so inside of our app and our all folder we're going to create a folder in here called components so this will be all of our authentication components so it's going to be our sign in and sign up form inside of this folder so let's go and create those files now we're going to type in sign in form. TSX and then we're going to do sign up form TSX all right let's go and Export them all right and head over to Let's we're going to work on a sign up form first so in here let's go and import that so uh I want to div I'm going give this div a class name of py5 and then this is where we're going to render our sign up form right so we can actually go and click on sign up and there we go we got our sign up form there so now we can go ahead and start styling this up we head over to the component and let's get started all right so first things first we got to make this a client component and try to think if we should just yeah I say we just go ahead and get the styling done and then there's a few packages that we going to have to install uh so we use hot react hot toast and if you guys don't know what that is basically I could show you guys right quick react hot toast it's like notifications that pop up uh it's really cool it's my first time using it in um one of my projects but we're going to be using this so whenever a users created uh if you're success successfully signed in you know you get that little tost right there and then if you get a error toast going to pop up and they got a bunch of other stuff here um that I find like they got notifications pretty cool all right um so yeah we're going to be using that but let's go ahead and install up our form first so turn some jsx let's get it so we're going to do a div my class name and do a margin top of eight small screen me do MX of Auto small going do a width of full small again Max width 2 XL medium screens and up we want it to have an outline then we have to outline one and then we also want the outline to be great 200 right and inside this div we're have another div it's going have a class name of PX4 a py of eight small screens and up it's going to be rounded LG and small screens and up a px of 10 right and inside this div this we have another div and this one's going to have a class name medium screens up it's going to have a text for XL small screens and up it's have a text of 2 XL a margin bottom of five uppercase a width of full text Center Flex item Center a text of white a gap of one justify Center and do a BG of gray 700 a py of four and then arounded MD man bunch of bunch of class names on that one all right and inside of this div just we H1 and it's going to say join the BT Squad it's kind of cringy to be honest but whatever join the GT Squad let's take a look at that there we go nice all right and we're going to have our TB brackets TB see if it auto completes TV bracket angle yeah all our little logo icon there nice all right so underneath this div this is where we're going to have our form uh not that div this div here this we have our form a space Y6 and a margin bottom of three all right now we can go ahead and render our all of our input and our in puts UI component and our buttons let's go input give Auto Auto Import input um it's not Auto Import and let's go and import it I guess import input from slash components slash UI slash input all right so let's head over to that something's up must okay we forgot to export both of these so let's do export default button and for the input we got to export it as well export default input all right save that head back up to our signup form all right and now we got our input our first input is going to be type and the first one's going to be type text and then the ID for this one's going to be name and then a label is going to be name with the uppercase M and then disabled is going to um we could just do disabled for now uh but it's going to equal to is submitting but we didn't set that state yet uh but so for now I just put disabled um actually we could just do we could just type it in is submit all right so we might get an error but we got our input there and yep we got a error so let's go ahe and set that state I guess right now so that way we can see everything working we're going do a con is submitting and then set is set is submitting that's going to equal use State and default is going to be false right and we got to go ahead and okay we already import it use State give this a quick refresh we can actually copy this input and just change up uh some of the props that's sent over so it's going to be three inputs 1 2 3 and the second one's going to be email for the type for the ID is going to be email for the name I mean for the label it's going to be email with the uppercase E and disabled is is submitting third one is going to be type password the ID is going to be password and a label is going to be password uppercase p is submitted let's give that a save and there we go we got our inputs there now we need our button let's run the these here and render our button UI component there we go and this takes in a type which is going to be submit and we also got to render our children inside this so we can just type in create account good look nice all right so if we already have an account we want a way to send the user to the sign in form so right underneath this form going have a link make sure we import it from NY and this link is going to send us so hre is going to send us to the sign in page right inside this link we have a span with the class name of margin top three a hover of underline and it's just going to say already have an already have an account question mark sign in and I use a HTML uh entity or like this little arrow and it's basically the N sign the pound sign the number 8594 and press enter and as you can see I got that little arrow there we click on it it's going to take us to the sign in page let's see sign in perfect so we got sign in page but we want to go back to the login page we want to finish this all right so I think the styling is done we exported it so now let's go ahead and add our let's create our server action that we're going to be using on this signup form uh so we're going to head over to actions and we're going to create and we could create this we can name this whatever we want uh but I'm just going to name it off actions off actions. TSX all right and we're going to be using you server we got to import a few things we're going to import Prisma from our lip folder SL liip SL Prisma and we also import revalidate path that's from next cach and we're also going to import bcrypt bcrypt from the Crypt all right so let's go and create our function now so we're going to export async function it's going to be create user we got to take in form data and let go to the form data and we got to do our try catch so we're going to try cons email that's going to equal to form data dot get and it's going to get the email and as a string um and now we need our name and password as well so I'm just going to go and just copy this paste it two more times we're going to need our name and this is our name we need our password this is going to be password all right so basically whatever we named our inputs that's where this data is coming from so if for example if I head over to my signup form if I have an input and the name or the ID um um is um I don't know um phone number or telephone number or something um then inside of my uh server action this would be you know this here this dogit will be just telephone number you know it's whatever you name your inputs that's where we're getting this data from all right so after this still inside of the try we do another try first time ever doing a try catch inside of a try catch uh so we're going to do a cons existing user that's going to equal a wait Prisma do user do wait wait oh I SP wait wrong I was wondering we had the error that find unique find unique and we're going to tell it where to find it so where it's going to be email all right so that's if the user exists going to so if they we input an email that's that already exists inside of our database um it's going to be save under existing user all right and if we get existing user we're going to just throw a new error and you can just do you're already your already a member right cool so after this going do cons hashed password I'm going to do a wait decrypt do hash and do password comma 12 right that's our hash password and right after this we're going to do await Prisma user. create and we got to send it over our data it's going to be email it's going to equal to our email um input that we the stuff that we get from our email input and then name it's going to be name and then hash password going to be our hash password like that all right we are going to error name oh forgot the comma here all right cool so after this we have to revalidate our path all right now let's do our catch statement so we did two tries so we got to have two catches so we do catch so the first one we're just catching the existing user and we're just going to return existing user and we could type in you are already a member a member please sign in all right and so now we got to do our next catch do two go here going catch error and we can just console. error um I guess error do like that perfect all right so we got our server action uh if you guys don't know what this is I had I got a video on server actions um personally I like it but um you can't really use it all the time um if you want to over complicate things you can but sometimes as you can see in this project you use it sometimes and then you can also um reroute back to the old ways of doing things which is you know your get and your uh post request and stuff like that so um yeah so this is our server action let's go ahead and close out of this and close out of that close out of that and head over to our input form so there's a package I want to install first let's go and install toast react hot toast so open up your terminal close it out and uh let me get the so is mpm I react Dash hot Das toast okay okay so that's installed we can go ahead and start up our server again cool so for react toast to work we actually got to make a file inside of our contacts folder so let's go and close out of that open up our contacts and we're going to create a file uh see contacts it's going to be called hot toast context toast context TSX all right and here we're just going to do a use client and then we're going to import toaster from react hot toast then we going do a cons toaster contacts and we're just going to return toaster that it's going to export default it all right we're going to en close out of that and head over to our layout and here we're going to import it here and wrap our um project with it so import poster context so we're underneath all context this where we have our toaster context we're going to wrap our nav bar and our children in it right um all right my apologies uh we don't need to wrap the whole entire ification with it we just it's just a self closing tag so like that all right and let's head back over to our sign up form so um yeah I made this project I want to say maybe like a month ago so I'm already working on two other projects and so a lot of this code it's I'm like I'm going off of my GitHub and you know that's why it's I'm typing a little slower and trying to see you know the path the a good path to take on creating this because like I said I made this like a whole month ago and I was just trying to pile up a bunch of projects for the new year so that way I can have a bunch of content coming out so uh but yeah um we're going to get through this hopefully you guys follow following along um and it's actually good that you know I'm going a little bit slow so you guys can get everything perfect and this is a really good project I really enjoy making this one all right so we got our sign up up form now uh we need to do our submit um for our form and add our server actions in here so a few things we got to import so we're going to import our server action so that's going to be create user that's coming from our actions slal actions and then we also going to import uh use ref and use effect all right and we also going to import use session from next off and we're going to import believe that's it actually oh actually one more we're going to import toaster I mean toast from react hot toast all right uh let's get rid of that one all right cool so it's going to be a bunch of stuff going underneath this use State uh State all right so first we're going to do a con session let's go to equal use session and then we're going to do a cons R go use ref default null but for typescript in here we got to do brackets HTML form element right like that and then we're going to do a cons router so we forgot to import this cons router let going to a use router and do not import use router from next router we're going to be using next now navigation I still don't know why they have this Import in there if this is the one you have to use use router from next navigation and that's going to make our use effect so the whole reason why we're doing a use effect because we want to see if you're already authenticated if you're already logged in we want we don't want you on this page we're going to push you back to the homepage and say that you're already signed in so that's why we making this use effect here so that's the first thing we're going to do we're going to do if our session. status triple equals to authenticate it we're going to do a toast. success and we're just going to say you are already signed in like that all right and then um after this we're going to do a router push and we're going to push you back to homepage right so after this um hold on uh did I do parth I did parentheses we got to do brackets sorry going to use effect so brackets here like that all right um we do router. push and then we need our dependency array which is just going to look out for our session that status and then also our router like that all right so basically this is just checking to see if we're already authenticated if we are it's going to push it back to home it's going to give us a nice toast message at the top saying that we already uh signed in probably should be toast. eror right um I mean I guess it could be a success now let's go ahead and make our handle submit for our form it's going to be cons handle submit and this is going to be async we taking in our form data form data all right so first thing we're going to do is set submitting uh wait something oh sync set submitting so we're going to set is submitting to true and then we're going to do a con result that's going to equal a weight create user and that's going to going to send it over our form data all right and now we're going to do a if check so if if our result. existing user going do a toast. error um post. error and going do result. existing user so that message that we wrote inside of our server action and then we're going to do a else we're going to do a toast. success and say welcome please welcome and do please sign in right and then after this we're going to do a ref. current reset that reset in the form and then we're going to do a router. push and then we're going to push our signin page sign Dash in like that all right nice and last but not least we're going to set is submitting the false okay now head back down to our form and add this on submit to it all right but first we got to add our ref so we can get that form reset that we added to the um the handle submit function and do on submit um we going to do a e prevent and e. prevent default cuz we don't want the page need to refresh and um we going to do a cons form data that's going to equal new form data e do Target e. current Target sorry right then we also going to run that handle submit and that's going to be our form data give that a save and we should have a working um form now so what I want to do is actually headit over our mongodb database and see if once we create our account will this pop up in here so let's go ahead and create our account so I'm just going to do my name is Antonio my email is going to be I'm going to do admin account so that way we can sign in and sign out with this do admin at uh dt.com and then my password just going to be admin two3 click on create account see if this works all right guys so I found the issue remember that change that we made uh when we was creating this um our API route for NEX all um and we made that change for to the adapter where we installed NEX off/ Prisma adapter so we actually need to reroute back to what we had and we're going to get a typescript error and to get rid of that error we're just going to do as any there just to get rid of that error so make sure you just go back to add uh import Prisma adapter from at off/ Prisma adapter all right and let's test this out head over to your signin form and then I'm going to do name it's going to be Antonio my email is going to be admin at dt.com and my password is going to be admin1 234 click on create account as you can see we got our welcome toast there and we got pushed to the sign in page because now we have to sign in and let's refresh our database and hopefully we got our user in here yep we got our user we got our ID we got our name our email our hash password and we got the time our account was created nice so now let's go ahead and create our sign in page so that way we can be authenticated and get access to bunch of other features that we're going to add I'm going to head over to off and I'm actually going to head over to the sign in page and I'm going to import it here so that way we can see all the changes that we're making I'm going to do a div I'm going give this div a class name of py10 and I'm going go to import the sign in form all right and I'm going to close out of that and then head over to the sign in form component and let's go over here at the sign in for and it's going to import a bunch of stuff so first we got to make this a client component and we going to import toast react hot toast I'm going to import sign in and that's going to be coming from nexo react make some space here then we're going to import our input from our UI component folder we just going to import a button import button we're going to import use router Router from next navigation not um next router and last but not least um I believe that's it actually so we got to sign in input actually use ref use ref and that's coming from react all right so our sign and form first thing we're going to do is do our cons form ref and that's just going to equal to use ref no and just like we did inside of our sign up form for typescript we're going to make this HTML form element like that all right and next we're going to do cons router and that's going toally use router like that all right cool so let's go and do our handle submit actually let's just go and style our form first um all right so let's write some GSX it's going to have a div have a class name of margin top 8 small MX Auto small with full small screens and up Max width 2XL Max with 2XL medium outline give it an outline one and then outline grade 200 all right and then in here we have a div have a class name of PX4 a py of 8 small screens and up you going to give it a rounded LG and small screens and up px1 have H1 in here and it's just going to say sign in as H1 we going to have a class name of text 2XL and um text 2XL and a margin bottom five all right let's give that a quick save and take a look all right uh do we okay there we go we got sign in right underneath this H1 is going to be our form form and we going to do ref it's going to equal to ref form a form ref sorry Sor form ref and we didn't make the onsubmit yet but we're just going to give it a class name for now of space Y6 space y six if you guys don't know what this is I believe this give um top and bottom margin to all of the children inside of um the form so we're going to do a margin bottom of five and input right let's do our types so first one is going to be email type email ID it's going to be email and then the label is going to be email all right and like before we're just going to go ahead and copy over this but we only should copy it one more time because we just need email and password to sign in we don't need our name so next one is password ID is going to be password and then a label is going to be password all right and then we need our button and this is going to have a type submit and keep forgetting that it takes children so we just got to put login like that take a look there we go we got a nice sign in form but just like our sign up form if you already have an account you get you can click on a link and it routes you it pushes you to this page but if you go to this page and you don't have an account you mean you will want to get pushed to the sign up page so after this we're going to do a link and this link will take you oh man all right this link will take you to the sign up page all right wait did I import link okay we didn't import link import link from next all right and inside of this we going to have a span and it's going to have a class name a margin top three and then same thing a hover underline and this one's going to say don't have an account create one it's going to have that little arrow HTML entity right there and give that a save and there we go so this should take us to the sign up page and then we got the signin page nice all right so let's go ahead and do our handle submit so whenever we so we can get signed in and authenticated do a cons [Music] handle submit all right and this will be a async function do async and this will take in um form data actually will take in uh so yeah we're not sending over to form data cuz I forgot we didn't use um we didn't use server actions in this component but it will take in an event and this is a react. form event right first thing I'm going to do is e do prevent default and then we're going to do a cons form data that's going to equal new form data form rep current all right and just to get rid of this typescript error we're going to exclamation point right after that and then we're going to do a cons email that's going to equal form data dog same thing we do get the email it's going to be as string all right let's grab the password [Music] now password and password right and now we're going to do our try catch we try cons result it's going to equal a wait sign in this is coming from um nexo and credentials comma first we got to give it a redirect a false and then email comma password all right and we got to tell it what to do if it's if uh we get our error if result error we're just going to throw a new error result. error all right and we could do cuz this could possibly be undefined so make sure you put a question mark there and so if there's no error and uh we're able to sign in we just want to give it a toast. success authentication successful or or we could just do successfully signed in success sign in like that and then after I probably sell successful a successfully wrong that don't even look like that let's see how to spell that successfully okay I spelled it right okay I know how to spell I know how to spell successfully signed in and um we going do a router that push we're going to push home and we're going to catch an error it's going to be any then we going to do a toast dot error and we just going to say um we can just do invalid credentials like that all right let's give that a save and let's try to sign in with the account that was that we already made so if you head over to our database we made this account admin DT and the password is I believe I made it admin 1234 so let's go and try that so admin DT admin 1 2 3 4 press enter and it doesn't look like we signed in maybe I change maybe it's not the password 1 2 3 4 okay let's create another account maybe that wasn't the password Antonio I want to do admin at admin antonio.com and then password is going to be admin 2 3 4 5 I'm click on create account welcome please sign in all right so admin and Antonio admin 1 2 3 4 5 enter oh okay so we forgot to put the onsubmit on the form form now it makes sense so on submit and that's going to be um it's going to be handle submit right and now let's try the old one sry admin DT then admin 1 2 3 4 ooh we getting an air okay all right small mistake guys thank God for stack Overflow so uh inside of the API slash uh nexo folder we actually got to make another folder and then we're going to put this nexo inside of that so make sure you click on API and make a folder in here and it's going to be called off okay and now we're going to drag this X off folder inside of there all right so it should be API so inside of the off we should be API off then we got the spread operator with next off in the brackets and then we got our route so make sure you do it like that all right and let's uh try this again let's close out everything [Music] and let's see if this works now so do admin 1 2 3 4 5 enter thank God perfect we got our so we're on home and let's see we got access to the user menu we don't have access yet so there must be something in our nav bar that we did wrong so we'll go back and fix that but we should be successfully signed in uh let's check our database make sure everything thing is so I made should we should have two users since I made two users all right cool all right so now I say we go into our hero section um which is going we're going to use swiper JS to make a slider really easy to use my first time using it in this project and uh yeah so let's go ah and do that all right so before we start the hero section you may notice that once we signed in our user menu doesn't show up and that's because if you check the terminal we are getting an error uh it says Des cryption operation failed and a bunch of other stuff so if you head over to our API off um route with NEX off and scroll down as you can see we our secret uh has this process. EnV NEX off secret so we got to go add this NEX off Secret inside of ourv file I was supposed to do it whenever we finished that but I totally forgot so we're actually going to add two things so we're going to do next oore URL and that's going to equal to http SL slash local who host 3000 all right and then we're going to do our NEX off secret NEX oore secret and that's going to just you can literally do this you can do that and it will work but we're going to be we're going to um be a little bit organized and just name it NE off secret like that all right so yeah I think we have to sign in again because remember that use effect that we put on this page was supposed to bounce this back to the homepage and say that we already signed in so I don't think we're currently signed in right now so let's actually go and log in and I'm going to sign in with this one here admin 1 2 3 4 5 um admin Maybe okay I got cap lock on all right so authentication successful p a quick refresh and let's see if we got access now yep perfect so we got access to the um user menu now so orders wish list and sign up nice all right so before we start the hero section what I would like from you guys is to go download all of the images that we're going to be using for this project uh there will be a link in the description you can either go to the GitHub but I highly recommend using the link because the link is going to provide you with the product images as well and those are the product images we're going to be adding to stripe and uh fetching those products so I highly recommend going to the Google um the Google link inside the description and downloading a whole folder and here are the site images we're going to be using so close out of that and let's go ahead and start the hero section uh there is a package we had to install so we're going to go ahead and do mpm install swiper and let that install and we're going to start back up our server all right get this page and refresh let's go and create our component it's going to be called hero. TSX all right just going to export it computer's going slow right now let's refresh in that page right and we're actually going to go ahead and import it on our homepage right here and import hero our components let's go and put it down here here going do fragments because we're going to have a bunch of other components come in here like that all right so we should see hero now watch this pag it takes this whenever I start my server up it takes a while to load my computer my MacBook is I need a new one um and yeah that's I'm I'm saving up for one I'm saving up for one all right uh so we're going to head over to let close out all of this stuff and head back over to our hero and we're going to start importing some stuff but first we got to make this a client component and then we're going to import swiper let be coming from I I think we have to install swiper SL react actually um now that I'm thinking about it let's see if it already Okay still I think it'll still work we'll see and then swiper slide that is this page still refreshing okay we're good it and then we're going to we got to import this swiper CSS so import swiper SL CSS and then we got to import swiper SL CSS SL autoplay and then import swiper SL CSS SL pagination all right and this is my first time using swiper in any project um I could say they got some really good doc mation and really easy to use I highly recommend um if you want to make a quick slider or something highly recommend using it we're going to import autoplay it's going to be coming from swiper modules and then we also going to import pagination all right and let's go ahead and write some GSX so get rid of this and then we're going to return a div with a class name of margin top two and another div with the class name of main Das container and then in here is going to be our swiper slider all right and this swiper slider is going to have a bunch of stuff so get ready so we got modules that's going to equal to to make sure you do brackets do autoplay and pagination then we got autop playay uh I did um 5 seconds so we're going to do delay and then do 5,000 for 5 seconds and then speed going do 500 pagination we're going to do clickable and that's going to equal to True space between that's going to equal to 10 slides per uh per preview per view sorry is going to be one and then on slide change it's going to be a function and it's going to return uh we I don't think we need that actually this is all in the docs so basically this on slide change you can have it return something uh in the docs it has just console log in at the slide change and we don't really need that uh but we are we are going to add a class name to this and it's going to be height of full and then a width of full all right we shouldn't see anything because we don't have anything inside this slider yet but whenever you add a swiper slider you got to make sure you add a swiper slide Swiper no swiping Swiper slide all right in here it's going to be our image and I'm not going to use a um I'm not going to use a a nextjs image uh tag I'm going to use a regular one in this one I was having issues with it and the source it's going to be slash slider Das image-1.png and then the class name is going to be height full width full object cover all right we can actually copy this whole entire swiper slide and make another one cuz we just doing two images and the next one is just going to be number two and get that a quick save um got it working so there we go we got our slider and that's really it for the hero section uh now we're going to do that info SE uh section at the bottom here with the icons and all the information about payments and stuff so inside of the components we're going to make another file so it's going to be called info TSX all right and this one isn't too long we're going to import a few react icons I'm going and copy these Imports over paste them here we got bi world we got um fa aor rotate we got Io Io lock we got GI trophy we just go ahead and import those and I'm just going to export this while we're here and then we're going to import this inside of our homepage it's going to be right under here so info all right hit back and let's go ahead and write some jsx so we're going to do a [Music] div and this div is going to have a class name of margin top two and a py of five and do another another div gra the class name of main container Flex justify between on Max uh MD we're going to do a grid Crow 2 and on Max MD we're going to do a gap X of 20 and then I'll Max MD we're going to do a gap y of 10 all right and all right [Music] cool and then now we're going to do a div and then we're going to give this a class name of flex item Center gap of two uppercase uh sorry uppercase and then a text small inside this div this is where we're going to have our first icon going to do bi World we're going to give this a class name of text 3 XL underneath here we have a span and it's just going to say free shipping worldwide all right give that a save and let's take a look might got to refresh nice was right there all right so we could just copy this div and just change up the content so let's copy that and we're going to paste it three more times one 2 three so the icon for this one is going to be [Music] fa Arrow rotate left and instead of it saying that we want it to say money back guaranteed right and then the next one is going to be [Music] IO iOS lock and it's going to say secure online payments which we really going to add secure online payments CU we're going to have a stripe check out directly on our site so GI trophy is next and this is going to say best premium quality nice all right let's take a quick look perfect all right so now it's time for the fun part we're going to go ahead and add our products we're going to create a stri account add all of our products and start fetching that prod those products and making our cart and wish list and stuff like that so let's go ahead and do that now all right so now it's time to add stripe to our projects let's go and open up our terminal and we are getting the air and that's because we forgot to add a key prop to our um whenever we we're using map we're going to go back and fix that in our nav bar before this project is over but for now let's go ahead and close out our server I'm going go ahead and clear the terminal and I'm going to type I'm going to go ahead and install stripe uh react stripe JS and uh just stripe itself so we're going to do mpm install D- saave at stripe SL react D stripe DJs space at stripe SL stripe DJs I'm going go and press enter all right so those packages are now installed and I'm also going to run an mpmi stripe like that all right nice so now stripe is installed so we I believe we can go ahead and start up our server again let's just go ahead and start it up and now let's head over to our browser I'm going to give this a refresh and we're going to head over to stripe and if you don't have an account uh just go ahead and create one and whenever you create one uh just going to go click on new account and um I'm going to name this one Dev threads dyt and I'm going to click on create all right and now we got our Dev threads uh we can ignore this we're not going to activate any payments uh the account is in test mode okay that's what we want uh we're going to go over to settings and we're going to head over to actually we're going to head over to home and API keys for developers and here are the keys that we're going to be needing so let's head over back to our project and inside of ourv we're going to paste it this key in here so we're going to need the next we're going to name this one next underscore public underscore straight underscore publishable publishable key all right this is going to be the publishable key here so I'm going to copy that and just paste that in there and then next is going to be our stripe Seeker key and do stripe underscore secretor key all right let's go back and copy this I'm going paste that in there all right nice all right and let's give it a quick save oh sorry about that hit my mic all right so we can go ahead and now we can actually just add our products um so what we're going to do is I say we go ahead and add four we're going to add four top products for our homepage so if you guys seen the preview down here is underneath this section is going to show the top rated products so um let's go and add those now so inside of think we go here one more product catalog and then we just add our product here but there is a catch to it so don't click off this video and start add in products so for the top products um I'm just going to choose any one uh you could choose any four you want um I don't know which four did I use on I believe it was this one um thr that so make sure you guys download the um T-shirt the product images as well and inside the description and I'll just name this one stack Overflow shirt and the description we don't need a description so just don't put anything in there you're going to do one off payment and this one's going to be $24.99 and so for us to tell our uh database that this is a top um top product top rated product we're going to add some metadata and only thing we're going to do here is do top rate and we're going to do true like that all right so now like I said we're going to add four products so you guys can pause the video and just go ahead and add those three but I'm going to cut this part out just me add in three more products doing the same exact thing we just did so I noticed I was zoomed out a bit so I'm going to add this last one um as I'm zoomed in we're going to click on ADD product and I'm going to drag over the image inside that upload and I'm going to name this debugging debugging shirt no description uh for going do one off 24.99 and for the metadata for these we're going to do top rated is going to equal to true and click on ADD product all right so we got our four top red products so let's go ahead and try to fetch these products and place them down here underneath our info section so we can actually keep stripe open we're going to keep our database open I'm actually going to give this a refresh and see if anything changed in here all right so we got our two users which is good all right so let's let's go ahead back to our vs code and we're going to create some components inside our inside of our components folder so the first one is going to be called products. TSX and the next one uh actually let's export it just so we don't forget and the next one is going to be called Product cart products card at TSX let's export this as well and last but not least we're going to do top rated component so top r at TSX now we need an action to actually fetch our products from our stripe so inside of our app we made a folder called actions earlier well I thought we did we're going to create a folder called actions cuz we made one for off so these are all of our all stuff so I want all of that to be separate from this so we're going to create another folder inside of our app and this one's going to be called actions all right in this folder we going to create a file and it's going to be called get stripe products at TSX all right and this is a pretty lengthy uh action bunch of stuff going on here try to explain it the best I can so only import we're going to have is go to import Stripe from stripe and then we're going to do a export const fetch products going to be async function and we're going to do const get products it's going to be async and then we got to do con stripe that's going to equal new stripe all right and in here we're going to do process we got to send over our EMV stripe uh our stripee secret create in our umv file so we do process. EMV stripe uh stripe uncore secretor key right and then we got to do a comma and we got to give it a API version API version is going to be 20 23 10 16 perfect and we getting an error because um argument of type string undefined is not assignable to pan so what we can do here just do Ed string and that should give rid of that error nice all right so underneath here we're going to do cons products equals a wait scrape do so the good thing about uh typ scrip is what I like is once you like click Dot and you have access to all of this stuff it just it feels like um what I say uh I'm trying to think of the word it just feels like I'm doing something right when I have to get access to the stuff as you can see up here we did con stripe equals new stripe we get the API version and we gave it our stripe secret key so if I would have clicked Dot and nothing showed up then something would have been wrong so um we going to do stripe. products. list parentheses we're going to do brackets so um this got me stuck when I was creating this produ project so by default stripe only allows you to render out 10 products at a time um but to bypass that all you have to do is do limit and we're going to do 99 just so we can have all of our products show up um that took me a while to find I was I spent like couple days trying to figure this out and then we're going to do a cons price map it's going to equal new map all right and to retrieve the price from stripe uh it's really complicated can just be like you know uh product. price you got to um do all this extra stuff just to get the price so we do cons prices equal a weight stripe. price prices. list and same here we got to make sure we give it the limit of 99 or it's just going to render out the first 10 product prices we don't want that and then we're going to do prices that data that for each price so we want to do if our price. product inside this if statement we're going to have another if if price map there not price map that has our price that product we're going to do price map that's set our price. product all right and we're getting a error because we got to also do price there as well all right and now we need our else just going to go right after this going do else and then we're going to do con existing price equal price map that get our price. product right and now we're going to do a if check so we're going to do if our price. created is greater than existing sorry it's greater than our existing price that created we're going to do price map that set our price. product and then comma price all right that was a lot a lot of work there all right so that's all just to get the prices from stripe and we're still not done still not done all right so after trying to see where all this in at so 1 2 3 4 5 1 two three four five so here we're going to do const all products that's going to equal products data map do product and we're going to turn con price equal price map thatg product id id all right but now all we have to do is just return our uh the stuff for our project I mean product so right underneath here uh trying to see here hold on okay so still inside this return statement so right underneath here I mean still inside this um All Pro products um where we're mapping through the products. DAT we're going to return our ID which is going to be product. ID I'm going return our name so the product name so product that name we're going to turn a price ID price ID and you would think you just do product. price ID but nope we got to do price so it's price we're going to return price. ID otherwise it's going to be null right and for unit amount which is the price the actual price so we need this price ID for um what is it we're using U shopping cart uh we haven't installed it yet yet but we will after we um start adding products and stuff and start working on our shopping cart we're using use shopping cart JS so I had to add this uh price IDE in um because um that it requires that so we're going to do price of this price we're going to return price do unit underscore amount else we want turn all and we also want to turn to image which is going to be product. images and we got to make sure we do um index of zero and we forgot a comma here all right so image and we also need our currency that's going to be price it's price going do price currency else null I keep forgetting the comma and two more then we're done description actually we don't even need a description but uh I believe we added it inside of our Prisma so let's just go ahead and add it in here because I have first I was going to add Dynamic routes but the way I had it got it set up is it it works so so perfectly without having Dynamic routs you can add the cart you can choose the size all within the same page I just think that's it works better like that so description and metadata metad dat is going to be product. metadata all right nice and now all we got to do is just return all of our products so return all products all right and right underneath here we're going to do a cons products equals a weight get products like that and now we're just going to return products all right cool so that is initially our fetch products fetching products from stripe um if you guys know a more simpler way to do it um this is the way that I found out um how to do it and I know it's pretty complicated but um yeah we got our products now so now what we can do is inside of our top products are top rated products and I meant to change this to top products not top top rated so we're going to do top products make sure you guys change that and I'm going to go and change the export as well top products and top products all right uh let's see so now here what we can do is we can go ahead and import our fetch products fetch oh wait we doing something wrong oh there we go all right fetch products and then we also going to import our product card and we're going to import link as well from nextjs all right so here this here's where I want to actually fetch the products and then we're going to send all of the data that we get from all of our products we're going to send it over to our product card uh so we're going to have to make this a async function and all we have to do is do a cons products that's going to equal a weight fetch products like that all right but we can't just do it that way cuz this is fetching all of the products we want to just fetch all of the products that have that metadata that we added the top rated metadata uh because this is the top rated component so to do that what we're going to do is do a cons top products that's going to equal products. filter and then taking a product and all we're going to do is just return our product metadata do top rate triple equals to True these are the only products we're going to show is if the metadata top R equals to true all right and we could put a question mark there CU possibly be undefined all right cool uh let's see so now let's go and return some jsx do a div class name py of 10 a border T and then here we have a div with a class name of main Das container another div in here with a class name of flex just not flees Flex justify between and item Center then we're going have H1 with the class name of text XL uppercase a border b a border grade 900 and then a text Gray not 100 all right and this is going to say top products all right and then right after the right after this H1 we going to have a link all right and this is going to have a h ref and all it's going to do is just take us to our shop page that we haven't created yet and it's going to have a span in here that says say view more and we're using the HTML entity again I believe it's the same arrow that we used before on um our sign in form not sure all right let's give that a quick save so we won't see anything because we don't have the top rated imported inside of our homepage yet so let's go ahead and do that it's going to be right underneath this info bar top uh top product sorry that a save all right make sure our server started all right server started nice all right perfect we got our top products we got view more I do want to add a class name to that view more that I think will look nice um top product let's give this link a class name of hover underline let's save that when we hover I think it looks nice whenever we hover come on there we go perfect all right and underneath this link well underneath this div here we have another div and this is going to have a class name of grid LG we GNA do grid Cal 4 gap of five and by default it's going to be grid cow one I mean two all right and um here's where we're going to map through our top products so we're not mapping through our products we're mapping through our top products this is what we did up here we're filtering out through um the product so top products that map and then we're going to do product we might get some typescript errors and we're going to return a product card here and then we're going to send it product equals product we're going to send over the product to here all right and I believe we did products card like that get that a save all right uh now let's go to our product card and this is a pretty long file here um yeah there about 100 lines of code here um so yeah let's let's get it some of this stuff we can't do yet because we don't have used shopping cart installed but uh we're we're going to make it work I think I can make it work all right so we going to do a use client and then we're going to import use State we're also going to import image from nextjs uh we're going to import two icons go and copy this over so we're going to import fa heart circle plus and F Ai and that's coming from react icon SL F6 all right and um we're also going to import toast from react hot toast so there's going to be a few more Imports that we haven't created yet but um for now I believe we can make this work all right um so let's go ahead and return some jsx but first we got to accept our prop in here which is product all right and we will get a a typescript error we'll fix that later so we do want to set some State here we going to do a const select it size actually I don't want to do this right now because I want to add the you shopping cart and stuff first so let's just try to style this up the best we can um then we'll go ahead and add when whenever we finish our cart we'll go ahead and add all that in so we're going to do a div here class name of relative Flex Flex call and item Center another div and this is going to have a class name of relative group like that um and then in here we have an image a self closing tag cuz we're using nextjs image tag and the source is going to be product. image and we going to do a width of 300 height of 300 and then alt going to do brackets back tis we going do image of dollar sign brackets product that name all right and it's also going to have a class name of cursor Das pointer right give that a save and let's see what happens so it is showing four that's what we want we should get an error now that I think about it yep so we have to whenever you're using images outside of next year so whenever you're um like fetching images from somewhere else um you got to go ahead over to your uh next config file and we got to edit this file a little bit let me go and open it up here threads and next config all right so what we got to do first thing is we're going to do uh react strict mode because by default react strict mode is set to true and then we also going to do images remote patterns and that's going to be array and then we now we got to do brackets and do protocol https and then host name it's going to be files. stripe.com give that a quick save and go ahead and refresh that actually let's see oh okay there we go restarted the server normally it'll you have to restart it but I guess with the new update if you make any um changes to your next config it'll just automatically restart the server which is nice all right so I'm going to close out my terminal and then I'm going to head back over to my product card and so right underneath this image here we're going to have a div and this div is going to have a class name of hidden absolute a top of five item Center justify Center a group- hover and that's going to be Flex Flex call a gap of three all right so underneath here we're going to have a button and it's going to have a class name of MX2 a BG of grade 900 a border text White a pattern of two a rounded MD hover have a BG of gray 900 all right sorry about that guys I've restarted my computer hopefully it moves a little bit faster now um so we left off here um so it is showing our product images and whenever we hover as you can see we got this little box there that's what we're working on right now so um whenever we hover we want it to be BG gray 900 sl75 right and in this button we're going to have let's see so for now we're going to add fa heart circle plus but we're going to make our own wish list button um component but for now we're just going to add that in there and I'm actually going to copy this button and I'm going to go and paste it again but I'm just going to change this one to fi that give that a save and let's take take a look let's get it there we go perfect so we got our add the wish list button and we got the view but like I said I didn't add Dynamic routes in so this view button is not going to have any functionality but to add to wish list will all right uh so underneath this button and we got two closing divs here we're going to have a H3 and this is going to have our product. name and this H3 is going to have a class name a font bold and a tracking wide right save that underneath this H3 we going have a span and this is going to be our product. unitor amount and it might look a little weird just because we got we haven't made our format price util yet so it's going to look like this without the dollar sign and a dot in between the 24 and 99 so but we're we're going to come back and fix that and now we need uh our drop down menu to choose our size going have a select all right and in here we have our value is going to be selected size but we haven't created this state yet but I guess we can create it now whatever select it size and then our on change is going to be Tak in Min and it's going to set our selected size to our e. target. value all right let's go and set that state so we don't get any errors let scroll up and then we're going to do a const selected size set selected size that's going to equal you state and by default it's just going to be empty quote like that all right scroll down so we got our value selected size and this also going to need a class name of my2 a pattern of two order and rounded MD quick save as you can see it's right there looking all sexy all right all right so in here we're going to have four options um actually might just copy this over four options in here all right so the first one is going to be empty because that's our default State and it's going to say select size and then a value for the small it's just really simple small and then medium and the large and you can see we got values here all right and just a quick summary I'm pretty sure all you guys know this already but this is basically just set in whenever one of these changes changes it's just set in the State uh selected size is setting that to whatever the value is so if we change it to medium set select um select the size value is going to be medium all right and now um all right uh now we need our add to cart button I'm just going to do a button for now that just says add to cart all right nice perfect um so we are getting some typescript errors as you can see um to fix that we're going to create a file or a folder inside of our roof Ro and it's going to be called types all right and in here we're going to do product types. TS right and we're going to import stripe in here import Stripe from stripe and then we're going to do export interface product type so our product it has a string I mean ID which is a string of course it has a string come on a name is going to be a string a unit amount underscore amount and that is we're going to do any image it's going to be a string a price underscore ID d That's optional and do a string right there all right and our currency which is could be possibly undefined currency that's going to be any description I don't know why it's not my select button not working I mean my enter button description I'm going to do a string or it can be null and our metadata possibly undefined this one's going to be stripe do metadata and last but not least our quantity and that is a number all right so that's our product types um let's go ahead and close that out we can close out the config we don't need that anymore and now what we can do is import that product type up here product type and let's go and set our um type for our prop here do bracket product and that's going to be product type all right give that a save all right perfect uh all right cool so now inside of our top products I'm surprised we're not getting any errors in here um so I guess we're good um I think that's because we're setting the type inside of our product card so that's good all right so now it's time to start building out our cart functionality so what we're going to do is let's go and close out of everything just so we can have a nice fresh start and there are a few packages that we have to install as well so what we can do is before we do that let's go ahead inside of our app we're going to create a folder and we're going to do parentheses and then we're going to do shopping cart so this is where all of our cart stuff is going to go our components for our cart our API routes for our cart and everything uh so in here we're going to create three folders one's going to be called API and then we're going to create another folder it's going to be called components and then last but not least we're going to create one that's called cart all right let me just verify that okay perfect so inside of this cart um folder we're going to do a page that TSX this going to be our actual cart page and then inside of our components we're going to have a folder in here it's going to be called UI and then we're going to have three components so not inside of DUI yet so this is inside of components let me just make sure all right components so we're have a cart. TSX and then we're going to have a checkout that TSX and then we also want to have a checkout form TSX right and then inside of the UI we're going to have our add the cart button do add to cart. TSX and then we also going to have our cart icon which is this up here so cart icon. TSX all right cool so that's our component and inside of our API route we're going to have three API routes um we're going to have one it's going to so it's going to be a folder this is going to be create dorder and inside of this folder make sure we do our route. TS route. TS all right two more so we're going to have a order ID order ID and we're going to do a route. TS in here and then we're also going to have another one another folder is going to be called update Das order Das status right and this is going to have a route. TS as well all right cool we can go and close that all of this because now it's time to actually install our state management library and we'll be using zustan uh we only need a little bit of state to be managed and uh pass along some of these components so uh let's go ahead and install Zan so we're going to do npm I okay z s t a n d all right and now we can go ahead and create our store a Zan store I'm going to open it up on my other monitor I thought I had it open okay all right and so it's going to be a folder inside of our root it's going to be called store all right and in here we're going to have a file and it's going to be called use checkout store. TS all right so we got to import two things we're going to import create um got to go on brackets sorry brackets create from Zan and then we're want to import persist and that's going to coming from zoan middleware and then we're going to do export const use checkout store use checkout store and we're going to equal it to create new parenthesis then we're going to do another parenthesis and going do persist and then do another parenthesis and this is where we're going to set our initial state so we're going to do a set parentheses brackets so our initial State our payment intent is going to be empty and then our on checkout is going to be cart and then our cart actually we're not adding a cart because we're using you shopping cart um all right and now we we set our state here so let me just put like a comment so we do initial or Set uh initial State this is initial State all right and then down here is where we're actually going to set our state so I'll do comma there we're going to comma there and now we're going to set our state here so set State this thing is so easy to use so set State all right and going to do a set payment intent all right so we want to take in a value and then we're going to return set set parentheses brackets payment intent value so whatever this value that we're taking we're just going to set payment intent to that value really simple and then uh same with the checkout uh I'm just going to copy this over so so we're set checkout uh this is basically a use state so we got our initial State and we're setting our state so same here we set checkout taking a value and then we're just setting on checkout to that value really simple and um after this we're going to do a comma make sure I added all the commas here we need a comma there do not forget these commas cuz this thing will break and we got to have a name for our store I think you can name this anything we want but I'm just going to do checkout Dash store all right and we are getting some errors because value got any type value got any type so let's go ahead and set our types do type check out State and then our payment intent it's going to be a string um our on checkout I don't know why okay on checkout it's going to be a string and our set payment intent is going to be a function that's going to take in a value which is going to be a string and just going to return vol right and same with our set checkout I'm Tak in a value and that's going to be a string and return void all right and I believe that is it for this uh we just got to set our um so right in between this create and this um the parenthesis here we're just going to do brackets and then check out State like that nice so that's all we get that's all we need to do uh for our statement actually we do have one more uh we got used wish list store we're going to create and that's for our wish list uh but we're not going to do that now because we're focusing on the cart all right so I think it's time to install Us shopping cart so head over to Usopp cart.com and we're going to copy over this code and they have some pretty decent docks um pretty straightforward how to use it um it just save saves us some time from creating our own cart uh so if you guys want to check them out check out some of the docks we'll be using most of this stuff in here but um yeah definitely check them out if you're creating a store I'm going head over and paste that code inside my terminal and then I'm going to start back up my server once it finish all right mpm R diff and give this page a refresh close out of that and I say we go ahead and work on our add the cart button first and then we're going to work on our cart icon and then that's when we're going to start styling the cart once we have some items inside of our actual cart cuz I don't see the point of styling up our cart and we don't see anything so um as you can see it says add item and this is how you um add the items to the cart it's pretty straightforward we got remove item we can increment it we'll be using that one we also be using decrement item um we won't be using clear cart or low cart um here's a few few few more stuff we'll be using total price cart count cart details formatted total price and stuff like that so uh we can actually close out of use shopping cart and let's head over to our app shopping cart components UI add the cart all right so first we're going to make this a used client then we're going to import use shopping cart use [Music] shopping part I'm not sure why I'm not getting the auto complete hope it installed all right there it goes your shopping cart we're also going to import product that's going to be coming from you shopping cart SLC core this is for typescript so that way we can um add types to our props that we're going to be getting from this um inside of this add the cart and then we're also going to import toast because we want a nice toast whenever we add item to cart and cons add to cart all right so this add the cart button is going to take in a bunch of stuff we just going to have a currency take in a name image price ID a size a size selected size select sorry and onclick all right and all of this is going to add type now so this is going to be our product but our on click is not part of our product so oh I did something wrong here I think okay yeah product and then we're going to do and brackets we on click and that's just going to be a function that returns void right and after that we need our return like that perfect all right so we're going to do a const add item and that's going to be coming from you shopping cart right and then we also need a account product ID and we're going to equal that to back tix brackets actually dollar signs brackets ID then we're going to do a dash dollar sign brackets size so the reason why we're doing it like this is say for instance you want to add a small shirt in a small GitHub shirt inside the cart right and then you also want to add a medium GitHub shirt inside the cart so if we don't have have it like this it's going to oh we forgot the dash we put equal it's just going to add a quantity um the quantity is just going to increase by one instead of adding a small and a medium inside the cart so that was the issue I ran into and I I got stuck for a few days on that as well and this is um the fix that um I figured out so now with this when if we add a medium to the cart we going to have a GitHub shirt medium and if we had a small it's going have a GitHub shirt small inside of the cart all right and now we need the cons product and that's going to equal currency let me just copy all of this over so basically all of the props that we just took in so currency is going to be currency name is going to be name image image price price ID is going to be product ID so just make sure you do that and then size is going to be size all right so now we can go ahead and write our return and then we're just going to return a button and onclick be a function and we're going to do a if check so if our size select so if it's not size select and onclick we're just going to return on click all right else we want to go ahead and add our item so we're going to add item and we're going to add product and just do as any and then we also going to have a toast. success and we're going to do back ticks dollar sign brackets and do name has been added to cart right right and in between this button we're just going to say add to cart oh for case actually just keep it like that at the cart I think it looks better when it's like this at the cart all right cool so let's go and Export this export default add the cart nice let's go ah and import this inside of our product card uh let me going and open that up okay and import that here import uh add the cart so down here where wherever we wrote this button we just going to remove that have our add the cart component in there so I got to Tak in a bunch bunch of props that I'm just going to copy over paste it up in here all right so we got our name um which it's going to be our product name image product image all this is straightforward uh until we get here is where it gets a little weird so we got to on click is selected uh if it's um not is selected so if it's false it's going to show toast else it's going to be undefined so we didn't create this show toast yet so let's scroll up and right underneath this use state so we're going to do a const is size selected that's going to equal selected size when it's not empty okay and then I'm going to do a const show toast that's going to return a toast. eror and just going to say please choose a size first so what we just did was basically um if somebody try to add an item to the cart without choosing the size it's going to throw an error and we are getting an error here at the cart did it all right so as you can see we are getting an error here and we're getting an eror that says um undefine reading dispatch and that's because we forgot to make a context and we got to wrap our whole application up with a used shopping cart so inside of context we're going to create another one another file it's going to be called cart context TSX all right this is going to be use client and then we're going to import react node and then we also going to import C Prov provider and we're going to do it as cart right and then let's go and make our export default function cart context parentheses brackets and we're taking in um our children children let's go and give this children a type which is going to be react node we going do children to be react node right and let's go and write our return statement so we do return and return cart right and we got to give this cart a bunch of props we're going to do mode it's going to be payment uh cart mode is going to be client only uh stripe is going to be process M v. next public stripe underscore publishable underscore key and let's make sure we do s string before we get a error s string and um we also need a currency this is all in the docs as well by the way currency um we don't need any billin address collection because um the cool thing about you shopping cart is you get access to um stripe but it's going to be on a whole different page we want the checkout form to be directly on our website so but if you want to it's so easy to integrate it um it's you just click check out and it just takes you to the um checkout Page by um stripe but we want the checkout form to be directly on our website so we do should P persist and that's going to be true and we also need a language it's going to beore us and we are getting some errors I believe we got to do like um I think we also got to give it like a success URL and stuff like that we can be it can just be home and then cancel URL let's see if the airor goes away it's can be home um and maybe build an address can be false all right oh okay maybe that's why we didn't put our children in all right there we go so I don't even think we need the success URL oh maybe we do uh billing address no need that cancel URL all right so I guess we still have to put success URL and cancel url url even though we're not using the checkout form um that's given to us by you shopping cart uh so just still put it and just um make the cancel and success URL throughoute to be our homepage all right so we can go and close out of that and we're going to head over to our layout let's go and wrap our application out with this import cart context it's right underneath here we're going to do cart context and W all of add up with that and hopefully this error goes away perfect it went away all right so let's go and try to add something to cart without choosing a size wa it says please choose size first that's perfect now let's go and add small and now it says debugging shirt has been add it to the cart so before we do the page for our cart we're actually going to um create our cart icon so head over to car icon. TSX and do import it's going to be a link from next we're also going to import a react icon AI outline shopping cart I believe this is the same icon we used inside of our nav bar so that's same exact icon and then we're also going to import you shopping cart from you shopping cart let's go and do a const cart icon and first things first we're going to do a cons cart details and that's going to come from use shopping cart and then we also going do a cons cart items and that's going to equal object dot values it's going to take in our cart details two question marks and then empty brackets like that all right and now what we're going to do is do a return I'm going do a link and our H RI is going to equal to carts and our class name is going to be relative right and let's go and do render our our aine AI outline shopping cart all right so we want a number to to show up inside of our cart whenever we add an item to show you know how many items are in our cart so to do that what we're going to do is we're going to do car items dot length so if our length is greater than zero going do n and we're going to return a span with a class name of absolute a left of three a bottom of three round it for a text small font bold a width of four a four a height of four and a BG gray 900 text white and we also going do Flex item Center all right see if there's anything else pretty long class name here item Center and let's do a justify Center and also pad in padn bottom of one all right and in here we're going to render out our carart items. length let's see if that circle's there now so Circle is not there I'm going to do cart items. length oh I forgot we won't see anything because that's not our cart icon let's head over to our naar and look for our card icon which is here this AI outline shopping cart and we're just going to render out our cart icon instead oh we forgot to um export it let's go export it right quick export default cart icon give that a save and then head back over to our nav okay there we go showing one nice we got one let's go and add another item and add a large now we got two and what I want to do is actually test this out we're going to add another large so it still should be two items perfect and let's just add a medium of the same shirt and it should be three now Perfect all right actually click on this and it should take us to our cart page now we can start styling up our cart page so inside of our app shopping cart cart um actually it's going to be components and then cart and then we're going to export this and we're going to go and import it here so just cart right and save that and you see it switched to cart so now let's start styling up this cart component it's be a bunch of imports so make some space here so first we're going to make it a use a client component and then we're going to import image from nextjs we're going to import you shopping cart from you shopping cart and now we're about to start using our Zoo stand store so we're going to import use checkout store from our uh zo stand store we created and we're also going to import um we didn't create this yet but let's go ahead and Export it now so let's head over to check out out and we're going to export it cuz we're going to have to import we're going to import it here I'll check out and uh we're going to import our button from our UI component and we're going to import two react icons one for plus and then one for minus I'm going to let you guys guess what those are for all right and let's go ahead and get going so first thing we're going to do we're going to do a const we do brackets and we're going to grab all of this stuff from you shopping cart so um if you guys went over to docs you guys know that uh you have a access to uh all of this stuff from you shopping cart so you got cart details got access to a remove item uh total price decrement item and increment item all right and that is going to equal to you shopping cart like that all right and now we're going to do we also got to do our store so we do cons checkout store and that's going to equal use checkout store all right let me make some space here so you guys can see everything all right and we Al we going to do the same thing we did inside of our add to cart we're going to do cons items and that's going to equal object that values and we going to take in our cart details and empty um brackets like that all right so let's go and write our return statement start writing some jsx there a bunch of bunch of code all right um so let's let's get started so we have a div and we have a class name of py20 and I actually think we need to H actually I don't think we need to do that we'll see though I have a div another div inside of here and this is going to have a class name of main Das container and then um now we're going to render stuff out conditionally we're going to render out so if our checkout store. on checkout is equal to checkout so we're going to do if our checkout store do on checkout so this is the zoo stand store um so if that equals to checkout I'm going to do and in we're going to return a button and this button is going to have a class name of text small font bolde and a margin bottom of five all right and it's also going to have a on click so whenever we click on this button we want to change set checkout back to cart so we going have an onclick so we have return checkout store that on checkout and we're just going to change it back to C sorry my cord fell all right we're going to change it back to cart on checkout oh set checkout sorry set checkout all right and inside this button is just going to say have the HTML entity again with the arrow but this time it's going to be going left and it's going to say back to cart just in case you want to add some more items to your card all right so we shouldn't see this because by default our um on checkout is set to cart okay so we only see this whenever our on checkout is set to checkout but I believe there's a way we can change it so if we hit over to checkout store and as you can see it says on check out let me zoom in some uh let's see uh let's see let me scroll up some so as you can see um it's we got a payment intent and that's um empty let me just show you guys how I got here by the way so you just you know click inspect Dev tools and you head over to application and you just head over to Local Host 3000 and as you can see we got our next off we got our La supports cash we got a checkout store and our prist um route so a checkout store is what we created in zustan and um as you can see it says on checkout as cart so let's actually change this wonder if we can change it let's see uh maybe we could change it here I thought there was a way we can change it hold on let's see um maybe here okay here we go there we go so we can change it to checkout all right so if we do that and not not give it a save we don't got to save it this isn't vs code all right so we get our on checkout to checkout we should see that back to cart button right I mean give it a refresh but there we go so we got our back to C but we get errors um yeah we're we could just ignore this we kind of messed up our own site there but as you can see back to cart and once we click that now it should be back to cart let's give it a refresh and hopefully we doesn't we don't get any of those errors anymore all right so we got our back to C button there and now we want to render out a message if our cart is empty so right underneath here we're going to do brackets again we do items. length so if it's less than one do an in and our checkout store. on checkout is equal to cart because we don't want this showing if our on checkout is equal to checkout um we're going to return div with a class name of height screen Flex item Center and justify Center and in here we have a span with the class name of text 2XL uppercase and it's just going to say your cart is empty empty and do like that let's give it that a save we will get a err because we don't have our else so else we could just return n like that all right so our car isn't empty so we're not going to see this message but we can actually empty our cart let's go to inspect go to application and all we got to do is delete this precis route delete it all right and I'm going to refresh and now our cart is empty perfect um H maybe I should give let's see if this works R bottom 20 bring it up some um all right so we got that and after this null now we're going to uh actually render out our products so we only want to render out our products if our checkout store on checkout is triple equal to cart and do and in and we're going to return fragments in here we're going to we're going to do items that map and we going to take an item and return jsx so what we can do is let's actually change this to UL and we're going to return an lii with a key of item. ID and it's also going to have a class name of flex and a py of six right so inside of this Li we're going to have a a div and this is going to have close out of this quick okay this div is going to have a class name of height 24 with 24 Flex justify Center item Center overflow of hidden around it m d a border border gray 200 spell border wrong all right and inside here we're going to render our image for our product right and a source is going to be item. image and ALT is going to be we can do brackets uh back ticks dollar sign brackets um actually let do image of dollar sign brackets item do name right I'm we getting error because let's see so string undefined it's not assignable to string static import so all we got to do is just do as string here and I should get rid of that we got an alt and we're going to do a width of 100 a height of 100 and let's go ahead and add some products to our carts so we can see these products so I'm going to add a medium debugging shirt a stack oh dude this shirt right here dude these two right here they're looking for someone who can commit this shirt goes too hard bro like I'm actually thinking about got buying a shirt um so uh we're going to do a large in this and I'm going to do medium in this I really like this one too to stack Overflow let's check our cart and there you can see we got our images there and so right underne this div have another div and this is going to have a class sorry a class name of margin Left 4 a flex a flex one and also a flex C all right in here we're going to have a div and in that div we going have another div bunch of divs have a class name oflex justify between a text text base a font medium and then a text Gray 900 all right inside this div have another div that's going to hold this H3 and this is going to be our item. name all right and then we're going to have another H3 and this is going to be our item. size all right um this H3 is actually going to have a class name of text small and let's goad and save that and see if everything pops up perfect looking good all right we're going to item do size so we got our closing div here and now we're going to need our P tag and this is going to have a class name of margin Left 4 and this is going to show our price we're going to do item. price all right and we still haven't made that formatted price util yet we're going to do that here in a second all right so P one two underneath this div so two divs down so one closing P down and two divs down we're going to have another div and it's going to have a class name a flex a gap of five and a margin top three all right this is where our increment and decrement buttons going to go it's have a button um and inside this button it's going to show our fi minus react icon and we're going to have a on click we got to return um our decr item decrement item that takes in an item ID and you also tell it how much you want to decrement it by so we're going to you can decrement it by any number you want we're just going to do it by one so count is going to be one right so now we need our increment button but I'm just going to copy this save some time and I'm going to paste it right underneath this button and we just going to change it to increment item and then change the icon to IO m d add let's take a look all right there we go and now we need somewhere to actually see our quantity so right underneath this div here me scroll down some I have another div and it's is going to have a class name a flex a flex one items in justify between and a text small have a P tag in here with a class name of text grade 500 500 and this is going to be our quantity so we can do qty and that's going to be items. quantity quantity all right we are oh item sorry item. quantity did we do okay perfect we got one and once we click as you can see the number goes up and once we go down it should just remove the item Perfect all right so we going to keep going here like I said this is a pretty long this probably the longest um component that we have right underneath this P tag I have another div and it's going to have a class name uh Flex and here we're going to render out a button and this is going to have a type of button and it's going to have an on click and we're going to remove item and I that takes in item id as well and we also going give a class name of font medium font medium here we go all right and it's just going to say remove like that and I should just remove the item from our cart I'm just going to remove it perfect all right and now we need to um render out our sub to subtotal and um our checkout button so I'm trying to see how many divs down it's a bunch of divs so we got one button and one two three 4 and then that so still inside the UL we're going to render out and do items. length so if it's greater than zero do NN parenthesis we're going to return a div we class name border T and we going do a border gray 200 a px of four a py of 6 on small screens we're going to do a px of six right scroll down some inside this div we have another div a class name of flex justify between a text base font medium and then a text Gray not 100 all right and we have a P tag in here and this is just going to say sub total like that and then after that we're going to have another P tag and this is going to show our total price total price um so yeah let's just keep it like that for now we still haven't done the formatted price yet the total price and so after that div there we're going to have another P tag and this is going to have a a class name of margin top margin top one text small and then a text Gray 500 and this is just going to say shipping and taxes are calculated at checkout all right give that a save Perfect all right and and now underneath this P tag I'm going to render our checkout button so we have a div class name of margin top six with the full Flex justify Center in here we're going to have our button component button all right and remember our button component takes bunch of props um actually well we made most of those props optional but in this case we're just going to have it on click on this and first thing we're going to do we're going to take in an event and then we're going to return e. prevent default and we also going to do checkout store do set checkout and we're going to set it to checkout all right and oh it does take children so we got to make sure we just change this to check out all right nice we got a checkout button so once we click it should change our checkout store to checkout and now it says back to cart Perfect all right and underneath here um so underneath uh right here so two closing divs up trying don't don't want you guys to get lost because I know it's it's hard it's really easy to get lost whenever you're dealing with a large file like this and I don't want you guys to put something inside the wrong div and then you got to backtrack so two closing divs up we're going to do checkout store. on checkout so if it equals to checkout we want to render out our checkout component right and we're going to send over items to our checkout component so our items in our cart and we also going to send over our total price okay perfect items is items okay nice all right so that is it for our cart um really simple cart um let's go and add some more items add a large add a stack Overflow shirt oh we got to choose the size first small all right cool so now I see we go ahead and do our API routes because we have to do that before we actually do our checkout um page and before we do our checkout form so let's head over and do that now uh let's see let me go and open it up we got Dev threads and then we're going to go to app shopping cart API and we're going to do create order first cuz that's the largest one all right so let's head over to there create order API route Perfect all right this one's pretty long as well all right so here we're going to import next request and we also going to import next response right and we're going to import our get current user action import Prisma from our lib so that/ lib SL Prisma right and we also going to import stripe and last but not least we're going to import cart entry and that's going to be coming from you shopping cart SL core all right so first we got to do a cons stripe is going to equal to new stripe process. EMV stripe uncore secret uncore key and just get rid of that typescript error as string all right we're going to do a comma and we also got to do a API vers version uh okay I did it wrong sorry guys no closing parentheses there we going to do a comma and now we do our API version [Music] comma then brackets then API version and this should autocomplete once we put the quotes 20 23 10 16 right and we need a Clos in parentheses there all right so now let's create our manage stripe payment intent function so we going to do a manage stripe payment intent it's going to be a async function and we're taking in a payment uncore intent underscore ID which is a string and we also going to take in our total which is a number all right and just going to return so we're going to do if let me make some space here so if our payment uncore intent id we're going to return oh wait stripe so once we click dot we should get access to a bunch of stuff and one should be payment intent and we're going to dot update so we're going to update the payment intent id comma and also the amount and a total all right so what this is doing what what this function is going to do is basically if we click checkout it's going to create a payment intent id okay but if we click so let's go and click check out out and then if we click back to cart it's going to still keep that payment intent id but if we remove an item it's just going to just update the amount it's just going to change the amount on the order and um so it's not going to create a whole another payment intent id cuz you know you can just Spam check out back to cart check out back to C and then our databases just get filled up with different payment intent IDs and we don't want that so we got so if our payment to that dat we return that and then after this we're going to do return await stripe do payment intent. create so amount this total our currency is USD and then our automatic payment methods is enabled enable enabled true all right so that should be it for our manage stripe payment intent function uh let's scroll down now we're going to create our manage order in database function so this this one's pretty long we're going to do cons manage order in DB function so async and this is going to take in payment intent which is we just do any our total which is going to be a number our items which which is a cart entry and it's an array of items and last but not least our user ID which is a string right scroll down some and let's go to do our return all right so first we're going to check and see if the order already exists in our data base so we do a cons existing order it's going to equal await Prisma order. fine unique and we got to tell it where to find it so we just got to check and check the payment intent id payment intent id and that's going to be payment intent. ID I must have spell intent wrong up here Hur up intent pment intent. ID all right so let's just check in to see if the order already exists in our database all right so now we got to tell it what to do if the order exists in our database so if existing order we're just going to return A8 Prisma order update so we're just updating the order instead of update an order instead of um create a new order do where and same thing we're going to do payment intent id and that is our payment intent id we do a comma and we got to give it data the data is going to be user ID comma amount and that's going to be total currency which is going to be USD comma status this is really important cool little feature we add it and this is going to be a weit in payment all right and that's that one and now so if it's existing order just going to update it and now we need need to actually create the order if it's not already an existing order so we're going to do cons created order equal a weit Prisma do order. create and we got to do data we're going to use our ID comma we got our amount which is going to be our total currency it's going to be USD um status it's going to be awaiting payment awaiting payment and then our payment intent id which is going to be payment intent. ID right cool and now we want to um attach the items that we order or that was um so whenever we click checkout the items that sent our car we want to attach that to that order so for example if I click checkout um this debugging t-shirt will show up in my database and it's going to be tied into that order specifically and we're going to tie it in with the order ID number number so what we're going to do now is underneath here and do a cons order item um just do cons order item I guess and do items that map new async item do brackets like that all right so we're going to do a weit Prisma order item. create and data all right so we got to give it an order ID and that is going to be our created order. ID all right and then we also going to give it give um name that's going to be our item. name make sure we add the commas here I'm actually just going to copy and paste all this over because this is all easy stuff so we got our quantities item. quantity price item. price image item. image and size item. size really easy so underneath all of this we just going to do a wait and we do a promise all and then we're going to order item our order item function and then we also want to return our created order all right so that right there is our manage order in database and now we need to do our uh post request so we're going to do an export async function P brackets and then we're going to do requests and that is a next request all right and in here we're going to do a cons user and that's going to equal to await get current user and then we're going to do if we don't have a user we're just going to just uh return aex responsejson and it could just say something like I do parentheses brackets we do a error and it can say something like not signed in all right uh we can also give it a status as well status I think it's got to go in Brackets this isn't in my code but something that we should probably get in habit of doing whenever we doing API routes so status 403 and then we got to let me scroll down some so we're going to do a cons user ID and that's going to equal user do ID and then we got do a cons body that's going to equal a weit brick. Json right and we got to do const items payment intent id and total amount and that's going to be all coming from our body that we're going to send over from our checkout form so this part all makes sense here in a second once we do our checkout um component all right so we're just extracting everything that's that we send over from our um checkout so we we're just going to be sending these three items um our car items our payment intent id that's stored inside of our state that we made with Gyan and total amount all right so we got our body and then our con total it's just going to equal to total amount right now let's go ahead and do our try catch so we're going to try do a Cons payment intent that's going to equal a weight and we're going to do our manage stripe payment intent function and we're going to go ahead and send over our payment intent id and our total all right so that one's done and we also going to do our cons order and we're going to do a wait manage order and database and same thing we're going to send over our payment intent we're going to send over our total we're going to send over our items and we're going to send over our user ID all right nice and we can just go ahead and do return a NY response uh next responsejson and we're going to return our payment intent like that all right so now we need our catch so we can do catch error and you can do whatever you want we could just do console error error right I'll give that a save and that was a bunch of typing woo that was a large large file there wasn't that long I mean it wasn't longer than our um cart cart was pretty long I think it was like what 150 lines of code and our cart component so yeah 140 all right cool so that is our crate order API route um let's just go back over it right quick so here just managing our strip payment intent I tried to name the functions as best as I can to describe them uh so yeah that's just managing our payment intent uh and here this is where all the magic really happens is managing our order in our database we're just checking to see if the payment intent exists if it does we just update the order that has that payment intent if it doesn't we create a new order and here we're just adding the items that was tied with that order and we're just creating a another uh order item inside of our database and it's tying into this order here these orders that was created and out here everything just comes together all right so now let's go and create our order I ID actually I think we need to do our update order status first so let's go ahead and do that this isn't too long so we're going to go ahead and import Prisma it's going to be coming from at lib SL priso and then same thing we going to import next request and next response all right and to export async function it's going to be a post I'm going to do req request and it's going to equal next request like that all right so we the same thing we going to do a cons body it's going to equal a weight uh w. Json and now we need to extract stuff from net body so we do a const order ID and we're going to take in take our status from that as well do body all right so now I'm going to do a try catch new try do a con updated order that's going to equal a weight Prisma do order. order order. update and we got to tell it where to update so obviously we're going to use our order ID number and the data is going to be status status all right and we can also return a next responsejson I'm going to return updated order right and then we need a catch so catch error and what we can do is we can just do a console. error eror and also return like that all right so that is our update update order status so this is basically once we check out completely we want to update the order status to payment successful and uh we're going to use this inside of our checkout form all right so now it is time to do our last API route for our shopping cart and that is going to be our order ID um all right so we're going to import our next response and also next request and then we also going to import Prisma I don't know why this this is the only thing that doesn't autocomplete for me all right so let's go and do our export and we instead of a post we're actually going to do a get a sa function so G and then we going to do req that's going to equal next request comma re s and that's going to equal next response all right let's go and do our Tri cat we going to try and do a cons latest order equal await Prisma order. fine first and we're going to do order by we created date and we want it to be descended all right and then select we want to select by ID and that's going to be true right and underneath all of this so if we don't get our latest order so if latest order is false we just going to return right all right cool um now underneath here we're going to return a next response not next request next responsejson parentheses brackets and then our order ID is going to equal latest order. ID all right and we also need a catch let same thing we just do catch error and then just console. eror the eror and then we can just return like that all right uh so that is that is it for our API route so now it is time first we're going to try to fix this see what's up with that I don't know why that is happening but afterwards we're going to work on our checkout page and then our checkout form and then we'll be all complete with our cart and then we'll go into the wish list we'll focus on that and then we'll just finish styling up the homepage we still got to do our footer we got to add the rest of our products so we still got some ways to go uh so yeah let's um head over to this checkout page all right so it's time to actually build out the checkout page so we're going to make this a use client client component and we're going to import a few things going to import load stripe and this is going to be from um stripe at stripe slash react slash actually it's going to be at stripe slash stripe.js and this has to go in Brackets like that and also we're going to import stripe elements options is here elements options there we go all right and we're going to import elements and this is going to come from stripe SL react stripe JS we going to import our checkout store so use checkout store all right and use State and use effect use State and use effect and also use router cuz we're going to be um pushing the sign in form if you're not signed in and try to check out you got to be a member to check out so that way you can track your order inside of your um user dashboard we going to import we going to do use router and that's going to come from next navigation not next router and we're going to import the checkout form which we haven't I don't think we exported it yet so let's go and Export this right quick little checkout form and I'm going to import car entry but we're going to import it as I cart entry this was in a dock this the way they had it inside of the docks so going to import toast from react hot toast and that should be all of our Imports for this um component so first things first we're going to do a cons stripe promise and it's going to be load stripe and this takes our um stripe public our stripe publishable key so we're going to do a process. EMV nextore strip or public underscore strip underscore publishable underscore key right and do exclamation point just to get rid of that error or maybe we just have to just right as stream all right uh and now let's go ahead and work on our checkout component um first things first let's accept the props because inside of the cart and this is why we was getting this error earlier I was wondering why we was getting this eror so um yeah we just got to accept these props inside of our checkout so we getting total price and items so items and total price price and um now let's give these some let's give these types I'm going to do brackets and total price is going to be a number or it can be undefined and um next items can be is going to be our iart entry but it's going to be an array right and it looks like we're getting error somewhere oh okay we don't have anything in our return all right so that got rid of that error in here which is good and let's go ahead and do cons router equal use router and we got to do our cons checkout store and that's going to equal use checkout store and last but not least we're going to set some state so we're do a cons client secret and a set client secret and by default it's going to be empty quotes view State and just going to be empty like that and a mistake all right and now we're going to have a use effect and this is going to be uh our create order function and we're going to send a post request to that API route that we made earlier just create order and we got to send it over over um items we got to send it the payment intent id from our checkout store and then we also got to send it over the total amount so let's go ahead and do that now pretty lengthy but it works all right effect use effect all right so we're going to do a const create order and that's going to equal async all right let's go do our try do cons response equal a weight Fetch and we're going to fetch the API route so let um do slash API slash create order order create Das order and then we're going to do a comma and we got to send it over the method the method is going to be post comma and our headers is going to be I'm going to do content type content Dash type the application slash Json all right let me scroll down some all right comma and now we got to do our body and it's going to be json. stringify parentheses brackets and now this where we send over all of the data so we're going to do items going to be items our payment uncore intentor ID is going to be our checkout store. payment intent and then our total amount is going to be our total price all right I forgot to add a comma there all right cool and now we need to do some error checks so we're going to do if our response. status triple equals to 403 we're going to toast do error and we're going to say please sign in all right so if Oh wait we're getting error let's see if we go check out create order and as you can see we made a status 403 if we don't have a user available um so inide of our checkout component if the status is 403 we're going to toast the error and it's just going to say please sign in and why am I okay that's because we didn't do the catch inside of the try all right and we also want to push sign the signin page so we're going to do router. push we do slash sign dasn all right right and then I'm going to do checkout store do set checkout and I'm also want to set that to cart right because once we click checkout our checkout store going to be set to check out so we want it to set it back to cart all right and then after that we're just going to return okay all right and after that we're going to do if our response is not okay not IG not IG if our response is not okay uh we're just going to throw a new error and it'll say something like network network issues I don't know you can put anything there Network response not okay if you want network issues all right so now let's go ahead and do a con data let's going to equal weit responsejson right and then we're going to do if our data andn our data. payment intent we're going to set the client secret to whatever our data that payment in intent is so we're going to do payment intent do client secret all right because we're going to send this client secret over to our checkout form right um and then we're also going to going to check out store set payment intent to our data do payment intent. right that's that all right now we need our else do else and we could just console. error uh unexpected on x expect it data structure right you can also add data in there if you want like that uh now we just need our catch our catch is going to go here I believe so this is to try yep so our catch is going to go here so we going do catch and we just going to catch a air make get this console eror eror all right and after all of that we have to run this create order function because we're still inside of that use effect so we also need our dependency array which is going to go here so we got to do a comma and do empty dependency array because we just want this to fire only once when the component is loaded we don't want this to keep firing over and over again so right under over top of here we're going to do create order like that all right so somewhere we messed up oh maybe because this doesn't have anything in there there we go all right let's give that a save make sure we don't have any errors so that right there is our um create or order function make sure everything looks good Perfect all right and now underneath this use effect we're going to do a cons options so I don't think I showed you guys this website so stripe so you have stripe.com this is what we added our products on but then you also have another website called stripe JS or which which is I mean it's still the same thing but you just go to their docs and then it looks totally different looks like a whole different site and here you know you can learn about all the stuff that I'm doing now with about like the um the options the stripe element options and um the low stripe and everything so all of that is inside of the docks all right so if you guys want to check it out they got pretty good docks U the only docks that that I really don't like it's NEX off their their docs is a little bit confusing I'm not going to lie but um yeah um they got pretty good ones stripe does all right so we're going to do a const options and this is stripe element options thata type and it's going to be our client secret comma and we're going to give it an appearance so this is going to be our actual checkout form and we can give it a theme the theme is going to be stripe comma and then labels it's going to be floating all right um just got to go in quotes right perfect and now let's do our return we're going to do if client seek secret and and parentheses that's when we're going to render out elements um yep elements and let take some props this is going to take our options and is also going to take stripe which is going to be our stripe promise all right and in between here is going to be our checkout form and this takes a prop this is going to take our client secret perfect that to save so once we click check out nothing should happen let's see yep nothing should happen yet but it renders out our checkout form so that's what we're about to go work on now all right so head over to the checkout form component and first things first we're going to make this a client component this one's pretty lengthy as well so we going to do import use State and also use effect all right and then we're going to import three imports from uh stripe react stripe JS we going to do import import payment element going to import use stripe and we're also going to import use elements right and then our checkout store there's checkout store and then our uh use shopping cart you shopping cart use router that's coming from next navigation I always keep putting next navigation and we also going to import toast from react toast and import our button all right cool so we need to accept this uh client secret prop that we made so it's going to be client secret all right and let's go ahead and give it a type which is just going to be a string so we're just going to do brackets client secrets and is a string all right so let's go ahead and get access to all of our stuff so we going do a con stripe that's going to equal use stripe going do a cons elements that's going need to a use elements con checkout store checkout store that's going to be use checkout store and uh now let's set some State we have to set is loading and we also got to set um we also got to do an order ID um so let's do cons is loading and then ass set is loading my default going to be false now for our order ID const order ID and then set order ID that's going to equal use State and by default is going to be null all right uh now let's grab some stuff from you shopping cart so we want to grab the clear cart so I guess I did use Clear cart I think I said I didn't use it so clear cart and total price and we're going to grab that from you shopping cart all right and up here we forgot to add our cons router go use router so that way we can push back to the home screen once you have a successful checkout all right so we're going to do a use effect and this part is all inside of the docs so we're going to do a use effect and all we got to do is if it's not stripe we're just going to return all right and then we're going to do after this we're going to do a if it's not a client secret we're just going to return as well and we're just looking for any changes made with stripe okay and now let's do another use effect and this is going to be our fetch latest order ID and we're going to be making a um a request to our order ID route that we made so let's go ahead and do that and this is just basically just getting that order ID that way we can use that and change the status of the order once it's completed because if you guys don't remember by default um once you click checkout you get a payment in 10 ID and the status is a wait and payment so we want that status to change whenever we actually check out so to do that we're going to grab the order ID first so we're going to async function and I'm going to do fetch latest order ID and do a try cons response that's going to equal await fetch I'm just going to fetch the API route do slash API slash order ID right and I think it's undercase that's really important cuz I don't think it'll work if if it's a uppercase all right we're going to do const data there await responsejson and now we're want to set our order ID to that data. order ID that we're getting from cuz we did we did a uh get request right yep get and we're just getting the ID so we're saving that inside of our state here all right and now we need a catch so we do a catch error and we could just console that error the ER all right uh so this is the use effect now we need our dependency array because we want this to fire as soon as the component mounts and only one time and we're going to call it here so we're going to do fetch latest order ID like that let's give that a save all right and now we need our onsubmit for our actual checkout form so we going to do a cons handle submit async I'm taking an event and that's going to be a react. form event first things first we're going to do eevent default and we're going to do if stripe is false and elements all we're going to do is return right and we're going to set so after that if that doesn't so this doesn't return that's what it we just going to set is loading to true all right and we're going to do stripe dot so once you click dot you should have access to for a bunch of this stuff uh I haven't used probably about 99% I only used this one and that is confirmed payment confirm uh I thought confirm payments was there oh I spell oh my God I spell con okay con confirm payments there we go confirm payment that's the only one I use all right and we're going to do parentheses brackets and in here uh we're going to have our elements comma and redirect is going to be if required right and then we going to do a DOT then going take in a result and we're going to return if check so we're going to do if results. error we're going to do checkout store. set checkout back to cart cuz we don't want it to stay on checkout right now let's go ahead and fet our updated order routes um let's see cart all right so still inside this if statement we're going to do we're going to go and fetch that we're going to do fetch slash API slash update dorder Das status do a comma and I believe we did a post yeah we did a post request on there so the method is going to be post comma we got to do our headers is going to be content type it's going to be application SL Json right let's go and send it over our body we got to make sure we add this comma here the body is going to be json.stringify and only thing we send it over is our order ID and that's going to be order ID and then our status which is now going to be payment successful Right add that comma there all right cool and now we have to set is loading wait some we did something wrong all right I see it now so we just got to remove that um parentheses there and we're going to add it down here like that all right and so underneath here so make sure you do bracket parentheses bracket parentheses and then a bracket I want you guys to get lost like I did so do set is loading to false and then we're going to do a router. push and we're going to push our homepage and then we also want to set our checkout store. set payment intent back to the default which is just empty and last but not least we're going to end it off with a nice toast success and say that your payment is successful there we go perfect so that is our handle submit function all right so now it's time to actually do our form so let's go and return a form and we can get rid of this act and give this a class name of text Gray 600 and go and give it our on submit which is going to be our handle submit that we just made and in here we're going to do payment element that's a self closing component and we got to send it over some props we're going to do options double brackets and we're going to do layout is tabs right now we're going to have H1 and this is going to have a class name of py4 text small and a font bold and in this H1 it's going to render our total price but we're going to come back and format it for now we're just going to put total price and then underneath this H1 I'm going to have a button I forgot this takes children all right so I send it this button over some props so we're going to do disabled equals loading is loading or stripe I mean or not stripe or this not elements like that all right and then we want to onclick here and this on click is going to clear out our cart clear cart and then give it a type of submit all right cool and now inside of this button we're going to have a span and inside the span we're going to do if is if it's loading we have another span and it's going to say processing dot dot dot else we want to span and it's going to say pay now right give that a save and I believe that should be it for our checkout so we can actually test this out but before I do I actually want to add some more products add a medium in my favorite shirt love that shirt and I like two c on check out and hopefully it renders out all right guys so I spelled next public straight publishable key wrong inside of checkout and that was why this wasn't working at first but now we got our checkout form uh but before we actually test all this out uh mongod DB is currently down so we can't really see anything in the database right now they're working on the issue so I say in the meantime we fix the pricing for all of our stuff I meant to do that earlier so to do that what we're going to do is we're going to create a file a folder inside of the root of our project and it's going to be called UTS let's go and close out of all of this stuff and we're going to create a file a folder and it's going to be called utils and in this folder we're going to create a file and it's going to be called format price TTS all right and here we're just going to do actually I might just copy this over and just paste it in here it's not too much we just do con format price we take it in amount which is the number number and we return intl. number format and the style currency currency USD and we do do format amount 100/00 and then we just export it right so now we're going to head over to one of our components so let's start with the cart so let's go to app shopping cart components cart let's go and import that in here import format price and wherever we put total price that's where we want to believe it's down here somewhere sub total so total price so we want to so we can't just do brackets or format price like this uh wait I think we got to do brackets sorry so we can't just do format price and then take in total price like that can't just do that we'll get a error saying uh type undefined is not assignable to number so to actually a work around what we can do is do brackets and then we'll do total price if it's not undefined that's when we're going to uh render our format price with our total price but else we just want to show null all right so now hopefully and as you can see it's got that dollar sign now and it also got the dot in between the 74 and 97 the cents and the dollars now we need it to do it here for the price let scroll up um where is it item. price but I think we can do item. format it value for this one there we go item. formatted value that's built in from you shopping cart all right uh let's see so we did it there and we also need to do it for our uh product card as well let's actually copy this where we at copy this here because we might need to do do that for this as well so head over to components product cart and we do have a error here on click oh I forgot we supposed to come back and try to figure that out we never came back for it all right so we looking for Price where are we at Price a product i unit amount all right so we're going to [Music] do um format price and then just take in the product. unit amount right I should switch that perfect all right so let's go and fix this error right quick so if you read it it's saying that type undefined is not assignable to type void uh the unexpected comes from property onclick which is declared here so type undefine okay so it could be undefined so we just got to head over to our at the cart button so leave this inside of components UI at the cart and all we got to do is add a question mark here and I should get rid of that error perfect all right so let's actually test out our stuff now because we about to work on our wish list so we got our cart we got two items three items in our cart we got two medium GitHub shirts and one debugging shirt I'm going go and click on check out our checkout form is rendered and we forgot to add the formatted price there so we'll go do that here in a second and let's go and check our database DB Atlas was just down so so hopefully it's working now um it was taking a while just like this I really hope it works but I checked the status it said that it was having some issues so hopefully this loads up come [Music] on start it over brow collections all right perfect I load it all right there we go so now we got our ID we got our user ID so this user ID should be the same as the user ID if it loads up I'm probably asking asking for asking too much from it right now like I just said it was just down probably should have just stayed on the screen okay so we got our amount we got our uh currency and we got our status which is a weitting payment and now I'm getting that error that I was getting so yeah M go was just down and all right but it showed so now what I want to do is actually check out so I'm going to do 42 42 424 424 424 and 424 and click on pay now and then we get processing and now our card is empty and we get payment successful and we get pushed back to home so that's what we want it so now let's go ahead and check our database and this should change to payment successful you probably have to give it like a minute or two all right perfect so now it says payment successful before it disappeared so all I wanted to see mongod DB fix your okay by the time I get back all right so now it's time to work on the wish list so our cart is empty now uh so our whole cart functionality seems to be completed so let's go over it we can add the cart if we try to add the cart without choosing a size we get a errror okay and we can add size small we can add multiple sizes and if we do that it just adds twice with the different size instead of increasing the quantity uh that was an issue that I was having and that issue is fixed now and we can also check out we can also increase the quantity decrease check out and so we got to fix this um fix that total amount right quick so let's go a and do that so let's head over to the checkout form and I believe it's down here total price so I'm going to just paste paste that in so we got the same thing we did for our uh with a check our cart I'm just going to go to import format price all right and give that a save click back to cart click on check out perfect and we're we can check out and it's get all getting tracked inside of our database and to be honest it's also getting tracked inside of our stripe as well so as you can see it says incomplete and this is the order that we just did it's not complete it yet but if we go ahead and check out which I'm about to now 42 42 424 424 424 and click on pay now processing car empty payment successful push back to home and now let's go ahead and refresh the stripe page and now that payment should be successful Perfect all right so now I think it's time to start our wish list functionality and to do that we're going to head over to the store and we're going to create another file it's going to be called use wish list store and inside of the description there's going to be a GitHub gist with the this code here for the store or you can head over to the GitHub repository just to save us some time I will go over it and also added some comments in it so you guys know what each line mean and once you paste you will get a bunch of errors that's just zustan been a little bit buggy to get rid of the errors just watch this you just get rid of one of the comments and then click control Z and then that's it so um yeah it's a little bit buggy but uh basically same thing as we did inside of our use checkout we did our types up here and then you just set the initial state which is our only initial state is going to be wish list it's going to be empty array and then here we do a function to add an item to our wish list we take in a state and we also check and see if the item already exists in our wish list if it does we'll just add a quantity to it um and if it doesn't we'll just um add it to our wish list with the quantity of one and down here is just a remove from wish list function and we also got to name it um down here so really simple um let's go and close out of that and now inside of our app what we're going to do is create another folder and we're going to do parentheses wish list so in here is going to be all of our wish list components and uh wish list page so let's actually start by creating the wish list page or actually start by creating wish list components so in here we're going to do a component folder and inside this components folder we're going to do a add to wish list button. TSX and we also going to have a wishless icon I TSX and that's going to replace the icon inside of our nav bar and I believe that's it um now let's make sure you click on wish list folder uh now we're going to have a folder in here it's going to be called just wish list and we have a page. TSX let me just make sure all right cool so let's start with our add to wish list button and do use client and we're going to import our react icon that we use inside of our product card cuz this button is going to replace that button inside of there and then we're going to import use switch list store going import product type and last but not least we're going to import toast cuz we want a nice toast once an item is added to our wish list so we're going to do cons I'm just going to do RF right all right so we're going to receive some props here we're going to receive name going receive ID image unit amount quantity right and all of this is going to have a type of product type right let's go and get access to our wish list stores we do wish list store wish list store that's going to equal use wish lless all right so now we want to make a function I'm going do add to wish list all right and kind of the same thing that we did in our in our store we going to do a cons existing item and we're going to do wishlist store. wish list. fine and it's going to take in a wish item and return our wish item. ID equals ID so that's existing item and so if existing item we want to do a toast. error and it's going to say fatic dollar sign name is already in your wish list all right that's that and then we need our else else we're going to do wish L store. add to wish list and we're going to add everything in here so we're going to add our name we add our ID we add our image add our unit amount need amount we add our quantity which is going to be one and then afterwards we want to have a toast SU ESS and this was going to say back ticks dollar sign brackets name add it to wish list all right and then last but not least down here we're going to do we're just going to have a div and this div is going to have our icon fa art Circle plus we going have the on click on this div so we have on click and add the wish list Perfect all right so now we got to head over to our cart I mean not our cart our um product card and we got to add this in there so do components product card and wherever we added that fa circle plus I believe it's this here so instead of this now we're going to have our add to wish list button now we can send it over all of these props that I'm just going to copy over so we send in a name which is product name image ID unit amount and quantity so let's give that a save and let's head over to our project and once we click this button hopefully we get the confirmation that has been added to our wish list nice got our wish list and then if we let's see if we try to add it again if we get that error GitHub is already in your wish list nice all right so that is our wish list button so now we need to update our wish list icon this isn't too long so basically all the only thing I want is whenever there's an item inside of our wish list I just want this to change the color to Red that was the whole reason why um I did it this way separated the icon uh so we're going to do import link and then we also going to import AI outline heart coming from react icon SL AI and we also going to import our used wish list store right RF all right so since we already exported let's just go ahead and head over to Navar right quick and we're going to import it here so instead of this AI outline heart I'm just going to do wish list icon like that right as you can see it just messed up our whole entire nav bar but we're about to fix that we going do a cons wish list store it's going to equal use wish list store right and let's go and return some jsx I'm going to do a link and this link is going to take take us to our wish list page SL wishlist and we're going to have a class name we're going to do brackets back ticks dollar sign brackets and I'm going to do wishlist store. wishlist length. length is greater than zero if our wish Lord has any items in it we want the text to be red 700 and then else we're just going to return all all right and inside this link we're going to render our AI outline heart like that give that a save and we should should be presented with the red heart there we go nice um all right perfect [Music] see all right nice now we need to style up our wish list page supp we click this should take us to our wishless uh the default is a rare okay that's because we didn't export this yet this page let's go and save that and I should get rid of that a all right so first things first we're going to make this page a use client component I mean a client component not use client component and then we're going to import use wish list store also going to import image from next and also import our add the cart button from our shopping cart components folder a cons wish list store equal wish list use wish list store all right and let's start stying up this page so we're going to have a div it's going to have a class class name of py20 and then we have another div with a class name of main Das container and now we're going to map through our wish list well actually we're going to show a message if our wish list is empty so we do brackets wish list. store. wishlist that length is greater than zero oh okay we only going to show this if it's greater than zero we have to show our message at the end so if our wish list store is greater than zero that's when we're going to return fragments and return a span and just going to have a class name of font dasb in this span is going to say [Music] you have brackets wish list store dowi list. length items in your wish list give that a save so we should have two items in our wish list uh okay we forgot the else that's why I was doing that all right for now we could just do else null just so we can see all our changes all right let's give a save and so we got two items in our whisk list we can just get rid of that all right cool just underne this span we have a div with the class name of flex Flex wrap gap of 10 a Max MD of justify Center and now we're going to map through our wish list so we do brackets wish list store. wishlist map and we do product and we going return a div and give this div a key of product ID scroll down some and inside this D we have an image this is going to be our image of our product source is going to be product that name I mean image sorry the alt is going to be product that name width is going to be 200 height is going to be 200 all right so underneath here we're going to have H1 with a class name of font bold and here is going to be our product that name that a save and then underneath here we're going to have another div with a class name of flex and a gap of three and here we're going to have our add the cart button and also our remove from wish list um Button as well so let's go and do our add to cart add to cart and if you guys remember just add to cart takes in a bunch of props pretty simple so we got our name product I mean our name our image price ID and also send over our currency give that a quick save and then we're going to do a button and this button is going to have a onclick and what it's going to do is wish we're going to remove we're going to do wishlist store. remove from wishlist and we're going to remove the product dot dot dot product like that and it's just going to say remove right try it remove nice all right so now we need our else down here instead of saying null we're going to return a div with a class name of with full height screen F justify Center item Center and we're going to have a H1 with a class name font bold and then a text Excel and it's going to say your wish list is empty all right perfect sweet okay that was weird all right so now once we remove it now it says your wish this is empty I don't know why it's all the way down there we don't probably have to make this height screen I don't know why I did that all right Perfect all right so now I say we so our wish list functionality is working we can go to add an item to our wish list if it's already in our wish list we get an error we can add that one add that one and then head over to our wish list we get our items there so our wish list is complete so now I say we start styling up this homage and then start stying up our shop page and then our contact page and then we'll be really done and we still got the user dashboard we have to do and perfect so yeah everything's coming along pretty well all right so now it's time to start styling up our website a little bit more uh we got most of the backend functionality done we still had to got to do the user dashboard where we can track all of our orders um and that's really about it so let's go ahead and we're going to create let's go close out all of this stuff so that way we can have nice clean slate and inside of components we're going to create a file and this be called banner. TSX all right and we're going to export this export and we're going to head over to our app and inside a page it's going to be right underneath top products later all right uh we didn't import it that's why Banner there we go all right save that and now we should see it inside of our project is our server okay there we go all right so head back at the banner and this is really really easy component here we're just going to import image from next and we're just going to render out div with a class name of main container Flex justify Center and a my of five and in here we just going return our image and the source is going to be slash Banner Das image at PNG the width is going to be400 the height is going to be 500 and ALT can be um Banner t-shirt Banner or shirt Banner give that a save and let's see if it shows up nice this is my Cod and t-shirt all right right cool so now it's time to do the section uh I said we do the footer and then we're going to do the new product section for the new products so it's going to be kind of like similar to this section here the top products but it's just going to be for new products and so let's go and do the footer so inside of the components close out of this we going to create footer oh sorry footer ttsx right and this is going to be a client component and we're going to import a bunch of icons that I'm just going to copy and paste over so we import an fa Square X Twitter fa square Instagram fa Square Snapchat TB brackets and Fa Facebook square right and then we also going to import image from nextjs all right let's go export this and we're going to go ahead to our layout and we're going to import it there we head over to layout and we want it right underneath our children so footer give that a save and head back back over to our component and let's start stalling this up so we're going to have a div with a class name of with full a py of five BG gray 00 margin top 10 we have another div with a class name of main container main container and let me go and close out of this right quick all right and then we're going have another div in here and this is going to be a class name with py5 margin bottom five a border b a border gray 300 a border opacity border opacity 20 Flex justify between item Center on Max MD we're going to do Flex C and let me scroll over bunch of class names for this div Max MD Flex C and also Max MD a gap of eight okay uh do we put a okay perfect all right and inside of this div we're going to have another div and we're going to have a class name of flex Flex one a gap of one item Center text Xcel font medium and also text white all right and in here we're going to have our H1 and it's going to say Dev Dash threads right and now we're going to render our icon our TB brackets angle icon like that and let's take a quick look there we go it's our logo all right and then this D we're have our ul and we're going to have a class name of flex item Center justify Center a gap of 16 Flex one text White on Max MD we're going to do a flex C and Max MD gap of five all right so this is where our Link's going to go so we actually have to import our main links as well main links from our constants and we're going to import link from nextjs I must have got lazy in my project and didn't do this so all this is all off the off the brain right now all right so we're just going to render out our main link through our main link so we do main links that map and we going to take in a link and we're going to [Music] return from jsx so we're going to turn link tag from nextjs all right and we do HR and that's going to be link routes and in between here we have our Li and that's going to be link. label right and we also need a key so I think I might just do key and what we can do is do link and then ID I believe we can just do ID there like that or maybe not let's see if it works all right uh okay perfect all right shop perfect contact about nice all right um U so right underneath this U we have a div and we're going to have a class name of flex a gap of five text white Flex one justify in and then a text 2XL all right and in here this is where we're going to render out all of our Icons copy and paste these uh I must have didn't it finish just copy some of it all right so two divs now right underneath here we're going to have another div and it's going to have a class name of with full text Center a text small text white Flex Flex call a gap of five on medium screens and up we're going to do a flex row justify Center and also item Center in here we're going to have a span and it's just going to say all right reserved and then Dev threads.com right and we're going to render our image of our payments we going to have an image our payment methods that we accept and the source is going to be slash payment Das getways I meant I meant to put gateways I put getways are you serious so getways PNG and the width is going to be 300 the height is going to be 100 and then alt is going to be accepted payments give that a save and let's take a look it's looking really good and we got our payments nice and we can inspect I'm zoomed in a little bit too much see how it looks on mobile nice looks really nice on mobile o looks beautiful all right cool so that is our footer so now it's time to do our new product section which is going to go in between this footer and this Banner all right so before we actually create that section what we're going to do is head over to stripe and well we already we was already on it I don't know why I just did that so head over to stripe and we're going to add four more products to our website and it's going to be the same exact way we did the top rated ones we're just going to add product I'm going to open up my product images and I'm going to go ahead and drag the ones that we haven't did yet so I started from P1 P2 P3 P4 and now I'm on P5 so put that image in there and it's asking for my password let that load up so this is that's the software engineer shirt or software developer shirt I think I just named it SD or or developer shirt developer shirt and so same way we did the top rate we're going to hit on the metadata and we're going to do new equals true all right and one off one to make this price $24.99 and then add product all right so we got our four extra more products there we head over to our project we still got these four here so all we got to do is like I said it's literally the same exact way we did our top products so we can actually copy this whole entire code and we're just going to change up a few things so we're going to create a new file and it's going to be called new products TSX and you could do it a whole different way you can actually um map through your whole entire products and uh just choose four of them but the way we're going to do it we're just going to just use the filter method um so top products so let's see what we got to change and let's actually render this out on our page so head over to page we're underneath our Banner uh actually hold on let's change the name first to new products and change this to new products head over to our page new products see if it auto completes okay there we go all right give that a save and head over back to the component and like I said we just got to switch up a few things so we're still going to need our fetch products still going to need product type we're still going to need link um actually I thought we would need product type but I guess we don't uh product card and Link so we got our cons products we're fetching them so this is going we're going to change this to new arrivals and we're still filtering throughout throughout our products and products filter product so instead of metadata top rate is true we're going to do metadata new is true and then down here we're just going to change this to new arrivals all right and just give that a save and we also can change this to new arrivals that save and as you can see we got our new arriv we got our four brand new shirts that we just added it's that easy and we can add these to cart GitHub shirt has been added got our cart there and it's inside of our cart Perfect all right now I say we work on our we can either work on our dashboard user dashboard or we can work on our shop page um I think we might go with our user dashboard let's go ahead and knock that out all right so um let's go ahead and do our dashboard we're going to create a folder inside of our app and this one's going to be called dashboard all right and in this folder we're going to have a page TSX are RAF and now let's go ahead and head over to our dashboard we're going to click on orders and now we're at our dashboard all right so before we do anything inside of this dashboard we're actually going to create a new action so head over to the actions folder and we're going to create one called get orders at TSX this was pretty small we're just going to do import Prisma from our lib lib uh SL Prisma and then we're going to do export con get orders going be async and it's going to take in a user do any and then we're going to return con orders that's going to equal a weit Prisma order that find mini I don't know why that did that fine mini and we got to tell it where to find it so where it's going to be a user ID that's going to user do ID and then we also want to include the items items is true right we got to add a comma there so where and include items true and all we got to do is return orders all right so there's our get order action so we can actually just close out of that and then head over to our dashboard and we're going to import that here and actually use it all right so first let's go and import it get orders make some space here we're also going to import get current user we're going to import image and also import format price all right so let's go and do cons user equals weight and that's coming from our get current user action and now we're going to send this user over to oh we got to make this a async function so let's just do async like that and now we can we're going to send this user over to our orders cons orders that's going to equal a wait get orders and going to send in our user like that all right and let's go and do our return I'm going to do fragments all right so if we are if we're are a user so if we're signed in that's why I want to show all of this stuff so we're going to do a div with a class name of main Das container and here we're going to have another div with a class name of padding 8 Flex item Center justify Center a gap of 12 a text Center and that's it for that d div and we have another div in here and this is going to hold our username and email so we're going to have a little welcome me message at the top so we Grab A P tag with a class name of text 2XL a font mode and italic and it's going to say hello user.name like that and this can be undefined so we're going to put a question mark there let's see if this works oh we don't have our else for now we could just do null just so we can see all our changes all right let's see Hello Antonio yay all right let's take off the B I think that's a little bit too much can keep it italic though all right there we go actually take off the italic too all right perfect hello Antonio maybe add a comma there and underneath this P tag we have our you our email p and then we're going to do user. email email should show up so we we're signed in at admin at antonio.com all right two divs down we're going to have another div and we have H1 that says orders and this is going to have a class name of font bold a text Excel text Center and underline let take a look at that nice all right so under this H1 one we're going to have we're going to render out a message if we don't have any orders available so we're going to have orders that length triple equals to zero and we have a div and it's going to have H1 that says no orders placed all right this is going to show when we have no orders but if we do have orders else we're going to show going do fragments and then we're going to do orders that map and make sure you put a question mark there because it could be undefined and do order and we're going to return a div and do a key of order. ID and this is also going to have a class name of rounded LG a padding of eight M of four a space y Y 2 a BG gray 200 all right and inside of this D we're going to have H2 this is going to have a class name of text extra small and a font medium and this is going to have our order number order number we're going to do that what we can do is like a little empty space like that and then we're going to do order. id order. id replace because our order number is super long and we only want to show um a little bit of that number so we head over to our database hopefully it just is working now remember DB was down earlier and refresh and see our order number is right here so it's the ID so we just want to just show the numbers in here and not actually show all of that so what we're going to do is do a order id. replace and we're going to do uh for slash uh where's the back slash on his keyboard back slash rber case D for slash lower case G comma empty quotes like that all right let's actually take a look at that there we go see it just shows the numbers from the order and underneath this H2 we're going to have a p and this is going to have a class name of text Xs and we have our status which is going to be our order status right underneath this P tag I have another div and this is going to have a class name of text small on large screens and up we have Flex item Center and then a gap of four right take a look payment successful payment successful and now we're going to render out do our items inside of our order so we're going to do order that items that map and this is going to be product right we have a div I have a key of product. ID and this is also going to have a class name of py2 all right scroll down some we almost finished with this all right so um now we got to render out our product image but we can't just do product image inside of an image tag we actually got to render out conditionally so we got to do product. image and and so this Pro if we get one render our image our image tag and in here a source is going to be part product. image the width is going to be 100 height is going to be 100 and then the alt is going to be we can do back TI um image for um dollar sign brackets product that name that name all right let's take a look at that see if our products show up nice Perfect all right so underneath here we're going to have our H2 with a class name of py2 and this is going to be our product. name save that we got our names of our products underneath that HQ we have a div with the class name of flex items Baseline and then a gap of four you have a P tag in here and this is going to hold our quantity for each one so Quant itty and this is going to be our product do quantity perfect um I wonder if we have let me just see if we have access to this product dot okay so what we can do is actually we can add something on here so this is not even in my project that the completed one we got a size here too so we can do is right underneath this H2 we can have a span and we could do product. size and we can make this span super small so we do a class name of text XS like that this py2 may change that to like a py1 yeah yeah that looks good medium small okay all right cool and underneath here that closing div we're going to have a P tag and this is going to have a class name of font medium and a py of two down some and in here we're going have our total which is going to be our format price and it's going to take in our order. amount nice all right so that's that and now we just need to instead of this null we're going to render out a message that says please sign in if we're not a user so we're going have a div with a class name of height screen we going do like height 500 or maybe like height 90 let's see the highest it goes let's do like height 96 Flex Flex items I mean F or item Center sorry justify Center text 2 XL and uppercase in here is going to say please sign in to view orders there we go that is the dashboard completed all right so now I think it's time to actually work on our shop page and this is going to show all of our products so before we do that let's close out everything and inside of the com the app folder we're going to make another folder and this is going to be called shop and in this folder I'm going to make a file page. TSX let's go and Export it and um now we can keep that open but let's go to the actual page so we're just going to click on shop and it should take us to that page so before we start stalling this up we're going to head over to stripe and we're going to add our last four products one off and the price for these ones I'm going to make them a little bit lower than our normal price because we're going to have a filter in our shop section that's going to filter price from highest to lowest and lowest to highest so just for us to see that filter work we're going to change up the prices a bit and now all of our products are added we can actually close out of stripe um if you guys want to look around here but like I said everything is getting tracked inside of our stripe as well but I buil we built our own database to track you know our users our orders as well so but everything in here is getting tracked we go to payments these are the two payments that was made succeeded so we can actually close out of stripe now don't be we shouldn't be needing it anymore for the rest of this video and now head over to page uh shop page and we're going to start styling this up a bit so what we're going to do I I don't know if you guys remember but inside of the components we made a component called products and we haven't done anything to this yet so this is going to show all of our products on this page so but what we have to do because this products is going to be a client component we have to send it the data that we want because we won't be able to fetch our products in this because um we need to use async await and you can't use async await inside of a client component so what we're going to do is actually um fetch our products inside of this shop page and then we're going to send it over to our products component so let's um go ahead and import our products component and we're also going to import fetch products all right some space and since we're using our fetch products component we got to make this a async so I'm just going to do async and now here what we're going to do I'm going to return my products component and then I'm just going to send over it's going to be all products and that's going to equal to products all right but now we got to do our cons products that's going to equal a weight fetch products right and we're getting that error because we're not uh accepting a prop inside of our products component so let's take a refresh this right quick make sure everything still works all right so now we see products nice let's head over to products now and this one is pretty lengthy it's about 80 lines of code so like I said this is going to be a client component and we got a few Imports we're going to import use State uh we're going to import our product cart product card and we're also going to import product type product type hopefully I'm zoomed in larger enough all right cool and let's go ahead and so products let's go a and set our types now so we're going to do react uh FC do brackets and then we're going to [Music] do uh brackets going do all products and that's going to be product type and it's going to be an array all right and we got to close our brackets there and in here we're going to accept the prop so all products like that all right all right so let's go ah and do our sort buy because like I said we going to have a sort um sort by Price high to low and sort by Price low to high so we need to set some State we need to store that inside some state so I'm going to do sort by and also set sort by all right and by default it's going to be an empty quotes all right and let's go and make our um handle change we're going to do a cons handle sort change and that's going to take in an event we're going to do e but we got to make sure we do our H set it give it a type and that's going to be a react. change event or we can't just do that we got to make sure as a HTML select elements all right and we need to return set sort by and that's going to be e target. value all right and now we just got to make a function to sort the products based on the selected option so um this is actually my first time actually using sort I believe this is my first time using sort um so we're going to do a cons sort products and we got to return so we're got to do a if our sort bu is triple equals to price low oh price low Dash High we're going to return all products and we got to do a DOT slice and then on that we got to do a do sort and then do double uh parenthesis and we do that takes in a b you can actually name that anything you do like C A BW it's going to be a. unit amount minus B do unit amount all right so that right there I believe is sort in yeah so it's sorting by Price uh low to high and basically the same thing so we're just going to reverse it so price high to low it's just going to be um we got to put B in front and then put a was going to be B that unit price minus a that unit price so same thing so let's go ahead and do our else so going do else do our else if our sort by is triple equals to price High minus low we're going to do the same thing we're going to return all products that slice do oh that sort and same thing I'm just going to take in a comma B and then we're going to return B unit amount minus a. unit amount all right so now we need uh a l statement to return our products if there is no nothing like if we don't have anything so if we didn't choose price high to low or if we didn't choose price low to high we just want to just return a product so we going do else and just going to do return all products right so that is our sort products function and now I'm just going to do a cons sorted products and that's going to equal sort products right so that is that now we can go ahead and start styling up this page and write some jsx so we're going to have a section I think this is like the only time I use section I probably should have used them in other ones as well uh we're going to do a class name of relative uh medium screens and up we're going to do a py of 24 uh py6 gra have a div in here and that's going to have a class name of main Das container we have another div and this is going to have a class name of MD Flex or Justify between item Center and a margin bottom of six all right and then this did we're going to have a span with the class name of font semibold and inside of this span we going to have um something that just says showing 1 to 12 of we can do all products all products. length and then we can do items let's take a look at that so we should only have 12 products all right so you look sh one one two TW one through 12 of the 12 items Perfect all right so underneath that spam we're going to have a div and this is going to have a class name of MD item Center and we're going to have a label in here um you don't need anything for the HTML 4 but it will have a class name of font semi Bode and on medium screens and up we're going to do a me of two you guys don't know what me is this is margin inline in all right and in here we're going to do a sort by like that let's take a quick look it should be right over there nice all right now let's go and make our select um we going do a select select all right and this we going to give it a value so the value is going to be sort bu that's where we store in our state at and then our on change is going to be handle sort change and we also going to give this a class name of um medium screens it's going to be a width 36 a width full medium screens and up we're going to do a margin top of zero margin top of one py of two sorry about that phone went off py of two a px of three a height of 10 BG transparent round it outline none got to scroll over because it's a bunch of class names outline none going give it a border border gray 100 and then last but not least a focus a ring of zero take a look nice all right so now we need some stuff inside of our select [Music] and so we need options I'm just going to copy these options right quick and paste them up in here so we got we are getting oh why don't it save I mean why don't copy all of the stuff all right let's paste that in there there we go all right so the first option is just going to be the value is just going to be empty uh we get in an error all right so we got price low to high price high to low right so the first one is just going to be empty the value is going to be empty string so that's our default State and it's just going to say select next one is going to be price low to high you just write price low to high and the third one's going to be price high to low really simple all right so now we need to actually render out our products at the bottom here so we got our select we got our closing div we got another closing div so right underneath that second closing div we going to have another div and this is going to have a class name of grid on large screens and up we're going to do a grid cow 4 or medium screens we're going to do a grid Cy 3 on small screens we're going to do a grid cow 2 and by default on like extra small screens do gr K one and then into a gap of six and now let's go ahead and map through our products so you're probably thinking um we're you probably thinking we're just going to map through all products but since we're have this sorted products we want to map through our sorted products and not um our all all of our products cuz we made the sorted products function and then we gave it a name here sorted products so that's what we're going to do we're going to map through that so we're going to do sorted products map and we're taking in a product um and then we're just returning do parenthesis so we're returning our product card product card product card and we can give this a key of product ID and then also we're going to send this over our product as well all right take a quick save and this hopefully this works nice perfect and I see if this Filter Works so loow to high that's low to high and high to low perfect nice so now all we got to do now is work on our contact page and then I'm going to go back over through everything and make sure we didn't miss over anything but we don't do about page in this project I just left that out I mean I really spend most of the time working on the functionality on um this project and I know you guys don't want to get bored with just style and stuff so I did do a contact page and like I said that's just styling there's no functionality in that page so if you guys want to skip over that section you can but we're about to go build that page up now all right so let's go ahead and close out all of this stuff and we're going to head over to our app folder and we're going to create another folder contact and then in here we're going to do a page. TSX and then let's export that save it and now let's click on contact now we got our contact page so uh if you guys seen the uh preview I don't know if I showed this in a preview but um we do have like a map on here and if you guys want to know how to add a map to your website I normally just type in uh iframe Google Map uh HTML or something like that and it should be when these websites oh right here iframe generator so this is the yeah this is the website I use and it generates a map and it's interactive and stuff so um I did one and I'm just going to put it inside of the gist the GitHub gist in the description or you can just click on the GitHub repository so we're going to make a map component so new map. TSX and what I'm going to do is just copy and paste this it's not too long so like I said this all of this is inside of here you can generate one so you can put the address um I just think I just did Brooklyn New York or Bronx New York and you can set a height I would definitely keep this at 100% I'm not sure if you can change it yeah you can so keep that at 100% And just um copy over this code and just paste it in here so here's one and I make sure I put a main container our div main container so you guys just want to copy this one it should be good and now let's go ahead over to our contact page and we're going to import a few things here we're going to import map from components going to import button from our comp component we going to import input and we're also going to import image right and let's go ahead and write some jsx so first things first we're going to do a fragment and then we're going to add our map all right now let's take a look at that all right let's refresh and now map should be right there nice and then we can interact with it so yeah I did Bronx New York all right and then we just going to make some space here and we have a section with a class name of large py of 24 a py of 16 and then we have a div with a class name of main B container have another div and it's going to have a class name of grid grid cow 12 and this grid C 12 is going to be for medium screens and up make sure you add that and by default it's going to be g k one item Center and then a gap of six all right and we have another div in here and it's going to have a class name of LG call span five and on medium screens we're going to do a call span six all right and this is where our image going to go I'm going to do image make some space so the source is going to be slash contact. jpg and then our width is going to be 500 our height is going to be 500 and then our alt can just be contact image take a look and let's see if our image show up I think I click re refresh twice all right so our image oh I forgot to Dot there we go save that all right let's see if it shows up now nice we got our stack Overflow shirts there all right so underneath this div here we have another div and this is where our forum's going to go contact forum and it's going to have a class name of LG call span 7 and on medium screens call span six so this this right here is just giving me bootstrap Vibes if you guys don't know um I forgot so bootstrap was the first thing that I learned and I remember uh bootstrap was it a grid or something it went by like 12 and then you can do like the span I forgot but it just reminds me of bootstrap doing it doing it like this and we have another div and then we going have a class name of LG ms5 right you guys don't know what Ms is that is margin inline start so we use margin inline in and margin inline start in this project my first time ever using those things we're going to do div and a class name of BG uh White um actually need BG white uh let's just do a border and then a pattern of six let's take a look at that all right so ni we got our border and now in here we're going to have H3 let have a class name of margin bottom six text 2XL a leading of normal and and then a font of semi bold look all right nice make sure everything I think I might switch cuz this font semi bold is uh let's see how it looks I don't think I'm going to keep that get and CU I use semi B on yeah see look it's too much um might get rid of that let's get rid of that I save it yeah I think it looks better all right so after that H3 we have a form uh no action this form won't do anything just just for show and this form's going to have a div scroll down some have a class name of grid large grid and up grid Cal 12 and then grid call one and then a gap of three all right and then in here we're going to have another div uh what I might do is actually copy this so we're going to have our inputs and then a div so let me copy this and in here just paste that hopefully it's not confusing let me just zoom out some all right so this is our first one so we have a div with the class name of LG C span six and then our input not sure why that is uh not competed let's go and just save it see what happens all right so we got our input and since we did a um gr K 12 once we add another one of these so that's um type text ID name label name so if you guys don't remember we made this UI component and it takes in all of those props so let's head back to the page so we're going to have another div just like that and this is going to be also LG call span 6 and it should be right next to it because we did a ky span 12 I mean we did a um LG grid K 12 all right so this last one which is going to be our subject actually we have two more so this is going to be our subject so same thing but instead of uh col span six we're going to do a call span 12 so it's going to span um all of the columns that's our subject and now we're going to have a text area and which also is going to um span against 12 of our columns as well but I'm actually going to type this one out so this going to be a class name of LG call span 12 and then we going to have a label um let's see get rid of that um actually let's keep it cuz just going to be for comments and then I'm going to have a class name of text small right and then the label is just going to say your comment like that let's take a look at that okay and do they look like different fonts or am I tripping that one's bold that's because inside of our let's get rid of text small actually let's go look inside of our input and see what we did here mean put okay label here we go let's copy these class names and then we're going to head over to contact page I'm we going to paste them in here all right out class name and then paste so now they should look the same Perfect all right so label and then text area and we're actually going to do the same thing we're going to head over to our input and we're going to copy over these class names here right might switch up a few things I'm not sure yet so for the name um we don't need any name actually we could just do comments uh ID we don't need um yeah I think that's we don't need this either let's just add our class name and paste that in there let's see what happens all right perfect we got all the styling as our put we don't need to change anything keep everything like this uh now we just need our button so one to right underneath here for our button and just going to say send don't need to add any props or anything to it uh actually here let's add a margin bottom of three there we go perfect so that right there is our contact page like I said I know that probably was boring styling I know most of you guys are here for the functionality the backend um every time I do just like a styling video with no backend it doesn't it don't tend to do well so um yeah that's why I didn't do it about page it's just um just did a contact page did a little quick contact page but most of the functionality it's um it took a lot it took a while um I think we are complete I am about to go go through the uh project and see what we missed and I'll be right back and see if we missed anything all right so we're going to do a few changes because I don't know if you guys notice but for the contact page and um for the product page I believe we did sections so just uh make things more semantic we're going to switch these divs here want switch this to section and same for our top products I'm going to switch this part to section uh so we don't need to do it in products cart uh products we already did it new products to switch this to section nav bar we got nav for it so that's good map um I think we could keep map like that info let's do section hero uh we could do section footer I'm not sure if we did footer hopefully we did we didn't wow let's change this to footer all right and banner we already did all right so that's cool and let's go ahead and check our terminal see if we got an error so we are getting those errors for the key prop we got to find out where we did that I know we did it inside the nav bar so let's head over to our nav bar wait we get in a all right that'll go away it's just my computer going slow all right now bar so wherever we map do the stuff so what we're going to do is just do comma uh index like that and then we can just do key index like that give that a save and then believe we did a map down here do index and then on a link key index data Save Right same here index key index and last but not least index and give this a key of index all right so see if we all right so this looks like we missed one cuz it compiled right there so we missed one somewhere let's see if we can find it we got it there we got it there all right so it seems like this page is good let's see let's think about what where we map through our component so we know we did it inside our products card I believe I'm not mistaken Aken maybe not products so we didn't do it here top products we did so let's see so yep we got one right here so we going to do products and here we can actually do we can actually just do key product. ID give that a save and now let's see a compile and hopefully no errors okay we missed another one somewhere all right uh so that's that one uh let's see na bar map obviously not hero info footer maybe it was the footer all right so I put ID here let's change this to index and then just do index even though it still should work all right maybe our page okay so I think I found it's inside of our new products uh so we're going to do comma index and then actually we don't even need to do that we can just do key product. ID give that a save and compiled no errors Perfect all right uh I think that is it guys let's take a look at some of the features inside of our hero section we have this search form where we can search for a specific job we can search by job title we can search by job location and we can also search by company name when we find the job that we're interested in we can click on it and it takes us to that specific job page using nextjs Dynamic routing on this page you can see the job description and other job details back on the homepage right underneath our job listings we got our sponsor section we got our about section we got a contact Section with a nice contact form and we we also got our footer if you noticed in the na bar we got this post a job button if we click on it it takes us to the job posting page where a user can post a job we use react hook forms to manage our form State and validation if we try to submit an empty form we get a bunch of Errors so let's actually fill this form out do software engineer for a job title do Raleigh NC for our location do Apple for our company name and for our salary and do 70,000 and for our image I'm going upload the Apple icon and we'll be using Edge store to manage all of our images employment type and do full time and just do test for our description click on submit and if we head back to the homepage our job should be listed there now so let's actually get started on this project all right so I got a fresh project open here so let's go ahead and create our next app so inside the terminal we're going to type in MPX create next app at latest and I'm going to do a DOT after mine because I want mine created in the folder that I'm currently in and we will be using typescript ES lint no Tailwind yes Source directory no app router yes import Alias this is optional you don't have to to use it if you don't want but I'm going to use it all right so once it's finished I say we go ahead and clean up all of our files and start with our folder structures and then um we can start with our nav bar so inside of the app we're going to get rid of Fon uh inside the global CSS let me close out of this we're going to get rid of all of this here all right and inside of layout uh we're going to come back to this we're going to install a font but let's head over to our page and we're going to select all delete and we could do [Music] RF change this to home I'm going to change this to home as well all right um public we can get rid of this these two svgs and I believe that's it um yeah so that's good let's hit head over to our layout and we're not going to be using enter font uh let's actually start up our server as well just so that way we can see the changes so mpm runev give this page a refresh and I'm just going to inside of the page I'm just going to maybe return a div with an H1 it says hello world all right Perfect all right so inide of the layout uh instead of enter we're going to import oh scared me for a second I'm like where are the Imports all right so um we're going to change this to railway just the font that really grew me lately I've used it inside of my um e-commerce site that I just built all right so railway from next font Google so we got to change this to railway as well and we're going to change this to railway and we got to import the weights as well we're going to import so after this um Latin we going to do a comma make some space there and just put the weights in so we're going to do weight 200 3 4 5 6 seven not eight we're going to do nine all right and for the metadata you can just put um job posting site or something or actually the site name is called workery workify and for the description we could just do a job board or something all right probably want to be more descriptive than that but all right so for the um inside of the body we're going to change this to railway and give that a save and we should see our font perfect looks so beautiful all right so that is it for our layout for now um our page is good so what I say now is inside of the description there's a GitHub gist and I want to just download all of our images and we're going to put them inside this public folder but before we do that actually let's create another folder on our inside of our root and it's going to be called constants all right and in here we're going to make a file it's going to be called index.ts and this basically just going to be our nav links cuz we're going to use our nav links in our mobile menu our nav bar our desktop menu and also our footer so just this just easy way so that way we can map through it so it's just going to be um this is going to be inside of the description as well or you guys can pause the video and just copy this over it's not too much just um nav links we got our name we got our route all right so that's that and now I just say we go ahead and download our images and once we download our images we can start our nav bar so let's go ahead and do that now all right so hopefully you guys downloaded the images not sure if I told you guys but it's going to be a Google Drive inside of the description with all of the images or you can just head over to the GitHub repository and just download each one I'll find that easier so we got our air Airbnb logo we got Capital One uh we got our little contact Section um uh image there a Discord Dropbox we got our hero background uh our signature and we also got a slack logo so these are all the images that we'll be using on this website so let's close out of this and now inside of our app actually outside of our app inside of our rout we're going to create a components folder and we're going to create two compon two folders inside of this components folder we're going to create one it's going to be call shareed and then another folder is going to be called UI all right so our UI is going to hold our buttons and our inputs and our share is going to hold our nav bars and Footers and stuff like that so let's go ahead and create our nav bar component inside of shared and do navb bar. TSX all right and let's go and Export it cuz we're going to import this inside of our layout so head back over to our layout and right over top of our children and do Navar right and we should see it nice all right so before we actually start our nav bar uh I want to go ahead and I'm going to open up a new terminal in here so that way we don't close out our server click on the plus and I want to install a package I'm going to install react icon so I'm going to do a mpmi react Das icons right perfect let me just make sure that installed head over to my package lock Json and where is it oh there it goes react icons Perfect all right so let's go ahead and start our naar so first thing we're going to do is we're going to make this a client component you use client and we're going to import a few things we're going to import link from next make some space here and we're going to import our nav links from our constants folder uh we're going to import uh some react icons going copy these over so these two are fi menu so that's basically our hamburger menu and MD close which is going to be like the X icon that we're going to use to close out our mobile menu and then we're going to also import one more it's going to to be called MD ads click and this is for our logo little logo icon that we make and we also going to import button from our UI but we didn't create this yet so actually instead of our UI let's create a button. TSX and let's export it and what we can do let's just go ahead and just return a button let's go return button and it's just going to have our children in here children well children raw and then we got to send it over our prop so we going to do children here we're going to come back and style this up and fix all the typescript errors but for now let's just keep it like this and that way we can import it in here and we can use that all right so let's go ahead and set some State now we're going to do a const open mobile menu and then I set open mobile menu and that's going to equal use State false I don't think we imported use state do we so it automatically did all right and let's create our um mobile menu Handler function so we're just going to do a con handle mobile uh actually handle open mobile menu tried to be very descriptive and that's going to equal an arrow function it's going to return just set open mobile menu and it's going to toggle our open mobile menu really simple we do this every single time we do a project all right and let's go and write some jsx and start styling this thing up so we're going to have a nav and this is going to have a class name of py5 a BG of transparent position relative a top of zero a z of 10 and a width of four all right and here we're going to have another div and let me close out of this thing on my other monitor all right and this is going to have a class name of Max width 1450 pixels and then a width of 90% a MX of Auto Flex justify between and item Center okay make some space here and maybe I can actually bring this out just a little bit cuz we're going to be clicking back and forth like this so all right Perfect all right so now this is where our logo is going to go so we're going to have a link all right and we're using nextjs link tag so we got to do a hre and that's just going to lead us back home and inside this link we going have a div with a class name of flex item Center and a gap of one and then inside of this div we going have H1 with a class name of text black a font of semibold oh my bad semi bold uppercase and a text XL and this is just going to say workify workify let's take a look perfect nice all right so at the this H1 this is where we're going to have our MD ads react icons MD that's click self closing tag and we can give this a class name of text purple 600 that's going to be like our color for our website and then also we're going to make this a little bit bigger we're going to do a text 3 XL take a look hold on wait did I save it maybe refesh there it goes had to refresh all right perfect and just a heads up I'm very sick guys so um if I sound like really stuffy that's why um I don't know if we got C but the whole household is sick we're all sick my children they stay home from school and it's just it's like a war zone in here man it's crazy all right so after this after our link tag we have a ul and we have a class name of flex a gap of 16 item Center and on Max MD we're going to have hidden right and now we could just map through our nav links we have nav links map link taking a link and we're going to [Music] return a link from nextjs and hre for this is going to be our link. rout we got to also give this a key which can just be index and we're going to get error because inside of our link we got to do a comma we also got to take in an index as well index all right and inside of our link we going have a Li and this is going to be link. name Perfect all right nice all right so now we need our button our post a job button on that side so right after this UL we're going to have a div but the class name of Max MD it's going to be Flex justify Center item Center and then a gap of 10 right and inside of this div this is where we're going to render our Postal job button and also our open and close um icons as well our mobile menu icons so we're going to have our link this is going to be we're going to do our button first I don't know why computer's lagging behind there we go all right link and it's going to have a hre and hre for this one is going to be slash create so we didn't create this route yet right and we have our button and uh just going to take in our children so we can just do post a job like that let's take a look at that it's not styled up so it's going to look normal we're going to style it up here in a second so after our link we have a div and make sure we're still inside of this div here where our buttons at so we have another div in here and this div is going to have a class name of MD hidden uh um a text of 3XL cursor pointer and a text black balance text black all right and in here uh we actually we actually want to add a um on click on this div as well on click and it's going to be a handle open mobile menu it's our little function that we made at the top in here we're just going to run our so if it's open mobile menu it's going to show our MD close icon else it's going to show our fi menu icon all right we shouldn't see it here but if we go to inspect and we change the screen size now we see it but once we click it it goes to close open close open Perfect all right so after this div now we're going to render out our open mobile men our mobile menu um links so underneath this div so still inside of the div where our button is at we're going to render it R render this out conditionally so we're going to do open mobile menu do double and so if it's open mobile menu we're going to return a uo and this uo is going to have a long class name the class name of MD hidden a BG of purple 600 not pink purple 600 position absolute a top of 14 a right of five a px of four py of six text Center a text white rounded MD flex and we also going to do a have to scroll over some it's pretty long class name Flex I'm going do a flex c a gap of three and then a shadow MD all right let's take a quick look at this so once we click it we should see it as you go as you can see we see it there so inside of this uo this where we're going to render a map do our nav links again so we do we actually just copy over this here let's copy this over here and we're going to paste it down here right and there we go nice so once we close it perfect so the only thing we're missing is we're actually going to add a onclick on this link because once we click these links inside of our mobile menu we want them to close we don't want them we don't want this mobile menu to stay open so um go back to the menu expect all right perfect so what we're going to do is we're going to have a onclick on this link click and all we're going to do is we're going to just return our set open mobile menu to false right and with that once we click it closes nice all right so I believe that is our Navar that is it guys for our Navar um now it's time to work on our hero section which is the coolest section um I really like the background I put on this one and made it look really nice with the search bar so let's go ahead and do that now all right so inside of our components folder shared we're going to create two components the first one is going to be called search form TSX and we're not going to do anything with this yet we're just going to export it I want to add you know Prisma and our database first before we add functionality to our form so let's just export it and then we're going to create another one it's going to be called hero TSX all right let's export this as well and now let's head over to our app and page and we're going to import it here I'm going to do fragments so do fragments and then just put hero here that just so that way we can see it all right so that changes to Hero nice all right so let's start stying this hero section up so uh we're going to import our search form here but like I said it's just going to just say search form we're not going to stall it up yet or anything let's go to import that here and going have a div and it's going to have a ID of home and I have a class name of BG Dash URL and then we're going to do um quotes it's going to be our hero.png right a little confusing close that and close the brackets all right and now we need to give it a height we going do a height of screen position relative with a full BG of cover and let's just save that for now Perfect all right so as you can see it is acting very weird it's supposed to be on top of our naad bar so let's see what we did wrong here BG should BG transparent oh let's see than screen position relative maybe let's add a margin top of negative 70 pixels I think that's what I forgot perfect now it's on top of our nav bar I mean underneath our nav bar all right so inside of this div we have another div with a class name of flex Flex call height of four item Center justify Center a patent top of 82 pixels a gap of 20 a width of 90% MX of Auto and also a Max with of 1450 pixels all right and inside of this div we have another div not that word but another div with the class name of text 6xl a font of extra mode and a text block I don't know why I keep all right all right and first we're going to have our H1 um actually we messed up so change this div we're going to change this to our H1 and then we're just going to have another div wrapping this H1 another div wrapping it like that and this div is going to have a class name of text Center Flex Flex call and a gap three all right so this H1 is going to say Len the add some space like that let's take a look at that so L the right and I have a span in here with a class name of text purple 600 and a font of extra bod and this is going to say dream job all right take a look land the dream job I don't know why oh we forgot to add the space like that you got to add a space in between there perfect after this spin I'm going to do a comma space You Deserve nice all right and then after this H1 we're going to have another span and this is going to have a class name a font thin and this is just going to say 100,000 jobs listed here your dream job is waiting all right look nice all right so after to this div so we got our closing span closing div then right after that closing div we're going to have our search form search form right and like I said it's just going to say search form for now but this is where it's going to go so we got it in the spot where we want it all right nice so now let's go ahead and install Prisma get our database connected and all of that fun stuff all right so now it's time to set up our database with Prisma and Railway so head over over to Prisma doio and we're going to click on get started and we're going to do quick start scroll down we don't need to install typescript we already have that but we are going to use this command here install Prisma D Das save dasd so let me copy that head back over to my project and I'm going to paste that in here all right so once that's finished let's H back over to Prisma doio and we're going to copy this we're we won't be using SQ light but we can just change that once the uh schema gets created so we just going to paste that in here as well and it should create us a Prisma folder instead of our root with a schema. Prisma and like I said it's going to say SQ light but we're going to change this to postgress SQL all right let's go and close out of our terminal for now get rid of some of this stuff all right so I say we go ahead and do our schema since we're here it's going to be a really short schema um probably one of the shortest that no I think the shortest one was our to-do app that we made so we're going to do a model and it's going to be job [Music] posting model job posting and we got to take in the ID which is going to be a string and every time we um take in the ID we got to make sure that ID at default I'm going to do uyu ID like that give that a save and we also going to take in a name which is going to be a string description which is going to be a string as well uh our salary salary which is going to be a number but you can't just put number here you got to put float and we also got to whenever you use float you got to give it a default so by default is going to be zero uh location is going to be a string uh save that our author is going to be a string so that's going to be our company name image it's going to be a string put a question mark after that one and then Employment type employment type that's going to be a string as well I'm going to put a um question mark after that one that a save and we also going to do a create it at create it and that's going to be a date time we also got to give this a default as well which is going to be now give that a save so that right there is our schema um so we got our D it should have made us a perfect so it made us a EMV file as well whenever we use Prisma in it so here's where our database URL has to go and to get that URL we're going to head over to railway create an account um don't worry about the free trial it's just more than enough um so right now you you are on a should be on a trial once you sign in with your GitHub like I said it's more than enough I click on new project I'm going to do PR SQL and it should take a second to create and click on uh the database and as you can see we have no data we have no deployment so it says active go over to settings I believe we go here hold on uh maybe it's variables actually and we're want to copy our database URL I'm going to copy that and paste it in here I laughed a little bit because every time I do make one of these videos somebody always uses my um database URL and I go look at my database and it's just filled with just random stuff like use your own guys use your own please uh maybe I just might delete this one after this video uh all right so that is should be it so now what we can do is we got our database URL let's go back to our schema what we can do now is we going to open up our terminal we're going to run a command we're going to run MPX Prisma migrate I can spell migrate migrate Dev all right so what this is going to do is we should see our schema basically inside of our database now so let's give this a second and as you can see it says railway. net so everything is getting connected uh for the migration name you can put anything for this I'm just going to do test all right perfect so once it's complete we can head back over to our data base hold on let's close out of this and open it back up data hold on okay so we're unable to connect the database over public network can you connect using this command uh let's refresh and see what happens here we go perfect scare me for a second I'm like hold on I didn't have to do that before I used this multiple times all right so now we should see our schema that we made we got job posting and we got our ID we got our name description salary location author image employment type and created at Perfect all right so we're going to create a another folder inside of our root it's going to be called lib we're going to create a file we call Prisma TTS and here I'm just going to go and paste this in uh this is the normal thing to do um I do this in all my projects so you guys can go to the GitHub repository and just copy this over right quick and this just so that way we don't get that error saying that we call in Prisma too many times so uh so that's that and now I say we go ahead and set up Ed store which is going to be a wait to handle all of our file uploads whenever a user uploads an image to the job posting form um it just goes to here so uh head over to EDG st.dev and create an account uh should be already signed in there we go all right as you can see I got 172 files inside the jaw board um site that's already completed there was a lot of testing going on it was a lot of frustration so uh once you here you want to click on create a new project but before we do that actually let's head over to the dots cuz we got to set everything up install edge store and everything so let's start from the beginning let's s copy this code head over to our terminal and install edge store paste that in there and while let load in let's head over to number two and here we got to do our environment variables inside of ourv we'll do that in a second but let's just copy this over go over to ourv and we just going to paste this in there like that and then we'll just switch all this stuff out okay and now we need to make a API route so close out of that inside of our app so it's saying inside of our app we got to create a API folder then create another folder Ed store then create another folder Ed store with the spread operator and brackets and then do a route. TS so inside of our app we're going to do API and then inside of our API we're going to have another folder Edge store and then inside this folder another folder and do brackets dot dot dot it's store close brackets and then inside of that folder that's where we going to have our routes file and do a route .ts all right and we can just copy this over and paste it in there all right we can close out of that close out of our API folder keep the EMV open we're about to use that here in a second and now it's saying um create our context provider so that's going to be inside of our lib uh folder as well so inside of lib we're going to create EDG store TS do H store. TS and we're going to paste this in there and now it's saying we have to wrap our whole application up with Ed store provider me just save that and close out of that head over to our app layout so right over top of our children uh I think I might put it over our NAB bar as well do Edge store Edge store provider that's coming from our lib folder all right perfect make sure we don't get any errors just refresh uh let's go to Local Host 3000 all right perfect um I believe that is it you can use Edge store hook all right we'll do all of that ourselves all right perfect so now let's head back to our dashboard and create a new project a project limit reach are you kidding me that's hilarious man all right so what we need to do is create a new project and since I already got one I'm just going to probably I can find it where do I find my okay project key you go to Project keys and we're going to copy this over I'm already going to have 172 files on here H well I mean it's not connected with our database because what we're going to do is we're just using this to store our files but we're going to fetch our images from our uh Railway database using Prisma so I got 172 files in here so that that won't mean I'm going to have you know fetching 172 images it's going to be the images that's connected to that job so yeah we can go ahead and connect this so EMV and paste this in there all right so let's close out ourv uh we can close out our layout for now and close out of edge store so now I want to install two packages uh first one we're going to install is react hook form so NPI react Das hook- form and then the next one we're going to install is clsx mpmi clsx okay and what I want to do is just go ahead and knock out our UI components uh the style in uh the functionality for those um and then we'll work on our um creative job form and then our search sear form and all that other fun stuff so inside of our components let's do our button first because we can actually see that here CU we got our button right there and then we're going to do our input but we're not going to see that we're just going to just complete the style in and complete all the all of the props inside of it so that way it'll make our form a lot easier when we whenever we build it so um trying to think here so instead of our button start styling this up so we're going to make this a use client and we're going to import clsx and we also going to import use form status and that is coming from our react Dom all right so we are going to need um an interface going to do inter interace button props and type I'm going to actually copy these and paste them in here it's just for typescript not sure if you got whenever I do projects with typescript it's optional you guys don't have to do it with typescript if you don't want to but I highly recommend it so uh we do an interface for our button props uh so we taking in type which can be button submit or reset or undefined our children which is a react. react node on click and that's optional um outline and full width so these are just stylings um depending on if the Boolean I mean if outline is true then the styling is going to have that outline and then full width if it's true then it's going to be a full width button so uh Actually I don't even think we need outline anymore I think that was something that I ended up not using so we can just remove that for now all right so for our props I'm taking a type comma onclick and also full width okay perfect and let's go and add our props I mean our types to this we're going to do react FC and going be button props like that all right so that should get rid of those errors all right and what we're going to do we're going to do a cons pending that's going to equal use form status okay all right and it's going to return a button and we're going to do a type is going to be our type disabled it's going to be pendant pending so whenever our form is submitted we want that button to be disabled onclick it's going to be onclick and then our class name for this uh we're actually get rid of the quotes I'm going to do brackets clsx and we're going to do parenthesis make some space here so I'm going to do back ticks so the first style we going to do we're going to do BG purple 600 a px of four a py of 1 around it um MD a text white a height of full going add a transition and a duration of 300 add a hover effect hover of BG purple 600 sl75 all right as you can see we got it right there when we hover showing that that nice little hover effect and let's go and just add our children in here children all right perfect nice uh let's see and now what we want to do is so after this we're going add a comma and we're going to do if is full width so full width is true we just want the styling we want to add the styling of width full cuz we're going to need a full width button I believe we're use it inside of our contact Section and also our um post a job form perfect so that is our button component our re reusable button component so now let's do our input inside of our UI create another file we input. TSX okay that a save um I'm trying to think maybe I should add an input so let's go ahead over to our share search form and let's go ahead and add this input here uh let's do fragments just so that way we can see some of the styling that we're doing input UI like that all right so we we got it right there cuz this is a pretty large file this one there a lot of functionality in this input all right so we're going to do use client and I'm going to import clsx right make some space here and I'm going to import some stuff from react hook forms import filled errors with an S and also we're going to import use form register return those are both coming from react click form and then we also going to import change event and that's coming from react all right and now we're going to do our interface our input props that we're going to be taking in and paste that there so we're going to take in our label which is a string ID string type which is your string register which is um coming from react hook form also uh errors which is um coming from react hook form as well disable which is a Boolean No Label which is a Boolean so that's basically we're going to add this No Label whenever we don't want a label uh because we we don't want to label inside of our search form but we do want to label inside of our post a job form so that's why we adding this booly in there and is text area so this right here is we're going to change the way this input looks we're going to change it to a text area if this Boolean is true because we use a text area inside of our poster job and also inside of our contact form at the bottom of this page placeholder which is a string no border which is a Boolean onchange and then also our value which is a string so those are all the props that we're going to be taken in here so it's pretty long so now we actually got to receive these props so inside of these parenthesis we going to do brackets and we're just going to paste all of that in here we got our label ID um no border uh okay that's why we get in the air I was wondering why we didn't put it up here um type going to do react FC and it's going to be input props like that all right perfect so again label ID type register errors disabled this text area No Label placeholder value on change and no border so those are all the props we're going to be taking in this pretty long all right so um now let's go ahead and style this up a bit so we're going to to do a const actually I want that inside of that return it's going to be over top of this so we do a const input element input hold on sorry input element and that's going to equal to is text area all right so if this is text area we want to return our te a text area text area that and you can make this self closing tag save some space here that all right so our text area is going to take in ID which is going to be ID our Auto it's going to take autoc complete which is going to be our ID of rows is going to be six disabled it's going to equal to disabled placeholder it's going to equal to placeholder so these are all the props that we're just getting in we're just um making it equal to our props that we're getting it that we're getting in and then register this is coming from RE act hook form and now we need our class name so our class name is really long so we're going to do class name brackets clsx all right and make sure you do parenthesis back tick so first one's going to be block I going make some space here and do with full I'm going do round it MD a border zero uh a py of 1.5 a px of one a text Gray uh 900 a shadow MD and do a ring one a ring inset of rain gray 300 uh placeholder of text got to scroll over here really long class name sheesh oh my God a placeholder of text Gray 400 a focus ring uh actually Focus sorry focus and and this is going to be a rank two and then also Focus do a outline of purple 600 and then on small screens we want the text to be Smalling up want the text to be small and then on small and up screens we're going to do a leading of six and then a margin bottom of five okay woo I'm tired all right so all right so we're not returning nothing that's why that's we're getting an error here all right uh so that is our text area but as you can see we use clsx so we're going to actually do a comma after this and now we want some styling to be shown whenever there's a error from um react hook forms we do errors and do NN errors ID and then and in we want the styling to be ring rows 700 all right we also do another comma so when it's disabled we want the opacity to be 50 and also curs a default so you can't click on it all right so now we need our else so this is if text area is true now we need else uh actually hold on I believe it is down here okay this is weird so there okay there we go it was weird for a second so our else we're going to return a input input and the good thing is we don't got to cop we don't got to um write all this over because it's going to be damn near or same styling so I'm just going to paste this up and we'll just switch switch everything out and then we're going to paste that in there um so yeah take over text area can get rid of that take out of rows um so we'll just be using autocomplete and then we got type which is going to be type autocomplete which is ID disabled which is disabled uh we're going to do name which is going to be our ID and then we also going to do value which is going to be our value okay we got name name value disabled placeholder register and we also need on change on change that's going to equal on change on oh my God there we go okay perfect and this has the same styling um believe if not we can always just come back and fix it but only difference is so after this disabled we're going to do a no border so if it's no border do NN we want the ring to be zero Shadow none and also a margin bottom of five okay all right so we got our input element so this is basically you just using an aary operator if this is text area it's going to show a text area if it's not it's just going to show an input really simple and then in our return statement I have a div right and here we're going to render our label out conditionally so if it's No Label right we're going to do NN we going to return label label and we're going to do HTML 4 it's going to be for our ID and this is going to have a class name of block text small font medium a leading of six and a text grade of 900 and then a margin bottom of two all right and inside of this label we're just going to render out our label like that and I'm going to do a little symbol like that and we shouldn't see anything because our search form we're missing a lot of props so actually I'm just going to get rid of this and then whenever we do our form it's going to all make sense uh so we're just basically just doing our UI component for now so that way we don't have to rewrite all of these class names over and over and over again we make three types of forms on this website we got to post a job form we got a search form and then down below we got a contact form all right so our label there and uh you're probably wondering why we got No Label and and this is basically I call it short circu in method I believe there's an actual word for it but um basically basically if it's No Label um that's when that's when the second half is going to fire but if it is a label that's when it's just going to Short Circuit out and it don't even run um the second part of this um that statement so after the label uh we're going to run we're going to have a div and just going to render our input element like that all right cool so I'm going probably leave it at that um we'll come back and add our error messages underneath here all right so I think it's time to actually work on our Posta job functionality um so let's go ahead and close out everything and before we start that we're going to make another folder inside of our root it's going to called types and in here we're going to create a file and it's going to be called job types TS all right and we're just going to do a export interface job types uh because um we're going to do ID string do a name String image string everything string author string salary string location description and employment type all right cool so inside out of our app we're going to create another folder and we're going to do parentheses create all right and then inside of here we're going to have a folder it's going to be call create and inside of this folder we're going to create a file it's called page. TSX so if you remember we added an on a link to that post button there to take us to slash create so once we click this it should take us to slash create perfect and we sh page there all right and we're going to create a we're going to create two two more folders in here so inside of um parenthesis create we're going to create another folder and it's going to be called actions and then we're going to create another folder components right and inside of components we're going to create a file and it's going to be called create form oh create form. TSX and let's go and Export it all right perfect and now let's head back over to our create page and I start styling this up a bit so we're going to go ahead and import create form or create form and we're going to return a div with a class name Max with 1450 pixels a width of 90% a MX of Auto all right and inside of this div I have another div it's going to be class name with full mt5 and a text Center and we have a H1 and it's going to have a class name of MD text 6 XL text 4 XL a font of extra bold uppercase and a margin bottom of one and it's going to say post a I'm going to do a little space trick here space trick there and then we're going to have a span and it's going to have a class name name of teex Center and actually text purple sorry 600 text purple 600 and this is just going to say job let's take a look at that perfect post a job all right and underneath this span actually underneath this H1 have another span and this is going to have a class name of with full text Center and this is just going to say currently 100,000 users are actively looking for a job Perfect all right and so we got a span we got a div and then underneath that div where this is where our create form is going to go nice all right so before we actually work on our create form we're going to head over to actions I'm going to create a file in here and it's going to be called create job actions TSX all right and we're going to be using server actions so we're going to do use server and we're going to import revalidate path we're going to import Prisma for some reason I always got to type this out so Prisma and this is going to be coming from our at SL lib SL Prisma and then we also going to import field values uh I don't think we need fill values actually all right and we need to set our type so we're going to export type form data and our type is going to be name String description string location author salary image and employment type all string all right and we do export async function create going do create job and it's going to take it in our data which is going to be our form data all right and we're going to do in a wait Prisma do job posting. create create right and we got to give it the data so the data is going to be our name which is going to be our data do name let me just copy all of this over here paste it in here it'll be faster than me type in it all all right so we got our data our I don't know why we're getting error here object literal so yeah I think I see the issue so as you can see it says Sal the salary is uppercase it got to be lowercase so now we actually have to do a Let Me Clear this out we got to do a MPX Prisma migrate Dev and I should get rid of that error once um we complete all of this it's going to ask us to do a name again yeah my new migration just going do test and then just give this a second and hopefully that error clears and it does nice all right close out of the terminal uh last thing we got to do is revalidate the path revalidate and I'm going to do slash create that give that a save and that is our server action we'll be using let's close out of that and now we can start our create form all right so let's go and add use client and we're going to import a bunch of stuff um first we're going to import uh we're going to import use form we going to import create job comma type space form data like that and then we're going to add another comma actually we don't need a comma we going to do from and that's going to be coming from at slash app slash create slac SLC create jobs all right so we got to type in our form data all right let's go to import [Music] button for my UI also import input for my UI as well make some space here we're going to import use State and use effect and use effect and we're going to import use Edge store and I believe that is it well we're not finished but this is all of the Imports um so now let's go ahead and set some State here so first thing we're going to do so have you checked the docks of uh Edge store let's go to docks and hit over to maybe next or Ed store maybe uh configuration oh image here we go so it shows you how to do everything I use this drop um Drop Zone on my uh uh full stack blog website uh but we're not going to use that in this project so we're going to and set some State we're going to do a cons file and then a set file and it's going to equal use State it's going to be empty like that but we're going to do set a type here we're going to do file like that all right and then we're going to do a cons Edge store and that's going to equal use Edge store like that and right underneath this file we forgot one we got to do a cons image path and then a set image path and by default that's just going to be use State and empty quotes like that so we're going to save our image path from Ed store inside of this state here send this image path to our Prisma then fetch that and um um for our job component so now we need to do some things with uh react hook form hopefully this this part is not confusing so I don't think I showed you guys react hook form site so they actually got some really good docs this is my first time actually using react clip form and I ran into some issues at first and I was actually going to not use them but um I ended up fixing it so let's go to docks where are we at get started maybe but yeah they got some really really good docks here it just shows you how to do everything uh register Fields this what we'll be using this uh we'll be applying uh valid validation and we'll be handling errors as well and we got a bunch of stuff for typescript as well we'll be using some of this stuff so yeah just head over to the doc so all of this stuff that I'm about to do now is inside of the docs um so we do a const we're just basically grabbing everything from um use form uh so we're going to use register cons register I'm going to do set value handle submit submit comma uh we're going to do form State and in here it's going to be errors comma is submitting comma is dirty and then dirty fields all right dirt Fields all right and then we're going to do a comma and then we also going to take reset as well probably should put that up there all reset and this is going to equal [Music] use form and now we got to set our default values and do default values and in here is we we got our name which is going to be an empty string just going and copy all of this paste it in there so we got our author empty string description location image and employment type all right and now as you can see we got our type form data here we actually going to set our type on this use form we going do form data like that perfect nice all right and now we need to make our upload image Handler for Edge store so I'm going to do a cons upload image Handler that's going to be async right going to do if file I'm going to do a cons res that's going to equal a weight Ed store Dot public files. upload right and in here we're going to upload our file like that all right but we also want to set value set value of image to our resz so once you click a DOT here you should get access to some stuff the res. path. path order size. upload. URL so that's what we want so we're setting our value of image to res. URL so now that I think about it um I don't even think we need image path so this is the issue that I was having at first so whenever I was um saving the URL to image path it just it just wasn't working aside a database what it was what it would do is whenever you upload the form it would send the data before it saves the URL inside of this state so the workaround for that was I found this set value from react hook forms and what we're going to do is set the value of this input name so we're going to name the input image and we're going to set it to res. URL and with this um it worked so um I ended up doing it like this so I honestly think we don't even need this U image path anymore but let's just keep it for now um so now we're going to do a use effect and I'm going to return if file we just going to run our upload image Handler function and we're looking for any changes to file just in case they changed the image or anything they'll just upload it to our um to Edge store all right so now we need our onsubmit so we do a const onsubmit and that's going to equal handle submit async so that handle submit is coming from react hook forms and we're going to take in our data and we're going to return await create job and we're going to send it over our data and we then after that we want it to reset the form so we're going to run a reset like that all right but we shouldn't see anything cuz we didn't write any jsx so now let's actually write some jsx so get rid of this and and return a fragment like that and it's going to be a form action no action I have a onsubmit and that's going to equal our onsubmit function and it's also going to have a class name of margin top 10 right so in this form we going have another div class name of flex Flex call Smoke screens and up is going to be a gap 10 and then a gap five for extra small screens and then we have another div in here with the class name of grid small screens and up grid C two and then a gap of five all right so now we're going to do our first input so input self closing tag and we're going to send it over to our prop so we got ID is going to be our for this first one's going to be for name our label is going to be job title our errors is going to equal errors that's coming from react hook form up here our form state so it's coming from that and disabled it's coming from is submitting that's coming from react hook form as well and now we got to do our register register we're going to do double brackets dot dot dot register register and we got to give it a name so the name's going to to be name and we going to do comma and we can add a bunch of stuff here but we just going to add requ re ired um required and we want it to be true like that all right take a look at this nice we got our first input and it looks great nice shadow once you click you got the our um site color ring it looks nice perfect or outline all right so now I'm going to copy this input and I'm going to paste it again and we should see another one right next to it so this next one the ID is going to be location label is going to be location uh errors going to be errors disable is submitting register the name is going to be location and we also want to make this required as well okay perfect underneath this div here I'm going to have another div with a class last name of grid small screens and up grid Cal 2 and then a gap of five same thing as the top one and we can go ahead and paste another input and uh another input to paste two more okay so let's go ahead and change up this first one this one's going to be author and the label for this one it's going to be company name errors errors disabled is submitting register uh is going to be author and we also going to make that required okay so this next one is going to be a little bit tricky um because I don't know if you guys saw the demo but for salary we wanted to show a error if it's not a number so uh let's go and change the ID to salary label is going to just be salary errors errors disabled is submitting and register this is where it gets a little tricky so we're going to change this to salary and um we also going to do required true but after true add a comma add some space here we're going to add validate and what we're going to do is we're going to take in a value and we're going to return con par value that's going to equal par oh parse um float and it's going to be value like that okay return so we want to return is na n not a number parse value okay I I see what I did wrong here guys um I'm actually going to remove this validate and we're just going to rewrite it so we're going to do validate and we're going to take in our value and we're going to return brackets I put parentheses last time do cons pars value and that's going to equal parse float and it's going to take in our value but we got to do a do replace got replace and we're going to do slash comma slash g and then we're going to do comma space empty quotes like that all right so as you can see we're still getting in the air that's because we want this return statement to be inside of this so I'm going to empty that and then put it right there and another Closing one there and we forgot to close a bracket here actually I think we got to many parentheses there we go told you that was that one was little a bit tricky all right so again uh we're just basically checking to see if our value is a number if it if it's not um we're going to return this error must be a number all right perfect so that is our salary one and now underneath this div here we're going to have another div with the same class name grid small screens and up grid c 2 grid C two and then a gap of five all right and this next input is going to be a little bit different as well so we could just actually type this one out this going to be our file so input and a label for this one is going to say select company image like that and then the type for this one is going to be file and this is is going to have an on change take an event and we want it to return set file to our e. target. files and we want it to be the index of zero all right and we can add a question mark right there okay uh we are getting an error there ID is missing oh let's add ID to it ID of file like that all right so we got our file there nice perfect and now we need our employment type so underneath this input actually underneath this div uh actually underneath the input sorry have another div no class name I have a label um label is going to be or employment type like that and we're going to have a class name on here class name of block text M um actually the same exact class names as our label there text small we going to do a font medium El leading six that's why I was frozen for a second I'm like hold on aren these the same class name a text Gray of 900 and a margin bottom of two okay that's our label and then in here it's going to say employment type all right let's take a look just show right there nice and now we need our select so our select our name um we don't need a name we do need a ID which is going to be employment type and are we going to need a register let's make some space here so dot dot dot register and now we set our name is going to be employment type and we also want this to be required as well required which is true okay and uh this is going to have the same class names as our input so we can actually head over to our uh components UI input scroll up and copy this class name here copy all of this copy and then inside of our crate form the class name and we going to paste all that in there like that okay there we go but as you can see our height is not lining up with that and let's do a padding of three give that all right perfect so now it's line It lines up with that one all right nice so that's our select now we need to add our options for our select scroll back over this monitor sorry it's unorganized today huh like I said I'm sick I think we got Co guys I think my whole family got Co we've been sick for the last three days so I'm struggling here option and a value for this one value is going to be part time part Das time that and it's going to say part time part dash time actually I'm going to keep this like that part time all right and we can copy this two more times one two and just change up the stuff so this one's going to be full time and the next one's going to be temporary we're just probably just do temp like that all right let's take a look temp full time Perfect all right and now we need our text area so we got our select closing select we got a closing div and another closing div so right underneath this closing div here this where we're going to have our input and actually what we can do is copy one of these inputs up here so I'm going copy this one here this auor author and down here going paste it there and we're just going to add a Boolean to it is text area and it's going to be true as you can see now we got our text area that is the power of reusable components all right and we just got to change up the stuff there going to be description label is going to be description errors is going to be errors disable is submitting register is going to be description and we're also going to make it required nice all right so now we want a hidden input for our um server actions so right underneath this div here we're going have a input input like that it's a regular old input it's going to be hidden anyway I'm going to type hidden and we going have an ID is going to be image but we going have it register dot dot dot register and it's going to register IMG so that's that's the name of this input so whatever you put for this register that's going to be the name of this input so you guys remember we set the value up here of this image to our res. URL so that means that this hidden input is going to hold that value and that's what we want so what I'm going to do is actually copy I mean highlight this and I'm going to just comment this out cuz I actually want you guys to see this right so the hidden input is down here is right there all right so let's add our submit button it's going to just be button that it's going to say submit and let's go ahead add our type which is going to be submit all right we got our button there that input is going to be gone so we can just keep it like this for now so we can actually test this out now I'm really hoping this works um actually we didn't add our errors in there so once we submit this it's going to submit as oh it's showing okay I forgot we did add errors but we want it to show underneath here you know um job title must be uh filled out location is required company names require salary so you want that to show here show there so let's head under our input component and we got to add some stuff underneath this input element here so we going to do brackets errors and and errors ID right then we do and in parenthesis and you want it to return a span your class name of text red 600 and then a text small like that and in here this is where we're going to render our errors we're going to do errors ID and once you click that you should get access to message and then we're going to do NN parentheses do a fragment this way we're going to render out our errors ID that message we're going to have if it's not errors ID that message and in and do back ticks do dollar sign brackets label is required all right my bad I forgot to add the bracket here and I also forgot to add the bracket here I do apologize guys I'm really trying here to sick guys I'm sorry all right so as you can see we got okay now we got an extra bracket somewhere hold on okay I think it's right here so we don't need wait it's required yeah we don't need that bracket there all right so now as you can see we got job title is required location is required nice so as you can see it's showing like a little like I don't like how it's so far apart let's actually put it inside of this div here and let's see how that works how that looks maybe that won't make a difference actually see here margin bottom five see what happens when we take that off I think we might take that off guys take off that margin bottom five I don't think we need it because we're using Gap instead of our grid so let's actually take that off for now on um um text area we can remove the margin bottom as well and I just think that looks so much better when it's closer all right but here's the thing let's see how it looks on mobile oh it still looks good okay perfect cuz we got that Gap from the grave all right so I believe we are done our with our input um component let's go ahead and give rid of that we can get rid of our schema so uh let's test this out um for the job title I'm just going to do software engineer location righ andc company name going to be Apple Incorporated salary I'm just going to put a string for now this sdfds and then for the image I got this little Apple logo so as you can see once we add a image there our hidden input stores that image um URL so that's what that's for so let me let me actually get rid of that now type hidden just wanted to show you guys what it does so now we storing that URL inside of that hidden input employment type is going to be part-time and description I'm just going to do test so with that we should get an error for salary so yep it must be a number I'm just going to do uh 20,000 okay and submit as you can see we get the inputs they go disabled and now here is the Moment of Truth check our database and perfect it is there we got our ID we got a name we got our description we got our location author image which is one thing that I really I'm happy about because this is the one thing that was really um messing with me whenever I was creating this part-time created that and also the salary Perfect all right so there's a few changes that I want to make to this so as you can see we got our button right next to our description and we need that Gap I we need that uh margin bottom so what I'm thinking is we can either add the margin bottom to our button and just add a Boolean onto it so what we can do is probably do this we can do um uh margin top and then do Boolean and we can make this optional like that and then bring in the pop prop for margin top like that all right and now down here we can add a comma margin top and and and then we can do a margin top of five okay and that's going and add that prop to our button inside of our create form we going do margin top and let's see if that works perfect and let's try to submit and we still got the margin nice all right so that's one fix I wanted to do so you're probably wondering why we don't have our image required and our part-time required so we're going to add a a um a fallback image if they don't um upload an image cuz you know I don't know if you guys filed any job applications lately but I have I mean I'd apply for like probably like 300 jobs right now by now um and sometimes you know you see jobs that don't have a image they but they have you know the site's default image so we're going to um add one of those if they don't um upload an image and then Employment type uh we're not making that required either because by default it's part-time so we are getting a value from this either way if they don't choose uh but there is one thing that I wanted to do so for uh not that one down here for our select that's it I want to add a disabled and that's going to equal is submitting all right so we want to disable that and what we can do is actually let's copy all of this here I'm going get rid of it and up here actually we can just do it down here where we just at I'm going to do brackets cosx and I'm going to import it [Music] and and paste those class names back in there think I did it wrong hold on think I got to be back Texs paste those class names back in there I'm going do a comma and now I'm going to head back over to my input and I want to render this out disabled go back to Great form and ah forgot it's not going to do it because um it's not a [Music] Boolean T is or we could just probably just do is submitting right yeah there we go so if it is submitting the opacity be that that's for that one and uh for this one um we could just do where's this one at this one's here we could just do disabled is uh is submitting because um this is going to be disable either way because we're using the input component so we don't got to add all the extra stuff like we just did this one all right perfect so that is our form let's just test this out one more time I want to create another job and it's going to be with apple we're going to come back and add more jobs later I'm going to do a full stack actually I'm going to do something easy ui/ux designer location is going to be Albany New York company name is going to be Apple Inc salary is going to be 70,000 and for the image going to do apple and we're going to do full time this time and description just put test so let's see if everything gets disabled and it does nice and we should see it inside of our data base perfect nice so now U it's actually time to start working on seeing these jobs on the homepage so we're going to work on our search form first but before we do that we got to install a package we're going to install zustan because we need to manage some State mpmi Zan install that and close out all of this stuff for now close out and we're going to create a folder on our desktop I mean folder in our route that's going to be called store right and inside of this store we're going to create a file it's going to be called use job store. TS X all right so I'm just going to paste this in there it's not that much we just got to import create from Z stand we're going to import job types from our uh types folder and then we just got to Define some State we got a filter jobs um it's go to be job type it's going to be an array and then set filter jobs it's just going to take in uh jobs and then just return void and then down here is our actual store so we got use Job Store create let we add in our job store State there our types and then we got set so first by default our filter job is going to be an empty nay and then we're going to set filter jobs it's going to take in a job and then just going to set filter jobs to jobs really simple it's just basically like you state you know you got your filter jobs you got your set filter jobs and it's just setting filter jobs to jobs okay all right so that is our store so before we start render our search form we're going to head over to our next config cuz there's some stuff we have to do in here remove it strict mode so react strict mode I'm going to do false because I ran into a bunch of issues with this and do images and we do remote patterns it's going to be in here we're going to do protocol HTT https comma and we need our host name and all of our images is going to be coming from files. EDG store Ed st.dev okay Ed store. Dev okay perfect so that's that now it's time to work on our actual search form all right so the moment you all been waiting for it is time to start our search form so inside of oh we already created a component nice so let's get rid of actually just keep that input that import and we're going to make this a Ed client we going to import a few more things we import button from our UI and we're going to import change event and use State all right so change event use State that's both coming from react we're going to import our used Job Store and import we can add use effect to this use effect and last but not least our job type from our types folder all right so let's do our interface so interface search form props that's going to equal [Music] jobs job type all right it's going to be an array and then we need to set some initial State initial State and that's going to be title it's going to be in location it's going to be empty I was about to type empty and author is going to be empty all right that's our initial State and we're going to accept some props in here we didn't fetch our data yet but we will we will jobs and it's going to be search form props okay all right perfect so let's go ahead and set our values uh set our state I'm going to do cons State set State and that's going to equal use State and it's going to be our initial state that we set at the top there and then we're going to do a c value uh set value and that's going to equal use State default it's going to be empty quotes right and we do cons set filter jobs filter jobs and that is coming from our used Job Store like that all right so now we're going to do a use effect and I'm actually going to paste this in cuz it's pretty long but uh in the description that will will be a GitHub gist or you can head over to the GitHub repository and just copy this over I'm going to explain it so I'm going go ahead and paste it so once I explain it it'll just it'll be really simple so um basically what we're doing is how to use effect we're creating this function called filter and set jobs and in here we're just basic basically checking so the first one is this one the title condition and we're basically just checking to see if the job title matches the search title or if the search title is empty uh I believe um so if the search title is empty this second half wouldn't fire um and same with the location condition so it's basically the same thing just called so this is um title condition we got location condition we got company condition and then at the end we're just returning all three and then at the bottom here we're just setting filter jobs to fil uh set filter jobs to filter jobs and this is coming from our uh used Job Store uh using Zan and down here we're just calling our function that we just made and then for our dependency uh array we're just looking out for any changes within jobs our state and our set filter job so if any any of those changes that's when this use effect will fire okay so now I think it's time to create our on change going to do a function on change and this is taking in an event this is a change event which is a HTML input elements all right so in here basically uh whenever input fi value changes this function is going to be called so um in here what we're going to do we're going to do a set State set State we going to do parenthesis brackets and first thing we're going to do is spread out our state do a comma and then we're going to do brackets event. target. name and that's going to be event. Target that value all right so now we need to make our onsubmit so we're going to do a function on submit and that's going to also take in an event this is going to be a react. form event which is also a HTML form element so it won't be an input element right make a SP place there and in here we're just going to do an event dot well event. bubbles what is that prevent default all right perfect so now we can start styling up our form all right so we're going to have fragments we going to have a div with a class name of BG gray 50-50 vacity of 50 a shadow a rounded MD a pattern of five and a width of full right and then in here this where we're going to have our form and we can get rid of action we're going to add an onsubmit onsubmit and that's going to be our onsubmit function in here we have a div with a class name of grid grid grid cow 2 or actually grid cow 12 sorry 12 and then a gap of three right inside this div we have another div with the class name of call span 12 and on large screens and up it's going to be a call of span 3 okay all right and now we about to have our first input I have input I might just actually just copy this over going to be kind of the same thing as our inputs in our post the job form so uh we send it over to props so it's the in our input component and we got ID we got our type text No Label this time cuz we don't want any label Let me refresh and placeholder job title and we're adding it on change all right and right underneath this div here have another div with a class name of call span 12 and also lar screens up is going to be call span 3 right we're going to have another input here but this one's going to be cannot read filter okay that's we not sending over the props to um to hear yet so let's um I say we go ahead and do that now so we got to send over our props um so what we're going to do is I say we send it through our hero section and then so we're going to fetch trying to think so we'll fetch it from our homage the uh jobs and then we send it over to our hero and then our hero send it over to our search form all we got to do we're going to change this to a async and we got to import Prisma Prisma and like I said for some reason I always got to type this out it never picks it up lip SL Prisma and all all we got to do is do a cons jobs that's going to equal a weight Prisma do job posting and we just got to do find mini like that and we just got to do a little empty object like that and now what we can do is just send over our jobs to our hero section like that and inside of our hero section we take in these props jobs that then we send over our jobs to our search form Js s Perfect all right so we shouldn't get that error no more nice all right we're going to finish what we was doing so this next one's going to be next input is going to be location placeholder is going to be location type text No Label on change Perfect all right and now we're going to do another Di so I'm going to copy this if here just paste it down there have another input there like that and his next one is going to be author type's going to be text placeold is going to be company onchange onchange nice now we need our button so right underneath this div here we can actually just copy over this div and just remove this input and have our button here button component and it's going to say search jobs all right and we're going to do a type submit and we also going to do full width right perfect now we have our search um form so now we need to render our our jobs at the bottom of this so let's go ahead and do that now all right so before we start our jobs and our job cards we're going to head over to Hero I just want to fix this error right quick so here we're going to do an interface do hero props and we're going to do jobs it's going to be our job type it's coming from our types folder it's going to be an array so here we just got to do hero props and I should get rid of that error so inside of shared we're going to create two components we're going to create one it's going to be called jobs. TSX and then jobs cards. TSX that one and we're going to export this one all right perfect so now inside of our homepage we're going to render our jobs underneath our hero jobs going save that and now we should see jobs down there hiding down there all right so let's start Stelling this page up first we're going to make this a use client and we're going to import use state from react we're also going to import our used job store so that we can have access to our filter jobs and we're going to import jobs card job cart and we also going to import our button component from our UI folder all right so let's go ahead and grab our filter jobs from our uh zand store and do a cons filter jobs and that's going into equal use Job Store that and let's go and set some state do a cons visible jobs and set visible visible jobs that's going to be use State and default value you can change this I'm going to do eight so what we're doing is basically we're going to have a show more button at the bottom of our job component and whenever you click it it's going to render out um more jobs cuz we don't want all the jobs to be posted just be a long page so we're going to have some show we only going to have eight jobs showing at a time then when you click a button it's going to show four more all right and we can actually play around with this number if you want as well so we're going to do a cons jobs increment and we're just going to equal that to four um so like I said you can render out eight more um jobs if you want can run out two more if you want but I'm going to do four all right and now we're going to make a handle show more function this we're going to add this as an on click to our button do handle show more and what we're going to do we're going to set our visible jobs we're going to take in let me make some space here our previous visible job I'm just going to do preve and make some let me make this look a little bit better here sorry make this look a little bit better all right so we're taking our previous jobs and we're just going to return our creeve plus our job increment that simple all right all right so that's our handle show more and now let's go ahead and start styling this up a bit so we have a div with an ID of jobs and a class name of py10 and a with the full right and then in here we have another div with a class name of with full text Center margin bottom 10 text 2XL font extra Bode uppercase uh and then text purple 600 all right and it's going to be our section title which going to have H2 in here it's going to say job list in take a look at this all right perfect or jobl listing sorry all right so now we're going to render out we're going to actually we want to error message so if we have no jobs so whenever we search and um um no jobs is shown down here we want to message what we're going to do is right underneath this div have so of our filter jobs. length is less than one we're just going to return a div with a class name with full text Center and then inside this D we have H1 uh with the class name of text 2XL and it's just going to say no jobs found right and then we have a span with a class name of text small check back later all right uh okay then else we got to do our else that's why we get an error so else we're going to return a div with a class name of grid uh grid c 2 uh this grid c 2 is going to be on medium screens and up so I'm going do MD and on large screens and up we're going to do a grade cow 4 going do a gap of 10 a width of 90% % MX Auto and a Max width of 1,400 pixels 1,400 pixels all right and then in here we're going to go through our through our jobs now but we're going to first we got to slice it so we're going to do filter jobs. slice and we're starting at zero and we're going to end at visible job so it's at eight it's only going to show eight and we're going to do a map that map we're going to map do that we got our job and we're going to return our jobs card our job card that all right we can give this a key which is going to be our job. ID and then also we're going to send over our job which is just going to be job okay let that load up and let's see if we see anything we should see two jobs because we yeah we made two posts and once we write anything let's write some gibber now we get no jobs found nice and so I remember we did Apple so if I type Apple here which show so two and then if I do Raleigh and see we got one there cuz remember we did one with the location Raleigh all right nice so let's go ahead and do our filter um I mean our show more button it's right underneath this um that div there going to have another bracket so going new filter jobs our length so if it's greater than our visible job so if we have more than eight we're going to return a div with a class name of text Center margin top 10 and text small and it's going to be our button and it's going to say show more all right and we got to add on click which is going to be our handle show more so we shouldn't see this because our filter jobs is not greater than our visible job so we don't have more than eight yet but we will soon let's just go ahead and start styling up our cart all right so inside of our jobs card we're going to make this a use client we going to import link from next and we're going to import job type all right so we got to take in our props that we're getting from our jobs card we're going to take in job that's going to equal our jobs card props all right we didn't make that interface yet so we do interface jobs car props and we new job is going to be our job type right perfect and let's go ahead and start styling this up so going to do a link and we didn't do our Dynamic routes yet but we're just going to go ahead and just do a href and we're going to do back ticks slash job SL dollar sign bracket and it's going to be job. ID so we didn't make this route yet so whenever we click on our uh job card it's going to take us to that specific job page with more uh details I have a div with the class name of Border a pattern of three arounded MD Flex Flex call hover it's going to be BG purple 600 add a transition uh the transition the duration is going to be 700 do a cursor pointer even though we don't need the cursor pointer now cuz we got that link I think by default it should be cursor pointer and you have a hover it's going to be text white all right take a look at this and see if it shows yep nice all right so start adding our details in here we have a div with a class name of flex justify between by between and then have another div in here all right inside this div we're going to have a image tag we're going to do from next make sure we import that as well right and the source for this is going to be job. image height is going to be 40 our width is going to be 40 and then our alt it's going we're going to do brackets back TI dollar sign brackets and do job. author and then logo like that there's our logo Apple logos all right so right underneath this image tag we have a H2 with in here is going to be our job. author so our company name and this is going to have a class name of tech small Perfect all right underneath this div here we have a H2 and in here is going to be our job. salary all right so we don't want it to be like that we're going to do K slash year like that 100K a year 70k a year can't wait till I start making that type of money that's what I've been going hard for we're do a div do a class name of margin top three text XEL in here we're going have a H3 and we have a j we have our job. name and then underneath this H3 have have a P tag it's going to be our job. location all right and then underneath this P tag we have a spin and it's going to be our job. employment type a look perfect let's style up this span a bit do a class name of BG purple 600 inline block even though I don't think we need inline block believe span is already inline block right yeah um I'm going do a text EXs and do a px of three around it m d and then a text of white all right take a look at that perfect nice nice all right so that is it for our jobs card so what I say we do now is we take the timeout and we add more jobs so head over to post a job and we just you just add job so in the description there will be a folder or I might just add it whenever we actually um cuz I didn't add it inside of our public folder so whenever you downloaded this folder you should probably going to see um the job icons like this Apple icon have Microsoft going to have you know um uh Facebook to Twitter and stuff like that so I'm going to add those icons in that folder so yeah just go ahead and create some jobs post a job and just create one different ones different cities different job titles different salaries and meet me back here all right so I added nine jobs just so we can I can show how to show more button works so once you click it it renders out that last job um so yeah just try to follow this um if you guys want to add your own jobs you can I just did you know from Amazon Google Facebook Microsoft I just think this looks so much better uh and yeah everything looks good so now once we click on this we're going get a 404 because we didn't set up our uh Dynamic routes yet so let's go ahead and do that now so inside of the let me close out all this stuff inside of our app we're going to create a folder and it's going to be called job job and inside this folder we're going to create another folder we're going to do brackets ID like that and then inside of this folder this is where we're going to have our page. TSX right go and Export it all right and let going to import our button from our component and we're also going to import oh we didn't create that yet so we're going to make a utils um I'm going to do that here in a second actually let's do it now so we're going to create a um folder on our route it's going to be called utils so in here do utils in here we're going to create a file it's going to be called format date format dat. TS all right so I'm going to go ahead and paste this format date utils in here um you guys can head to the G repository and just paste this in here I got this off of stack Overflow and basically this is just going to format our date to show when our um job posting was created so like if it was created 3 days ago it's going to show 3 days ago um if it was uh created you know a week ago it's going to show you know how many days ago it was created 7 days ago of it's a week um so that's what we want here so so let's get rid of this and I'm also going to have a GitHub gist with that as well um and let me open this back up and now just going to import that here all right so let's do our interface and we're going to do we could just do interface uh Dynamic props going do pams and we're just taking in our ID which is going to be a string all right and before we even write anything inside of our page we're going to do a cons get data that's going to be async function and we're going to take in our ID which is a string and then we're going to return con R equals wait Fitch and we're going to fetch we're going to do back TI HTTP SL SL Local Host 3000 slash API slost slash um dollar sign ID so we didn't create this route yet um I mean we didn't create this API route yet but we will in a second all right so after this uh we're going to do a comma and then we're going to do the cash no store all right so now we're going to do if our res it's not okay we just going to throw an error so I'm going to do throw new error and just going to say failed all right so now we just need to return our res. Json return rz. Json like that perfect all right so I say we go ahead and create this API route all right so inside of this folder so inside of our API folder we're going to create another folder and then we're going to name this we're going do brackets job like that sure you close the brackets then inside this job folder going to create another folder we going do brackets ID and then inside this ID folder we have a route. TS right we got to import Prisma and we also going to import next response perfect let's go into our interface params I'm going to do ID string all right so let's go and do our get we're going to do export cons get that's going to be async take in a request which is going to be our next um response hold on I think it's supposed to be this is supposed to be next Quest sorry next request all right and then we also going to take in our prams and we got to do our types so we're going to do params is pams like that all right let's go ahead and [Music] return so we're going to do let's go and grab our ID from our cam so we're going to do cons ID and that's going to equal prams okay and now we're going to do a TR catch all right I'm actually just going to probably copy this try catch and just go over it okay so um I guess we do need next next response as well next response okay there we go all right so we're doing a TR cat so we trying we're doing cons post equals a weight Prisma that J posting and we're doing fine unique and we're just finding uh we're telling it where to find it so it's going to be by ID and we're just returning our next response json. stringify and giving it a status 200 and we're just catching the error uh we can console log error um and that's really about it uh so that is our route uh I think this looks good let's go and close out of that and let's go and finish up styling up this page actually grab our Pam so we're going to do a make this a async in here we're going to do pams that's going to be our Dynamic props and then we can grab that ID from our params kind of like how we did in our routes we going do ID just going equal pams and then we're going to do a cons job equals await get data and we're going to send it over that ID from our prams then we also going to do a cons format it format it posted date and that's going to equal format Post-it date and we want it to format our job. created at oh that's why format it I confused there for a second all right so now we can start styling this up let's go and click on one click on this one hopefully it takes us okay so we're getting an error all right so I think I see the error we did Local Host 300 so I'm going to save that and now hopefully this works perfect we got our page all right so we can start styling this up now do fragments and we're going to do a div with a class name of BG Das uro parentheses um quotes SL hero PNG in quote in parentheses in bracket all right so we shouldn't see this because we don't have a height yet do a height fit position relative with full VG cover margin top is going to be - 70 pixels and then a py of 28 all right perfect right in here we're going to have another div with a class name of flex Flex call a height of full item Center justify Center a pad in top of 82 pixels a gap of 20 width of 90% MX of Auto a Max width of 1450 pixels right perfect and inside this div we have a H1 inside this H1 we're going to have our job. name just take a look and make sure it's working perfect so we got software engineer and let's click on on uiux designer now we got uiux designer Perfect all right so let's give this H1 a class name of text purple 600 font bold and then a text 4 Exel nice all right so underneath this div here I have another div with a class name of of with 90% MX of Auto oh my God not Max Auto MX Auto and then a Max width of 1450 pixels also a py of 20 all right and then we have a div with a class name of grid medium screens in up we going to do a grid KY 12 and then we going do a grid KY one and then a gap of 30 pixels okay so we shouldn't see anything we don't have any content in here yet so inside this div we're going to have a a class name another div with the class name of large call span 4 medium screens and up we're going to do a call span six and here we have another div with a class name of Shadow arounded MD BG white sticky and then a top of 20 it's going to be our little sidebar over there I don't know if we'll be able to see it yet yeah we shouldn't see anything all right and then in here we have another div with a class name of padn six then we have our H5 that says job information let's take a look perfect and we're going to give a styling into this H5 it's going to have a class name of text large and a font of semi mode look nice at this after this H file we going to have a div with the class name of padn six a border top and then a border slate 100 all right take a look a nice little border right there looks nice all right and we have a UL inside this Ur we going have a Li and then inside of this uh this Ali we have a div with the P tag going to say employment employment type right like that all right and then underneath this P we going to have a span with a class name of font medium and in here so we want to have our job. employment to that deployment type I don't know why I'm not getting getting the auto complete okay all right so we can actually copy over this Li here copy this Li and we're going to paste it one [Music] two three four more times uh but for the class name for each one after the first one it's going to have a class name of margin top four all right take a look all right so now switch up everything in here so the next one's going to be company company I'm actually going to copy this class name and so we going to do job do author and then make sure we add the class name to this Li here the next one is going to be location and we do job. location and the next one is going to be salary job. salary all right and the last one is going to be our created date all right so we going do post it and it's going to we're just going to add format it posted date in here all right and let's take a look at this nice so we got today cuz it was posted today and for our salary we got to do drop. salary K slash year pick do nice all right so now we need our little description on this side so trying to I got to count the div so we got a div Li uo and we got four clo one two three four closing DS down so right here I have another div class name of LG I'm going to do a call span 8 and no medium screens and up going do a call span six all right in here we're going to have H5 with a class name of text LG and then the font of semi Bode and it have job description job description all right and then we have a P tag with a class name of margin top 4 and then a text slate 400 and in here is going to be our job. description all right perfect let's take a look all right it just says test uh for the newer ones that I added I put some laurum Tex so I'm just going to do this one here we got some laurum there all right and the cool thing is this little sidebar we did position sticky so if we want we can actually just so we can see it work just add job description a few times like that just so we can see the this works and then when as we scroll as you can see that sidebar stays there so that's like it's really cool sexy man all right um so after the P tag we're going to have another div and we have a button and it's going to say apply now and this button is not going to do anything but we will have a class name of margin top four all right Perfect all right so that is it I think we got our functionality I don't think we tested out our we got software so we type in a S Type in a o we get the software engineer um if I type in UI ux or UI slux you can see we got all the UI ux so that's working I type in Raleigh North Carolina we got all the ones from Raleigh I type in Google we got all the ones from Google and we got Apple we got Microsoft perfect so that's working fine all right so now it's time the functionality for our site is done so if you guys want to just quit here not quit but if you guys want to just stop here you can I know most of the people watch for the functionality not really the styling but we are going to finish up this homepage we're going to do our about section we got a sponsor section and we also have a contact Section and our footer so let's go ahead and do those things now all right so inside of our components we're inside of our shared we're going to create another component and this one's going to be called sponsors at TSX let's go to export it and let's head over to our app page and we're going to import it in here we're going to come back and fix that error sponsors like that okay um we should see it down here now Perfect all right so we're we're just going to import image from next and let's start styling this up I have a section section with a class name of py10 and we have a div with a class name of Max with 1450 pixels a width of 90% And then a MX of Auto right I have another div with a class name with full text Center in here we're going to have our H2 with a class name of text 3XL I'm going to do more then do our little space trick like that and then and still inside the H2 we going have a span with a class name name of text purple 600 um what do we do wrong here span with a class name of text purple 600 and then a font Bode and here it's going to say 10,000 companies take that all right let's take a look at this all right more than 10,000 companies and we're going to do a little space trick again that and do trust us like that perfect all right and now underneath this div have another div with a class name of flex justify between item Center margin top of five Flex wrap and then a gap of 10 and we just going to just show all of our little images I have an image our sponsor images so we're going to do a source and it's going to be um Flash air this one's going to be Airbnb PNG do alt Airbnb logo then a width is going to be 144 height is going to be 144 let's take a look perfect and now we just copy this few times so 1 2 3 3 4 1 2 3 four more times paste it and we just go and switch up everything so this next one is going to be Discord PNG and then we can just change this to Discord next one is going to be slack. PNG change this to slack logo uh this one's going to be Capital One C Capal one and this is going to be Capital One I think I spelled Capital Wrong by the way Capital One logo let's see oh I spelled it right all right and Dropbox drop box and then Dropbox Dropbox logo that a save and that section is complete so now let's go and do our about section so inside of shared going to create another folder I mean another file it's going to be called about. TSX and this section is going to be really really quick not that much in this one let's go and Export it and let's go and import it inside of our page about okay now we should see it down there all right so we are going to import image from next for our uh signature and return a div with a class name of py6 a BG of gray 50 slash 50 a margin top of 10 and we also want to give this an ID of about all right and then inside this div we have another div with a class name of width 90% MX of Auto and then our Max width of 1450 pixels all right we have our H2 with a class name of with full text Center margin bottom 10 text 2XL a font of extra Bode uppercase and then a text purpose 600 text 600 okay let's take a look at this oh we didn't write anything in our H2 we're just going to say about us like that all right nice and it's got that little nice gray background little nice little divider all right and inside this uh after this H2 we have another div with a class name margin top five with full Flex Flex call justify Center and then item Center then we have a P tag with a class name of leading loose my first time ever using that one and then the text Center all right and we just did some lurm here copy this over and paste it here some lurm take a look and now we need our signature right underneath here so we have an image and the source is going to be signature.png and we got to give it a width of 400 and then a height 400 and then the alt can be workify signature oh forgot to slash take a look nice Perfect all right so let's go and do our contact Section now all right so for inside of our shared we're going to create another component it's going to be called Contact at TSX and set of our page actually we got to export it first our page to be contact all right and uh where we at contact we're going to import input from my UI and then also button from our UI as well right and let's start stying this up have a div with a class name LGE screen it's going to be py 24 and on smaller screen py6 and it's also going to have an ID of contact all right we do a div we do our normal container we've been doing you guys probably caught of me saying this width of 90% MX of Auto and then also a Max width of 1450 pixels uh got the PX all right and then now I'm going to have a div in here with a class name of grid medium screens and up we have a grid call 12 then we going do a g c one item Center and then a gap of 30 pixels take that right and in here we going have so on the left side we have a div and this going to have a class name do a large screens and up it's going to do a call span six and on medium screens and up we're going to do a call spin oh now we'll just do do medium screens and up call span six right and we have our image but I'm not going to use the nextjs image because I was having issues with it so we should do a regular image tag and we're going to do a class name of height Auto and then a Max withd P all right and then the source it's going to be our contact that PNG and then alt is going to be contact image all right let's take a look nice next is going to be our form um so after this div here I have another div have a class name LG uh we going to do MD call span 6 and we do a BG of gray 50 BG gray 50 sl50 all right in here we have another div in this div we have another div with a class name of rounded MD a shadow pattern of six and a width of four this did we have H3 that says get in touch right save that and take a look all right um we're going to do this H3 is going to have a class name margin bottom six a text 2XL and a leading normal okay all right add to this H3 this is where our form's going to go and our form is going to have a class name of flex Flex call and a gap of five okay and now it's time to do our inputs trying to think so we are going to have so let's do a div in here with the class name of grid medium screens not we're going to do a grid K two and then a gap of five and this is where we're going to have two inputs we have one the first one's going to be have a ID of name a label of name and also a placeholder of your name name this form won't do anything just for styling purposes but if you want to add email JS to this you can it's really easy to do I did it in my last project you guys want to go check it out this one is [Music] email label is going to be email and placeholder is going to be your email okay all right and let me just copy this over so after this div here have another input it's going to be subject label subject placeholder subject and the next one is going to be text area so remember that is text area we're going to add that and the ID is going to be message placeholder message all right perfect it's looking really nice okay and now we just need our button which I'm just going to copy and paste over here so right underneath this text area have our button type submit send message Perfect all right uh that is our contact Section um now let's go ahead and do our footer all right so I created the footer component and I'm actually just going to copy and paste over the fter component you guys can head over to the GitHub repository to get it or the GitHub gist in the description uh I think the gist to be faster all you got to do is just click on GitHub gist and it's going to be all the files that that you need in there um that we needed to copy and paste over um I will go over it's not that it's not that much it's just basically footer and we got our links here you will uh we got all our links we got home we got jobs about contact and then down here we got UND Flex just spot Center item Center and these are just icons we got believe this one is the Twitter icon and we did an SVG uh we got this one here which is another icon we got this one here which is another icon so these are just social icons you you can use um react icons as well if you want and just take out these svgs so let's go ahead and inside of our page actually inide of our layout right underneath our children we have our footer right and let's take a look all right perfect and that is our footer nice all right um now we got to make sure we add something inside of our Global CSS so as you can see once we cck on this it kind of just jumps to to the location so we're going to do HTML scroll Behavior smooth right so now once we click on contact let's give it a refresh right quick let's click on jobs let's just go to Local Host 3000 all right now it worked soon as I did that all right so once we click on contact it should like nice smooth scrolling all right guys so a few changes so inside of our job types we're going to do add a created at and that's going to be a date employment type is going to be string or n salary is going to be a number or n and an image is going to be a Stringer n and with that we shouldn't have any more [Music] errors that should have got rid of that error on our homepage so we had an error here here and then the last thing we got to do is instead of our jobs card we're got to add our fallback image so instead of job. image inside of our source we're going to do a Turner operator and check if job image is there if it is we're going to return our job. image if it's not we're going to return this fallback image.png which is here and that's basically whenever we posted job uh I'm going to do data intern uh Raleigh NC company name is going to be I don't um I'm going to make up a name um space attires and then salary is going to be 56,000 a year so I'm not going to do a image because we didn't make this required so that's the whole reason that fallback image it's not required to put an image description is going to be test and then we're going to click on submit so now once we go to our now we got that fallback image there and show that they didn't upload an image so that's really it hopefully you guys enjoyed that we're going to start by adding authentication with clerk so let's go ahead and sign into our account with Google once we're signed in we now have access to take the weekly quiz we can view leaderboards we can also view our stats let's start by taking a quiz if you notice we have a timer on the right hand side once it counts down to zero and we don't have an answer chosen it'll just skip the question and goes to the next one so let's go ahead and run through these questions I'm just going to answer the top answer for each one and we're going to click finish and as you can see we got our results I score 40% we got our total questions we have the options to add more questions if we want we got our total score which we scored 20 correct answers I got four and wrong answers I got six so I got the options to restart the quiz if I want but I rather go ahead and check out the leader boards to see where I place on them right now I hold the number one spot got the nice little Crown next to my name but hopefully I keep acing e quizzes and keep this number one spot let me go ahead and check my stats out so I got a total of six 1,670 points uh correct answers I got 99 answers right but I got a total of 227 answers wrong so let's go ahead and get started on this full stack quiz app all right so let's go ahead and start our project with nextjs so inside of the terminal we're going to type in MPX create next app at latest and we will be using typescript yes lint no tawin yes Source directory no app router yes and import elas this is optional you don't have to use it if you don't want to but um I will be using it in this project so I'm going click yes and then click enter again all right so once that's completed let's go ahead and clean up everything and then we're actually going to start off with our Au authentication first so before we do that let's just clean up our file so the focon we can delete I like cleaning up everything nice clean project uh Global CSS we're going to remove all of this stuff here layout we're going to come back to that here in a second page we can select all and then export brand new page and we could change this to home and then change the export to home all right give that a save all right scrolling down inside of public we can delete these svgs so now we can head over to our layout and we're going to install our font and uh just work on our metadata and then we're going to do some stuff inside of our tail wi config before we start with authentication so inside of our layout uh we don't want this interent font we're actually going to use a font called Railway all right and so we got to change this to railway and we can change this to railway as well and then down here we could just change this to railway all right so we will get an error because we got to import the weights as well we're going to do comma and just paste the weight so we're going to do 200 three four 5 6 7 8 7 n not eight and then give that a save and then our metadata going to change the title to this to code quiz it's the name of our website and then for description um I'm just going to do I don't know we probably probably want to be more descriptive than that all right so we got our metadata and let's head over to our tail wi config and we're going to remove this background image we don't need that but we are going to extend our colors and the first color is going to be our primary and that code is 1 b 2 ffff all right and next is going to be our secondary F 5 f8 Fe right I don't know why that was lowercase but it's fine and then last but not least we going to have dark and it's going to be for our text our dark one is going to be 17 1 B2 give that a save and those are our colors all right so let's go ahead and start up our server I'm going do mpm runev and head over to our page our homepage and I'm just going to do a div and inside this div I'm going have a H1 and just going to say authenticate because we're about to start our authentication and let's give it a class name make sure tail when is working I'm going do text primary all right perfect and let's um just change this to like text 3XL all right so we can see it a little bit better all right and we got our font there that's the realway font all right so we're going to head over to clerk.com and if you don't have already have an account just make an account because this is what we're going to be using for our authentication so uh head over to your dashboard and clerk makes it so easy to add authentication to your project one of my favorites um and you want to click on create application and application name is going to be code quiz and you can actually choose which um signin options you want you don't have to use the same ones that I'm using uh but we won't be using email we're just going to be using Google and Facebook in this project but if you want you can add GitHub Microsoft it really doesn't matter it will still work um so but in this project we're just going to be using Google and Facebook I'm going to click on create application so now it's giving me a public key a publishable key and a secret key we're going to go ahead and copy that and we click on continue in docs and their documentation is so good uh it just walks you through everything and it's so easy um so let's go ahead and start this so let's actually make a EMV file EMV and we're going to make sure we add this to our get ignore I don't know if it's already in there all right and just go Ahad and paste our publishable key and our Clerk's secret key don't use mine please every time I create a project I go to my mongle DB database or something and it's just filled with like random stuff but I'm not going to make that mistake this time this this is going to get change before I upload this video all right um so now we got to install clerk so copy this open up our terminal I'm just going to open up a new so our server can stay online and go npm install clerk nextjs let that install we're going to move on to number two so we already did this and now we got to wrap our application with this clerk provider close out of that and and head over to our layout now we should have access to our clerk provider so import clerk provider and we're going to wrap our whole entire application with this all right so that's done step number four is to create a middleware TTS file so inside of the root we're going to do a file it's going to call middle wear. TS right and we could just copy this over and paste it in there we're actually going to come back to this a few things we got to put in here and um actually we could probably copy step number um 4 three so step number four but number three is probably the one that we should that we want so let's copy this one and we can actually get rid of all these comments clean it up a bit and we can actually get rid of the public routes and ignored routes all right so number four I mean number five we already started our project let's go and refresh it maybe will be directed to sign in now so perfect all right uh but as you can see it's not our website we get sent over to this random generated um URL but we don't want that we want it to be on our own website uh the signin page so to do that um let's see create custom sign up and sign in pages so yep here we go all right so let's actually copy number three over and we're going to head over to our. EMV I'm going to paste that in there so this is basically telling clerk that we want our signin page to be SL sign in we want our sign up the page to be SL sign up so these are our routes and then uh after we sign in it's going to send us back to home and then after um sign up it's going to send us back to home all right so if this works we should get a 404 let's see yep so we should get a 404 because we don't have these um routes yet inside of our app router so let's go and create those now this is Step number one so inside of our app it says that we have to create a folder called sign up it's going to do that sign Dash up and then inside that folder we're going to create another folder and this is going to be double brackets do dot dot sign Dash up and then close the double brackets like that right and now inside of that we're going to have our page page TSX and we can go and copy up copy over this and paste that in there that's our sign up page and um inside of our sign our sign in page is going to be the same exact thing but before we actually do that I kind of forgot something so I kind of want to organize this a bit better so inside of our app we're going to create another folder I'm going to do parenthesis do off it's where all our authentication stuff's going to go so we can put in this sign up form inside of at off perfect and now let's go and create the signin page and it's the same exact thing let start sign in all right so with that it should work now so let's let's see if this works uh maybe we did something wrong all right so I just had to refresh uh to get rid of that error so if you head over to just Local Host 3000 we just get directed to our signin and sign up Pages uh so with that you got authentication um and um we can style this page up a bit so let's head over to what page are we on are we on sign in okay so we're on sign in so what we're going to do is wrap this around in a div do a div and I zoomed in a bit more uh sign in all right and we can add a class name to this a class name of flex justify Center item Center height of screen and then a BG um we can actually do a BG of secondary let's see how that looks perfect and what we can do is copy everything and then head over to our sign up and just paste it in here but change sign up to sign I mean sign in to sign up all right so once we click sign up it should be this exact same thing all right so let's test this out I'm going to go and sign in with my Google and now we get authenticated and if we head over to our Clerk and hit on click over to users and as you can see we got our user perfect and we can do a lot with this we can ban user we can set a password just so much you can do with Clerk and it's it's like magic I'm not going to lie all right so now it's time to configure our Prisma and mongodb database so we're going to head over to Prisma and we're also going to head over to mongodb um go and sign up sign in with Google if you don't already have a mongodb account just go Ahad and create one right quick and I'm click on head back over to Prisma I'm going click on get started and to the left you should see um quick start all right and so we already got typescript installed so we don't need that we can skip down to here where it says npm install Prisma D- saave ddev so we want to copy that head back over to our project and paste that in there let that install let's go and copy this over the Prisma init data source provider we we're not we won't be using SQL we're going to be using mongodb so what we can do is actually erase that and do DB all right and this should generate us a Prisma folder with a schema already inside you can see all right let's go ahead and get rid of these comments I'm zoomed in a lot so it might look a little weird just want to make sure you guys can see all right all right so now we just got to do our schema now okay but before we do our schema let's head over to our mongodb database and you can see I already have a um quiz one already uh but I'm going to create a new one click on new project and a project name is going to be quiz dyt next um click on create project we need to do any of that stuff all right perfect and now it's going to say uh create actually we going head over to database click on database it's going to be build a database all right and we going to do a free one we can keep everything the same click on create let ask me to choose motorcycles all right so this is very important um make sure you just don't skip past this I did it a few times uh you want to change the password to something you're going to remember I'm just going to change it to my name Antonio and the username I'm just going to do admin like that and then click on create user and for the IP I'm just going to do 0.0.0.0 and I'm going to go and add entry and then finish and close all right congratulations on setting up your access rules right so now we can go ahead and click on connect and then we click on drivers so we don't have to install mongodb but we just need this URL right here copy that over and close head over to our EMV and as you can see Prisma already generated us some stuff inside of ourv file let's erase all of this stuff right and we don't need this mongodb URL we need this one all right and as you can see it says password we can rras that and we going to type in our password that we made up and right after this slash here uh the Slash and in like right in between the Slash and this uh question mark we're just going to type in quiz all right so let's head back over to our schema and I'm going to go and paste this in here I will go over it inside of the description there will be a GitHub gist with um the schema inside or you can head over to the GitHub repository and just copy it over it's not that much it's only two models um I am about to go over it though so we got our user model user and each user is going to have an ID uh they're going to have a username a email which is going to be unique profile picture which is going to be a string clerk user ID that's going to come from our clerk uh create at time update at time honestly we don't even use these so you probably don't even need to add them but just uh add it anyway uh quiz results um that's going to be quiz results it's going to be an array so it's going to be down here this model which uh each quiz result is going to have an ID uh just going to have a user with a relation to the user ID so basically we're just tying up this quer result to the user uh user ID is going to be a string quiz score it's going to be a number correct answer is going to be a number wrong answer is going to be a number um and created that perfect all right so we can head back over to our terminal and we can type in a command we're going to do npx Prisma DB push all right so hopefully everything works run and generate and we got the qu we got the uh check mark so let's go back to to our uh mongodb and click on database I'm going click on this cluster actually sorry and click on browse collections and as you can see we got our user and we got our quiz result Perfect all right so we can keep our mongodb database open because we're going to run some testing here in a few because we're about to create our first server action but before we do that we want to create a folder inside of our route it's going be called lib and inside here we're going to have a file called Prisma TTS and this is just a best practice to do just so that way we don't get error sign that we call in Prisma client too much I'm go and paste this in there I use this in all of my projects if you guys want to head over to the GitHub repository or the GitHub just in the description just copy this over right quick um so that's complete so we're going to create a file inside of our app off folder and it's going to be called actions and inside this action we're going to be Crea another file it's going to be call fetch users TS right perfect and since we're using server actions we're going to at the top of this page we're going to use use server and we're going to import that Prisma file that we just made for some reason I never get an autocomplete for it I got to type all this out we're going to do at slash lib SL Prisma and then we also going to import current user this is coming from our um clerk SL nextjs so let's do a export cons and we do fetch users and it's going to be async so we're going to do a try catch going do a try and the first thing we're going to do is basically just check if the user already exists inside of our database um so what we got to do here we're going to do a cons clerk user and that's going to be await current user all right and then we're going to do a let user that's going to be null all right then we're going to do user equals await Prisma so once we click thatt we should have access to a bunch of stuff so we're just going to be using our user model Prisma doine unique parentheses brackets so we got to tell it where to find it so we going to do where and we want it to be our clerk user ID so we got to tell it what the clerk you so basically we got to tell it what we want it to find and what we going to use to find it so we're going to use our clerk user dot so let you click dot you sh have access you see band you see birthday I didn't know birthday was up there email address first name and image URL and stuff like that we want ID and this is coming from this await Uh current user from clerk all right perfect so still inside of this try do if we don't get a user so basically if the user don't exist we're going to do let username that's going to equal our clerk user. username right and then we're going to do if they don't have a username we want the username to be clerk user. first name plus do a empty quotes there and we do plus our clerk user. last name all right so now it's time to actually create our user uh so what we're going to do is we're going to do a const new user and take in the clerk user ID and that's going to be our clerk user. ID let me see why it's not autocompleting oh it did okay all right we going do a comma and then we're going to take in our username comma and then our email that's going to be our clerk user Dot email address since it's an array going to take the first index which is zero and do. email address and then we're going to also take in our profile picture profile pick that's going to be clerk user. image URL okay perfect so now we got to tell Prisma to actually create this so after this we're going to do User it's going to equal a wait Prisma user. create and parentheses brackets just got to give it data and the data is going to be new user for new user let's do any like that we'll come back and fix that any for now it's not really best practice to use any all right uh so after this we got to do our we got to fetch the quiz results for the user so we going to do a cons quiz results that's going to equal a wait Prisma quiz results find mini scroll down some you got to tell it where so where is going to be our user ID which is going to be our user. ID all right perfect so after this we want to return our data going be our user it's going to be our user and also our quiz results which is going to be quiz results probably could have just put instead of quiz results quiz results probably could just put quiz results like that should work uh and now we need our catch as you can see we get in err so whenever you use try you got to make sure you use catch we have do catch and we can just catch an error and we can console do log the error I believe that is it for our fetch users we might have to come back in here and change up a few stuff but for now I believe that is it for our um server action to fetch our users all right so we can't just test this out right now uh we actually going to create a layout provider and we're going to wrap our whole entire application up with that uh but before we do that let's go ahead and create a components folder inside of our root and we're just going to create our nav bar and footer components we're not going to style them up yet we're just going to export them I'm going create a file it's going to be nav bar TSX just going to export them and then our footer because we're going to be using this inide of our layout provider all right perfect let's go Ahad and close out all of this stuff and inside of our root we're going to create another folder call providers and this is something that I just started doing um actually my first project doing this is doing a layout provider um so inside of this we're going to do layout provider TSX all right so we got to make this a use client and we're going to import use path name that's going to be coming from next navigation and then we also going to import our fetch users going to import use effect and also use state from react and let's go ahead and import our Navar and also our footer Perfect all right so we're going to have a function and this is going to be our layout provider like I said we're going to wrap our whole application up with this well not our whole we're just going to wrap our children up all right so it's going to take in our children like I just said children and we are going to get a typescript error to get rid of that just going to do parentheses and children is going to be a react do react node new cons path name that's going to equal use path name all right so we're going to do a cons is public route this is going to be brackets sign- in a comma sign- up these are basically the routes um that any user can use without being authenticated so that's basically our sign in and sign up pages so do do includes parenthesis path name split do parenthesis quotes do a slash and then we're going to take the first index so let me me just explain this a little bit so this is basically turning this sign in string into an array so we're doing a do split so this is basically turning it into this um let's turn it to an array split with empty quotes like that comma I believe it's like sign sign in like that so we'll turn into that and then we're just taking the first index because that's how an array works so we'll go zero 1 2 3 so we're taking this one hopefully that makes sense all right so that is our public route and now what we're going to do is make some space here we going to do a cons get Navar check if we got is public route then we're going to return all but else we're just going to return you don't even got to write an else we just going to return our na bar like that all right so if it's public route we just return an all um but else we're just going to return na bar so we can actually copy this and paste it one more time and we can just change this to get footer and just we're going to return footer all right and then we actually going to paste it again because now we're going to do get content this is going to return our children so inside of this div we're going to do actually we don't even need this we could just do fragments and it's going to return our children like that right so we got our get AB bar get footer and get content so now we're going to get our current you make a get um current user function so right down here do a cons get current user and another try catch we new try do a cons response it's going to equal a wait our fetch user all right and do some error handleing here so we going do if our response. error our response. eror we're just going to throw I don't know why throw a new air and that's going to be a response do error do message which I don't know why I'm not getting auto complete you know it's something wrong where you don't get those Auto completes let's see what's up all right so we got our try cons response I can just do any for this um and that's going to equal a wait fetch users and if our response. error okay perfect and throw a new air and that's go and do our catch do a catch and we just going to catch an error and then we could just console.log the error we going do console. log error this error handling really helps when you're building a project when it's already built and I already know all this stuff works but I mean it's good to have it cuzz I'm not going to lie I had to go through a lot of trial and error so this ER hand handling really helps um and then we can do a finally and there we could just do a return all right going to save that and hopefully that works and we're going to do a use effect inside this use effect we're going to check if it's not is public public route so if it's not we're going to do our get current user function and whenever you're using use effect you got to make sure you use a dependency array we only want this to run when the component mounts okay all right so now it's time to do our return statement return return a div with a class name of flex Flex call justify between a Min height of screen and then also a BG of secondary okay and in here we're just going to run our three functions it's going to be our get Navar like that then we're going to run our G content and then also our G footer like that all right perfect and we also need to export this I'm going do export default layout provider okay so with that all we have to do is wrap our children up inside of our layout and we can actually test this out hope hopefully this works uh where are we at um I'm lost here always get lost there we go layout all right so let's go and wrap our children up with this layout provider give that a [Music] save and we got our nabar we got the iated we also got footer it's not getting the Styles though hold on maybe we need to add a Min height on our body instead of our layout maybe as well so to do that what we can do is um we can wrap this up with brackets again like that put a dollar sign I actually um here do back T back tick dollar sign there and then now we can write some extra class names do a m height of screen all right all right so let's just ignore that for now let's test and see if this works let's see maybe our user yep it does cuz the component mount it and we got our user here so r that use effect so we didn't even need to sign out and sign back in I was about to head over to Clerk and delete the user so that way we can sign out because we don't have any actually we can sign out believe we can just go to um Local Host at 3000 sign out but we don't need to do that because we got our user here we don't have any quiz results because we didn't take the quiz yet so yeah we got our ID we got our user name uh we got our email profile pick which is image. Clerk and I'm glad that that showed up because we actually have to do something inside of our next config us to get access to that profile picture um so there's a few things we got to do so first thing I like doing is react strict mode false this um and we're going to do images inside here we're going to do remote patterns brackets and then we need a protocol which is going to be https and then we also need our host name which is going to be image. clerk.com all right so way we can have access to our images we can close out of that now and Perfect all right I noticed that I was zoomed out a bit on the mongod DB so was kind of hard to see but zoomed in a bit uh so now I think it's time to actually start our Navar and I know why it's like this because we don't have any width set for our um none of our components that's why it's lined up like this so inide of our na bar let's start off with this one uh we're going to make some imports here let's see all right so open up your terminal and we're going to install react icons mpmi react Das icons right let that install and we're going to make some imports first we're going to make this a use client and then we're going to import user button that's going to be coming from clerk nextjs going to import link from n and then we going to also import MD quiz and that's coming from react icons slmd all right make some space here and last but not least we're going to import user menu um user menu oh we didn't create that yet the user menu I was confused for a second so yeah we're going to create a user menu let's actually create that right quick um set of components do user menu. TSX going to export it head back over to our nav bar and let's go ahead and import it here Perfect all right so let's go and start styling this thing up so first going to have a div with a class name of patent top five and then inside this div we're going have another div with a class name of Max width 1,500 pixels MX of Auto a with of 90% Flex justify between item Center and then a border bottom border B and then a patent five right let's take a look should be able to see something there uh probably got to give it a refresh because I believe once we mess with our next config it restarts our server we got to give this a second to reload all right perfect we don't see anything there because we don't have any content in there yet so I have a div and this div is not going to have any class name but it's going to hold our logo so we have a link don't know why I didn't all right so we're using link from next JF so we need to give it a hre hre is just going to lead us back to to home and this link is going to have a class name of flex Gap one item Center inside here we're going to have our H1 the class name of text 2XL dark and then a font mode all right and it's going to say code quiz is take a look at that right quick all right perfect okay so yeah it's really not that Flex cow really not working going have to go back and look at that all right so for now inside of the layout provider let's actually just get rid of flex Le call and justify between uh just so that way we can start stying this up once everything finished we will we'll come back and figure that out um maybe we don't need it to be honest so let's head back over to our nav bar finish stying this up so at our H1 we going to have our react icon which is MD quiz and we're going to give this a class name of text primary and also a text 2XL as well let's take a quick look at this this a refresh Perfect all right so just to save some space in our code we can remove text to Excel or MD quiz and remove text 2 XL for this H1 and we just add it here on our link class like that give that a save and it should shouldn't change all right perfect so after this div here we're going to have div this is going to have have a class name of MD block by default is going to be hidden justify Center we're going to do a text no wrap and then item Center um I actually don't know why we did that cuz we're Now using Flex for that we could probably remove that and we have a span it's going to have a class name of BG primary PX of five py of 1 round it MD and then a text white and inside the span we're going to do today's today's category category is Javascript like that let's take a look at that right quick all right perfect so we can actually remove this item Center keep the text no rrap uh justify Center keep the hidden and the block don't think we need any of those all right perfect we got that and now make some space this is where our user button and our user menu is going to go so going to do a div class name of flex item Center a gap of three and then adjustify in okay that's going to be our user menu and also our user button right take a look so we should just see user menu and then our user button because we don't have any styles for it but with clerk you get access to that's why I say it's like magic it just takes over your whole entire site so we got our div we got our user button and yeah I believe that is it for our Navar uh let's head over to our user menu right quick and we're going to style this up a bit and then import link from next going to import use State and then we also we're going to import a react icon I'm just going to copy this over save us a little bit of time right so CG menu grid zero that's coming from react icon slcg all right let going to set some State we're going to do open user menu and then also set open user menu it's going to equal use State my default is going to be false right and we're going to do some links here actually let's do our um use menu Handler so here going to do use menu Handler and in here we're just basically going to just set our open user menu to toggle our open user menu so basically it's going to toggle back and forth all right um don't know why I put brackets oh we forgot the arrow too oh man all right so now we got have our links we only going to have two links for our user menu it's going to be stats and leaderboards it's going to be an array I'm going to take in a name and our path which is going to be stats so then the next one going to be leaderboards and our path's going to be SL leaderboards all right so let going to write some GSX here so we're going to have a div and on this div be a few things we're going to do first we're going to have a class name of text XL margin top of one cursor pointer and also a padn of two and then we're going to have um two event listeners so we're going to have on Mouse enter on Mouse enter and this is basically going to set our open user menu to True okay and next we're going to have our on Mouse leave and this is going to set our open user menu to false all right so every time we click it's going be open false it's going to be true false true false true false okay all right so inside this div have a class name of relative in here we're going to have our CG menu grid zero take a quick look at that we should see like a little menu grid here perfect and underneath here we're going to render some stuff out conditionally so we do brackets so if it's open user menu do the n and so we're going to do the short circu in method we're going to render out a UL with a class name of absolute a BG of primary a zindex of 99 a top of of s you can play around with these numbers these are the best ones I found um that makes that centers it right underneath that um that menu grid uh then we're going to do on small screens we're going to do a left of 60 pixels and then on uh small U medium screens and up we're going to do a left of 80 pixels a pattern of three text white around it MD and then a text center right take a look we should see like a little blue thing there there's no content in it but as you can see every time we hover we get access to it okay all right so in here we're going to map through our links so we're going to do brackets do links map and take in our link can also take in our index that and we're going to return some jsx we're going to do parenthesis and for each link we're going to render out a link tag from nextjs and we got to give this a key which is going to be our index and then we also give it a hre which is going to be our link. path class name we're going to give it an on click and this is for mobile uh so whenever we click we want to set the open user menu to false we're going to do set open user menu to false cuz when you're on mobile that on Mouse enter on M leave kind of don't work uh you just click on it and then it opens up and it stays open so to close it click on the link and um it'll close it or you can click off of it and it should close it all right and then we have Li and this is going to have a class name of hover underline in here it's going to be our link. name with that we should have our links now and we got access to them perfect and if we click on them we'll get a 404 so we didn't create those routes yet all right so before we start our footer I think we should just go ahead and knock out our hero section cuz I'm tired of seeing this authenticated right there so uh inside of components we're going to create another file it's going to call hero. TSX and inside of our let go to export it since we here inside of our page get rid of this H1 can actually get rid of that and do fragments and then we're going to do hero all right so let's import link from nextjs and let's start stalling up our hero section so we're going to have a section and it's going to have a class name of relative with full a in height of 500 pixels sorry I thought I was getting a phone call for a second uh Flex item Center justify Center and text Center in here we're going to have another div or a div and it's going to be a class name of PX4 medium screens and up we're going to do a p X of 6 and we're actually going to use um actually we going to do a Max width of 1500 pixels in Max of Auto and um a width of 90% let's go ahead we're going to have another div in here and this div is going to have a class name of space Y 2 H1 that's going to have a class name of text for Excel a font of bode a tracking of Tighter and then we're going to do a small of text 5 XL uh medium screens and up I don't know why I say it's small small screens and up going to do a text five XEL on medium screens and not we're going to do a text 6 XL and then on large screen ring up we're going to do a text 7 XL and then we're going to do a text of dark okay let's take a look so we shouldn't see anything nothing's inside of our H1 yet do ready to take this week's quiz should be right there in a center Perfect all right so underneath this H1 we have a P tag and in here it's going to say get ready to AC it period and this is going to have a class name text Gray 600 let's take a look nice all right underneath this P tag actually underneath this div have another div and this is going to have a class name of just margin top six and inside this da we're going to have a link and this link is going to lead us to quiz so our actual quiz and this link we can actually make this happen this a class name do an inline of flex item Center justify center around it MD a BG a primary PX of 8 py of 3 text small font medium and then a text Gray 5 100 right believe that is maybe we got some more actually hold on I had to scroll over uh text Gray 50 sorry and then we're going to do a shadow and then then we're going to do Transition do a transition of colors and then we're going to hover to be primary we're going to give it a opacity of 80 see how 80 looks there probably change that and then inside of this link we're just going to just going to say um ready MF you guys don't know what MF stand for look it up all right so yeah when we hover as you can see uh maybe add a duration do a duration of 500 it there we go all right Perfect all right nice so that right there is our hero section so we can go down to our footer and we can knock this out right quick um pretty simple footer so going to return a footer with a class name of py10 and then we have a div inside this footer with a class name of Max width 1500 pixels MX of Auto width of 90% probably should have made a reusable class text Center and then we have a span in here and I'm just going to actually copy this over side this span it's just going to be copyright 2024 All rights preserved by code quiz.com and as you can see we see it there Perfect all right so let's see okay it seems to be uh so the only thing is the furter is all the way up here but we want it down here all right so I'm actually curious and I want to see if this is going to work so I'm going to make a style inside of the global CSS and I'm gonna try to add it to that layout and see if it works Flex column works on that um so I'm going to do at layer I'm going to try like this first I'm just do Flex or I'm just going to do Styles I guess and then the the name of this is just going to be I guess Flex call like that and then we just going to apply Flex call like that I just want to see if this works all right so let's head over to our layout provider and let's add this class so we got flex and now we got access to flex call like that I just want to see if this works oh it seems to be working but now we just got to do a justify but between and now we oh my God okay so that works right there all right so now it's time to add sanity IO uh but before we do that I want to close out of all of this stuff clean it up a bit have a nice first start and as you probably notice we got a new file here data. TS so um in the description uh inside of the GitHub gist or you can head over to get a repository I recommend um downloading this so that way you can just copy over the questions the answers and a correct answer um but we will be using sanity iio so we not going to even fetch from this data file we're going to be fetching our data from um sanity.io um so this is just here just so you can have a general idea of the type of questions we'll be using I got these from um chat gbt I just typed in uh 20 hard JavaScript questions or something like that and um it spit out all of this stuff so these are pretty hard I'm not going to lie some of these are pretty easy like this one it's pretty easy um yeah some of these are actually really easy uh but uh yeah so make sure you download this and let's go ahead and head over to sanity IO and create an account if you don't have one I already have an account and just click on manage and I'm going to do create new project it's going to get give you this command head over back to your project and paste that command in and it's going to ask a ton of questions all right so we're going to create a new project project name I'm just going to do quiz Das youube and um use the default data set I'm going to say yes and it's going to be creating data set and it's going to ask would you like to add configur configuration files yes typescript yes uh embedded sanity Studio yes app directory yes uh and then SL Studio that's going to be our um route so yes and clean project with no predefined schema and then yes for that question and it's going to take a while to install all right so it just finished and for some reason every time I install sanity it messes up my Tailwind config probably did the same thing for you guys so if you head down to Tailwind config as you can see the error is here all you got to do is um hover over it and just do quotes and then click save and that error should go away all right so we got sanity installed it made us a sanity folder with schema and uh EMV and if you look inside ourv file it also added some stuff in here our sanity project ID and our San sanity data uh data set all right and it also inside of our app it made a route so we got sanity Studio here so you don't want to touch anything in there all right so what we're going to do is inside of Sanity the sanity folder we're going to create a file and it's going to be called questions TTS all right um and here I'm actually just going to paste this in there export default and you got to give it a name you got to give it a title which is questions a type which is document and our Fields all right and we take in take a name and we take in a name which is question title which is question and the type is going to be string and then our answers is going to be an array because we get to choose you know which answer is correct so that's going to be type array and got to do of type array and they're all going to be string and then next one is correct answer title correct answer type is string all right so that is our question schema so we we can head over to schema and we can import that in here import questions and all we got to do is inside of types add questions like that right close out of that and close out of that and now we're going to head over to our project and now we can do we can do slash studio all right so once it loads as you can see we are getting error all we got to do is click on continue it's going to take us back to our s sanity IO settings now we got to do is add course origin and then it should reload and we should have access all right so we got to sign back in I signed in with my GitHub all right so once we're in as you can see we got our SK we got our questions here and we can create once we click this plus sign we should be able to create our questions I don't know why it's going so slow super slow all right so we got question there and you can see I still got some of the questions that I made before we got our answers which is going to be an array so we could keep adding as many as we want and we got our correct answer there so um what I intended this website to be is basically and that's the whole reason why I'm using sanity for this is um every single day or week as you can see I put today's is there uh every single day or week you know a new quiz will come with a different category so this week is Javascript uh so it shows you know today's category which is JavaScript for this entire week so that's going to stay JavaScript for the whole week and then you know next week it'll be something like CSS that way you can come in here and change up the questions really quickly with sanity Studio you don't have you don't even have to go open your vs code to change all the questions for that week and then um yeah so it's that is that easy so um I'm going to do one question and then off camera I'm just going to add the rest of them so head over to the data or if you guys want to come up with your own questions for now you can and just copy over this question paste that in there let's ask the question and then answer we got number we got string object undefined [Music] string object undefined and the correct answer is string all right once we do that we can click publish and we got our question published so off camera I'm going to go ahead and add the rest of these uh I believe I got more than 10 but I'm only going to add 10 here so he has a bunch to choose from 20 um so yeah I'm just going to add 10 and I'll meet you guys right back all right so finally finished I got 10 questions here so we can actually head back to our homepage and now we need to fetch these questions and we're going to send it over to our actual quiz that's why we're going to get and then we're going to get started on our actual quiz let's close out of that let's make a folder let me call it quiz and in here we're going to have our page at TSX give that a save and let's click on this button now and it should take us to quiz perfect so we got page there all right so in here we're just going to return our quiz component but we didn't create this quiz component yet we're about to all right so inside of components create another file name it quiz. TSX same thing I'm going to export it and import it here all right Perfect all right so to fetch data from um sanity we got to import our client uh it's going to be bracket client that probably probably got to manually import it so many clients there it's going to be coming from our sanity or at SL sanity SL lib SL client and we also going to import our fetch user server action right so outside of our page function so make sure you don't add this inside there we're going to go on top of that we going to do export cons Dynamic equals force dyamic right and then we're going to do async function get data into a const query why we I SP oh I spell function I was wondering I'm like hold on okay cons query and then we're going to do back Tis the little star symbol I can find it there we go brackets uncore type this is all inside of uh sanity iio docs by the way and then we got to call out our schema which is questions like that and we basically want to tell what we want to pull from this so we want to pull the question going to pull the answers and then we also want to pull correct it correct ansers all right um oh this backtick is not supposed to end right there supposed to end down here and now we're going to do a const data that's going to equal a weight client. Fetch and we're going to fetch the query and last but not least we're just going to return data right perfect so we got access to our questions answers and correct the answers now we're going to do cons questions equals a wait get data since we're using a weight we got to change this to async and then we also going to do cons user that's going to equal a wait fetch users because we want to fetch the user ID so let's go ahead and get that now we're going to do cons user ID is going to equal you would probably think we'll just do user. ID but we can do it like that we got to do user. data dot user do ID all right perfect and we want to send over these props to our quiz and do questions it's going to be questions and user ID is going to be user ID nice oh forgot the S there there we go all right so we will be getting an error because we we haven't received the props inside of our quiz app but we're going to go do that here in a second before we actually start stalling up our quiz we do have to make an important API route um so inside of app we're going to create a folder it's going to be called API and then in here we're going to create another folder it's going to be called quiz results and inside this folder this is where we're going to have our route. TS all right Perfect all right so I'm going to explain this rout I am going to paste it it's not that much because we do have a long file ahead of us this quiz component is going to be believe 200 300 lines of code it's going be pretty long it's a bunch of um features and stuff we got to add to that um so I'm going to paste this in here I am going to go over it's not too much if you want guys want to copy and paste um this file just head over to the GitHub repository or just the GitHub just it'll be quicker that way so we're just importing our next response uh basically these are just types next response next server and down here um we are basically um parsing the Json body of the request right here and then here we're just extracting that data from the body uh so we're using the destructor I can't say that word destructuring method as so we're taking user ID quiz score correct answers wrong answers and then um down here we're just basically um trying to find the the user uh from our database and uh make sure that we include the quiz results and now here's where all the magic happen so basically what we're doing here is if the user already exists and has quiz results we're just going to increment their quiz score their correct answers and their wrong answers with the score with those the data that we get from our body so for example if I already took a quiz I want to say let's say I took a quiz last week and um I scored 100 on it that was my first quiz I had 100 points total and I take one this week and I scored 30 on it that this function here basically will make that score be 130 instead of having two separate scores just increments I've really trying to explain it the best I can but once you break it down it's really simple so just basically just checking to see if the user exists inside of our database and if they has quiz results if they do we just increment them from the data that we pulling from our body that we're going to send over uh via post request all right and then down here so if they don't have none of that we're actually just going to create them new data so we're going to create them new quiz results and that's what that's that's doing down here so really simple and we're just catching an error all right all right so now it's time to actually do our quiz component is a really long component really complex we got a timer in there uh we got a bunch of functionality and it's it's going to be it's going to be a long one uh but we're going to take it slow and have fun building this thing you know that's the most important part so first thing we're going to do is make this a client component and we're going to import use State and use react I say use react use effect uh use effect all right and then we also going to import um we're going to create another component right quick it's going to be called stat card at TSX and we're just going to export it for now go back over to our quiz and let's go and import it here so we are taking in some props here we're taking in our questions and we also taking in our user ID uh user ID all right so let's go ahead and do a interface for this so take care of our typescript error so interface quiz props that's going to be [Music] questions question which is a string we got answers which is a string but is an array of strings and then correct answer which is also a string and then um we don't we're not doing an image all right so this is an array so we can put an array after that and then we also Tak in our user ID which is a string or it can be undefined like that right go ahead and add our type here all right so I got rid of that error now it's time to set some State and this will be a bunch of States so we got const active question we got sit active question and by default that's going to be use state zero all right and then we got another one cons select answer and then set select answer and that's going to be default use State and that's going to be empty quotes right then we got cons checked then set checked that's going to equal you State default false right got a few more here told just going to be a long one it's going to be a long one let's relax and let's have some fun cons uh this one's going to be selected answer index and then set selected answer index and by default this is going to be um null we can't just put it like that because we will get some errors down low so we just going to do number or it can be null like that all right we got selected answer I mean select answer index and set select answer index then we got cons show results show results and then set show results that's going to equal use State the default false right and two more we got const result results and then set results default is going to be uh brackets so score by default is going to be zero uh correct answers answers by default is going to be zero and then wrong answers by default is going to be zero all right now two more we got cons time remaining and then set time remaining that's going to equal use State 25 we going to start off with 25 seconds you can actually do however many you want but we're going to do 25 seconds and then cons and do timer running and then set timer running that's going to equal use State and by default false all right so we got all our states set um perfect okay so now it's time to work on our timer CU this is what we working on first we're going to work on our I'm going to do time remaining so this should be just 25 so we should see it 25 I'm actually going to give it a class name of BG primary um then do a text of white um and do like a px of four rounded MD and then a py of one right all right Perfect all right so we get to see it there and then we can do uh time remaining and then seconds to answer all right all right so we about to work on this timer first so underneath all of our state we're going to do a use effect use effect all right so we're going to do let timer and this is a node js. timeout make sure you set that type because you will get some errors so we're going to check if the timer is running and time remaining is greater than zero going to do if the timer running and N time remaining is greater than zero and we're going to do to timer equals set time out all right and we're going to set our time remaining we're going to take in a previous time so we going do pre preve time and then we're just going to return our preve time minus1 so basically just decremented it every time taking in a previous minus one taking previous minus one so basically just going down all right and we want to set time out to run every 1 second okay 1,00 all right and then we need a LF else if all right time remaining is greater I mean it's equal to zero we're going to run this function called handle time up so we didn't create that handle time up function yet okay and then after this we're just going to return clear timeout of our timer okay and since we're using use effect we need dependency array so we only want to listen out for changes in our timer running State and then our time remaining okay so we going to do a cons start timer that's going to equal to Arrow function and here we're just going to do set time time CER running to True right so that's start timer I'm actually going to copy this and I'm going to paste it two more times we got start timer we got stop timer stop timer and it's just going to set timer running to false right and then last but not least we we got reset timer and this here this isn't going to set timer running to anything this is going to set our time remaining back to 25 okay hopefully all this is making sense it's really simple all right and now we're going to do a const handle time up so this is when the uh the time is up if that time hits zero we got to tell it what to do um right so here we're going to stop timer ah spelled it wrong this why stop timer reset timer okay we want to stop the timer want to reset the timer back and then we also going to run our next question function that we haven't made yet right let's refresh and I think once we refresh the timer should start going down maybe not um oh okay you want to know why because our timer running is currently false we never really set it to true so let's go and set that to true and now let's see refresh there we go well it started going down there we go 23 22 21 20 but we're going to set this back to false okay and let's refresh so it can go back to 25 let's work on our on select on answer selected function first cuz we're going to need that instead of our next question function so we're going to do on answer select it um so we do answer which is going to be string and then we also want to take in our index which going to be a number right uh we need our Arrow all right so first thing we're going to do we're going to set checked to True right and then we're going to set our answer set select the answer index to our index then we're going to run an if check if our answer is triple equals to correct answer this is supposed to be selected answer set selected sorry and then now here um set selected answer we're going to set selected answer to our answer and then we're just going to do else going to set select the answer to empty quotes all right so we can ignore this error here this correct answer ignore that for now so underneath this function there if we're going to do a cons next question in here first thing we're going to do is we're going to set selected in answer index to null and then we're going to set results going take in our previous and then we're going to return selected answer question mark So if it's selected answer going to take in do the spread operator Tak in our previous comma and then score we're going to take our preve do score + five all right so we going to add five every single time but that's only if they get it right and then correct answers I'm going to take the preve dot correct answers + one right all right perfect and then down here we got make sure we do our else or else we're just going to return do preve wrong answers I spell wrong answers wrong oh my God where we at wrong answers and that's going to take in and that's going to be our preve do wrong answers + one right okay perfect so we still get an error there that's fine all right so right after this still inside of our next question function we're going to check if our active question is not equals to our questions. length minus one if it is we're going to set our active question to our previous going to take in a prieve and then we're going to return preve + one okay all right um I think I messed up the state here this is what's really that's why I'm like keep pausing I keep messing up here set active question and active question now you guys see what I go through when I'm making these projects it's even worse um all right so then we need our else cuz we doing this if so else we're going to set show results to true and we also going to stop the timer we don't want that timer to be gone and now this where we're going to fetch our API route so we're going to fetch this is after the quiz is gone fetch SL API slash quiz results and after this we're going to do a comma brackets we got to give it a method which is post and we also got to do our hits which is going to be content Das type and that's going to be application. Json all right all right so now we need to do our body so our body is going to be [Music] Json stringify right and in here we're going to send over our user ID and we also going to send over our quiz score that's going to be our results result do score and then correct answers and last but not least our wrong answers going to be result do wrong answers so now we need to do some error handling we going to do a do thin Tak in a response and um do if our response uh do then I know we can do a do then there maybe see okay I had to get rid of that that's why I was getting error so if our response so we got to do it if it's not okay so response. okay uh we could just do a um I guess we could just throw a new error and we could just type whatever we want in here on um network isn't working fam all right uh and then down here we can just return our responsejson okay we going to set checked to false and we also want the timer to reset res set timer okay all right perfect um now we can start styling this thing up and yeah let's see this thing works hopefully it works okay so we can actually just scroll down a bit all right so first thing actually let's just cut this and then whenever it's time to use it I'll just paste it in there all right so we're going to have a diff this is going to have a class name of Min height 500 pixels have another div with a class name of Max with 1500 pixels MX of Auto with 90% uh Flex justify Center and py of 10 and then a flex call okay uh now we're going to render some stuff out conditionally so whenever the quiz is done we want that we want to show the results and that's the whole reason why we have this show results State here uh where is it show results there so we need to basically render some stuff I wonder why this isn't answer is correct answer we must be forgetting something hold on guys okay I see where we forgot something now it all makes sense and this is this is why I was pausing throughout the video I was a little confused so we forgot to destructure um some stuff out out out of our props that we're receiving so we forgot to take out the question the answers and also the correct answer and that's going to be coming from our questions with the index of active question okay uh forgot the comma okay there we go so now we shouldn't have any errors here Perfect all right so inside of this div if it's not show results so if the quiz isn't done yet we want to render out fragment div probably didn't need that fragment class name of flex justify between margin bottom of 10 item Center and inside this div we have another div with a class name of um BG primary um a text of white a px of four Around It MD and a py of one right inside this D we're going to have H2 and inside this H2 it's going to say question and it's going to be our active question + one let's take a look oh we don't have a else so for now let's just down here for the else we could just return all or we're going to come back and change that all right nice so we see our active question there okay so underneath this H2 we going to have a span and it's going to have slash brackets is going to be questions. l take a look so it should say one out of 10 because we only got 10 questions all right and I don't know why that is all the way over there like that so underneath this div we have another div maybe this will fix it and let's have a class name of BG primary actually this is going to be our same exact div as so that right there okay so this closing div here needs to come down here I believe that should fix it but this should I'm not sure why that is like that let's see what's going on here let's put this span inside of this H2 like that perfect all right nice okay so after this div here we G have another div and have H3 and this is going to have a class name of margin bottom five text 2 XL and a font of bold and in here is going to be our [Music] question take a look so that is our first question and then after this H3 we going to have a ul and this where we're going to map through our answers answers that map um make some space here be taking in an answer which is a string and then also our index which is a number and we're going to return some jsx so we're using parenthesis we're return to Li this Li is going to have a key of our index it's also going to have an on click which is going to set our on answer selected on answer selected let's going to actually we oh we're running an all answer selected function sorry and we're sending over our answer and also our index okay all right and we can also give this Li a class name of cursor pointer a margin bottom five py of three around the MD on Hover want the BG to be primary and then also hover want the text to be white all right okay all right so inside of this Li um actually we forgot one thing so for the class name we're actually going to render out conditionally so we can get rid of these quotes here and I'm going to do let's um highlight it do brackets and then highlight it again I'm going to do back ticks like that all right and so we got PX3 R text white let's do PX3 we forgot that all right and let's make some space here so now we're going to do dollar sign bracket and then down here we're going to do selected answer index so if it's equal to our index and and um the class name the BG is going to be primary BG um going to be primary and also our text going to be white so basically if we click it our BG is going to be primary and our text going to be right also if we hover so check this out we click it see that it stays that color click that okay so inside of this Li we're going to have a span and it's going to be our answer let's take a look perfect oh and we got our answers there all right so after this UL we want our button and this button is going to have the on click of our next question function and also we're going to disable this button so you won't be able to click next question if you don't have the answer selected we're going to disable this button every time the answer is not selected so if checked is not true and we also going to give this a class name of font Bode and now we're going to render out this button conditionally so if our active question is triple equals to our questions. length minus one we want the text to say finish else we just wanted to say next question next question as you can see is disabled because we don't have one checked but now once we click we can't click it perfect all right so we can actually test something out right quick I want to see if our quiz results is getting saved in the back end so let's go and just finish out this okay disappears let's hit over to our mongod DB and see if it saves and we don't got nothing all right I say we finished styling this up um few more stuff we have to do let's finish styling this up and then we'll take a look at why it's not saving in a backend okay so after our button here um our div so now we instead of null we're going to return our results so um for now we just going to put a div with a class name of text Center okay and then in here we're going have a H3 with a class name of text 2XL uppercase and margin bottom 10 and this is going to say results and I got like a little Emoji just going to copy and paste over all right so we should be at the results there okay so we got to work on our stat card uh we're taking in a title and also a value we got to find our types here so title is a string and value is also the value is going to be a string it can be a number and it also be undefined okay and then we're going to return a div with a class name of patn five around it MD BG primary text White text Center and then text 2XL and here we're going to have our H3 and this is going to have a class name of uppercase and text base and this is going to have our title all right and then underneath here we have a span and that's just going to hold our value okay all right so let's head back over to our quiz component underneath this H3 we have a div have a class name of grid on LG screens and up it's going to be grid c 3 my medium screens and up it's going to be grid c 2 and then gap of one I mean gap of 10 in here we're going to out some stat cards stat card right the first one title is going to be percentage and the value is going to be back ticks Bor sign brackets parenthesis our result do score slash 50 and we also going to times that by 100 so we got a zero percentage and we also going an air okay network isn't working okay so there's something going on uh with our function we must have forgot something so we got our percentage which I guess we got a zero we must have got everyone wrong let me just go back and make sure there's no way we just got a zero hold on and that's the whole reason why you always should error handle okay yes so we are we are getting all right so I've been trying to get this to work for a while now um not sure why however I just want to show you some of the changes that I made so I did some little bit more air handling trying to get this to work I don't know if you guys want to add this um as well so uh we did the that then we took in a response and then we um did the if check if our response is not okay we threw a error and then uh we return the response. Json then after that I did another dot then and I took in my data and then I console logged uh if the quiz results were successful then it just showed the data and then I did a catch do catch error uh catch um console log in the error error saving quiz results and then it showed the error and then down here uh we just set checked to false and reset the timer so with that I took the quiz and it saved into the data base right everything is Saving right but the bug that we're having is that it's not saving the quiz results um I'm not sure why it's not like it's just showing zero and showing that I've gotten every question wrong for some reason so I say we finished up the stat cards right quick and then we're going to try to figure out that error so this value is result. score um50 time 100 and then the little percent sign so we can actually copy this and what I'm going to do is actually probably copy the ones over here so we're going to have one two three four five uh five cards so this next one it's going to be we sending over total questions and also the question. length and then this next one's going to be I change this to results next one's going to be our total score and then the next one's going to be our total correct answers results. correct answers and then the next one is going to be wrong answers going to just change this to wrong and then change this to results dot oh man results do wrong answers all right let's give that a save so it's showing our total questions right showing our showing that we got every question wrong for some reason uh and also we also forgot to so if you notice let's head back over and start their quiz over so if you notice um our timer is not starting for some reason now so to fix that underneath our handle time up we're going to make a use effect um and do use effect and we're going to start timer on our start timer function we don't want it to keep running forever so we're going to return stop timer right so whenever the component um unmounts it's going to stop the timer okay so now the timer's going all right guys so it took me I want to say a few hours to figure this out so the issue that we was having is whenever we um completed a quiz it wasn't saving are correct answers it would just show zero for everything so um you guys would never believe what it was so if we head over to quiz page I just I had a s here right and it would just it's just supposed to be correct answer um yeah today's not my day I just recorded on to say an hour left of this project or maybe like 30 45 minutes and it just wasn't recording so uh yeah so I'm basically just backtracking of some stuff that I already did which sucks so um now once we complete a quiz now we have have a percentage we got our total score correct answers and wrong answers and all of this is getting tracked inside here head over to quiz results and then we got our total score we got uh correct answers and wrong answers all right so let's go back to our quiz page uh I believe we left off down here right after this so so we did a button and did a onclick here uh this on click this window. location. reload this basically just reloads the page and whenever we reload the page it just starts over the quiz that's that's the whole reason why that's there and we added a class name of margin top 10 font mode and uppercase and then inside this button it says for start quiz so those are only changes made on here uh actually it was one more change um we added a arrow for next question this little HTML entity you can just head over to Google and type in write Arrow HTML entity and this will pop up all right so that is it for our quiz so now it's time to work on our stat page and our leaderboard page and then will be completed so close out of this app we're going to create another folder it's going to be called leaderboards side here we're going to do a page. TSX export it and now we can actually H over to leaderboards now and we should see page there right so we're going to make a few Imports here um let's see leaderboard so we're going to import Prisma this is going to be coming from our at lib uh don't know why it's like that oh man I really need to go to sleep at SL lib SL Prisma and then we're going to import image that's going to be coming from next and then last but not least we're going to import fa Crown actually going to copy this paste that in there so what I might do is actually just copy over some of this code because I I said I just did this and I wasn't recording and you know um just copy just a little bit of it and just go over each line I think it'll be faster and much easier anyway so here we're just doing a cons users await Prisma that user that find mini and then we're including the quiz results so we're just grabbing all of our users inside of our database and as you can see we're getting an error because we got to make this a async function like that all right and now we're going to you do a users. sort we're going to do sort method and we're also going to use the reduce method so basically we going to sort the users by quiz score in a descending order um and AC c um I'm about to past it ACC stands for accumulator and Cur R Cur is the current value so that's what we doing here so we got users. sort and we just AB this can actually be anything we can do Antonio and Rogers and then it'll still work but um just AB um and then we do b. quiz results results. reduce and like I said we're taking in the accumulator the current value and we're doing accumulator plus our current quiz score all right and then same down here we're minusing it so like I said we're doing by descending so we're doing it from um top to bottom I guess yeah like um the highest to lowest that that's sounds better all right and now let's go and write some jsx I'm actually going to type this so we going to have a div I have a class name I'm going to do a Max width of, 1500 pixels to MX of Auto a width of 90% And then a py of 10 and here we're going to have a H1 with a class name of font bold margin bottom for text Center text 2XL and uppercase and in here is going to have leaderboards with a like trophy Emoji let's take a quick look U I wonder why it's oh got the dash for text 2 XL all right perfect and underneath this H1 have a o I know you guys like o never used that we're using it in this project users that map take in a user and also our index and we're going to return Li and we're going to give it a key of user ID also give it a class name but we're going to render this out conditionally so we going do brackets back tis py of4 then we're going to do dollar sign brackets and now we're going to check if the index is less than three we want the styling to be font bold else we just want nothing there so basically we're going to give the the top three users font mode for their uh usernames okay so inside this Li we're going to have a div with a class name a flex item Center gap of five and a width of four right and have another div class name of flex small screens and up and do Flex row Flex call Gap of one justify between with the full item center right you have another div in here with a class name of flex gap of Gap of three item Center uh item Center all right in here we're going to have another div I'm joking it's going to be a span this time don't worry span class name of text Exel and then a margin bottom of one right and we have render our index plus one let's take a look we only got two users in this Pro in this project uh the demo that I showed at the beginning of this video that had more users so that's how the leaderboards will look if you have more users but we only got two users so that's why it's just it's going to look a little bit weird but just if you want to want it to look like the demo just add more users we got spin I'm going to render our image from next uh the source is going to be user. profile pick width is going to be 30 height is going to be 30 and then alt do brackets back Tex image of dollar sign bracket user. username all right then we do a class name of round it full and let's take a look nice so we got our image all right so after this we have a span class name of text Excel and here we're going to have our user. username underneath the span we're going to have we're going to render out a crown so if for the number one uh user just want to have a crown next to his name so to do that all we got to do is take in our index and if it triple equals to zero we want to return fa crown and we're going to give this a class name of inline block width of six height of six text yellow 500 and then a margin bottom of one take a look Nies we got a crown next to my name let's get it all right so we got span got our div and then we have total um sorry underneath this div we going have a span oh man span and this is going to have actually no class name have total quiz score I'm going do brackets quotes add like little space in there it's a little trick to add a space then we're going to render our quiz results user. quiz results. reduce and we're going to take in that ACC again take in the current value and we're going to return ACC plus our current value. quiz score and since we're using reduce we got to make sure we add comma zero Perfecto all right so now it is time to do our stat page all right so we can close out of this and we're going to make a another folder inside of our app it's going to be called stats and in here we're going to have a page. TSX all right so we're going to import stat cart and then we're also going to import our fetch users all right and since we're going to be using our fetch user server action we got to make sure we change this to async and then we're going to do a cons current user is going to equal a wait fetch users all right so I'm actually going to copy this code and paste it in here it's just a little bit of jsx not too much uh we most likely we will get errors here so it's showing that the current user is possibly undefined so we could just add a question mark there because it's possibly undefined just add question marks there give it a save make sure everything works so we got our stats there perfect so just to go over it we did a div with a padn top and bottom of 20 we got another div inside that with text Center margin bottom 10 text 2XL uppercase in here we got our current user. dat. user.name so basically just our username and then I added stats and a Emoji there in here we got our uh container and it's just holding our stat cards if you guys remember uh in our side of our stat card we're looking out for these props which is title value and that's what we're doing inside of our um stat page we're just basically telling the title giving it the value really simple um that's why I just copied this part over uh title correct answers value that um which is our quiz results that correct answers and same with our wrong answers and this is what we get all right so there is one bug that I'm glad I remember so if we let the timer run out and it automatically goes to the next question by itself the timer won't start but if we click on next question the timer will start so to fix that little bug um we can head over to quiz and inside of our next question function right underneath reset timer I want to kind of want to see it it happened oh as you can see see look it went to the next question and now it's not starting again so to fix that all we got to do is call our start timer function like that and now once it goes as you can see see it started again so now everything should work the way supposed to if I missed anything don't feel free to message me on LinkedIn um or GitHub or um my Discord I I probably need to put my Discord inside of the description I don't think I um have it there but I get ton of messages from people um all the time that they you know find little small little bugs or small little issues in my projects um which is you know totally fine don't be afraid to message me because honestly I'm still learning uh I started learning cold last year so I'm learning as I build these projects uh so yeah if you see anything wrong see any issues different ways I should approach things please let me know because I am eager to learn and but yeah I will see you guys next video peace
Info
Channel: Antonio
Views: 1,513
Rating: undefined out of 5
Keywords: javascript, master javascript, tailwind css, next js, nextjs portfolio, react js, next 13, nextjs tutorial, tailwind css portfolio, next14, next 14 tutorial, next 14 project, nextjs14, nextjs 14 project, nextjs 14 server actions, next js server actions, next js server side rendering, next js 14 full course, nexjs react, nextjs routing, nextjs auth, clerk auth, nextjs full stack app
Id: f9OJvzUi9lQ
Channel Id: undefined
Length: 711min 38sec (42698 seconds)
Published: Sun Mar 24 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.