React Node.js Real Estate App Full Tutorial | MERN Stack App & Real-time Chat

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hello friends today we are going to complete the full stack real estate application using react and not. js on the homepage we have a search bar where we can write the location and the price range when I click here it's going to patch all these data from the database based on our search query here we have a filter where we can change the options on the right side we have a map component displaying the locations of these items we can navigate this map or zoom in when I click on any item it's going to show the short information of that place if you want to see the details you can click here or select from the list on the single page we have all the information and the location and we can view larger images by using this slider and to send a message to the owner or save the place we have to be logged in first when I click here it's going redirect me to the login page if you don't have an account you can create one using the registration page let's login if you don't write the correct credentials it's going to show this error and after the login process you can save the place let's see the profile page I can log out or change the user information we have an upload widget here I can drag and drop any image write an image address or choose any story provider let's choose from the computer and update our user information here we have our posts and saved posts let's create a new one we have a text editor here so we can change the description style I'll add the other information for the posts we can choose multiple images when I click here it's going to create the post and open the post page as you realize we have a notification here and that means we have a message when I click on that message it's going to remove the notification and show the chat component this component allows us to send realtime messages when I send a text the receiver will see that immediately to do that we are going to be using socket iio so you will learn how to send real time events using socket connections you'll also learn many different react Concepts to fetch data we will not use an additional Library we will create a loader function and use it in the react router when we visit this page it's going to automatically fatch the data like a server component moreover we can use react suspense to show a loading indicator for the back end we will create our own API from scratch and use Prisma for the database operations for this project I used mongod DB but thanks to Prisma you can use any database Pro provider you want without changing the query methods for the authentication we'll be using Json web token to encrypt our cookies and after we will be able to verify the user authorization for each request it's a great project to understand react and not JS and start creating your own full stack applications of course it's not possible to handle all the features in one video so if you are interested in mastering react you can join the react Master course waight list okay if you are ready let's get started okay I created a new folder here and inside this folder I will create my backand server but before that let me show you my vs code extensions during this tutorial we are going to need two important extensions you don't have to use them but they are going to make everything much easier the first one is console ninja it basically allows us to see our console log outputs on the vs code so we don't have to use our console or any browser and since we are creating an API it will be easier to see our requests and responses you can use this feature for free but I want to give a pro membership to some of my subscribers so you can check its testing and debugging features as well I will randomly select 10 people and send them the Code and the second one will be Prisma in this tutorial we are going to be using Prisma om for creating database fetching data adding new data so using this extension it will be easier to create our models and the types okay let's close here and open up our folder and inside this folder let's create our API and after that I will create one more folder and it's going to be our react application we have already created our react app in the previous tutorial so we are just going to download our design here but before let's take care of our API firstly I'm going to create my main Javascript file let's say app.js it's going to be the file that we are going to run our Express app of course before creating anything we are going to need not JS to do that I'm going to open up my terminal and my folder and I will say mpm in it Dy and enter as you can see right now there is a package Json and in this file we can see all our dependencies scripts and configurations in our project we are going to be using module types so I'm going to come here and say type and it's going to be module basically when we install any library or when we try to import any function we will be able to use import a from P structure if you don't use module you have to import your files or functions like that const a require and B we don't want to do that we are going to be using import export and right now we are going to create our first dependency and it's going to be expressjs let's say mpm install express our library folder is here right now let's create our app I'll say import Express from Express to create our app I will say const app and express function and that's all our app is ready of course to run this app we have to listen any port number you can give here any number I'm going to be using 880 and after a call back function and let's say console lock server is running okay we are ready to start our app to do that I will say not app.js and as you can see our server is running but if I make any changes here let's say console lock test and if I save as you can see nothing is happening because we just run our application once it's not actually listening every single changes here to prevent this you can use third party libraries like nodon just say mpm install nmon and after creating this Library you can say nmon app as and it's going to listen every changes in your app and it's going to restart your server each time but since we are using console ninja we don't need that I'm going to close here I'll write here console ninja note watch in this case it's going to listen our application our changes and the main file and as you can see our console outputs are here if I make any changes and save the file as you can see it restarting our app and our new output is here so we don't need this terminal anymore let me shrink this menu and let's create our first API end point for example when we visit Local Host and the port number and we will create our API endpoint and let's say test as you can see it doesn't return anything because we are not using this end point let's use it I will say app.use let's say test and when a user makes a request we'll be able to take that request and send a response let's send a text response send and it works let's try again I'm going to refresh and as you can see our output is here right now using our react application we can make some requests to our API let me show you the main structure of our application firstly we have our client side app let's say react app and also we have our backand server I will say Express API and we are going to send some requests from the react application and according to this request we are going to make our crit operations it can be adding new user patching posts deleting user information or whatever it might be to do that we are going to need a database we going to have here mongodb database but we are not going to send our requests directly instead we are going to be using Prisma orm because if you want to use any other database provider you can do it easily using Prisma so when we try to make any database operation firstly we are going to use Prisma and it's going to create the required query get the information from the mongod DB take it back and send it to the backand server so this process will be our cruit operations so let's take a look at our mongodb table and I'm going to create here my table and inside this table firstly we are going to have the user collection and each user should have a unique ID it's going to be a string and it's going to identify our user basically I'm going to write here the primary key of course we are not using a relational database but anyway we are going to connect our collections using their IDs and we are going to have the username email AAR and the created at date and its type will be date so let's do the same thing for the posts we are going to have a post collection again each post has an ID and I'm going to delete here and paste my data but remember in the single post page we are going to need more information so instead of writing all the detail inside this post collection we can create a new one the post detail and also as a user we can save any post we want to do that we can create one more collection and it's going to be saved posts we should store the user ID and the post ID and if we want to send a message to other user we need to create a chat collection and inside these user IDs and seen by IDs arrays we are going to store our user IDs and each chat collection has multiple messages let's create our model and let's take care of the relations each user can have a multiple post so we can use here our primary key and the relationship is one to many and each post will have a post detail just like that and a single user can save multiple post and each post can be saved multiple times and finally a single user can have multiple chats and inside chat we can have multiple messages this is our main structure let's move this here database table and using these models and relationships we can fetch our data and send it to our API and we can send them as a response so this is the main structure of our application but of course we shouldn't send response for every request for example when a user tries to get another another users chat or tries to delete other users post we shouldn't let them to do that we should verify our user but we are going to handle this after the authentication we are going to separate our API endp points for example for the authentication we are going to be using the off endpoint and let's say register and after creating the user we will be able to login log out and then we want to create a post we are going to be using post endpoint and then we try to fetch all posts again it's going to be posts end point but this is going to be a post request and this is going to be a get request and when we try to fetch any single post we are going to pass here the post ID we are going to find that post in the database using this ID and send it to the user but as you can see using all these end points and functions in the appjs is not a good idea we are going to need a separate folder for this so I'm going to come here and create a new folder and it's going to be routes and the first route will be off Route another one user route post routes we are going to create some other routes but for now it can stay like that let's choose one of them it can be post and I'm going to call here Express rather const rather Express do rather that's import Express and and right now using this router I can create my requests for example router dot get method and let's write here test again request and response console log router works right now I can use my router inside the appjs to do that I'm going to export this export default and rouer let's use it here import rou from routes and post rout actually let's change this name post rout and right now I can use it here app.use and I'm going to write here my common endpoint which is API and when we visit posts we are going to call our post route let's say posts basically when we visit Local Host the port number API and posts it's going to visit our post route and if I say test it's going to run this function let's try API posts and test as you can see we are not returning anything and here router works this is how we create apis using Express if you want to make other requests you can just change here for example post requests when we update our items we are going to be using put request and when we remove our items from the database we are going to be using the delete request this is the main structure so right now we are ready to create our authentication requests I'll create my rouer and Export and right now we are going to need three end points the first one will be register login and log out and they all are going to be post requests because we are going to get add some information from the user for example here we are going to take the username email and password and we are going to create a new user and save it to the mongod DP and here again we are going to take the username and password and we are going to check the user so basically we are going to create some database functions so what I'm going to do is create here a new folder and it's going to be controllers let's create create our authentication controller and here I'm going to create my functions export const register request response and DB operations we are going to create a new user and two more is going to be login and log out right now I can use those functions in my route in this case we don't need those anymore for the first one I'm just going to call my register function login and log out and I will write here JS and that's all as you can see it's much simpler right now everything is easier to see we are just adding here our routes and we are going to handle everything in our controller let's test I will just say console lock register end point of course we have to use our route inside the appjs first so I will say off Route and I'm going to use it here API off and our route here okay let's test we are going to be using this end point and after this register end point as you can see cannot get because our request is POS let's change it for the test purpose I'm going to refresh as you can see we are not returning anything if I come here you are going to see that it works okay let's take this back and let's try to get some information from the user to do that we are going to need a form here but for now we are not using our react app in this case to test our API we are going to be using Postman if you don't have Postman just download it it's really easy to install and after that we are going to create a new collection for our API let's write here a title estate app and inside I'm going to create a new folder and it's going to be authentication let's create our first request I will say add request let's say register and I'm going to write here my API URL which is Local Host 8800 API off and register it's going to be a post method and right now we can pass here some user information I'm going to choose body row and we are going to be using Json object and here we can send any information we want for example username let's say John email at gmail.com and password let's write from 1 to six but how I'm going to reach to this data if you realize when we make request we are using the bud so we can reach it using request and bu let's try I'm going to send of course we don't have any response I'm going to cancel but if you check here as you can see our data is not here it's undefined the reason for that our application is not allowing us to send any Json object to provent this I have to say app use express and and Json in this case we can send our data I'm going to send cancel and our information is here so using this information we can create a new user so let's D structure our data here I'll say const username email and password from request and bu and firstly we have to Hash our password because we are sending here a plane text we shouldn't store this like that in our database and after hashing the password we are going to create a new user and save it to the database to do that we are going to need a library let's open up a new console here and I will say mpm install bcrypt let's import this here bcrypt from bcrypt so I will say const hash password bcrypt do has function and we are going to pass here our password that comes from the user you can write here any number so using that number is going to generate a new password so let's say 10 for example but as you realize it returns a promise that means our function is an async function our main function should be async in this case we are going to await our hash function and after that let's see what we are going to have I'm going to come back and send again and as you can see our password is not a plain text anymore instead we are going to be using this encrypted password so right now we have the username email and hashed password so we are ready to save this user to our database to do that we are going to be using Prisma so I will say mpm install Prisma let's see how to use it we are going to install our dependency and after that we have to initialize our Prisma and for the provider you can add any database you want in our project we are going to be using mongod DB let's come here and say mongodb as you can see there's a new folder here and inside we have our schema and our database provider is mongodb and here we are going to add our database URL as you can see it uses the EMV file if you open up you are going to see this example database of course we are not going to use it we are going to be using our own on mongodb URL let's get rid of here and open up mongod DP okay if you visit cloud. mongod db.com you are going to see this page of course you should be logged in first after the login process you can create your free cluster and choose here m0 you can give any cluster name you can choose any provider and create deployment it's going to take a while and during this process let's take care of our database access I'm going to click here let me zoom in by the way as you can see I already have a user here if you don't have just click here and create a new one and inside you are going to create a password and after creating your database user find the network access our list is empty in this case nobody is able to access our database you can add here your IP address or you can allow access from everywhere I'm going to choose this one but after deploying your application you have to write here your server address I will confirm and that's come back it's still deploying our changes during this process let's get our connection URL to do that I'm going to be using drivers we are using node.js our URL is here I'm going to copy this and paste it here this is my username for the password again and at the end of the URL you can add here any database table name let's say estate I'm going to save let's check it's ready to use so let's create our user model I'm going to close everything here and open up the schema and here I'm going to create my first model and it's going to be the user model and when we create a user we are going to have a user ID email username password we can have a user image let's say auter and the created at date and I'm going to write their types here our ID will be a string again string username password AAR will be our image URL in this case it's going to be string again and for the created ad date it's going to be a date time and right now we have to give some additional information firstly I will say this ID will be the unique ID of my user model and when we create a user by default it's going to generate an ID then we use a relational database you can leave it like that but if you are using mongodb you have to add here mapcore ID and DB object ID we are doing this because when we create a document Inside mongodb by default it creates ID using underscore basically we are going to connect this mongod DB ID with our model ID using map and after that we are going to have an email but be careful here it has to be unique every user has a different email and username it doesn't have to be unique I'm going to come here and add a question mark because it can be empty it's not required and for the created ad dat by default we are going to add the current date using the Now function I'm going to use up option shift f as you can see it looks much better right now and this is our first model so let's create a new user using this model and when we do that it's going to write it in our database let's try I'm going to open up my controller and I'm going to come here and say let's close here by the way con new user again await we are going to be using Prisma but we don't have the Prisma client let's create inside API I'll create a library folder and inside let's say Prisma JS import Prisma client from Prisma client let's import this first I'll say mpm install Prisma client let's write it here so I will say const Prisma new Prisma client and finally I can export this Prisma okay let's use it here right now I'm going to import don't forget writing here JavaScript and I'm going to call the user model and I will say create and I'm going to add here my data and it's going to be our username email and password but be careful we are not using this password we are going to be using this hash password let's add it here just like that let's see what's inside our new user console loog new user I'm going to come here and send a new request let's see and our user is here as you can see this is the random ID we don't have any image and this is the created ad date let's check our DB I'm going to browse Collections and as you can see our user is here okay right now I can send a response I'll say response status is going to be 2011 which is successfully created and I'm going to send a Json and let's send a message user created successfully of course we can an counter any error to catch that error we can use try catch block actually I'm going to wrap this password also because we are using a wait so I will say try I'm going to WRA my Asing functions and I will say catch if there is an error I'm going to console lock and I'm going to send an error message let's say status 500 Json and I'm going to send a message and it will say failed to create user and that's all let's try again if I send again user created successfully but there is a problem here again it has created but our username and email is not unique that means our schema is not working that because we didn't save our changes so whenever you make any changes on your Prisma schema you have to open your terminal and write here MPX Prisma DB and push okay if you have an error here here make sure that you cleared your database actually I'm going to delete this too okay my database is empty right now I'm going to run again perfect let's try to add new user perfect and if I try again as you can see there is an error there is a Prisma error and it says user email is not unique okay perfect let's close here and this menu and let's take care of the login again I'm going to take the username and password from the user const username password it comes from request and Buddy and after after that let's write our steps firstly I'm going to check if the user exists or not if the user exists if not we are going to return an error and if everything is okay we are going to check our user password if the password is correct and if the password is correct finally we are going to generate a cookie token and send it to the user and send to the user okay these are our steps let's right here try catch block if there is an error console log and send a response status 500 Json message fail to login here is going to be error and let's try to find the user first I will say const user await I'm going to call Prisma and my user model and I will say find unique because we are searching for only one user and I'm going to pass here my condition I'll say where the username equals username that comes from the client and since we are using the same name I don't have to pass this here I can use it like that as you can see there is an error because we didn't write here AC sync okay it's going to find our user if it doesn't exist if there is no user I'm going to return a response status for off for and Json let's say user not found but returning this message is not a good idea because we shouldn't let the people know that this user doesn't exist in our database it's better to write here 401 which is not allowed and inv valid credentials okay and what about if there is a user right now we are going to check our password remember we are storing here our encrypted password so we are going to take it and compare with this password to do that we are going to be using bcrypt compare method let's say const is password valid and I will say await bcrypt compare and we are going to pass here our user password and we are going to compare this the password inside our database remember we have a user here so we can use its password and again another condition I'll will say if password is not valid again we are to return an error it's going to be 401 and invalid credentials and finally if everything is okay we are going to generate a cookie token we are going to be using JWT but before let me show you how to set cookies I will say response set header and we are going to set cookie and I'm going to write here the cookie name let's say test and pass here any value let's say my value let's see what's going to happen I'm going to come here and create a new request and it's going to be login right now I have to write my API URL again but we are going to create many requests here so we shouldn't write this is again and again to prevent this I'm going to come here I will say edit and variables let's add a new variable and it's going to be base URL and it's going to be Local Host the port number API and I'm going to copy this and paste here and I'm going to save right now I will use curly bracket and as you can see our variable is here and after I'm going to write my login end point so I can do the same thing here by the way I forgot off let's add it here okay so I don't need here anymore I'm going to be using my URL okay let's come here again and send our user credentials I will say username John and password let's change this username it doesn't exist I'm going to make this a post request and sent as you can see our credentials are not correct if I make this John part change here again it's not correct and if I write the correct credentials as you can see we are not sending any response let's say success and try again okay as you can see there's a cookie here if I click you can see that my cookie name and its value this is how we are setting cookies normally but writing this like that is a little bit confusing because we are going to be using our JWT object and also when we try to read our cookie it's going to be harder to prent this we are going to need a new library so I will say mpm install cookie parer let's open up our appjs and import it cookie parer chome cookie parer let's use it here app.use and cookie passer okay right now it's much easier to set and read our cookies so instead of this I will say response cookie let's say test two and I'm going to pass here whatever I want and I can write here any options to provide a security I can say HTTP only in this case client side JavaScript cannot access our cookie and also I can write here secure true but in this case our connection has to be https connection but we are using Local Host so we cannot use it for now but in the production mode make sure that the Ure is true okay after that let's send status 200 Json login successful let's try I'm going to send our cookie is here and HTTP only secure is false and as you can see it expired is whenever we close our session to prevent this you can give here any H let's say Max H and let's make this one week let's actually write here const H and 1 millisecond multip by 60 which means a minute an hour a day and 7 Days let's use it it here okay let's try again I'm going to sent as you can see it ends after one week so right now instead of this test let's create a Json web token to do that we are going to be using Json web token Library mpm install Json web token let's import it I will say JWT from Json web token let's create our token JWT the sign function and we are going to pass here our user information you can send anything you want I want to send user id user. id remember we are patching our user from the database we can use its ID and store it inside our token of course it's not going to be visible we have to Hash this to do that we are going to be using a secret key you can write here any script key you want but again we are going to be using our EMV file and let's write here JWT secret key if you want to generate a secret key you can write on your terminal open SSL random base 64 and 32 as you can see there is a random generated password I'm going to use it here and let's use our secret key here I'm going to delete this and I will say process EMV and JWT secret key if I do that it's not going to work because not JZ doesn't know if it's an EMV file or not to prevent any possible error you can install EMV library but we don't have to do that there's an easier way I'm going to terminate my terminal here if you remember let me close this menu we were using console ninja noes and our app name and also I'm going to provide here my EMV file writing EMV file and I'm going to pass here the path of my EMV it's going to be in this folder so I will just say dot EMV and if you are not using console ninja if you are using not modon it's exactly the same when you start your application just add this EMV file flag okay I'm going to start and right now I can use my EMV file let's try again I can use this maximum H let's move this here and after this key I will say expires in h so after one week we won't be able to use this token it's going to be expired okay let's send this token the cookie name will be token and I'm going to pass my token here let's see I'm going to send and as you can see this is our encrypted token and inside this token we have the user ID so right now when user makes a request we can take this user token and we can decrypt that and take the user ID so when a user tries to delete a post we can check if the post belongs to them or not if the user ID is different we can send an error this is the idea so what about log out how we can delete our token it's really easy I will just come here and I will say response clear cookie and the cookie name and I'm going to send a status let's say 200 and Json message log out [Music] inside a cookie and whenever we make a request we are going to send this cookie to our API and inside our API we can decrypt this cookie and check our user information and using that information we can intercept our requests so basically we are going to have some routes and some of those routes will be protected to do that we are going to be using a middle where so when a user makes a request we are going to take that cookie and we are going to verify our user I said protected routes because when we try to fetch some posts or a single post we are not going to run this middleware everyone is allowed to fetch that data but if a user user tries to delete some other users post or chat firstly we are going to verify our Json web token and if it's not the correct user we are going to directly return an error in this case we will not make any unnecessary database request and also inside our react application we are going to have some protected Pages inside app we are going to have our Pages or let's say routes and some pages are protected and the others are the normal routes so here is going to be layout and here is going to be protected layout so if we are not logged in we are not going to see the pages inside this layout now which Pages we are going to have here we are going to have have the user profile page user update page and add new post page so if we are not logged in we are not going to see these pages but even if we are not logged in we can see the homepage the list page the single page login and the register page so after the login process we are going to save our user and to reach these Pages we are going to verify our user first so this is our authentication structure so I'm going to close everything here and open up my GitHub repository if you remember in the previous tutorial we have created a react design and right now I'm going to download this project remember we we have two branches I'm going to download this completed version let's come back open up our terminal let's open up our client folder CD client and I'm going to download this project let's copy our URL so I will say kit clone single branch and the branch name which is completed I'm going to paste my URL Dot and enter let's see I'm going to close here and inside the client folder as you can see this is our react app but we don't have our libraries let's install mpm install and it's here let's start mpm run Dev let's use this URL and our app is here let's visit our register page as you can see we have username email and password inputs so using this form I'm going to send my data to express API but how I'm going to reach these data let's open up our component Source folder routes register and register file let's close here and in this form I'm going to create an event and it's going to be on submit event let's create a function handle submit and I'm going to call it here after react 19 we are not going to use on submit event we are going to directly call our action but it's still on better you cannot use it on production it will probably come out this summer but anyway when react 19 comes out we can update our project easily instead of this unsubmit we are just going to use action and we will be able to use use form State and use form status hooks but for now let's stick to the react 18 okay as you can see we have name email and password inputs use using those names I can reach my input data to do that I'm going to create a form data const form data new form data and I'm going to pass here my event Target basically this represents our form and since we are using form data we will be able to use our inputs and using their names we can reach their values let's do that I will say const username form data doget and username I will do the same thing for others email and password let's see if everything is okay or not I'll say console lock username email and password let's write here something John John gmail.com and and from 1 to six I will register as you can see it refreshes our page to prevent this I will come here and say event prevent default so it's not going to refresh our page by the way as you can see our inputs are here so we have our data it means we are ready to send them to our database to make a request to our API we are going to need a library called axos so I will say mpm install axios let's use it here I'll say const response await we are making a request so don't forget to add here async I'm going to be using axos and we are making a post request Quest remember our URL Local Host our port number API authentication and register and we are going to pass our data username email and password let's import axos okay it's not coming import axos from axos of course we can have some error so I'm going to erupt this with try and catch if there is an error console lock and also I'm going to show this error somewhere here after this button in this case we are going to need a use State const error set error and use State hook and at the beginning it's going to be an empty string if there is an error we are going to set our state but I'm going to do this later let's first check if our request is working or not I will just console look response. data if everything is okay it's going to run here if not it's going to run this error let's see I'm going to write credentials and P password here I will register and as you can see there is an error because I forgot HTTP here let's try again and this time we have a network error that because we don't let any client side application to reach our API let's open up our appjs and here we are going to need another Library that's let's open up our terminal let's create a new one I'm going to open my API and I will say mpm install course let's call it here car from course and here I'm going to write my middleware I'll will say use we are going to be using the course library and we can and pass here our client site URL remember it's Local Host 5173 I'm going to copy this and paste it here but also we can use it in our EMV file let's say client URL because when we deploy our application we are going to change here and let's use it here process EMV and client URL and also I'm going to pass here credentials because remember we are going to be using cookies it's going to allow us to send our cookie to client site let's see again I will register and we have an error because remember we already have this user let's create other one I will say John 5 five from 1 to six our register and right now user created successfully and right now instead of this console log we can redirect our user to to login page to do that we are going to be using react rather and use navigate hook I'll say const navigate use navigate and using this hook we can send our user to the login page and if there is an error we are going to set our state and pass here error response data do message and I will say if there is an error show it here let's create a span and I'm going to show my error here let's see I'm going to try to add exactly the same user fail to create user if I create something else let's say six as you can see we are on the login page of course our password is to week from one to to six but anyway we are just testing so what about the login page we are going to do exactly the same thing but after getting the user information we are going to store it in our browser let's do that I'm going to open up my login page it will do exactly the same thing here I will copy and paste them here let's import them just like that and on submit event handle submit and now we have just username and password and again I will say if there is an error show it inside the span by the way you can give here any requirement like required minimum or maximum character let's say three maximum let's say 20 and here is going to be required also and one more thing we can do here after clicking here I can disable my button because we should wait until we get the response from the API so I'm going to create one more use State here and it's going to be is loading at the beginning it's going to be false when we start our submit event it's going to be true and finally if there's an error or if it's successful it's going to be false again so let's right right here our Condition it's going to be disabled if is loading right now I can change my end point but as you can see this URL is too long and we are going to make a lot of requests so instead of writing this again and again I can create my base URL and I can use only this ending part if you remember we have a library here let's create a new file API request. JS so let's create our function API request we are going to be using axos I will say create I'm going to pass here my base URL HTTP Local Host port number and API and we are going to be us using cookies all the time so I will say with credentials and it's going to be true so let's export this export default API request okay let's use it here okay I can't import we don't need this anymore I will say API request from library and API request in this case we don't need this long URL anymore we are just going to be using off and register of course it's going to be login and we are going to pass our user name and password we don't need this email and if everything is okay we are going to have the user information let's comment this out for now by the way I will do exactly the same thing for register API request post and end point finally set is loading false of course we don't have this yet let's create just like that and we are going to disable our button is loading okay so let's see what we have inside our response I'm going to send my data John and my password oops it's the wrong one I think let's try as you can see from 1 to six of course we should remove this error after clicking here I'm going to close this menu by the way we have our data here as you can see data message is login successful before that let me set my error and it's going to be an empty string again let's do the same thing here okay right now if I click it's going to remove that and our login process is successful as you can see our data is here but instead of sending this message I want to send my user information let's open up our controller and here in the login instead of sending this message I'm going to send my user information but be careful as you can see it includes our password also but we don't want to send this we are just going to be sending our ID email and username so I need to eliminate this password to do that I will come here and say const we are going to take the information from our user remember this user comes from the database and I will say take the password and all the other information User info I can directly send this user info right now just like that but remember we have used here password so it shouldn't be exactly the same name so I can give here any other name let's say user password okay let's see right now I'm going to send as you can see we have disabled our button and it changed its style and if I check here you can see that inside data we have ID username AAR and created at right now I can save this data to my local storage but don't worry when we make any request we are not going to be using that storage it's just going to show our username and Avatar here when we try to add new post or delete any post we are going to be using our cookie so our application will be secure so I can delete this right now and I will say local storage set item user and I'm going to send my response data but if you are using local storage you have to send a string you cannot send object to do that I'm going to be using Json stringify and pass here my data response. data and after that finally I can redirect my user to the homepage let's see I'm going to open up my console and choose here application and inside cookies as you can see we have the token actually let's clear here and also local storage clear and I'm going to send again as you can see our user is here we have all the information and also we have our cookie this token to show our user information here we can use the local storage and when we make any request we can use this token it's that easy so what about log out we don't have any log out button here inside our profile I can actually add it somewhere here let's open up our profile page I'm going to close everything here open up profile page if you remember we have our user information here after this username email I can create a button here let's see okay I can give a style let's open up our profile page inside information we have span and after those spans I'm going to choose my button let's give it with I'm going to change the background color and I'm going to delete the Border let's give a padding and change this color maybe too much okay and also I'm going to give csor pointer and maybe border radius okay perfect so when I click on this button I'm going to make a request to API and delete my cookie and also clear my storage let's do that I will say on click event handle logout let's close here const andle log out async and try catch if there is an error show it here and I'll will say const response API request again post request and the end point is log out let's import this Library API request okay and if everything is okay again I'm going to redirect my user const navigate use navigate hook now we get to do homepage and also I'm going to clear my local storage remove item and the item name let's see I'm going to click here we are on the homepage if I open up my local storage by the way we don't have any cookie anymore and we don't have any user this is how it works right now we know how to authenticate our user but what about the authorization let's see how to protect routes in our API I'm going to close everything here and open up my API folder and inside routes let's create here a test route we can test everything here and I'm going to create my controller test controller and I'm [Music] in request response and one more and it's going to be should be admin let's call them here let's open this first and I will say should be logged in now for here should be admin Okay so let's take care of this controller first when I visit API test and should be logged in I have to verify my token first remember it's inside our cookies so I will say const token request cookies and token if we are not logged in we are not going to have any token in this case we can return an error I'll say if there is no token return response status 401 Json and let's say a message and it's going to be not authenticated and if we have a token this time we have to verify that because remember when we login we are creating our token using this secret key and also we have a time here it might be expired or the user might change our JWT token so we have to verify this first I will say JWT do verify function of course I have to import first JWT from J on web token and I'm I'm going to pass here my token to decrypt again we are going to be needing our JWT secret key process em our secret key and I'm going to write here my call back function it's an Asing function and it's going to return as either an error or our user information remember we set here our information you can give any name you want here let's say payload for example and inside this function I'm going to write my condition I'll say if there's an error that means our token is not valid so I can return an error and I can say okay you have a token but it's not valid and if everything is okay response status 200 Json message you are authenticated Let's test this I'm going to open up my hostman and here let's create a new folder let's create our first test is going to be protected route and I'm going to be using my base URL remember test should be logged in let's check our header as you can see we don't have our cookie so when I sent this there is a problem of course I forgot Jazz here let's check here also okay okay let's see again I'm going to send not authenticated because we don't have our token let's log in I'm going to send let's come back send again and you are authenticated that because our token is here but if I come here and change my token by the way let's remove them we don't need them this is our JWT if I add here one I will save and let's send again and token is not valid 403 Forbidden this is what we want what about role based authorization in our example we don't have any admin property yet but let's say when we login we are passing here is admin and true let's say we have a user and it's an admin in this case we are going to store this value inside JWT and we can check it here let's do exactly the same thing here I'm going to close this menu and right now I should check one more thing here remember we have the payot and I will say if payot is admin sorry if it's not admin we are going to send another error 403 and again a message and I will say not authorized okay we have a token and we are authenticated but we are not an admin so we cannot reach our data okay let's log in again let's come back and it's going to be should be admin I will send you are authenticated but if I change this to false let's log out let's change here by the way and log in again right now I'm going to try to send my request and as you can see not authorized it's that easy guys this is how we handle authentication and authorization but in many request we are going to need this verification we have to verify our token first for example when we want to create a new post or update our profile for the chat functionality basically we have to write this blog again and again to prevent this we can use expressjs middleware let's come here and create a new folder and I will say middleware and inside verify token I'm going to import JWT from Json web token and I'm going to create my function export con verify token we are going to take request response but we are going to need one more thing here and it's going to be next I'm going to explain this right now don't worry and insight I'm going to add exactly the same thing I I will copy here and paste of course it should be an arrow and we are taking the cookie we are checking our token and after we are verifying our token here if it's not correct we are sending this message and here if the verification is completed we can run the next process and we can use the this payload here remember we have an ID inside right now I'm going to assign this ID inside my request let's say user ID you can give any name you want here and it's going to be payload do ID basically expressjs middleware allows us to intercept any process make your verifications and after continue that process for example here in our route when we make a request for this endpoint it's going to run our middleware first it's going to make our verification if everything is correct it's going to run next and that means you can run should be logged in in this case we don't need to add this block anymore and what we can do here is we can reach our user ID because inside middleware we passed our user ID to request using request user ID we can reach that value I will say console lock request and user ID not response request I will save and let's see should be logged in let's log out first log out successful let's come back log in and not authenticated and if we are logged in I'm going to send come back and send again you are authenticated and if you check here you can see that your ID is here this is so important because using this ID we will verify our user when we delete any post we are going to check the user ID of this post if it equal to this ID that means we are the owner of that post in this case we can delete this is why we pass here our user ID okay so I'm going to close everything here right now we can take care of our react application as you can see our user information is here and also when we open up our profile page we are going to see our information here and if we are not logged in we shouldn't see this page basically we are going to need this user information everywhere so what we can do is we can create react contact API and we can store our user information there and whenever we need it we can just call use context hook and we can reach that data and also we will create a function that we can update our user for for example when we update our profile we are going to change this user information immediately so let's start and you are going to understand better I'm going to come here I will find the source folder and I'll say context and inside let's say off context. jsx let's create our context I'll say export const off context create context it comes from react and after that we are going to create our context provider export con of context provider and we are going to pass in the children and we are going to return our provider here I'll explain soon Al context. provider and it's going to cover our children okay so basically we are going to WRA our entire application with this provider and if I pass here anything we can reach that data inside any component or page so basically we are going to have here our user information let's say const current user Set current user I'm going to create my state here when we visit our website we are going to check our local storage if there is user information or not remember that user information is a string so I should transform that into an object so I'm going to use Json pars local storage get item and user so if there's a user in our local storage we are going to use it if not it's going to be null so if I send my user information here we can use it everywhere Let's test I'm going to open up my homepage and I'm going to call my context you use context it comes from react and we are going to call our context just like that and right now we can call our current user just like that and let's see what's inside I'm going to come here as you can see there's a problem because we didn't wrap up application with this provider to do that you can open up your appjs or main JS and wrap your entire application with the provider all contacts provider let's try again okay our homepage is here let's check and as you can see it's null let's log in John my password I'll login if I refresh the page you are going to see that our user is here but we shouldn't have to refresh our page all the time when we make any changes so right now instead of changing our local storage in the login page we can handle that in our context let's come back and I will create here a function const update user we are going to take the user information and we are going to update our current user and whenever our current user changes we are going to update our local storage to do that we can use us fact hook whenever our user changes I'll call my local storage set item user will be again we should send a string so I will say Json stringify and we are going to pass here our current user in this case we can use this function everywhere let's open up our login page so we we don't have to set this here anymore instead we are going to use our update function and our context is going to change our local storage let's do that I will do exactly the same thing here I'm going to call my current user let's import them let me close this [Music] menu right now I'll call my function update user and I can use it here we don't need this anymore I'm going to send my response data let's see I'm going to log out let's open up login and let's check our storage as you can see it's null right now if I say John and my password and login as you can see our user is here so right now when we update our user information we can call this function and update our data easily and we can use it everywhere for example in our naar again let's call our context and use our user information I'm going to copy this open up my nowbar I'm going to import use context and my authentication context and again we are going to be using the current user so we don't need this dummy data anymore I'm going to delete here use the current users Avatar and if it doesn't exist use no Avatar let's check our public folder okay we don't have let me edit here just like that okay if we don't have any image we are going to use this Avatar and after that I can update this username and let's see okay our username is here but we don't have our image it's the extension I think okay it's here so right now when we log out again I'm going to update my user so let's come here and close everything and open up our profile page let's call update user and current user use context hook and off context let me import this so right now instead of removing this user information I'm going to make it null to do that I'm going to be using my update user function and pass here no by the way we need here a wait we are making a request and we don't need this response and I can use this current user here again if there is an AAR use it if not use no AAR and here here is going to be username and here is going to be email just like that when I log out we can see our links here by the way we don't have any link let's open up the now bar okay I'll say login and register so we can log in right now and our user is here perfect but how we are going to protect our routes for example if we are not logged in I'm going to log out and if I try to visit profile page as you can see we have an error here because we don't have our user and that means we don't have the user information so what we can do here we can create a use effect and we can listen our current user we can write here a condition if current user doesn't exist we can be redirected to the login page in this case we need navigate here and if there is a user we can show our profile page I will refresh as you can see we are in the login page if I try to reach the profile I cannot see it but doing this again and again for each protected route is not a good idea we shouldn't repeat ourself so what we can do is we can create new layout if you remember inside droughts we have a layout here and it drops our entire application but right now I'm going to create another layout let's copy this I'm going to close my menu and I will say require off and I'm going to call my current user let's copy this and paste I'm going to import them and I'm going to write my user fact here and whenever current user changes we can write our condition here if there is no current user we should be redirected to the login page to do that we can use react rather navigate component to the log page and if there's a user we'll show our layout right now I can separate my react louer D Pages if you remember in our appjs let's save here by the way I'm going to open up appjs and here we have our router and we wrap our pages with this layout right now we are going to need another one so let's come here and write exactly the same thing path the homepage I'm going to add here my layout by the way I have to export this as you can see by default it's a layout but it's going to be layout and require layout oops not layout it's off and I'm going to write my children here firstly let's decide which page requires to be logged in everybody can see homepage everybody can see list page single page but when it comes to profile page I'm going to cut this from here and paste it here let's give a comma so basically whatever we add here will be depending on our layout by the way let's open up profile page we don't need this anymore and here everything is going to be handled by our layout let's see I'm going to visit my profile page by the way there's a problem here because of this import it's not export default anymore by the way I think we don't need this use effect we can directly write our condition here if there is no current user we are going to show this component if not our layout here let's see okay we are in the login page if I say profile as you can see it shows the login page so I'm going to delete here and this is how we protect our routes right now we are going to add one more page here let's log in again I'm going to open up the profile page and when I click on this button we are going to show the update page and again we have to be logged in to see that page so I'm going to close everything here and open up my update page but in the previous tutorial I forgot adding that page here so I quickly created a new one and if I make any design changes you can find it in the GitHub repository so I will say profile update page let's create our page and CSS that's create our function remember how to do that and inside I'm just going to paste my design and here and let's see of course we have to add it to appjs I'm going to add one more path here and it's going to be profile and update just like that let's see I will say update actually we can fix this button let's open up profile page and we have a button here I'm going to wrap this with react ROM link and when we click on this link it's going to redirect us to profile and update I will click and it's here by the way here is going to be our user image so we need to call our context you already know how to do that I'm going to close here and let's close here also so let's call our function and current user here I'm going to import them okay it's not coming let me copy and paste my path I don't want to waste time here you already know how to do that and for our inputs we can use our information for the username I will say default value will be current user. username so I can do the same thing for email I will not use for password because remember we are not storing our password it's not on our browser and for this image I'm going to be using current user. a by the way my path is not correct of course it should be double level just like that as you can see our username and email so when we don't touch them they are going to store our previous values but if we change it we are going to update our username but before where is our image of course we don't have an avatar that means we need to use no Avatar image just like that and later I'm going to show you how to add image to do that we are going to be using a library but before let's take care of our API let's close here I'm going to open up my menu for now I can close client and here we have the user route as you can see it's empty let's copy this and paste here and let's decide what we are going to need firstly we'll be able to fetch all users in our app you are not going to need that but anyway let me show you how to fetch multiple items so it's going to be get users and also we can get a single user in this case we should pass here the user ID I'll say get user also we can change our profiles so it's going to be a put method again we are going to need the user ID and update user and finally we can delete our profile delete user let's create our controller user do controller export const get users Asing function request response and let's write try catch block for now if there is an error we are going to console loog and after we are going to return a response status 500 and our message here fail to G users so I'm going to create three more it's going to be G user update user and delete user okay I can use them right now I'm going to import don't forget to add here JS and right now we can use our middleware when we hatch our user profile we have to be logged in first so I will say verify token I will do the same thing for updating use user and the leading user let's import middleware and verify token and let's test our end points I'll say console lock it works and I'm going to open up Postman and create a new folder and it's going to be users the first request will be get users I'm going to call the base URL users I'll save let's copy this and paste it's going to be single user get user in this case we are going to need a user ID here let's paste again update user in this case it's going to be a put request I'll save and finally delete user just like that I will save and let's fetch our users I'm going to send as you can see we cannot run our route because probably it's not in our appj yes okay as you can see it's not here I'll say user route API users and we are going to pass our route here let's actually move this here okay let's see it again I'll send again there's a problem probably our extension okay Js Js verify token oh it's not export default like that let's send as you can see it's sending a request we don't have any response but if I check here I can see that our end point works perfect so let's fetch our data from the database it's really easy I will just say const users await I'm going to call Prisma here from my library I need to add JZ here and the user model and I will say find many we are going to patch multiple data and we don't have any condition here I can directly send my users status 200 Json and users let's see again I'm going to send and as you can see our users are here as I said we are not going to use it in our application but I just wanted to show you so let's find a unique user you already know that I'm just going to copy here and paste this time we are going to find unique only one item and inside I'm going to write my condition where and the user ID will be this ID to get this ID we are going to be using request params ID equals request and params do ID let's pass it here ID equals ID and since we are using exactly the same name we don't need to write this I'm just going to pass ID and if everything is okay we are going to pass this user let's take one of them I'm going to take this ID let's come here let's try 1 through three by the way not user users we have an error there is no user but if I pass my user id it's going to return my information information again we don't need that in our application because when we login we already fatch our information I'm just showing how to fetch data using Prisma uh for update user again we are going to take the user ID con ID it comes from request params do ID and there is something important here we are going to take the user ID from the cookie and we are going to compare this with this ID if they are equal that means we are the owner of that user so we can update remember we have passed our ID inside the token const token user ID it's inside request and user ID let's remember again then we verify our token we just pass here the user ID so we can use it here so let's try our condition if ID doesn't equal token user ID it means we are not the owner in this case we can return a response status 4 all three Json and message let's say not authorized and after that we are going to send our inputs using body let's make this users again I'm going to choose R and Json and let's say I want to update my username only username nothing else it was JN and it's going to be let's say updated JN so let's get this data remember it's inside our body const let's say body request. body let's separate them to see better okay we are going to make some changes here but before let's try I will say con updated user await Prisma do user. update and I'm going to write my condition here which user I'm going to update it's going to be the user with this ID and also I'm going to pass my data and I will say body so let's see what we have inside console loog updated user actually let's send this directly response status Json and updated user let's see I will send not authorized because it's not our ID let's remember our user ID I'm going to copy this and paste here send and as you can see our username is updated John let's try email updated at gmail.com let's make this updated joint on to I will send it's here but what about password if I try to add a password let's say hello it's not hashed anymore so we have to be careful here if we have a password we have to Hash it first so what we can do here I can separate my password and and the other inputs let's say inputs and I'm going to write a condition here I'll say if there is a password hash it first so I can create here a new variable let's say updated password it's going to be null and if we have a password inside the body we can change it updated password will be await bcrypt do has remember how we are doing this I'm going to pass here my password and assault let's import this okay and right now I'm going to change my data firstly I'm going to update whatever inside our inputs but also so I'm going to need here a condition if there is no password we are not going to add anything else if we have we are going to update our password and it's going to be this updated one to write our condition we can spread it like that and write our condition I will say if updated password the password will be updated password so if it's not null it's going to spread this object and it's going to be password equals updated password let's try I'm not going to send any password here let's say three and updated three I will send our password is still hello but if I say password test I'm going to send and as you can see it's hashed password and I can do the same thing for Avatar because in our application in any case we have the default value for username and email even if we don't change them we are going to send them like that but our password can be empty in this case we shouldn't change it and the same thing for our user image if we don't don't change it we are not going to send anything in this case I should do exactly the same thing I'm going to also get my AAR here and write my condition if there's an avar use it here okay and let's take care of leading User it's really easy again we are going to need our ID and token ID if they are not equal we are going to return an error just like that we don't need anybody here and I will say await Prisma user model delete and I'm going to pass my condition where and ID and that's all after that we can return a response 200 Json message and user deleted it's that easy so let's see how to update our user on the client site we are going to be using this end point it's going to take our cooky and verify our token and after that it's going to take our request body and update the user so let's close here open up profile update page and let's create our submit function I'll say on submit handle submit let's create this function const handle submit we don't want to refresh the page so I will say Pro and default and I'm going to get the form data const form data new form data and I'm going to pass here Target so right now we can reach our inputs using their names as you can see name email and password const that's the structure them username email and password and I can get them using this form data to do that we are going to be using object from entries and pass here are from data remember in the login page we get our users just like that form data get and whatever the name of that input here and also you don't have to do this one by one you can directly use object from entries and form data and you can D structure your inputs okay it's going to be an Asing function we'll make a request here I'll will say try catch if there's an error show it here and also I'm going to create here a state that we can show our error errors at error view State at the beginning is going to be an empty string and if there's an error remember where is our error message response data. message and let's try to update our user I'll say const response remember we have created API request function we can use it what was the name name Library okay API request it's going to be a put method and I'm going to pass here my API URL and I will say users current user. ID and after that we can pass our data username email and password let's import this API request from library and API request and if everything is okay we can update our user response. data because remember it returns our new information so so we can update our user and see it here immediately let's see by the way if there's an error we can show it here let's log out first because we have changed our user in the postman I'm going to log out sign in again what was the name updated John 3 actually let's make this John again and password is test okay let's open up the update page I'm going to update here let send oops what's going on okay user is undefined so we couldn't pass our information let's delete this refresh our page and login again test okay it doesn't work it means we have updated our user but we couldn't return that information let's right here console log and see what we have response. data I'm going to open my console this is because we entered a wrong credential I'm going to remove here and let's say John 3 I'm going to update okay it says undefined because I forgot a wait here let's see again I'll say four update okay it's here by the way we have a password here but we shouldn't send it remember how to eliminate our password here I'm going to open up user controller and I'm not going to send this user directly instead I will separate my password and the others let's say the rest of them from updated user so I can send rest here but be careful here we already have a password we shouldn't create exactly the same name so I'm going to give here different name user password okay let's see again John 5 update okay there's an error because we already have John 5 let's say something different and as you can see we don't have our password anymore okay so what about this image I'm going to refresh here of course I can right now send my item here instead of this console lock I can update data let try again last time I will update and I'll username is here after updating we can redact the user so I can use use navigate hook const navigate use navigate it comes from react R and I can use it here profile page let's try I said last but it was not the last time okay update and we are on the profile page okay perfect so let's take care of this image if you watch my tutorials you know I try to show different Technologies like Firebase file stack Cloud but this time instead of using an API I want to use a react widget there's an awesome solution for that if you search for cloud react you are going to see this page let's open up react image and video upload as you can see there is a button here when I click on this button it shows this component let's actually open up in sent box I'm going to click and as you can see there's an awesome component here that we can upload images from our computer or we can add any web address we can use any storage provider so we can use this widget let's see what we have here we are going to have this upload widget component I'll just drag the copy and paste here it just loads this widget from the cloud lary and initialize our widget inside component let's say upload widget and I'm going to paste it here let's change this name it's going to be upload widget okay and after that we are going to use it on our profile page let's see what's inside appjs I'm going to zoom in a little bit let's scroll down as you can see our widget is here and inside this component we should send our configuration we are going to pass our Cloud name folder name to do that let's open up our account just visit cloudinary dcom and after the login process you can see your console I'm going to zoom in and here I'm going to find settings upload and here we are going to create an upload preset let's give it a name I say estate signning mode will be unsigned and I'm going to save okay our preset is here and also you are going to need your Cloud name as you can see my cloud name is lad so we are going to use them not open up our profile page profile update page and call our widget here after this image and inside this widget I'm going to pass my configuration and first one will be our Cloud name and it's going to be lad I'll pass my upload preset it's going to be estate multiple files will be false we are going to add only one file we can add maximum image size let's say 2 megabytes and you can upload your images inside any specific folder let's say avars and after uploading image we can update here to do that I'm going to store my avatar using use State let's say Avatar set aatar the initial value will be current user. aatar of course it should be after this current user and I will use it here and after uploading my file I can set my Avatar so I'm going to pass my set State here set Avatar let's get this as a prop as you can see after the uploading process it shows our image result let's actually see that first and after we can update our Avatar I'm going to open up my terminal let's choose any image from my computer okay they are not user images but anyway let's try this one and after uploading as you can see we have all the information we need to know and here we have the image URL let's open up and it's here perfect right now I can set my avatar by the way we don't need this I will say set Avatar result info and inside remember we have the secure URL we can use it just like that let's see right now I'm going to upload again let's choose this one and perfect so right now when we update our profile I can also send this Avatar image let's close here and I will also send my avatar here oops it's our form data I'm going to send it here okay let's try again I'm going to refresh upload new file let's make this John again I'm going to update and perfect our image is here by the way let me check one more thing here I'm going to update my password let's see get user okay it's here 3F MVM and if I send empty password 3 F NVM I'm going to send okay it's still the same it's not changing this is what we want okay right now we know how to update profile so let's take care of our posts let's see what we need for the simple post information we have the image title address price bedroom and bathroom number and also we are going to need our coordinates because when we open up the list page we are going to see them on the map so let's create our post model I will close them and open up my Prisma schema I'm going to create a new model and it's going to be post you're going to have an ID again we will have a title it doesn't have to be unique we are going to have a price that's a integer we are going to have an image address City bedroom and bathroom numbers it's going to be integer of course what else are coordinates and as you can see we have a type here it should be by or rent and here is going to be another option and it should be apartment house condo or lent we cannot give anything else to do that we can create anom here let's say type it can be only buy or rent I can do the same thing for the property apartment house cond or lent let's use them here yeah are going to have a type and its type will be type and the other one and we are going to have a created at time and there is something important here each post has a user so I'm going to create here a user and its type will be our user and they are going to have a relationship between them so how we are going to connect our po post to user firstly I'm going to need a user ID here it's going to be a string and remember if you are using mongod DB it should be DB and object ID and right now using this user ID I can connect my pulse to user to do that I'm going to say Fields user ID and the reference in the user will be ID this ID will be exactly the same ID as you can see there's a warning here because inside user model we don't have our posts so I'm going to come here and create posts and post array because a single user can create multiple posts let me check this again ID title price image date time default now this user ID will be user ID okay I hope everything is correct so I'm going to save remember after saving your schema you have to come here and say MPX Prisma DB and push okay awesome right now we can create our post let me close here and this schema I'm going to open up my post route and let's create our route the first one will be rou get we are going to get multiple posts get posts single post we can create a new post let's say add post we can update again we are going to need ID update post and also delete and when we create a post we have to be authenticated so I'm going to be using verify token middleware and also when we update and delete the user let's import this from middleware and verify token JS okay let's create our controller post controller.js let's check our appjs if it's here or not okay post route API posts okay it's here firstly I'm going to call Prisma and after that let's create our first function get post Asing function we are going to get request and we are going to send a response and as always to try catch if there's an error console log and after send a response failed to get posts and if everything is okay I'll say response status 200 and Jon and we are going to pass something here let's create for others get posts get post add post update post and delete post okay let's call them here I can import them right now okay perfect I'm going to close my menu and let's get all posts I will say cons post await Prisma I'm going to use the post model yeah are going to patch many items after we are going to apply this filter but for now let's f all items and send it to the user I'm going to copy this single post find unique remember how we are doing this we are taking the ID from the parameters request. params and we are going to search for it where and ID after that we can send it to the user when we create a new post let's say const Bud request well buddy and also we are going to need our user ID because remember in our schema when we create a post we have to pass here a user ID remember it's inside our token I'll say token user ID request. user ID after that I'll say const new post A8 Prisma post model and create and inside I'm going to pass my data I will say take everything inside the body basically it's going to be title image all these information here and also I'm going to pass my user ID just like that and finally I can send this new post we are going to take care of this later let's try to delete our post firstly we are going to need the post ID request params do ID and our user ID request. user ID and after that firstly we should find our post and after we should check the user ID of that post if it equals to our ID that means we are the owner so let's say con post await Prisma post model and find Uni I'm going to pass here its ID and after I will write my condition here if the user ID of this post doesn't equal my token user ID that means I'm not the owner and I'm going to return an error let's see 403 Json message not authorized and after that if everything is okay we can delete our post await Prisma post model and delete and again I'm going to write my condition here where ID equals the post ID just like that and if everything is okay we are going to return a message that says pause deleted okay let's create our end points on Postman I'm going to create a new folder I'll say posts new request get posts base URL posts I'm going to save that's copy and paste it's going to be single post I'm going to pass here any post ID I will save let's create another create post it's going to be a post method just like that copy and paste two more it's going to be update post again we are going to need an ID here and finally delete post just like that let's get all posts I'm going to send okay there is something wrong of course after generation I didn't start my app okay server is running I will send as you can see we don't have any post yet let's create I'm going to open up budy choose R and Json and inside we are going to have a title let me write quickly I'm not going to waste your time okay I'm going to send and as you can see our post is here and this is our user ID we have created ad and all these inform information let's add one more I'm going to change here title two okay and let's get ID of this post tool get post I'm going to paste my ID here okay there's something wrong let's check of course params do ID let's check the others pars ID okay perfect our post is here and when we try to get all posts it's going to return an array that includes all posts Title One title two okay it works let's try to delete this one post deleted let's patch again and right now we have only title one okay it works so for the list page we are going to Fouch our posts but remember in the single page we also need this information to do that I'm going to create a new model and it's going to be pulse details let's open up our Prisma schema and after this post I will say post detail and again I'm going to create my ID let me close here and after that we are going to have the post description is going to be a string what else utilities pad policy and let's say income policy I'm going to change here and after we are going to have this side and the distance of these places so let's write them it's going to be a string but not required yeah are going to have pad policy income size and the places of course they are going to be integer school and size and each post is going to have a post detail so let's add our relation post post model and the relation and the fields inside our model will be post ID let's add it here post ID will be a string DB doob ID and it should be unique and the reference in the post model will be its ID so let's add our detail here post detail the post detail model okay of course it's going to be Fields not field so when we create a post we need to create post detail Also let's open up our controller and I'm going to add my post detail here post detail and right now I should separate my body we are going to send the post fields and also post detail Fields what I mean by that when we create a post we are going to pass our post Fields here let's create another object I'll say post data and paste it here and also post detail and we are going to have description and other fields here let me create quickly just like that in this case our post data will be body dot post data and we are going to create post details and we are going to pass body do PA detail remember if you make any changes in your Prisma schema you have to push it to your database by the way as you can see we are using a single image here but in our app we are going to have multiple images this is going to be the first image second third and fourth so instead of image let's say images and we are going to pass our string array so let's change here images it's going to be an array and inside the first image and the others okay let's delete this first one just like that and after I'm going to create my post with details let's push terminate this and I will say MPX Prisma DB and push okay let's run again and close here and I'm going to sand my data there is something wrong okay I forgot writing description oh when I copy and paste I edit this multiple times let's remove okay post data and post detail I'm going to send and perfect so if I get my all posts as you can see it doesn't include our detail this is what we want because when we fatch our data for the list page we don't need to fatch details we are going to fatch it only in this page so when we make a request for the single item single post we need to see our post detail and also as you can see we have a user here we can send it also we need its user image and username so I'm going to close this menu and make some changes here firstly I'm going to fatch my user where is our G post here so I will come here and include my post details and also the user let's see what's going to happen I'm going to send our post data is here and also post detail and the user information but as you can see there's a password Here we are going to need only username and Avatar I'm going to create here an object and I'm going to select only username and the Alor I'm going to save and that's see I'm going to send my request and we have username and AAR perfect so what about our react application inside our profile when I click on this button you are going to see the add new post page let's create that I'm going to come here inside my routes I'm going to add a new page let's say new post page my jsx and SC CSS I'm just going to copy and paste my component here again I forgot to design this in the previous lesson but don't worry there is nothing complex we are just going to create here a form just like that and my CSS so let's open up our appjs and add here a new item and it's going to be let's say at and I'm going to call new new post page let's see I'm going to add here a link I'll close everything open up my profile page and add here a link let's drop our button and say go to the ad page let's click okay we don't have our styles let's add this quickly new post page docss okay and for the description I'm not going to add here a text area instead we are going to be using a library that we can style our text so we are going to have here a toolbar that we can choose text type or Tex size color and also we will be able to add any link so let's add our library I'm going to open my console create a new terminal CD client and I'll say mpm install react Quil okay let's add it here react quill from react quill and using this component component we can show our text editor okay as you can see there is something wrong here because it didn't use its CSS file remember same thing happened when we created our map so we have to add here it CSS file just like that we are going to be using this theme let's edit here and when we write anything inside this editor we need to store it so let's create here a use State hook value set value use State hook it's going to be an empty string and when we change anything inside our editor we are going to update our state let's say onchange and set value and I'm going to add my value here by the way our description is here I'm going to move this under my label and let's see okay perfect so I can add here any text I can make it bold give an underline or any link I can create a list change this size here okay so let's take all these inputs from our form remember how we are doing this inside form I will say on submit and let's say handle submit I'm going to create my function here I will say prent default let's create our form data new form data and I'm going to pass my target here let's take all the inputs we have remember in the login page we get our data like that but we have many inputs here instead of writing them one by one I can directly say inputs object from anes and I'm going to pass my form data here let's make this lower case and let's see console log inputs I'm going to write something here title description will be inside our value let's say City any number here and if I send you can see our items here so we are ready to send our inputs to database to do that it's going to be an async function and I'm going to write here try catch block if there is an error console lock and after I'm going to create here a state error set error and I'm going to set my error here let's show our error after the button if there's an error create here a span and show my error okay so right now we can make our API requ request I'll say const response 8 I'm going to call my API request function and it's going to be a post request posts and pass here my data but be careful here I'm not going to directly send all my inputs because we also have a post detail so we are going to have the post data and also post detail so I'm going to send here all the data inputs and the post detail remember description is here it comes from our editor but there is one more thing we need to add here and it's going to be our images remember it should be an array let's create one more State images set images at the beginning is going to be an empty array and inside this right component we are going to add our upload widget this error is because we didn't add here anything we are going to fix that I'm going to find my site container and add my upload widget remember it's inside our components here we are going to use it just like that and I'm going to pass my images here okay it's here and remember we need to add multiple images so inside our configuration I'm going to say multiple and it's going to be true and also remember we are passing our Cloud name upload preset and maximum image size let's paste it here it's not going to be false anymore and let's say folder posts if you want to you can increase this size or just delete and if you remember inside upload widget we send here set Avatar state but it's just for the user information so instead of set AAR let's say set State and after uploading our images we are going to update our state and we are going to take the previous value create here an array take the previous and edit here a new one which is this URL in this case we can create multiple images so we have to update our profile page it's not going to be set Avatar is going to be set state but in this situation our state should be an array so I need to remove this and write here an empty array and when we upload any single image it's going to be inside this array right now I'm going to choose the first item and I'm going to update my sidebar because remember we are directly showing here an avatar but instead I'm going to show the first item and I will say if there is no Avatar show here the current Avatar and if it doesn't exist show the no Avatar image let's see okay if I upload let's add this image and as you can see it's here okay so let's do the same thing here when we have images we can show them here I will close this page and inside new post page I'm going to show my images images array map and for each image create here an image element and show the image of course we need a unique key in this case I can use my index number okay let's add our state here set state is going to be set images and as you can see they are here okay awesome of course this page looks a little bit ugly if I make any changes for this page design you can find it in the GitHub repository and if everything is okay we can be redirected to this single post page to do that we are going to need use navigate hook con navigate use navigate hook [Music] and navigate to the single page and I'm going to add here my post id respon data. id okay if we add a new post it's going to automatically add our user ID let's check our controller again to make sure as you can see it comes from our token and let's try I'm going to refresh upload my files title from client any price here address description and others let's add some random coordinates tenant is responsible you must be rich and let's write our size and other items I will say add and as you can see we are in the single page and this is our post ID Let's test get posts I'm going to send and as you can see title from client our images and other items by the way white minus 3 we can add here our conditions I will say minimum zero and here actually they can be minimum one if I add minus something okay so right now we can fetch our data of course we have many options here we can use a library like react qu but for the previous tutorials we have already used it for this tutorial I want to teach you something new to fetch our data we are going to be using react rou doome let's see its documentation I'm going to open up the tutorial and we already know how to add router and all our Pages here but this time I'm going to show one more thing and it's going to be loading data so basically we can create our loader function and we can fatch our post and we can add this function to our rouer so when we use the single page here we can run our and it's going to automatically patch our post and pass it to our page let's create and you are going to understand better firstly I'm going to create a new file let's close everything here and inside Library I will say loaders let's create our first loader I'll say export const single page loader and we can pass here our page L and also our parameter and using that parameter we can select our ID and make a get request using that ID so we can get request and also params and our ID is inside this params by the way it's going to be an error function and let's say const response await in this case it should be async and I'm going to call my API request function pass here my endpoint posts and also we are going to add our post ID params do ID we can use this ID because inside app Brer let's see the single page as you can see our path is including this ID this is how we can use it here let's import our API request function just like that and I'm going to return my data response. data so when we call our single page we can use this loader like that and to use it inside our page we are going to be using use loer data function let's do that I will save and open up my single page and call my response data here let's say post let's import this and let's see what we have inside I will refresh my page let's come here and as you can see our data is here it's that easy guys you don't have to use any third party Library you can handle everything with react rou so let's use it here I'm going to pass my data here we are going to be using post perfect but for this user remember when we patch a single post it returns this user and also we have the post detail so we are going to be using them here on the right side so for the username and user image we are going to be using post do user for the description we are going to be using post do Post detail and I can write here a condition if data. post. post detail equals owner right here owner is responsible if not the tenant is responsible oops not data it's going to be direct directly post and post detail and for the pad policy again I can do the same thing if post. post detail do pad equals all out right here pad allowed if not not allowed and let's change here I'll say income policy post. detail do income and I can change here let's copy this size bedroom but remember it's inside our post data so I can use it directly like that bathroom and the distance post detail. scull bus and Resturant if you want to you can change this me also what you can say you can say if it's more than 999 you can divide this value 1,000 and right here kilometer if it's not you can use it directly as you can see it's not kilometer because it's less than a th000 by the way we don't have our user here let's check user. image and AAR okay perfect and we don't have our description here it was description or just shortcut okay it's here but as you can see it shows our HTML element here but what we want is giving our Styles and HTML elements inside this div to do that we can use dangerously set inner HTML but if you are using this you have to be careful so we have to sanitize this Value First to do that we are going to need a library let's open up our console and I will say mpm install Dom proofy let's call it here and right now I can sanitize my item I'll say HTML don't proofy and sanitize and right now I can write here my this description post dot post detail and description of course we are going to need double curl bracket here and right now our description is a P tag okay perfect and also we can send our coordinate if you remember we are sending our post data here so instead of this dummy data I'm going to send my post of course we cannot see it here because our coordinates are different let's actually get the other post okay we can use this one so I'm going to copy this ID paste here and again it's not here but if I zoom out we can see our pin but why this is is happening let's open up our map and as you can see we are using our Center here and this Center is the middle of UK Let me refresh as you can see it's the middle we are doing this that because in the list page we want to see the whole country but in the single page we need to see our coordinate here to do that I'm going to write here a condition like let me copy this and I'm going to check the length of my items and I will say if equals 1 it means we are in the single page because we are passing here only one item in this case we can use its coordinates so I say items the first item and our coordinate here and I will do the same thing for the other coordinate and if it's not a single item we can use the center of the country let's see right now I'm going to refresh as you can see it's here and for the list page the whole country okay perfect so right now we know how to fetch data and later I'm going to show you how you can add a loading indicator but to understand that better let's take care of our list page again we are going to be using a loader but to fetch this data we are going to need our URL because when we search any item here let's say London minimum price maximum price and rent when I click on this button we are going to update our URL and it's going to be something like list typle will be Rent City will be London minimum price 10 maximum price a th000 and using this query we are going to patch our data let's do that I'm going to close everything here and open up my loaders and I'm going to add one more loader here and it's going to be list page loader before doing any request let's see what's inside this value I'm going to console lock and call this on my appjs just like that let's import and as you can see inside request we have our URL so I can split this URL into two pieces and I can take this part after this question mark to do that I will say const query equals request. URL and I'm going to be using the split method and I'm going to split my URL using this question mark and it's going to give me an array before this question mark and after this question mark and we are going to take the second part and right now I can send this query to my API so I'll say posts question mark and I'm going to add my query here so let's see inside our controller get posts again const query it comes from request and query let's see I'm going to refresh this page and as you can see these are our query items so using them I can write here a condition I will say where I'm going to delete this by the way and I can directly add here my query but be careful if we directly search for our items as you can see location is empty by the way it's going to be City we are going to change it and we don't have minimum and maximum price in this case we are going to have a problem here to prevent this I will take my items if they exist to do that I will say City for example query do City if it doesn't exist it's going to be undefined in this case it's not going to search for it it's going to hatch all CDs so I can do the same thing for others for type property and what else we are searching we have City type we have minimum and maximum price and also bedroom let's say bedroom and be careful when you pass your query is going to be a string but we have to transform this into an integer so I'll say parse integer and paste my value here and for the price I will say the price should be greater than the minimum price let's use parse in again query do minimum price if it doesn't exist is going to be let's say zero and also it should be less than maximum price and if it doesn't exist let's say 10 million so let's use our loader in the list page remember how we are doing this we don't need this data anymore I'm going to be using use ler data hook let's say posts use ler data so I can remove this here and use my posts and as you can see they are here let's try to find this one minimum price will be let's say 200 and the maximum price will be 400 I will enter okay it's not here maybe type is by okay it's here and the bathroom is minus 3 we are going to change it it's not important so this is going to be our main structure let's handle this search bar I will close them and open up my search bar remember we have our query here and using this function we are able to change our type here and also we are going to need our inputs so let's create handle change function for them for example for this city I'll say on change event and handle change I will do the same thing for others and let's create our function const handle change event and we are going to set our query again and we are going to do exactly the same thing we are not going to touch the previous items we are just going to change the inputs we are writing in this case we can use their names remember for each input we have name minimum price maximum price and City using those names we can update their values and Target and value okay when I click on this button it's going to send our inputs but remember these buttons are not inside our form so instead of sending them like that we can create here a link rra this button it comes from react ROM let's add it here and I'm going to write here my URL firstly we are going to go to the list page and the type will be query. type and the others okay let's see by the way since we changed our design we cannot see our button properly let's open up CSS file where is our button here so I will say the link is going to contain our button and in this case the flag will be here again its background color will be this yellow color okay and right now I'm going to Center my item here display flag align item Center justy content Center okay perfect let's try I'm going to choose rent London 100 1,000 I'm going to send and perfect if I don't write anything it's going to fch all the posts we have for our application as you can see loading is really fast but imagine you have a heavy database in this case fetching operation might take a little bit longer in this situation we can show here any loading indicator in this case we are going to need react rather D defer let me search for it it's here let's open up this guide it says speed up the slow things so basically we are going to be using suspense component when we visit our page we will be able to see this Nar and this filter component and we are going to show here any indicator it can be a text or image or whatever you want and it's going to be much better for the user experience to do that inside our ler as you can see we are using this defer function and we are sending our promise as you can see there is no await here here and inside our component using this suspense block we can show any indicator and Rea R Dom is going to await for our data if there's an error it's going to show this element and if everything is okay if we have the data we can show our list this is the idea so let's open up our loer and I'm going to remove this A8 and in instead of this data I'm going to return my promise defer and let's say post response and I will write here post promise and I'm going to S here let's import differ and let's use hpan inside our list page so right now I'm going to cut this I'm going to be using suspense and for the fallback you can show any image or text let's just say loading after I can change here and again if I change any design you can find it in the giab repository and after that as you can see we are going to resolve our promise and if there is something wrong we are going to show this text if it's not it's going to return our data and we can use our list map so I'm going to copy here and paste it comes from react ROM we are going to resolve data. our response here of course we are using posts here let's say data and if there's an error error loading post and if we have the response we can map through our post data and show our cards post response do data but before actually let's see what's inside I will say console lock post response post is not defined because we are using our map here let's refresh again and as you can see inside post response we have a data array and it includes our posts so we can use that array here and we are going to return post response. data do map and for each post Insight we are going to call our card component and we are going to give here a uni key post. ID and our post let's see our cart it was post or item okay it's item let's see I'm going to refresh as you can see loading is there let's make this process a little bit slower I'm going to open up my pause controller and instead of sending this response immediately I'm going to be using set timeout let's say send this after 3 seconds and let's see I'm going to refresh as you can see loading and they are here it's that easy I can do the same thing for this map I'll just copy here paste and instead of this map I'm going to s this component in this case again post response to data let's see I'm going to refresh loading loading and perfect but there's something important here theer data works on only initial loading so you can choose different options depending on your project as I said you can use react query or any other library but I just wanted to show you how easily you can patch and load your data and suspense your components using react ROM okay so let's take care of this filter let's write again London 100,000 I'm going to search okay our items are here right now we don't need this actually I will comment this out but it can stay in the GitHub repository so you can test it and what I'm going to do is taking my items from here and use them inside my filter so we are going to update here and these inputs to do that we can use react rather Dom use search part s let's close everything and open up the filter so I will say const search parms and set search params and they are going to come from use search params hook let me import like that and let's see what inside our perms as you can see we have for items inside our perms but how we are going to reach them it's really easy I will just say get uh for example let's take this city and as you can see it's London let's change here test Perfect by the way it runs twice that's because of our react Street mode if you watch my us effect video I'll explain this stct mode so don't worry about here it's running twice only in the development mode okay so let's take all our items and paste inside our query State const query set query I'll say use State and we are going to have an object and it's going to include all these items because when we make any changes we have to update our state and when I click on this button using this query items we are going to set our search params and in this case it's going to patch new items so I will say type search params dog type and if it doesn't exist it's going to be an empty string I will do the same thing for others city property minimum price maximum price and bedroom number of course they are going to be numbers 0 0 and Z but remember it shouldn't be zero let's say one and for this one let's say p million okay so we will do exactly the same thing here we will create handle change function event set query you target. name and value so let's use it for each input for the city on change handle change I'm going to copy this and paste for type and for the others okay if you want to you can use use reducer hook but anyway we don't have that complex State here we can use use state if you want to learn how to use use reducer you can watch my fiber clone video but we don't need this here because we can change everything in one function okay and when I click on this button search button let's say on click handle filter let's create const handle filter and we are just going to set our search params using this query so it's going to take this object and transform that into a string and update our URL Let's test by the way we should update our items first using this URL so I'm going to come here uh for this London I'll say query do City just like that and for inputs I'm going to give some default values for the city default value will be again query CD let's copy this for the type and for others okay our items are here if I refresh the page we can see them so let's change here I will say London actually let's change here using our search PRS otherwise it's going to update here whenever we write something so using search perms I'm going to update this location get and City okay so if I search of course there is no place like that let's actually open up our list it's going to PCH all our items and I'm going to change this price for example let's say 500 and the bedroom is 2 and perfect this is how it works if I say buy again two items if I say 400 as you can see only this item okay perfect and again we cannot see it here because we don't have the correct coordinates but if I say list as you can see we have only one item and it's title to okay by the way we cannot see our images here let's open up our cart as you can see it's searching for the image but remember we are using images and we are going to take the first item okay perfect and what else we can do let's open up our single page all the information is here but when I click on this button I want to save this place to do that we are going to need another model let's close here here and open up Prisma so what I'm going to do is create here a sa post model and it's going to store our user ID and the post ID let's say saved post again let's copy and paste this we are going to have a user and post user user it's going to be user ID and the reference will be the ID inside the user model so let's add our IDs user ID and post ID and if you want to you can add here the created ad date remember how we are doing this we are taking the date time and by default it setes the current time let's do that I'm not sure we are going to need it but anyway and right now I can use sa post inside my user and post each post can have multiple save posts and again each user can have multiple saved posts but we cannot create exactly the same save post for same user ID and post so I I can write here unique user ID and post ID so we cannot save exactly the same post okay let's push our database I'm going to terminate this MPX Prisma DB push let's run it again and let's create a new end point let's create a new router and it's going to be a post request and let's see save we have to be logged in first and let's say save post let's add it inside our controller I will duplicate this and save post okay so what we are going to do here let's get rid of this and here firstly we are going to take the post ID from the bodyy const post ID it comes from request body and post ID and also we are going to need our user token user ID const token user ID remember remember it's inside our request and after that I'm going to try to find the saved post await Prisma say post find unique where and I'm going to search for the user ID post ID and we can pass here our user ID it's going to be token user ID and also post ID this ID so we don't have to write it like that and if this post is saved when I click here we are going to unsave if it's not saved we are going to save so we are going to need a condition here I'll say if saved post exists that means we have already save this post in this case we are going to delete it Prisma save post do delete where its ID will be sa post. ID and we are going to return a status to 100 post removed from Saved list and I will write else if it doesn't exist in this case we are going to create a new sa post so let's say create and we are going to pass our data the user ID should be token user ID and the post ID should be the post ID and in this case again message and post saved okay but when we patch this single post we don't know if we already saved this place or not again we can open up our post controller and inside get single post we can check our user but be careful if you remember we don't have to be logged in to see this page inside our route as you can see there is no verified token middleware here so we need to take our token inside our controller and check if we are logged in or not so after fetching this post I will say let user ID and search for my token request cookie. token if we don't have the token that means we don't have any user if token doesn't exist the user ID should be null and else if we have a token we have to verify remember how we are doing this JWT do verify let's import this first otherwise I'm going to forget just like that and we are going to pass here our token and our secret key JWT secret key and it's going to return us an error or our payload and inside this payload remember we have the user ID but again I'm going to create here ifs block and I will say if there is an error again user will be null if not that means we are out authenticated and we can use our ID here so user ID will be payload do ID if you want to you can create a new function for this process inside your library but we don't need this we are going to use it only in post controller only for this endpoint so it can stay like that and using this user ID we can check if we save the post or not let's say const saved AIT Prisma do saved post and find unique I'm going to write my condition here again user ID post ID post ID will be this ID comes from request params and the user ID will be this ID that comes from the token and right now I can pass here one more thing so I will restructure this we are going to send all the data but also I'm going to send is saved and if we have an item here it's going to be true if it's not it's going to be false okay let's open up our single page and let's see what's inside post I'm going to refresh post data detail and user but we don't have are saved there is something wrong here cannot read toen Because I Said cookie is going to be cookies that's why it like that actually and let's try and here we have the post data post detail user and is saved is false okay right now I can add here my function when I click here we are going to call this say post function let's do that inside single page I'm going to delete this and for this button I will say on click and I'll save and it's going to be an asnc function we are going to make a request so I'm going to be using try catch if there's an error console log if you want to you can create errors State and show it to user and I'm going to check one more thing here since we can see this page even if we are not logged in and I click here we are going to be redirected to the homepage to do that we can use our current user remember how we are doing this I'm going to be using use context hook and pass here authentication context let's import this by the way we don't need this data anymore and if current user doesn't exist I'm going to be using redirect and the login page and after if we have a user finally we can save or unsave our post I will say await API request it's going to be a post method and the end point is users and save let's see user route and save okay let's import API request from our library and we need to pass here our post ID and it's going to be post. ID but how we are going to see that if it's saved or not to do that we can create a use State Hook const saved set saved at the beginning it's going to be our post dot is saved and whenever I click on this button I'm going to change my state after react 19 we are we are going to do this using use optimistic hook but since we are using 18 let's do this using the old way let's write here a note after react 19 update to use optimistic hook okay so I will say take the previous value and right here the opposite and if there's an error we are going to take that back just like this and using this value I can change my text and style I will say if it's saved right here Place saved if it's not save the place just like that and also I can change its color if it's saved let's use inner style and I will say background color if it's saved make it yellow if it's not make it white okay I'm going to click here as you can see play saved there is no error because it's still the same and if I refresh the page you're going to see that it's saved okay perfect and one more thing we need to do in the profile page as you can see there is an error because in our profile page remember we are using this list component and inside this list component we are still using this dummy data and inside this data we don't have images array we are still using the old one but if I make them images again just like that there will be no problem but anyway we are not going to use this dummy data anymore instead we are going to fatch our data using ler remember how we are doing this I'm going to close everything open up ler and let's create one more and I will see profile page loader you're not going to need request and Perms or this query I will just say users let's remove here and let's say profile posts and using this endpoint we can fatch our posts and our saved posts let's open up our endpoint here and I'm going to create one more route and it's going to be a get request let's say profile posts we need to be logged in and let's say profile posts but again as you can see when we PCH a single user we are using its ID in this case there will be a conflict it's going to take this as a user ID to prevent this you can write here search or even you can comment this out because anyway we are not fetching any single user when we login we are going to fatch this using the authentication route okay let's create our function inside controller so let's say export actually I will just copy and paste this I don't want to waste time and it's going to be profile posts we are going to take the user ID let's say token user ID for the consistency request params and user ID and after that we are going to search for our posts and also the saved posts user post a wait Prisma posts find mini by the way it's going to be singular and where the user ID equals the token user ID so they are going to be our posts and I'm going to create one more and we are going to search for Save posts and let's see saved where user ID should be token user ID and in this case case is going to return its ID user ID and post ID and this date but we want also this post because we are going to show it here to do that we can use include and pass here post and it's going to be true but again we don't need this sa post we are going to need only this post object so I can map through my item let's say saved posts take this saved array search for each item and return only the post inside this post basically it's going to return us to post array and we can send it firstly we are going to send our posts my list and after saved posts just like that and if there's an error fail to get profile posts okay right now we can use our ler I'm going to copy this open up my appjs let's close this menu and find our profile page here I will say ler and profile page loader so let's do exactly the same thing as we did for the list page I'm going to take my data there is our profile page that's open up I'm going to get my data here using this hook and after we are going to be using suspense and wait for our list so let's come here I will paste let's import suspense and O8 and instead of this map we are going to show our list and we can pass our data here so let's say post and remember inside this response we have a data and inside this data we have two items user posts and saved posts the first one will be user posts and I will do the same thing for the other list just like that and it's going to be save posts so let's take this as a prop inside our component and right now instead of this dummy data we are going to be using our posts I'm going to refresh as you can see the posts that we have created and the saved list if I come here and unsave let's open up profile and it's not here anymore let's add this one save the place open up our profile and it's here perfect of course we can improve our application we can add save fun functionality for this button or we can add some more information for the user but anyway this tutorial is already too long but if you want to learn a complete application from scratch using type safety using all the functionalities all the optimization features security pagination and other features you can join the react course weight list I'm going to create an also some course for you that you can create a real world application from scratch okay so we finished data fetching and other cruit operations so let's take care of these chat messages I'm going to close them to do that I'm going to open up my Prisma schema and create my new models the first one will be chat model again we are going to have an ID created ad dat and here let's decide what we are going to have in a chat model we are going to have two users me and the other user and also each chat has multiple messages inside and as you can see we have here the last message and to handle this notification we are going to create the seam by field basically when we open our chat we are going to see all the messages so we are going to remove these notifications let's do that firstly I will say users we are going to have multiple users and also each user has multiple chat collection let's actually move this two here so we can see better and if I say chats and chat array and here is going to be user array as you can see there is a problem here because we cannot Define find many to many relations like that in the mongod DB let's check the documentation I'm going to copy this URL and paste here if you want to add this relation I'm going to zoom in you should have here your model IDs and you should do the same thing for the other model in this case I'm going to add here user IDs is going to be a string array and inside this array we are going to collect our user IDs that means it's going to be object ID so I will do the same thing for this chat array I will say chat IDs string array DB object ID right now I can write my relation Fields I'm going to choose chat IDs and the reference point in the chat model will be ID let's do the same thing here we are going to search for user IDs and those IDs will be this user ID and also I'll say seen by and we are going to store our user IDs again so let say db. object ID and finally I'm going to create my message model and again we are going to have ID and and created at and also we are going to have our texts and the sender ID so let's say text is going to be a string user ID again string and each chat can have multiple messages so I will say chat chat and I'm going to write here my relation Fields inside the message model will be chat ID let let's create it's going to be a string and the reference will be ID our chat ID let's add our messages here message array just like that and remember we are going to have here this last message it's going to be a string but not required because when we create our chat we are not going to have any last message when we write anything here we are going to update our chat okay let's push our DB I'm going to open my console inside API I will say MPX Prisma DB push okay let's run it again and right now I can create my routes and controllers I will just copy this user route this is going to be chat route and this is going to be message let's call them inside our appjs I'm going to duplicate here and it's going to be Chat and message so I can use them right now Chat and message okay of course plural just like that okay let's decide what we are going to have firstly I'm going to update here and when we open our profile page we will be able to patch all these chats so it's going to be a get method I'm going to be using my verify token middleware because we have to be logged in first and I will say get chats and also we can get a single chat so that's right here ID and we are going to have a post method that we can create a new chat let's say save chat or add chat and one more post method and it's going to be read when we open our chat we are going to automatically run this endpoint and we are going to read that chat okay let's call them here and read chat let's create them I'll open up my controller let's again copy and paste this chat controller and okay let's close them for now we are not going to need bcrypt the first one will be get chats I'll delete here let's say failed to get chats I'm going to delete the rest and duplicate this function and it's going to be g chat add chat and read chat okay so let's get our user ID from the token token user ID request. user ID and using this ID we can patch all the chats we have so I'm going to come here and say const chat chats await Prisma the chat model we are going to find many and I'm going to write here my condition if you remember we have user IDs and it's an array so we can search for our user ID using has some method and we are going to pass here our ID by the way it should be uppercased okay so let's see what we have here I'm going to open up Postman and create my new ant point and it's going to be chats new request get chats Bas URL and chats I will save and create a new one it's going to be g chat we are going to add here any ID let's copy and paste it's going to be add chat and the method will be a post method I will save and finally ReChat and the end point is read and the chat ID actually we are going to update our chat so it should be put or patch let's change here okay and I'm going to create one more folder and it's going to be messages and I will say add message before handling chat let's create this quickly it's really easy we are just going to have one request and it's going to be add message let's delete all we are just going to have one post method and it's going to be add new message let's change here and add this function into our controller let's delete all of them and change the name okay so let's test our chats firstly I'm going to login okay after we are going to get all chats as you can see it's empty right now I'm going to try to add new one I will choose buddy and Json here and remember what we have I'm going to open up my schema when we create a chat we are going to need user IDs the first user ID will be our user ID and the second one will be the receiver ID they are going to be empty so we need to pass only receiver ID nothing else so let's say receiver ID and let's pass here another users's ID for example this one okay so let's take this receiver ID and create our chat I will close everything open up my controller and I will come here again we are going to need the user ID token user ID and I will say const new chat 8 Prisma chat model create and inside data I'm going to be using user IDs and inside this array we are going to have our ID which is token user ID and the other one will be this receiver ID so I will say request bu and rece Seer ID after creating that we can return let's try I'm going to send and as you can see it's here and SE by and last message is empty and we don't have any messages inside okay so let's try to get this chat this single chat what was. id I'm going to copy this and paste here and let's come back I'm going to be using my user id again let's actually separate them and using this ID I can patch a single chat Prisma chat I'll say find unique and I will say where the chat ID should be this given ID remember how we are using this request perms do ID but also we have to check our user ID otherwise everyone can patch this data to prevent this I will say user IDs has some and I'm going to pass it here my user id let's send this just like that but in our example when we open a chat we should see all these messages and as soon as I open this chat I'm going to update scen by array let's do that firstly we are going to add our messages to do that we can use include and and it's going to be messages and also you can give here any option like order by and I will use created at and it's going to return us the latest messages okay after that we are going to update our chat a wait Prisma chat and update I'm going to write my condition the chat ID will be request params do ID and the data will be seen by and I'm going to add my user ID to do that we are going to be using the set method and it's going to push our token user ID inside this array okay let's try again I'm going to send and as you can see we don't have any messages and scene by array includes our user ID okay and finally let's take care of read chat I'm going to take my user ID and again I'll will update my chat const chat or updated chat whatever you say oh8 Prisma chat update method and let's write our condition ID should be request param ID and again we have to make sure that it includes our user ID user IDs has some and I'm going to pass here my ID okay let's update this I'm going to pass a data here and I'm going to update the scene by array and I'll will push my user idid okay let's send this chat or you can send a message and let's take care of messages we have only one function here I'm going to get my user ID and remember what we have inside we have the text sender ID and the chat ID we are taking this chat ID from request and params let's actually write it here chat ID it comes from request PRS and chat ID let me check first if I add this or not okay we need to add here the chat ID and also we are going to need our text let's say request buddy and text okay so firstly we need to check if this chat belongs to us or not so I will say con chat await Prisma find unique where the ID should be the chat ID and again to provide the security it's going to include our user ID okay and if it doesn't exist we can return an error response status let's say 404 chat not F and if it exists finally we can create our message Prisma message model create and I'm going to pass my data and it's going to be the text the chat ID and the user ID and it's going to be our ID just like that and when we send a message here we need to update the scene by array because we don't know if the other user sees our message or not in this case seam by array is going to include only our ID so I need to create here one more function chat update again I'm going to pass here the chat ID and I'm going to update the scen by array and it's going to be only our user ID as you realize I didn't say set because if I say set it's going to put my ID but I'm going to directly pass this array so it's going to remove the other users ID and also we are going to update this last message last message and it's going to be text okay finally I can return this message and we are going to take that message and addit here okay I hope everything is okay let's actually try I'm going to choose this chat ID and we are going to pass here the text first message and here is going to be our chat ID let's send and perfect this is the sender ID this is the chat ID so we can use this object to show our message and if you check our chat you are going to see our messages and the latest message is first message perfect everything is ready right now I'm going to save here and let's try I will close my tabs and open up my client application I'm going to open up library if you remember when we open up our profile page we are patching only our posts right now I'm going to add one more promise and it's going to be chat promise and we are going to fatch all the chats we have in this case I can add here my promise and it's going to be chat response let's use it in our page I'm going to open up profile page we have the data here and remember how we are using suspense and await and I can do the same thing for this chat component right now I'm going to add my suspense block here and this time we are going to f the chat response if there's an error we will say error loading chats we are going to get our respon and show our chat component I'm going to move this here and let's pass our data let's say chats chat response. data in this case we can use this prop inside our component just like that and let's see what we have as you can see chat array and it includes all our chats we have only one but there's a problem here we also need this user image and its name if you want to you can use this array you can fatch your user information in this component but let's handle everything inside our controller so when we fatch our posts oops it's the user I'm going to find chat so when we fatch our chats we need to add our user information also so we are going to need here a loop let's use a for Loop chat of chats remember inside chat there is a user ID is array using this array we can find the other user so let's say const receiver ID I'm going to find user IDs and I'm going to check the each ID inside this user IDs array and I will write here my condition and it shouldn't be our token user ID remember it includes two IDs and if it's not our ID that means it's the other user and using this receiver ID we can fatch the user information so let's say receiver wait I'm going to be using the user model find Uni let's write our condition and the user ID should be this receiver ID and if I do that it's going to return all the information but we are going to need only this image and username so I'm going to use select we can also fetch the user ID username and Alor right now I can add this information to my chats object so I will say chat. receiver equals this receiver okay let's see it again I'm going to refresh and right now we have the receiver okay perfect so instead of this dumy data we can show all the chats we have let's remove here and all the messages here I'm just going to leave this last one let's use our array I will say chats map and for each chat ins it we are going to return this div I'm going to add here quickly the uni ID it's going to be chat ID and I'll write here my condition if chat receiver as an AAR use it if it's not use our no Avatar PNG what was the name okay it's not PNG okay by the way it's not chat it's C and we can use the user ID sorry username and here is going to be the last message okay by the way I removed my state by mistake Chat Set chat new state and let's say false we are going to change it later I'm going to refresh and as you can see our message is here and also I can change my style to do that let's use inner Style Style I will say background color if scen by includes our user ID in this case we are going to need the current user remember it's inside our context use context and off context okay let's use our ID here if it includes it can be white if you didn't see the last message it's going to be yellow let me copy and paste just like that of course we have already read this message it's going to be white okay so what I'm going to do is when I click here I'm going to open up my chat component so let's right here and on click event and let's say handle open chat handle open chat it's going to be an Asing function we are going to take the chat ID and using that ID we are going to make a request in this case we have to pass here our chat ID so I'm going to create TR catch block if there's an error just console log and I'm going to try to find a single chat so I will say const response await I'm going to call the API request the end point will be chats and we are going to pass here the chat ID remember we are fetching a single chat and after finding our chat we can update this state so let's say set chat response. data but remember there is something important here if I say true as you can see we are going to need this AAR and username again if you want to you can handle this in the back end but since we already patched our user here we can use this so I can pass here also chat. receiver and let's add it here so I will say take everything inside this data and also add here the receiver okay so at the beginning it can be null and when we click on any message here we are going to open let's click perfect right now we can use our information here let's choose this chat and here I can update my user if chat receiver has an avatar use it if not use our no Avatar image okay it works let's change here perfect and I'm going to update my messages right now I can delete them and I'm going to leave only one of these divs let's create our Loop here I will say chat messages do map and for each message call this div let's give our unique id message. id and let's update our text message. text and remember we have the created ad dat but how we are going to transform that into this format to do that we can use a library let's open up a new terminal here CD client and I'll say mpm install time ejs we are going to be using its format method and I will say format and inside let's pass our date message. created at and that's all let's see I'm going to open and perfect and for the style we are going to have a condition if this message belongs to us is going to be on the right side if not it's going to be on the left side if you remember we were using this subass name but instead let's use a style because we are working with aate I will say style align self and let's write our condition if message. user ID equals our user ID is going to be at the end flx and if not it's going to be flx start and I'm going to add one more and it's going to be text align if it's our message it's going to be on the right if not it's going to be on the left okay nothing has changed but if I change here and as you can see it's on the left okay it works right now we can send a message using this form it's not a form let's change it and I'll say on submit and let's create a function called handle submit if you are using form inputs you need to give here a name remember and let's say text let's create our function const handle submit again async prent I'm going to prent the default Behavior so I will say event prent default and let's write our block and firstly I'm going to get my data that's a form data new form data I'm going to pass my event here and we need to catch our text input remember how we are doing this I'll will use my form data and get is going to be the name of the text input which is text and if it's empty we are not going to do anything and if everything is okay we can send it to our API Ty say const response A8 API request it's going to be a post method remember our endpoint is messages and we are going to pass our text and if you remember we need to pass here our chat ID let's say chat. ID and it's going to return us our message so using this response I can update my chat remember it includes all our messages and at the end of that messages I'm going to add one more message so let's say set chat get the previous values write them again but update messages I'm going to return this like that and again I'm not going to touch any messages inside this array so I will say take all the previous messages and add here one more data and it's going to be response data and after sending our message we can reset our input we don't want to see that message anymore you and Target and reset let's try I'm going to open right here any message text from client I'll send it and as you can see it's here and if I refresh the page you are going to see that it's inside our database perfect it works but what about the real time chatting when a user sends a message we cannot see it immediately here we have to refresh the page to do that we have many options to use you can use any real time database like Firebase or any others but I want to teach you suck at iio it basically allows us to create real time events on our application we can send any real time notifications we can send messages or whatever it might be and it's a really cheap option because we are not using any database we are collecting all the data inside a pool and we are listening events let's open up the documentation I'm going to zoom in as you can see we are going to need a socket server first and in the client site as you can see we are going to need a library and using this function we will be able to connect to the socket server and listen our events and here we are going to have two methods Emit and on basically when we try to send anything to other site we are to be using the emit function and when we try to listen any event we are going to be using the own function for example if we use Emit and the event name which is hello we are going to send this data and to listen this event we are going to be using the own method on the client side and we are going to pass here exactly the same event name hello and it's going to return us our data which is word so we can use use it as we want and using the same way we can send any data to our server again if you want to send any message we are going to be using emit the event name and the data and inside our server we can listen this event using on we are going to pass here our event name and it's going to return us our data which is stranger so we can use it here this is the main idea so let's install our library and after create our socket server I'm going to come here close everything I'll open my menu and let's create here one more folder and I will say socket I'm going to create appjs let's initialize the not JS I'll open my cont all let's actually create new terminal I'll open up my folder mpm in it and again we are going to be using node modules just like that and again to start your application you can use not app.js but it's not going to refresh your application when you make changes to prevent this you can install nmon and run your application using nmon appjs but again I'm going to continue using my extension just like that and I'm going to create my server to do that of course we are going to need our library mpm install socket let's run it again I will import server from socket iio just like that and let's make this uppercase and create our server I will say const iio is going to be a new server and I'm going to add here my configuration we can use course and right here our origin and it's going to be this URL in this case only our application can reach This Server and let's create our connection and see how it works iio on connection and it's going to return us to socket and let's see what's inside so let's open up our console again and in the client site we are going to be using this Library mpm install and client and after that using this methods we are going to connect to our server we can use it in our profile page but you might need to use in different components or pages so I prefer creating my soat in a context so let's come here find our context and I'm going to create one more and it's going to be socket context it's going to be JS X and I'm going to do exactly the same thing here I'm going to change the name and I'm going to import socket io- client and here instead of current user I'll say socket and at the beginning it's going to be null just like that we don't need any function here and whenever we visit our website we are going to connect to our circuit so I will say iio and our server address HTTP Local Host and we are going to need a port number I forgot to create that I will say I listen let's say 4,000 let's use it here and right now I can pass this to my provider and I can use it whenever I want let's wrap our application I'm going to open up the main JS and I'm going to wrap my app just like that let's call our provider okay right now I can use it on my chat component let's call one more use context and we are going to find our socket from socket context just like that and if I refresh my page you are going to see that we are connected and inside this socket we have the socket ID let's see as you can see for each connection it's going to give us a unique ID and again it's rendering twice because we are using strict mode don't worry about that for the production it's going to render only once so using this socket ID we can send private messages before doing that let me show you how to create EV I will say socket and on remember when we use on we are listening the event name let's say test and it's going to return us a data and we can see it here so let's use this event name and send a data using our react application I will create here a button on click test let's create this function we are going to use it for the task purpose I'm going to delete this later and using my client side socket I can send any message event name will be test remember and we can send here any data let's say hi from client let's give any text here test me if I click as you can see hi from client and we can do the same thing inside our server if I say emit I can send any data to my client this is how it works right now what I'm going to do is I'm going to store all my users using their IDs because remember this socket ID is returning a unique ID but in our application for example we are going to send a message to John 5 but we don't know it's socket ID we can store all our users with their idies let's create and you are going to understand better I will create online users it's going to be an empty array and whenever we connect to our server we are going to create a new user remember how we are listening events sucket on and let's say new user and we are going to get the user ID from the client and save it inside our empty array here let's actually create our function here add user we are going to take the user ID and the socket ID and firstly I'm going to check if the user exists inside this array or not user exists I'm going to check my array and try to find this user and if user do user ID equals this user ID that means it's already inside the array and it's going to return our user and I will write here a condition if user doesn't exist push it to our array online users. push user ID and sucket ID let's call this here by the way if you have never worked with socket iio it might be confusing for you but as I said there is only two thing sending events and listening events watch the tutorial and try to do it yourself practice and try to understand and after creating a project you are going to understand everything better I'm going to be using this function and I'm going to pass the user ID that comes from the client and also remember inside socket we have the unique ID we can use it of course we are going to send user ID okay and what about this connection if we close our window or tab we are going to be disconnected in this case we should remove our user from this array to do that we are going to be using disconnect event in this case we are going to need one more function here let's say remove user in this case we are going to need the socket ID and using this ID we can find our user and remove it online users and I'm going to update it I'm going to filter and for each user search for the socket ID and filter this ID so it's going to remove our user from the array let's use it here okay and right now using the socket ID inside my array I can send private messages to do that I will need another function here let's say get user user ID and I'm going to return online users and I'm going to find my user using this ID if they are equal that means this is the user I'm looking for and it's going to return that user to me and after finding this user I can use its unique socket ID and send a private event before doing that let's try to send our message to the server I don't need this anymore remember we have handle submit function here I will come here and I will say sucket and remember when we send any data we are using the emit function and the event name will be sent message so I can send my message here but also I'm going to send the other users information because we are going to need its ID so let's create here object and I will say receiver ID remember it's inside our chat and also I'm going to send my message so let's say data of course it's going to be column we are using an object and response. data let's listen this event in our server on and the data remember we are sending the receiver ID and the message data and let's use them here I will say console loog let's say receiver ID and let's see what's inside I'm going to open my chat write something here if I send and as you can see we have the user ID and also we have our message let's see test I'll send and it's here right now we can send this data to other user to do that we are going to be using IO do2 and we have to pass here the socket ID that we want to send our message remember we have the G user function here we can use it and pass our user ID if I find that user I can reach the socket ID so let's get that user first I will say const receiver get user and I'm going to pass this receiver ID and find my user in this case I can reach its socket ID and I can send any message and let's write an event name I'll say get message and I'm going to send my data and again we are sending data from our server in order to listen that we need to use sucket do on so let's create here a US effect and listen our event I'll say socket and if there's a socket we are going to listen our event remember the event name is get message and it's going to return us a data and we can show this data here but remember to see this data this chat has to be here because if another user sends a message we shouldn't see that here here so I'm going to add here one more condition if there's a chat in this case I should write this as a dependency and I will write if chat. ID equals data do chat ID because remember when we send a message it includes our chat ID if they are equal it means it's the same chat and we can show this message here and right now I'm going to update my chat I'm going to take the previous value and again I'm going to write it here and I'm going to change my messages again we need to return this like that and it's an array I'm going to leave all the previous messages previous messages and I'm going to add here the new message and and if we receive this message here we need to read this on the database otherwise it's going to be yellow so let's create here a function const read async try catch and I'm going to make my request wait API request is going to be a put method chats and read and also we are going to pass here our chat ID let's open up our route and remember as you can see chats read and ID actually we don't need this response we are not going to use it anywhere and let's call this function after sending our message just like that and let's try I'm going to open up a private window and I'm going to login user five what was the name John 5 I'm going to log in okay just like that let's open up our profile as you can see it's yellow because we didn't read this message if I click it's going to read it but as you can see it's still yellow because we didn't update here but if I refresh the page as you can see it's not yellow anymore because in our database we have updated scene by array to prevent this UI mistake let's open up our chat component and and here I'm going to add one more condition and I will say if chat. ID equals this chat ID so whenever we open it it's going to be white okay I'm going to open my chat and let's write hi this is John 5 if I send oops it's on and it's not open as you can see this is our message let's try again I will say hi and it's not here that because I forgot to send my user data at the beginning whenever we connect to socket iio we need to create a new user we have an array here we need to add our user information to do that I'm going to open up my context and create here one more use State and whenever we are connected we are going to send our user ID to do that we are going to need the current user use context just like that and if current user exists we are going to be using sucket and we are going to pass our user data remember the event name is new user and we are going to send our user ID here current user. ID by the way I said use State it's going to be use effect we are going to need socket here and let's see again let's write here a console look and see after adding user I'm going to call online users I'm going to refresh the page and here and as you can see we have two items this is the first user and this is the second user let's try again I'm going to open and here by the way as soon as I open on my chat it returns to White and I'm going to test it there's a mistake here by the way if there's a chat and socket we are going to listen get message event we are going to get the data and if chat ID equals message Chat ID we are going to update our messages let's see again I hope everything is all right let's refresh the page and here let's open up I'm going to send a message from John it's here let's say from John 5 but when I send a message or open this chat component I want to automatic ly scroll down to do that I can create here a div and whenever I open this component I can scroll to that D using use effect let me show you and you are going to understand better inside my messages here I'm going to create a do and I'm going to be using ref here let's say message and ref let's create use ref hook const message and ra use ra I'm going to be using use effect and I'm going to write here the chat component because whenever we change it it's going to run this effect and using this gra and current we are going to scroll into view and we can change its speed using behavior let's see right now I'm going to open and as you can see perfect again okay it works so if I send a message here it's going to automatically scroll down just like that and here let's see so what about this notification if we have any unseen messages we are going to show here a notification and if I open any unseen message I'm going to decrease this number but as you realize our nbar and this chat component should be related to prevent any prop drilling we can use a state management tool you can use Redux but I prefer use using Zan it's much easier to use by the way I know its pronunciation is different it's a German word but I'm going to say zand and let's open up its documentation and see how it works I'm going to zoom in we going to install this Library and after that as you can see we are going to create a state here it's going to include our notification number and using different actions you can update this state as you can see increased population it's going to take our state and it's updating this variable at the beginning it was Zero if I dispatch this action in any component or page it's going to increase this number and if you want to you can reset you can add different number and in our case I'm going to create a fatch action and when we visit our website it's going to fch unseen messages from the database and using our state we'll be able to see that number here this is the idea let's copy this open up our menu and inside Library let's say notification store that's paste you can change this name if you have different stores you may want to use different name let's say use notification store it's really long but anyway and I'm going to add here number and I'm going to delete them and create my first action and it's going to be Fetch and you can use any Asing function also and I will say const response I'm going to make a request and endpoint will be users and let's say notification we don't have this yet but we are going to create and after returning this response we can update this number so will say set the number inside my state will be response do data and also I'm going to create one more action here decrease and I'm going to set my state take the previous state and return number previous state do number minus one and you can add any action you want if you want to you can reset that when you dispatch this action you can set your state and you can make your number zero let's write here export const and before using that let's create our endpoint users and notification I'm going to open up my menu r user route and let's create one more cat method and it's going to be notification we should be logged in get notification number and let's create it here I'm going to use this function change the name we are going to need our user ID but here we are going to search for our chats Prisma chats find many and we are going to pass here our user ID remember how we are doing this it's going to has our user ID and also we are trying to find unseen messages so I can use not here and seen by has actually let's use has some and we can pass here our ID let's use it here also and after we are going to send chats. length we can use here count Also let's use it like that and I will say number and send it here so let's use our first action I'm going to be using fatch action and I'm going to get the number let's open up our nowbar I'm going to close everything and open up nowar I will say const patch equals use notification store let's check again okay it's here state. fetch let's call it and C of course we are going to also need our state let's create one more and it's going to be number and I can use this number here as you can see it's zero so I can write here a condition I will wrap here and I will say if the number is bigger than zero okay I'm going to refresh here and here and I'm going to open up this message and add here one more message test not notification I'm going to send and if I open up any other page okay it's not one there is something wrong okay it's here and unseen but we cannot see our notification number and it says has some is not correct user IDs should be our user ID let's check our user ID okay it's not here oh I said PRS it should be request user ID of course if I refresh as as you can see it's one perfect so right now I can decrease this number when I open any unseen chat here it's going to decrease this number so again we are going to need our state I'm going to copy this open up my chat component and paste it after this ref for example and we are going to call the decrease method decrease action and after opening this chat I can write here a condition I will say if response data do seen by doesn't include our user ID seen by that means this chat is unseen in this case we can decrease this number oops there is a typo here decrease let's see I'm going to refresh if I click as you can see it's zero right now and we cannot see it and if I refresh again it's not here anymore and even if I open this chat it's not going to be minus one because we have a condition here okay perfect of course you can add more features you can send some images in the chat but for this kind of application I don't think we need to send any image this basic chat is more than enough but in the future I plan to create another tutorial and in that tutorial we can add more features like different notifications sending different data group chats calling or sending voice records and that's all we have finished our project if I make any changes you can find it in the GitHub repository I hope you liked it if you learned something new today please like the video don't forget to follow lad Dev social media accounts you can support lamade by joining the channel or using the link in the description below you can join my reactjs master course wait list is going to be in the description and that's all I hope I'll see you in the next tutorial goodbye
Info
Channel: Lama Dev
Views: 53,890
Rating: undefined out of 5
Keywords: react, react tutorial, react project, react course, learn react, node.js, node react, node react full stack app, react for beginners, react context api, react real world project, node react mongo db, react booking, mern, mern stack, mern project, mern tutorial, react hooks, jwt, cookies, react website, web design, mongodb, real estate app, prisma, mongodb prisma, chat app, socket io, react socket io, real time chat, lama dev
Id: eJ3YysWaP_A
Channel Id: undefined
Length: 300min 1sec (18001 seconds)
Published: Fri Mar 29 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.