Build and Deploy a Full Stack Realtime Chat Messaging App with Authentication & SMS Notifications
Key Takeaways
This video teaches how to build and deploy a full stack realtime chat messaging app with authentication and SMS notifications using JavaScript
Full Transcript
hi there and welcome to a project video where you'll build and deploy a full stack chat application with authentication and twilio sms notifications with direct and group chats emojis and reactions built-in gif support the ability to edit and delete messages specialized commands and much more this fully responsive medical pager is the best chat application that you can currently find on youtube in this video you'll work with modern technologies such as javascript node react and stream you'll learn advanced react best practices such as folder and file structure custom hooks and even react context api creating the user interface for the login and register page and for the entire chat feed you'll also learn how to work with stream api stream is the number one chat messaging platform that allows you to build scalable and completely custom chat applications using their apis we're also going to use twilio to send a real sms notification to a user when he's offline the chat app we'll be building is not a general purpose chat it is a medical pager themed chat application after watching this video you'll be able to build any chat application you can think of from clones of popular apps like whatsapp discord and slack to the fully custom messaging platforms i initially planned on putting this as a paid course but i later decided to release it completely free for you guys here on youtube so to support this video leave a like comment and subscribe it shouldn't take more than a few seconds and i really appreciate it in the end we're also going to deploy the application so that you can share it with your friends put it on your portfolio and get a job let's get straight into it [Music] before we begin please allow me to give you a quick demo of the application as i've mentioned the chat app we'll be building is not a general purpose chat it's a medical pager themed chat application it's an app where doctors and medical personnel can communicate to ensure that they're always up to date with what's happening in their divisions of the hospital of course this is just one example of how versatile stream is you can build anything you'd like clones of popular applications like discord or slack a coding community chat custom direct messaging app or anything you can think of this application consists of two parts a login and registration form and a chat dashboard so let's check out the login form when a doctor or a person is signing up for the first time they'll have to enter their full name username a phone number as well so that we can send sms notifications avatar url and a password once they sign up for the first time they'll be added to our database then they can simply sign in for example dr miller we enter the password and click sign in as simple as that we are right inside of our application as you can see it has plenty of features there are a lot of chat tutorials on youtube but i've never seen this many features on a video of course we can send messages but we can also add reactions to those messages there we go we can also reply in threads to a specific message so let's say hello there and like that we have built-in threads for replies as you can see right there we can also send gifs that's something that's pretty new so if you just type forward slash giphy and try to do something like hi it's going to give you all the random gifs that you can send right inside of the chat you can also send emojis images and you can also embed youtube videos so that you can play them right from inside of your chat we also have a search so you can search for different channels and users but more importantly the entire chat app is completely mobile responsive as you can see it has that native like feeling it feels like it is a mobile application and if you click right here you'll see a nice little animation that gives you access to all the channels and direct messages usually it would be extremely hard to add so many features to an application like this in one video but thankfully we are using stream as i've mentioned stream is the number one chat messaging api infrastructure it allows you to build scalable and custom chat applications extremely easily we can explore their demos we have a social messenger example the team collaboration one which is similar to ours customer support even live stream chat applications are covered and we also have virtual events if you wanna chat while watching a specific stream i think you can see how powerful stream is and stream is exactly what we'll be using in this video with that said i think you're pretty excited to start coding this application so let's dive into coding right away let's start by creating an empty folder on our desktop i'm going to call it medical dash pager of course feel free to call it a chat application or anything else you'd like once we have our folder i've also opened an empty visual studio code window of course feel free to use any code editor of choice in this case we'll be sticking with visual studio code so simply drag and drop the folder into your code editor now that you've done that you can simply go under view and then terminal we're gonna use this terminal to initialize our react application let's clear it and now we have to create two different directories so let's create a new folder this one is going to be called client for our client-side react front-end application and the other one is going to be called server this is going to be for our backend node.js server in this case we can start off with creating the client side so let's cd into client and then finally run mpx create dash react dash app dot slash that slash is going to make sure to install our react application right inside of the client folder now let's click enter we're gonna wait a few minutes and i'll be right back there we go our application has been initialized we can clear our terminal to start off let's go inside of our client folder and delete the source folder now every react application needs to have an index.js where we need to import react from react we also need to import react dom from react dom then we can import the app which we haven't yet created that's going to be import app from that slash app and finally we can say react dom dot render and we can render our application by specifying document.getelementbyid and that's going to be root even though i'm sure that most of you understand what this does let me quickly explain it our entire react application is going to be inside of this component and we're going to hook that component onto the root div and where that would div is is right inside of the public and then index.html this file might seem a bit weird but if we properly condense it like this remove some comments some more comments and even more comments and this you'll see that this is a simple index.html page with only one div and inside of here our entire react application will be while we're here we can also change this from react app to something like medical pager or feel free to change it to whatever you'd like great now we can go back to our index or more specifically we can start creating our app.jsx component inside of here i'm going to use an rafce which is react arrow function with export so this is simply going to create the entire boilerplate for the component you can use that same command by installing es7 react redux graphql snippets so if you install that extension you'll have plenty of these snippets that you can call to make your work easier with that said we have nothing more than a simple functional component inside of there for now let's simply create an h1 and say medical pager chat application great now we have our index we have our app.js and the last thing we need is to install all of the necessary dependencies there are only three most important dependencies that we're gonna need so you can say npm install and these are gonna be stream dash chat also stream dash chat dash react and finally universal dash cookie we're gonna use cookies to save the user information in the browser if you press enter this is going to install these three dependencies not a lot only three but these are going to help us to create our entire chat application while this is installing i wanted to quickly show you that we have the entire code for this project under project medical pager on github the link is going to be down in the description if you ever get stuck or something is not working as it should definitely make sure to check it out and compare the code even clone it if you need to if you like the project definitely make sure to leave a star as well with that said while our dependencies are still installing we can go ahead to stream and create a free account we're definitely gonna need it the link to stream is going to be down in the description now that we're here let's click try for free inside of here you'll of course have to enter your email also your organization name or your full name i'm just going to do javascript dash mastery and finally your password now that you've entered all the information simply click get started and with that you're already welcome to stream on the top right you can click go to dashboard there we go our demo production application has been created there is our key and our secret which we're going to use soon enough to create our entire chat application for now you can leave this page open and let's go back to our code editor our packages have been installed and we are ready to start creating this app so let's close this and this and we only need app.jsx for now inside of here we'll have to import a few things that we're going to use later on to connect to stream chat so let's say import stream chat from stream dash chat and we're gonna also need the react component which is going to be import chat in curly braces from stream chat react later on in our app we're also going to use cookies so we can say import cookies from universal cookie great now we have all of the imports right here to set up our chat we're gonna need an api key so we can say const api key is going to be equal to and now we need to find this key inside of our stream dashboard as you can see the key is right here you can simply copy it go back and paste it right here we're gonna use this to initialize our chat now that we have that we're gonna remove this h1 and we're going to give a class name to this div div class name is going to be equal to a string of app underscore underscore wrapper and inside of there we're going to render dot chat application chat is not going to be a self-closing tag we're going to put something in there more specifically we have to put the channel container and the channel list container these are all going to be components that we are going to create so let's simply specify them right now we're going to have a channel list container which is going to be a self-closing component and below that we're also going to have channel container again we don't yet have those components but we're going to create them right away also for this chat to work we need to create an instance of a stream chat so we can do that right here above our component we can say const client is equal to stream chat dot get instance and then we can call that as a function and pass in the api key finally we can specify client is equal to client we can also choose a theme of our application in our case i'm going to say theme is equal to team lite this is going to make our chat application look a bit better right out of the box okay we've set some things up but we don't have access to these components so what might be best is to create a components folder right away and to create the basic structure of all the components that we're going to have they are going to be quite a lot but if we nail down all the components and the imports at the start of the video it's going to be so much easier to simply keep using them later on so inside of the components folder we can first create two components the channel container and the channel list container so right here new file channel container.jsx and also channel list container.jsx and you guys often ask me what is the difference between js and jsx there is none i just prefer to use jsx for whenever a file is a react component that way it's easier to differentiate them okay with that said we can create a simple react arrow function component and we can specify the name of that component like this now that we have it it's going to be simple to simply copy and paste this across all the components we are about to create we can paste it here as well and you can double click the name of the component press ctrl f and then simply change it to something else in this case that's going to be channel list container great the two components we need right now are done so if we go to app.js we can simply try to import them like import that's going to be channel like this let me just copy it channel list container i misspelled it there so let's fix it channel list container from dot slash components slash channel list container and the other one is simply going to be channel container great as you can see we only have two so this is fine two imports two lines but later on we're going to have so many more imports and it's going to look like something like this this is not what we want so we're going to create a system for imports that's going to make her life easier in the long run if we go in our components folder and create a new index.js file inside of there we'll be able to export all the components automatically we can do that by saying export curly braces default as and then the name of the component something like channel container from and then we point to that file we can now duplicate this and inside of here this is going to be channel list container great now these components are being exported straight from the components folder and inside of our app we can say something like this import now in curly braces that's going to be channel list container and also channel container straight from dot slash components we don't need to add any file names because everything is being exported from there and now all of the imports are being done in one line there we go again i know this was a bit of work but it's going to make our life so much easier later on at this point we should already see something on the screen so let's open up our terminal by going to view terminal clearing the console and simply running npm start this is going to start our application on localhost 3000 there we go our application started but as you can see we don't have anything on the screen yet besides these two text elements so let's go ahead and add some styles to fix that at the end this application is going to look great but to keep this video focused and extremely informational only about building chat applications i'm going to provide you with the entire css style sheet we're going to use the bem methodology bem is a css methodology that kind of helps everybody understand how css class names are made we first have the block and then we have underscores with the element and then finally we have modifiers so you're gonna learn how to write these class names but i'm gonna provide you with the styles to create the styles we can go inside of our source folder and create a file called app.css inside of there we're gonna paste our styles all of the styles for our application are here you can find these styles and all of the links mentioned in this video are going to be right below in the description so just make sure to check that gist and simply copy and paste these styles right into the app.css then we can go inside of our app.jsx and right inside of here you can simply say import dot slash app.css this is going to import all of our styles and we'll be able to use these class names to immediately apply them great let's check out if this made any changes already no nothing special that we can see it just removed some margins and made everything appear in a list but of course as we add more styles and class names this application will start to look phenomenal with that said the basic layout of our application has been created now is the time that we keep adding more jsx more structure but more importantly keep getting into the logic of how we can implement our chat application let's start with creating our channel list container which is basically our sidebar now let's first import a few things from stream chat react we can import a channel list component and also use chat context that's going to be coming from stream dash chat dash react then we can import a few components that we are going to create ourselves something like channel search also team channel list and finally team channel preview these components will be coming from dot slash from r components and finally in this component as well we're gonna use cookies so we can say import cookies from universal cookie great now that we have that let's start creating our jsx for the sidebar so above our current channel list component we can create a new functional component which is going to be called sidebar our sidebar can have an instant return so just parentheses right there and then inside of there we can start creating some jsx first we're going to have a div that's going to have a class name equal to channel dash list underscore underscore sidebar and inside of that div we're going to have one more div which is going to have a class name which is going to be equal to channel dash list underscore underscore sidebar underscore underscore icon 1 and just one more div inside of it this div is going to have a class name equal to icon 1 underscore underscore inner great finally we have that icon so that's going to be an image which is a self-closing tag it's going to have a source src equal to hospital icon this is the icon that we're going to import right away and it's going to have the alternative text equal to hospital and finally it can have width equal to 30. great now that we're here let's also import that icon just at the top we can say import hospital icon from dot slash assets slash hospital.bng as you can see we don't yet have the assets folder so let's create it right now above the components right inside of the source folder you'll be able to simply paste the assets folder as with all the other files mentioned the assets folder is going to be linked in the description great as you can see that assets contain a few svgs which are going to be our icons and then it also contains a few png icons screens and images great now we can use that icon now i'm going to copy this sidebar icon 1 and duplicate it below this time it's going to be sidebar icon 2 icon one inner is going to remain the same but this time we're gonna have a logout icon also the alt is going to be equal to log out and the width is going to be 30 pixels for now we can simply duplicate this line and say import log out icon from and that's going to be logout.png great this is it for our sidebar now we can go inside of our channel list container i'm gonna make this div a simple react fragment and then inside of there we're gonna render that sidebar as a self-closing tag make sure it's spelled correctly and there we go of course we could have put the entire code right there but as our code is going to get more complicated we want to differentiate different parts of jsx to make it easier for people to read now that they've done that let's go into our browser and let's check it out as you can see this already looks just a bit better now we no longer have the channel list container which is actually just the navigation bar and now we're displaying it now let's keep adding more things to our navigation bar the second thing we're going to add is going to be another functional component called company header again just a functional component with an instant return just parentheses and then inside of there we're going to have a div that div is going to have a class name equal to channel dash list underscore underscore header and inside of there we're going to have just one paragraph tag which is going to have a class name equal to channel dash list underscore underscore header and then underscore underscore text again this is going to be a medical pager so we can specify that there finally we're gonna render that company header right inside of div below the sidebar so we can create that div give it a class name which is going to be equal to channel dash list underscore underscore list underscore underscore wrapper and right inside of that list we can render our company header let's save it and take a look as you can see we added this entire portion and just below we'll be able to display our search and all of the channels so as you can see stream is not simply building everything out for you it's giving you access to the apis which are going to allow you to search channels create channels send messages and everything else but you actually create the jsx the layout and the styling for your application now let's implement these three most important components the channel search theme channel list and team channel preview we can start with channel search i'm going to go to our components folder create a new file called channel jsx of course as soon as i created i'm gonna duplicate one more line inside of our index and i'm gonna add our channel search right there don't forget to do that because this import right here is not going to work then with that said how do we implement a channel search well our channel search is going to be a functional component so we can simply import react create that functional component and export it alongside react we're gonna also need use state and use effect hooks and we're gonna need the context from stream chat react so we can say use chat context and that's going to be coming from stream chat react inside of here we're also going to have one icon so we can say import in curly braces search icon and that's going to be coming from dot slash assets great now let's start creating the jsx for our search this div is going to have a class name equal to channel dash search underscore underscore container inside of that div we're going to have yet another div and this div is going to have a class name equal to channel dash search underscore underscore input underscore underscore wrapper now inside of that we're gonna have one more div and this div is finally going to have a class name of channel dash search underscore underscore input underscore underscore icon in there we can place our svg icon by saying search icon and calling it like a self-closing tag now of course below this div we can actually place our input so i'm going to say input and it's going to have its own class name which is going to be equal to channel dash search underscore underscore input underscore underscore text of course we'll have to provide it with a few more properties things like a placeholder equal to search a type equal to text and finally we have to give it a value and also the on change now that we can see we have a lot of props on this component i'm gonna simply space them out each in its own row okay so as we said input has two most important things and those are value and on change so what value is this input going to have well it's going to be query the search query we're looking for and what are we going to do on change well we're going to call the on search function so just above let's create that query state field i'm going to say const open pair of square brackets and that's going to be query and set query is equal to use state and at the start we can set it up to be empty string below that let's create that method for getting our search so we can say const on search is equal to we're going to get an event there and what we can do is simply first call the event.preventdefault we have to do this every time that you have an input or buttons or things like that because the usual browser behavior is whenever you click submit or something similar to reload the page we're working with react we want everything to be reactive instantaneous and we want to prevent that so that is what this line is doing now that we have that what we can do is we can also set the loading to be equal to true of course the loading is going to be another state so i'm going to duplicate this one and simply create a state field of loading and set loading at the start our loading is going to be set to false so we can do that right here now that we've set the loading to true we can finally set the query so what exactly are we searching for well we're searching for event.target.value remember in react whenever you type something into the input you get the value of that text under the event target value and finally the last thing we want to do is we want to get the chat channels for that we can call a new function called get channels to that function we of course also have to provide the searched query so we can simply say event target value one more time of course you can see this function is not yet existent so let's create it const get channels this function is going to be an async function because we have to wait for the channels to be fetched now that we have that it's going to accept the text we're searching for and inside of here we can open a try and catch block we'll try to get the actual channels if we cannot we'll go to the error so if we have an error we can simply set the query to be equal to nothing just reset the search but how exactly are we gonna get the channels well we have to do that later on because we haven't yet set up our entire chat application so i'm simply gonna add a to do right here and i'm gonna say fetch channels by the way if you're wondering why is this comment orange that's because i'm using an extension called better comments i find it to be pretty useful if you want to have a to-do you can just type to do or you can make something green like this or even add an exclamation mark to make it red so it's just coloring the comments basically we have our to-do here that's something we have to do later of course we have to do it once we actually have the logged in user to the chat and once we have a few chat messages direct messages channels and so on so for now the important part is that our jsx is done later on we're gonna implement the logic before taking a look in the browser i just noticed that i have a typo here that's gonna be assets now that we fixed that part let's actually use our channel search inside of our channel list container we are importing it but if you scroll down you'll notice that we're never using it so to use it we can call it as a self-closing component right here so to use it we can call it just below our company header as a self-closing component let's save it and take a look there we go our search bar with the search icon is right in here of course if you start typing something it's not going to work because we don't have users yet so now let's create the layout for the channels and for direct messages and then we'll move on to the channel container next component on our list is the team channel list so inside of the components let's just create it team channel list dot jsx and we're again going to use the rafce to simply create a functional component inside of here we won't have to import a lot of things this is just a list so what we can do is simply import add channel this is going to be an svg icon from dot dot slash assets and that's going to be it so now let's create the jsx of our channel list so right inside of here we'll have a lot of variables that we can work with and how are we gonna pass them well they're going to be passed for us by using stream so let's go back to our channel container we named our component team channel list but notice that we also have the channel list coming from stream chat react so if we scroll down let me show you how we're going to call it first just below the company search we're going to call the channel list channel list is a self-closing component but it accepts a few props first it accepts filters filters is an object that's going to allow us to filter some messages then we're also going to have the channel render filter function this is a function that we can call and based on that we can also pass on filters so again right now i'm going to leave this empty and finally the most important thing is the list so we can say list with a capital l that's an important part that means that we want to render a custom list we can do that by providing a callback function we get access to all the list props right inside of here and finally we can render the component we've created which is called the team channel list so basically what's happening is stream allows you to get a channel list component right out of the box it's going to look good but we still want to create our own custom team channel list and that's exactly what we're doing so we're getting all of these list props and we can simply spread them right here so that's going to be dot dot list props inside of the curly braces that means that our custom component will get all the props that the channel list would usually get using stream now when it comes to filters i'm simply going to put that as an empty object right now and for the channel filter function we're gonna just leave that as an empty holdback function just like this let's save it and now let's make use of all of these props we're passing to our team channel list going right in here now we can get access to them the first prop that every single react component has is the children property then we're going to have the error which we're going to set to false at the start we also have the loading and we also have the type that type is going to be dependent on are we in group chats or just direct messages so let's first handle the errors at the top we can say if error we're going to return something but before we have to check out the type if the type is equal to team then we want to return an error message like this right here we'll specify the jsx and if it's not team we simply want to return null it doesn't exist so how is the jsx for this going to look like well right here let's create a div and that div is going to have a class name which is going to be equal to team dash channel dash list below that we're gonna have one paragraph tag so p tag that's gonna have a class name equal to team channel list underscore underscore message and inside of there we can simply say connection error please wait a moment and try again great that's about it for the error now we can actually create the loading part so just below this if we're going to create if loading inside of there we're also going to have a return statement and let's return the same div that we already have so we're going to copy the div with the paragraph and paste it right here this one is going to be team channel list team channel list message but we're going to add loading to this so it's going to be space loading and then finally instead of the error message we're going to open a dynamic block and we're going to say if type is triple equal to team in that case we want to say channels else we want to say messages and then finally we're going to add loading dot dot this is our loading now that we've handled the error state and the loading state we can actually show our lists so this div is going to have a class name equal to team dash channel dash list below that we're going to have one more div and this div is going to have a class name equal to team dash channel dash list underscore underscore header and as we had so far we're going to have one more paragraph so let's create a paragraph tag and this p tag is going to have a class name equal to team dash channel dash list underscore underscore header underscore underscore title a lot of underscores there so what we can say is we can simply copy this dynamic block paste it here and if it is a team chat in that case we can simply say channels else we can say direct messages that's about it and below this later on we're going to have a button to add the channel right now we're going to leave that blank but later on you know it has to be here and finally outside of this first div we want to render the children everything that has been passed to our team channel list we want to render it right here great with that we are almost done with our team channel list component let's go into our index.js and let's export it from there so that we can use it in our channel list container that's going to be team channel list now that we are exporting it let's see where we are using it that's gonna be in the channel list container as you can see at the top right here we're importing it and we're using it right here and passing all the list props but remember we also have to pass the type the type is going to be equal to team we have to do that specifically because below we're going to have this exact same channel list but the type is going to be messaging for direct messages so we need to be able to differentiate them let's save it and take a look there we go right now we have connection error please wait a moment that makes sense because we haven't yet connected anything but we have it here for later on now we also have to implement the last component in this file which is the theme channel preview so let's create that component called team channel preview.jsx not to forget let's go to the index and let's quickly export it from there that's going to be team channel preview back in here we can run rafce to get our simple code running the situation with our team channel preview is going to be the same as with our team channel list we're gonna get a lot of props they're gonna get passed into it so by going here we can simply specified one more prop which is going to be called preview and that is going to be equal to a callback function with an instant return right there we get preview props and now we can render our own component which we called team channel preview now we can spread those props so dot preview props and finally we also have to pass the type which is going to be the same type is equal to team now that we have all the necessary components in our team channel preview we can go back and we can use them right inside of our props the props we need for now are going to be channel and also type great inside of this component we'll also use a few more things from stream chat react so we can say import and that's going to be avatar for images and also use chat context and this is coming from stream dash chat react now that we have these things let's actually use that context so right inside of here we can say const the things we need to get are going to be the channel and also the client that is coming from use chat context and we call it as a hook i'm going to rename the channel right here to say active channel because we're already getting a channel at the top with that said let's create a block of jsx which is going to be called channel preview so right here channel preview as we've done before it's going to be a functional component just to simplify the live for us later on and inside of here it's only going to be a simple paragraph tag with a class name which is going to be equal to channel dash preview underscore underscore item and there we can say hash or pound sign and we can specify the name of the channel we can get to the channel name by saying channel.data.name i'm going to add a question mark before the dot for the data and the name to make sure that we have the channel before we want to access something else or maybe the channel doesn't have a name in that case we can use or and then say channel question mark.data question mark dot id this is a preview for the channel with multiple users but now let's create a preview for direct messages we can do that by saying const direct preview is going to be equal to and then we instantly return it and there we're going to have const members is equal to channel dot state dot members but unfortunately the data that we get back is not going to be an array while you might think we're gonna get an array with different objects like this what actually happens is we get back an object like this and then that object has the ids one two three and then there's the user object so it's going to look like this because each user has a specific id and then based on that we're going to show their data so what we need to do is we need to turn an object with again objects as keys and values to simply an array of objects that we can map through so let's remove this and this and let's use the built in javascript object dot values that's going to give us the values of all the items in that specific member's object once we get that we also want to filter through that so we can call the filter method filter accepts a callback function and in this case we want to filter through the members so in here we get each member but to get the data about that member we have to destructure it and then specify the user so this is how we're accessing each specific user in that object then we want to check if the user dot id is not equal to client dot user uppercase id make sure that you have the id all uppercased and close the parentheses properly so what we're doing here is we're mapping over all the users and we're keeping all the ones where the id is not equal to the client id which is our id so we're basically throwing ourselves outside of that chat so we can get the actual users we're talking to i've noticed this is not going to be an instant return so i can just switch this to curly braces and in that case we have to remove one parentheses great now we have the members but they're not including ourself so right inside of here let's return a block of jsx we can say div there we're gonna have a class name which is going to be equal to channel dash preview underscore underscore item and then space single inside of there we're going to specify our avatar avatar is just the user's image so inside of there we can pass the image property which is going to be equal to members 0 and then question mark dot user dot image like this finally we can also pass the user's name which is going to be members zero dot user and then dot full name make sure to add question marks before all of these because we always need to know that the user actually exists finally we can specify the size which can be equal to a number of 24. finally below this avatar we can also have ap tag and then in here we can list our member's name we already have that so i'm going to copy the name and just put it here now we have the channel preview and the direct preview let's actually use these components inside of our team channel preview so this div is going to have a different class name depending on if the current chat is selected or not so we can say class name is equal to we're going to put it as a dynamic block in here we can say channel question mark dot id and if it's triple equal to active channel question mark dot id so if they are the same our class name is going to be channel dash preview underscore underscore wrapper underscore underscore selected else it's simply going to be channel dash preview and then underscore underscore wrapper it's not selected of course this also has to be a string and with that we've entered our class name so still inside of our div we're gonna add an on click property on our click we're gonna of course select the actual channel but for now we can simply console log the channel name so we can say channel right here great and then of course inside of this div dependent on the type so we have to say if type is equal to team in that case we're going to render the channel preview and then if it's not we're going to render the direct preview great this is it for our component for now of course i don't think any chats will be showing because we don't yet have the users so soon enough it might be a good time to actually start implementing the logic for creating the authentication getting our users in there and displaying the data so for now let's go back to our channel list container considering that we don't currently have any chats unfortunately the preview is going to be empty below this channel list we need to create one more exactly the same channel list below the channel list for group messages we also need to have a channel list for direct messages so simply select it and then duplicate it below we're going to have just a few small differences for example in the list we're going to render the team channel list but the thing we're going to pass over is going to be messaging so that's the type of the actual team channel list and you can simply paste that here as well so now once we actually get everything to work you should be able to see two different channel lists one for the group messages and one for the private ones right now we still have an error and that makes sense because we are not currently logged in we don't exist in database and there aren't any channels or direct messages so now might be a good time to implement authentication and the entire logic that comes with it we have to create a node.js server create endpoints for the signup and the login and then finally send the data from the frontend to the backend to create a user in the database so let's go ahead and first create the front-end layout for our authentication to do that we can close all the current files collapse everything go inside of the client source and then finally app.jsx instead of here we're going to import auth auth is going to be a new component where our login and registration form are going to be in so when do we want to render that auth well we're going to have a variable which is going to be something like auth token and this odd token is going to be available only if we've actually logged in so for now we don't have it it's going to be false and based on that variable we'll show or hide the form so we can say if there is no auth token in that case we want to render or return the auth component so we're gonna hide everything we've done so far if we're still not logged in now that we have this let's actually go to our components create a new file called auth.jsx and let's not forget to export it from here that's going to be off great inside of that auth it's going to be similar situation as with most components we're going to use the rafce alongside react we're also going to need use state and we also need to import a few other things in this component we're going to use cookies so we can say import cookies from and that's going to be universal dash cookie then we're also going to use axios so we can say import axios from axios and i've just remembered that we haven't installed axios so we can go under view that's going to be terminal and we can stop the current server from running by pressing control c yes and then type npm install axios great while that is installing let's import sign in image from dot slash assets forward slash sign up dot jpeg great this is installed and we can simply run npm start and close the terminal again now let's start creating the layout for our authentication our first div is going to have a class name equal to odd underscore underscore form-container then below that we're going to have one more div and that div is going to have a class name equal to auth underscore underscore form dash container underscore fields we're going to have one more container inside of that and this div is going to have a class name equal to auth underscore underscore form dash container underscore fields dash content i know these class names are getting long but this is how you use the bim methodology now inside of there we're gonna have a p tag and this p tag is simply going to say sign up or sign in so we need to have a variable to know are we on the sign in form or on the sign up form so let's create that variable that's going to be a state so we can say use state and select it right there so we are going to name it is sign up are we on the sign up form or are we not the initial state of the signup is going to be set to false because we want to get to the sign in first and then in here we can say if is sign up in that case show sign up otherwise show sign in let's save it and take a look in the browser as you can see we have this nice blue screen where it says sign in now let's keep in mind that we'll have to add a lot of inputs buttons and headings to this form and we want to see the changes live as we code them for that reason i'm going to put my browser side by side with the editor so right now while we code something we can see the changes live great just below the paragraph we're going to have a form that form is going to have the unsubmit property which is going to be empty for now and then inside of that form we're going to have a lot of inputs and labels some inputs will be available only on the sign up so we can make that check like this if is sign up then show this this is the shorthand method for the ternary operator you use the ternary if you have two things that you want to show but you simply say is sign up and then end end if you only need to show one thing based on this condition so what do we want to show if it is on sign up well we want to show a div and that div is going to have a class name equal to auth underscore underscore form dash container underscore fields dash content underscore input this is the longest class name so far but it's fine we got it done so inside of that input we're going to have a label that label is going to have the html4 property and is going to be equal to full name inside of there we can simply say full name of course below the label we have to have the input so i'm going to say input and let's add a few properties first the name is going to be set to full name then the type is going to be equal to text then the placeholder can simply say full name and finally we need the on change property on change we're going to call a specific function called handle change and this handle change is going to handle the change for all of the inputs that we have also let's make it required great so this is it let's save it of course we have an error we cannot have an empty on submit so for now i'm going to put a callback function inside of there and of course we also have to declare the handle change so we can see const handle change is equal to and for now we're gonna leave it as a blank callback function okay we cannot yet see this because we are on the sign inform and not sign up so let's manually switch this to true and there we go full name with the full name input of course we don't want to create all of the fields by hand so let's simply copy this div and paste it below the label is going to say username this time and we can say html4 username now of course the name of the input is going to be username the type is going to be text and then in here we can just say user and that's about it we have the input for the username as you can see right here now you might be wondering why is this not inside of the is signup block and that is because well we need the username both when we're signing up for the first time and every time that we sign in the user needs to enter the username now below the username we're going to have one more field and this one is going to be inside of the is signup block so i'm going to copy this entire block and simply paste it below there we go this one is going to be a phone number so we can say phone number here html4 phone number name phone number type text placeholder is going to be phone number as well and we're done with one more input field below that one we're going to copy everything and this one is going to be avatar url this also needs to be shown only on the sign up because we need to choose our image only once so that's avatar url like this make sure the name contains the url all uppercased and then in here as a placeholder we can also say avatar url great below that we're going to have our password this time we won't show it only on the sign up so i'm going to copy this div and paste it right here we can rename this and this to password html4 password name is also going to be password and the type is going to be of course password that's it our password field showed up now we want to have just one more field but this is going to be when we want to repeat the password so i'm gonna paste this entire part right there we need to copy the is sign up block because we only want to show the confirm password on the account creation like this i know the indentation is not perfect but let's try to get it done and this here is going to be confirm password i can put that here as well confirm password and the name in the html4 for that are going to be confirm password and again make sure that the name in all of these inputs is correct because the way we'll be managing data requires us to have a specific name right here that's great we have one more field which is confirm password finally below that we're gonna have one more div and that's going to be outside of the form so i'm going to put it outside and finally indent it properly now i can even make the text a bit bigger and this div is going to have a class name equal to auth underscore underscore form dash container underscore fields dash account so in here we can simply add a paragraph tag in this paragraph we want to show a different message depending on if user is sign up or if not so we can say if is sign up in that case we can display a message something like this is sign up and that's going to be already have an account question mark but if it's not then we can say don't have an account question mark we need to be able to switch between the modes and then we're going to have a span element inside of that p element and it's going to have the on click property which is going to say switch mode in there we can again look at the is sign up variable and if we are on the sign up then we can show sign in otherwise we can show sign up let's save it and take a look of course our switch mode is not defined so let's define the switch mode that's going to be fairly simple at the top let's define the switch mode function by saying const switch mode is equal to a function and then in there we can set is sign up to be not is sign up but the better way to do that is to provide a callback function where we get the previous value of a state field so previous is sign up and we simply want to return a negation of that so that's going to be not previous is sign up this is the correct way to do it in react when you want to change the state depending on the previous state there we go we have the signup form and the entire thing now if i click sign in it switches to the sign in which is a lot simpler finally we also want to display an image next to our form so we are going to go above the div that's the last one so above here and we want to create one more div inside of here that div is going to have a class name equal to auth underscore underscore form dash container underscore image and then in there we can simply display that image that's going to be img and then source is going to be equal to sign in image which we declared above we can also have the alternative tag which is going to say sign in great as you can see it doesn't look that good on smaller devices but if we actually switch to mobile you can see that it gets pushed to the top and it seems like a banner but then if we go to the full screen you can see it looks great right here as well so the actual layout for our login is now done now we have to handle the states of these fields and then send them over to the backend which is going to create an account or log in the user then our user is going to be logged in onto the dashboard we've created previously and we'll be able to show all of his channel previews direct messages and everything else first let's handle the data from all the inputs that's what the handle change function is for but of course we first have to create a state field let's create a new state field called form so we're going to have form and set form which is going to be equal to use state and there we want to show something at the start we want to have an initial state so at the top we can define that initial state as an object and that object is going to have a few properties it's going to have a full name which is going to be equal to an empty string we can also add the username equal to an empty string there's a password which is equal to an empty string and all of the fields we've had we have to reset them to an empty string so it's going to be a phone number and then finally the avatar url these six fields form our initial state and we can put them right here so now we have our form and set form and finally let's add our handle change so what do we want to do on the change well we get an event with text of the input we're changing and then we want to call the set form so remember a form is not just a single text field it is actually an object so we have to put an object there and we have to spread all of the other items from the form so we spread all the other inputs because we're only changing one and we want to keep all the other ones but then how do we change a specific one well we're gonna get e dot target dot name that's the name of the input we're changing and then the value for that same input is under the event.target.value and why are we using square brackets right there because this here is a syntax error so you have to wrap the name of this specific object key in the square brackets and then set that equal to e.target.value that's going to update our state field and we can even take a look at that by simply doing a console log which is going to say form so let's check it out there's my form and i'll try typing something dr smith there we go as you can see it's keeping track of everything that we write the username can look like this and as you can see now it kept the full name but it keeps adding to the username and it's always going to be one letter late but don't worry about that because our user still has to click the actual sign in button now that i've mentioned that i'm noticing that we are actually missing our sign in button so let's add it right away that button is going to be right here as the last thing in our form so still inside of our form we're going to have a button more specifically it's going to be a div with a class name which is going to be equal to auth underscore underscore form dash container underscore fields dash content underscore button a long one and then inside of that div we're gonna have a button that button is going to check if we're on the sign up or on the sign in if we're on the sign up we're simply going to say sign up else we're going to say sign in let's save it okay now we have the button and that button is going to trigger the actual submit so if you scroll up you'll notice that right here we have our on submit and we have to create a function for that so let's create a handle submit function we can add it right here const handle submit it's going to accept the event and in here we have to handle the logic of logging in or registering usually when you submit a form you need to add e dot prevent default because it's going to reload the page and in react we don't want that okay now we have it let's also console lock the form to see if we're getting the right thing passed to the back end we can remove the console from the handle change let's save it and take a look okay let's enter our name let's do dr smith again dr smith as the username one two three one two three one two three in here we can enter his avatar image i just went on google and i copied the image address so we have a doctor image address here and then finally let's enter and confirm the password i'm going to click sign up and look at that here is our data object this is exactly what we want to pass over to the back end so that we can create a new stream account let's do that right away of course to be able to make requests from the front into the back end we have to create the backend part so let's close all the files collapse it and go inside of our server directory inside of there we can create a new index.js file this is going to be the starting point for our entire server we can also open the terminal by going to view terminal and we can split the terminal in half by clicking this button now this one is running the front end and with this one we can cd into the server part let's clear the console and we're going to run mpm init dash y this is going to initialize amt package.json there we go with that we can now install all the necessary dependencies and add corresponding scripts so let's first start by installing all the necessary dependencies to do that we can run npm install make sure that you're in the server part of our project and we're going to need bcrypt we're going to use that for hashing passwords also crypto to create a random cryptographic string then we're going to need dot env for environmental variables also express also get stream and stream dash chat we are also going to use nodemon and finally twilio for sending live sms messages so let's press enter and we're going to wait for this to be installed now that our packages have installed we can add some new scripts so i'm going to delete this test script and i'm going to add a start script make sure that everything is in double quoted strings because we are working with json and then right here we can say node index.js this is a command to start our server below that i'm going to add a dev command which is going to run nodemon index.js nodemon is a package that reloads your application whenever you change the code so we need that for development so as you can see now we have the scripts we also have all the dependencies and let's create the basic express node.js server so inside of index.js we can say const express is equal to require and then express we also need course so we can say const course is equal to require and then that's going to be course that's used for cross origin requests and i just remembered that we didn't install that so we can say npm install and then simply paste course okay now that we have express here let's create the instance of that express application by saying const app is equal to express and then we call it we also need to specify the port for our backend so we can say port is equal to process.env.port or 5000. also we're going to use a lot of environment variables so we can say require and then dot env and then dot config this is going to allow us to call the environment variables right inside of our node application now let's set up our middleware by saying app.use instead of here we can use that course if we call it as a function that's going to allow us to make cross-origin requests we need to set one more middleware which is going to be express.json and you call it as a function this will allow us to pass json payloads from the front end to the backend and finally have that use and inside of here we're going to say express dot url encoded this is a built in middleware function in express so it's going to be url and coded like so great finally we are ready to create our first route and that's going to be app.get and it's just going to be a root route so we can say just forward slash create a callback function that callback function is going to receive request and response as parameters we can use the res.send method to simply respond with something like hello world just so we know that our backend server is running of course for our server to be running we need to run it on a specific port and we need to listen for it so let's say app.listen and that's going to be on port port we get a callback function and there we can simply say console.log and say something like server running on port and then we can say port right there of course for this to work we have to use backticks so i'm going to put them right here and here and we have to close the last parentheses there we go this is a minimal instance of an express application so let's run it i'm gonna run it in the development mode by saying npm run dev nodemon started their application on localhost 5000. so if you open up localhost 5000 in the browser you should be able to see hello world that means that we successfully created and ran our server now let's add routes for our sign in and register we can do that by requiring routes at the top const aud routes is equal to require and then that's going to be dot slash routes and then forward slash auth.js of course we haven't yet created that so let's go to our server and let's create a folder called routes inside of there we can create a new file called auth.js there we need to require express so we can say const express is equal to require express and we need to get a router from that express by saying constructor is equal to express.router and we call it finally we're going to create two different routes router.post both of these routes are going to be post routes because we have to send the data from the front end to the back end and only with the post routes can you send a payload the first one is going to be to forward slash sign up and the second one is going to be to the forward slash login of course we want to have a function that's going to happen on each one of these routes so we're going to create controllers inside of the server i'm going to create a new folder called controllers and inside of there i'm going to create the auth controllers so auth.js now inside of there we can create the actual login function by saying cons login is equal to a function like this and also we can create the sign up function like this of course these functions don't do anything yet but we're just creating them so that we can export them right here and with modules we do module dot exports is equal to an object and there we have the sign up and also the login so now we're exporting the functionalities which are going to happen once we go to a specific route so inside of here we actually have to import them and we can do that by saying const sign up and login we're getting that from which means equal to require dot dot slash controllers slash odd dot js and what do we do on the sign up post we call the sign up on the login post we call the login and we need to export our router which we can do by saying module.exports is equal to router now we can use this router inside of our index.js which means that these routes are going to be added to our whole server we can do that by saying app.use and then we can specify the start of the url which is going to be forward slash auth and what do we show on the forward slash auth well we show the auth routes which we imported from the routes folder that part is now done and now the only thing we have to do is actually implement the logic of receiving the data from the front end and finally creating or logging in the user a reasonable first step would be to create the sign up first because we have to have the users to be able to log them in so let's try with the signup we're going to have a try and catch block right there if something goes right we're going to be inside of here if something goes wrong well we're inside of the catch if we're there we can simply run console.log error and also res dot status 500 dot json and then we're simply going to send back the message which is going to be the error you might be wondering where is this rest coming from well every single controller is going to have the rec and the rest functions our rack is going to contain the information what we're sending from the front end now i'm going to copy this part to the login as well because that part is the same and let's start implementing the sign up for the sign up what things do we need to get from our request.body or more specifically from the front end well we can destructure it because we are getting everything from direct.body so what do we need well we need a full name to save it to the database also the username the password and finally the phone number now that we have that information let's create a random user id for each new user we can do that by saying const user id is equal to crypto that's going to be a package that we need to import at the top so just at the top above the sign up let's require the crypto package or let's also require all the packages that we're gonna use in this file so that's gonna be const connect that's coming from or more specifically require get stream then also const bcrypt is equal to require and that's going to be bcrypt we also need an instance of a stream chat so we can say const stream chat is equal to require stream dash chat and finally cons crypto is equal to require crypto that's it now we have everything that we need let's scroll down and let's implement the user id so to create a random crypto string we can say crypto dot random bytes and let's do something like 16 and create a hexadecimal string out of it this is going to create a random sequence of 16 hexadecimal digits now let's make a connection to stream we can say const server client is equal to connect and now we have to use that connect from the get stream to connect to the server but we need to pass a few things we need to pass the api key so let's specify it here api underscore key also api underscore secret and finally app underscore id all of these things should be secret and you shouldn't share them with anyone that's why we're gonna use environment variables so just at the top let's say const api underscore key is equal to process dot env that stream underscore api underscore key i'm going to duplicate this two times the second thing is going to be api underscore secret and in here we can say stream api secret then we're going to have the app underscore id and that's going to be stream app underscore id so stream underscore app underscore id great now where do we find these values well you can find them in your stream dashboard let me show you right here on your stream dashboard you have your profile you go to chats and then finally you go to overview there at the top you'll be able to find your app id so that's the first thing that you can copy now we can create a new file inside of our server called dot env and there we can add our app id so i'm going to copy the name stream app id and paste it here and add the equal sign in between so stream app id like this also we can copy those paste them and let's go back to the dashboard to find the values for the secret and for the key now if you scroll a bit down you should be able to see app access keys here is a key let's copy it paste it right here and finally a secret i'm going to copy it and paste it right here now we have all of the necessary environment variables let's go back to our controllers and now these values api key secret and id are going to be populated straight from our environment variables therefore we can use them right here to connect to our server client we are going to use that server client to create a new user token so let's create a password first const and that's going to be hashed password is going to be equal to a weight bcrypt and then we call the dot hash method on the bcrypt and we pass in the password and finally we can pass 10 as sold basically how much is it going to encrypt it this number specifies the level of encryption great i've noticed that i didn't specify my function as async so let's add it as async because we're using a weight in here and this line is turning our plain text password to the hashed password finally let's create a token for our user by saying cons token is equal to server client dot create user token and then in there we can pass the user id now we have everything we need we have a phone number username full name token everything ready to create a user so let's return that data to the frontend res that status is equal to 200 dot json and then an object we want to pass the token full name username user id hashed password and finally we also want to pass the phone number we could get these values straight from the front end but let's get them from the back end as it's more secure that way to be sure that this is the actual user we're creating and while we're here let's also create our login function it's also going to be an async function we also want to get some data from the front end const and in this case we just want to get the username and the password that part is coming from wreck that body and rig that body is getting populated as we pass data from the front end from our form which we created previously to the backend we also want to connect to the client so we can use this server client connect it's going to be the same thing i'm going to paste it here and we also want to create a new instance of a stream chat we can say const client is equal to stream chat dot get instance and then in there we pass the api underscore key and api underscore secret we need to use that because we want to query all the users from the database that match this specific username so we can say const destructure it to get the users and then say equal to await client dot query users and then only the users that match the name which is equal to username so one more time this time we're not creating the user we are taking the username and we want to query all the users from the database to see if anyone matches if there are no users so if no users.length then in that case we can return rest.status let's do 400 dot json and the message is going to be something like user not found if we go over this point that means that our user does exist and we have to decrypt the password and see if it matches the one that the user created the account with so we can say cons success is equal to await bcrypt dot compare we pass in the password and we take the old user's password by saying users 0 dot hashed password again every user is going to have that hashed password variable because remember when creating the user we actually create the hashed version of his password we are not keeping it in plain text and that's why we gotta do it now that we have that we also want to create a new user token by saying cons token is equal to server client dot create user token and this time the token has to be created using the same existing id so we can say user 0 dot id we are no longer passing just a regular user id which we just created we want to pass that specific user's id and now that we have everything we have the token if our action is successful so if this is success in that case we want to finally send all the data back so we can say rest.status is equal to 200 and then dot json and here pass the data we want to send we want to pass the token we also want to pass the full name which is going to be equal to users 0 dot full name then we want to pass the username finally we want to pass the user id by saying users 0 and then dot id now we have everything we need finally if we had a failure here we can say rest.status that's going to be 500 dot json and we can simply return a message in an object which is going to say incorrect password like this that's it i know that this hasn't been easy we are creating users creating different user ids hashing passwords sending the data back to the front end and then for the logged in users we are querying that user from the database again decrypting that password comparing it and then finally creating the new token and sending it back it's definitely not easy but now we have our back end done now we can close all of these files and then go back to the client side more specifically in components auth and then from here in handle submit remember this form data we want to pass that form data back to our backend let's do that right away okay instead of console logging the form let's actually get the data out of it we can say const and then destructure some data from the form in this case we are going to need the full name username password phone number and then finally the avatar url and all of this is coming from not e target it's coming from form then we need to specify the url we'll be making a request to so we can say conturl is equal to and that's going to be http colon forward slash forward slash localhost collin 5000 that's it this is our url but don't forget it's going to be to forward slash auth now that we have the data and we know our url let's make an axios call i'm going to turn this function into an async function so that we can use async away and let's use axios to make that request we can say const that's going to be data and that is coming from await axios.post we post to a specific url so i'm going to say url but it's not it we have the forward slash odd but then it has to be either sign up or log in and how are we going to know which one is which well we can say forward slash and then inside of here we can see are we on the sign up so if it is sign up in that case we are going to simply show sign up but if it's not sign up we are going to go to sign in so we can have this logical block right inside of our string right here and finally the second thing that we have to pass into this function is going to be the object with all the data we can pass the username also the password full name and finally phone number and the avatar url great there are a lot of things we're passing but we should be fine from that we are getting the data that's the data we're passing back from the front end now that we're passing the right url and we're passing all the necessary data we'll also be getting something back from that data so let's immediately destructure some things out of it we are going to the structure the token also the user id and finally the hashed password great now let's use those values to add them to the browser cookies so let's create an instance of our cookies at the top i'm going to say const cookies is equal to new and then we call cookies great right here we can use those cookies by saying cookies dot set and then for example let's first set the token right here i'm gonna say token and then pass the actual token value now i'm going to repeat this three more times and the second time instead of the token it's going to be user name for the third time it's going to be the full name we want to store all of this data inside of our cookies and then finally it's going to be user id but if we are creating the account so if is sign up we have some more things we might want to set so i'm going to copy these and if it is sign up we also want to set the phone number so right here phone number also the avatar url make sure that all letters are uppercased and finally hashed password in this case we are storing everything inside of the cookies we might not need everything on our front end but it's just good to know that all the data we're getting from the back end we now have it we have the avatar url the phone number and we'll be able to use it all across our application finally once we set the cookies we want to reload our browser we can do that by saying window dot location dot reload and we call that as a function with that we are completely done with our odd file so one more time to repeat we are going to fill in all the inputs then we are going to go into the handle submit function get all the data from the form get the url make the request to our backend more specifically we're going to make a request to a different url each time depending on if we're logging in or signing up and we're going to pass all the form data then we're going to get some data back from the backend and we're going to store everything into cookies then finally we're going to reload our application why are we doing the reload well if we do the location.reload we're going to reload the application and this time our auth token should be filled that means that we are not going to hit auth again we are going to go to our chat as a logged in user because now we are going to have our odd token okay but right now we have this odd token set to be false how can we actually get the data well we can do that using the cookies we can say const cookies is equal to new cookies same thing we did before and now instead of setting the values we are going to get them let's first get the odd token i'm going to pull this up below the api key and we can simply do cookies dot get and then in here it's going to be token now we can see if we have that auth token by doing if odd token if we do have the auth token we want to create a user so we can say client dot connect user if the user hasn't been created yet it's going to create it so client dot connect user this thing accepts an object so let's expand it and we have to pass everything that we have right here in the cookies so i'm going to simply copy these values and also these values now i'm going to go back and simply paste them as you can see we have all of these cookies of course this is not in the right format so what you can do is click here then you can move across by holding ctrl and using arrow right and arrow left by doing that we can now delete or reset this set to simply get also we are not setting anything so we can delete these values by simply moving to the end of each line and then holding ctrl and pressing backspace as you can see now we're simply getting all of the values but we're not done yet of course we're in an object so we have to have the key go at the end of the string hold ctrl and shift and press arrow left that's going to allow you to copy each word now press ctrl c and then a few more times ctrl left arrow go to the start of the line and press ctrl v and finally a colon once you do it one more time go to the end of the line and turn all semicolons to simply columns and just like that we've used some shortcut magic to format all of our data from setting the cookies to getting the cookies and using them for the connect user call now if this was a bit too much for you or if you followed along but you would like to learn more cool shortcuts let me know in the comments down below to create a whole shortcuts video if this was too hard for you to follow along definitely make sure that you have everything the same as we have right now you need to have the token username full name and all these details being fetched from the cookies we have to make just a few changes the user id cannot be user id it simply has to be id that's how it is in the client.connect user then instead of the username this thing here is just going to be name after that we have full name after that instead of the avatar url we're going to call this simply image then we're going to have the hashed password and finally the phone number we won't need the token here because we're already getting it at the top so you can remove that line now that we're done with this make sure that you have everything the same just in case so that we don't have any errors moving forward finally this connect user function accepts a second parameter which is odd token that same token we had right here that's it this is going to connect our user and we'll be able to get all of his messages now let's see if our if statement here makes sense so if there is no odd token then return auth but if there is odd token then simply show this and that's exactly what we want to see so let's try creating a user and then logging in as that user before we go ahead and sign up let's quickly open up the stream chat overview right here you can go to chat and then explorer under users you should be able to see just yourself your own user and then under channels no results at the moment so if we successfully did everything once we sign up we should see a new user created right here so let's go to our medical pager before i click sign up i'm going to open the console and let's click sign up there we go we have an error which is completely normal we did a lot of coding but we haven't tested it so now is the time to finally do so we have a 500 let's look at it 500 on the sign up and we have a message this method can only be used on server side using your api secret use client and then stream connect so looks like we are using something that shouldn't be used on the backend let's check it out in more detail looking at the code and looking at the stream documentation i've noticed that right here alongside stream chat and just requiring stream chat we also have to create an instance out of it so right there we have to say stream chat i'm assuming that the values of these environment variables are undefined so let's go to our index and then let's take this require.env.config and let's just put it right here above where we need those values i'm going to save it go back and one more time i'm going to click sign up there we go we didn't have the values for the environment variables so let me quickly explain what happened we were trying to connect to this specific thing and it was saying you cannot connect these values are not filled in so i assumed that the environment variables from the env weren't filling in and that means that we need to require the envconfig just prior to using the environment variables so just by adding this line we fix the issue but also it's good that we came across this issue because i've noticed that we were missing this dot stream chat here so definitely make sure to include that part with that said we are actually logged in as you can see right there channel container we have our channels and direct messages and you have no channels currently of course right now we don't even have the button to create those channels but if there were any they would show here what we could do is now go to stream chat overview and see if that user has been created so let's go to explorer users and look at that this is our user id and if you click it you can see right here you can see the phone number the hashed password this is what the hash looks like so we don't want to share a plain text password and then finally here is the name and the full name and the image everything is here the user has been created which means that our sign up works now let's try to log out and let's try to see if the sign in works but you might have a question how do we actually log out well we have a button here but right now it's not doing anything so let's make it do something to do that i'm first going to close all the files and collapse the files and folders go to client source components and then that's going to be channel list container more specifically we should be looking at the sidebar so i'm going to go to the top and there is our logout button what we have to do is just below create a new function const logout is equal to an arrow function and basically we want to clear the cookies and also we want to reload the window so how do we clear the cookies well let's go to the app.jsx i'm again going to copy all of these including the auth token i'll go back to the channel list container and paste them all here now we just have to do some formatting remove these previously object keys we just have the cookies dot get but now we have to switch all of these from cookies.get to cookies.remove these have to be semi-colons so let's do it like this and as you can see our cookies are not defined so at the top let's just say const cookies is equal to new cookies now below we are removing all the cookies and finally we have to call the window dot location dot reload to reload the page to get us back to the authentication page finally this logout is not being used right now so let's pass it as a prop to our sidebar and now on sidebar let's retrieve it from props right here and let's actually use it once somebody clicks on this button so i'm going to give this div an on click listener and simply call the logout function once somebody clicks on it before actually testing it out i've actually made a typo this here is remove and not removes now if you save it let's finally check it out we are back on our medical pager and let's click the log out button there we go we were logged out and we're back on the sign up screen let's go to the sign in and let's try to sign in as dr smith one more time and the sign in worked perfectly we are in great notice how we no longer have the error here it's just you have no channels because that's it we don't really have them so now let's create the rest of the screen the entire right part which is the channel container where the messages are going to be the input for sending messages gifs and everything else let's start with the channel container if you remember correctly inside of the app.jsx we have the channel list container and finally the channel container now is the time that we start working on that second piece of the puzzle so let's go inside of the channel container and let's start implementing the logic and the jsx first of all we're going to import a few things from stream these things are going to be channel and also use chat context and this is coming from stream dash chat dash react great these are all the external imports but we're also going to have quite a few internal imports meaning components that we are yet to create these components are channel inner also create channel we're going to have the edit channel and finally the theme message these things are coming from dot slash again that's our components folder so let's quickly create the layout for these four components first starting with the channel inner i'm going to create a new component channel inner dot jsx again inside of there let's run rafce and i'm simply going to put channel inner inside of it then moving on to the second thing which is the create channel component that's going to be create channel dot jsx again i'm going to copy what we had in the channel inner and simply change the naming to create channel moving on to the third thing which is the edit channel thing so right there new file edit channel dot jsx again i'm going to copy what we had in the create and paste it here rename this to edit channel and then going back one more time for our team message i'm going to create a new file called team message dot jsx and final time i'm going to copy it go to the message and rename everything to team message and don't forget we have to go to the index duplicate this four times and finally we have to add imports for all of these components so these components are going to be the ones we just created so that's going to be channel inner right here create channel as well finally edit channel and the theme message with that we've created all of the imports and i think that's going to be it for the components we might have just one or two more but we are basically done so let's see how we can use those components to create a layout in our channel container first things first we need to get the information about a specific channel we can say const that's going to be channel is equal to use chat context that's going to give us the information about the current specific channel then we need to know are we currently creating that channel then we have to show a specific message or a dashboard for creating that channel so we have to have a variable called is creating and if we are creating we want to return a specific jsx block then we're also going to have one more state which is is editing so i'm going to copy this paste it here and say is editing these are some states that we always need to be aware of we have to know this information inside of the channel container but we also have to know it inside of the channel list container for that reason we're going to declare these state fields right inside of our app and that will be the next step so right here let's create a state field called const create type set create type and that's going to be equal to use state and we're going to leave it as an empty string we also have to import use state at the top okay and i'm going to duplicate this two more times the second thing is is creating so is the user currently creating a new chat room and also set is creating and at the start it's going to be set to false then finally we have is editing and that's going to be set is editing also set to false now that we have these variables we can pass them as props to our components so we can say is creating is equal to is creating and then set is creating is equal to set is creating we also want to pass set is editing is equal to set is editing and finally is editing itself is equal to is editing you might already notice that this is not the best way to pass props a better approach in this case would be to use the context api but for now let's keep it like this i'm going to copy this and paste it right here so that we are also passing the props to our channel container our channel container is also going to need the create type is equal to create type and i've just noticed we won't need this is editing rather we will need set create type is equal to set create type like this and i just noticed i have a typo right here okay now we're good now we're accepting all of these props we can even copy them and we're accepting them inside of the channel container so we can go back and now right here in the props we can destructure them all right here of course we have to separate them by commas so let me add some commas here and again i'm going to use some keyboard magic to simply put them all in one row there we go so now we simply accepted all of the props we're passing right inside of the channel container and now based on these variables we can show is creating window is editing window or the channel container itself first let's start with is creating if the user is creating a new channel we can create a div that div is going to have a class name which is going to be equal to channel underscore underscore container and then inside of there we can simply render the create channel component it is going to be a self-closing tag and we can pass two things the create type is equal to create type and we can also pass set is creating which is going to be equal to set is creating now for the editing i'm simply going to copy this div and it's going to remain the same this is going to be channel container but instead of create channel we're going to have edit channel and instead of the create type which we don't need we're gonna be passing set is editing great so that's it right now we have no way of seeing these components because we don't have buttons to initiate the creation process or the editing process so let's keep it going with all the possible states we have just one more state and that is going to be const empty state that happens when we just create a chat and we have no messages yet so we want to display something it's going to be an instant return we are going to return a div with a class name equal to channel dash empty underscore underscore container now inside of that div we're gonna have two paragraphs first one is going to have a class name equal to channel dash empty underscore underscore first and in there we can say this is the beginning of your chat history and then i'm going to copy that the second one is going to be channel empty second and there we can say something like send messages attachments links emojis and more so this is our empty state and finally let's declare the channel container itself the div is going to have the class name equal to channel container and there we're going to render the channel component channel is not a self-closing tag we have something inside of there and that something is channel inner so this is the inner part of the chat application we have to pass a few props to our channel so let's expand it the first prop is going to be empty state indicator that empty state indicator is going to be equal to empty state and then we can define how our message is going to look like so we can say message is equal to and that's going to be a callback function where we get message props and we also get the index make sure to spell this correctly and what do we return we return our special team message that's going to have a key equal to i and we're also going to spread the props right inside of it so dot dot message props finally we just have to pass one last prop to our channel inner which is set is editing is equal to set is editing so just before we go to the browser to check it out we are going to add one more thing inside of our app.jsx if you scroll to the top just next to our app.css we are going to add one more import line more specifically import stream dash chat dash react and then we're going to take their index css for pre-built components this is going to help us to more quickly get a better looking chat application now that we're done with that let's go into our channel inner the channel inner is just a bit different from all the other components it has a lot of business logic and a lot of if statements just to check if something that we pass to the input is an attachment or a gif or a text for that reason i don't want you to spend a lot of time on doing something that's not really educational and we're simply going to copy and paste it so attach below you'll find the entire code for the channel inner as you can see right there it mostly has some overrides setting up the states using things from the channel action context and then mainly using a lot of different stream chat components let's see the jsx part and this is about it we are setting up the window the team channel header message list message input and the threads these components are not the components that we create they are here for us right out of the box when using stream chat so let's save it and let's take a look in the browser there's currently nothing here but if we go to stream chat explorer which is right here and then under users find your new user copy the id let's go under channels create a new channel and let's call it something like cardiology to keep it medical themed that's going to be a team channel type and let's click create once it's created let's go to members add new channel member and paste that id you copied let's click add and go back to medical pager if you reload the page you should be able to see that now we have the right portion of our screen cardiology three users online this is the beginning of your chat history send messages attachments links and more great so let's try sending our first message let's say hello world and there we go we can only see team message and for every message that's the only thing we'll be able to see because we haven't yet coded out the most important part and that is the actual message if you click right there on more info you'll notice that we also don't have the edit channel component so that's something we'll have to code that together as well now let's start with coding out the team message now let's remember where our theme message is it's going to be in the channel container if we scroll down you'll notice that we have our custom team message here but i've just noticed that stream chat react already has a good looking team message and we can get to it by specifying message team that component is deprecated feel free to find any other newer or rename component i really like the look of this one so we'll keep using it for this video we no longer need this theme message right here so feel free to delete it from the components folder now we can use this message theme if you scroll down and simply paste it right inside of here that's going to display all the messages that our users have sent and there we go take a look at that dr smith here is the image here is even the time stamp and here's a hello and a hello world we can try testing some new things like test and then an emoji and that is sent as well our messages are being sent we have the entire chat room here dr smith timestamps we can even add emotes to those messages as you can see right now we can even open the thread and start typing something right there in the thread as well and finally you can also delete so i deleted a test message and let's also edit hello world let's change that to hello doctor there we go so our chat just got so much better by using built-in stream chat components of course i've shown you that you can do everything yourself you can build the css the jsx everything there is but you can also pick and choose from the wide variety of stream react components let me show you what i mean going to their website we can go to chat messaging open up the docs and then under react you'll see ui components here are some of the components we've just used there's the chat channel list channel message list and everything you need to know to build your own fully custom thing if we scroll down below you'll see here the custom code examples emoji picker channel a lot of different things that you can pick and choose from so what i really liked about stream is that they offer you the api just raw data you can build everything with it but they also allow you to pick and choose from pre-built good looking components as we've done it right now great our chat just got so much better now if we click right there you can see that the edit channel and the add channel buttons have not been yet created so let's first add a button to create a channel and then the entire dashboard view to create name channels invite different people into it and then we'll be able to browse through a lot of different channels that our users will be able to create let's do that right away we can add the button to add a new channel by going to client source components and then that's going to be channel list or team channel list if we scroll down you'll see that we're currently displaying the text of channels if the type is steam or direct messages if the type is not team we can even see that in the code right now we have a channels header and a direct messages header but now we have to add a plus icon right here if we want to create a new channel or a new direct message we even left it to do right here button add channel so as you can see at the top we are already importing an icon from assets called add channel and that is a simple svg but on that svg i've already added the onclick property and that's simply going to set the state of create type to type meaning either a direct message or a team chat and it's going to trigger the set is creating to be true that way our new window for the channel creation is going to open so what we can do is simply call the add channel component currently we don't have access to the props that we have to pass to the add channel even the team channel list doesn't have them so let's see where the team channel list is getting called we can just search it like this team channel list and we can see that it's getting called into the channel list container if you remember correctly if we go back to the app we sent some props to the channel list container but we haven't yet used them so let's copy these variables go into the channel list container and now you can simply put curly braces right there to destructure the props and then paste all of the variables we're passing from app so let's take all of these variables and let's paste them right inside of our team channel list right here and under messaging as well so i'm going to paste them and now we have to say is creating if we copy it and is equal to is creating then set is creating also is equal to set is creating one more set create type is equal to set create type and finally set is editing is equal to set is editing great now we're passing all of the necessary props to our team channel list both for messaging which is a chat for two people and then also in the team chat which is for chat of three or more people great let's save it and now we can have access to these same props right inside of the team channel list so one more time i'm going to copy these go into the team channel list and now we have access to them right inside of here the way we're doing it right now is not ideal we had to pass these props from app to the channel list container and then one more time to the team channel list a preferred way would be to switch it to a context api and if this video doesn't end up lasting too long we're going to make that switch at the end if not please let me know in the comments if you'd like a special video or a project only focusing on the context api with that said let's go to our team channel list and now we can make use of these variables more specifically we can simply pass them into the add channel so i'm going to go back to the channel list container and right inside of here i'm going to copy these four values we can simply paste them right there and indent this properly the last thing that we have to pass is the type variable we're going to make a check to see if type is equal to team in that case we're simply going to have a string of team else we're going to have a string of messaging with this done our ad channel is successfully going to trigger the set is creating state now let's check it out and see if we can actually see the add channel button back on the application you can see that we have two clickable buttons let's try to create a new channel once i click here you can see that we have a blank create channel component this basically means that we've already created the create channel component but we haven't implemented the logic so let's do that right now let's move into the create channel component right here and as you can see right now we don't have anything so what we can do is we can first import use chat context which is going to be coming from stream chat react then we are also going to import a new component called user list that's going to be user list and that will be coming from that slash meaning that is a component that we are yet to create and we need one more thing from the assets and that's going to be close create channel icon and that's going to be coming from dot slash assets great now let's create the layout first let's create the channel name input that's going to be a component above our current functional component called channel name input and that component is going to accept a few props it's going to accept a channel name prop which we're going to give the default value to be equal to an empty string and also set channel name this is going to be a function so we can have a return there and inside of there we can return the jsx more specifically we are going to have one div that div is going to have a class name equal to channel dash name dash input underscore underscore wrapper inside of there we're going to have one b tag and that b tag is simply going to say name then we're going to have an input tag and that input is of course going to have a value and it's also going to have the on change property right now we're going to leave them blank and finally it's going to have a placeholder which is going to be equal to channel name and i'm going to put no spaces here because we have to create a channel name with no spaces in between and we're also going to have one more p tag which is going to say add members let's quickly create a value and an on change for this and let's change the typo to on change so what we can do is say const handle change is going to be equal to a function where we get the event and then in there we can say event dot prevent default we discussed a few times what that does that prevents the browser reload and finally we're going to use the event target value to populate the channel name so on change we can call the handle change and the actual value is going to be channel name okay now let's use that inside of our component just to see how it looks like so it's going to be channel name like this i'm going to save it and if you click a plus here you can see we have name and then channel name looks like our no spaces is not fitting here so i'm just going to remove it from the placeholder okay let's remove it from here and for now we're going to comment out this component or you know what let's completely remove it because we have to add some other layout details first of all we're going to have a div that's going to have a class name equal to create dash channel underscore underscore container inside of that div we're going to have one more div which is going to have a class name equal to create dash channel underscore underscore header and in there we can check if we're currently on the team chat or messaging chat so we can say if create type is equal to team in that case we can simply say something like create a new channel or otherwise we're going to simply say send a direct message great and this create type is coming as a prop to our create channel component so let's see if we're passing that value correctly one trick that you can do is go to search and then open the opening component bracket and then the name of the component that way you'll be able to see where you're calling the current component you're working on if we go there you can see that indeed we are passing two different props that we can use so we can go back and use these props create type and set is creating so right here the structure the props create type and set is creating great now below that p tag we are also going to have a close create channel icon and we're simply going to pass set is creating straight to it just so we can reset it to not creating below that div we're going to have one more logical block and we can say if create type is equal to team then and only then we can show the channel name input that is this component we just created so we're going to call it as a self-closing tag and remember we have to pass two props to it which is the channel name and set channel name so right there i'm going to pass the channel name and also the set channel name to be equal to set channel name but as you can see right now we don't have access to those values and usually whenever you have a pair of something and set something that's going to be a state variable so just at the top of our create channel we can create a new use state like this and it's going to be channel name set channel name and at the start it's going to be set to an empty string we also need to import use state from react at the top just like this great now let's save it and see how it looks like now if we click channels add we have create a new channel and then we can enter the channel name and also add members but if we go to direct messages right here send a direct message we don't have that naming of the channel because it's just going to be a direct message as we discussed previously the user list component doesn't exist yet if we go to client source components there is not a user list component so let's create it right now components new file user list dot jsx our user list is going to be a longer component we're going to have a few functional components inside of here so let's start at the top import react and we're also going to need use effect and also use state hooks and that is coming from react then we're going to need the avatar component and also use chat channel and this is coming from stream chat react finally we're going to need import invite icon and that is coming from that slash assets great so let's create our primary functional component which is going to be const user list and that's going to look like this we are of course going to have a return and there we can return a div that's simply going to say user list of course we have to switch this as well and we're going to do export default user list great now we have everything ready we have to go into our index.js and export that component from there and finally back in the create channel we should be able to see our user list there we go user list is showing up right here both on channels and on the direct messages as well now considering that we'll be making a lot of changes to our code for the user list i'm going to pull my browser to the right side and go to the left so you can see in real time what's happening okay let's go back to the user list and there we are so what we can first do is to create one more helper functional component which is going to be called const list container and that's going to be a react functional component all react functional components have access to a specific prop called children so whatever components you render inside of this that's going to be populated into the children prop in this case we can say return and we're going to have a div that div is going to have a class name equal to user dash list underscore underscore container and we're going to have one more div inside of it that div is going to have a class name equal to user dash list underscore underscore header and inside of there we can simply have two paragraphs the first one is going to say user and the second one is going to say invite finally below that we want to render the children i'm going to save that and finally we can now use that list container inside of our user list so right here instead of the div we're simply going to use the list container as you can see it added the headers for the user and the invite but the user list still remain there because we are rendering it as children below the user and the invite now we can start creating the second helper functional component which is going to be called const user item and that user item is again going to be a functional component but it's going to be a bit more complicated let's first create the return jsx right here so we want to have a div and that div is going to have a class name equal to user dash item underscore underscore wrapper inside of this div we want to create one more div and this one is going to have a class name equal to user dash item underscore underscore name dash wrapper inside of there we can show the user's avatar so we can say avatar that is going to be a self-closing tag and we want to get access to the current user that we are mapping over right now we don't have access to that so let's see how we can get all of the users into our list container and therefore into the individual user items to get the users we'll have to go inside of the user list and we'll have to create a new state const users and also set users and the default value is going to be equal to an empty array then we have to create a use effect hook which we're going to call when something changes more specifically we want to call it once filters change because sometimes we want the users for direct messages and sometimes when filters change we want users only for channel messages so instead of this use effect we can create a new function const get users and that is going to be an async function and in there we're going to of course get the users so first we're going to check if we're currently loading something and in that case we're going to go outside of the function we don't want to get users if we're loading something and that loading is going to be a state field so we can say use state autofill it and then there we can say loading and set loading at the start that's going to be set to false if we're not loading something we can set that loading to be equal to true because we're starting to get users we want to enable our loading below that i'm going to create a try and catch block in there we want to query the users and we are going to query the users from the use chat channel context more specifically above our use states we are going to get the client so const in curly braces client and that is going to be equal to use chat channel but i've just noticed that this is not supposed to be channel it's supposed to be context whenever you have a form like this get something from use something that means that it's a context or a hook so let's copy this and instead of use chat channel let's import use chat context so from here we're getting a client but what are we going to do with that well down below we can say const response is equal to await client dot query users so this is going to allow us to query all the users based on specific parameters and we can specify parameters like this in the first object we're going to have the id equal to and then we want to have one more object and then say dollar sign n e not equal to client dot user id so basically we are excluding the queering of users for the user with the current id we don't want to find ourselves there because we are the people adding different users to the channel okay looks like that i saved my file for the first time in quite a while and i've noticed that we haven't declared our filters yet i've just noticed that we don't even need these filters yet because we'll be filtering based on the fact are we currently on the direct messages or on the channels we don't need any specific filters for that and then we can pass some additional information to our query users object if you hover over it you'll be able to see that we have the sort options to sort by specific variable and also the options object so the second object will pass here is going to be id is equal to one this is just the way we want to sort specific things here is the explanation then the third thing are going to be the options and in the options we're going to provide our limit so let's say that we want to limit only to the eight users great that's about it for our response i have to rename it because it had a typo now let's see if we actually have anything in the response i'll say if response.users.length in that case we simply want to set the users to be equal to response.users else we're going to have a special state field called is list empty or just list empty so let's create it use state list empty and set list empty at the start that's going to be set to false so if we don't have users we can simply call the set list empty and set it to true finally if there was a problem while catching the users we can simply console log the error and after this whole part is done we can finally set the loading back to false great now we've created the function to get the users now let's actually call it if there is a client means if we are connected only then do we want to call getusers function let's do it save it and see if we're expecting something well with that we're simply populating the users but we're not using the variable yet so we want to map over the users and for each user we want to show a user item let's do just that right inside of our list container we're going to have a loading property and if we're currently loading in that case we want to show a div which is going to have a class name which is going to be equal to user dash list underscore underscore message and that div is simply going to say loading users dot dot so we can put that here in new pair of parentheses with a column if we're not loading we want to see if we have the users so we can say if users question mark dot length and finally we want to say users question mark dot map we're mapping over the users in here we have a callback function and for each user we want to render the user item component that's the component we created right here at the top of course we want to pass some things to it so we're first going to provide an index which is going to be equal to i we also want to provide a key which is going to be equal to user dot id and finally we want to provide the user property which is going to be equal to the user we're mapping over now back in the user item through the props we can access the user object and now we can get his name avatar and everything else so the avatar component has the image property and that is going to be equal to user dot image it also accepts a name property which is going to be equal to user dot full name or user dot id and also you can set the size equal to the number of 32. let's save it if we hover over it you'll see that this is the javascript mastery user so far we don't have a lot of users we are currently logged in as dr smith so that's why we cannot see ourselves but if i remove this part here you're going to notice that we're going to have two users dr smith and javascript mastery but dr smith is ourselves and we cannot invite ourselves to the chat we are creating so that's why we're saying if our id is not equal to the current id of the user there we go we disappear from the list and now alongside avatar let's add a name for that user we can do that by adding a paragraph tag and now let's add a name for the person we're inviting we can add a paragraph set the class name to be equal to user dash item underscore underscore name and then inside of here we can simply render user dot full name or user dot id that means if for whatever reason we don't have access to the full name we can simply show the user id let's save it and as you can see this is javascript mastery now let's add icons to keep track of if we're inviting the person or not we can add an icon by simply putting invite icon svg right here and saving it as you can see this is a filled check mark but we can also have a self-closing div and then inside of there we can add a class name equal to user dash item underscore underscore invite dash empty if we do that you'll notice that we have an empty checkbox so now we have to be able to toggle between them and we can do that by creating a new use state field so we can say use state and we can call it selected so selected set selected and the initial state is going to be false based on that we can make use of that like this if selected then we show the invite icon else we show the empty div so let's save it and as you can see right now we have just the empty div which is like an empty circle so now how can we toggle between those well we're going to add the on click property straight to this div and what we can do on click is simply handle select we're going to create that handle select function right here const handle select inside of there we can simply set selected inside of there we get a callback function with the previous selected so we can say prev selected and then we can simply return not prev selected this is how you do it in react when you want to modify something by the previous value and now if you see that we can click and toggle the users on and off but the problem happens if you want to invite more users if we had a second user right there then you wouldn't be able to toggle on and off both of them we have to keep track of which ones are toggled on and which ones are not to do that we can go back to our create channel and then right inside of here we are going to create a new use state field use state and in here we can call it something like selected users then we're going to have set selected users and at the start we only want to input our own id because we always want to be in the chat that we are creating so how can we get to our id well we can do that by using the use chat context so we can say const client and also we're going to need set active channel that's coming from use chat context and we call it as a hook of course there's the equal sign in between and now we have the client and we can simply get the user id right here at the first element in the array by saying client dot user id id all uppercase or if there isn't one we can simply say or empty string so what we've done is we've just created the selected users field and immediately added ourselves to that group okay now that we have the selected and the set selected users right here what we need to pass into the user list is going to be the set selected users variable set selected users is equal to set selected users we can go to our user list and then right inside of here inside of our user item we want to pass that over one more time set selected users right now it's undefined so right here inside of the user list we need to get that set selected users great now we have access to the set selected users right here inside of the user item so what we want to do is we first want to check if the user has been selected so we can say if selected in that case we want to set selected users to be equal to then we're going to have a callback function and in here we get prev users so what we can say is prev users dot filter we get that prev user and then we want to filter the prev user that doesn't have an id equal to to the user dot id so basically we are keeping all of the selected users so far but removing the one that we've clicked right now so if we had two more of these and if we clicked all of them and then click the third one we would just remove the selected user from the third one and keep it on the first two ones i know it's a bit confusing but i hope it makes just a bit of sense and then we're gonna have else and then all else we want to do set selected users we are again going to get prevusers as a callback function let's make sure to close it properly and in this case we want to add a user so we can create an array where we spread all the previous users and finally append our current user id to it right here it should have been prev users and not user so the above part is just filtering out the currently clicked item if it was clicked but this line is adding one more selected user as you can see we are spreading over all of the previous users plus adding the one we just clicked great so that part with the user item is now done the final thing we can do is some slight error handling and handling the situations where we have no users so what we can do is add one more use state field there we're going to say error and set error at the start that's going to be set to false so let's set it to false right there and right here instead of cons a log in the error we're simply going to say set error and we'll just say true now based on these conditions instead of rendering the list container if we have an error we don't want to render that so what are these conditions going to be so we're going to write if there is an error in that case we want to return some jsx more specifically a div really similar to this one it's going to be a div a user message but instead of loading users we're going to say error loading please refresh and try again but make sure that that is inside of the list container so i wrap that inside of the list container and it's going to be just like this in this case we cannot see that arrow because we have users but if we didn't have any or if there were some connection issues then we would see that error and one more thing is we're going to copy this entire if statement and just change the error part to be equal to list empty so if our list is empty in that case we simply want to say no users found great we have the loading states we have the no user state error state and if everything works out we are displaying our users and we can toggle the user invite on or off that was it for our user list it was such a long component but now we can go back to our create channel we can remember what we had the name add members there is the name and there is the add members and finally we can add a button to make an invite of the user to our channel to create a channel we just need to add one more div below the user list and that's going to be a div with the class name equal to create dash channel underscore underscore button dash wrapper inside of that div we're going to have a p tag and that p tag is going to check on what is the create type and if it's currently team in that case we want to say create channel otherwise we want to say create message group great let's save it and check it out as you can see there is our button at the bottom and now we just have to add the on click property to this div so on click let's do something like a create channel function just below these use states we're going to create a const create channel function it's going to be an async function and we are going to get the event as the first parameter inside of there we can first say event or e dot prevent default not to do a browser reload and then finally we'll have to create a new channel we can do that by first opening a try and catch block to make sure nothing goes wrong and this is how we create a new channel const new channel is going to be equal to await client dot channel and that's going to be the function that's going to create a channel we have to pass a few options into it first of all we have to pass the create type is it a messaging channel is it a theme channel then we have to pass a channel name and finally we have to pass an object that's going to contain the name as the channel name and also the members and this is the most important part as members we're going to add our own selected users great once we finally created the channel we can just say await new channel dot watch we want to keep watching that channel we want to see whenever there's a new message in that channel and finally once the channel is created let's do a clean up first we're going to reset that field if we go here you can see there is a field with the channel name so let's reset that that's going to be set channel name equal to an empty string then we're gonna set is creating to be false because we're no longer creating a channel we just created one then we're going to reset the set selected users so we can say set selected users and we're going to reset that back to an array containing only us one more time so client dot user id we always want to be there in the channels we create and then finally we're going to switch that channel by saying set active channel is going to be equal to to the new channel and finally if we have an error we simply want to do console.log right there console.log error great this is going to be it for the entire channel creation process now we should be able to finally see what channels and direct messages we have right here on our lists so let's go under new channel so right now i'm going to maximize this window we are going to go under channels i'm going to name the channel something like doctors meeting and let's invite javascript mastery let's create a new channel and there we go we are in let's send a first message something like hello and as you can see dr smith the message is there unfortunately the channel didn't seem to appear on the left side so we need to see what's up with that also if we go here under edit you can see that we still haven't implemented the edit feature now let's reload and unfortunately yeah there still is not a doctor's meeting channel on the left side if we tried searching still nothing happened so these are the things that we have to fix to make this work fully the channel was indeed created and we can verify that in the getstream dashboard but we still cannot see it on the left side so let's fix that right away to make our channels and direct messages appear we can go back to our channel list container inside of here if we scroll down we left our filters to be empty so we are not filtering any data we're not trying to look for any channels so let's fix that right away so first in here we have the sidebar then we have the company header after that let's create some filters so right here i'm going to say const custom channel team filter and that's going to be a function and as a parameter we're going to get a list of all the channels there we can return channels dot filter so we want to filter out the channels and we get each specific channel and which ones do we want to leave out well we want to keep only the ones where the channel dot type is triple equal to team because this is our team filter now we're going to copy that same function and we're going to call this one custom channel not theme but rather messaging filter and we're going to set the channel type to messaging great now where can we use those filters that's going to be here in channel render filter function in here we can simply say custom channel theme filter and for the second channel list right here we are simply going to paste custom channel theme filter but this time it's going to be messaging okay now that we have the channel render filters before we fill in the other types of filters we need to do some quick renaming i've made a mistake when calling this component the channel list container this one should be called the channel list content so this is just the content for our container and then the actual component is going to be below and we can create it right here that is going to be const channel list container that's going to be a functional component and inside of there we can of course do some logic these props are going to be in curly braces set create type also set is creating and finally set is editing great now we're passing these three props and we're going to have just one more state value this channel list container is going to give us the logic for that sweet animation you saw for mobile devices so we need to be able to toggle the container based on the width of the screen so let's create a use state field and let's call it toggle great we have to import the use state at the top so right here we're going to import use state and let's scroll down the initial state for the set toggle container is going to be set to false also make sure to put a capital t right there so what jsx are we going to return from here inside of the return we are going to return a react fragment inside of that fragment we can return a div and this div is going to have a class name equal to channel dash list underscore underscore container and inside of there we can render our channel list content of course we were using some props in our channel list content as you can see right there so we have to make sure to pass all of the props from our channel list container to the channel list content of course we have to space everything out properly and then set the equal values to be equal to the names themselves we can do that by using some shortcut magic there we go and we can do the same thing for set is editing there we go the only thing we don't have to pass here is the is creating property we need just these three great now below this div we are going to have one more div and this div is going to have a class name equal to channel dash list underscore underscore container dash responsive so this one is only going to be visible when we are on mobile devices so we are going to give it some inline styles more specifically style is equal to left toggle container and that is going to be either zero percent so let's put that here zero percent or that's going to be something like let me put it like this something like minus 89 i found this value to work the best basically it's going to pull from the left side to the right and it's going to have 11 percent of the width finally we need to give it a background color so we can say background is equal to and that's going to be hexadecimal string 0 0 5 f f f great now we have everything it is complaining about the toggle container variable because i have this column here we don't need that with that we created our div and we need to have one more div inside of it so we can create the final div here this div is going to have a class name equal to channel dash list underscore underscore container dash toggle and it's also going to have the on click property on click we are going to simply call a function set toggle container and we want to toggle it off so as we discussed we are going to get the toggle container and we're simply going to return not prev toggle container that's how we toggle values in react state and finally below this div we just created we're going to add our channel list content we can basically copy what we had here so this same thing let's simply copy and paste it here and we're going to add one more prop to it this time that's going to be the set toggle container is equal to set toggle container so why do we have two different divs with two of the same components this one is for the desktop version and this one is happening on mobile great so now we have two different versions the channel list content and the same channel list content but the one for the responsive version where we're passing the set toggle container we are going to use that in just a moment but for now let's finish these filters right here and here so that we can actually see the channels in action so to get these channels we're going to get something from the use context so right here at the top of the channel list content i'm going to say const lowercase and we want to get the client object that's going to be equal to use chat context so once we get this client then we can create the filters object and we can say const filters is equal to an object and then in there we can say members colon that's going to be an object and we want to say dollar sign in that means included and there we can simply say client dot user id so that means that we want to get all of the channels and direct messages where our user is included great now we can copy that variable and paste it right here instead of this empty object and right there in the channel list as well now let's save it and check it out and as you can see the cardiology we previously created that was the demo chat and the doctors meeting channels are now here we cannot yet switch between those but we're going to implement that soon but for now we are at least seeing them on the left side we don't yet have any direct messages but let's try to create some let's try to invite javascript mastery create message group and let's say hello there we go something happened but it doesn't look like a real direct message yet we'll have to look into this component and see if we've created everything correctly for the direct message output with that said let's finish the left side with the mobile toggle for the responsive view so we can do that considering that we are now passing this set toggle container variable to the channel list so if we scroll a bit up you'll see that there is our channel list content and then in there we can simply get the set toggle container now we can pass that variable deeper into the team channel list right here and we need to pass it in a few more places like into the theme channel preview and we have to copy the same procedure right here as well for the team channel list and theme channel preview down below now that we are passing those values to the team channel list and the theme channel preview let's see where we have to pass them to make it work so right here at the top we can get one more prop which is going to be called set toggle container now that we're passing the set toggle container we can go inside of the theme channel list and team channel preview to see where we need to use them first of all we can accept them here as a prop at the top and then right here we can pass it over to the add channel by simply doing set toggle container is equal to set toggle container now if we go back to the channel list container we can go to the preview team channel preview we are passing it going there we can also get it right here from the props and in this case we'll have to do something on click and as you can see this is another feature we are yet to implement clicking on a specific channel to open the messages for that channel so while we're here let's make that work right away to make that work we also have to make use of all of the other props we are passing into this and right now we are not passing any so what do we need to pass well that is going to be the same once we're passing here set is creating set is editing and that's going to be it so i'm going to copy these two and simply paste them here set is creating and set is editing now we can go back to the theme channel preview get the set is creating and also set is editing and finally we can use those value to preview a channel so we need to call set is creating and set that to false because we are no longer creating a channel we want to see the messages for a specific channel then if we're currently editing we don't want to do that anymore we want to see a specific channel and then finally we want to see if the set toggle container exists so set toggle container and if it does we want to call it as a function set toggle container remember we are going to get a previous state and we can simply do not previous state so we are doing this if because on our desktop devices we won't have this set toggle container but on mobile we will so we want to toggle it on and off and then finally we have to set the active channel and we can get the value for that right here from the props set active channel and we simply need to call it right there set active channel and we pass in the channel variable this should allow us to switch between the channels before we go ahead and check it out let's first go to the channel list container and make sure that we have these props right there also in the upper preview because they should be the same so right here i'm going to copy these that's going to be set is creating set is editing and set toggle container and paste them right here these have to be the same now let's save it and take a look in the browser now we're currently on the direct message with javascript mastery but if i switch to cardiology you can see we successfully switched to another channel we can also go to the doctor's meeting and damn is it nice to see how everything is working well we have doctors meeting cardiology and then we have direct messages now that we can create new channels also create new messages and switch between the channels let's see what's happening with the styles of our direct messages and then we're going to implement the edit channel functionality it won't be that hard as you can see most of the logic for everything has already been done so let's keep it going to figure out what's happening with our direct channel preview we can go into team channel preview and then right in here this is the channel preview for the channels and this is the preview for direct messages so in here we're looping over the members and then we're showing the image and the full name for the member but for some reason this is not getting displayed so let's simply console.log members 0 right here so that's going to be members 0. let's see how our user looks like so if we open up the console we can inspect and right here we can have two different objects and this is going to be the javascript mastery user javascript mastery is going to be the only account ever on this platform that we haven't created ourselves all the other accounts are going to be created using the sign up and the sign in form but this is the default stream account and unfortunately this one doesn't have the full name property so what we can do to fix this is we can simply right here say or members 0 and then we can use the id so that's going to be question mark dot user question mark dot and that's going to be id so we either show the full name or we show the id and if we go back take a look at that we have a little j thing there and javascript mastery but now let's actually test this out with a real user of course right now we're logged in as dr smith but we need another user to be able to chat with him so let's log out and create one more account i'm going to close this click log out and right now let's create another doctor let's do something like dr miller dr miller as well phone number is not important for now we can enter the same avatar url and the password can be something simple let's click sign up as you can see there are no channels yet but let's create a direct message with dr smith i'm gonna click create message group and there we go we only have an id unfortunately there doesn't seem to be a full name so let's open up the stream dashboard and see what's happening if you go to the dashboard.get you are going to be on your app overview but we can go to the app explorer right here you should be able to see all the users and let's check it out there is our dr miller looks like that he has his username here and here's our dr smith the full name is there as well but let me show you something once we actually log out and try to log in one more time as dr miller and then i'm going to enter the password log in as you can see nothing is there same thing as before but now if i go here and i visit dr miller the full name is actually going to be empty why was this string cleared well let's check it out so what's happening is that we have a small mistake in the auth component when we log in we're filling in these values the username full name user id and token but think about it if the user is logging in he won't have to type in his full name therefore it's going to remain as an empty string so instead of getting the full name here what we can do is just get it from the data that's returned back from the database so here we can get the full name but then on the sign up when we're sending the data to the database here it has to be form dot full name so this is the data from our input only on the sign up great that part is now fixed so let's try to create a new user and test it out i'm going to log out let's try to sign up as dr james that's going to be dr james we can use the same avatar and password and i'm just going to click sign up now that the dr james was created and we sent a message to dr smith let's try to log in as dr smith and see if the issue has been resolved so i'm going to log out and sign in as dr smith there we go our issue was fixed because we can now see dr james right there to test it out properly let's log out one more time and log in as dr james so that's going to be dr james and there we go now we can see dr smith once again that's great i'm going to log out and finally one more time bear with me to test this out properly we're going to log in as dr smith and then i'll see how it looks like there we go dr james is still there we can ignore this person right there or as a matter of fact i'm going to delete everybody who's not dr smith and dr james because we had an issue that caused their data to be corrupted so i'm going to hard delete this user right there and from now on we shouldn't have absolutely any problems while we're there let's also delete all of the channels that we have i've deleted all of the channels besides the ones that have proper names so now if we go here you can see that we can switch between the channels and let's try out the direct messages i can try to message dr james and say something like hello and there we go dr smith said hello to dr james that's great that means that our direct messages our channels switching between the channels everything seems to be working great one thing that we still have to do is fix the edit channel functionality so if we want to go to cardiology and add a new user we need to be able to do that right now our edit channel is empty so let's do that and then we're getting close to the end where we're going to implement sms notifications using twilio so let's keep it going let's close all of our files and folders to have a clean working environment and let's go to client source components and then finally edit channel this is the component we need to focus on right now inside of the edit channel we're going to import react as well as the use state then we're also going to import the use chat context that is coming from stream chat react we are also going to need one more component and it's the one we already coded out it is going to be the user list remember we use the user list to create a new channel and we'll say from that's going to be dot slash and finally we're going to need one more thing from the assets and that's going to be close create channel that's going to be coming from dot slash assets the first thing we're going to add in here is going to be a channel name input component and if you remember correctly we already created something like that so we can go to create channel component and simply copy the channel name input go back to edit and paste it at the top we are going to reuse this component now let's start with working on the edit channel our edit channel is going to have a div that's going to have the class name equal to edit dash channel underscore underscore container and inside of there we are going to have one more div and this div is going to have a class name equal to edit dash channel underscore underscore header inside of that div we can put a paragraph so let's put a p tag and we can simply say edit channel now let's also put a close icon so we can say close create channel icon and in there we have to pass the set is editing prop as set is editing this prop we are receiving from the props at the top so we can simply destructure it from the props right here now below this div we are going to call the component we created above which is the channel name input so that's going to be channel name input a self-closing component and we have to pass in the channel name as channel name and we also have to pass the set channel name as set channel name so you might be wondering where are we getting these values from well we can get the channel name from the chat context so we can say cons in curly braces channel and that's going to be equal to use chat context then for the channel name or set channel name we can create a use state field so right here we can say use state channel name also set channel name and the default value is going to be equal to channel question mark dot data question mark dot name so if there is already a channel name we'll try to get it from the channel i've noticed that i've misspelled the name here that's going to be channel name and now we have both the channel name and the set channel name the last thing we have to do is render out the user list so right here we can say user list it is a self-closing component and in there we can simply pass set selected users is equal to set selected users and again selected users and the set selected users are state fields which we don't have already so let's create a new use state field and we're going to create our selected users and also set selected users with the default value equal to an empty array great now we have the header channel name input and the user list let's just add a button to save the changes and we are almost done so it's going to be a div with a class name equal to edit dash channel underscore underscore button dash wrapper and inside of there we can simply say something like ap tag that's going to say save changes let's save it and see how does it look like if we go back you can see this looks similar to what we had with the creation of the channels because we are using most of the same components so now if we switched to the doctor's meeting you can see we can invite new users direct messages don't have the added channel because they are not channels but cardiology and doctors meeting have them and we can invite new users or simply change the name great finally the button doesn't do anything yet so let's go ahead and create a function that's going to save the changes we are going to add the on click on this button or a div and on click we simply want to call the update channel function we can declare it right here const update channel and that is going to be an async function inside of there we are going to get the event and as always let's call the event dot prevent default now let's see if the user has changed the name we can say const name changed and that's going to be equal to if channel name is not equal to in parentheses channel dot data dot name or channel dot data dot id that means that the name has been changed so if name has been changed inside of the if we can simply say await channel dot update and then inside of there we can pass an object with what we want to update and the thing we want to update is going to be the name to channel name we can also set the text for the update so in a new object as a second parameter we're going to say text is equal to a template string channel name changed to and then in here we can say simply channel name great finally if the name hasn't changed but if the number of users has changed so if selected user is that length meaning if we added some new users in that case we want to await channel dot add members and simply pass in the selected users that is going to be it and once we're done we have to set channel name back to now we also have to set is editing back to false because we're done with the editing and finally we have to set selected users to be equal to an empty array and with that we are done with the edit functionality let's go ahead and try it out let's try to go to the doctor's meeting and let's try to change it to something like emergency and i'll also try to add dr james i'm gonna click save changes and there we go channel name changed to emergency at friday at 6 pm great that means that this part works perfectly as you can see our application is getting better and better and it seems like we have a fully working chat by now i know this was a long video so if you're still here and watching definitely make sure to leave a like and comment down below with that said let's check if our search is working so i'll try to search for dr james but unfortunately nothing seems to be coming up let's see what's happening with our search we can look into our search by going to the channel search component and would you look at that we even left ourselves a to-do right inside of here so in the channel search let's make it work what we have to do is we have to use this chat context to get the information about the active channel so right there we can say const and then the structure the values client and also set active channel and this is coming from equal to use chat context great we also have the query and the loading but we're going to add a few more use states that we are going to need for example i'm going to write use state and we are going to need team channels we need to know which are the currently active team channels and at the start that's going to be set to an empty array then i'm going to duplicate that and then we're also going to add direct channels and set direct channels we need to know which are the currently active direct channels also at the start equal to an empty array now that we have all of these used state fields let's make our get channels function work so inside of the try block let's query our channels we can do that by saying const channel response is going to be equal to client dot query channels and then inside of there we need to pass some options the first thing we have to specify is the type which is going to be equal to team then just next to that we can specify a name which has to be equal to dollar sign auto complete is equal to text so we want to autocomplete all the usernames and then finally the third thing next to the name is going to be members and for members we can say dollar sign dollar in is equal to an array where we have the client dot user id make sure that the user is lowercased and the id all uppercased let's space this in a few rows and this is how it looks like query channels type is theme name is autocompletetext and members includes our own user id now let's also query the users we can do that by saying const user response is equal to client dot query users and it's the same situation we have an object where we pass some information so first we can say id is equal to and then an object and then dollar sign and e this is going to make sure that we exclude our current user id we don't want to find ourselves on the search but rather next to it we can say name is equal to and we can copy this autocomplete text so we want to get all the other names there we go now we have the user response and we also have channel response and let's see what we can do with that we want to put that into a promised at all because we want to start fetching them at the same time so what we can do is say const and then square brackets inside of here we are going to have channels and also in curly braces users so we want to get the channels and the users at the same time and we can do that by saying equal await promise dot all and then inside of there inside of an array we want to get the channel response and also the user response so this is an interesting way we did this we could have just put the await in front of this one and in front of this one but that way if we make a request we'll have to wait for this one to be done and then only start this one once this is done but this way we'll be starting both of these requests at the same time they will be happening simultaneously so that's going to make it quicker so finally let's see if we have any channels that length meaning if the channels exist in that case we want to set team channels to be equal to channels we'll do a similar thing for the users and say if user is that length then we want to set direct channels equal to users if you think about it a direct channel is nothing more than a user great this is our get channels function completely done finally we have to make use of it so just below this input we are going to create last component of our entire project at least i think so so right here we want to open a dynamic code block and we want to specify if the query exists so if the query exists meaning our search term in that case we want to do something like this we want to render a component called results drop down a drop down that's going to contain the information about all the channels and users of course we'll have to pass a lot of information into this component we have to pass things like team channels is equal to of course steam channels then we have to do the same thing for direct channels also we have to pass the loading property so that we know if we're loading also the set channel property equal to set channel and also set query which is going to be equal to set query of course and finally we'll also have to pass set toggle container is equal to set toggle container now let's see which one of these we don't have currently access to and these are going to be set channel set channel is going to be a function that we can create right here const set channel is equal to a function that accepts a channel and in there we simply want to reset the query so once we set the channel we want to set the query to be equal to an empty string and then finally we also want to set the active channel to be that specific channel now let's see where is the set toggle container coming from that should be coming from props so let's see if we're passing that into our channel search let's check if we're passing that value through props so i'm going to go to the search open the opening component bracket and look for channel search and it looks like we're not passing any data so let's scroll up we have the set toggle container here and we're simply going to pass it through props right inside of there now if we go back to the channel search we can get that variable right inside of here but make sure to put it in curly braces so that it means that it's destructured from props great that means that now we have almost everything if not everything for our new results drop down component before we go ahead and code it out there's one more thing we have to add to this file and that is going to be the use effect we can create that use effect right here at the top use effect make sure to add a dependency array in there so just at the end we need a dependency array and we want to call the function every time that the query changes so if the query changes and if there is no query in that case we need to clear the theme channels and the rack channels so what we can say is set theme channels to be equal to an empty array and also set direct channels to be an empty array as well great now we are ready to code out the results drop down component let's go ahead in the components folder create a new file called results dropdown dot jsx and then in the index we can simply use it right here results drop down now let's go to our results drop down the situation with our results drop down is going to be incredibly similar to our channel inner it's going to be a component with a lot of code but not a lot of useful stuff that we can learn from so in this case it's going to be linked down in the description alongside all of the other files find the results drop down and simply copy and paste it here as you can see the result dropdown component accepts a lot of props simply does the loading or no channels and then finally it shows all of the search results it has to show them both for the theme channels and also for direct channels if we save the file go back to our channel search we need to scroll up and simply import results drop down from the components so right above our assets we can say import that's going to be results drop down and that's going to be coming from components so just dot slash great and finally let's check it out in the browser there we are we have our conversation with dr james emergency and cardiology so if i go ahead and search for doctor you can see that the dr james appears immediately and if you search for something like cardiology you can see that appears as well and also emergency so everything that you search for is going to appear here immediately right now we don't have a lot of channels but if we had more all of them would be listed right here inside of the search great we are done with the entire authentication search channels messages editing the channels and creating channels adding users reacting to messages adding threats to messages sending images gifs and anything you can think of you can make this chat completely your own but as you know on javascript mastery we always like to take it even one step further we are going to connect twilio notifications so that if a user is not online and he receives a message the notification about a new message is going to be sent straight to his phone so let's do that right away to send the sms notifications to the people using our chat we'll have to create an account with wilio so to do that head to twilio.com link is going to be down in the description and make sure to click sign up once you do that you can enter all of your information and i'll see you in the dashboard once you sign up you'll have to verify your email so let's go to our email and quickly verify it once you've verified your email in this case we'll also have to verify your phone they accept all of the countries in the world so yeah let's go ahead and type in your phone number once you've verified your phone number as well you can fill in this little questionnaire so in here we're going to use sms and we plan to build alerts and notifications how do you want to build it well of course with code so what is your preferred coding language that's going to be javascript and would you like to be able to host your code no in this case we are going to host it ourselves so let's get started with vilio and there we go at the start you're given 15 bucks for free so that you can use for your email notifications that means that you won't have to pay absolutely anything to test this out in here you have your account sid and the odd token so let's complete the steps below first you'll have to get a twilio trial phone number so let's click here they gave us a random us number so let's just click choose this number there we go we can click done and now that that is done we have our account sid and also the auth token so let's go to messaging and then finally try it out and get set up in here you can see get set up in five minutes so let's click start setup you have to enter your messaging service name i'm gonna say just medical pager and finally in here you can enter your phone number choose your sid enter the text message and in here you can see the code example of how that message will be sent we don't need to do that from their interface because we are going to take this code and do it straight from our express application so let's go back to our app and let's code it right away to implement our sms messages we'll have to go to server and then index.js inside of here we'll have to import a few things so just below this require.env we can say const account sid and we're going to get that from process.env.twilio underscore account underscore sid we don't want to simply paste it here because we need this data to be secure then we're also going to need the odd token so we can say const odd token is equal to process dot env dot twilio underscore auth underscore token and finally we can set up our twilio client by saying const twilio client is equal to require twilio and then we call it one more time pass in the account sid and the auth token great this is our twilio account which is going to allow us to make twilio requests so let's set up our process.env we have to add the twilio account sid and the twilio token so back in here just a bit below we can add these two variables and now we can copy the values from the web to do that we can go back and you can copy the account sid number straight from here let's paste it right there and then you can click show auth token right here and then you can copy and paste the auth token as well so let's paste it here great with that we are done with the initial setup now we can use this twilio client the way we're going to do this is we're going to set up one more route we are going to do this using webhooks stream is going to trigger a specific endpoint on our server and then we're going to send a message that endpoint is going to be app.post and then inside of here we can set up our route which is going to be simply slash we also get the request and the response of course inside of a callback function rec and res and we have a function right here inside of that function we are going to receive some data from stream more specifically we can say const in curly braces we are going to type in message also user colon is equal to sender we're going to get the user who's sending the message and then also the type and finally members we are getting all of this data from rec.body that's the data that stream going to put into our endpoint this part cannot be tested in the development mode we have to code it out deploy the project and then we'll be able to test it out once it's deployed so let's code it right now it's not that complicated i promise we are going to add an if statement and say if type is equal to a string of message dot new that means if the event is the creation of a new message if that is the case we want to loop over all of the members that belong to the chat the message was sent to so we can say members dot for each in there we have a callback function and for each member we want to run the following block of code we want to first extract the data from this member and we can do that by destructuring and then simply calling the user variable from that member then we can check if the user is online so we can say if not user.online we only want to send messages to the people who are not online it wouldn't make sense that people are using our chat and we also send them messages to their phone and only if they're offline only then are they going to get the message so we can run twilio client dot messages dot create that's a function that takes in an object as options inside of there we can specify the body of the message so let's do a template string that's going to say you have a new message from dollar sign curly braces message dot user dot full name and then we can put a dash and simply say again dynamic block message dot text so this is going to give them the message to their sms then we have to add a comma and specify the messaging service sid we can find this by going to twilio's dashboard right here you can see that we have a special medical pager service id so we can simply copy and paste it let's copy it and instead of simply pasting it here we're going to do the same thing with it before that's going to be const messaging service sid is equal to dot env dot twilio underscore messaging underscore service sid so let's go to our env and then inside of here we want to paste that variable and set that equal to twilio messaging service sid great now we can use that variable right inside of here and the last thing is the to property who do we want to send our message to and that is going to be user dot phone number that's the reason why we're requesting the users to enter their phone numbers at the registration process so once the message is sent we have the dot then which is going to have a callback function if the message has been sent successfully we can simply console log message sent and we have a dot catch if we have an error we can simply cancel log the error this is going to be almost it but think about it we are also a member or a user and we don't want to send the message to ourselves when we send the message via stream so just before the for each i'm going to run the dot filter method that filter accepts a callback function where we get a member and then we want to filter out ourselves so we can say if member dot user underscore id is not equal to sender dot id this is simply going to filter ourselves out and then we can send the message to everybody else finally if everything goes right we can do res dot status 200 and then dot send we can simply say something like message sent and we can also return that and down below if it's not a new message if it's another kind of event in that case we can say return rest that status 200 and we can say not a new message request it was just something different somebody else has read a message or gone online stream has events for all of these different types but we are only tracking the new message request and this is it this is the entire twilio code that you need to put there to successfully send real messages from a real phone number to real people they just make it so easy with that said let's take one last look into what we've built see if there are any other issues and if there are none we are ready to deploy this project i went ahead and did some more testing messages emojis checked threads let's check them out hello threads work as well you can reply to messages sending images check we can also send gifs and embed youtube videos everything is working perfectly with that said we are finally ready to deploy this project let's first deploy the backend of our project to heroku you can head to heroku.com and then log in or sign up if you don't have an account already when you sign up you'll be greeted with a page that looks like this in here on the top right you'll be able to click new to create a new app i'm going to type medical dash pager and i'm going to choose my region as europe finally you can click create app once that part is done you simply need to follow the instructions right here first you need to download and install the heroku cli if you haven't already you just need to click that link scroll down and download and install it for your own operating system now that you have downloaded and installed the heroku cli we can run the command heroku login back in our code we can open up our terminal and then i'm going to stop both servers from running by pressing ctrl c and then y now i'm going to delete one and clear the server okay now we are on the medical pager forward slash server so make sure that you're on the server directory we can see the one time and now if we do ls you'll see that we have client and server make sure that you cd into server because right now we are deploying the backend so now let's run heroku login and then press enter you will be prompted to log into heroku cli so click login and then you can close that page and go back to the code there we go we are logged in it might be a good idea to put the editor on the side so that we can view both the instructions and the terminal at the same time there we go we've just run heroku login and then we have to simply run git init so right here i'm going to run git init again make sure that you're in the server directory and then run heroku get remote and then a medical pager before you run git add make sure to go to your server and then right there add git ignore so right here let's add a dot git ignore file inside of here you can simply type node underscore modules this is going to make sure to ignore the node modules and they are not going to be pushed to heroku now that we've done that we can run git add and finally get commit and they say make it better we definitely will now that that is done we can simply run git push heroku master it's going to take about half a minute and your project should be up and running on the web there we go the application is live we can go back to our medical pager and simply click open app and if you see the hello world in little letters at the top left that means that we reached our endpoint on our server and if this route works all of the other ones are working as well great now we have this backend url that's your entire backend url and we need to connect that to stream and also to our front end so let's first go to our stream in here we'll have to go to chat and then overview we'll have to scroll down and we'll have to enter the url under the webhook url this is going to allow us to send sms messages great simply do it like this without the forward slash at the end and paste it finally you have to click save now let's open up our frontend code we can go to the client source and that's going to be inside of the components and then auth inside of here you can see that we have our own localhost 5000 so paste your new url right here and make sure to have the odd at the end for me that's going to be medical pager heroku app.com forward slash auth that's the new server url we want to make the requests to great we are going to deploy the frontend part using netlify we can go to login or sign up and once you're in your account you'll be able to click sites and then here you'll be able to drag and drop your build folder so how can we create a build well let's open up our terminal and this time we'll have to be in the client side so click cd dot dot to get back to the root folder and then cd client to get to our client side now that you're here simply run npm run build this is going to take about a minute and you should see a new build folder appear there we go if you can see this message that means that the project has been built successfully now you can right click the build folder and click reveal in file explorer once you do that you can simply drag and drop your build folder right here and it's going to be built right away as you can see it took seconds we can go under domain settings and then options and edit the site name in here you can do something like medical pager but of course you can do anything that you prefer in this case medical pager is taken so i'm just going to type jsm and there we go our website is now live there is our great form let's try to log in as one of the users for example dr smith i'm going to enter his username and password and click sign in and there we go we are live but this is so exciting because this is now live on the web that means that you can use this for your own purposes to create a group chat with friends colleagues or anybody else you can create entire communities of people that can chat inside of this chat create channels direct messages send gifs and do all that other good stuff of course all of this has been made possible by stream so huge thanks to stream not only for sponsoring this video but also for creating such a phenomenal piece of software that allows you to create chat applications and feeds professionally and scalably with that said that's going to be the end of this video this was quite a long one so congratulations to you for coming to the end of this video and building this project out i'm sure you've learned a lot there are many more interesting projects coming up on the js mastery pro platform so if you're looking forward to that definitely make sure to put your link into the mailing list to be sure to be notified once again thank you so much for watching stay healthy and see you in the next one [Music]
Original Description
With Direct and Group Chats, emojis & Reactions, Built-in Gif support, the ability to edit & delete messages, specialized commands, and much more, this fully responsive Medical Pager is the best Chat App that you can currently find on YouTube.
You'll also learn how to work with Stream. GetStream.io is the number one Chat Messaging platform that allows you to build scalable and custom chat applications using their APIs.
💻JS Mastery Pro - https://jsmastery.pro?discount=youtube
✅ A special YOUTUBE discount code is automatically applied!
⭐Stream - https://gstrm.io/js-mastery
📚 Materials/References:
GitHub Code (give it a star ⭐): https://github.com/adrianhajdin/project_medical_pager_chat
Styles & Other Code: https://gist.github.com/adrianhajdin/900fc7bb6cff0db26a5b6fa7106e7b17
Assets: https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/adrianhajdin/project_medical_pager_chat/tree/master/client/src/assets
📧 Join our JavaScript Mastery's Newsletter on Web Development, JavaScript & React to get exclusive programming guides, tips & tricks, and entire e-books: https://resource.jsmastery.pro/newsletter 🔥
🌎 Find Me Here:
Discord Group: https://discord.gg/n6EdbFJ
Instagram: https://instagram.com/javascriptmastery
Twitter: https://twitter.com/JS_Mastery
💼 Business Inquiries:
E-mail: javascriptmastery00@gmail.com
Time Stamps 👇
00:00:00 Intro
00:05:40 Setup
00:11:21 Initial Structure
00:50:07 Client-Side Auth
01:08:57 Server-Side Auth
01:29:32 Client-Server Communication
01:45:15 Channel Container
02:01:57 Create Channel and Sidebar
02:58:22 Edit Channel
03:06:47 Search
03:17:43 Twilio SMS Notifications
03:28:38 Deployment
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from JavaScript Mastery · JavaScript Mastery · 55 of 60
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
▶
56
57
58
59
60
Learn Async/Await in This Real World Project
JavaScript Mastery
JavaScript Exercise | Learn JavaScript with Exercism | #0 Setup
JavaScript Mastery
JavaScript ES6 for Beginners
JavaScript Mastery
ES7 and ES8 New Features
JavaScript Mastery
Learn JSON in a Real World React App
JavaScript Mastery
How to Create PDFs With Node JS and React
JavaScript Mastery
Must Have Visual Studio Code Extensions
JavaScript Mastery
Top 10 JavaScript Array Methods
JavaScript Mastery
JavaScript Map and Set Explained
JavaScript Mastery
Git Commands Tutorial for Beginners
JavaScript Mastery
Build and Deploy a YouTube Clone Application Using React
JavaScript Mastery
React Hooks - Most Used Features
JavaScript Mastery
JavaScript Best Practices and Coding Conventions - Write Clean Code
JavaScript Mastery
Build and Deploy a Realtime Chat Application - Socket.io, Node.js, and React.js
JavaScript Mastery
How to Create and Deploy a Portfolio Site in less than 30 Minutes
JavaScript Mastery
SEO for Developers | 2020 SEO Tutorial
JavaScript Mastery
Web Development Roadmap 2020 [Learning Path] - Start Coding at Home!
JavaScript Mastery
Random Quote Generator - React Fetch API Data | Build and Deploy a Real Advice App Project
JavaScript Mastery
Build a COVID-19 Tracker Application - React JS Project (Hooks, Material UI, Charts js)
JavaScript Mastery
JavaScript ES2020 - The Most Requested Feature Explained in 10 Minutes
JavaScript Mastery
Modern React Event Handling Using Hooks
JavaScript Mastery
Deno JS - Intro + Real Life Example
JavaScript Mastery
Build and Deploy a React PWA - Why Progressive Web Apps are the Future of the Web
JavaScript Mastery
Build a REST API with Node JS and Express | CRUD API Tutorial
JavaScript Mastery
Build and Deploy an ARTIFICIAL INTELLIGENCE React App | Alan AI, JavaScript
JavaScript Mastery
Master Async JavaScript using Async/Await | Quokka JS
JavaScript Mastery
Spaced Repetition in Programming | mem.dev
JavaScript Mastery
Stop Copy & Pasting Code | mem.dev
JavaScript Mastery
GitHub Profile README | Create an Amazing Profile Readme | Setup + Templates
JavaScript Mastery
NEW GitHub CLI 1.0 is here! | GitHub CLI Tutorial - Demo & Commands
JavaScript Mastery
React Custom Hooks | Learn Custom Hooks & Build a Project
JavaScript Mastery
Learn how to deploy an NPM Package
JavaScript Mastery
JavaScript Algorithms for Beginners
JavaScript Mastery
Level UP your GitHub Game - Get Hired Quickly
JavaScript Mastery
The Best Way to Host & Deploy a React Application
JavaScript Mastery
Full Stack MERN Project - Build and Deploy an App | React + Redux, Node, Express, MongoDB [Part 1/2]
JavaScript Mastery
Full Stack MERN Project - Build and Deploy an App | React + Redux, Node, Express, MongoDB [Part 2/2]
JavaScript Mastery
ECommerce Web Shop - Build & Deploy an Amazing App | React.js, Commerce.js, Stripe
JavaScript Mastery
JavaScript Crash Course 2021 - Master JavaScript in One Video!
JavaScript Mastery
MERN Auth - Login with Email (JWT) + Google OAuth Authentication | React, Node, Express, MongoDB
JavaScript Mastery
Chat Application using React JS - Build and Deploy a Chat App in 1 Hour (Microsoft Teams)
JavaScript Mastery
MUST USE Websites & Tools for Web Developers
JavaScript Mastery
Learn Material UI in One Hour - React Material UI Project Tutorial [2022]
JavaScript Mastery
Shopify ECommerce Store with React & Next JS | BuilderIO
JavaScript Mastery
React Video Chat App | WebRTC Video Chat Zoom Clone | Tabnine
JavaScript Mastery
TypeScript Crash Course 2021
JavaScript Mastery
Build and Deploy a Premium Next JS React Website | Landing Page, Business Website, Portfolio
JavaScript Mastery
Full Stack MERN Project - Pagination & Search | React + Redux, Node, Express, MongoDB
JavaScript Mastery
Build a BETTER Facebook Messenger Chat Application | React JS, Firebase, Chat Engine
JavaScript Mastery
Build and Deploy THE PERFECT Portfolio Website | Create a Portfolio from Scratch
JavaScript Mastery
Full Stack MERN Project - Implement MERN Comments | React + Redux, Node, Express, MongoDB
JavaScript Mastery
Turn an API into a Startup?! Build & Sell an API with JavaScript
JavaScript Mastery
Exclusive First Look at GitHub Copilot - All you need to know
JavaScript Mastery
Build and Deploy a Google Maps Travel Companion Application | React.js
JavaScript Mastery
Build and Deploy a Full Stack Realtime Chat Messaging App with Authentication & SMS Notifications
JavaScript Mastery
Build and Deploy a React Cryptocurrency App and Master Redux Toolkit in One Video
JavaScript Mastery
Build and Deploy a Group Video Chat Application with Messaging, Polls & More
JavaScript Mastery
Build and Deploy Google Search 2.0 with React & Tailwind CSS (simple!)
JavaScript Mastery
Top 10 Web Development Chrome Extensions You Simply Need to Try!
JavaScript Mastery
Build and Deploy THE BEST Modern Blog App with React | GraphQL, NextJS, Tailwind CSS
JavaScript Mastery
Related Reads
Chapters (12)
Intro
5:40
Setup
11:21
Initial Structure
50:07
Client-Side Auth
1:08:57
Server-Side Auth
1:29:32
Client-Server Communication
1:45:15
Channel Container
2:01:57
Create Channel and Sidebar
2:58:22
Edit Channel
3:06:47
Search
3:17:43
Twilio SMS Notifications
3:28:38
Deployment
🎓
Tutor Explanation
DeepCamp AI