React Node.js Booking App Full Tutorial | MERN Stack Reservation App (JWT, Cookies, Context API)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello my friends today we are gonna complete our full stack booking application using react node.js and mongodb this is the home page we will fetch all data from mongodb using a backhand api let's choose any destination date range and option when i click on this search button it's gonna fetch all related hotels we'll be able to change search inputs or price range and it's gonna re-fetch this list let's choose one of them and this page shows the hotel information and here it calculates the price according to date range and room number which i have chosen and when i want to reserve any room i will be redirected to login page and i will try to log in after a successful login process i will be able to see room options and available rooms i'm gonna choose room numbers and complete process and let's say i'm another user and i want to reserve a room on these dates which includes exactly the same dates the previous user has chosen in this case when i select the same hotel these rooms are not available anymore and finally we are gonna use an admin dashboard and we will be able to delete items and create new ones if you didn't watch the react admin panel tutorial it's gonna be in the cart on the top left it's an awesome project that you can learn how to create a rest api how to provide security using jwt how to make api requests using cookies custom hooks react context api and more i hope you will like it if you want to see more tutorials like this please like the video if you are ready let's get started okay firstly i'm gonna create new folder here it's gonna be our back-end server i'm gonna say api and after that we are gonna add here our react application also so let's open our terminal so firstly i'm gonna initialize my node application to do that i'm gonna say npm init dash y and it's gonna create our packages first if what we are going to need is express framework so i'm going to say npm i or if you are using yarn yarn add and express okay it's ready to run our application we are gonna need main file let's say index.js and in this file i'm gonna create my application let's import express it's going to be from express but if you are using node.js by default you should export your libraries like that const express require and express but i don't like using this structure instead i'm gonna use import export but to do that you are gonna add one more line and it's gonna be type and it's gonna be module in this case we can use as6 modules like import export if you do that let's create our application i'll say const app it's gonna be express function and that's all to run our application we should listen any port so let's say app dot listen i'm gonna write here any port number let's say 8800 you can write here whatever you want but make sure that other applications are not using this port number and finally after connection you can write here let's say connected to back ends so let's start our application to do that i'm going to write here start and it's going to be not index.js so whenever i write here npm start or yarn start by the way i prefer using yarn instead of npm i think it's much more effective of course it depends on you if you are using npm it really doesn't matter i will say start and as you can see connected to backend but if i want to make any changes here like that i'm going to save my file to see our changes we have to come here and terminate and start our application again but it's not a good idea to do that over and over again instead we are gonna use one more library and it's gonna be not more and right now instead of nodes i'm gonna say node mod index.js and let's terminate this server and start again and this time as you can see nodemon is watching our files and whenever we make any changes we are gonna see it here immediately let's say dot i'm gonna save and as you can see it's here perfect so let's try to connect our mongodb i'm gonna go to cloud.mongodb.com and here after logging your account you're gonna see this page let's create new db as you can see there are three options here but we are going to use the free one we are just trying to learn something and here you can choose any cloud provider like google windows or amazon and after choosing your region you can create your cluster of course here you should create a username and password let's say llama and llama and i'm gonna create user this is gonna be our admin account so nobody else can reach rgb and one more thing we should do and it's adding an ipa address of course if you are deploying your application you should criteria server ip address but we are gonna use localhost so you can use either your current ip address or you can write here for zero like that in this case it's gonna allow every ip address and i'm gonna say finish and close and i'm gonna go to db okay we are gonna connect this i'm gonna click here we are gonna use it in our application so i'm gonna click here and this is our mongodb uri as you can see we have username here we are gonna change this password and finally we are gonna add here our db address but this uri is really important it's gonna be kinda a secret key so we have to hide it so instead of coming here and mongodb connection and this uri i'm gonna hide it inside emv file i'm gonna say dot emv and let's say equals this of course let's change our password it's going to be llama and eb name will be booking i'm going gonna save but how we are gonna reach that data we can't directly write process enemy i'm gonna add here one more library and it's gonna be dot eme so let's import this dot env to use this we should make some configuration and it's going to be dme and config and that's all right now we are able to reach our data but we are gonna connect to mongodb of course you can use mongodb javascript library directly but there is one more option and it's my favorite and it's mongoose and one of the most important thing is we can create any collection schema you can give its properties and its type let's copy this and add here and add a mongoose and let's see how we can connect i'm gonna click here and as you can see we are gonna use mongoose connect methods and inside we are gonna pass our url let's copy this i'm gonna come here and paste of course we should import mongoose and it's gonna be our secret url so i'm gonna say process emv and remember what was the name just and after that if there is an error we are just gonna throw this error in this case our application will crash let's come here and say const connect and it's going to be async function that because we are using a weight here and i'm going to wrap this function like that and whenever we connect it to our back-end server we are going to call this function like this if there is any problem with mongodb connection there is no sense to use our back-end server because it's just an api server if there is no db connection it means there is no api request so it's gonna return this error let's write here some console log and i'm gonna say connect it to mongodb i'm gonna save as you can see connected to backhand connected to mongodb i'm explaining this arrow throwing again and again that because it's really important to understand that it's our initial connection if there is a problem it's not able to connect again and again it's not gonna try but if our initial connection is okay then some problem happens in our mongodb after that it's not a problem it's gonna try to connect again what i mean by that let's say mongoose and connection it's gonna listen our connection and if there is a disconnection problem disconnected we can just log this problem let's say mongodb disconnected and in this case if it disconnected it's gonna try to connect again so let's write one more listener for example and it's going to be connected mongodb connected as you can see connected to mongodb so if i come here and for example for my network access if i delete this ip address it's going to return our error here mongodb disconnected we should wait that because it's going to take time as you can see mongodb disconnected but if i add here this ip address again access from everywhere i'm gonna confirm it's gonna take a while and we are gonna see that it's again connected as you can see we didn't do anything it's gonna reconnect again and again and this is why this initial connection is important i've just seen many questions in our discord group and facebook group and i just wanted to explain by the way guys if you are not following discord or facebook groups links are gonna be in the description i highly recommend you to follow them you can help each other okay let's try to understand how an api works i'm gonna come here and i'm gonna say app.get and i'm gonna write here any endpoint let's say the home page the main url and here what express does is taking a request and response parameters and use it inside any api request what's this request basically whatever comes from a user who is making api request and this response will be what we are sending to our users as a response let's say response and i'm gonna say send or if you are sending a new object you can say json doesn't matter let's say send and i'm gonna say hello first request i'm gonna save and if i come here and open localhost 8800 we are gonna see a response here and if i say here for example users i'm going to refresh here as you can see cannot get that because we don't have any function but if i go to users we are going to see our response again and i'm going to explain these requests later of course we can't have any get methods post methods put delayed or any others we are gonna use all of them but there's a small problem here that because we cannot write all of our request functions in the index file it's going to be probably thousands of lines to prevent this we are going to create one more folder here by the way they are not inside our api folder i made a mistake here i'm sorry for that i'm going to move them here and in this case it's not going to be booking app we are going to go inside api and start again okay let's lay this one you don't need that i think we can delete this one also but if you want to lock your disk connection in a text file or something like that you can use this function okay anyway so what i'm gonna do is creating here one more folder and it's gonna be roots which roots we are going to use we are going to use users we will be able to add new user update delayed whatever and second one will be hotels hotel rooms and finally i'm going to add one more route here and it's going to be auth so for authentication we are not going to use users root we are gonna use a specific one it's gonna be separated because it's really important we are gonna use cookies json web token basically it's better to separate this file but how we are gonna use them again i'm gonna use express here and i'm gonna say const router and it's gonna be express router and i should export this i'm gonna say export default and router in this case we can take any api request using this router let's say get method main url again request response and it's going to be let's say response send hello this is auth endpoint i'm gonna save and i'm gonna use this inside index file to do that we should import this i'm gonna say import authentication root you can name this whatever you want but because we are using export default and it's gonna be from roots and auth and be careful here if you are using import in express server you should write here js also for libraries you don't need anything but if you are using any file don't forget to add this x action okay let's use it i'm going to come here and i'm going to create a middleware let's say middlewares and i'm going to say appuse this is how we are creating any middleware if you are not familiar with middlewares don't worry i'm gonna explain them you're gonna understand better but for now let's say any url here it can be authentication and if you visit this endpoint i'm gonna say use oauth route whenever we make requests for this endpoint it's gonna use our route here and it's gonna look at any other endpoints for example this one let's try so you can see better i'm gonna say house and i'm going to enter and as you can see this is all endpoint i can do for register for example both and register endpoint i'm going to say register and enter as you can see it's here perfect it works like that by the way if you want to you can give here any common endpoint like api or if you want to you can write here your version version 1 but it can stay like that in this case we should add here api also and that's all so i'm gonna do the same thing for others for users hotels and rooms users hotels and rooms and i'm gonna import them of course we don't have yet but we are gonna create hotels and rules okay let's copy everything here and i'm gonna paste for these rooms of course we don't need them hotels and users so let's close everything here and for better understanding let's create new hotel and update delayed and get methods so first one will be create update delayed get and get all let's get started i'm gonna say router and it's gonna be post method that because we are creating and it's gonna be main url and request response and we are gonna try to create new hotel to do that we are gonna need hotel model one more folder here is gonna be models and inside let's say user.js hotel.js and room.js basically we are going to create our schemas let's come here as i mentioned before we are going to create this schema and we are going to export it let's close them for now we are gonna create them later let's see what we are gonna do we are gonna import them like that and i'm gonna say const hotel schema and it's going to be new mongoose and schema and we are going to write our properties first one will be hotel name we are going to specify its type it's going to be string and i'm going to say required and it's going to be true because we cannot create any hotel without hotel name and for others let's say type is going to be string again and required basically it's going to be type of our properties it can be hotel or cabin or apartment whatever and it's going to have st let's copy this and let's say sd and address and distance from center it's gonna have some images let's say photos but this time it's not going to be string that because we are going to have multiple images so i'm going to write here array and each item inside will be string it's not going to be required i'm going to delete here and we are going to have hotel description let's say description like that it's going to be string and required and also we are going to have hotel rating it's going to be a number it's not going to be required at the beginning we are not going to have any hotel rating but we are going to limit this i'm going to say minimum will be 0 and maximum will be 5. it's going to be in this range and what else is going to be rooms i'm going to lay it here and again it's going to be an array that because it's going to include room ids which we are going to create later here basically it's going to be a child of hotel and let's write cheapest price the price of the cheapest room is going to be number i'm doing this that because let's say we have hundreds of rooms and checking their price for the cheapest one can be tough the owner of the hotel or admin can just update this price finally featured and it's going to be boolean and by default it's going to be false basically in our react application we are going to show some featured hotels that's why we are using this and that's all let's create our model and export i'm going to say export default and it's going to be mongoose.model and we are going to write here model name it's going to be hotel and to create this model we are going to use hotel schema by the way we don't have to use this schema we are already using like that so i'm gonna come here and i'm gonna try to create new hotel to do that i'm gonna make here async that because we are gonna connect to our db try to create new collection and new document inside so it's gonna take time that's why we are using async and let's say try catch block if there is an error we are gonna send this let's say status 500 which is server error and we are going to send this error but don't worry this time we are not going to be sending our errors like that we are going to handle them we are gonna specify them you are gonna see how to handle arrows using express middlewares so don't worry about that but for now i'm just showing for beginners how to make a real request so let's come here and take hotel information from user i'm gonna say const new hotel and it's gonna be new hotel remember this is our model and inside i'm going to say request and body so what does it mean basically as i said request is what we are taking from user we can take any parameter here or we can take any query like that limit five or we can take body which i'm gonna show you soon in this software so basically it's gonna store our hotel information let's delete here it's gonna be home homepage and what we are gonna try i'm gonna come here const saved hotel it's gonna be great we are gonna use new hotel which we have created and just save and if it's successful we are gonna return this hotel so i'm gonna say response status 200 which is successful and json saved hotel oops there is a problem ah okay as i said if you are using import you should write here js okay so let's come here we are gonna use insomnia to make api request of course you can use postman or you can even use your vs code but recently i'm using this insomnia it's much lighter than postman we are gonna just make api requests so it really doesn't matter which one you are using so i'm gonna say new request and it's gonna be create hotel and it's gonna be post methods and here as you can see there is a body and i'm going to choose json and i'm going to send hotel information remember what we have inside i'm going to write them quickly name types d and others okay let's give its name by the way i want to check something here okay we forgot hotel title it's gonna be string and required okay let's say hotel i don't know i'm using joan everywhere it's going to be hotel st will be let's say berlin address somewhere distance 500 matters from city center and best hotel in this d and hotel description it should be longer but anyway and price will be number remember so let's see 100 features will be actually we don't have to write this because by default it's false and that's all let's try of course we didn't write our endpoint it's gonna be localhost and our port number and remember api and we are gonna use hotels endpoint and that's all i'm gonna try to send and there is an error here i just wanted to show this error to you that because it's a common problem in our discord server let's come here by default you cannot send any json object like this to express server to prevent this we are gonna use another middleware here and it's going to be f.use express and json i'm going to save and i'm going to send again and 200 successful as you can see this is the unique id of our document let's check i'm gonna refresh this page actually it was network page but okay let's come here db bros collections and as you can see it created our db immediately and inside we have a collection which is hotels and in these hotels we have a document as you can see all those informations are here perfect so we can do the same thing for others not same of course but similar things when we update anything we are going to use put methods and this time we don't need that we already have inside rdb let's say updated hotel awaits hotel model and we are going right here find by id and update so we are gonna pass here our id about how we are gonna take this it's really easy we are gonna use request parameters let's say id and we are gonna pass it here it's gonna be request params and id and after finding our hotel we are gonna update it to do that we are gonna use mongodb set method and here we are gonna pass what we are gonna change and it's gonna be inside request and body and after that if it's successful we are gonna return this i'm gonna save and let's create another by the way we are gonna need this id so i'm gonna copy and i'm gonna create new request it's gonna be update hotel put methods and we are gonna have json buddy i'm gonna create localhost hotels and we are gonna pass here our id and finally inside body we are gonna send what we want to update let's say hotel name it was hotel john but this time it's going to be hotel g let's send and as you can see it's still hotel jump but if we check our db here i'm gonna refresh as you can see it's hotel j why it's happening is that because find by id and update method is gonna return the previous document not the updated one to prevent this i'm gonna come here and write one more option and it's gonna be new and true in this case after updating it's gonna return to new version of our document i'm gonna save and let's create again hotel awesome hotel i'm gonna send and this time as you can see it's the nearest version perfect so let's come here and do the other things it's going to be id again but this time find by id and delete in this case we don't need them it's going to be only hotel id and it's not going to return anything that because we are deleting let's make this delayed by the way and if everything is okay we are gonna just send a message hotel has been deleted and that's all if you want to get a specific hotel it's gonna be get we are gonna take id again let's say hotel and this time we are just going to find it we don't need them and if it's successful we are gonna return this hotel and one more thing get all methods basically it's gonna get all hotels so we don't need any id anymore and this time instead of find by id it's gonna be just fine basically it's gonna fetch all hotels let's say hotels and it's gonna restart i'm gonna save and let's copy this actually let's say get hotel it's going to be cat method i'm going to paste and that's all it's here sorry it should be like that it's our specific hotel let's create one more hotel chain i'm gonna send and if i create one more request get all hotels localhost api hotels i'm gonna send and as you can see all hotels are here and one more and it's going to be delayed hotel it's going to be delayed methods localhost api hotels and i'm going to give specific id here and if i say send hotel has been deleted let's check here i'm gonna refresh and as you can see only one hotel here let's try to understand how to handle errors in express server to do that firstly we should understand express middlewares why middlewares are really important that because it's able to reach our requests and response before sending anything to user what i mean by that let's write here another middleware so i'm gonna say use we can reach request and response and also we are gonna use next callback function you are gonna understand better don't worry just listen so i'm gonna come here and i will say console.log hey i'm a middleware and i'm gonna go to hotels let's choose get all for example doesn't matter i'm gonna say console.log hey i'm a hotel root and after if i use here next and if i say next let's see what's going to happen i'm going to go to get all hotels i'm going to send and as you can see hi i'm a hotel root i i'm a middleware so what happens here basically whenever i run my application it's gonna be ready for any api request and as soon as a user makes an api request it's gonna come here and check all middlewares firstly it's gonna come here and it's gonna say okay in your api request you can use anybody so it's gonna come and check our routes which we are using hotels so it's gonna run this one we are going to hotel routes it's writing console.log i am a hotel root and after that it says next basically it means go to next middleware and what's the next middleware we are not using rooms it's gonna be this middleware it's gonna come inside and it's gonna say hi i'm a middleware so basically you can send anything to user here you can interrupt your api request here and you can send anything else let's say response send hello from middleware if i make this request as you can see it's not sending this user anymore that because we are going to next middleware and it's sending this message to us and by the way our application has crashed there is one of the most common problems it happens when you don't use any return statement yes we are going to another middleware but there is one more function here we didn't end them so instead of next i'm gonna say return next and let's try again and as you can see there is no error anymore that because we are returning a response okay so if i move this middleware here at the beginning and this time let's delete here and i'm gonna say next of course let's say console log a middleware i'm gonna send and this time as you can see a middleware that because it visits this middleware first and after that we are going to next one which is api and hotels and it executes those functions it's that easy so instead of this middleware i'm gonna use a specific one it's gonna be error handling middleware so i'm gonna write here but the different thing is we can actually have an error parameter here so if any error occurs in our any route here any api request right now we are able to handle this error so i'm gonna say return response and status will be let's say 500 we are going to change this and json will be hello error from handler it's a specific middleware that we can use for error handling don't forget it's gonna take four parameters and it's gonna be in this order error request response and next otherwise it's not gonna work and if i come here let's like this and if there is an error instead of sending this like that i'm gonna say next error of course when we make requests it's gonna work to prevent this let's say find by id for example and i'm going to write here any id which is wrong and let's say send and as you can see error from handler and it's awesome that because we are able to customize our arrows right now we don't have to write 500 we can send specific one or we can send specific message to do that i'm gonna say const error status it's going to come from our error and status or if there is no status it's going to be 500 and i'm going to do the same thing for message error message error dot message and if there is no message we are gonna send something banned wrong and in this case our status will be error status and our message will be error message of course you can customize here let's do that actually i'm gonna say success false we can send status again for users and we are going to send message it's going to be error message and also what else you can send you can send stack it's going to give more details about our error so it's going to be error.stack you can send whatever you want there is no certain rule so let's come here let's send again actually and as you can see successfalls 500 and this is what mongodb sends us as a error message and this is stack which explains more details so let's imagine you are doing one more operation here of course it's going to be a fake operation and let's say it failed and if it fails you don't want to try and catch any hotel you just want to return any specific error so i'm going to say cost error is going to be new error and let's say error.status 404 error dot message sorry not found and we are going to return our next function here and inside we are going to return this error let's see of course i'm going to say if failed let's try i'm gonna send oh what happened here status is oh sorry it should be equal of course it's not a function a message we are defining from scratch let's try again i'm gonna send and as you can see 404 sorry not found and there it error occurs okay perfect it's that easy of course each time sending these like that is not a good idea instead i'm going to copy this and i'm going to create one more folder let's say utils and i'm going to create error file arrow.js and i'm going to create a function const actually let's say export const we are gonna import this in our roots so i'm gonna say create error and it's gonna take two parameters status and message and we are gonna create our error here of course status will be status which we are going to send and this is going to be message and finally we are going to return this error i'm gonna save here and let's come back instead of this i'm gonna say create error like that and i'm gonna give status let's say 401 and message you are not authenticated and if i come here and send again and this time as you can see 404 sorry 401 you are not authenticated perfect it's gonna work like that but right now we don't need that we are gonna use this later and it's gonna be fine again let's slate this also okay perfect i hope you understood how it works and let's create the most important part and it's going to be authentication it's important that because we are going to make all our requests using those authentication rules otherwise everyone can delete our users hotels rooms everyone can update them there is no rule here if someone get this url they can just execute them anywhere to prevent this firstly we are gonna create our users then we are gonna give authentication and authorization rules but before that i wanna do something more here what i want to do is moving all those operations in a different folder so i'm gonna create here new folder and it's gonna be controllers let's create our files for user of course you can say user controller or whatever you want to name it hotel room and authentication i'm gonna close them and first one will be create new hotel so i'm gonna say export const create hotel it's gonna be async request response and next and i'm gonna move everything here i'm gonna take this and paste here by the way we are gonna send our error using next and i'm gonna use this function here i'm gonna delete here and it's gonna be our function let's import and that's all it's much more clear because it should show us only our routes only endpoints and all those process will be in these controllers and update late get and get all let's say update delayed get and get all or get hotels let's put them here i'm gonna copy and for updates i'm gonna paste here i'm using next be careful about that and play it like that get and get all like this okay i'm gonna save here by the way we should import hotel model and we should write here js okay let's delete them and call our functions this one will be update hotel delayed hotel get hotel and get all hotels like this let's try again i'm gonna send okay it's here it works so what i'm gonna do is closing everything here and opening authentication let's delete this one and then we try to register we are gonna call our controller function let's come here and i'm gonna say export const register async function again and it's gonna take request response and next and we are gonna make our operation here let's save and let's use this function here okay we are ready quickly i'm gonna write my try catch block if there is an error we are gonna use next and send this error and what we are gonna try firstly we are gonna create new user let's say const new user i'm gonna say need user but of course we didn't create our models let's come here actually i'm gonna copy here and paste and i'm gonna change this name it's gonna be user and what we are gonna have firstly we are going to have a username it's going to be string required and also i'm going to say unique that's because we shouldn't create any other user with this same username so it's going to be unique so i'm going to do the same thing for email and let's say password and finally it's going to be is admin to do that we can use this featured it's a boolean is admin default is going to be false and i'm going to delete the rest like that okay and one more thing i'm gonna add here and it's gonna be timestamp timestamps and it's gonna be true basically it's gonna give created add and updated at times i'm gonna save okay we can use it i'm gonna import this user and inside i'm gonna say username it's gonna be request body and username email and password we can directly write here request and body but i'm not doing this that because we are going to change this password we are going to encode this password to provide more security so it can stay like that and i'm going to say await new user and save and if it's successful i'm gonna say respawn status 200 by the way you can use 201 also which means created successfully it doesn't matter and i'm gonna say user has been created there's a problem here i forgot this js in this route i think okay this js okay it's ready let's come here and try to register i'm gonna create one more request and it's gonna be register it's gonna be post method did we say post or not okay it's gonna be post i'm gonna save and we are gonna give json object let's write here localhost api and auth and register and i'm gonna pass here username let's say john email john gmail.com and password like that i'm gonna send and as you can see user has been created let's check here i'm gonna refresh and we are gonna see our user here okay perfect user and john but as you can see our password is what we have written but we shouldn't reveal our passwords like this even if in this db so what we are gonna do is encoding our password to do this we are gonna use one more library yarn add and it's going to be pcrypt.js i'm gonna install actually let's check how it works as you can see we are gonna import this first by the way it's a really popular node.js library so we are gonna use this tool and as you can see to hash our password we are gonna use this function we are gonna generate our hashing method here and after that we are gonna use this function it's gonna be our request buddy and password and it's gonna give us our hashed password let's copy this i'm gonna come here and let's say const first this is gonna be our request body and password and instead of this request buddy we are gonna use hash password it's that easy let's try again i'm gonna come here john 1 and i'm gonna send oops we didn't import let's take this import decrypt from eclipse.js i'm gonna send again user has been created and let's check and this time we have this hashed password and it's much more secure right now so what else we can do we are gonna create login function let's say login and here i'm gonna create by the way i shall save this to use this login function login and login endpoint okay what we are gonna do firstly let's see i'm gonna copy here and create new request i'm gonna say login again post methods and it's gonna be json and i'm going to paste it here this time it's going to be login and what we are going to send we are going to only send our username john 1 and password like that so basically we are gonna take this username and try to find it inside our db so i'm gonna say let's actually delete here and i'm going to say const user and it's going to be user dot and i'm going to say find or find one let's say find one that because we have only one user with this username and i'm gonna write here my condition username will be request body and username and i'm gonna create a custom error here i'm gonna say if there is no user return next and i'm gonna create error 404 user not font and after that if there is no error we are gonna try to verify our password that's because in request and body it's one two three four five but in our db it's this hash password so how we are gonna compare that let's come here and as you can see to check a password we are gonna use compare function and it's gonna be our password and we are gonna compare with hash password i'm gonna say const is password correct and it's gonna be await again that because it's an async function decrypt and compare function and we are gonna send our request buddy by the way it's gonna be buddy and password and we are gonna compare with our password here and it's going to be user.password and again i'm going to create one more error here if his password correct is not correct if it's false it's going to return 400 and it's going to be bad request we can say wrong password or username and finally if everything is ok we are going to send our user let's say json that sent let's see okay i forgot a wait here i hope that's the reason let's send again okay wrong password or username if i correct this but if i write wrong username user not found if i correct them it returns our user perfect but as you can see it returns this password also in our react application we are gonna store this user so we shouldn't send our password to prevent this what i'm gonna do is writing here const and i'm gonna destructure my user it's gonna be password by the way we can delete this is admin also that because in the client side they can change it actually we are gonna use jwt but in any case let's write it also and for other properties we're gonna use other or other details and we are gonna use it here of course inside an object we are gonna spread other details let's see as you can see there is something strange here that because our user object it's inside user and underscore dock so what i'm gonna do is writing here talk and let's try again okay perfect right now we don't have its admin or password but we didn't end yet that because we are gonna send jwt to do that we are gonna add json web token and basically we are gonna hide our user information in this json web token and we are gonna send it as a cookie so whenever we make let's say update hotel api request we are gonna check first this json web token and it's gonna decide whether the user is admin or not if it's not admin we are gonna send an error and if it's admin it will be able to update hotels or delete or whatever you want let's use jwt here and if password is correct we are gonna create new token token is gonna be jwt and sign and inside we are gonna give our information whatever you want but what i want is giving my user id it's gonna be user dot id remember it's underscore id we are gonna use it and also we are gonna use is admin it's gonna be user dot is admin basically we are gonna hash this information and for each request we are gonna send this jwt to verify our identity and one more thing we are gonna need here and it's gonna be a secret key you can write here any key but let's generate here i'm just gonna generate a random key you can use it in your linux or windows machines open ssl base64 okay it's gonna be our secret key and again we should hide this so i'm gonna go to dot emv and i'm gonna say jwt secrets or directly jwt and i'm gonna use it here process emv and jwt and right now let me show you this what i'm gonna do is setting this token into our cookies to do that i'm gonna install cookie parser i'm gonna say here and add cookie parser and inside index.js we should use it as a middleware i'm gonna import and here let's say app.use cookie parser okay let's send this before status we can send this here i'm gonna say dot cookie and its name will be access token and we are gonna pass our token here and also we can write any configuration here and the most important will be http only it's gonna be true why we are doing this that because basically it doesn't allow any client secret to reach this cookie so it's much more secure right now and let's save and see i'm gonna send as you can see user is here and if i click on these cookies as you can see our access token is here perfect right now we are able to use this token when we delete our hotel we are gonna send this cookie and it's gonna verify our token first after verifying it's gonna check our user information and if it's admin we are gonna be allowed to delete this hotel it's that easy so what i'm gonna do is closing this authentication and i'm gonna come here and copy those and paste for user and we are gonna change those hotels it's going to be user let's change here users and users it's exactly the same thing of course we are not going to create any user we already have register function update user delete user get and get all users let's use them inside user root again i can copy them and paste here where is users okay here and this time it's gonna be user let's delete here okay let's import them it's going to be just by the way delay user get user and get users right now i'm gonna show you how we can verify our jwt let's come here and i'm gonna write requests and it's gonna be update user put methods json and what i'm gonna do is changing my username username it's gonna be john updated of course we are gonna need our user id this one i'm gonna write here localhost users and user id if i click on send button it's gonna update but i don't wanna do that that because firstly we are gonna test our token to do that i'm gonna create new file inside these utils and it's gonna be verified token we are gonna need jwt and create error firstly we are gonna verify our authentication so i will say export const verify token and it's gonna be request response next and we are gonna take our token from our cookies so i will say const token request cookies and access token remember its name was access token and if there is no token it means we are not authenticated so i'm gonna say return next and we are gonna create new error it's gonna be 401 and i'm gonna say you are not authenticated if there is a token it doesn't mean it's a correct one we should verify this and i'm gonna use jwt and we are gonna use verify function and we are gonna pass in token of course we are gonna need our secret key env and jwt and after that it's gonna return as either an error or our information let's say user remember it includes this information and i set user for them and i'm gonna come here and i'm gonna say if there's an error it means verification is not successful so we can return an error i'm gonna say 403 and we are gonna say okay you have a token but it's not valid token is not valid but if there is no error if everything is okay we are gonna set new request property i'm gonna say request dot user and it's gonna be our information user id and is admin and pay attention here you can write here whatever you want it really doesn't matter at the beginning we don't have anything like that we don't have user and we can assign any new property here and it's going to be our information and after that what i'm gonna do is writing next so it's gonna run this middleware if there is a error here it's gonna return if there is no error it's gonna check our token if everything is okay we are gonna go to next operation so how we can use this let's come here and create another request here i'm gonna say get and let's say check authentication and i'm able to use my verify talk middleware here and after that i'm gonna say response sorry request response and next so what it's gonna do i've already explained how middlewares work whenever we make requests for this endpoint it's gonna go to verify token if everything is okay it's gonna say next and we are gonna come back here and we are going to apply this next function and i'm going to say response send hello user you are authenticated or you are logged in let's try i'm going to copy this and let's paste here i'm going to send of course it should be get methods hello user you are logged in that's because we have a cookie here but if i edit this let's change in this case token is not valid yes we have a token here but it's not correct but if we don't have any token i'm gonna delete i'm gonna send and this time 401 you are not authenticated you cannot reach this data and again i'm gonna log in and we have a cookie right now and let's send hello user you are logged in but what about if we try to delete or update our user of course we are not gonna do right now but i'm just gonna show how we can verify our user i'm gonna say check user and i'm gonna give here its id and i'm gonna say hello user you are logged in and you can delete your account but this time we are not gonna use this middleware instead we are gonna create new one i'm gonna say const of course export const verify user request response next and firstly we are gonna call this function that because to verify our user it should be authenticated first we are gonna send request response next and i'm gonna write here a callback function and i'm gonna write my condition i'm gonna say if request dot user dot id we can use this user right now and if it equals request params.js remember we are sending our user id here if it equals this user id which is inside jwt token it means we are the owner so i'm gonna say next and if it's not we are gonna send another error it's gonna be 403 again but this time it's gonna be you are not authorized and in this case the only owner of this user can delete account but not only user and also if request user is admin they can also delete this usage so let's use this here i'm going to copy and paste okay it's here i'm gonna save and that's all i think by the way we don't have next year otherwise it's gonna go to user's root again it's gonna take request response if everything is okay it's gonna come back here again and we are gonna check if it's if it's the owner or not or if it's an admin if everything is correct finally we are gonna go to users so let's use this check user and i'm gonna give id here actually let's give other users id i'm gonna copy and paste here and let's check i'm gonna send as you can see for all three if i write my own id here i'm gonna send and hello user you are logged in and you can delete your account your account and one more thing we are gonna verify and it's gonna be is admin i'm gonna duplicate this and verify admin and we are gonna verify our token again but this time only condition will be request user and is admin let's try one more i'm gonna say check admin hello admin you are logged in and you can delete all accounts let's try i'm gonna send oops i forgot verify admin here i'm gonna save again okay we are not allowed to do that but if i come here and change this it's going to be true i will update of course we should delete this cookie it stores information that we are not admin i'm gonna delete and in this case we have to login again i'm gonna log in and let's try again hello admin you are logged in and you can delete all accounts perfect it's gonna work like that so i'm gonna comment this out so it can stay in our github repository you can check so what i'm gonna do is giving verification middlewares for them update user will be verify user so owner or admin can update this same thing here and again get user but forget all users only admin can do this so i'm gonna say verify admin and that's all so i'm gonna do the same thing for hotel let's close everything here and i'm going to come here and for creating hotel we are going to be verify admin or for update delayed everybody can get hotel or at least all these hotels so we don't need that here and that's all let's import this by the way it's not coming utils and verify token i'm gonna come here for this hotel i'm gonna try to update i'm gonna write updated it's gonna be hotel id i'm gonna send and as you can see we have updated if i delete this cookie wait a second it's coming here because of this next item i made a mistake here it should be next also let's see okay it works let's login again we have a cookie here i'm gonna try to update okay it works so we need this next year also by the way guys if any error occurs here i'm gonna update in the github repository if there is any mistake we are gonna fix it don't worry and that's pretty all so let's create room model i'm gonna come here and copy this and paste here i'm gonna change this name it's gonna be room model and let's change it firstly it's gonna be a title it's gonna be string required i'm gonna delete here and second one will be room price it's gonna be number required and description again string and one more number is gonna be maximum people that can stay in this room it's gonna be number and required and finally we are gonna have room numbers and basically it's gonna be an array and it's gonna include all room numbers what i mean by that basically this room includes all room information let's say title big room with two beds we are gonna have price maximum people too and some description but we will be able to have more than one room like that imagine you have a hotel and the first floor has too many rooms and all those rooms are the same their title is same price same maximum people same and only difference is their room numbers basically we are going to add room number and its type will be number and one more thing we are gonna add and its gonna be unavailable dates so when somebody reserved this specific room we are going to add here unavailable dates so nobody can resolve this room again and it's going to be array again and each item will be date let me show you an example here it's going to be an array and first room will be let's say number 101 and it's going to have unavailable dates by default it's going to be empty and we are going to have more rooms like that one or two three four five okay it's enough and when somebody tried to book or reserve one of these rooms we are gonna come here and update one of them actually there is a mistake here let's remember how we are doing if you remember we say type an array like this which includes only strings so we are going to do the same thing it's gonna be type and this time it's gonna be date so basically it's gonna be first of may 2022 second of may 2022 it's gonna work like that i hope you understood so let's create quickly our controllers first one will be create room async request response next but this time we are going to do something different that because remember in our hotel model we have rooms here and it includes a room id like a parent and child so what i need is one more model here and it's gonna be hotel basically after creating a new room we should add this room id inside room array here what i mean by that let's say const hotel id it's going to be request params we are going to send this as a perm and let's say hotel id and i'm going to say const leave room it's going to be new room model and it's going to include request and buddy let's write here try catch block if there's an error next arrow and what we are going to try firstly we are going gonna save our room i will say const saved room and create new room and we are gonna save it and after that i'm gonna create new try catch but because we are gonna update our hotel next error you don't have to write another try catch by the way and i'm gonna say await hotel and find by id and update remember our hotel id is here we can use it and after that we are gonna add this saved room id inside hotel and rooms to do that we can use mongodb push method basically it allows us to push any item in any array so i'm gonna say rooms and what we are gonna push we are gonna push save room dot id and finally we are gonna send our response status 200 and json save true and others will be the same actually let's copy and paste from here there is nothing different it's going to be update room this time we are gonna find by id and update we are gonna set new one and finally we are gonna return the newest version of our document and we are gonna send it to user and it's gonna be delayed room get room and by the way let's make this lower case and get rooms like that okay let's write them here let's copy here and for rooms it's gonna be verify admin again i'm gonna say create room let's import this also when we update we should be admin again update room delayed get and get all rooms but remember for creation we are sending hotel id so what i'm gonna do is writing here hotel id parameter and we are gonna use it of course js okay let's try i'm gonna take this hotel by the way let's refresh i'm not sure if it's still same or not okay we have updated so i'm gonna come here and say create room it's gonna be post json and i will say localhost rooms but we are gonna pass here hotel id and i'm gonna write first title king groom and description king size bed one bathroom and let's say for example balcony and price will be 100 by the way there is a comma here and maximum people it's gonna be two what else we have price maximum people description and room numbers room numbers it's going to be an array and in this array we are going to have each individual rooms let's say number it's going to be 101. let's create another one number 102 let's create okay as you can see our numbers are here 101 unavailable dates perfect and if we go to any hotel here let's say get all hotels i'm gonna send as you can see our room number is here by the way when we delete our room we should again update our hotel we are gonna do this similar thing i'm gonna take hotel id and we are gonna try catch and update our hotel i will come here and paste but this time it's gonna be pull and we are going to give here request params.id let's try it was our room id i'm going to create new request and it's going to be plate room delayed method i'm gonna create localhost api rooms and it's gonna be room id and it's gonna be hotel id let's see here this is our hotel i'm gonna copy and paste here of course we didn't create our route so i'm gonna come here and for delayed method it's gonna be id and hotel id i'm gonna save and let's try i'm gonna send room has been deleted let's check our hotel here i'm gonna send again of course it's gonna be params there was a mistake here let's delete that i'm gonna delete this okay let's create again and let's try again create room i'm gonna send this is our room id and again i'm gonna try to delete this zoom i'm gonna copy and i'm gonna paste it here let's send room has been deleted get all hotels and as you can see it's empty okay perfect so we have finished our backhand server for now of course we are gonna add some additional things for example for this hotel we are not gonna only get whole hotels and also we are gonna add here our limitations our conditions like get by st get by featured or get only 10 items but it can stay for now let's create a react application here i'm gonna close here oh my god forgot going into api but don't worry it's just three items let's say yeah and add big crypt jazz cookie parser and json web token i'm gonna enter it's gonna install those libraries and after that we can delete them okay it's ready as you can see so let's delete them okay so what i'm gonna do is creating here a client folder and inside this folder i'm gonna create my react application let's visit our github repository and here as you remember we have this branch which includes our ui we are gonna clone this to do that i'm gonna choose this url and i'm gonna use only this branch react booking ui so let's get inside client and i'm gonna say git clone single branch and i'm gonna write here my branch name which is react booking ui and i'm gonna paste my url and i'll say dot and enter and as you can see our project is here of course we don't have our libraries i'm gonna basically say yarn and it's gonna download all those libraries okay it's ready let's start our application yarn start and it's here perfect and as you realize here we are gonna need hotel numbers by city name and here again we are gonna get numbers by its type and finally we are gonna get some featured hotels so let's come here let's see what's inside our homepage actually i'm gonna close everything here and i'm gonna show you this and let's open back and as you can see featured property list and featured properties featured property list and featured properties so let's open this component featured so basically we are gonna get this number using this t okay basically we are gonna get some more end points for this one is gonna be count by st count by type and we are gonna provide a query and it's gonna take only featured hotels so let's do that i'm going to come back here for routes hotels and it's going to be two more and let's say count by city name and count by type let's create our controllers let's duplicate this actually it's gonna be count by st and we are gonna have a query what i mean by that let me write here count by city basically we are gonna add a query here to do that we are gonna use question mark and we are gonna write our query name which is this and we are gonna write here city names let's say berlin madrid and london so how we are going to use these cities let's come here and i'll say const st it's going to be request query and steez by the way there is a typo and it's gonna return us this string but i want to transform them into an array to do that we are gonna use split method and we are gonna split them using comma it's gonna split this word and after that it's gonna start here stop start and stop and it's gonna make them an array and here i'm gonna create a list and i will say await but this time we are gonna try to find multiple items that because we are gonna have three states here so in this case i'm gonna use promise and all and for each test will say map we are going to return hotel but this time we are not going to use find and st and its length of course you can do this but it might be a little bit expensive that because it's gonna fetch all those data their properties and after that it's gonna find its length so instead of that we are gonna use mongodb count document and here i'm gonna say csd so it's exactly the same thing but it's not fetching any property it just shows its count and it makes it much faster and after that we are gonna return this list let's try by the way we should call this here okay firstly i'm gonna create some hotels it's in berlin let's say madrid hotel jain one two three and four will be in london let's create okay so i'm gonna create new request here get hotel count hotels is going to be count by st and actually we are going to use this endpoint barely madrid and london i hope everything is okay let's send okay there is a problem here it's looking for an id but we are giving count by st why it's happening that because as remember we are using this id for getting a single hotel here and this express server assume that this is an id because there is a slash here and after there is some word and it's exactly the same thing slash and id to prevent this what we can do instead of only id we can just write any specific word here like find okay i'm gonna save and let's try again i'm gonna send and as you can see berlin is one madrid three and london one so let's use it here i'm gonna come back and what i'm gonna do is creating a custom hook that we can make any api request and fetch data so i will say hooks and inside i'm gonna say use fetch to fetch our items we are gonna be using axios so let's create one more terminal here and i'm going to say cd client yarn at axios and let's create our function const use fetch and it's gonna take a url and i'm gonna create three use statehook first one will be our data data set data it's going to be used statehook and at the beginning it's going to be an empty string and two more is going to be loading set loading and error and at the beginning they are going to be false so basically when we make a pr request the loading will be true and after ending our request if there is a data we are gonna fill inside this data array if it's not successful the error will be true or we can just pass whatever the error is okay i'm gonna use use effect and whenever our url changes we are gonna fire this function so i'm gonna say const fetch data and it's gonna be an async function and firstly we are gonna set loading to true we are starting and we are gonna make api requests right now i'm gonna say const response and it's gonna be axios it's gonna be get method and we are gonna write here our url of course i forgot here writing try catch block if there is an error set error will be this error so if there is no error we are going to set our data let's copy this i'm gonna say response.data and we are gonna call this function here fetch data and that's all and of course after this process we are gonna set loading again and it's gonna be false okay so what i'm gonna do is creating one more function here and it's gonna be refetch of course we should cover this with this code bracket so if we need to re-fetch our data again we are going to use this function so let's export them i'll say return we are gonna send data loading error and refresh and i'm gonna export my component export default and use fetch by the way they are gonna be await okay let's use them inside our component i'm gonna copy this and i will say const data loading and error we don't need this refatch and it's going to be use fetch and we are going to write here our api endpoint of course you can say localhost 88 api and whatever you say but instead we are gonna use proxy for that i'm gonna come here and i will say proxy and it's gonna be our main url which is localhost port number and api i'm gonna save and i'm gonna come back here and right now i can write my endpoint let's copy here like that and let's see what's going to happen i'll say console.log data and as you can see our data is here 1 3 and 1. so we can use them i'm gonna delete here and firstly i'm gonna create a condition here i'm gonna cover them and i will say of course we should write here react fragments and let's close it here and i'm gonna say if looting is true we are gonna send loading plays and if it's false it means we have a data so we can use those items let's check this and instead of this one i'm gonna say data and first element and let's say it was berlin or madrid okay berlin and second one will be data and second item and third item of course you can change its names and images here but as you can see they are here by the way guys if you don't want to use react proxy i highly recommend you to use course middleware for your back-end server so i'm going to open new terminal it's going to be api and i'm going to say yarn add course let's import this course from course and we are going to use it here but it's not important for now that because we are using proxy so we are not going to have any problem and first component is ready so let's do the same thing for this one let's come here okay count by type and let's create it here i'm gonna duplicate and it's gonna be count by type let's use it here okay so what we can do we can basically take types again inside our query but i'm not gonna do this it's not like city we have infinite cities but we have only five items basically i can fetch all of them one by one if you want to you can use again this query and promise all but i'm just gonna fetch them hotel count and it's gonna be hotel count document and type will be hotel and i'm gonna do the same thing for others of course they are gonna be inside try and i don't need that anymore basically i'm just gonna send them let's open here an array and first item will be hotel and let's say count it's gonna be hotel count and others let's see i'm gonna copy this and paste here let's delete this query and i'm gonna send oops there is something wrong again i forgot to wait i'm gonna send and as you can see we have five hotels and others are zero let's use this i'm gonna come here and copy this and for property list i'm gonna use exactly the same thing use fetch but this time it's going to be count by type and we are going to use them here i'm going to cover this react fragment and if loading just say loading if it's not just show those items by the way guys instead of writing here any text you can show skeleton loading components to do that you can watch my previous skeleton video it's an awesome video that you can learn how to create animated loading components i highly recommend it okay so instead of writing them data012 what i'm gonna do is creating here an array let's say const let's say images it's gonna be an array and i'm gonna just pass those images here i will just copy paste like that so we don't need them let's delete everything and i'm just gonna leave one of them this one and i'm just gonna cover this and i will say if there is a data images dot map and for each image i'm gonna return this div like that and in this case we don't need this image anymore we can directly use image like that and i'm gonna write here data and which element i'm gonna use i can use its index remember we have five items here so it's gonna be index zero one two three four we can use them i and remember what it returns type and count we are gonna use this one dot count and for here it's going to be data i and type i can use same thing here let's see as you can see hotels apartments and others and their numbers perfect by the way for this item we can make this first letter capital so i'm gonna choose this h1 let's open up css here and i'm going to say text transform is going to be capitalize i'm going to save and as you can see they are uppercase right now by the way i'm gonna add here a unit key if you are using map don't forget to add here a unit key so i'm gonna say just i and also i'm gonna add here question marks just to make sure this data array is not empty and that's all i'm gonna refresh okay everything looks good so let's take care of these featured hotels i'm gonna come here and open up my sidebar and future properties i'm going to come here and copy this use fetchhook and i'm gonna import and right now we are gonna do something different let's check out our server hotels and as you can see this is gonna be our endpoint and in the controllers get hotel get all hotels and we don't have any query here that's right i'm gonna say request and query and let's check i'm gonna come here get all hotels i'm gonna delay it here and i'm gonna write my query and it's gonna be featured property true let's send okay it's empty i think we don't have any featured property yet okay it's false false everything is falsies i'm gonna change some of them let's say true second one start one and the last one let's see right now i'm gonna send and as you can see all those featured hotels are here and also we can give any limit here like that and in this case we are gonna fetch only three or four items let's add this i'm gonna come here and i'm gonna say dot limit and it's going to be request query and limit if i say 2 for example it's going to fetch only 12 of them what else we can add here we can add maximum or minimum price that because in our application we are gonna search for them and after that we will be able to change pricier in this case we can use the same endpoint but we can take the price between minimum and maximum to do that i'm gonna do something different i'm gonna say const we are gonna take from request and query but what i'm gonna do is taking here minimum and maximum and also others so basically i just separated them so i'm gonna come here take others other options it can be featured address type title whatever but minimum and maximum will be different cheapest room sorry it was cheapest price and i'm gonna write my condition here i'm gonna say greater than minimum and less than maximum if we do that i'm gonna save and i'm gonna send it's gonna cause this problem that because we don't have minimum and maximum price what i can do i can say minimum or 1 maximum if there is no maximum let's say this amount let's check right now i'm going to send and perfect so if i write here minimum let's say 10 and maximum let's say 200 i'm gonna send and they are here okay it works so we can use this endpoint here i'm gonna go to home page by the way for this logo we can use realcloud.link let's open up never and for this link i'm gonna say link and i'm gonna wrap this spam and i'm gonna import this i'm gonna say import link from real gratuate in this case i can give here any url so i'm going to say to and it's going to be home page as you can see its color is different that because it's a link right now what i'm gonna do is coming here and giving inner style color will be inherit okay it's white right now but we have a underline here let's delete this i'm gonna say text decoration and it's gonna be known okay perfect so when i click here we are going to home page perfect so let's fetch this data i'm gonna close this and i'm gonna come here and i will say featured true and i'm gonna give a limit it's gonna be four i'm gonna do exactly the same thing i'm gonna delete those three of them and i will say here if it's looting just right here loading or whatever you want if it's not just return this div i'm gonna go over here and of course we are gonna use map again cover this and i will say data dot map and for each item just return this div of course this curly bracket is here okay i'm going to give again my unit key and this time we can use item and id and it's gonna be item.name let's copy this it's gonna be item.city it's gonna be cheapest price and i'm gonna write here a condition that's because by default we don't have any rating and i will say if there is a rating just showed is d and it's going to be rating number like that so what about this image in our db we don't have any image yet but if you remember we are using an array here so what we can do we can take just the first item and we can use its image so i will say item dot photos and first sight let's see i'm gonna come here and i'm gonna refresh if you want to you can write here a condition if there is no image just don't show them but they can stay not because we are going to upload images and that's all for the home page i think it's working here and featured properties awesome so what about this search bar when i write here any st name when i choose any date range here i'm gonna search and as you can see we are gonna fetch one more hotel list here and its api query will be city madrid minimum price and maximum price of course at the beginning we don't have them yet but when i click on search button we are gonna refresh our hotes so let's do that i'm gonna close everything actually and let's open list so i'm gonna write here my hook use fetch i'm gonna import and here hotels and city will be destination actually i'm gonna use here a backtick so i can use my javascript code insights so i will say destination and if you want to you can give any limit here but it can stay for now let's use this data where are our items okay here i'm gonna delete them and i'm gonna use map i'm gonna say if it's loading right here loading text if it's not just return search item but of course we are gonna use map data dot map and for each item we are gonna return search item component and of course i'm gonna give unit key here and it's gonna be item dot id and also i'm gonna pass this item in this search item component so we will be able to use hotel information so let's open search item component and i'm gonna take this item and ak item dot images it's gonna be hotel name item.name item.distance it was distance or not okay it is title description okay let's use here it's description like that and again i'm gonna cover this and write my condition if item and rating you can show me this due and this number will be item dot rating and it's gonna be the cheapest price and what about this button again i'm going to use a link let's come here and say link from rearcrowder.com and i'm going to cover this and finally single hotel page but of course we are gonna use hotel id so let's say go to hotels page and single page and here use its id let's see i'm gonna come here and i'm gonna search again okay there's something wrong ah okay i said hotel it's gonna be hot house let's correct this okay they are here and when i click on this button we are gonna go to this specific hotel page and we are gonna fetch our data using this unique id but before let's take care of this search button as i said we are gonna consider this minimum and maximum price so i'm gonna come here and i'm gonna say two more use state let's say undefined undefined it's going to be minimum and maximum like that and then i change them okay it's here there is our input okay here i'm gonna say on change event i'm gonna set minimum it's gonna be event target and value let's copy this and paste for the maximum one and we are gonna set maximum and for our button i'm gonna write here on click method okay here i'm gonna say on click methods and we are gonna call handle click function let's create this i'll say const handle click and we are gonna use refresh function but in this case it's gonna affect the same url but we don't have minimum or maximum that's right here minimum will be this minimum price and maximum will be our maximum price let's see okay it's happening that because it's taking this undefined as a string so i'm gonna do the same thing here if there is no minimum it's going to be zero if there is no maximum it's going to be 999 of course you can't change here okay they are here i'm going to say actually they are in the same price let's change them for this madrid i'm going to change this price it's going to be 200 and for this one let's say 300 and i'm gonna save let's try again i'm gonna go to home page and it's the name okay a hundred to a hundred and three hundred i'm to change here let's say from 50 to 150 and as you can see it's here by the way it's changing immediately that because in our use facebook let's open up here use fetch as you can see for the use effect the dependency is url it means whenever we change this url it's gonna refresh again if you don't want that you can delete this dependency in this case if i change here as you can see it's not coming only when i click on this button it's going to refresh but it's not working let's see okay there's a typo here it's gonna be uppercase and here okay let's try again 0 to 200. i'm going to search as you can see only this one is here but actually i'm not going to delete this dependency i think it's better when i change here it's going to fetch immediately let's say 250 and it's here by the way it's not fetching 200 that because we set less than this amount if you want to you can say equal or less than but anyway it's not a big deal let's increase here and let's choose this hotel and what about this single page i'm gonna close everything and i'm gonna open hotel page here let's quickly import our fetch function and inside i'm gonna say hotels and i'm gonna give my hotel id but we don't have yet how i'm gonna reach this data it's really easy i'm gonna use use location hook let's come here i'm gonna say const location is gonna be use location hook and if i say console log and location as you can see our path is here so what i'm gonna do is i'm gonna simply this path name using those slashes and i'm gonna take this last item let's do that i'm gonna say const path and i will say location i'm gonna use split method and i'm gonna use slash here and remember we have three items here that because we have to slash here it's gonna be first item second item and third item so if i write here two it's gonna give me hotel id actually that's right here id and i'm gonna use it here let's come here and use it i will take this div i'm gonna wrap it call the brackets and i will say my loading condition if it's not loading it's going to return this div and i'm going to use my hotel information here let's grab it data dot name here is address here is distance cheapest price and here if you remember we are using this image array but we don't need this anymore i'm gonna delete here and i'm gonna say data dot photos okay it's for slider and also i'm gonna use it here data dot photos and what else we have title here and description let's save oops split is not a function oh why you are here i'm gonna paste this here and also i forgot path name here i'm gonna save and let's refresh right now it's giving this error that because we don't have any image yet let's check line 90 i'm going to come here okay as you can see i'm going to come here and i will say question mark which means if there is an image array so i can do the same thing here by the way it's not going to be source it's going to be directly our image and here okay let's see and right now we have one more problem that because i used wrong and point let's open up hotel router here and as you can see we should use find key before i forgot that i'm going to come here and add here find let's refresh again and right now it's here perfect of course it looks a little bit stretch that because we don't have any image and our address and description is really short but anyway it works we are gonna add them later but what about here as you can see it says nine night and here and according to this number we should update this price but we don't have our date range here so what we can do when we choose any date range here we can pass it into hotel page and we can use it here but to do that we should use app.js here and define our dates here and send to home page and hotel page basically we are gonna need prop drilling and it's not a good idea the best thing is using a state management tool or react context api and i checked your comments in the previous video and most of people just want to use context api so we can do that let's come here and inside source folder i'm gonna create one more folder and it's gonna be context so let's create here our context i'll say search context firstly what i'm going to do is creating here my initial state and it's going to include c at the beginning is going to be undefined we are going to have dates it's going to be an array and we are going to have options and remember we have adult undefined again children and room so let's create our context i'm going to say export construct and let's say search context i'm using export that because we are going to use it everywhere that because we are going to use it in different components so i will say create context and our initial state here so let's write here our actions to do that i'm going to create reducer i'm going to say search reducer it's going to be state action and we are going to use switch case and let's write here action type and our first action type is going to be new search so whenever we change our search information here we are gonna dispatch this action you are gonna understand better and in this case i'm gonna say return action and payload basically this payload is gonna be our destination date range and options and we are gonna update them in another case and it's gonna be reset search for example oops there is no column here i'm gonna say return our initial state it's gonna be again undefined and empty array here basically we are gonna reset and there's a warning here that because we don't use any default case that's right here default and we are just going to return our state okay let's use this reducer in our context i'm going to say export const search context provider and i'm going to write here children basically these children will be our components which we want to reach this data we are gonna wrap our application and you are gonna understand better just wait for a second and i'm gonna say const state and dispatch and it's gonna come from our reducer so we are gonna use use reducer hook and inside search reducer and also our initial state of course so let's return our provider here i'll say return search context and provider and we are gonna wrap our children and i'm gonna write here what we want to pass to children it's gonna be value and we are gonna pass city is going to be state.t we are going to pass dates state dot dates and finally options and also we should pass this dispatch that because when we update our search bar here we are gonna call this new search action to do that we are gonna need this dispatch and that's all i think so let's wrap our application basically we are gonna choose components that we want to use those states and dispatch function in this case we are gonna need it here we are gonna need it here and we are gonna need in this single page basically we are gonna need it everywhere we can just wrap our entire application with that i'm gonna say search provider and i'm gonna wrap my application like that i'm gonna save so let's use it in our header component and you are gonna understand easily so let's come here and i'm gonna say const we are gonna use something here but before i'm gonna say use context we are gonna use our search context like that and which value we are gonna need here as i said when we change those states and when we click on this search button we are gonna update our state in this case we are gonna need this new search action to dispatch that we are gonna need this dispatch function so i'm gonna import this let's say dispatch and let's use it here when i click this button i'm gonna dispatch my new search action so i will say type is going to be new search and we are going to give a payload here that because remember when we dispatch this action we should return any payload and it's going to be our new state so basically we can share our all information here like destination dates and its date or dates okay eat state and options i'm gonna save and i'm gonna go to hotel page and i will do the same thing but this time instead of dispatch we are gonna fetch dates that because remember in hotel page we are gonna need how many nights a user want to stay so i will come here and i'm gonna say use context i'm gonna import them and we are gonna need dates let's see i will say console.log and dates but it's gonna be a mistake there that because we are using date here actually let's change this dates it's gonna be like that that because it's an array i think it's a better naming so it's gonna be dates again in this case we should correct our list remember it was date i'm gonna make this page again why i use date and that's all i think oops there is something wrong in header here i should fix them it's okay i think i'm gonna save and let's see how it works i'm gonna refresh this page i'm gonna write here location i'm gonna choose some dates here let's choose two adults i'm gonna search and let's choose this one and i'm gonna open my console and as you can see we have date here so we can use them everywhere in our application in every component we can use dates destination or options but how we are going to calculate how many dates we have between this start date and end date 4th of may and 7th of may i'm just going to copy paste my function like that basically it's gonna subtract the starting date from ending date and then divided this by one all day this is the milliseconds per day if we divided by this it's going to give us a difference let's try i'm going to say console.log day difference and inside we are going to give dates and date and start date as you can see three days four two five five to six six to seven okay awesome we are gonna use it here so instead of console log let's say const days and we are going to use it here days and here and we are going to make a calculation here i will say base multiply by cheapest price and also we can use room number remember we can use options also here inside our context state we are gonna have options and inside options we have room number so we can use it here also option store true of course it's gonna be data and let's see okay as you can see three nights and six hundred dollars i'm gonna close here and i'm gonna choose one more time like that and let's choose one more room two hundred dollars and as you can see oh it's quite expensive i want to try something here from today to okay i'm gonna choose maybe 20 rooms and let's say madrid again it's going to be insane let's use this one the most expensive wow it's actually 43 million dollars so keep in mind guys if you want to stay 20 years in hotel jain you have to pay this price of course worth 20 rooms okay so one more thing we need to do when we click on this button we are gonna see available rooms and we will be able to choose them but before i want to create authentication context also that because it's not gonna be opening for unauthenticated users so let's create one more context i will come here actually i will just copy this and paste again and i'm going to say also context and i'm going to change this name here here and here it's going to be authentication and what we are going to need here let's delete them we are going to have user information at the beginning is going to be null and loading when we try to click on login button it's going to be true but at the beginning it's going to be false of course and error is going to be now if there is an error we can update this so let's change them i'm going to plate them and for first case i'm going to say login start basically when we click on login button we are going to run this action type and what we are gonna return let's copy here i'm gonna return this object user will be null loading will be true error will be now by the way i deleted here default that's why it's warning us okay and second case let's duplicate this and third case it's going to be login success and if it's successful we are gonna pass here our user so i'm gonna say action payload and looting will be false that because we are ending our fetching process error will be null and last one will be failure and in this case user will be null loading will be false but error will be action payload like that and one more action i want to create and it's going to be logout basically it's going to be our initial state user null loading false and error now okay i'm going to do the same thing all reducer and here let's say user loading and error by the way guys when we login i just want to save my user into local storage in this case even if we refresh the page we are not going to be logged out to do that i'm going to use use effect here and my dependency will be state.user because whenever it changes we are going to update our local storage let's say local storage and set item and item name will be user of course this is an object but we cannot store this in our local storage it should be string so what i'm going to do is using here json stringify and state.user in this case when we refresh our application it's not going to be null anymore firstly we are going to look inside our local storage this time in our local storage it's going to be a string and again we should parse it so i will say json parse local storage and this time we are going to use get item item name and that's all it's gonna check our local storage if there's a user it's gonna use it if there is no user it's gonna be now okay let's wrap our application with this context provider and after that we are gonna create our login page i'm gonna open up index here and i'm gonna write here all context provider let's import this and wrap our application like that that's all let's create here login page login.jsx and css let's create our function and import our css file so what i'm going to do is creating my credentials using use state so i will say const credentials set credentials and it's going to be use statehook and at the beginning it's going to be user name undefined and password so which values we are going to use here we are going to use loading error and dispatch let's do that i'm gonna say const loading error and dispatch it's gonna come from use context hook and alt context so let's create here our class name first it's going to be login and inside i'm going to create a container let's say a container logincontainer it's going to be two inputs let's say as input first one will be text placeholder username id will be username and onchange and let's say handle change and i'm going to create one more but this time it's going to be a password placeholder will be the same and id and after that we are going to have a button login button and it's going to be login and if there is an error after login operation we are going to show expand here and it's going to show us our error message okay let's create this function const handle change so let's set our state here set credentials i'm going to take the previous value if you are following my tutorials you already know how we are using it we are going to return the previous value and credential name to do that we are going to use its id remember we have password and user name so we can use them like that event target dot id and it's gonna be event target and value okay right now we have user name and password we can create onclick method and we can dispatch our actions so i will say on click and let's say handle click or handle login i'm gonna say const handle click i'll say event prevent default if you don't do that it's gonna refresh your page by the way i'm gonna say async function that because we are gonna make api request let's dispatch our first action here and its type will be login start if you remember we are not passing any payload here it just updates our loading state and after that we are gonna try catch and we are gonna catch this error if there is an error we are going to dispatch error action its type will be login failure and payload will be error response and data and for try block i'm going to say const response i'll say wait we are going to use axios and post methods login endpoint and we are going to pass our credentials and after successful operation we are going to dispatch our other type here let's say type login success and payload will be response and data let's see actually our user here if it works or not i will say console.log user of course we didn't create any login route let's come here i'm going to create one more root here and it's gonna be login like that let's see i'm gonna say login okay it's here let's remember what we have here okay john john 1 and as you can see it's null right now i'm going to say john my password that's a different username here i'm going to log in as you can see 404 and it says user not round and if it's correct but password is wrong i'm gonna login wrong password or username and if it's correct it's gonna return as our user by the way let's give some style here i'm just gonna copy paste there is nothing important here as you can see something like that so what i want to do is if it's successful i just want to be redirected to home page to do this we can use use navigate hook i'm going to come here and i'll say const navigate it's going to be use navigate and if it's successful i just want to navigate to home page by the way we can use this loading to disable our button i'm gonna say disabled if it's loading let's try again john 1 password i'm gonna login and we are going to home page so even if i refresh the page if i go to application and local storage as you can see our user is here perfect in this case we can use this user and according to this user we can delete these buttons or this one let's do that i'm gonna come here and let's plate this actually and this user okay i'm gonna copy here and for number i'm gonna paste of course we are gonna need only user here use context auth context and i'm gonna write my condition i will drop here and i'm gonna say if there is no user show this div like this and if there is a user actually we can use our username let's delete this and write here condition user dot username if there is no user we are going to see those buttons of course we don't need here curly brackets we are already in the javascript like that perfect if you want to you can create your logout button and when you click on this you can dispatch logout action and let's do the same thing for header let's paste it somewhere here and i'm gonna take this user and for this button i'm gonna use it like that okay so what i'm gonna do is let's write here our destination again let's choose some dates here i'm gonna search let's choose this one and right now when i click on this button we are going to create a condition again if there is no user we are going to go to a login page if there is a user we are going to open here a model that we can choose our rooms i'm going to close everything and i'm going to open up hotel page again and for this button let's create another on click and i'm going to say handle click i'm gonna write it here and i'll click of course i'm gonna need to import user first of context and let's write here our condition if there's a user do something here if there is no user just navigate to of course we are gonna need navigate also let's write somewhere here const navigate use navigate hook i'm gonna take this and we are gonna navigate to login page what about if there is a user as i said we are going to open a model so let's create one more use state here remember this is our slider model open and close state i'm gonna create one more and it's gonna be let's say open book or let's say jazz model and if there is a user we are going to open this set open model it's going to be true like that let's create here our condition i will say if it's open show me my model but to do that we can create one more component let's say reserve user [Music] jsx it's going to be css my function here and css let's give class name and we are gonna take a prop here and it's gonna be set open that's because in this component we will be able to close our model again and one more thing we are gonna need and it's gonna be hotel id that because we are gonna fetch our rooms in this page so we are gonna need it and let's come here and call our component wizard and i'm gonna pass my props here set open will be set open model and hotel id will be jazz id remember it comes from this location so we are gonna use it here let's try as you can see there is nothing i'm gonna click and it's here okay of course it's gonna be position absolute and we are gonna move this here let's do that actually i'm gonna create here a container let's say reserve container to close this model we are gonna need a button to do that we are gonna use font awesome and icon will be exactly the same icon that we have used before it's going to be circle x mark let's import this here and i'm going to give a class name let's say our clause and finally i'm going gonna give on click and set open will be false of course a function here okay i'm gonna click it's here when i click here it's gone let's write here a span and it's gonna be select your rooms so let's fetch our hotel rooms to do that i'm gonna go to root here and as you can see we don't have yet so what i'm gonna do is creating here another cat request and it's gonna be room and we are gonna pass here hotel id so let's create our function here inside hotel i'm gonna say export const get hotel room actually rooms it's going to be async request response next try catch block error and next error firstly i'm gonna find my hotel i will say const hotel is gonna be hotel model and find by id i'm gonna pass here my id which i added inside request and params and let's remember what we have here as you can see we have rooms and it includes room ids so according to this id we can fetch our rooms so let's do that i'm gonna come here and i'm gonna use promise all that because we have multiple rooms so i will say const list and promise all of course it should be await and i will say hotel rooms it was room or rooms okay rooms and i'm gonna use map and for each room remember it's an id we are gonna return our rooms room model but it's not coming let's import here i'm gonna duplicate this and it's gonna be room and again find by id and this time we are gonna pass this id let's use it here i'm gonna import and let's try in our api tool here i'm gonna say new request get hotel rooms localhost hotels room and its id let's see our hotels here let's choose this one but we don't have any room that because we didn't create in this case it's not gonna return anything by the way we didn't return anything let's say response 200 json and we are gonna return this list so for this hotel we are gonna add some rooms this is hotel id remember we are creating room that because if i open room and create room as you can see we are taking hotel id and creating new room so let's do that okay first one two bedroom like that and another room let's say 101 102 i'm gonna send let's see and it's here okay perfect so if i come here and say get hotel rooms and if i send oops it's still same why i am forgetting these weights i'm sending and they are here perfect so we can use this endpoint and we can show our rooms and their numbers i'm gonna come here and i'm gonna use use fetchbook and url it's gonna be hotels room and hotel id like that and i'm gonna use it here i'll say data dot map and for each item inside we are gonna return another div and it's gonna be reserve and item let's say item info and we are gonna have title description maximum people information let's say our title description and max people like that and it's going to be item.title item.description and maximum people actually let's do like that max people and we are going to show this inside bolt text like that okay let's see actually i'm gonna come here and open okay it's wrong hotel it was in berlin i'm gonna open and they are here okay perfect of course we have a lot of issue that because we didn't create our hotels and rooms properly i'm just trying to be quick otherwise this video will be really long but anyway it works our items are here right now we are gonna show their room numbers and we will be able to select them actually let's create one more and it's going to be price user price and after this do i'm going to create one more and it's going to be let's say just room and inside i will say item room numbers because remember they have room numbers and inside the actual number and unavailable dates we are gonna use them i'm gonna say map for each room number let's create here a label and it's going to show room number dot number and we are going to have input that user can choose any room so let's say input type will be select by the way i'm gonna move this room here and value will be room number dot id that because again let's remember each room number has different id we are gonna use them and i'm gonna use on change method here when we select them we are gonna change selected rooms so let's say handle select i'm gonna create this here const handle select of course it's gonna be event but how we are gonna set this of course we are gonna need use state here i'm gonna say const selected rooms and set selected rooms it's gonna be use state and at the beginning it's going to be empty and let's create our logic here i'm going to say const selected and we are going to check if it's selected or not to do that we can use event target and checked so when i click oops by the way i said select it's going to be checkbox of course i need take a break i think my brain doesn't work anymore so when i click here it's gonna be checked we are gonna need our values so i will say const value is gonna be event target and value and remember its value is gonna be its id and we are going to set our state i'm going to say set selected rooms and i'm going to write my condition if it's checked take the previous rooms additionally add here one more id and if it's not if it's not checked we are gonna filter our previous selected rooms and we are gonna pull a room id from the selected rooms so i will say filter and for each item we are gonna check if item doesn't equal our value which is room id they are gonna stay if it's equal we are gonna move out this value by the way it's gonna be checked okay let's see actually selected rooms i'm going to open my console i'm going to click here and as you can see this id is here when i click again it's going to be empty i'm going to add this this those okay it's working perfect and after all of those i'm gonna create a button let's say button r button and reserve now and i'm going to create on click event here and i will say handle click let's create here const handle click and we are gonna make one more request basically we are gonna update this unavailable date to do that we are gonna need our selected dates it's really easy only thing we should do is using use context i'm going to say const dates discovery use context and search context okay we have dates but this date is a range remember we can choose it like that from third to tenth but we are gonna need all these dates here so i'm gonna create here a function let's say get dates in range it's gonna take start date and end date and i'm gonna create one more date here and it's gonna be exactly the same date with this starting date that because we are gonna create a loop and and after each operation we are going to increase this date until it equals or less than this ending date so let's say new date i'm going to add here starting date and i'm going to say get time let's create our loop i'll say file if date less or equal and then date we are going to create a list and we are going to push our dates inside list is going to be an empty array for now and inside this loop list dot push and our date and after that we are gonna increase this date dot set date date dot get date plus one okay and finally we can return our list let's see actually i'm gonna say console inside this function i'm gonna add my starting and ending dates let's click here okay there is an error here to prevent this you have to use new date all the time that's actually right here const start and new date it's gonna be our start date let's say start date and date and one more i'm gonna say and date and it's gonna be end and let's try right now i'm gonna write again four to seven i'm gonna click ah this get time is here i'm sorry it should be here this time it's gonna work hiding you don't need them but they can stay in any case i'm gonna write one more time i hope this time is gonna work four to seven and i'm gonna open my console and as you can see our dates are here from four to seven but if i write here get time it's gonna give me these timestamps so it's easier to compare dates because all dates are not the same but if you are using timestamps it's much easier to handle them ok we are going to use them and we are going to update these unavailable dates but before i want to do something more here that because we are not sure that those rooms are available or not we should check them first otherwise a user can order same room to prevent this let's create here another function by the way instead of console.log i can say const all dates and what i'm gonna do i will say const is available and we are gonna take room number and we are gonna check if those unavailable dates includes any of those dates or not if it includes what we are going to do is adding disable html attribute here so we cannot select this so i will say const is font it's gonna be room number and unavailable dates i'm gonna use some methods it's gonna check whether it includes some of them or not and i will say date and we are going to check all dates and if it includes any of our dates inside our db we are going to set a flag here of course remember we are using get time here we will do the same thing here to compare easily so i'm gonna say new date and we are gonna pass our date here and i'm gonna say get time and finally we are gonna return this font but i'm gonna return the opposite of this that because if it includes it's gonna be true but if it's true it means it's not available that's why i'm using like that so i'm gonna come here for our input i'm gonna say disabled if it's not available and i'm going to pass here my room number let's create our css it's going to be easy to see firstly i'm going to say user it's going to be full screen 100 vw 100 vh and i'm going to give background it's going to be black but i'm going to reduce this opacity of course it's going to be a modal and let's say position fixed if you watched the previous video you already know how to create model so i'm gonna center everything like that and i'm gonna give some style for this container let's say background color white i'm gonna give some padding and position will be relative that because we are going to use close button remember it was our clause and i'm going to make this position absolute top 0 right 0 and cursor will be pointer like that so what about each item here i'm going to say display flex align item center let's give gap between them and i'm going to give some padding like this and for this info it's going to be display flex flex direction column i'm gonna give gap i'm gonna give some font weight for those texts i will just copy paste here there is nothing important it's bolder it's thinner and finally for this button i will use exactly the same button as well bases like this by the way for these rooms we can decrease these numbers and we can make here display flex to do that i'm gonna create let's say select rooms it's gonna be a container like that let's use it i will say display flags flex wrap will be wrapped because if we have many room numbers we are going to move it to another line so let's give a gap here i'm going to decrease the font size like that maybe color and for each room display flex flex direction column like that okay it looks pretty good it's a fixed deal perfect as you can see none of them are disabled right now so let's make a request when we click this button we are gonna update our rooms i'm gonna come here it's gonna be async of course i will say try catch block let's write here wait and again we are going to use promise and all that because we are using map here and i will say selected rooms and for each room let's say room id i'm going to say const response we are going to make axios call here and i will say put and we are gonna update our rooms but we don't have this endpoint right now let's come here actually let's open our route here and i'm gonna create one more put and it's going to be update availability or directly availability and it's going to be room number by the way it's not going to be admin that because users can do that let's create i'm gonna go to room here and one more update but i'm gonna say update room availability let's pass this here and import and i'm gonna delete it firstly i'm gonna find my room using its room number id remember we are updating here not our room so we are going to use this id we are going to find this room number and we are going to update these unavailable dates to do that i will say wait room and i will say updates 1 again we are not using find buy id and update that because we are not updating our room we are updating room number okay so i'm gonna pass here room number dot id and it's gonna be request params and id that we pass here and after that we are gonna push some date inside this unavailable date i'm gonna copy this and i'm gonna say push and i'm gonna say room numbers by the way it's not number it's gonna be numbers and i'm gonna use here dot dollar sign and dot again and unavailable dates i know this is strange but this is how it works if you are updating nested properties you have to write it like that of course you can create more models like main room and each individual rooms and you can connect them by using their ids but i especially wanted to show this because i want you to learn some advanced methods about mongodb okay what we are gonna pass we are gonna pass request body and dates let's update this i'm going to copy this let's duplicate this and i'm going to say add date this id it's going to be availability and rooms it's gonna be put methods i'm gonna write here dates and inside this let's actually put this date and one more it can be same doesn't matter i'm gonna send has been updated let's check here i'm gonna send back and as you can see our dates are here okay perfect so we can use this endpoint i'm gonna come here and i will say rooms availability and of course we should use backtick and room id and which dates we are going to send dates will be all dates remember it takes all dates between our starting and ending point by the way i'm gonna delete this and i'm gonna return response and data actually we don't need that but what's wrong here by the way promise all okay i should close it here okay and after this i'm gonna take a break that because i'm making a lot of mistakes right now so i want to take one more rooms availability room id all dates i hope it's okay let's check i'm gonna choose this one and i'm gonna reserve okay there is no error has been updated and i'm gonna come here and i'm gonna choose one more time and i'm expecting that it's gonna be disabled let's choose and as you can see it's disabled right now so we cannot choose this perfect it works so what else you can do when we click on this button you can redirect to another page and show their rooms maybe cancellation button maybe payment page i'm not gonna deep dive into that much but i can write here set open and it's gonna be a false we are gonna close our model and maybe we can go to home page we are gonna need navigation of course const navigate use navigate and we are going to go to home page let's choose this one resolve now and we are here perfect and it's enough for this client side i think we can search we can choose rooms we can reserve and let's create admin page i'm gonna take a break for a while and i'll see you then okay right now what i'm gonna do is creating here a new folder and it's gonna be our admin panel and inside this folder i'm gonna say cd admin and i'm gonna clone this branch to do that again i'm gonna copy this url git clone single branch react admin and this url and i'm gonna import them in this folder and enter let's see okay they're here right now i'm gonna install my libraries i'm gonna say yarn and it's ready let's start our application yarn start okay it's here right now i want to create my login page and we are going to create authentication context again let's see what we have inside pages we have login but we don't have anything here actually we can just copy and paste login component from our client site let's come here page login and here okay i'm gonna copy here and paste for my admin panel like that but as you can see we are using sas here so i'm gonna say as css we don't have any authentication content right now i can comment this out for now and we are gonna import axios i'll say cd admin and add axios and we are gonna use exactly the same authentication context so we don't have to create again i'm gonna come here copy this and paste inside my admin context like that okay let's wrap our application i'm gonna copy this provider and open up index.js and i'm gonna wrap my application with this provider import okay it's almost ready but we should provide some security for our admin panel that because if we are not admin we are not supposed to see this page so when i refresh my page i should be redirected to login page how we are gonna do this i'm gonna import this by the way and okay let's open up our edges and as you can see we are using real gradle dom but we don't have any protected root let's create here i'm going to say const protected root and we are going to take here a children that because we are going to wrap our roots with these protected roots for example for index page we are going to wrap this component so if we are not the admin we will not be able to go to this page firstly i should import user from my context i'll say user use context and auth context okay but there's a problem here even if i log in as a normal user we are gonna see this object so what i'm gonna do is go into api controllers and authentication and as you remember we are passing these other details and it doesn't include password and is admin we are doing this that because we are storing these other details but what i want to do is passing here is admin property also but don't worry we are not going to store this after logging process we are going to store these details but we are going to need this admin property so i'm going to come here and as you remember we are using navigate hook here and after successful login operation we are going to home page but i'm going to create a condition here i'm going to say if response data is admin we are gonna dispatch this action and we are gonna go to home page if it's not admin i'm gonna create one more failure dispatch here and i'm gonna say message you are not allowed okay and here we are not gonna store all these data we are just gonna store these other details by the way let's say here details and we are going to store this object let's say details by the way i should do the same thing for client application let's come here login it was response and data is gonna be data and details okay i can close here and let's create our protected route i will say if there is no user which means if there is no admin we are going to navigate to login page return navigate from react router dom and it's going to be login and if there is an admin we are going to return our children okay let's use this in our home page and let's check i'm gonna wrap this by the way i'm gonna take this login somewhere here okay let's see i'm gonna go to console and i'm gonna delete my cookies and local storage that because we are using here same port so we have still user here clear and clear of course you can use another port number but anyway i'm gonna refresh this page and as you can see we are in the login page it doesn't allow us perfect by the way let's add our css here it's exactly the same css as you can see let's try some wrong username here i'm gonna login but of course we didn't create our proxy let's come here i'm gonna say proxy localhost port number and api okay let's restart our application oops it's not here it's gonna be here i'm gonna terminate and start again okay let's try login and using netfound john 1 my password and we are going to home page perfect of course our password is really weak don't worry about this so what i'm going to do is doing same thing for other routes for this list okay i created for all of them so we can continue i'm not gonna take care about here that because we are not selling anything it's just an resurrection app so i'm gonna go to users page here and as you can see we have data here it means we are gonna fetch some data not for only users we are gonna fight for hotels rooms basically we are gonna need use fetch hook again okay client side source and hooks i'm gonna copy here and close and i'm gonna paste for my admin source okay we are gonna use this let's close everything here and i'm gonna go to data table here by the way if you didn't watch my previous admin panel tutorial i highly recommend you to watch it before getting started otherwise it can be hard to understand some parts here okay anyway let's remember what we have here we are using material ui data grid here and we are passing our fake data those users and also for these columns we are using data table source as you can see user columns all those properties and our fake data as you can see it's temporary we are not going to use it anymore we can delete but the important part is here that because here we have user image username email age status we can change them but in our application let's open up api and user model as you can see we have only username email and password so i'm gonna create some more property here like that country string profile picture city and phone number so let's create some users i'm gonna say country let's say usa it's the new york phone number like that let's create okay there is a problem here it says they are required that because if you remember in our authentication controller we are taking only username email and password that's because we are using hash password here so basically i can delete here and instead i can say request and body so it's gonna take all those properties here and additionally it's gonna take this password and create new password here hash password okay let's try again i'm gonna send okay we are already using drone one let's change this three i'm not sure we are using or not okay it's here let's create a couple more but we can use some images let's open up paxas.com of course in admin panel we are gonna create our own users and upload our own images but for now to see our list better we are just gonna create some users i'm gonna send five okay it's enough so let's fetch our data i can close here and go to data table again so instead of this data i'm going to delete here we are going to use use factor const data loading error use fetch hook and our endpoint will be users why it's not coming okay let's import import use fetch hooks and use switch i'm gonna comment this out by the way we are gonna handle this later and what i'm gonna do is changing my table source here okay first one will be image username it can stay email it's okay also i'm gonna add here country let's add two more it's gonna be city and phone as you can see there is a problem here let's open console and it says all roles have to have a unique id but in our application we don't have any because in this fake data we were using those ids but in our mongodb they are not id they are underscore id so by default it cannot take this id so what i'm gonna do is writing here get row id and i'm gonna pass my id manually so i'm gonna choose each row for each item it's gonna take their ids let's save and as you can see they are here perfect what else i can do here as you can see they don't have any image i can write a condition i'm gonna open my source again and for those columns as you can see we are using this image but i will say if there is no image use this url which is not our entire image like that and also i'm gonna delete this status i forgot that we don't need any status okay perfect but how we are gonna delete those items if you remember the previous admin tutorial we are passing our item ids by the way this time we are gonna pass underscore id and here we were filtering those items but we cannot filter this data we can basically create one more use state here let's say const list set list it's going to be use state at the beginning it's going to be an empty array and whenever our data changes we are going to update this list let's write here use effect i'm going to say data and whenever it changes we are going to update set list and it's going to be data so instead of this data we can use list here and whenever we delete our items we can filter this list so i'm gonna say set list it's gonna take list and filter this item so when we choose any item we are not going to see this anymore but also we should delete this item from our mongodb to do this i'm going to right try catch block here and we are going to handle delete method by the way that's right here async function and we are going to use axios i'll say wait axios it's going to be too late methods we are going to use our endpoints but this data table is common component for users hotels and rooms so i cannot write here drag the users or here so what i'm gonna do is deciding which page i'm in to do that we can use this location remember how we are doing this we can take our path we did this couple times so i'm just gonna copy paste you already know how to do this we are gonna take our path and according to this path we can fetch our data and delete data so i'm gonna write here path of course slash here so it's gonna fetch users for this page and when we go to hotels page it's gonna fetch hotels so i will do the same thing here i'm gonna say path and we should give here our id it's already here we can use it here so it's gonna delete this item and if it's successful we are gonna filter our item let's try i'm going to delete this john 5. i'm gonna click here okay i had to refresh this page okay that because it should be underscore id let's try to light this one okay it's gone and when i refresh this page as you can see it's not in our db anymore perfect so let's do the same thing for hotels by the way it's products yeah i'm gonna change them let's open up it was sidebar i think okay it's gonna be hotels i'm gonna change here and one more it's gonna be rooms of course i'm gonna wrap this also like that and its link will be rooms let's try i'm gonna click here and it's gonna be an error that because we are using user columns as you can see so how we can make this dynamic of course we can use this location and we can say if it's users use users columns if it's hotels use hotel columns and also we can pass it in our app.js here let's do that for this user list i'm gonna say columns and it's gonna be user cons and i can do the same thing for hotels and rooms but we don't have here let's create like that hotel columns and room columns by the way i can delete this user rows we don't need this anymore okay as you can see we have hotel name type title nct and for rooms title description price and maximum price of course it should be lowercase so we can pass them i'm gonna take this and for products of course it's gonna be hotels and i'm gonna pass here hotel columns so let's use them i'm gonna come here and take this prop and i'm gonna update this okay it's not here that because we are passing to list page of course we should take this here we are prop drilling but anyway it's not a problem it's just two components okay perfect we can increase this id maybe table source and gonna make this 200 let's try maybe 50. okay it's better and let's increase this name also it's not that important but anyway it looks better so let's delete this last one okay it's not here anymore i'm gonna refresh okay perfect so you are gonna do exactly the same thing for rooms but for now let's try to create new user i'm gonna come here and as you can see again we are using some data here let's see we have form source and inside we have user inputs product inputs so i'm gonna update here again i'm not doing this one by one not because it can take time i just copy paste and you can find this source in our github repository as you can see user information hotel information and room but we are gonna have something different here that because for example for this user page we are gonna upload only one image and also we are just gonna use those text inputs but for hotel page we are gonna upload six items here and we are gonna have some selects that we can choose hotel rooms or we can choose whether it's a future total or not so basically using a single page for all of our models is not a good idea i think of course we can still do but this page will be really messy i don't want to do this so basically i'm gonna create two more new page and first one will be new hotel hotel new hotel css actually scss let's come and i'm gonna change here new hotel and export and i'm gonna do the same thing for room page it's going to be new room jsx and css and again let's update here and let's get started okay so i'm gonna close everything here and we are gonna start with new user page why this input is here let's check okay we are using space around why we are using space around there i just wanted to give some padding i think but basically we can give here i'm going to say padding 0 20. okay awesome so what i'm gonna do is taking those text inputs using use date so i'm gonna come here and i'm gonna say const info user info and set info it's going to be use states at the beginning is going to be an empty object and we are going to change them const handle change and we are going to use it for our inputs here this is file input it updates our file and for this input we don't have anything let's write on change it's going to be handle change and remember in our source we have ids it's exactly the same text in our mongodb username email phone so directly we are gonna use them i'm gonna say set info and again i'm gonna use previous states and i'm gonna return previous state and event target id and it's gonna be event target value so when we click this button firstly we are gonna upload image and we are gonna take its readable url and we are gonna send this url along with those inputs to our mongodb to do that i'm gonna create handleclick function he dot prevent default we don't want to refresh this page so let's use it here send button i'm gonna say on click event and firstly we are gonna upload our image here let's say first async function but where we are gonna upload our image in our other tutorials we were using google firestore but this time let's use cloudtonery if you log in your cloudnay account you're gonna see this page and we are gonna upload files here it's really easy to use let's come here and in the dashboard you are gonna see your cloud name this name is important we are gonna use it and as you can see it's a free plan we don't need to pay anything and what i'm gonna do is coming here and giving some configuration i'm gonna come here upload and i'm gonna scroll down and what i'm gonna do is adding upload preset and here i'm gonna write my preset name signing mode will be unsigned and folder will be upload folder and i'm gonna save and i'm gonna open documentation and as you can see upload api reference so basically we are gonna use this url in this part we are gonna use our cloud name remember it was lamadev and you are gonna use your own so let's come here firstly remember we have a file here but we should transform into form data so i'm gonna say const data is to be form data and inside this data i'm going to pass my file appends file name and file and also i should provide my upload preset to do that i'm going to say append upload preset and my folder name which is upload and after that i will say try catch block if there is an error i will say console.log or you can show this anywhere and i'm going to say const response actually let's say upload response wait i'm gonna use axios and it's gonna be a post method and my url and as i said we are gonna change here it's gonna be lambda let's import this actions by the way okay and i'm gonna pass this data let's see whether it's going to work or not i will say console.log and this data and i'm going to choose this image and let's upload something is wrong oh sorry it should be version of course and this demo will be our cloud name by the way upload response and data let's try again and as you can see it gives us those properties and we are gonna need this image url let's take this i'm gonna say const url i'm gonna destructure this upload response dot data and after that after uploading we are going to make api request let's say const new user and it's going to include all user information which we are taking here and updating in this function and also we are going to use this image it's going to be url let's make our api request it's going to be axios post methods auth register and we are going to pass our new user object and that's all let's try i'm gonna choose this image chain phone number password country c and username i'm gonna send okay there is something wrong i'm gonna say console.log info ah oh we couldn't update them that because we didn't use id here it's going to be input dot id let's try right now i'm gonna choose again okay it works and jane let's send i'm gonna check network okay it's successful and let's check here and as you can see it's here okay awesome so let's do the same thing for hotels i'm gonna click here and we are gonna change i'm gonna do the same thing i will copy here and paste for new hotel this time it's not going to be file it's going to be files and we are going to upload multiple files so let's say multiple here set files and we are not going to take only one we are going to take whole and in this case we are going to see here only first item so i'm going to say zero okay let's use this here this time i'm not gonna forget id input dot id and on change methods it's going to be handle change by the way we are going to users page that because in the data table as you can see our link is going to use this page we are going to change it and we can use our path again so i'm going to say path and new page let's try i'm going to hotels and add new okay we are here let's close here by the way we are not going to use those inputs from our app.js because we were using the common name component here but this time we are gonna use new hotel in this case we don't need this input or even this title let's copy here and delete this i'm going to come here and delete this probe also [Music] i'm going to paste it like that and our inputs will be hotel inputs like that okay here so i'm gonna do exactly the same thing but we are gonna add one more thing hotel model has featured property so i'm gonna add here html select and one more component i'm gonna add here and we will be able to choose any room let's do that i'm gonna come here and i'm going to create one more form input and we don't need this key and label will be featured and we are not going to use input here we are going to use select i will say id featured on change will be handle change and inside i'm gonna write my options it's gonna be no or yes i'm gonna say value is gonna be false if it's yes it's gonna be true let's see okay something like that we are gonna choose if it's featured or not and let's create another one and we are gonna choose our rooms i'm gonna copy this and paste again but this time it's not gonna be form input that's because i wanna make this 100 percent so i'm gonna say select rooms i'll say rooms let's say id rooms and we will be able to choose multiple room and i'm gonna say on change it's gonna be handle change and i'll select let's create const handle select okay so what i'm gonna do is fetching all rooms first to do that again we are gonna use use fetch let's come here and use use patch and end point will be rules so let's use this data i'm gonna delete those options and i'm gonna use map i'll say if it's loading right here loading if it's not and if there is a data right here data dot map and for each room show me an option and it's going to show us room to title of course we should keep here value and it's going to be room id let's see okay that's why it's not multiple did i delete this or okay perfect so let's take care of this class name form input as you can see it's 40 percent i'm gonna say with a hundred percent and select inside it's gonna be the same maybe i can give some padding okay perfect we can choose multiple items now when i click this button we are gonna upload our images then we are gonna create new hotel and also we are gonna add room ids inside hotel rooms that's right and you are gonna understand better right now by the way we should handle this select let me show you something i'm gonna say event target and selected options i'm going to open console by the way we didn't give any key let's say key will be room dot id i'm gonna refresh okay i'm gonna choose this one and another one and as you can see it shows us an html collection so it's not an array so how we can transform this what i'm gonna do is writing here array from and this html collection of course we are not gonna take all those properties we are gonna need only value so i will say option and return me option dot value okay let's say cost value and we are going to create one more state here it's going to be rooms set rooms at the beginning is gonna be an empty array and we are gonna set it here side rooms and it's gonna be value let's see console.log and rooms i'm gonna clear here i'm gonna choose this and as you can see its id is here i'm gonna choose one more perfect if i don't select this it's gonna delay it so we have room ids we have text inputs we have image input so let's take care of on click method let's say handle click prevent default and try catch block and firstly i want to upload all my images to do that we are going to use map so if you remember if you are using map for any api request what we were doing we were using promise all so i will say list it's going to be promise all of course it's going to be await and async here and inside i'm going to use all files and let's say map and for each file i'm gonna do exactly the same thing remember first creating data then uploading this file and taking this url and finally we are going to send this i'll say return this url of course we are using a weight here in this case it should be async let's import these axios and after getting this list which includes our image urls we are gonna create new hotel i'm gonna say const new hotel it's gonna be again info rooms and photos and it's going to be this so let's send this i'm going to say wait axios post and hotels and we are gonna send this new hotel so let's use this i'm gonna copy and on click event it's gonna be handle click and i forgot something here that because our files are not an array let's see console.log files i'm going to choose some images here and as you can see it's an object so how we are gonna transform this into an array we are gonna use object values so let's see i hope everything is okay i'm gonna refresh the page choose those images some names the it really doesn't matter and some rooms here and i'm gonna send and as you can see it's successful all our images perfect let's see and it's here awesome and one more thing we are gonna need and it's gonna be rooms of course we didn't pass our columns let's do that i'm gonna copy these hotels route and paste and it's gonna be rooms and this page will be new room for these columns it's going to be room columns like that title description price by the way why it says add new user let's check data table okay so i'm gonna write here path actually it's not add new it's going to be just pass okay users hotels and rooms so we already know we can delete this so i'm gonna add new room page new room and as you can see we don't have any prop here title will be add new room and instead of inputs it's going to be room inputs id type okay so what i'm going to do is deleting this image so we are not going to add any image actually let's plate this left side like that okay i'm going to create handle function and we'll change and here i'm going to delete this file okay and this time we are going to choose hotels that because remember our api roots and rooms as you can see to create in a room we need this hotel id so we are going to fetch hotels first and according to our choice we are going to update it i will say hotel id let's say null or undefined and we don't use form input that because we don't need any file and i'm going to create one more form input here let's delete this key and let's write here our title choose a hotel and again we are gonna use select id will be hotel id remember in our api is gonna be our parameter and i'm gonna write my options of course i will say if it's loading show me loading texts and if there is a data map through this data and for each hotel create here an option but this time it's not going to be multiple we are going to be able to choose only one hotel so i'm going to say hotel dot id sorry it's going to be name that because users can see this but value will be hotel id so let's write here on change event and whenever we change our option we are going to update this hotel id so i will say hotel id is going to be event target dot value oops so basically this event target and value will be our hotel id like that as you can see we can't choose any of them and let's create our handle click function for our button here on click and a little click const handle click event prevent default we are going to send it but let's check what we have here and models and inside room we have title price maximum people description like here and we are gonna pass hotel id but additionally we have room numbers which includes the actual number and unavailable dates so we are gonna need one more place so let's come here and i'm going to create one more forum input before this hotels and it's going to be rooms and this time we are gonna use text area it's gonna be a little bit bigger like that and let's give placeholder q comma between room numbers so let's create use state here and it's going to be rooms it's going to be an empty array and we are gonna set it here in our text area i'm gonna say on change set rooms it's gonna be event target and value by the way of course it's gonna be a string but we are gonna make it an array and we are gonna do this here let's say const room numbers and i'm gonna say rooms it's a text and i'm going to use split method and let's say comma so it's going to give us an array but if we do that let's check numbers if i write here some numbers like that i'm gonna send and as you can see we don't have object here but in our case we are gonna need this object by default unavailable dates will be an amp theory but we are going to need this number so to create this i'm going to use map and for each room return me number equals this room let's see right now i'm gonna click and this time it returns those objects perfect this is exactly what we need so i'm gonna write here try catch block and here i'm gonna use weight axios and post method and it's going to be rooms and remember hotel id here so i'm going to say hotel id and we are going to pass our information which is info and room numbers by the way i forgot async here i didn't use it let's check okay on change method is gonna be handle change by the way there is a typo here id okay everything looks good let's try of course we forgot unique for this options hotel id okay anyway it's not that important i'm gonna go to network i'm gonna write new room awesome room this price two people and i'm gonna choose hotel here hotel jane and i'm gonna send and it's here as you can see and room numbers as you can see by default it adds unavailable dates they have individual ids perfect and this is our room id awesome so basically that's all of course we don't have home page or single page but if you understood this tutorial it's a piece of cake for you i think you learned the important parts of course i didn't implement anything here that because we didn't sell what you can do here you can get rid of all those components and you can say maybe latest hotels latest users but you already know how to make api requests how to create new endpoints i think it's not a big deal and if you enhance this project let me know in the comments or our discord or facebook groups i'm gonna be waiting for your projects okay that's all i hope you liked it if you learned something new today please like the video and you can support lamadel by joining to channel or using the link in the description below and don't forget to follow social media accounts i hope i will see you in the next tutorial goodbye you
Info
Channel: Lama Dev
Views: 411,265
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 hotel reservation, react booking, react calendar, mern, mern stack, mern project, mern tutorial, react hooks, jwt, cookies, react website, web design, mongodb
Id: k3Vfj-e1Ma4
Channel Id: undefined
Length: 229min 3sec (13743 seconds)
Published: Sun May 08 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.