React Node.js Fiverr App Full Tutorial | MERN Stack Freelance Service App w/ Stripe

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hello friends today we are gonna complete the Fiverr application using react node.js and mongodb this is the home page when I click on any category it's gonna patch all the gigs belonging to that category I can filter items using the minimum and the maximum price inputs and also I can sort them and I can get items using this search filter we can create a new user and login let's open a single gig page here we have the geek details the user information and all the reviews of this geek let's purchase we are gonna integrate this strike payment and you will learn how to handle a payment process using a node.js server after a successful payment it's gonna create a new order and redirect us to the orders page let's see the geek page after purchasing we'll be able to add a new review it's immediately here also it calculates the new geek rating right away and you'll see how to do that without using Redux let's get back to the orders when I click here it's gonna create a new conversation with that user and I can send a new message let's login as the seller in a new browser window we can see the new orders we can contact the customer and here we can see all our conversations as you can see this is the conversation that I have created I can Mark as read see the messages and send a new message as a seller we can't create a new geek to upload files we'll be using cloud unary and all the images will be stored in a Cloud Server let's create a gig and it's here it's a great project that will teach you all you need to know about full stack basics you will learn how to create a clean API structure how to filter documents using Advanced methods how to integrate Skype into the server and receive payments how to use JWT and cookies to provide security how to use Postman shortcuts to test your API basic grading system error handling use reducer for complex forms file uploading and more by the way this is the second part of the project if you didn't watch the design part you can find it in the description I hope you will enjoy if you want to see more projects like this please like the video and write in the comments what kind of Technologies you want to see for the next project in the previous video I asked your opinion and most people wanted a merge stack this is why I used when stack for this tutorial and again you will decide the Technologies we will be using for the next project OK if you are ready let's get started okay I created a new folder and inside this folder I'm gonna create my backhand server let's say API folder and in this folder let's create our not application first I'm going to open my terminal and I will say CD API I'm in the API folder right now and I'm gonna say npm init and why let's open up our folder as you can see we have a package Json and our main Javascript file is index.js I should create this file here basically we are going to create and serve our backend server using this file of course you can change its name doesn't matter but be careful here if you change your file name here you have to change here and let's create our dependencies of course the first one will be Express server I'll say yarn at Express and to run our application we are gonna need note mode let's install them okay as you can see our libraries are here to run our application as I said we are going to be using note mode I will say start not mount server.js so whenever we make any changes in this file not mon is gonna reload our application let's see I will say console log test let's start our application yarn start I will save here as you can see test if I change it's gonna refresh our application like that this is how we are using note mode okay of course we are going to install other libraries but before let's create our server I will say import Express from Express if I save our application is going to crash that because we are using as6 modules here by default you should import your applications like const Express require Express if I save as you can see there is no problem but if you want to instead of common JS you can use as modules as I did here if you want to use it like that you should come here and say type and module if you make any changes in your packet Json you should restart your application by the way I'm Gonna Save here let's do that yeah let's start and as you can see there is no problem anymore let's create our application post app Express function and we are going to be using localhost to run our application to do that we should listen any localhost port I'll say app listen I'm going to write here any port number and after connecting to this port number I'm gonna say back-end server is running I will save and as you can see it's here our application works okay right now we can connect to mongodb let's open up cloud.mongodb.com and here you can create your own free cluster and after creating you are gonna see this page and we are gonna connect to our database using our application and after that we are going to create collections and documents as you can see this is our previous marriage stack project as we did here we are going to create our users gigs orders and others but now we are going to connect let's come here sorry it's not here I'm going to click database as you can see there is a connect button here let me make this page bigger firstly we should allow our server to connect mongodb in our application we are using localhost in this case you can add your current IP address or if you want to you can give access from anywhere let's do that of course if you deploy your application instead of everywhere you should add here your server IP address but for now it can stay like that let's give here a username and password I will say llama Dev I will create and let's choose connection method we are going to be using our application let's copy here using this URI we are going to connect to rdb now time we are gonna do that we have here two options the first one will be using mongodb directly and the other solution is using mongoose I recommend you to use Mongoose that because it allows us to create collections schemas what I mean by that in this example as you can see we can Define collections field here before making any current operations and it makes everything much easier firstly we are gonna Define our let's say user Fields username is going to be string email password if you make any mistake where you make API requests it's going to show you where the error is I'm gonna come here connection as you can see we are going to be using these methods and we already have our mongodb URL we are just gonna copy this and paste inside this connect method let's do that let's open up one more terminal here and I will say yarn at mongoose let's import this and I'm gonna connect here you can directly use this function but I want to create something Advanced here we can catch any error it's the better option I'm going to copy this and paste here and let's paste our URI here I'm gonna copy this and paste I'm gonna change this password is gonna be number there and you can write here in a database name DB name will be let's say Fiverr by the way there is a warning here let's see and it says in mongodb 7 strict query option will be false by default okay we can't change it only thing you should do is writing here Mongoose set strict query will be true okay and after this connection we can write here anything let's say console log connect it to mongodb okay connection is successful if I change something here as you can see it has crashed but there is something important here because we are revealing our password so we can hide this information I will copy this and I'm gonna create here an emu file Dot eme and let's see and it's going to be this URI basically you can write here any secret key you should do this that because if you share your code you can easily hide this emu file in this case no one will be able to access your data here okay I will save of course if you make any changes in your yummy file you should restart your application and right now I'm gonna use this I'm going to place here process Dot eme and the variable name if I do that it's not going to work oops there is no handle error function that's a console log and as you can see there's an error that because it cannot read our string that we gave here to prevent this problem we are gonna need one more library and it's going to be dot EMV and add dot EMV let's call this here and I'm gonna write its configuration dot eme dot config let's see right now I'm gonna refresh and it's successful okay if you want to you can write here any function connection function let's say First Connect it will be async function and I'm gonna wrap this connection and then we listen our application I'm gonna run this function like that it's exactly the same thing okay so we are ready right now let's create our first schema let's open up our folder and we are going to create here our models and the first model will be user model and let's remember how we are doing this I will copy here we are going to import schema and our schema name will be user schema let's delete them and then we create any User it's going to have a username type will be string it's gonna be required that because we cannot create any user without username and I'm gonna say here it should be unique we cannot create another user with this username and the other one is going to be email again type string required and unique password it doesn't have to be unique I'm going to delete here let's duplicate this and what else user can have image it's going to be string that's because we are going to store the image URL and let's say false we don't have to upload any image and it's going to be country maybe phone number let's say false we are going to ask for font number for only sellers Maybe user description it's going to be false because the normal users don't have to write any description I'm gonna say is seller let me create any user by default it's going to be false by the way it's not going to be string it's going to be Boolean it will be true or false and if we don't specify any Boolean by default it's going to be false okay I can't delete others and here we can write our options I'm just going to write one option here and it's going to be timestamps so when we create any user by default it's going to create its created ad and updated ad dates let's export this I will say Mongoose model name will be user and we are going to be using this user schema basically this name will be but we are going to create in rdb like hotels rooms users okay let's create others I'm gonna copy this new file and it's gonna be kick dot model dot Jazz let's paste let's change those names it's gonna be geek let's play it here and right from scratch so when we create any gig firstly we are gonna have the owner of this gig so we can store the user ID actually let's create here our client folder and install our react application and I can explain you better what we need client folder and in this folder we are going to be using our front-end application let's import this here so I'm going to open a new terminal let's open up our folder client folder and let's open up our Ripple story and it's going to include every project that we are going to create this year so I recommend you to give a star for this repository so it's gonna be easier for you to follow our projects if you check here you are going to see fiber UI here this is our react app let's import this I'm going to come here copy this URL I will say catch clone single branch I'm gonna write here my Branch name Fiverr UI let's paste our URL Dot and enter let's see okay they are here but we don't have our libraries let's install I will say RPM install or just yarn and it's going to install our libraries and after that I'm gonna run my application and show you what they are gonna need for the geek schema let's come here and open our application localhost 5173 if I enter it's not going to work that because we didn't run yet okay it's ready let's start I'll say yarn run there as you can see it's ready here let's refresh okay our application is here and let's open up any geek as you can see the first thing will be this geek title and we are going to have a description here a geek rating let's create them first otherwise we will forget I will come here and say title but before as I said we are going to have a user ID the owner of this gig and type will be string is going to be required let's duplicate this I will say title is going to be required description we are going to have a rating to do that we are going to have total rating here let's say maybe total Stars and the type will be number and one more number and it's going to be the star number so basically when we divide this total number by star number we are going to get this average number we are going to make that simple calculation later but for now let's focus on other things here it's gonna have some category that's a category is going to be string and required we are going to have any price here let's say number we have those images but also we are going to have this cover image so let's say color is going to be string and images is going to be an array which includes strings that because we are going to have multiple images here we are going to store them in this string array and what else as you can see we have a short title here and short description we have this delivery time and revision time it's gonna be number also and finally we are going to have some features here let's create one more it's going to be features and again we are going to create an array and it's going to include strings by the way I didn't give true or false let's give them you don't have to have any features and they are going to be by default let's say zero and that's all I think maybe we don't have to upload any image let's say false but the color image will be required and what else we can add here the sales number and we create any gig of course the sales number will be zero let's say number and by default is going to be zero and when we sell our product we are going to increase this number and that's all I think I'm Gonna Save and let's create other models when we buy or sell any product we are going to have an order model and what else as you can see we have reviews here we are going to create reviews model actually I'm just gonna copy and paste this model and we are going to change later let's say video model we are going to have conversation model that because remember we can see our messages here actually they are not messages there are conversations and when we click on them we are gonna see our messages so we are going to create one more model and it's going to be message model okay that Scrolls everything and start from let's say review I'm going to change this name let me close this sidebar I'm going to delete here and let's see I will get back of course we are going to have the gig ID first because all those reviews long to this geek number kick ID so I'll say gig ID type will be string and it's going to be required now I can duplicate and it's going to be a user ID this user the star number that's a star and number and this description it's going to be string and required okay that's all by the way I said number but we can choose only five numbers from one to five if I enter 10 or any other number it shouldn't be allowed so I can give my options here using num and in this array I will say it can be only one two three four or five nothing else okay I will save and I'm going to open up order model let's delete them and give new name and it's going to be order I'm not right here and then we'll buy actually let's open up here we have a page for that we have orders we can store the gig image and its title its price and do we need this or not I'm not sure maybe we can ignore here let's create them first I'll say geek ID type string is going to be required now I can duplicate we either have image and let's say false actually we don't have to write and it's title describe a string price let's say number and we are going to have seller and buyer ID and I'm gonna explain why we need them I will write here this completed it's going to be Boolean and by default it's going to be false basically when a user clicks on this button we are going to create an order but it's not going to be completed after a proper payment after the correct card information credit card information this field will be true and we are going to be using stripe for that so we can write here stripe number actually I will say payment intent it's not important for now when we work on payment you are going to understand here better but for now it can stay required true and that's all I think okay I was going to explain this seller and buyer we are using them that because then we try to contact to this buyer or seller we are going to create a new conversation and this conversation ID will include seller and buyer ID so if you haven't created any conversation before we are gonna create and if we have any existing conversation we are gonna open directly this message page you're not gonna understand everything better just follow me step by step okay I can close here what else we have I have conversation let's delete them and as I said we are going to create our own conversation ID using seller and by your ID so I will say ID is going to be string required unique again we can use seller ID and buyer ID of course you can separate them using this ID but anyway I can stay and we are gonna have read by seller it will be Boolean and read by buyer again Boolean we are doing this that because let's check as you can see we can Mark as red some of those conversations when we click here for example if we are the buyer it's gonna be true and what else as you can see there is a last message here last message and it's going to be strick and I will say false that because when we create any conversation we are not going to have any message only after writing anything here we are going to see our message okay let's open up our last Model and it's the message model and let's see firstly we are going to have our conversation ID and after that we are going to have the user ID and its message let's say conversation ID is going to be required but not unique also we are going to have user ID and finally the message is going to be string and that's all so we have created our schemas right now we are ready to create our first documents to do that we are going to create our endpoints and controllers let's create here another folder and it's going to be routes and again we are going to create different routes for each model let me write them quickly first one will be user dot Rod dot JS I'm going to import Express here so we are going to create our amp points using Express router so I will say const rather it's going to be Express and router methods and I'm gonna export using default this rather default rather okay so we are ready to use our user router we are going to import this rather in our server.js so let me explain how it works I'm Gonna Save and open up my server.js that's import routes folder user Dot product yes so we can give here any name that because we are exporting this by default so let's say user route now I'm gonna come here and use this route using app.use so I can give here any endpoint and it's going to be API users and then we make any request using this endpoint we are going to be using this route I'm going to say user route and I will come here and create my first amp Point using this rather I'm going to create a get method and let's say test if you are using Express server you should write here request and response if you already know Express server it can be easy for you but I know some of you are not familiar basically request is what comes from the user from client server and the response will be what we are sending to user as a response let's say response send and it works so let's visit our endpoint remember it's API user and also this test I'm gonna come here and say localhost remember our port number API users and test oops I said user is going to be users let's refresh as you can see it works this is how we are going to create our endpoints and using these endpoints we will be able to create new user we will be able to delete or update them in here we are going to create our functions path Rising everything in this route is not a good idea that's why we are using controller folder let's create one more folder Discovery controller and that's a user.controller.js and here let's say we are going to delete an existing user const late user and we are going to take our request and response here and we are going to write our functions so using this function let's export I'm going to copy this and I'm gonna delete here and I will paste my function in this case it's gonna run this function let's say response send from controller of course we didn't import this function from user controller and that's right here delete user actually let's make here controllers not controller I will save and that refresh here and from controller okay guys this is our main structure right now I'm gonna delete here this function and let's say FN and I'm gonna duplicate my folders and create other controllers and routes using those collections okay I have created them using server.js I can import my other routes like that and like that and right now we are ready to make some crude operations firstly we are going to create a new user of course to do that we can use user route and right here register and login endpoints but I don't like using user rod for authentication operations because it's a really important process we are going to add extra security and we are going to use our logged in user in all around our application so what I'm gonna do is to create another route here and it's going to be authentication route let's copy this and paste here and I'm going to create controller let's copy this actually okay so let's create a new user I'm going to open up authentication route as you can see we have register and login endpoints but they are not going to be get method they're really post that because we are going to send our user information remember if you are sending any input you should use post or put if you are fetching any data you should use get technically you can send any input in get method also but it's not recommended if you are sending any information just use post okay right now we can create our functions it's going to be register and login and actually one more is going to be log out let's import those functions from our controller and let's create our functions we are going to have three functions it's going to be register login and log out by the way they are going to be async functions that because we are going to make operations using our database let's say try catch block if there is an error we are gonna send this to user let's say response we should give here any status we are going to create Advanced error handling but before let's say 500 and we can send any message here something went wrong it's just a basic one we are going to change here and after we should create here a new user using user model so let's say const new user I'm gonna call my user using user model and I'm gonna create a new user instance and I will write here my fields for example username will be test email password country and that's enough and using Mongoose We Are Gonna Save this user to our database it's really easy to do that I'm gonna say await we are going to wait this operation new user and Save and after we are going to send a response status will be 200 successful or 201 which means successfully created and I'm gonna send user has been created Let's test our application by the way did I use my authentication route here or not no I didn't let's import okay to test our endpoints we are going to be using Postman if you want to you can use insomnia or any other API software not in this tutorial we are going to be using Postman let's create a new request here and let's test our first endpoint it's going to be a post method and I'm going to write my endpoint vocal host part number API authentication and register later we are going to be using this body section and we are going to send our user information here but for now we can send this user we are just going to test it I'm gonna send as you can see user has been created 201 successful let's see mongodb I'm gonna refresh this page let me make this bigger and as you can see our database is here and we have a user's collection and inside this collection we have our test user and it has every field that we have sent and as you realize we have created and updated ad times also it's that easy guys right now we are gonna send this user using our client as I said using request we are taking inputs from user so I'm gonna play it here actually let's delete this object and request buddy let's add our information using this body make sure that you choose here Json file and I will say username user one let me make this bigger email password that's a gmail.com USA that's end as you can see this is how we are sending our error here we send 500 status codes and this message 500 and our message and this error is happening that because we didn't allow our application to take any input from user to prevent this problem I'm gonna come here and say app dot use Express dot Json in this case we can send any Json using client site let's send as you can see it's successful I'm gonna refresh and it's here okay right now what I want to do is I want to encrypt my password as you can see it's a plain text it's extremely dangerous storing your passwords like that to prevent this we are going to be using a library called bcrypt let's come here I'll say yarn at decrypt and I'm going to call this Library here not here in our controller let me close everything actually and it's gonna look better I'm gonna import my library and I'm gonna hash my password I will say const encrypted passwords or just say hash decrypt you can hash your password using one of these methods async or normal let's use this one and I'm gonna add request body and password teaches the input that we have sent here display text if you hash your password in this way you should write here an assault number it can be any number doesn't matter I'm just going to say 5 and right now I'm gonna use this hashed password instead of my playing password I'm gonna come here I will say password will be hash password and other information request dot buddy if you don't know how to spread objects I recommend you to check on the internet basically it says take everything inside this but the objects outside of course I should spread this here and after it's going to overwrite our password that sent back and here perfect right now we are secure nobody can reach this password and I can log in and after that we are going to handle those errors let's come here again I will say try catch block I'm just gonna paste this for now and firstly I'm gonna take those information from my user and I'm gonna encrypt this password and I'm gonna compare this with the password inside my DP if they are same it means we are the correct user so we can send our user information to client site let's do that firstly I'm gonna find my user in DB I'll say const user wait user model I'm gonna use mongodb find function as you can see there are many options here we are gonna find only one user because it's Unique and I'm gonna pass here my username and it's going to be request body gold username we are going to take this username here and using this username we are going to try to find our user and if there is no user you can send here another error return response status 404 and send user not found for example and after that I'm gonna compare my password let's say const is correct using this Library I'm gonna compare passwords I'll say decrypt compare and I'm gonna pass the password comes from the user request by the password and the password in my DP and I'm gonna write here one more condition if it's not correct we are gonna return here 400 and wrong password or username you can directly say wrong password but I recommend to use username also in this case you will not reveal which one is correct and after that if everything is okay finally we can send our user I will say response successful of course status sent I'm gonna send my user but if I do that it's going to send my password also to prevent this I'm going to take this password outside of my object and I'm gonna send the rest let's say const from our user I'm gonna take the password and other information and I'm gonna send only this information basically I've separated this password and other fields here that's it it's gonna be an error right now because I missed something here let's see I'm gonna say login actually we can create here new collection let's say Fiverr application and in this collection I can create new folder let's say Authentication and I'm gonna add a request first one will be register is going to be a post method I can copy this actually we are going to be using this localhost port number and API endpoint all the time instead of writing this again and again I can come here and create an environment let's say Fiverr and I'm gonna create here a variable it's going to be URL and I'm going to pass here my URL let's save I'm going to open up my Collections and here I'm going to choose my fiber environment in this case I can use my URL here as you can see our environment and URL and right now I can write my authentication endpoint register and I can pass here my information that's copy them and I can close here not sent as you can see something went wrong that because we already have this user perfect so I can create another request here that's a login it will be post URL by the way if you want to learn more tricks about Postman just let me know in the comments and also we can test our apis if you want to just let me know and I'll say pause actually we don't need this and login and that's Camp here and send our username and password use it one I'm gonna send and as you can see there is an error here it's not an error but this is not what we have expected as you can see all this information is here and it's inside this underscore document field to prevent this I'm going to come here and say document and let's try I'm gonna send perfect it's that easy but to add here more security we need more than this instead of only user information we should also send an access token why do we need any access token that because in our application as you remember we have orders here let's choose this one actually okay as you can see we have this delete action when I click here we are going to delete this gig for example but if I'm not the owner I shouldn't be allowed to delete this gig if I don't do this with any access token somebody else can update or delete our information or add here for example new geek or they can delete any other information to prevent this we are going to be using Json web token I have cookies so I will say yarn at Json lab token and cookie parser I'm gonna enter to use cookies in our client site I'm going to open up my server and import this cookie parser and I'm gonna add here one more middleware this is our first middleware I'm gonna add one more and it's gonna be cookie parser and let's create our Json map token and I'm gonna come here and create a token I'll say const token JWT I'm going to import JWT from Json web token and we are going to create using these methods and we are going to send any user information we can send anything we want but the important thing is here our user ID so I will say ID it's going to be user and ID remember this is the user which we have hatched from rdb we are using its ID and not as we can send we can send the seller information if you are a seller or not let's say is seller and it's gonna be user dot is seller we are gonna need this information that because when we create any order for example or review we are not gonna allow any seller to create any review for example only normal user can create a review and Order this is why we are gonna need it finally we should try it here in the secret key if you are using a secret key as I said you can use EMV file let's say JWT key and I'm going to create a random string you can write anything if you want to you can use your terminal you can say date md5 and it's going to generate this timestamp we can use this JWT key let's restart our application and I'm going to be using this script key process eme JWT key and I can send this token using cookie inside this response I'm gonna say send cookie and the cookie name will be access token and I'm gonna set this token and I can write here any option it's going to be HTTP only in this case no secrets can reach this data this cookie we can change it only using HTTP requests and that's all I think let's see I'm going to come here let's check first as you can see cookie is empty I will send user is here if I check my cookies as you can see there's an access token and inside this token we have our user information user ID and eseller so using this cookie we can reach that information everywhere in our application what I mean by that for example let's create another folder it's going to be users and let's create a request it's going to be a delete method delete a user our URL users and we are going to pass here our user ID let's check our user in rdb I'm going to refresh to make sure it's correct okay we have two users for example this one I'm gonna choose this user ID uh pass here and if you are logged in as a user tool we shouldn't be allowed to the latest user to make sure that we are going to be using JWT remember it's inside our cookie we can use it let's create our function I'm going to come here user route let's make this plate delete and the parameter will be user ID and the function will be to date user controllers user.controller Dot yes let's create this user controller is going to be played user of course it's going to be async and I'm gonna say wait user model that's a user like that for the consistency and I will say find by ID and delete here so we are going to pass here user ID remember it's in our parameter using request params and ID we can find this user and delete but as I said we should check first if we are the owner or not to do that we are gonna need our JWT so I'm going to say const token it's inside our cookies so I'll say request cookies access token we are going to check if this column exists or not I'll say if there is no token we are going to return a response let's say status 401 and I will say you are not logged in or authenticated and if we have a token we have to check the user ID inside this token to do that we are going to be using JWT let's import from Json web token and I will say verify token and we are going to pass here our secret key remember it's inside our eme file JWT Secret and after this process if it's not verified it's going to return an error if it's verified it's going to return us our payload and we can write here not sent this payload for example you're going to understand better right now I'm gonna comment this out for now we are not gonna delete by the way it's gonna be Js let's see I'm gonna send cannot wait let's check our route oh my eyesight delayed here it's a delete method and we are gonna pass our ID directly of course you can write late also doesn't matter that's sent oops it didn't return anything it's key not Secret I'm Gonna Change here let's try and as you can see it sends our payload which includes our user ID is seller information and also JWT creation date it's issued at date basically it has a lifetime if it expires we won't be able to use this token anymore okay basically using this user ID I can write a condition I will say if payload.id equals user ID in my DB to do that of course we should find our user first I will say const user await user model find by ID we are going to pass here our user ID remember request parents dot ID and we are going to find this user and take its ID don't forget you should write here underscore that because in rdb it's stored as underscore ID and actually let's write here and if condition if they are equal actually let's say if they are not equal we can send an error here let's say 403 okay you have a token but you are not the owner you can delete only your account if not finally we can delete this user say async and I'm going to say return of course otherwise it's going to run this and let's see remember it's the user one and I'm gonna be logged in as a user tool for example I will send right now I can delete this user as you can see you can delete only your account if I don't have any cookie let's delete this it's gonna say you are not authenticated and if I log in as a user 1 finally I will be able to delete my account let's see I will send that because in our database as you can see it's not a string it's an object ID to prevent this error I'm going to come here and say to streak and I'm gonna return here in response plated let's try it's deleted it's successful I will refresh my mongodb and as you can see we have only user 2. okay awesome this is why we are using JWT even if you don't have to compare anything you can check if your user is authenticated or not and we are gonna use it almost everywhere in our application so to make it easier we can create a middleware instead of writing them again and again for each function let's open up our API I'm going to create one more folder it's gonna be middleware and let's say JWT of course Javascript file I will say export const verify token is going to be request response because it's a middleware and I'm gonna take here and also I'm gonna verify my token but we are not going to make an operation here I can delete here instead I can assign this payload as a request so if I say request and for example user ID is going to be payload.id number request dot is seller it's going to be payload is seller and if there is an error let's say 403 that means token is not valued yes there is a token but it's not valid anymore and that's all we can use this middleware everywhere right now let's open up our user route and before this function it's gonna visit our middleware first if there is some problem it's going to return error before going this function if everything is okay it's gonna run out late user function let's import this middleware JWT and right now I don't need here I don't need here and right now instead of payload I can say request a user ID that because we have assigned ID in our request so it's exactly the same thing and using this middleware is much more effective I hope you understood how to use JWT right now let's take care of our errors here so instead of writing our errors in this long way we can create an error handling middleware let's open up our server.js I'm gonna come here I'm gonna create one more middleware I will say app use and normally as you know we are taking request and response but for the error middleware we are gonna pass here four parameters it's gonna be error request response and next if there is an error anywhere in our application we are gonna return them using this error and next you are going to understand better right now so we can send the error status and error message to user let's say const error status and it's going to be error and its status if there is no status it's going to be 500. I can do the same thing for message let's say error message if there is an error message we are going to send it if there is no we are going to send let's say something went wrong let's return the return response status is going to be our er error status that we have created and I will say send and we are going to send our message you can send here anything but I prefer sending only message and status if you want to you can send the error stack or you can create here any object whatever so let's use it let's open this controller for example for the register I'm going to be using the next parameter and I will say next and error let's come here register I'm gonna create user one user has been created if I send again as you can see it sends the error status and its message it says there is a duplication here you cannot use this username and also you can specify your errors let's check here as you can see we have a specific error here let's use next I'm gonna copy here and I will say next but before I should create a new error I will say closed error is going to be new error I'll say error. status 404 and the message will be user not found not sent this error right now I'm gonna come here and let's say another user I'm gonna send as you can see user not found so you can create a specific error like that but to make this easier let's create a file and create our errors using that file I'm gonna cut this let's say utils I'm going to create a file it's going to be create error I will say cons create error status and message and we are going to create a new error its status will be this status and this message and finally we are going to return this error let's export okay right now we can use this function and we can send our status and message I'm gonna come here and say create error and I'm gonna pass 404 and my message and that's all let's import this create error.js let's see I will send as you can see it's exactly the same thing and it looks clear right now we can do the same thing here actually I will pass it like that and copy this message and that's all and here next and this error okay let's do the same thing for this JWT I will say next I'm gonna pass create error and it's going to be next create error 401 and this message and I can delete here of course inside code and finally token is not valid okay that's all by the way it's gonna be 403 not one and by the way one more thing we should do here if we don't use this next here we won't be able to go to other function let's open up our use a route here as I said after this API request is going to verify token and after this verification it sets our user ID and its seller information but if I don't say here next it stops if I say next it's gonna go to the next function it's really important don't forget this next and that's all let's add next here create error 403 you can delete on your account okay let's see here we have next error handling and others and that's all so we can log out so what I'm gonna do is to clear my cookie to do that I'm gonna say clear cookie and my cookie name remember it's access token and I'm gonna write here my options I will say same site it's going to be known but be careful we are doing this that because our backend servers URL remember localhost 8800 but our react application is 5173 basically they are not the same size to reach our cookies we have to say same site no and I'm gonna say secure true and let's say status 200 user has been locked out by the way don't forget we are just gonna clear this cookie from our browser it's not a problem for most cases but if you want to create an advanced logout function you can use a blacklist here Blacklist array and you can store your logged out tokens or you can use redis in the future I'm gonna show you these Advanced methods but for now it's totally okay we don't have to go further so that's all I'm gonna close everything here and let's try to register and login using our react application let's open up our pages login and we have only username and password input here so we can create basically a use statehook and then we change our inputs we can set our states I will say const username set username you stay took it's going to be an empty string and same thing goes for password foreign if there is an error we can show it at the beginning it's going to be null of course and let's change this input I will say on change method and whenever we change this input it's going to set our username you and Target and value let's copy and paste for the password by the way placeholder is email and delete this is going to be a password set passwords to add Target and value that's right here on click methods actually we have a form here we can say on submit method and handle separate let's create this function cost handle submit since we are using a form to not refresh our page I should write here event default and after that we are gonna send our username and password to our DB I prefer using axios let's create one more terminal here actually I'm going to close this and let's create new terminal here client and I will say yarn add axios okay it's ready I will say async function const response weight axios post methods and my endpoint here localhost server port number API auth and login and finally we are going to pass our username and password in this object username and password let's import axios okay of course I can say try catch block if there is an error we can set our set error State here it's going to be error and also let's see this error and we can pass here error message but we should see first and same thing here I want to see my response data okay let's see I'm going to open up the login page okay I will say user run user run let me make here bigger if I log in there is an error here okay I forgot HTTP here but if I log in there will be another error and it says it's blocked by course not because we are trying to reach our API from different websites to prevent this let's open up API here I will say yarn at course Library and let's open up our server.js and I'm going to add one more middleware here this is going to be course and I can allow to my react application using its URL so I will say origin http localhost and port number and I'm gonna write here one more option and it's going to be credentials and I will say true we are using this that because we are passing our cookies from client to backend server that's why we need this let's import this by the way course from course let's start our app I'll say user1 user one and login and as you can see it returns our user and if I check here my application in cookies oops we don't have our cookies that because in axios we didn't pass credentials option I will say with credentials it's going to be true let's try I hope everything is okay right now I will try and this time we have our access token here okay actually instead of this axios request I can create here my utilities and initialize my axios request here and I can use it everywhere let's say utils new request import axios from axios const nib request I'm going to be using axios and create we are creating an axios instance and we can give any base URL here and I'm going to copy and paste my base URL like that so we don't have to write this again and again and I will say with credentials it's going to be true let's export this by default new request okay right now I can use it here let's delete this post method authentication login and I'm gonna pass my username and password let's import this and delete this axios we don't need this by the way if there's an error we are writing this on the console let's say username one for example you don't have any field like that I'm gonna plug in and as you can see there is an axios error inside response and data we have our message so we can use it instead of error I'm going to say response and data let's take this back and I can use this error oops not console log is going to be set error and I can use this error somewhere here after this button if there is an error just show it okay I'm gonna add some more things here I'm gonna take this why did I delete this I don't know I'm gonna take this and use it in my local storage to do that I'm gonna say local storage set item that's a current user and I'm gonna pass my information here but remember response dot data is an object but we can set only string to local storage so I have to convert this to string to do that I'm going to be using Json stringify and response dot data and after that we are going to be navigated to the home page to do this we can use navigate hook I'll say const navigate use navigate hook it comes from real gradu Dom using this function we are going to go to the home page let me check here of course you can use context API for authentication we have done that for a million times if you check my other tutorials you can see how to do that but I just want to set my item here because this tutorial will be really long we are gonna learn tons of other things so it can stay like that let's try I will say user one I will log in let's check application we have an access token and also in local storage we have our user information as you can see awesome so using this current user right now I'm able to change this nearby user let's do that I'm going to open up now bar if you remember we have created here a dummy data we don't need this anymore I will say current user is going to be local storage this time I will say get item I'm going to choose current user in my local storage but right now it says string but I should convert this to Json I'll say Json dot parse and this item let's use this user here it's gonna be user image and if there is no image we can show something different and it's going to be no Avatar dot jpeg that's the extension let me check okay like that of course in image folder and username let's see as you can see user1 and our image perfect so we can log out using this button let's create here here's our logout button okay here you're not gonna be navigated to anywhere instead I'm gonna say on click method and let's say handle logout let's create this function we are going to make a request try catch I will say oh wait leave request it's going to be the post methods my URL log out and after that if we log out it's going to delete our cookie and I'm gonna delete this local storage item let's do the same thing here I'm going to copy this but this time it's going to be now and we are going to be navigated to the home page navigate the home page let's import this here Chrome reactor other Dome okay let's see I'm gonna click as you can see we don't have any user let's check our cookies as you can see it's empty here okay awesome it works and for the register page of course we can use use States as we did here for each item but we have many items here so we can create only one new state for inputs another use state for this file let's do that I can close here and open up the register file I will say const user set user I'm gonna add here my fields like that they are going to be empty for now after updating our inputs we are gonna set this user by the way you might think using context API or use reducer but as you can see they all are inputs nothing else there is no nested inputs here we are not incrementing or decrementing anything so there is nothing complex but for example in the add gig page we are going to be using use reducer so don't worry so let's come here and for each inputs I'm going to be using on change methods and handle change let's create this function first for others email passwords by the way I can delete this placeholder it's a file we are going to be using different method here for here for this checkbox we are going to be using different method also for this phone number and description as you realize all our inputs have their names like phone country password email and username we can set our user easily using those names only thing I should do is writing here set user take the previous state and return a different objective I will say take the previous object and event Target dot name it's going to be event Target dot value and if you are confused why we are using this previous or why we are using them like that you can check my use State video you are going to understand everything after that video okay right now we have our inputs but we don't have our file let's create one more use State it's going to be file set file if you don't have any file let's come here it's here I will say on change I'm gonna set our file it's going to be event Target files and we are going to take the first item that because we are going to upload only one image it's not multiple and it will update our file and one more thing we should update this is seller to do that I'm gonna create one more function here let's say handle seller and is seller will be event Target and checked that because it's a checkbox when I open this it's going to be true When I close it's going to be false let's write it here only change and a little self Nazi I'm gonna write here something as you can see it updates our username phone number password email like that if I change here seller will be true description okay it works and also we should upload our file to do that we are going to be using cloud ownery it's really easy to use we are going to be using its endpoint and we are going to send our file let's come here by the way of course you should plug in first and after you can create here any folder let's create a folder it's going to be Fiverr for example and I'm gonna come here upload add upload preset and that's right here Fiverr and our folder name and Save right now we are ready to upload our files and I'm going to come here and say upload function is going to take our file remember it's here we are going to convert this to a form data first I will say const data need form data and inside this data we are going to add our file like that and also we should add one more thing and it's going to be upload preset and I'm gonna write here the preset name and it's going to be Fiverr and after that we can make our API request try catch let me make this async function and I'm gonna say const response await I'm going to be using axios here and I'll say post method and I'm going to add this URL here and remember your name will be here do not use my account and I'm gonna pass this data let's import this quickly okay actually I can use this upload function in different JavaScript files so we can use it everywhere let's come here and I'm gonna say upload like that let's export this upload in this case I don't need this anymore but I'm gonna import here and after that it's gonna return our URL let's say const URL it's inside our response and data and finally we are gonna return this URL that's safe I hope everything is okay I'm gonna come here and I don't need here I can delete and finally we can submit our user information to mongodb or we can use our form let's use form I will say on submit it's going to be handle submits I'm going to copy this and create a function prevent default and firstly I'm going to take my URL image URL upload file and I'm gonna pass here my file and after that we can send them let's say try catch I will say wait leave request is going to be a post method I'm going to add here my endpoint register and I'm gonna pass the user information it's going to include everything inside the user state this state and also I'm gonna pass my file but remember user image name is image and it's gonna be this URL let's import this like that and also we are going to be using use navigate hook using this navigate hook by the way the error is because of here I forgot writing async and let's say to home page but before let's check if there is anything wrong I'm gonna come here let's say user from react gmail.com I'm going to choose an image here let's choose one of our images here this one USA any phone number and description I will register and there is something wrong okay it says we don't have any image that because there is something wrong with our cloudinary API let me check okay I forgot writing here uploads it's going to be upload and also I said mode is signed but it should be unsigned let's see exactly the same thing I'm gonna choose this image level register okay it says there is no image okay it's here but it didn't return us this URL oh that because I didn't await this upload function this time I hope it's gonna work let's choose this one I'm gonna register and finally no error of course we didn't show any response here but there is no error let's check our database I'm gonna refresh and as you can see it's here and this is our immature let's check okay perfect right now we have completed our Authentication so we can take care of our Geeks we can create a new gig and we can fetch all gigs from database I'm gonna close everything here foreign okay let's write our endpoints firstly we are going to create a new gig to do that we should be logged in so I'm gonna use verify token and I will say create gig let's create others we can delete any gig using its ID we can get a single gig I will say single and the geek ID and also we can catch all kicks by the way let's change here cat geek and get kicks okay I'm gonna import them and let's create our functions first one will be create gig I'll say async function request response and don't forget next and others too late kick get kick a single gig and multiple gigs and I'm gonna import create error function and gig model and let's start creating a new gig firstly we should be able to create a gig only if we are a seller so I'm gonna check if the user is seller or not to do that I'm gonna take request and each seller remember it comes from JWT if it's not I'm gonna return an error I'll say next create error it's going to be 403 only sellers can create a gig okay and after that I'm gonna say new geek using kick model we can create a new object here and the user ID will be request dot user ID comes from JWT of course not equal colon and others will come from request and body it's important to take the user ID from JWT because other users can send different user IDs okay let's say try catch block next error I'm going to say const saved geek newgeek dot save okay and after that we can finally send this saved kick to user status will be 201 Json and saved geek okay let's try I'm gonna come here and create one more folder new request is going to be add geek pulse method URL Geeks let's remember what we have geek model as you can see we have many fields here title description and other fields instead of write them one by one I can just copy and paste let's see as you can see all those information and in images field as you can see we have an array and it includes three images let's send it says it's for written that because we are not a seller let's create one more user here actually I'm gonna say seller and each seller will be true I'm gonna send let's login okay you have a seller right now I can add a gig oops I forgot category not say design I'm gonna send and it's here okay awesome I can add another gig here let's change its price is gonna be more expensive like that and another one okay maybe different category let's say AI okay they have same image part anyway it's not important the important thing is here this category and price that because we are going to change using this input and this section and let's create other controllers blade kick try catch block actually I can copy this for others okay firstly I'm gonna find the gig in our database and I'm gonna check its user ID if it's user ID equals my ID it means I'm the owner of this gig so I can delete that gig so that's a const kick wait geek find by ID request params.id and after we are gonna check if geek its user ID is not equal to my user ID I'm gonna return an error let's say next create error 403 you can delete only your gig and after that if there is no problem we can delete our gig wait kick find by ID and late and I'm gonna pass here my ID request params.id and finally we are going to send a response let's say status 200 gig has been deleted by the way it's not a big model it's geek and let's see where is our gig ID here I'm gonna take this and create any request delayed kick foreign Geeks and its ID if I give different ID of course it's not going to get the user ID because there is no gig like that but if I create another gig with different user actually let's say seller two seller two and I'm going to create different gig let's say five let's try I'm gonna take this back I will send as you can see you can delete only your gig but if I try to delete this one let's see where is its ID here thank you as you can see it's been deleted perfect it works by the way if you don't save those methods will not change okay I can close everything here and I'm gonna create another controller function I will just say const geek actually I will do exactly the same thing I will find my gig using parameter and I'm gonna send it like that of course you can write here additional errors like not found error let's do that if there is no gig I'll say next create ER 404 keep not found let's see and I'm going to choose this gig okay this endpoint doesn't exist that because I forgot writing here single and it's here as you can see there is only one gig I will save and let's create one more and it's gonna get multiple gigs I will say const kicks awaits kick model I will say find because we are going to find multiple data and we are gonna send this gig let's copy this and paste here like that if I do that it's gonna fetch all our Geeks but we don't have any filter here but in our application we have to filter our gigs using those inputs these buttons and also we should filter them by using their categories so basically we are going to send those data using query for example then I say category and Design it's gonna fetch only gigs that have this category if I say for example search and any search inputs here is gonna fetch all gigs using this search query to do that I can create here a filter variable I'll say const filter actually let's say filters if I say for example category design and if I add these filters here let's see as you can see design and design nothing else and if I say for example price and greater than let's say a hundred is gonna eliminate this gig for example let's see I'm gonna send as you can see it's not here anymore and what else I can do if I say Title Gig title and I can use mongodb rejects function and let's say geek2 okay I can search for this for example I'm going to paste here there is a comma I will save and let's send and as you can see there is only this gig it's gonna work like that so right now instead of writing them like this I can use request and query let's say post query request and query now you'll see Q dot category right now as you can see category is design it's gonna take this design and write it here and it's going to fetch our gigs let's send oops of course it's not going to be question mark it's gonna be and and as you can see it's here instead of D2 if I say query and search if I write here click three as you can see it's safe but what if if I write here lowercase geek3 as you can see it's empty I don't want to do that so I can write here any option and I will say I so it's not going to be sensitive for lower or upper cases anymore by the way options let's see I will send and as you can see it's here okay I hope you understood how it works but there is something important here if I don't write anything it should fetch all our gigs but let's see what's going to happen as you can see it says rejects has to be a string that's because we don't have any search query here also we don't have category we don't have cute price it means they can be empty to prevent those errors I'm gonna come here and write a condition I will say if there is a query category spread this object like that if there is a category it's going to create this object and if I use here spread operator it's gonna get this object to outside and if there is no category it's not going to create anything it's that easy so I can do the same thing for others I'll say if query and price actually it's not price that because in our application we have minimum and maximum inputs so I'll say query minimum or if there is query maximum write this object and spread of course I should write here one more condition let's delete this I'll say if there is minimum it's gonna be greater than minimum and I will do the same thing I will copy here and paste it can be a little bit confusing but if you do this by yourself you are going to understand better that's because here we have a nested condition firstly we are going to check whether we have minimum or maximum if you have one of them we should also check which one exists and after that condition we are going to write our filter here like that and what else is going to be title like that I will say if query and search for this search query and find inside the title field and one more I forgot adding here is going to be user ID maybe click on any user here we are going to fetch that user's Geeks okay if you didn't understand here you can watch three or four times and after that if you try by yourself I believe that you will understand everything let's try I will send as you can see all our gigs are here that's right category is going to be designed okay they are here let's eliminate this one I will say minimum 60. as you can see so I'm gonna delete this one I will say maximum 200 for example oops there is something wrong of course it's going to be less than not greater than okay perfect only this one so let's take this back and write a title I mean search query and it's going to be key to search and as you can see only this one so it works maybe this user ID I'm going to delete everything here okay so it's ready let's use them in our application to fetch any data we are going to be using react query of course you can fetch time using queues effect but I think it's more effective let's open up our client here I'll say yarn at 10 stack react query and I'm going to close everything here and open up my Geeks page here but before we have to go to app.js and wrap our application with react query where is the app.js here let's open up the documentation we are going to be using react query version 5. and as you can see we are going to be using react query client provider and wrap our application and we are going to pass this query client let's do that I'm going to copy here and paste let's create this client and drop our application like that the reason we are doing this is to Cache our fetched data we can use it using use Query function firstly we are going to pass a unique key for example when we fetch kicks it's going to be gigs when we fetch orders it's going to be orders you can give anything and here we are going to write our fetching function and it's awesome that because it provides its pending and error values also so you don't have to deal with Redux or context API it's going to provide everything you need let's copy this I'm gonna come here let's import this and of course we are going to be using axios remember we have new request function and the request will be Geeks for now we are not gonna pass anything let's see first I'm gonna come here and console log and data okay it says 401 you are not authenticated and it's correct let's sign in by the way why I can't click here okay it says span it's gonna be a link and I will say two login of course the class name will be link if you remember the previous tutorial I'll say class name think okay I will click let's say seller one oops oh it's not seller one it's seller okay I'm gonna click and as you can see inside data we have four objects four gigs let's use this data and show our gigs by the way if you wonder why it renders multiple times you can watch my use effect video it's nothing to worry about don't worry about that let's use our data I can close here and here I'm gonna first use this pending and here I will say if it's pending right here loading if it's not we are gonna check one more thing and it's gonna be this error if there is an error right here something went wrong if it's not show this Geeks map but if you remember we are fetching this using dummy data as you can see but we don't need this anymore I can play it instead we are going to be using this data actually I will say then take the response and return response dot data in this case it's gonna return this array directly okay let's see something is wrong by the way it's going to be a cat method if you don't write by default it's going to be get but in any case okay guys I found out that it's not going to be is pending it's going to be is loading let's see as you can see they are here right now we can pass our filters if you remember we have sort minimum and maximum refs we can use them I will come here and I'm gonna write here backtick that because we are going to write JavaScript inside and we are going to add here our query to reach this data we are going to be using react router Dom location I'll say const location use location let's see console log location it's here and as you can see it shows our path name and search query we are going to be using this one let's say search like that and I'm gonna pass this here right now as you can see there are three items by the way it says there should be a key but our key is geek ID remember it's going to be underscore ID foreign three items let's search for geek2 I will say and search E2 as you can see it's here it works if I don't write anything it's gonna fetch all this data right now we can use those inputs I will say minimum it's going to be minimum Wrath current value and maximum like that let's see right now I'm gonna search for this one for example minimum 200 and when I apply it's gonna re-fetch our data it's the other amazing feature of react query we can re-fetch our data and that may apply as you can see we just console log them instead we are gonna refetch let's try let's actually say minimum 100 maximum 300 and here let's see 200 okay perfect and what about here we are going to sort our gigs to do that we are going to Open click controller again and I'm gonna write here sort if I say created ads for example and -1 it's gonna show the latest items if I say price for example let's see first as you can see the biggest one is here if I say created at again this one because it's the latest three to one so it works like that so if I write here query.sort of course I'm gonna take its name only like that it's exactly the same thing as we did in register for example here we are taking its name only this string and let's do that I will write here sort price as you can see it's here right now I can add here one more query and it's going to be sort we are changing our sort here in this function and I can say use effect Reef hatch my kicks whenever these sort changes let's see I'm gonna refresh I will choose the newest as you can see it's here and best selling it doesn't matter they are zero but it works okay so let's open up our gig cards and update our item let's delete here it's gonna be item dot color not image like that and as you can see there is a user here to do that we can fetch our users I will do exactly the same thing I can copy here and paste for my card use Query we don't have to refresh anything by the way I forgot changing this unique key is going to be kicks this is gonna be that's a Kik user and we are gonna search for users and we are gonna pass the user ID remember it's inside our item that because we are passing here our gig as an item so it's going to be item dot user ID after that I'm gonna use this loading variable and for this user is loading right here loading if it's not check for error like that it's going to be data dot image data dot username as you can see it's loading but there is something wrong I think it says 404 that because we didn't create our endpoint I think let's open up users throughout okay we don't fetch anything let's say get get user let's open up controller I'm gonna duplicate this it's gonna be cat user we are going to find by ID and send this user and as you can see seller is our username but we don't have any image let's write here a condition if there is no image show here in which folder no Avatar okay awesome so what about those Stars if you remember where is our model we have total stars and star number I'm gonna just write this total Stars by star number and I'm gonna get my average rating so I will say math round we are going to round our number that because it can be a float we don't want to do that it should be from 1 to 5. and I will say data but total Stars divided by data dot star number actually it's not data because it's our user it's going to be item let's see as you can see it's num that because they are 0 0 divided by zero is infinite so I should write here a condition I will copy this and I'm gonna say if it's not none let's say Now function show these numbers as you can see we don't have any more because they are none but let's change one of them which one I'm Gonna Change gigma total Stars will be let's see 12 and star number is going to be 4. let's update this and let's check as we can see it's here perfect so our cards are ready let's open up a single page and update our single gig okay I close everything and right now I'm gonna open my key craft and as you can see we have this single item we are going to fetch our geek it's not gonna be verified token that because even if we are not logged in we will be able to see our clicks okay I'm gonna open up single gig page here and we are gonna do exactly the same thing we will fetch our data let's copy this the key will be gig is going to be single endpoint and we are going to pass here the gig ID how we are going to reach that as you can see we have an ID here we can reach this data using use patterns I'll say const parents use params hook I'll say console log as you can see it's here and we have an ID inside we can use this by the way there's an error that because we didn't import use Query and I'm going to take my ID from here and use it right here let's use this data it's going to be a title by the way we are going to flash this user also and we can use our image array I will say data dot images dot map for each image we are gonna call one of these images like that and the source will be image and I'm going to give a key here and it's going to be image also I can delete this and our description again user there are reviews and on the right side you can change this short title and description price delivery date and revision number now finally our features again I'm going to use map data dot features dot map for each feature we are going to call this item let's give a key it's going to be feature and here is going to be feature let's delete this by the way let's take here to here I will say if it's loading right here loading if it's not check the error if there is an error right here something right wrong if it's not show this container let's see by the way we can make them inside curl the brackets like that I change this name by the way for fun let's take this back and okay by the way I should import this let's see okay it's going to be an error that because we don't have any gig with this ID I forgot changing there let's open up git cut as you can see there is a random ID here let's change this is going to be item dot ID let's get back foreign this as you can see perfect three images title description everything works perfectly let's take care of those Stars I'm gonna do exactly the same thing remember in the keycard we were using this function I'm gonna copy this and paste here of course it's going to be data by the way I can wrap my entirety with this condition let's take this here if it's numb we are not going to show this star Steel like that let's copy this and search for other stars I will do exactly the same thing here and what about those Stars as you can see our star number is four but we keep seeing here five items let's take care of this I'm gonna come here and use this star number and I'm gonna create an array using this number using array methods I'll say fill and right now we have an array and if I say map for each item inside and let's say index I'm gonna return this image let's delete others I'm going to give my key it's going to be I like that and let's see it's about seller and it's here perfect let's do the same thing for right here okay let me show you what we have done here I'm gonna copy this and I will say console log of course it's gonna be if it's not loading otherwise we are going to get an error and as you can see we have created an array and we fill inside with undefined variable we don't have anything inside but we don't need we just created this array to map through these four elements and create Our Stars okay I will delete this and right now we can fetch this user I'm gonna copy this let's change their names it's gonna be is loading user error user and data user by the way we don't need this refetch the query key will be let's say user there's going to be users we are going to pass the user ID remember it's inside our data so I will say data and user ID so let's use this I'm gonna wrap this do and I'm going to write my condition I will say if it's loading user right here loading if it's not check the error write the error message and RD let's copy here I will do the same thing for the seller section here like that of course I should close here okay let's change them it's gonna be data user and image and if there is no image remember what we are doing I will say in which folder and no Avatar let's copy here I'm going to change this username data user username and if and what does we have the user country data user dot country and we don't have those fields we can do them like that we have a description and that's all I think let's check okay there's an error our application has crashed there is something with user ID oh let's start our app and refresh here and it's here okay right now we can take care of those reviews if you remember in our application we have created our reviews inside the geek page it's here but I want to separate this it's a different component I'm gonna cut this and create any components it's going to be reviews let's create quickly import our CSS file and I'm gonna paste it here and for each View I'm going to create a different component let's copy this I'll say preview a single review like that let's change those names like that and it's going to be a single item I'm just gonna take this I will cut I can delete everything else we need only one item and the class name will be let's say review okay all right now I'm gonna pass here reviews components and pass inside my geek ID remember this ID comes from use params we can use it as you can see it's still the same let's take our CSS Styles and paste inside our new component I'm going to open this find reviews I will cut this and paste here and for this item no it's the biggest part I'm gonna cut and paste here but remember we have changed this name it's going to be review and I'm gonna come here delete those items and call my review component okay it's here so let's fetch our reviews using this gig ID and map through this review component let's open up this gig page I will copy this use Query let's import it's going to be reviews endpoint we don't have yet but we are going to create and we are going to pass here our gig ID remember we are taking this as a prop kick ID and I will pass it here let's see okay and I'm going to change this name it's going to be previous and using this data I'm gonna map through this component of course if it's not looting for each review called its component and don't forget giving your key here and it's going to be review ID and the review will be review okay let's create our endpoint and controller I'm going to come here and we will have three endpoints first one will be post we can create any preview it's going to be verified token of course we have to be logged in and let's say create review and the second one will be get reviews remember we are passing here our kick ID get reviews and finally we can delete them I'm gonna pass here the review ID and it's going to be late I'm going to import my functions and let's create them not before let's remember what's inside we have gig ID user ID star number from one to five and a description I'm gonna open here I'll say async I'm going to write my try catch Block in advance next create error and error of course next here by the way we don't need create error we already have our error but anyway we are going to use it and two more is going to be create review is going to be get reviews and delete review okay firstly I'm gonna check if we are a seller or not because if you are the seller we can't create any if request is seller I'm gonna return an error 403 sellers can't create a review and after that let's create an object preview object I'll say const new review let's import this from our model and the user ID will be request and user ID is going to come from the body description and stash okay right now we can add this by the way I can take this outside of the try catch block they are not async and firstly I'm gonna check one more thing if we created a review before for this gig ID we shouldn't be allowed to create another one to do that we are going to fetch our review first I'll say const the review awaits preview find one and I'm gonna add here my condition the review of geek ID will be request by the gig ID and the user ID will be request user ID and if there's a review like that it means we have created before I'll say if there's a review I'm gonna return error let's say create error 403 you have already created a review okay and after if you didn't finally I can save this review I'll say const saved click sorry preview wait new review and save and finally we can set this I will say response status 201 send saved review and one more thing here since we are giving a star we should update our gig I'm gonna come here and say wait geek model let's import I will say find pi ID and update I'm gonna give its ID here remember comes from request buddy click ID and I'm gonna increment my total stars and star number to do that we can use mongodb increment method I'll say ink and I'm going to increment total Stars it's going to be request by the star and I'm going to increment the star number only one okay and let's get reviews I will say closed reviews await reviews model finds and I'm gonna pass here like Condition it's going to be kick ID request by The Geek ID of course inside an object and that's all we can send it okay let's create using Postman NC I'm gonna create one more folder here request is going to be create review I'm going to write here my URL is going to be a post method and inside body yeah I'm gonna have a gig ID user ID actually we don't need this we are going to take it from request and user ID we are gonna need a star and a description let's find a gig ID for example this one star will be let's say five and let's say test review let's see okay there is an error that's crashed okay there's something wrong here I think of course it's gonna be Js and also create error here okay don't forget if you are using as modules you have to write this extension if you are using common.js you don't need okay let's try it says you are not authenticated let's login okay remember we are the seller right now foreign sellers can't create any review let's say user1 I hope I didn't delete this user let's try okay we are not the seller I'm going to create okay geek ID required but oh I didn't change here I'm sorry one more time and it's ready if I try to add one more time as you can see you have already created a review perfect I'm Gonna Save this and create another one get reviews and I'm gonna pass here my geek ID I'm gonna copy this okay it returns empty array by the way it's not going to be 201 we are not adding anything I said review find kick ID will be request by the kick ID of course it's going to be params and it's not kick ID it's an ID remember it's here to not be confused let's actually make this gig ID it's the better solution I will try and it's here let's see we have one review here we can change his description star and the user I'm going to open up the review remember we are passing our prop I'll say review remember we have a user we have to fetch our user part before let's change here preview and description preview and star and remember what we are doing here I'll say all right we will dot start fill inside and use map for each item return one of these Stars and I'm gonna give a key it's going to be I like that I can delete other stars here let's see okay perfect so we can fetch our users let's come here take this function and pass it here I'm gonna import them once you create a use Query using this for other components is really easy we are going to search for users user ID is going to be review plot user ID and let's say review users so let's use this I'm going to take this is loading I'm gonna write quickly okay let's change it data dot image and if there is no image username and the country which actually we don't need this we can change only here data dot country okay awesome but we cannot add any review let's create a component actually we can write it in here after those reviews I'm gonna say add new component is going to be add let's say add a new review and I'm going to create here a form and we are going to add here inputs that's a placeholder write your opinion and a select here we are going to select our star number let's say option is going to be one and finally a button and I will say set that's right here on submit methods I'm going to say handle submit const and submit and we are gonna need this star number and this input text of course you can create use State hook but we can also use this event directly we have two HTML elements this input and this select so if I choose the first element I can reach its data if I choose the second element I can reach the number what I mean by that firstly I'm gonna say prevent default of course description is let's say const description event Target and the first element and its value and the second element will be the star number it comes from input it comes from select right now using react query use mutation hook I can make a post request as you can see using use mutation we can create update or delete our items in this example it adds a new to the item let's copy this I'm going to come here use mutation and we are going to make any request it's going to be a post request I'll say reviews endpoint and we are going to pass our review so using this mutation we can send our description and star like that and one more thing we need and it's this geek ID K ID description and start and after sending we should update this reviews list to do that there is an awesome function here and it's on success I will say if it's successful I'm gonna emulate these reviews and it's gonna add our new review into this data to do that we are gonna need use Query client let's say const query client use Query clients I'm gonna use it here and I will say email date queries and I'm gonna pass this key here revalidate this let's try of course we are a seller I'm gonna log out let's say user two let's open up of course we are going to give a style but let's say from user 2 thank you three stars I will send and it's immediately here but there is something wrong it shows the user one and the reason is that if you remember I said you should use here a unique key but we are using the same key for each user it should be unique so I'm gonna say you will dot ID sorry user ID in our case it was caching our data and giving the same result but right now as you can see it's different okay by the way there is a problem here it says there is no user ID in geek jsx let's check 27 okay basically it says there is no user ID yet what can I do I can say const user ID if there is data and its user ID is going to be true and there's an awesome feature in react query we can enable this use Query function only when this user ID exists so I will say enable user ID in this case if there is no user ID it's not gonna run I can delete here okay perfect let's give a style quickly I'm gonna open up review CSS actually it's reviews CSS and I'm gonna come here and say add I'm going to give margin top it's going to be display Flex direction will be column and I'm gonna give a gap between each item like that and for this add input let me check first let's give a class for this form I have to say class name I will say add input or form foreign flags flags Direction column again cap and for the input inside I'm going to give padding like that and for this select options let's say select I'm going to give a width padding will be 20 and I want to see this select on the right side of the component so I'm going to say align self it's gonna be flex and so it will be in the end of the flexbox I can do the same thing for this button allow itself flex and I'm gonna give a width I'm going to delete the Border why I didn't create this in the previous lesson I don't know but anyway I will say color and background color cursor pointer I said time is going to be a hundred okay there is nothing fancy but it looks much better and okay we completed our geek page let's take care of our items here for example orders so I will come here close everything open up my order model sorry auto route and controller and let's create our endpoints firstly we are going to create a new order it's going to be post and we are going to verify our user and let's say create order and one more is going to be a get method and we are going to get all our orders get orders I'm going to import verify token import from controller it's going to be get orders and create order we are going to add more endpoints but for now it can stay like that that because we are not going to handle the payment process right now we are going to handle this at the end of the video okay let's say create order async I will say next try catch I will say next error and I'm going to import create error okay actually I'm going to copy this for conversation controller and message controller after that it's going to be easier to handle them okay let's see what we have first in order model we have geek ID geek image and title its price seller and buyer ID and payment intent as I said it's related to strike payment instead of stripe intent id we can just write random string it doesn't matter for now so let's create I will say const New Order model I'll say new let's import this okay and firstly I want to fetch my kick that because we are going to write here a price we shouldn't take this from a user because they can change the price so what I'm gonna do is to fetch my gig first let's import kick model I will say const geek it's gonna be geek model find by ID I'll say request params and geek ID in this case we should write it here like that of course you can send By Request body but anyway it can stay in params and after that I will say kick ID equals geek dot ID and image will be remember its cover title it's going to be buyer ID in this case we are the buyer I can say request user ID we are going to need the seller ID it will be geek dot user ID finally Price Kick dot price we are taking everything from this gig not from user and finally payment intent it's going to be temporary string it can stay like that let's save this I will say oh wait a order and Save and after that we can send it response send I will say status 200. normally we are going to send this stripe ID but for now let's say successful okay let's create I'm going to come here I'll say orders or order create order URL orders I'm gonna pass here the geek ID by the way there is something wrong get orders no that because we didn't create anything let's create get orders I'm gonna delete here okay let's choose this one I'm gonna copy this ID and it's going to be a post method let's send didn't send I forgot here await okay it's successful let's get our orders get orders and that's right our controller remember we are gonna fetch only our orders using our user ID I will say cost orders it's going to be await order find and I'm going to write my condition here if you remember we have here the seller ID and buyer ID and our username will be one of them so I can write here if request is seller the seller ID will be our ID request user ID if it's not buyer ID will be our ID and also I will say is completed should be true like that I'm doing this that because when we click here as I said we are going to create an order but it's not going to be completed when we enter our card information and make the payment it's going to be true and when we click here we are going to see only completed orders okay that's sent this response status and orders okay let's do that I'm gonna send it returns an empty array that because by default is completed is false if I come here let's check our orders I'm Gonna Change here right now we are going to see our order here okay awesome let's use these endpoints in our react application let's open up orders I'm gonna open this gig copy here by the way we have a current user here we don't need this anymore if you remember not with it in there bar I'm gonna copy this and paste here let's import use Query and new request like that I'm not late here the query key will be orders and I'm going to delete here I will say orders and after that I can use this data I will wrap this container let me close this I'll say if it's loading loading if there is an error error if it's not it's going to show this container and this is the head of the table and this is our item basically I'm going to take this item and using data and map for each item actually let's say order I'm gonna return here of course we don't have any unique key let's give is going to be order ID let's change here order image order title price you don't need here and we can delete this user we don't need this or if you want to you can show the buyer or seller ID and that's all let's see by the way I'm gonna delete others as you can see it's empty that because we are the user 2 but in our example we are using one let's log out and sign in I will open up and as you can see it's here right now when I click on this button we are going to open the chat page but there's something important here if you already have a conversation with that user we shouldn't create the new one which will directly open the chat page but if you don't have the conversation we should create the new one using the buyer and the seller ID let's first open up our conversations let's create our endpoints and controller and after that you are going to understand better I'll come here I will say verify token cat conversations we are gonna get we are gonna fetch all our conversations and we are gonna create a new one I will see create conversation we are gonna get a single conversation let's say get conversation or single conversation in this case I will say single and ID we are going to get the conversation ID and finally I will say update conversation and the conversation ID let's import them either way what's wrong here oh I said comma of course they are going to be semicolon okay let's come here I will say create conversation let's say cost new conversation I'm gonna import my model and insight let's see what we have we are going to have an ID and it's going to be seller ID plus buyer ID read by seller read by buyer and the last message we don't have to give this it's not required let's do that I will say ID and I need a condition here I will say if request is seller is going to be request and user ID plus request buddy let's say two if it's not it's going to be the opposite request buddy.2 plus request user ID the first one will be the seller ID remember it has to be like that this is our rule I will say seller ID again if we are the seller it's going to be our ID if not it's gonna be request body and true I will do the same thing for other one like that and read by seller again that because if we start any conversation is going to be true and the other person will not see our message immediately so it's going to be false this is why we are doing this like that by fire is going to be the opposite of our situation and we are not going to have any last message we are just starting the conversation we are not adding any message and let's save this I'll say actually inside try block const saved conversation await new conversation and Save after that we can send this 201 7 conversation let's create others update conversation I'm gonna delete here not as we have got single conversation and get conversations okay using this update conversation basically we are going to update the red by seller or buyer information let's open up any message here then we add any message by default read by buyer will be true read by seller will be false that because we are not a seller and if we are the seller it's going to be opposite I'll say const updated conversation I will say await conversation I will say find one and update I'm not saying find by ID that because remember the conversation ID will be seller ID plus buyer ID that's why we have created the ID field so we can use it I'll say ID it's going to be request params ID and after that after finding our conversation finally we can update using the set method so I will say read by seller this is going to be true if we are the seller and I will do the same thing for buyer like that and after updating I want to see the updated conversation so I'm gonna write here new and true if you don't write this it's not going to return the new conversation you will keep seeing the old conversation I'll say response status 200 Cent and updated conversation okay let's see a single conversation I will say const conversation await our model find one and again I'm gonna use the ID request params ID and we can return this if you want to you can send any error if there is no conversation you can send 404 but it can stay and finally get conversations I'll say close conversations I will say await the model I'm going to say find again if we are the seller the seller ID will be our ID otherwise the buyer ID will be RIT and finally we can send it like that let's test it I'm going to come here new folder firstly we are going to create it's going to be a post method an inside body foreign this is where we are sending it's going to be the user ID let's choose any user ID here are we the user two or one okay one so we can choose this one and send okay there is no end point like that let's check oh I forgot writing here post by the way when we update is going to be put and here let's check it's going to be buddy let's see I hope everything is okay I will send and as you can see it's here let's see our conversation in our application I'm gonna close them and open up messages page and again we are going to be using react query foreign import and this let's say conversations I'm going to delete this by the way I can do it here and take this from local storage and let's see as I always do I'm gonna wrap my app I will say if it's looting loading error if it's not this container right now I can delete other items here I'm Gonna Leave only one and I'm gonna map through this item I will see data dot map for each conversation let's say C stands for conversation I'm gonna return this TR let's give a key it's going to be CID remember this is a custom ID I'm not using underscore and it's going to be C dot description and we are going to be using updated add date but to use it like one hour ago two hours ago we need a library let's open here I will say yarn at moment it's a really useful Library if you are working with times so I'm gonna come here by the way I'm going to choose the latest version and I will say moment I'm gonna add here conversation updated add date and from now let's see of course it's not description it's the last message but remember we don't have to have any last message it can be empty so I'm gonna add here a question mark and it's going to show only if it exists okay as you can see it's here we created this five minutes ago and instead of this name we can maybe show the ID again we need is seller variable if we are the seller C dot buyer ID if it's not C dot server ID we are the buyer and as you can see it's going to be seller ID here and finally when I click here we are going to update our conversation and react by will be true by the way as you remember in our controller I said one of them will be true one of them will be false but they all are gonna be true that because if we are the buyer the seller is already true read by seller in this case Red by buyer will be true but we are not gonna make it false if we are the seller if we are the seller it's the same thing when we click here redbye seller will be true and read by buyer is already true we don't have to make it false if you want to you can write it like that it's exactly the same thing if request is seller rat by seller will be true if it's not if we are not the seller this time rat by buyer will be true basically the other one will not be false that's because it's the center of the text it has to be read by sender we are not the sender we are the receiver it's gonna be false at the beginning when we click is going to be true okay let's do that by the way if we have already read this message we don't have to see this button let's write here our condition if current user is seller and if read by seller is false we can see this and also one more condition I'm gonna copy here or if we are not the seller and rat by buyer is false in this case we can see this button one more time let's say we are the seller it's true and read by seller will be false in this case we will see this button if it's true it means we have already read this message we don't have to see it and the same thing for this one if you are the buyer it should be false let's see as you can see it's not here not because Red by buyer is true we have created this conversation and I can do the same thing for this active class I will say if it's like that it's going to be active in this case it will be white as you can see when we don't read the message it's going to be green okay let's login as user tool actually I'm going to open a new tab let's log in here I will say user 2 user 2. foreign as you can see this is the message when I click here we are gonna read this message I'm going to come here and I will say oh click event let's say handle read const handle read and we are going to mutate our conversation remember how we are doing this I'm going to open up reviews and if you remember we are using use mutation hook let's do that I'm going to import client of course I should create first like that and using this mutation we can write our endpoint here it's going to be conversation and remember it's a put method and we are going to pass here our conversation ID let's make this backtick and I'll say ID let's say ID here I will click this and when it's successful we are going to refresh these conversations let's take our ID here using our button I will say C dot ID and I'm going to take this ID and rotate I will say rotation and ID let's see I'm gonna click as you can see it's completed perfect right now when I click here we are going to open up the message page but here as you can see we are going to have an ID let's write it here we have a link I'm Gonna Change here and it's going to be C dot ID okay remember it includes our seller ID and buyer ID this is why it's that mock so let's create our messages I'm going to close everything and let's open up message route and the controller we are going to create a new message so I will say host method of course we should be logged in I'll say verify token and create and one more is going to be a get method and we are going to fetch all messages of a conversation let's say get messages let's import them okay and create our functions messages okay firstly using our conversation ID easily we can find our messages and send them to users I will say const messages await message model I'm going to import I will say find and the conversation ID will be request params and ID and we are just gonna send it like that not about here I will say closed new message new message model and inside we are going to have a conversation ID it's going to be request body and conversation ID we are going to have a user ID it's going to be our ID like that and finally a description is going to be request body and description okay it's a comma and inside try catch by the way it should be in try catch of course I will say const State message wait new message and Save and after that then we send any message if we are the seller for example red buy seller will be true right by buyer will be false so I will say wait conversation I'm gonna import this and I will say find one and update I'm gonna pass here my condition it's gonna be ID equals request body and conversation ID and after finding here I'm gonna set create by seller is going to be true only if we are the seller read by buyer is going to be the opposite and finally the last message it will be request body and description and let's see if true okay we can send our message right now response status 200 or 201 send and save message let's try I'm gonna open up the message page and using this conversation ID we can fetch all our messages let's first get our ID I will say const ID from use params by the way it's messages it should be a message I'm sorry single message here like that and I'm gonna be using use Query and also query client that because we are going to add a new message let's say messages here and we are going to pass our ID the conversation ID let's import this by the way okay let's use it I'm going to cover these messages if it's loading if there's an error if it's not these messages I'm Gonna Leave only one item here and I'm gonna delete the rest like that I will say data dot map for each message called this item I'm gonna give the unique key message.id and I'm Gonna Change here message dot description okay we are going to patch our data by the way I didn't import this and new request let's see as you can see it's empty we don't have any message inside we have created the conversation but we didn't create any message inside let's create using this input to do that of course we are going to be using use mutation let's copy here and I'll say handle submit we are going to be using use notation let's import and we are going to take the message and make a request to the messages endpoint and we are going to pass our message and if it's successful we are going to refresh our messages and let's write here event current default because we are going to be using a form we don't want to refresh the page as you can see we have it right div here I can change this to a form and I can use on submit methods and handle submit and the button type will be submit when I click here is going to run this function okay remember what we are doing using event we can reach the first item and its value let's do that I'm going to pass here my message firstly conversation ID will be the ID comes from use params and the description will be event Target and the first item and after sanding when we write here anything when I click on this button it's gonna stay same but I will not delete here it's going to be empty again so I will take here and make it empty string let's check messages we are sending our message which is here okay I think everything is okay let's try I will say first message I'm gonna send and there's an error let's see oh there is a typo here in our controller okay here let's try again I'll say hi another error okay it says Capital user ID there is something wrong in our model no why they are capital let's try one more time and it's here okay awesome let's check the other user and as you can see we have our last message here and we didn't read this message if I click we are gonna read let's open up I will say hi and it's here by the way if we are the owner of this message remember we are changing the class name I will come here to message component and I'm gonna write here a condition for this item I will say if message dot user ID equals our user ID current user dot ID but we don't have current user let's create current user like that I'm gonna close here if IDs are equal it means we are the owner in this case it's going to be owner and item if it's not it's going to be only item okay awesome as you can see this is our message if I turn back to other user this is our message let's check here I will turn back when I write something as you can see it's here and one more thing related to our messages and conversations when I open up my orders as you can see I can contact with the seller or the buyer of this order so what they are gonna do here when I click here firstly we are gonna check the conversation we are gonna combine the seller and the buyer ID and using that combined ID we are going to check our conversation if it doesn't exist we are going to create a new one if it exists we are going to directly go to the chat page so let's open up the order page and for this image I'm gonna say on click and let's say handle contact let's create this const handle contact is going to be async and of course we are going to need our order that because we need the seller and the buyer ID so I'm gonna pass here the order and I'm going to take this order const ellar ID order dot seller ID and buyer ID so our conversation ID will be const ID equals seller ID plus buyer ID okay let's find our conversation I'll say const response weight I will say new request and it's going to be a get request we are not fetching data using use Query we don't need that I will say conversations and I will say find single one and I'm gonna pass the conversation ID let's make here Mac tick and I will say ID and after that we are going to check our response and data and if you check our controller let's say conversation controller we don't have any custom error here let's create I will say if there is no conversation we are gonna return next create error let's say 404 and I'll say not font okay using this error we can create a new conversation I forgot writing here try catch I'll say error and I'm gonna write here my condition I will say if error responds and status 404 it means we don't have our conversation so I'm gonna create a new one let's copy this I forgot this it's always going to be a post method conversations I can delete here and we are gonna send here remember we are sending only two I'll say true if current user is seller it's going to be buyer ID if it's not it's going to be seller ID and finally we can open the chat page it's going to return us our conversation and inside this response and data we have its ID conversation ID using use navigate hook we can open any new page I will say const navigate use Navigator let's use it I will see response data and ID of course before I will say message page and the conversation ID I can do the same thing for here if you don't have any error it means we already have this conversation we can drag the coder like that let's see by the way it's not going to be like that it's going to be equal let's try I hope everything is okay I will click as you can see it has created a new conversation let's check I'm gonna come here and as you can see we have a new conversation here by the way we can sort them by updated add date let's open up our controller conversation controller I will say sort created at I'm sorry it's going to be updated at and minus one of course inside an object and right now the latest message is here when I click that button I updated my conversation and right now it's here that's right something let's get back and it's here perfect so we have completed all our components but there is one more thing and it's the most important thing it's the payment when I click here we are going to open up the payment page and we are going to integrate the stripe to make payments I'm going to come here and close everything so I'm going to open up my menu and create a new page I will say pay pay.jsx and CSS and that's import okay so what I'm gonna do is when I click on this button I want to be navigated to pay page and when I open this page we are going to create an order immediately and we are going to see the card inputs we will enter our cart information credit card information and when we click on the pay button we are going to complete our order to do that we are going to be using stripe if you don't have any account just create one and after that you are going to go to dashboard.strike.com if you check here you are going to see that we have some API keys as you can see we are going to use this in our react application and this one for our backend server let's see how we are going to use it I'm going to open up documentation and get started and here we have two options we can create pre-built checkout page in this case when we click this button it's going to open up a stripe website and we are going to make the payment process there but I don't want to do that I want to make the payment in our website so I'm gonna choose custom payment flow in this case everything will be in our website and it's going to look more professional let's see what we are going to have firstly we should create a backend server we already have we are just going to create our endpoint we have our react application and we are just going to create this checkout form let's see in server.js what we are going to do firstly we should install stripe let's open up new terminal here I will say CT API yarn add stripe and after that as you can see there's a pause request here so we are gonna need this endpoint of course you can create another endpoint it doesn't matter for example if you remember we are creating our order in this way if you want to you can just use this endpoint but I just want to do everything from scratch if you are watching only this part of the video it's going to be easier for you so let's create this endpoint I'm going to open up or the route I'll say post create payment intent we should be verified of course and let's say intent I'm gonna create this function in my controller let's create here I'll say export const intent request response and next of course it's going to be async because we will create our order after creating this intent and firstly I'm gonna create my Strat variable but it uses common.js we cannot use import like that so I will come here and say import stripe front stripe and after that we should pass in our secret key if you remember we have secret key here I'm gonna copy this and I'm gonna come here and say const stripe Leaf stripe and I'm gonna pass in my secret key like that but if you remember we have an eme file we can use it I'm gonna come here and say stripe I can use it here I will say process eme and stripe of course if you make any changes there in emu file I recommend you to restart your application like that and after that as you can see we are going to create our payment intent using this stripe like that we can add here our product price you shouldn't take this from user like request by the amp price because user can change its price it's not secure so what I'm gonna do is adding here an ID is going to be our geek ID product ID and using this ID I'm going to fetch my product and I'm gonna use its price here so I will say const click find by ID I'll say request params and ID and I'm gonna get its price of course again I forgot wait here I'm gonna say geek dot price but make sure that you multiply this amount a hundred otherwise it's going to calculate with cents not dollars and this function is going to create payment intent id and also client secret and we are going to send this secret to our payment page you are going to understand better right now but before I want to create my order if you remember we have created our order here I'm gonna copy this and paste here after this I'm gonna delete this function we are not gonna be using this create Order anymore we are going to be using this endpoint it was just for test okay after saving my order I can finally send my payment intent client Secret so I will say response send and I'll say client script and it's going to be payment intent and as you can see there are many options here you can send whatever you want but we are gonna need client secret let's say 200 here and right now I can change here it was just a random text I'm gonna use payment intent and I will take its ID okay right now I can delete here like that okay it's ready I'm gonna open up my app.js let's actually come here it starts from here and as you can see we are gonna need those libraries for the react application I'm gonna copy let me make this bigger actually I'm going to open my terminal client-side and I will say yarn at react strap let's copy them and I'm gonna paste here I'm gonna import and it says firstly log your Skype promise using our public key remember it's here we are going to use this and it says make sure to call this outside of the component I'm gonna copy this and paste here you don't have to hide this key it's not a secret key and after that as you can see we are going to create a use state and after making our API request remember it returns us this client secret and we are gonna set our client secret here I'm gonna import at the beginning it's empty and as soon as we open this page we are gonna make API request I will say user facts empty dependency and let's write our request function I will say const make request it will be a async function try catch if there is an error just console log for now and I will say called response wait new request remember it comes from here we are using axios let's import this like that and it's going to be a post method and remember our endpoint orders create payment intent and also we are going to pass our gig ID because we are going to need its price how we are gonna get this we can use we are ground or don't use params remember how we are doing this I will say ID use params let's import this via crowded on and we are going to take this ID and use it here by the way it's going to be in the outside of this try block okay let me shrink this and I'm gonna call this function here and after that finally we can update this client script I'll say set client script is going to be response data and client Secret and stripe is going to check our client script if everything is okay it's gonna provide us some inputs that we can enter our card information to do that we are going to be using stripe elements and we can pass here any stripe team after this payment process we can check what kind of teams it has but for now it can stay like that let's write it here and let's use react payment elements did I import or not okay it's here I'm gonna copy here I will say if there is a client secret you can show this checkout form we don't have yet let's give here class name and I'm gonna create your new component checkout form jsx let's create our function let's import this here okay and inside this form let's see what we are gonna add I'm gonna copy them actually let's copy here like that we are gonna use stripe and use elements and we are going to need some new States we can take the customer email if there is any error we can show this message and if it's looting we can disable our buttons like that and in this use effect basically we are going to listen our user actions and when the user enters his card information and clicks the pay button we are going to have some options here it can be successful still processing payment was not successful or there is something wrong with stripe servers in all those cases we are going to set our message and here in our HTML we can show these two users let's copy this use effect here it takes our client secret that we have sent and listen our actions let's create here our elements is going to be a form we are going to change its style later basically it's going to show the card information inputs and then we click on this submit button it's going to run this function let's create and we'll submit let's see actually let's directly copy this and I'm going to explain one by one okay basically when I click on this button firstly it's gonna check whether the strap loaded or not if it's not it's just gonna return it's not gonna do anything and if it's looted we are gonna start our process firstly we are going to set our loading state is going to be true in this case we can show here this spinner as you can see if it's looting show this spinner if it's not right here pay now and after that stripe is gonna confirm our payment and if there is an error it's gonna set our messages and it's going to show what kind of error it is and if everything is okay we are going to be redirected to this URL of course I'm Gonna Change here it's gonna be our port number and success page we don't have yet but we are going to create let's actually create I will say success and our function like that and let's open up our app.js those are our Pages I'm going to add two more page here first one will be pay I'm gonna add here pay page and success page okay I'm gonna close everything let's open up our react application and when I click on this button using this gig ID I'm gonna open my pay page let's do that I will say gig page and for this button I'm gonna wrap this space link react rather dump link I'll say two pay and the geek ID remember we have our gig ID we can use it like that and let's see I'm gonna click oops there is something wrong app.js because we have a parameter here I forgot adding here a parameter like that and as you can see it's loading this payment form and using this form we are going to complete our order if you check the mongodb and in orders as you can see this is our previous order I can delete this and this is our order as you can see we have this ID and also is completed is false let's write here any email here and fake card number it's for test you can write here any month and year let's say 25 any three numbers country and you can save your cards and I'm gonna pay now let's add here any zip number I will pay and as you can see we are in the success page right now and it includes this payment intent using this number we can update our order it was false and we can turn this to true and we can complete our payment process if you check out your balance here and this is our balance if you check your payments you are gonna see this price it's 59 we have here our intent number and customer email and after the strap Commission this is our balance it works like that so let's take this payment intent and update our order I'm going to open up success page and let's say payment successful you are being redirected to the orders page please do not close your page something like that let's say you are being redirected and after this message we can update our order using use navigate Rook we can be redirected to the orders page navigate use Navigator and also we are gonna need this query to do that we are going to be using react router Dom use location hook I will say const use location if you remember the search string gives us our query search so we are going to take this part but we need only this section to do that we can use URL search params I'll say const params new URL search prompts and I'm gonna pass here my search query after this we can take whatever we want we can take this payment intent we can take this intent client scripts redirect status whatever you want any query here but we are gonna need only payment intent I will say const payment intent it's going to be params get a payment intact let's create a use effect I'll say const make request is going to be an async function I'll say try catch block and I will say await new request and it's going to be a put request remember we are updating I will say orders and we are going to pass here our payment intent so using this ID we are going to search for our order and we are going to update this is completed field it's going to be true if it's successful we can be navigated to orders but I just want to wait let's say five seconds so I can use set timeout like that and I'm gonna say five thousand milliseconds which is 5 Seconds okay let's call this function here so when we open this success page it's going to run this use effect immediately let's check our end point here we don't have any put methods let's create I will say put I'm gonna delete here we should be verified and let's say confirm let's create I'm going to come here Order controller I'm going to create one more function it's going to be confirm and I'm gonna say await order find one and update and I'm gonna write here my condition and it's going to be payment intent equals request body and payment intent and after finding I can update my order I'll say set and is completed field will be true of course it should be in an object like that and let's send any message here order has been confirmed let's see I'm gonna refresh after five seconds as you can see we are here and this is our order awesome it works like that guys if you want to learn more advanced version of payments you can check the documentation by the way stripe documentation is one of my favorite documentations you can find anything you want they didn't miss any points they explained every little detail you can find any other Solutions like sending a physical product for example or subscription or installments whatever you want okay and we didn't add here any functionality let's create I'm gonna close everything here and I'm gonna open up to featured component and we have a search button here and using this input we can store our text let's create here use State I'll save const input set input view state and I'll say on change set input event Target and value and after that let me click on this button let's say on click I'll say handle click or submit let's create this const handle submit we are going to be navigated to gigs page but we are going to add our query here into URL so let's use use Navigator I will just copy and import and I will say navigate gigs and remember our query will be search and it's going to be this input like that let's try let's see first okay I'm gonna search for Geek 2 for example I will say geek 2 I will search and as you can see it's here awesome and by the way one more thing and it's the last thing that sign in I will say seller seller and here we are gonna list our Geeks and also we will be able to delete them or using this button and those inputs we will be able to create a new gig let's do that quickly so let's come here open up my Geeks page I'm gonna get the current user by the way if you don't want to write the same thing again and again you can basically create here let's say get current user accounts get current user it's just gonna return local storage current user let's export this okay I can use it here like that and we are going to fetch our gigs here let's delete those items we are gonna need only one let's open up here for example we are going to be using use Query hook and as you can see we have an action here we are going to mutate our items so let's open the reviews we are going to need query client and mutation actually let's copy here and paste I'm gonna import them quickly use mutation use Query and query client from react query new request from our axios instance okay but we are gonna fetch we are gonna fetch our Geeks let's say my Geeks and remember we can pass here any query and user ID will be the current user ID and after that we are going to pass here the gig ID and using this gig ID we can delete our gig and I'm going to pass you this ID we are not going to pass anything in the body is going to be parameter and he's gonna invalidate my gigs let's handle this on click handle delete of course we are going to pass our item id here so we have to use this data first I'm gonna wrap my container I will say if it's loading and if there's an error like that by the way why here is like that it's going to be only kicks and we don't have handle delete we are going to handle that but before let's use our array here I'm gonna wrap this and I will see data dot Mac for each gig we are going to return this TR IA gonna need a unique key dot ID it's gonna be keep cover kick title uh price and its sales number right now we can pass here our gig ID like that let's create this function I'm going to take the ID here and I'm going to use rotation mutate and I'm going to pass my ID that's all let's see okay we don't have any geek we can basically log out and log in as other user or before that we can handle this add new gig page so we can add our new gigs after that we can fetch let's do it like that I'm going to open up at and right now instead of creating use state we are going to be using use reducer that because we have many inputs here and I want to change these features we are going to have only one input here and I'm going to add here a button when I write something and click on that button it's going to add new features so we can add infinite features like that and there is a select here of course we can use use state but it's going to be a little bit complex in this case I recommend you to use use reducer let's create here new folder I will say reducers is going to be kick reducer before that I recommend you to watch my use reducer video before starting if you don't know anything about user reducer it's going to be really helpful and in this video I'm not gonna Deep dive into it it's going to be in the cut on the top right you can check it and firstly we are gonna need an initial State let me paste this as you can see yeah I'm gonna have a user ID and we are going to take it from local storage and I wrote here every fields that we have for the geek and using geek reducer we are going to update this date let's say export const geek reducer is going to be State and action we are going to be using switch case and we are going to check our action types in the first case will be change input basically we are going to change all these text inputs using this action I will say here return I'm gonna return the state but I'm going to change my inputs remember how we are doing this I will say action payload add name is gonna be action payload and value so we can update most of our inputs like that but we have image here and those images so we can update them let's say add images so color image will be action payload cover and one more is going to be images and what else as I said we are going to add our features using a button let's create another case I'll say add feature I'll say features I'm Gonna Leave the previous features let's say state DOT features and I'm gonna add a new one and it's going to be action.pay Dot and also we can delete any of those features let's say remove and in this case we are going to filter our features array and it's going to be a filter we are going to check each feature and we are going to have filter it's not going to be our action payload thank you basically it's gonna keep each element except of this one and by default it's going to be returned state okay it's ready let's open up our ad page and call our state I'll say const use reducer from react and I'm gonna pass here my geek reducer and its initial state let's import them like that let me check okay export export okay so we are going to take the state and dispatch so we can dispatch our actions using this function and what I'm gonna do I'm gonna need some use States for my images that because we are going to store our images and we are gonna send them to upload.js remember it uploads our images into cloudinary and sent us a URL what can I do I can add here a button that we can upload images let's say const single file or cover file whatever you say use state at the beginning that's a undefined and one more and it's going to be an empty array and it will be files set files and I'm going to add far more use state and it's going to track our uploading process at the beginning it's going to be false when we start uploading it will be true in this case we can disable our create button we have to wait time first after we can submit and let's check our inputs it's going to be category this name is important remember we are using them here let's say on change handle change for this title I will add here a name I'm going to leave them description name will be description short description sorry it's a short title and the other one is short description on change delivery time and revision number let's delete those we are going to need only one and this price okay using this handle change method let's say const handle change event and using this dispatch we are gonna pass our event Target name and value I will say dispatch I'm gonna add here an object and it includes our action type is going to be what was the name change input and the payload name will be event Target and name value will be human target and value and our reducer is going to take this payload and update our state I'm going to create one more function and it's going to be handle feature let's check add feature let's leave this empty for now and let's scroll down so I'm gonna add here a form and it's going to cover this input and also I'm going to add here a button and let's say add like that and on submit it's going to be handle feature let's say type submit so when I click on this button we are going to take this input value and add it to our payload let's do that payload will be event Target and the first Target remember it's a form and the first child is input and after adding I want to make this input value and empty string by the way I should say event prevent default otherwise it's going to refresh the page and what does we should handle our uploads let's say handled uploads I'm gonna delete everything it's going to be a little bit long but first let's add our files single file and these multiple files I will come here and say on change event set single file event Target files and I'm gonna take only one file I will copy this and paste here as you can see it's multiple so in this case it's going to be only files and let's say set files okay we have our files right now we can use uploads file function and take our URLs in this case it's going to be async and remember we have set uploading you state here it transforms when we start this process it's gonna be true after that we can right here try catch block and start our process that's a console log I'm going to say const color cover picture URL it's gonna be await upload let's check what was the name okay upload let's import this like that I'm gonna pass here my single file and we are going to upload multiple images to do that we can use promise all I'll say prompt images wait promise all we are doing this that because we are gonna need multiple async function I will say take the files array but there is something important here let me show you console log files and I'm gonna choose three images here and as you can see it's not an array it's a file list to transform this to array I'm going to be using this methods I'm gonna wrap this and spread my file list in this case it's going to be an array we are doing this that because we cannot apply map function for file lists it's going to be JavaScript list so I will say files and use map and for each file comes URL is going to be await upload and we are going to pass this file and finally of course it's going to be async and it's going to be curly brackets like that and we are going to return this URL basically for each file we are going to get URL and This Promise is gonna take those URLs and make an array and it's going to be our images after this process finally we can say set uploading false we can finally create a new gig and let's say dispatch type not plus the name add images and payload will be cover and images it means cover equals color images equals images but if they have the same name you don't need that we can leave it like this I'm gonna take this and create a button actually I can create here let's say images div I'm gonna wrap here and one more images inputs and next to them I'm gonna create a button and let's say upload actually we can write here a condition it is uploading what was in him okay only uploading it's gonna be loading if it's not right here upload let's see okay it's here let's give a style add CSS and I'm gonna come here and say images I'll say display flex and an item Center I'm going to give gap between them like this and input section will be display flex but Flex Direction column let's do that images inputs black extraction column and let's say cap to any okay perfect and for here after this button I'll say at what was the name this class name let's check okay I didn't give any let's say class name is going to be at and I will say display Flex justify content space between and input size will be a hundred percent or I can decrease let's say eight percent okay it's much better and when I add here an item we are gonna create some small buttons that we can see are features let's come here after this form I will say edit features and let's create a div it's going to be a single item and I'm gonna add here a button it's going to show our feature and also I want to add a span here and it's going to be X basically when we click on this button we are going to delete our feature using this reducer okay let's give a style I will say added features display Flags Gap 20 a button let's say hi 30 I'm going to decrease font size and font rate let's say background color transparent we are not gonna see right now let's change its color let's say red and I'm going to add a border pixel solid and red and Border radius that's it 10. or I can delete this border okay it's better let's enter everything inside display Flags align item Center and let's give gap between this text and X okay it looks nice right now we can give our functionalities instead of this text we can take it from our state so I'm gonna wrap here and I will see State features of course I should use question mark here because they can be empty and I'll say map and for each feature we are gonna see this item we need a unique key it's going to be f and after that when I click on this button let's say or click event I'm gonna dispatch my action let's say dispatch type will be let's check I'm gonna close here by the way remove feature and the payload will be our feature so I will say F and instead of this text we can show our feature let's see as you can see it's empty we don't have any but when I click here we are going to add this feature did we handle this or not okay we did let's try test I'm gonna add okay there is something wrong oh I said feature is going to be features State features okay let's see okay second awesome if I click here it's removing this is what we expected perfect and let's try to upload some images I'm gonna come here take this handle upload where is our button here I will say on click it's going to be handle upload let's see I'm going to open my console it says stripe should use https but we are just testing it's not a problem I'm gonna choose my image here and those images I will say upload of course I didn't write any console log here let's say state and as you can see you have our cover picture and inside images we have two pictures it works if I give any price here as you can see it's updating like that if I add any features let's click here awesome another one perfect basically we have everything we need right now by clicking this button we can submit our information to database so let's say handle submit events prevent default and we are going to be using mutation let's open up previews I will copy this let's paste here we don't need use Query I will say use Query client use notation and new request I'm going to import them and we are going to make requests to gigs endpoint is going to be a post method I'll see geek and it's going to emulate my kicks actually we don't have to write here but after adding a new gig we are going to be redirected to my gigs page let's create here use navigate okay let's use this mutation I'm going to pass here my state and right after that we can be navigated to the Geeks page my Geeks okay I hope everything is okay let's see I'll say from react animation let's choose this one upload images let's say upload I will say description from react short from react I'm gonna add features and price let's create nothing happened that because we didn't use this function let's find out our create button and I'll say one click and before this navigation let's see if everything is okay or not thank you I'll open my console and let's check our Network here I will create and as you can see it has created our new gig and this is its ID okay awesome so that's all I think of course it's the basic version of Fiverr but you can add many features here we just covered most of the features we can fetch data we can filter Geeks we can create an order we can make our payments we can see our gigs we can add new one orders messages I think it was a great project to improve your man's Tech skills if you want to see more features just let me know in the comments and that's all if you learned something new today please like the video and don't forget to follow namade's social media accounts and let me know in the comments what kind of projects you want to see in the next tutorials I hope I will see you in the next video goodbye
Info
Channel: Lama Dev
Views: 122,644
Rating: undefined out of 5
Keywords: react, react tutorial, react project, react course, react mern, react application, node.js, mongodb, react query, tanstack, usemutation, express server, mern, mern project, mern course, react hooks, jwt, web design, web application, react website, cookies, react real world projects, react node mongo, full stack app, Fiverr clone, lama dev
Id: csUM7yfiaMw
Channel Id: undefined
Length: 268min 5sec (16085 seconds)
Published: Wed Feb 22 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.