Twitter Clone with NextJS - Tailwind CSS - MongoDB - Prisma - NextAuth - Typescript [2023]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
you know hi everyone today we are going to make this full stack Twitter clone let me give you a quick demo so over here uh we have um our feed and our home page right we can see all of the tweets along with their uploaded images if I click on any of the tweets it takes me to their own tweet Details page where um I can view all of the replies that the Tweet has and also post my own reply over here like this awesome if I click back it's gonna take me back to my um home page right and over here I can also um like any of the tweets I can bookmark any tweet and if I bookmark something I can go to my bookmarks section over here and it's going to load all of the tweets that I have bookmarked um I also have a profile section over here and it's going to basically load my profile which includes my profile image my name username all of my tweets and replies I can even change my profile picture so I can upload um a new one over here and click save and it's going to update my profile picture and all of my tweets and replies um we can also post our own tweets um along with the replies over here from our home page and I can upload images inside any tweet or reply so I'm just going to select something over here and we can see the image that we are about to upload as a preview over here we can click this button to discard it and go ahead and select a different image as well I'm going to upload this image along with whatever you have written over here in our new tweet right um the tweets can also be multi-line they can have emojis and all of that good stuff finally um all of this is um authenticated or protected via Google sign in so if I click log out over here it's going to take me back to the login page and we can't access any of the Twitter app pages without signing in and you can simply sign it with any Google account if you sign in for the first time it's going to create a new account for you and it's going to give you a username and it's going to take your name from your Google account so this is a full stack clone and we are going to make this um using next.js react uh so react inside next year's and Tillman CSS for the front end we are going to use mongodb as our database and we are going to use Prisma to interact with it um and we're going to be writing all of our code in typescript and finally we are going to be using net dot for implementing the sign in with Google functionality and for protecting all of our API routes so that no one can really use the backend apis for this clone with if they are not signed in user from our application all right let's get into the code okay so we are going to start by creating a new next JS project and we're gonna use the following command we are going to use typescript um and keep everything else as the default the Tailwind flag over here is going to set up Tailwind CSS inside your next JS project so um over here we can already see the Tailwind config in place and we also have like all the other um uh setup needed uh to use the event inside our next yes project ready so now all I'm going to do is open this project up in my vs code okay so first up we are going to run npm runtime and it's going to basically um it's going to basically start our application and host it on localhost so let's check that out this is the blank um project that you get with create next app now we are going to basically go into um our index page I'm gonna turn off the terminal and we're gonna replace um all of this right so I'm gonna delete everything over here and just write the hello and you can see um we can we can get basically get started with our project over here right so the first thing I am going to set up is basically going to be the authentication right because yeah it's going to serve as a base for everything else that we built on top of it for example the apis so in order to set up the authentication we need to do two things first up we are going to be using next auth right um and for that I'm just going to Google the next auth documentation we are going to go and to get started and we're going to follow these instructions for the most part all right so first up we are going to have to install the um next auth package so I'll just go over here shut this down install next Dot right it's going to take a second and next we are going to have to create this file called um next auth.js and it's going to be placed inside our API folder right um make sure you're actually um using the exact same file name over here so I'm just going to go over here and I'll click on new file and it's going to be inside an auth folder inside the API folder next auth.js right now that we are over here and just copy paste this code from their example to start with but we are going to be using something different so first of all we are going to be using a Google provider instead of a GitHub provider because we need to log in through Google we are going to import this from next dot slash providers slash Google right now as you can see over here we need um a couple of environment variables for this to work right so first up I'm going to change this to um Google ID and over here I'll just write Google secret and now we need these variables in place how do you get these variables uh I'm just gonna show you in one second so first of all I am going to go to the root of the project create a new new file and we are going to name it dot EMV dot local right over here we want our Google ID right we also want our Google Secret right and we are going to uh fill in all of these values in just a second we are also going to need a couple other uh variables so first of all we are going to need as able to go to Secret and you can add anything over here but um yeah it's it should usually be a long random thing for now I don't really care about uh the security concerns I'm just going to write ABCD over here right the other thing that you're going to need and by the way all of this is not um like you can basically find all of this stuff over here all right like uh as we follow these instructions you're gonna see how we add these variables but I'll just add them all right away um uh to keep things a little bit quick right at the end you can also see we need to add this next auth URL environment variable and for now we are going to just save localhost over here and I'll save this file I'll go back to my browser and over here what I want you to do is Google Google Cloud console right um this is needed in order to get the Google ID and the Google secret we use to implement the sign in with Google functionality so we're going to go into um our Cloud right like and um you can actually create a new project over here or you can if you have like a new dummy project over over in your Google account it's going to show up over here all of these are fine uh what I want you to do is go into API and services right so you can by the way do this with any project right like I'm just going to do it over here because I was already using some Google apis for some experiments and we already have like some clients created over here but what I want you to do um is basically go over here so we need to create a new client ID over here right so I'll just click create and I'll select oauth client ID okay okay now I want you to go ahead and select a web application over here you can give it any name I'm just going to write Twitter clone 2 over here and now we need to add some URLs so first of all you are going to add um the localhost so this basically tells Google that this is your web application URL and we're also going to need a redirect URL right um so for this you can basically write um localhost 3000 and I believe there is actually check over here so um if we search for like call back the URL um I'm just going to uh find it somewhere over here right so we have riders or odd um everything over here okay so over here if if you can see that they tell you um how to register your application in the developer Pro portal of your providers the developer portal is over here right like this is our developer portal and what they want you to do is basically for example if you're using Google or whatever it's you're gonna have to enter um a call back URL that looks like this right so in our case it's going to basically look something like this with localhost over here once you deploy your application you can change the or you can add another callback URL with your um like word cell URL for example or whatever you want over here so I'm just going to copy this look over here and uh paste this right so now this is done I'm going to click create now it gives me a client ID over here that we can copy go back to our environment file and we can paste it over here now it also gives us um a client secret so we can also copy this one over here and um paste it over here and now click save so now we are all set up from Google's end right we can click OK and you can also view these at a later point in time by just going into uh this section over here but for now we are going to go ahead with like the rest of the steps so viewer over here right like we added um basically instead of the GitHub provider we have in our next auth config we have added the Google provider right now we need a couple other things apart from the providers array you're going to just set all of those up in just a second the first thing you're going to need um is basically um our secret and what we are going to insert in the value is our JWT Secret that we declared in our environment what this does is this equal it acts as like the encryption key for storing all of the access tokens and session tokens that you're going to receive from Google inside your browser so you want them to be encrypted before get them getting stored inside your cookie uh and we're going to use this value as the encryption key right now let's sort of like go back over here and see what else we need to set up uh the next thing we're going to need is basically we're going to have to modify the underscore app.jsx file so I'll just open that up over here and as you can see instead of this what they want us to do is basically import a session provider and wrap our entire application with it what I'll do is just that I'll delete all of this stuff and we are going to okay let me just take a second over here we have this stuff okay uh this is not a typescript example so we can't directly copy paste it because it messes up the types so I'm just going to import the session provider over here [Music] um over here what I want to do is basically instead of page props I want to extract out the session object from within the page crops right and then I want to wrap this app component with the session provider right so we're done with this step as well and now we are going to basically implement the sign in and sign out functionalities so to create the login page we are going to go back into our editor and I'm going to add a new file over here called login.dsx right now over here uh what we are going to do is first of all I need um to export a function I'm going to call it login and over here we're going to keep things simple for now uh I'm just going to add a button that says sign in with Google right and I'm just going to give it a bare minimum styling so we're going to give it a width of hundred percent the height of the screen I'm going to Center everything over here this and we have the sign in button right now in order for this sign in button to work we basically need to import the sign in function from next auth slash react so we're going to do um just that right so I'm gonna write import sign in from next dot dot react and we are going to basically go over here and create the on click function we're going to add sign in over here and over here as you can see we need uh we can add in some optional parameters that we are going to use so the first one is called provider the provider name for Google is just Google over here right and we're also going to add um another option called um callback uh URL right and we are going to give it the base URL as the value what this does is once you click on sign in and once you are logged in into your Google account it's going to redirect you back to the home URL so you're going to get back to index.tsx right like whatever is in there and you can continue on with your application um so I'm just going to click save over here and we can go back to our browser and just type in login right um and for some reason oh okay we forgot to start the server again so I'm just going to do that trace this out go back and now you can see they signed in with Google button it's completely unstyled because we haven't added anything yet but we are going to do that uh later on right and now that we have like this in place uh we need to do a couple other things right first I'm going to go back to my next auth config and over here I'm going to add in another parameter and this is this one is called pages right what pages does is you can create we're going to create a key value pair called signing and we're going to write log slash login over here what this does is it tells uh next yes that the sign in functionality is going to happen at the slash login route and then a user is not logged in uh it's gonna help us tell next auth to redirect them back to the sign in page which is at um localhost slash login right now what I'm going to do is uh we're going to go back to our next configuration and over here we're going to um actually um we're going to see if the login works right so once the login is done the user will end up over here and over here what I want to do is basically add a couple of things so first one is going to be um a session object right and this comes in from the use session hook that we import from next dot slash react package and over here I'm just going to add in an extra parameter called required and I'm going to set it to true what just does is if the user is not logged in we are going to basically it's going to redirect them back to the sign in page that we set up over here what I can do over over here now is uh we can basically use the status value given provided by the U session hook so status basically can take an um two values over here right so it typically takes in three values one of them is loading one is authenticated and the other one is unauthenticated but because we have added this required um equals true inside our U session hook uh you will never actually get an unauthenticated um as the value of the status so if the status is loading that means the user is still being logged in we can just for now like we can add a loader over here but for now I'm just going to create a tip and just write um loading over here right and if not then uh the status is basically authenticated and they can actually access like everything inside the Twitter over here um now uh let's test if um if all of this is working okay so I'm going to go back over here and the first thing I'm going to do is basically um go on so so I'm not sure if you noticed it happened really quickly but basically the moment we went on to our Local Host dot 3000 over here um it showed loading for just a brief second and then it basically realized that I was not logged in so it redirected me to localhost 3000 slash login right like over here and now we have like being we basically need to sign in with our Google account um in order to access the Twitter page I'm just going to click sign in and it's as you can see uh it gives you the actual uh Google login page from accounts.google.com and we can select I'm just going to select my account over here and um it sends me back to the login page which is weird but we're going to fix that in a second right so um what I'm going to do is go back to my um go back over here go to my login page and I'm going to basically just check if everything is set up right over here so the other provider we have the Callback URL right this is fine um so it should actually send us back over here um let's see if we can actually uh access so yeah we are logged in it just didn't redirect us back to the home page um and that is something we are going to fix but for for that for us to test that I'm just going to add a sign out button over here so that we can test this functionality right now in order to implement sign out be implementing the sign up button is pretty easy you can just import the sign out function from next dot slash react I'm going to copy this over here and I'm going to just instead of this Twitter I'm going to add this button and I will import the sign out function and if I go back I can see the sign out functionality over here if I click on sign out it's going to redirect me back to the login page right now um okay so now that we are over here I just want to make sure that I have everything uh setup over here right click so we have localhost 3000 we have this over here I'm just going to go and check if I missed anything at all nope this seems to be working which is fine um I click sign in it basically logs me in but it doesn't send me back this is weird um okay let me go back and see what's happening oh oh no okay this is a typo over here so call back URL is supposed to be spelled like this right now if I um let me just clear all of this up right click sign out and now click sign in with Google so as you can see it redirects me back to the home page and we are over here with our sign out button and this is where our entire Twitter application is going to be sitting in okay so now we are going to set up our database so we are going to be using mongodb along with Prisma for this and Prisma just makes it really easy for us to interact with the database and perform all of the crud operations that we are going to need for our Twitter clone and for that to work what I'll do is put so you want to go to prisma.io right and you want to click on like Quick Start um go to add to existing project and click on mobile right so this nicely lists out the steps that we need to follow and um uh this I'm showing you all of this so that you uh you don't have to remember all of like these steps you can you just need to know where to look for when you are setting this up for any of your projects right so we're gonna go ahead and install Prisma as a web dependency and for that I am going to copy that command paste it over here and just press enter the next thing we're going to need is um basically set up our Prisma project by creating a schema file and for that you basically need the MPX Prisma init command I'm going to paste this in and now you can see inside our project we actually have a Prisma folder over here and it has a schema file right I'll just close out the terminal so it can see and over here we have like um like a couple of things right and we are going to the first thing that we need to do is fill out this database UI right like we need to replace this with our um mongodb URL right so the next thing we want to do over here is click on connect to database right and yeah um basically we want to get this sort of a string from mongodb and put it over inside our environment file right um the way we are going to do that is we are going to go to um uh mongodb right like over here and they have a nice um Fleet here right so you don't need to pay anything for this the free tier is more than enough for um projects like this um as long as they're not put into production right so they give you free database with like a decent chunk of storage and things like that that you don't even need a credit card to start um so I want you to go ahead and basically sign in with your Google account right once you do that you're gonna end up in a screen that looks like this right now over here what you want to do is create a new project all right or create new cluster um and basically uh you want to select shared because this one is free and um you can select pretty much like anything over here uh so I'll just go with like the default options and click create cluster it's gonna give us this uh you know verification thingy wait um yeah okay project already okay um so you can already create one free cluster but basically once you click create over here um what you're going to see is basically a card that looks like this right so I've already created one cluster over here for our um for for the build that I did before this video right and what you want to do is click on connect and then click on vs code because this gives us a string that's exactly um that's exactly like uh uh like the the string that we need in our Prisma file right and over here uh there's a password uh mentioned over here right so something that's gonna happen once you um I'm just going to close this out so once you are on the screen over here you click on create cluster it's gonna ask you to set up a password right like a password that basically um is is basically like the uh the password is going to be used to access the database right so that not everyone can access it only people with like a certain username and password can access it right so over here um what I'm going to do as I'm going to copy all of this right and I'm going to go back to my EnV file over here and over here as you can see it's it's it has like a string in place all already but this is a template string we can simply just delete this and enter our mongodb string right now I'm going to change two things over here number one is like the password and the other one um is this test right so what this test represents is if you go back into this cluster right and if you click on browse collections you're gonna see that we have this database called test right so this is the database that I used to spin up the Twitter clone that I I gave a demo for right now you you won't have this uh so you're gonna have like this by default but what I'm going to do over here is Click create new database right if you're creating a cluster for the first time you won't need to do this but over here I'll just say Twitter DB right and um uh we're gonna need like a collection name so we can basically just say um like I'll just add to it all right we're gonna be creating other collections right so collections is similar to our table if you are familiar with SQL database but basically um we're gonna be creating other collections for our um like Twitter functionalities so we can just enter anything over here and click create right once you're done you're gonna see a Twitter DB over here right so what I'll do is I'll just go over here I'll replace DB over here and uh save this and I'm what I'm going to do next is basically copy um my password for this mongodb from my other um project file and just paste it over here if you're creating this for the first time you're going to have your own password that you set up right before this step so you can just paste it in place of this string and I'll just do that and be right back okay so I pasted my mongodb password in my environment variable file and I've closed it um for now and you can do the same because we are not going to be changing it at any point in it will point from this point onwards right so now we have um we've basically um connected our Prisma to our mongodb database over there right and I'm going to go ahead and just change this mongodb right there is something we just filled out and now we are going to basically add in a couple of things over here so what I want to do now is is basically describe the schema for the um for the entities that we are going to be storing inside our database right and I'm going to just do it like this so first of all what you want to do is basically uh what I want is to store my users so for each of my users I'm going to basically say it's going to have an ID uh that is going to be a string right and I also want to add um this thing over here so what you want to do is like you want to add accurate ID and then activate default um Auto close this bracket and then say another map underscore ID and then say Android DB dot object ID right so the reason we are writing all of this extra stuff is because mongodb are automatically generates a unique ID for each entry right and um it gives it so the ID is basically stored under the key underscore ID right but this is not allowed in Prisma so we need to basically we want we want Prisma to map it to the key ID instead right um other than this what you want to do is you want to say it's going to have like every user will have a name um we can keep this optional they're also gonna have like a username we can keep these optional as well and we can add a really advert unique over here to specify that no two users can have like the same username if they do uh or if you try to store um two different users inside the database with the same username it's gonna throw an error right um we also want to store the email all right because uh we're gonna be creating the accounts using Google sign in and we're going to be primarily using email um uh to identify the users rights so we are we basically want emails to also be unique over here and um we also want a profile image all right and I'm gonna write string over here and this is because we are going to be storing our image in a page 64 string um other than that you also want something like created ad these are relatively standard stuff right you wanna um which which can be useful for treatments like uh most entities like this so created at it's gonna have like the type date time and it's gonna have a default value of now right so it's going to give it the current uh date time next we also want updated ad again date time and it's gonna be given the updated ad um over here um apart from this so we can keep it over till till just this much for now right the other thing I want is like post or a tweet right so this is also going to have a bunch of things but I'm just going to copy the ID um from over here right um and then I want a body so the body is going to be a string right the post can also have an image optionally so string and then a question mark over here um I want to basically um copy this these two lines created that an update that over here and um I'm also going to add a couple of things right so we wanna we're gonna so every user is going to have an unique uh email attached to their account right um and this is because um we're using like the the Google email that they're finding in with so we are going to just use that to identify um like uh the author of the post right so I'll just write user email and I'll write string over here then we want to know who has liked this post right so we'll just write liked user emails and this is going to be um an array of strings right then similarly we also want to know who has bookmarked these um this particular post so we're going to write bookmarked user emails and it's going to have the type string the array of a string right the other thing that I want to write over here is called parent ID right now this is a little bit interesting because what's happening inside Twitter is if you reply to a tweet the reply is also a tweet right it's a regular tweet with like everything it's gonna you can add an image over here you can add the same body over here it's gonna pretty much have like the same structure except that it is attached to a parent tweet right and to identify the parent tweet we're gonna add um basically a parent ID and this is optional because not all tweets are going to be replies so if if it if a post does not have a parent ID right because this is optional then that means it's not a reply but it's like it's it's an original tweet right um and basically I'm also gonna add comment IDs over here to uh to basically keep track of like all of the um all of the posts that are basically a reply to this particular post right so we are going to add comment IDs and it is going to be an array of string again right so I'll just keep this as it is for now if you hit command s it's going to format it a little bit so that it looks neat right and once you're done with this I want you to open the terminal and then say um um okay so there's a command for this that's basically yeah this one npx Prisma TV push right and what it is going to do is it's going to basically so let me just hit enter over here and as you can see it's actually connecting to our mongodb database right like our Twitter DB that we set up and now what it's doing is it's basically creating um like a bunch of stuff that you're gonna use inside your code to actually access or create or delete or update any of the user objects or the post objects right um and that's why it says generated Prisma client and added it to node modules Prisma client right so now you're done with this um and now what you want to do over here is basically um install Prisma slash client right so this is the client-side package of Prisma that we are going to be using inside our code great okay so now we are going to create the apis that we need um in order for our Twitter clone to work right and that means we need an API for for example getting uh the user details creating a user updating user profile pictures things like that right so I'm going to um so what I'm going to do is I'll just close this terminal for now and I'll go to my API directory inside my Pages directory and I'll create a new file right and I'll name this one user.ts right and what I want to do over here is basically um so I want to basically use next JS API right um similar to what you have over here but I want to protect this API route right so what do I mean by protecting an API route well if you go ahead and start the server again right and if I now go back to my browser and just hit flash um API slash hello right it's gonna give me a response regardless of whether I am logged in or not um right and you can see the response being sent over here but what I really want for my API routes is that if someone sends a request to my API and if they are not logged in right if it's not coming from a logged in client then I don't want to entertain that request and in order for that to work we are going to basically be using a functionality from next out right um so let me go back to my vs code and go back to my user.ds file and over here I am going to basically uh do a couple of things so the first thing is basically I'm going to copy all of this stuff right so that I don't have to type it all again and now we have like a basic um uh sort of like fun API Handler over here right I'm going to delete this stuff go back over here delete this for now as well right and over here I'm going to do a couple of things um first up I wanna import um get server session from next start right and what this does is it's going to help us basically uh verify if the request is coming from a logged in user or not the other thing we are going to need is basically um we are going to need the auth options right and the auth options are actually coming from our next auth configuration file over here right like so these are our auth actions and what I'm going to do like we've already exported this so I'll just go over here and I'll just write pages slash API slash auth um slash the finance right and now what we can do is go inside our function and create a session object like this so I'll wait get server session request response and other options right and now we have an error over here because our function um is not a sync so I'll just fix that writing async over here and then go back over here now if you get a session object from this function right that means that you have basically the request is coming from unlocked and user if not what we are going to do is we'll just say we're going to return a response uh with the status code 401 and we are going to write a message that says You must be logged in um that right like I think that's enough right and if not we are going to basically get um this uh John Doe as the response right right message over here um and now let's verify if this is working right so now right now we are signed in um so if I go over here and do a get request on slash API slash User it's going to give me Toronto right but if I go um to um let's say a different browser right or I'm just going to go and open an incognito mode right and over here I'm going to write slash API user and it's going to give me a message that says You must be logged in because I am not logged in inside of this browser instance right so that basically is how we protect our API routes right like so that no one other than a logged in user from our client and access whatever is happening inside our API um okay now that that is done I'm going to uh basically start implementing the rest of the API so first up I'm going to create a try tabs block all right and over here I'm going to basically um I'm going to handle two different kinds of requests so if request dot method is get I want to do something over here for getting the users and I'll basically return a response from over here so we can I request Dot method equals post I'm going to handle it over here right now what I want to do inside get is simply get the user from our database right the way you do that is I'm going to say you get um your uh we are going to add um for each character Quest we are going to basically add the user email right because that is the only identifier we get from our Google authentication so we're going to use that as a query param and we're going to say request dot query dot email and as string right now um um okay now uh if I have a valid email right I'm going to just say const current user await Prisma all right Dot okay so before we do that I just forgot one thing right so let me comment this and um before we do that we actually need to um do one more thing over here right like in our Prisma setup so what I'm going to do is go back to like um go back to basically my uh the root of my directory and create a new folder called um lip right and inside this I am going to create a file that says uh Prisma dot TS now over here I wanna basically use the Prisma client package that we just installed so I'm gonna write Prisma client right now below this I want to declare global um I'm going to write where risma is my client or find right and we are doing this basically so that we don't instantiate a new Prisma client um every single time right so what we are basically going to do over here is we'll write conch client is like global plus dot charisma or um a new Prisma client right so what this does is if you already have a Prisma client instantiated it's going to be used this otherwise it's gonna create an instance of a Prisma client uh right there right the other thing um that I want to add over here is if uh we're gonna add this environment variable later on but basically if we are in if you're not in um production right like if they're not in production I wanna basically set Global this Dot client equals sorry Prisma equals client right and then I am going to export this client object now we can close this file go back over here and now what we can do is basically we can import Prisma first of all so I'll just add that here I'll say import Prisma from add the rate lib s and we don't need these braces over here so just remove them and now we can basically uh use this prisoner object over here or anywhere at any point anywhere inside our code to actually interact with our database so as you can see we have like a bunch of methods over here so we can create a a user object we can create many different users we can delete we can find uh we can update right like all of these operations that you will normally be using inside your database we have them all over here so right now what I want to do is um find unique right and I want to find uh the one user which basically has email equals to email right like this is this is basically um this is what we we need over here inside our uh inside the get request right and what I'm going to do over here is basically um if if we can't find a user like this right click if if Prisma is unable to find a user like let's say it's a new user right it's it's unable to find a user with this email uh we're going to handle it over here and we'll just send back a response um and we'll send back a response that says um new user right and um yeah I think there's enough for now and we'll return back from this function if not we will basically send a different response that say is um user found right and we're going to basically um add the current user like the one that we found inside our database inside this key over here right once we are done with this we can return right now this is uh I'm going to basically look for a user with like a given email inside the database if it can find one it's going to return it otherwise it's going to just return a message that says a new user right um Okay cool so next what we are going to do uh is we're going to basically uh handle our post request um also before that what I'm going to do over here is just say um if there's no email I just want to send a message that says um no email sorry like if you if we don't have any email uh inside our request and then we can't really do anything now we're going to go back to our post request and over here we are going to have a body inside our request and we are going to use this to basically create and um update um our our user right so what I'm going to do over here is um so first of all I'm going to extract email out right so I'm just say request dot body dot email because we expect an email inside this post request and as string right if we have an email um what I'm going to do is I've handle a couple of cases over here right like so one case is we want to create a new user great so if that is the case what um okay so the way we are going to be creating or updating a new user like there are two cases over here create new user or update existing user and we're going to determine which one of these operations we are going to be doing by just checking if we have the user in our DB or not so we're going to what what I'm going to do basically over here is just um copy this stuff right cool so this is the same as before right like we are checking the DB we are trying to find a user with this email if we can if we can't find the user this is where we'll create right and it's very simple to create a new user you just write const user equals await Prisma dot user dot create right and over here what you want to do is basically add in data and we're going to send in like everything inside our body inside that data right once you're done I'm going to send a response that says done okay um cool now this is case number one right if this is not the case if we already have a user we need to update the existing user over here right so what I'll do is I'll just write const user is await Prisma Dot user dot update and over here we need two parameters one is where because you want to know which users do we need to update like best user so we're going to search for the user using their email right and the other thing that we need over here is basically data right and over here we I am going to basically pass in the entire body of the request and once we are done with this I'll just say uh response dot status 200 and then I'm going to um send back um basically uh send back a message over here first of all let's see done right and I'm also going to send back the user that we just updated right um once we are done with this we can basically press done right and this is sort of like if we had an email inside our request body you can also go all the way over here and just say um message no email over here in case there is no email right um and once you're done with this we can just return right now if there is an error over here we can handle that error log it out for now what I will do is give console log this error and just return uh response of like um so I'm actually gonna just just return um a 201 over here right and just say uh inside our message and right um so this is all for like our this is all we need to create a new user to update any existing user um I'll just delete these two lines and to fetch um the details of any user right now we're going to be using these apis inside our front end code um to do these operations right now in order for that to work we will go back to our index dot TSX file uh which is currently empty and it just has a sign out button but we are going to be adding um the user related functionalities over here next okay so now I'm going to show you how to automatically create a new user when someone signs in with their Google account for the first time and we're going to be using the apis that we just made um but first what I want to do is um create a use effect over here right and this use effect is going to be triggered on changes to status and session object right and what I'm going to do now is um just expand this and over here I am going to create an async function so basically inside use effect if you want to run anything in using the async await syntax you're going to have to follow a structure like this you declare an async function and then call it um separately right now over here what I want to do is if status not equals loading right because uh this is when you're gonna have like a loading screen over here but once this is done uh you are basically logged in so you should be able to perform all of the actions that you need and secondly I want to check if we have the session object in place because this also is uh null initially but it loads the session object from the use session hook and then uh you basically are ready to go now this session object is really powerful so this is where the convenience of using next auth comes in because next out gives you this session object which contains all of the information that you get back from um from Google right and what we are going to do over here is we want to extract out a couple of things so first of all we're gonna have email right this email is stored inside user session dot user dot email right um it's also going to have a name right so the name that you have in your um in your Google account that you're signing in with so user dot name right the next thing that we are going to create is a username right so we are going to automatically create a username um for for this person and the way we are going to do that is uh so we're going to utilize uh their name which means session dot user dot name right and we're going to use the first name this typically returns like both the first and last name so we're going to split it with a space and we are going to use the first name over here and there we are going to add an underscore and we're going to add a unique ID over here right like an add unique ID over here and in order for us to add that unique ID I'm just going to um create like some random uh numbers over here right so how do I do that well um instead of writing the whole thing I'm just going to go in my GitHub right because you are all also going to have um access to this code um like all of the code that I am writing so instead of typing it all again what I'm going to do is just go inside my index.js and there's going to be a function over here that says make ID right so I'll just copy this over here right and what it does is simply select so you give it a length right for example if you want a six random digits right like a string consisting of random digits which has the length six right so you're gonna basically select random characters from from this string right and you're going to create a new string out of it so what I'm going to do over here is I'll write make ID and I'll just write 6. and that's it right so now we have an email a name um and and like a username right and something else that I want to do something that I miss is basically initially the user is not going to have a profile image and in that case what I want to do is basically um I wanna I wanna I wanna add a blank as a sort of blank image instead all right like when the user account gets created and the way I'm going to do that um basically is um we're going to add in a file over here right like this file is available over here so let me just get that um you can go inside public right and we're going to have this file over here right um so what I'm going to do is is basically download this file right I can and basically um looks like this right and I'm going to uh download this over here and I'm going to put it inside my project right um and this is like the image that is going to come up uh when a user has not set uh his or her profile picture right um so what I'm going to do over here is just cancel this and I'm going to um copy paste the file over here into our public folder done let's run the project again close this terminal we are good to go now something I want to change inside um here inside our slash API slash user file is when a new user is getting created over here right like so if you sort of go over here like this is where a new user gets created you're gonna see that we actually okay we actually don't have like uh so we we actually are not passing in like we're we're going to have to make sure that we are passing um the profile image over here as well right and the profile image should basically contain the path of the blank image that we just contributed that we just downloaded right so now I'm going to go back to my index.tx file and what I'm going to do first before all of this works is I'm going to basically um check if the user exists or not because this might not be their first login so what I'm going to do is I'll write const response or let me actually just get out of this place and write a new version right missing function get user right um and over here I just need an email to get the user and over here I'm going to write response await fetch and I'm going to use the user slash API slash user route all right and before this we need to add some parents so I'll just create a new URL search perhaps I'm going to add an email as email and over here I'm going to go back and add a question mark over here and then go to add the balance right this is going to send the email inside the request and now what I want to do is if response dot status is 200. I don't basically say const data is of it response dot Json um and inside this what I'm going to do is check what the message is right so if it there's a new user right if if we can't find a user with this email inside our database we are going to basically get this string inside our message and this is because we actually um if we go over here you can see that if we can't find a user in our database we send back this message otherwise we sign the message that says user found and we have actually send the user object as well right so I'm going to go back over here and if we have a new user I want us to basically um uh okay or we'll just keep this as it is right now right and I'm going to um return the data from here right like this function as well now I'm going to create an another function and this one says create user right and over here I want um I'm just going to keep it as it is now I'm going to um I'm going to basically just say copy these three lines over here right um right and so it shows an error because it doesn't know that we are actually verifying if the session exists before calling this function you can actually add a question mark over here um that's okay because we're going to be only calling this function from inside this if Clause right now what I'll do is delete these three lines um and over here what I want to do is const um I'll just say data as get user or I should say await get user I'm going to pass in like the email right so over here [Music] um over here I just want to pass um session dot Reserve about email as right um cool now if data Dot message equals new user we are going to call the function that creates a new user right um and we're going to fill out the rest of this function now const response I'll wait that's um flash API user right and now we need a couple of other things so method equals port you're going to need some headers over here [Music] um I'll add these in just a second and then we need like a party so this body is really important because we are going to need um the email name oops the username and we're going to need a profile image that says um right yes so this is uh basically if you paste anything inside of your public directory like so you can access it at this route right and so we're going to send all of this stuff up um gives me as one error over here okay yeah that is because we need to run json.stringify on all of this right um cool so now that this is done um right so now that this is done um the one thing that we forgot over here is basically uh you're going to have to add um I guess it's content type equals um application slash this all right so this basically if you don't add this um it's not gonna basically pass um this request.body correctly which is why we we always add this inside or we are going to always add this inside our post request right um so this is done um okay cool now what we are going to do is like if we had a new user we created a new user right um and we're what what we're going to do is is if response dot status equals 200. we're going to extract um the Json right and we'll turn this data by the way we thought you also want to do over here is um okay so we are we're okay we'll handle like the edge cases later on right let's just create the basic functionality so we have create user once the queue user gets created we've turned back the data now once we are done with that you want to basically do a couple of things um so regardless of whether I'm just going to write um user data over here so basically um if a new user gets created we're gonna going to have like the user or data inside this object otherwise it's going to be inside this object right now what I want to do over here first of all just to show how this works is create a couple of states the const user I'll just say username right usernames that username also okay use date and there's going to be a string and I'm also going to require um and profile image right set to file image and this is again going to be on a string over here right and we're going to save this I'm going to scroll down and once we have either through getting the information from the database or by creating a new user once we have the user information right like once we have the user object um and it's always going to be over here inside like this user thing right for example over here um if we are getting it from like the database we are going to pass it over here if we are and creating a new user over here we are going to um pass it over here right save this and now what we're going to do is we're going to uh store the some of that information inside our react States so um we are over here right like and what you want to do is set username to user data dot user um dot username right and we also want to set profile image user data dot user dot um like profile image right and if this is not the case right like if it's not a new new user we can just um do the same thing except for uh we're going to use um data over here right delete this line and done so what's going to happen now is uh we have the server running cool if we open up the home page it's going to run this right and what it's going to do is it's going to get the email from the session object which means the email that you get back from Google after they sign in we are going to check if if we have a user with this email inside our database fb2 we are going to get that user's data if not we are going to create a user and then get that newly created users data inside our react States right now in order for us to see all of this I am going to basically added a couple of things over here just to keep things a little bit neat so I'll just say username right and over here I'll write username right um and I'll even add and an image tag over here the image is is basically we're going to use this from next image which for some reason isn't coming up okay let me let me first show you the username and then we're gonna add the image as well so what I'll do is I'll go back over here to our home page right and we're going to refresh right and once you've refreshed um all right so okay there's like a little bit of an error we are going to debug this but the username did show up like if I close this you can see the the username that we created using the random secret six digit ID is over here so we can see it but there's like an error right so let's see what's happening uh cannot read Properties or defined uh user over here so this is when we're creating a new user it's it's actually um okay let's see what's happening um so we are over here right we've just created a new user and returned the back the data that we got from our API so let's go into our user API file we are going to be looking over here because we just sent back the user that we just created um okay pretty cool um the weird thing somehow is okay let me just um let me just close this for now so we're going to check this but for now our account is created so if I sign back in it basically should just yeah it should quickly load my username from the database and show it to me right so this is pretty cool um this basically shows like all of the logic that we we were just writing now um I'm going to check that error as well but in just a second right so let's get back to our index um dot TSX file and till now what we have done is we are automatically creating a new user with a username the email the name that we get back from our Google sign in and we are attaching a blank profile picture as their profile image right uh okay so one more thing I'm gonna do over here is show the profile image that we are from the user that we just created so I'm going to use the image tag from next year's and over here we're gonna be adding Source profile image by the way this should only be visible um if um there is a profile image that can be displayed so basically we're gonna write profile image now uh we also need to set a width so I'm gonna set it to a thousand right and then I'm going to resize it using detail when CSS classes so you'll just add an ALT tag profile image over here and then add some class names right so I'll just write um like a width of 10 height of 10 right and save this let's go back and as you can see like our blank profile picture is showing up over here right now if we change this inside our user entry in our database we're gonna see the different image over here but the point of this was just to show you that we are successfully have created like a user over here right and we are fetching the data of that user over here after logging back in and we are able to show that data on our page right so now we are going to build um a little bit of ah the front end but before that I am also going to build some apis um for the tweets right because we need to fetch and create tweets over here as well so what I'm going to do is basically um go to Pages live API and I'm going to create a new file and I'm going to call this um post dot TS right now to start this off I am going to basically copy um a bunch of things over here we have an unused import over here so I'll just cancel this out but basically um you sort of need everything till at least like this point all right so I'll just copy this and I'll go over here and I'll paste this right now I can go down here and fill the rest of it up so you're going to implement a try catch and uh we are missing um a closing brace over here okay so what I've done so far is basically just copied um like the basic structure of of an API Handler over here and I've added in uh the uh session object that is retrieved using the get server session so that we this API route is also protected right like no one who is not logged in should be able to access anything um that is being done inside this API right um okay now that we're here I wanna again do two things right so we're going to be handling the post requests that come over here right and we are also going to be handling um get request all right so get request is basically going to be for fetching all tweets you wanna fetch all the tweets and show it and our feed right the post request will be for creating a tweet right because we are going to be able to post a tweet from right within our home page which is in our index.tsx file so I'm going to write this down first so over here what you need is um essentially the same way we created our user like cons pushed awaited uh equals await Prisma dot post dot create right and over here we need to pass in some data and over here um what I'll do um is I'll just pass in request.body right and this will basically contain everything that comes within that post right so that means basically the um like the post body the user email um the image um and yeah that's most pretty much like that that pretty one sums it up right once this is done uh what we want to do over here is send back a response so status 200 and I'm going to just say um done over here right okay we can actually even just send back the poster cool now as far as the get goes this is pretty um straightforward so what you need to do is just write cons posts await Prisma dot post Dot find many and over here order by I'm going to just use the created ad right and I'm going to say descending right so you can order it ascending or descending by using this format right so we are going to and because we haven't entered any uh where condition over here so it's going to basically um it's going to get like all of the posts right like and apart from the posts what we also want to do because each post is going to be displayed or each tweet is going to be displayed along with the um the profile picture and the username and the name of their author right so we also need to uh we need to basically fetch all of that information as well so what I'm going to do is declare um um like an array over here right user data and we are going to actually store everything um uh about the authors of like these posts over here inside of this array how do we do that uh just create a fall root right call zero post dot length I Plus right um and over here I'm going to just get a user how do you get the reuser simple um the same way we did it for uh inside our user API route so Prisma dot user Dot find unique over here you need where email equals um post I dot user email right [Music] um okay now we have the user so what you I want to do is user data dot push user and now that this is done I'm gonna basically just say press dot status 100 I am going to send um posts as well as the user data back right also um so I have I need to also add a return statement over here because we yeah we're pretty much done with like whatever like with our response that we needed to send back and I'm gonna just add um the same thing over here as well so return and um um just in case like uh we get any other form of request I'm just gonna also add like um a status over here um like a message over here all right I'm gonna say message uh incorrect request right um and if we have an error we can for now we can simply just console log error um and we can just say I don't know right so this is done um and delete this line and we are done with like the basic tweet um apis over here um so after this I also need some more apis just to basically um just to implement the functionalities of for example liking a tweet or um bookmarking a tweet things like that right but for that before I Implement those apis I am actually going to write a little bit of front end so that we can actually test these apis out as we um as we Implement them so we're going to be using all of these apis in the home page so let's go ahead and and implement the front front end of the home page now okay so in order to create the front end we are first of all going to create um some components right so I'm going to go to the root of my project and create a new folder called components and the first component that I am going to create will be layout dot TSX right so this is a special component this is going to wrap our entire application and um it's gonna basically take care of the sidebar right because that remains fixed but we can scroll through the Tweets in the middle right so I'm going to write um function over here and inside this function we are going to actually need a couple of text all right so um first of all I am going to lay down um some basic audio right so I'm going to replace this with me because this is actually the main content over here all right and now I'm going to write last name over here width hundred percent right screen and I'm going to create a flexbox right inside this uh what I need is basically um uh like a couple of tips over here right um the first one basically I'm going to give it a width of 20. right and actually we are going to what what I'm going to do is basically like make this responsive as well so by default we want a width of 20 which is basically like 80 pixels right so not that much but um if you're basically in a larger screen I wanted to um essentially occupy 1 4 or 25 percent of the birth right I'm going to give it shrink 0 and grow zero so that it does not um it actually accurately follows this with right instead of being directed by the flex filler and I'm going to give it a border on the right hand side and I'm going to write your curl let's go this one right then uh we have another black text white right and I'm going to say write a screen right now um what we sort of need inside this there is basically um a couple other tests all right so first of all what I'm gonna do uh okay so I'm going to write um height of screen and we're going to make this a flex box and set the flex direction to column and then just add some spacing over here we'll go with this one and I'm also going to add some padding right inside this div what I want to do is I want to declare a flexbox right give it the full myth and basically use justify Center so that like everything is Right within uh right in the middle right but in case we are on a larger monitor we wanna basically um if you want to basically to justify and so the reason we want to do all of this and because if we go to Twitter right you can see that we have um so we have like the sidebar right and on larger screens we have this entire div over here right like this section is on the um is aligned towards the left over here and this is what we're doing with the justify end if it's on a smaller screen it's going to be just these icons and it's going to be at the center of the sidebar so now I'm gonna go back over here and uh what I want to do is basically fill out these items over here right so we're going to create a tab for that and over here I'm gonna say um width should be um 60. right next next column um item Center and then if it's like a large screen um I want items at the start and we're gonna give it a gap of six right now in here uh the first thing that I'm going to add will be um the Twitter SVG right um so over here I'm going to add some class names first right so I'm going to give it um zero padding by default but on larger screens I want some padding right 32 pixels over here we want the Twitter SPG now um I've already actually Dot and then Twitter clone right so actually um copy pasted um the Twitter SVG over here and uh I'm just going to use that instead of like uh searching for a new one so I've just copy pasted it over here and I'll go back and um basically um use this one right so over here we can basically just add ruler SVG don't worry you're gonna have access to all of this code so you can copy paste it bits like the these uh wherever you feel the need for right I'm gonna add the Twitter SVG and then I'm going to add um some links right so we're gonna use the next JS link and um these links are going to be for example like home profile things like that right and they're gonna be uh linking they're gonna have like if you click on them I want the route to change and um for like the application to be redirect to to all different um page right so what I'm going to do over here first of all like um so we're gonna have like um let's see full box right um and over here I'm gonna say profile right click these three and we're gonna have different routes routes for them all of that but first uh let's sort of like put this layout component somewhere so I'm going to move out of all of these tests right like this is basically all of our sidebars and over here like if if you can see over here like we have a flexbox right so this is the first uh child of the flexbox which is the sidebar and the other main content is gonna come in over here I'll just write children over here and we also need um we basically uh we'll eat the children over here as well so I'll just write um children and then over here we have to declare a type so it's going to be children and then react dot react um node right this should do the job okay so we are over here and let's first wrap our application within this layout component and then continue on so I'm going to go back to my app dot TSX and over here I'm going to say layout and it's going to import it from at the rate components layout either it basically means the root um of our project directory right so I'm just going to put this over here and boom all right now um let's just check okay we have our server up we can go back to this part and now we can see a sidebar sort of shaping up over here right so we have a sidebar and we have this main component over here like whatever is being entered right and the sidebar is essentially gonna have these links and based on these links this content is going to change but this is going to remain static now um let's first add some icons right because these are looking pretty empty and for that part we are going to need is I'll just um and this and say um so yeah we are going to need uh we're going to be using something called hero icon so this is um like a pretty favorite of mine when it comes to icons they are uh created by the um creators of tailored cases and they are pretty damn good and they're free to use and convenient to use as well so I'll just install this package so that we can import these icons right um where are these coming from so you can just go to here icons.com right and for example we are looking for a home right so we have like this home over here and we also have one in like the solid format so we're going to actually use both of them right we are going to display the solid icon if we are on the home screen and we are going to display this one here if we are not on the home screen right we're going to do the same thing for every other page so um if you want to basically like import these icons like all you need to do is it's actually um ridiculously can convenient I'll just run this back close the terminal and then go inside layout okay so now what you want to do over here is right something like this so import from here I can react 24 and then we have two options outline and solid right for example uh if we want the home icon we can actually just import the home icon over here give it some class names like Tailwind CSS class names to set the height and width and like the color for example and uh we are pretty much done and I'm going to show you just um how that works right so um let's actually go over here right and over here what I want to do is um so I'm going to display this different icons right so for now let me just first show you how this look how this works right so I'm going to add some class names and over here I'll just say height of 6 worth of six right and let's go back and let's go back to our website okay this one did V restart the server we did okay let me re okay it's refresh now and now you can see this icon over here right like now we're going to style this a little bit more but uh you can see it's pretty easy to just import icons from the hero icons package and just use it very like okay uh cool but over here what I want to do is um I wanna basically uh import two sets of python right so I'll just say um home icon as um I can solid right and over here I'm going to copy this paste this but change this to solid all right so now we have like a homework and solid and we're also going to need other things right so we want to know where we are um so that we can decide if we want to display the solid icon or like the outline icon for that we are going to use the router um we can simply just say conf router equals use router which is imported from the next slash router right and once you're here um what you want to do is like this is going to contain um something called a path name right and this is going to be something like for example it could be just slash or it could be like slash profile it could even be slash login right things like that and um if you're wondering where all of this is coming from like you just you don't read need to really um remember like every little bit over here but you do need to remember that you have to Google something like next test router right once you Google this you're gonna end up over here um and you can you can sort of click this um and it's going to show you everything that's over here right so for example we have this router object returned by user order it contains path name which is a string and it contains the path of the current route file that comes after slash pages right um and yeah basically so we're over here and and what we're gonna do is um I'll go down over here and I want to do a couple of things right so first of all I'm going to add some class names over here right and I'm going to say uh this should be Flex right up Center um cap of 4 which is like 16 pixels we're gonna give it like some padding um so basically it's going to be a zero padding uh normally but in large screen so I'm going to give it a padding of my 32 pixels right like so now we're here now what I want to do is um I want to also change this into a P tag okay um so I want to basically uh change the styling based on if we are inside the home uh route um or not right and the way we're going to do that is we'll wrap this up right and we'll come over here and we'll say hey router dot path name equals slash right if this is the case I actually wanna use the oh I can solid we have at the same height and width which is like 24 pixels right so as you can see now we have like this conditional um icons over here the other thing that I want to change let's add some class names over here and this time I'm going to put it inside back text because we're going to be changing the font weight based on a weather based on the router uh path name right so I'll just say strategy this is like 18 pixels or font size and um then I'm going to add router Dot pathname equals slash and then this is true I want font wait hold right if this is not true I want um font weight as light right which is 300. okay now we're done uh we can go back um and over here now we have like um now we have this thing right so um there's something else you might notice like um so right now we are logged out of our application right and we can still see the sidewalk um which is not what we want over here right so we want uh to only be able to see the sidebar right which is part of the layout when we are logged in so we're going to change that in just a second and as you can see right now since you are not at the home path we uh the text is um like the font weight is 300 and this is an outline icon over here and it's going to change as soon as we log in and go to the home page right but first let's go back over here all right and um over here what I'm going to do is say if router your path me it's login right so if we are on the login page I don't want to return all of this stuff right uh all I want to do is just run a simple tab over here and um I want to have like the children which is going to be like everything inside the login page over here right so simply to turn this if not return this entire structure which contains the sideboard right now I'll save this go back and now you can see login page is clean we have no sidebar over here we can click sign in with Google it's gonna get us to the home page and over here we can see these icon is now solid it's filled and the font weight has increased uh to sort of like highlight that hey we are on the home page right now cool so now let's do that with um the other with the other links as well so I'll just actually utilize some of this all right I'll just copy um this over here or wait I'll what I'll do right now is I'll just copy these and I'll paste it two times right and I'll delete these two lines now we'll just change these right um so there's two things you want to change over here first of all this is like the pop marks page so I'm going to give it a route of Slash bookmarks this is not this does not exist yet but we are going to create it really soon secondly I want to change the icons right um so in case of bookmark you can actually like you can just like vs code simply gives you all of these like list of icons that are available so for example we're gonna go with like the bookmark icon from the outline package right we can just import this and um we can go um over here at the very top and what we can do is also import like the solid version of this icon so bookmark icon as book bookmark icon install it right and let's also um actually just import um I believe it's called like user something let's actually go back and check right so uh I'll just search for like user right and we're gonna go with like this one so it's called user uh we also have a user Circle but we're gonna go with this the solid version so let's go over here and say user icons right and we're going to import this as user icon install it and over here I'm going to just add user item okay cool we are now ready now we can go back here and I can add bookmark icon solid over here change this to book marks right and um change this to bookmarks as well and just go over here and what you want to do is replace this with bookmarks right so this is link number two now we can go over here and um I can just say slash profile over here right and what I want um yeah over here is user icon and um user I can solve it right over here we will change the route to slash profile and this one is okay we can just go back over here and say profile and uh we also need to change this route over here oh file right now we can go back and we can see we have like our file bar looking a little bit better oh right and I'm going to actually show you um what this this looks like and and like a responsive setup so I'll just expand this over here and what you can do is like you can slide this off and what did we want over here so this is like um the sidebar's width is changing as we sort of cross a certain screen width right but we also want to change this right so what we want is when we go towards like a mobile or tablet screen I just want the icons to be visible instead of like all of the text right and as we go over here you can see that we have like this particular div aligned um to the right hand side um right and it looks pretty neat right so uh we're going to keep adding like a bunch of things now over here but first of all I'm going to go back to my code and over here um what I'll do is I'm going to create these rounds right so that we have something over there right uh so I'll go and create new files inside my Pages directory one of them is going to be called bookmarks.tsx right the other one is going to be called profile dot TSX we can go over here and for now I'll just export um this function that will turn so there that says by profile right and we're gonna do like pretty much the same thing over here um right bookmarks and important box right so this is done we can go back over here and now we can test if this is working so if I click on bookmarks it loads up bookmarks in this content yeah and as you can see now this particular item in our sidebar is highlighted like with the icon and the font weight if you click on profile same thing we click back on home we are back at home right pretty cool um okay now what I want to do is go back to my layout right and work a little bit more on um on my sidebar right so something else I want to do over here um basically is I want all of these P tags to vanish when we are not in a large screen right and for that to work uh what I'll do is like I'll just add this over here so it's going to be hidden by default and on larger screens I want it to have um I want to be basically in line Flex right I'll just copy this through down here paste it go down here paste it done now let's go back to our browser and see what happens right so now if I shrink this Beyond a certain point it's gonna shrink right and now we have this neat looking sidebar which just consists of the icons right we can still navigate but it's just the icons the text is gone and it looks so neat right like now we can compress this all the way to mobile phones and it's still gonna work and if we expand back like all the text is visible this is how we are using um basically tail build um um classes to to sort of like come up with like a responsive CSS um really easily right so now that this layout is done we're gonna start working on this main area right like this content area so what I'll do is um we can get rid of these for now we don't need them I'll just close all of these files and we're here we seem to have someone saying changes I'll save them we can close this close this as well okay cool now what we'll do is will will work on the front end over here which means um of a sort of form that helps you create these tweets right and publish them and then a feed view at the bottom which shows all of the tweets right cool okay so for our home page let's first get rid of um all of this junk over here right like and now what I want to do is basically um we've already declared a main component inside our layout and all I'm going to do is like write a div over here and um now I want to change all of the CSS right um the way it's going to work right now as as sort of like this right I'll just put this back um over here it's really not necessary right now and the first thing because if you remember inside our layout we have the sidebar right like we have um you have this sidebar which has Flex string zero Flex row zero it's a it has like a fixed width right and this is the first child inside our flexbox the second child is whatever we are writing over here so I want this to grow crew into and expand into all of the available width on the screen apart from the sidebar right so this is going to be uh Flex row I want height create right and then I want um this part to be overflow I'll just write this out crop right um the key black right I'm going to give it a font color white now we can go inside this and now we can start adding in uh a sort of basic structure for everything right so at the top we're gonna have like a small header um this thing right clicking actually just right header over here this one is going to be um sticky right so it's going to remain on top as we scroll so we're gonna write sticky top zero going to be a flexbox um right and we're gonna give it a higher because all of the other content is basically gonna go behind it right so now once you're done with this like I wanna basically add another div over here and this one is going to have like a bunch of text right um so first up I wanna talk about width right so uh if we are in like a Mobile screen I don't want any space to be left right it's basically if we um go back to um trigger.com right right so what I'm thinking about is like this section right and this is sort of like the header right and we have like this section as well that's sort of like blank in our case and what I want is in in mobile screens I want the section to be hidden and I just want this to occupy all Optical right so we're gonna say words full over here or in large screens I'm just gonna say like well um okay by five right sixty percent of the available words over here um now once you're done with this uh we can just try it we can give it a height like 64 pixels over here I'm going to make it a flexbox I'm gonna say items Center um I'm also going to give it a border at the bottom the neutral 600. right um I think this much should be um okay right um but okay I I think I'm also going to need like some padding over here right so I'll just write PX4 over here now there's one more thing uh it's needed over here all right so if we go back to Twitter you can see that like you can see this sort of like classy Frosty effect right and that's basically like um what's called a backdrop blur right and we can simply implement this um so we can actually take a part like the exact blurring values from over here but what we can also do is you can just go to like Tailwind and search for like black backdrop blur right like so we have like the section over here and you can see it has like a bunch of values right like with varying the degrees of how much how much um do you want it to be transparent or not right like so we're gonna go with like this one right um and I'll just copy this class go back to my code and um okay over here uh I am going to paste this class and multiply Center and over here and what I want to do over here is just write home because this is the home page and I'll also let me style this up a little bit so we want a slightly larger font size right now we're done with this uh we can actually go back to you can actually go back to our browser go over here all right um and now you can see we have like this this section coming up right like in this there's nothing behind it so we can't really see like the sort of classy backdroppler over there but we're gonna be able to see that once we add some elements down here and we can basically like we start scrolling those elements behind this header button so I've got now I'm going to go back to my visual studio and I'm going to add a couple of more things over here so we are pretty much done with header now what I want to do is I wanna add like um add a sort of like editor right or a form where you can actually create your tweets upload the images and things like that so for that we're gonna add some basic structure first so um okay first of all I'm gonna add relative um and minus top 15 right why am I doing this because we have a height of 16 over here right like in a fee just add a div over here it's gonna be um foreign after this head right and I wanted to actually start behind the header so I wanted to start at the top of the screen which is why I'm using position relative and just moving it up by the exact same amount as the height now um over here I'm going to say vertical and flex and now that we are over here I'll just um add another tab over here I'm going to say uh again wordful so this is basically like us defining the section boundary like this Center section right so it's gonna occupy full width normally but on larger screens so it's gonna have like the same um 60 worth right row zero drink zero and go inside this right now over here um I think we also need like one more thing so this is going to be like the um the main box uh so to speak right like this is going to be the main main box inside where and we will have the create tweet section as well as like all of the tweets right so over here we'll just say Flex Flex column right we're gonna give it um because our um make our section over here like the section is actually starting from behind the header so we are giving it a top padding to avoid that avoid um putting our create tweet section behind it at the very beginning right like when when the screen loads so we're going to use uh padding top 16 main height screen and I'll just say border no you don't need any border over here right okay um now over here so this is where um I'm going to write the create tweet form right like we're gonna add this um up right and um once you're done with the form below this we're going to basically um like list out all of the tweets right so list of tweets over here right and we're gonna fill both of both of these up um but um but before that I want to actually uh finish out like the uh right hand side section as well so we are basically over here right like we're inside this okay this one this one is like the center section so I'm just going to create another Dev over here and I'm going to style this up very quickly this one is going to have a border on its left so border um neutral 600 right pretty good Flex crew all right so it's gonna occupy all of the remaining space which is basically 40 of like everything apart from inside one now I'll just say self um stretch so that it like sort of like stretches itself apart over the full height of the parent works and just add the same thing relative and then I'm gonna write like top 16 right so that it it actually starts um um below the character right um now once this is done we can actually um go back and we sort of have like this section over here right and as you can see it it Scrolls up right a little bit but we have like this um this one border missing over here that that I'm just gonna add um let me just give me one second okay looks good okay so what I'll just do over here and [Music] as we have this header over here right um and this is basically like this Center section of that header so what I'm do is add another over here right and this one um again it's going to be hidden and most of the time right um but on larger screens it's visible so um over here it's going to be in line Flex okay then uh we also wanted to have Flex group so stretch so stretch over the height of the header right and we're going to give it a border on the left hand side border color will be neutral 600. boom okay now we have like a consistent line over here right and this is our intersection where we're gonna be adding the created section followed by all secures right so this is basically your Center feed right and we're gonna follow this structure for other Pages as well because that is how Twitter does it but yeah we have like the basic structure in place cool so next we are going to um build components for uh these two things right so the create tweet form as well as like in the straws tweets okay so let's build the create tweet font I'll go inside my component directory create um this new component called tweet for TSX and over here we are going to oops default function tweet files right now over here we are going to be doing two things number one we should be able to write text and number two we should be able to upload images right for uploading images um part we are going to use is something called react Drop Zone right so this is a pretty neat package over here that you can use uh for basically um uh neatly handling the um the uploading of any any sort of files right for now we're gonna basically just allow the user to to upload only images right so PNG and and JPEG files to be exact uh but you can actually use reactor oxide to sort of create like these upload Drop Zones and like upload buttons for any sort of files right so we're going to be using this uh so let's go back to vs code open up our terminal install let me add Drop Zone I'll run the server again uh close this terminal and over here we're going to be using um using everything from like react drop zone right and for that to work uh basically you're gonna have to declare some functions right and and what that means is basically so let's just first import something called use Drop Zone all right so this is like a basic implementation of of like how react Drop Zone works right and we're going to have to uh declare a bunch of things over here right so the first thing that we want to declare is like a function uh handle drops right so this is basically um so this is basically going to uh get triggered when you actually select a file in your up when while uploading an image right so it's going to receive a list of files right and over here uh we're only going to allow the user at the moment to just basically upload one file per tweet right so we're just gonna grab the first file from that array and over here I'm going to write um const reader equals new file reader right okay now reader weird order report go back and say reader right cool dot onload now this is basically going to be a function I'll just write any over here for now and what this is going to do is um basically what I want to do over here is like I want to capture event dot Target dot results and what this is in case of images right is basically a base64 strain that represents the image and we are going to store this exact value inside our database now um this is not the most efficient way of storing images for your application right um because base64 strings basically consume roughly 33 percent or I I guess it was like 37 percent more data than required for storing the image rights for example if you're storing the image directly as a file it would require less storage but for now we're going ahead with like this solution um okay so now what I'm going to do is basically I want to capture like this string so what what I'll do over here is like I'll start declaring some uh props over here right first prop that I really want is going to be um something called like base64 and then set phase 64. right like this that's okay uh but we also need the types so I'll just declare them right here okay64 as a string right so this is both of these are going to come from like a u State hook uh from the parent component which is sort of index.tsx right um so that we can send the image value back over there cool uh so we also have like set page 64. which is basically going to have like it's going to take a value which is a string and then void over here now uh what I can do is um I can say set okay 64. and wrap this up all right now it's going to send the basics default string back to our parent object right uh once we're done with this um get this uh we're going to so this is basically like the onload function now we're going to say dot read um and we have like we have different ways of reading this file for now we're gonna go with like as data URL right and this is going to result um the base64 string over here cool so this is the handle um drop function over here right and um now we're going to use the use DropZone hook right so we're going to say we're going to get two things over here so we'll say get root plots right and then get input crops and we're going to say use Drop Zone over here we want to declare certain things so max files one right on drop we handle drop the function we just wrote and then accept right so over here I'm just gonna add like image slash jpeg right and I'm also going to add image slash PNG right and now we can use [Music] um these two props over here to basically create our upload button right before that uh let's actually add um a little bit of a structure UI so let's start with this step um what this is going to contain is like it's going to have like where to full I'm gonna give it like a border at the bottom neutral 600. we're gonna give it like some padding on the left and on the right as well right um and some vertical padding right we just want the left padding to be a little bit uh less compared to all the other paddings right so and we're gonna create a flexbox right now inside this I want two things one is like the user information so if we go back um and just open Twitter again you're gonna see that we have like this section over here where we have the where we have like the um the the user uh profile picture over here right and then we have like this area where you can write the tweet so we'll go back to vs code and over here let's implement the left section first so this is going to be all right um um I'm just gonna say like birth of 15. right and then three zero zero um I'm gonna give it like some margin at the right Flex Flex column and item Center right now once we're here we can basically add um an image over here right and um let's see so what I want to do is I want this to be rounded full all right and I'm going to give it height 12 width 12. next uh we need the source so the source is going to be like a profile image right where do we get this profile image from we're gonna get it inside the props right so I'll add it right here and then our type right here cool now um I'm going to do the same thing give it a height of like thousand world of like thousand and the actual height and width are going to be controlled from over here um I'll also add an ALT tag the profile pic right so this is I think all that's needed on this side right now I'm going to create another tab over here now this one is basically where you will be typing all of your text so um typically you might see um like a text area over here right but I want to use content editable tips over here and um there's a bunch of advantages as well as like complexities when it comes to using a Content editable div um for uh user input but if you sort of like if you if you look at like most places right like if you uh for example let's do an inspect element over here right and let's go over to this block over here um let me open this div up and okay okay yeah here as you can see like Twitter also uses like a Content editable div right for their text box um and you're gonna see this pattern in like a number of places like if you open for example in the YouTube comment text box things like that all right um now um one advantage that we're gonna see in just a second of using under the table divs is if you start typing in like tweets right uh so like hey and then you keep adding more things right the dev keeps on expanding right like this is one thing we're going to be taking advantage of but there's like other advantages as well right there's also a little bit of a complexity compared to using input element or text area element but I'm going to explain all of that um to you uh in in like a very simple way right so first of all uh let's go back to our vs code and over here I'm going to make this content editable I'm going to also add this suppress content editable warning over here right um okay now that we are over here I want to do a couple of things so first of all I'm going to add in class names um class names are simple so we need whole birth text should be a little bit large don't want any outline I'm just going to give it like um a part of margin over here um cool so um another we are over here I'll just save this go back to my browser go to localhost right and okay so we don't have this text editor inside our index um right now so I'm just going to import this first so that we can see what's going on as we write the code uh for our tweet for so I'll just replace this line and say tweet font right but we also need to pass in a couple of things right like this is why I love using typescript right like it basically like it's not gonna let you uh pass by without passing in like all of the needed things right so we need a base64 we need a sideways 64 and we need the profile image right like but we don't even have those things over here so let's actually go ahead and declare them right so I'll go at the very top of this function right like we have these things if we actually have a profile image already in place so it's actually uh go ahead and add a64 set piece 64 and just say you state string boom um and we're gonna fill this up right like we're gonna be uh using these things um and okay we also need uh let's go back over here um scroll over here you have uh do you have a profile image and we have like these two things okay these two are like the image Okay Okay cool so we have like profile image and these two things this is basically like the image that gets uploaded and new to it right that's what this is um okay so let's actually go down over here and start adding these things right so we'll just say profile image equals profile image right um and over here I want base64 equals space 64 and set base 64 equals set phase before right um now we can go back to our browser and we see we have like this sort of like area shaping up right now I can click over here and I can actually write stuff right and this is without any input element right so this is basically just this content editable div right and we can even like add more lines for example right uh point a whatever right like you can keep adding stuff you can um add emojis right so I'll just add this for example and all of this works right like you can see as we keep adding lines the dev keeps expanding as well smoothly and we're basically we going to using we're gonna use this content editable diff um as our text work right now let me go back over here and let's start adding some things uh to this right so um the first thing that I want to add is basically um an on blur function right so something that's very tricky to do is typically uh you would have like an input element over here right like and you would have a value write something and then you would have like an all change function that keeps changing this value um doing this in the exact same way in a Content editable tab is pretty tricky so we're gonna what we're gonna do is we're gonna let the user write whatever they want to write right and We're Not Gonna Change any state throughout that process but once the user um focuses out of that tip right which is basically when they click submit or when they click anywhere else or whatever like anything happens basically on the page other than the user typing something down this callback function is going to be called over here what I'll say is I want to basically um capture so I'll just write set text over here Target dot inner HTML right so this is going to contain like the a proper HTML code because we're actually writing stuff inside a div and not inside an input element right and we're going to capture it inside this set text right um where do you get the settings from again uh we're just going to add it over here right so um I'll just for example um I'll actually just add to values over here right so text set text um this is done and over here I'm gonna add text string set text value string White boom okay we are done with like the section and it's going to basically capture like whatever has been typed inside of this content editable tip right the other thing that I need over here is like when the um when the user uploads an image right like I want that image to be visible right like um similar to how it works on Twitter so over here what I'm going to do is if we have the image uploaded we're gonna have something in this base64 value right and what I'm going to do over here is the square the desk right um and if this is not present I'm just going to return well and over here I'll just say relative [Music] um I'm gonna add some bottom margin and we'll see how this goes right over here um the reason I'm adding relative by the way is because like each image is also going to have like a small cross button so that you can um sort of like unselect that image if you want after you've you've sort of selected it uh why you are writing the tweet so um what I'm going to do is like I'm going to create um so this this is basically going to be like the I'm going to replace this content right but this is basically like the cross icon over here um let's actually give it some like styling so absolute and top four right and then I'm gonna say left four so it's going to be at like the top left corner at least let me write write for okay um height 8 worth 8. Flex item Center just to keep the cross at the very center of it um and uh I'm also going to add like some other things over here so um okay get rid of this now um I want this to be a full circle so rounded full I'm going to give it like a black background with some opacity so that um it looks like a neat little close button on top of the image right I'm gonna say uh on hovering I wanna have opacity 40 right so a little bit of like when you hover on top of it it becomes just a little bit lighter and looks good right so I'm gonna go with like cursor default because now we're here um instead of X I'm going to just use like x mark icon yeah text Mark again right like what's the x mark icon well we are importing it from here icons you can just check it over here we have like this nice x mark over here right let's we're using this instead of just typing in x um and over here I'm just gonna write five four but four okay this is done now I'm going to add the actual image um over here so um let me add all of the things so first of all we need the image so this is going to be Basics before right then we need um some class names I'm gonna add like a large border radius and I'm gonna give it like four minutes next uh we need height for thousand birth cousin again um an old I'm just gonna say loaded all right so it's gonna basically uh throw those image and we can't see any of this right now because we haven't added an upload button so let's go ahead and add that so that we can actually test this out I'll just go below this create another tab and I'm going to add the following class name so with full Flex item Center um and then justify between right and over here um just the stiffer between is gonna basically put um the upload image icon and the sort of like submit button on on two separate ends on like the left and right and over here I'm going to the set of um and this is where um our Drop Zone starts coming in so we actually have like two properties over here right we have like input props and we have root props so this is sort of like the root diff we're just going to do um get root props over here and inside this root props we can actually pass in like extra class names I'm gonna say over um like uh 900 right otherwise it's gonna be um it's gonna be like white and I'll just say this one is like it's gonna have like an opacity of 30 percent right I want this to be rounded pool so this is basically gonna become like a sort of blue a blue uh circle with like um 30 opacity right and basically uh we are going to um so we're gonna need actually like a couple of couple other classes over here as well so I'm just going to write um like give it some padding or server pointer and yeah of bit content right okay now uh we can go inside so this is the root Dev right now inside this we can actually declare an input element right over here um we can just say get Imports so done right and now we're also going to add like a sort of photo icon right now photo icon basically photo all right so it's going to look like this right which is pretty cool like this is what we want inside our upload button go back over here last name I'm gonna give it like this blue color we're gonna give it height 6 width 6. done the other thing that we need is sort of like the submit button we're gonna style it um and a little bit later okay um okay I'm going to delete this and see if everything is all right because there seems to be okay now this is fine you can save this now right and now we need to pass in these extra props from over here right which is why we're seeing an error so uh we need text and we need like set text now we don't have both of these so I'm just going to add another state over here right and um basically this text is going to contain like everything that like all of the HTML content from within the content editable tab which is where the user will type everything so um okay so over here I'll just write um text set text new state right boom this is going to be the body of the tweet new to it done now let's go back to our browser and okay so we have some things over here it um we've missed some of the styling but this is basically like the Bottom bar right um so now what I'm going to do is basically um okay let's actually go ahead and like fix this first so um okay I'm gonna go down here and I'm going to go inside tweet form right and inside tweet form we um we sort of have like so this is sort of the um like the Bottom bar over here right like this is the Bottom bar and it actually um it's inside of like this is one sidebar this is Wonder it's inside of this massive div over here and what I want to do over here is just make sure that we are not using any extra Flex boxes all right let me actually um do something over here right so what I'll do is um we have this content editable tip right over here and this one okay yeah these are all inside of the flexbox that is not gonna work so let me just add another demo over here and um it's gonna wrap everything till here and I'm just going to say Flex Flex um column right and I'm gonna add some Gap over here and let's see what happens we're gonna go back over here and now we can see we have like the stuff I also need to add like something else over here so um let me see over here I'm gonna say Flex Pro right so that it occupies like all of this space and um I believe the added Flex goes somewhere else instead we didn't add it anywhere okay cool um okay that's fine now we have like all of this all of this all of this over here and what I'm going to do is basically just say um what does this do um item stretch right like this sounds good okay okay cool now we have like um the structure in place right so we're gonna style this submit button um and in a little while but over here we can type some tweets right and we have this upload button as you can see it has like this um this blue circle when you hover on top of it click on it and again basically um just select an image and click open and now boom we have it over here and this is the image that is going to get uploaded when we click submit and basically post this tweet out and you can see we have like this small cross button over here right uh the one we implemented right over here right like this one top fold right for absolute positioning boom this is what this is and if we click on this we should basically be able to um remove this image and that's actually really easy to do so let me just add that over here I'm going to say is on click set base 64 to Boom I can go back here and over here what I'm going to do is also wrap this up and just say that hey if we have base 64 right like I'm gonna display this image and otherwise we don't need this okay we actually had this already I'm sorry I'm just just remove this remove this boom we're done now if I click cross the image is gone right like if I I can I can even go ahead and upload a different image over here right so this is looking pretty neat already we are getting close we also have our profile picture over here and we're gonna add some functionality to change that profile picture so that this actually starts looking really good and you can also see when we scroll right like when we scroll over here um it goes behind our header bar and sort of gets blurred right which is what we wanted okay let's go ahead and finish up um finish up this this form over here right so now what I want to do is basically uh okay let's dial this button up first so I want background blue 500. right if I hover on it I want the background to become a little bit darker so I'll just go with this one Point hold right I'm gonna give it a width of 24. I'm gonna give it a height of 10. let's um Center this device enter I think this is this is pretty much like more than enough right let's actually see what's going on over here okay so we have this we also need something else rounded well both now it looks like a good uh like like the Twitter buttons over here right and um I'm gonna add something else over here so if I go and look at Twitter there's there's basically like they're not gonna be using like or implementing all of these things we're just gonna be going with like media over here so um I think this is like good enough for now now uh I'm gonna add some on click functions over here right um and on click is gonna do a couple of things let me actually just write submit over here right submit and we're going to Define this function over here so let's go back and basically just say async function submit now over here we will actually be doing a couple of things the first thing we want to be doing um a react state use state and it's gonna have like Boolean values right and it's going to start out as false so this is basically like sending is gonna hit the create tweet API that we wrote earlier and it's going to take um it can take a little bit of a time right so it can take a couple seconds for example and during that time you want to display a layout loader over here so um okay so what I'm going to be doing is is like uh we're going to be setting this state um to true and displaying a loader uh while the request gets processed so I'll just write set sending to true over here um I can actually do like uh I can actually do the uh like hit the create tweet or create post API right like this one once this is done basically set text to blank that a64 to blank right [Music] um okay um there's also this other thing right like this is actually not needed because um the content editable div over here it doesn't really um about the text state right um and that's because um this is not an input element right so we're gonna have to do something else to reset the state over here and I'll get to that in like just a little bit so I said base64 just remove the image and then finally set sending to First cool um what I'll need over here is like a function so I'll just write on submit for now you async function because we're going to be hitting API so I'll just ride um wait on submit over here and what I'll do is I'll add that as one of the problems right so I'll just say on submit over here I'll say on submit and this one is basically um a simple function right this is done um okay so this is all we need over here we're also going to need something else um okay so this part is is sort of done like what I want to do now is go inside this button right so we have this submit just over here but instead what we want is like if basically if the if if we are in the process of creating a new tweet what I want to do is like uh first of all I want to disable the button right so extending is to disable the button secondly um I want to add a loader over here right so some loader and if that's not there I wanna say submit cool um now what we can do for this loader thingy is basically um if you go to Tailwind right let's go to tail event and let's there's something called uh thin animate this one right so this this is pretty much all we need so it's basically like just a div um that's uh that has this class right like and it has uh some borders right and it's basically just just using those borders to um like uh it's it's spinning so it looks like a loader right and instead of like writing all of those classes over there what I'm going to do is just um copy it over because um and and then just explain it instead of typing them all out right so I'll just go back to components go to tweet form over here and basically go down here and this is the loader right here copy this and go back to this place right now I can this over here right so all it does by the way is we have like um a border worth of two pixels it has like a height and width of 20 pixels we have border white and we have like we've made the top order transfer right so when it spins it looks like like a sort of like a disk that has three quarters in and it's sort of spinning right and we have the Border radius to like maximum okay um now this is done we are we're pretty much done with like the Tweet form right like but now we need to go back and actually um to like connect it to the apis right so over here we're gonna write an on submit function right and um what I'm going to do is basically um we're gonna Implement these functions over here and there's a reason for that and the reason is basically we are going to be using the same tweet form for um getting the users to enter their replies as well right so if they can enter those replies then we're gonna be needing a sort of like different function over here and that is why we are we're sort of extracting it out as a prop so here over here let me just write something like tweet right like and let's implement this function so let's go all the way up over here and you say async function tweet now what I want to do and tweet is pretty simple like you already implemented the apis or response is await fetch slash API slash post right over here you want method is going to be post because uh we're using the post endpoint um headers this one is going to have the same content type equals applications last Json and now we need to add a couple other things body and we're gonna say like Json Dot stringify we're gonna add our object over here so what we need inside the body is is basically this right so we're going to need um text right or we don't even we don't actually need the text we'll just write um body text right so um basically what we can do is we can just open up our schema and see what's happening over here right so we need body we need the image and we need the user email right everything else can be left alone so I'll just go over here and say body as text um um what else so we have like user email right and this one is going to be session dot user right and then we have an image image is going to be basically before string that we collected earlier now this is done you can go out and you can just say reach if response dot status equals 200. and if we are done we want to do um I'm gonna do a couple of things right like so number one we're gonna fetch the tweets right because we have added a new tweet we want the feed to refresh the other thing is um we need to reset the Tweet font right um and we can't really reset the content editable easily but what we can do is use um are really useful property of react something that is usually um sort of ignored or are not put into Focus right and that is basically using the key property right so I'll just what I'll do let me declare a new state over here that says e right use state number and initialize it to zero so this is key of the Tweet form component let's go down here all the way over here and add this key right so typically we only add this key uh when we are iterating over an array right like when we are training over um some array and creating or rendering of some components out of them right and you just like uh like to add the ID over here but there's this unique thing about key right like so if you change this key right it's going to basically re-render this component right that's a really useful property of react to know and we are going to use it because once we re-render this tweet for um it's gonna um it's gonna basically empty out uh like uh the image that was there um like it's gonna empty out the image and it's gonna empty out the content editable text that we had over there right so now I'm going to go over here and I'm going to just say instead um key to key plus one right boom and now the um form is at least going to reset right like and all of this is is pretty cool um now let's actually test this out over here so let's go back to our page um and before I uh write this what I want to do is go into our database right so we created this database if I refresh this I should see a couple of collections over here right so now you can see a post collection and a user collection now this collection is right now empty because we haven't created a single post uh the users collection is has my um uh sort of like user object over here or user entry over here because we have logged in using my Google account and once you create a tweet it should show up over here right so let's go back over here and let's just say hello click submit the loader shows up right and now Boom the uh the Tweet form has reset right like this is now blank right and that's because the key has changed now let's go back over here refresh this and we should see a post right oh right body hello world image is blank and boom we are uh we have successfully created our very first tweet uh now all we need to do is basically fetch the tweets and show them over here so that we have a live feed um of all the tweets that have been posted thank you okay so just to display um every tweet we are going to make another component so let's go back to our editor um components directory and I'm going to create a new file and I'm going to name it this on tweet box and CSX right and over here we will basically be creating this component that contains the body of into it right and the image if it has an image right and then it should also have uh all of the buttons uh for example uh the like button The Bookmark button um there's also going to be like a button for retweet but that's not gonna be functional uh for uh this clone and um then if you also wanna um add some Behavior should for example if you click on the post we would want it to redirect to um a sort of tweet Details page right like a like a section where you have just that tweet and all of its replies in place right so what I'm going to do over here let's first of all let's just create an empty component fault over here and um let me first um just give this some styling so I'm going to start with some padding and then I want a border at the bottom with um neutral 600 so this gray color I'm going to make this a flex box right the reason we are making this of lexbox is because if you look at um any tweet we basically have like this section that contains the profile picture of um of the person who has tweeted right and then we have all of the content over here right so I'm going to create one uh element for this and then another box over here for this right okay so for the first element what we need is uh I'm just gonna add I'm just going to give it like a fix to it so we need to add shrink zero zero and I'm going to give it some margin at the right so this is basically we are simply following um the exact same pattern that we were using over here by the way right like um I can actually just let me just copy this right um and this is because we want all of the spacing to be consistent with uh whatever the spacing was over here right we had the same thing inside Builder form sorry tweet form component right so we have like the section and then we have like the rest of the section so I'm going to just copy this um over here the space does you need to import image from next image and we don't have a profile image here this is something we are going to receive um over here right so um for now let me just um a lenses leave it like this and then we'll come back and and add this uh somewhere in the props right so we have like this um this is like the first child inside our Flex container right now um I'm also going to add the second section which is going to have Flex Pro and over here what I want to do is basically um there's going to be two parts to this like one is going to be the um area where we have um the name as well as the username printed out so I'm going to use a P tag for this and over here I'm just gonna add um I want to hold and over here um we're gonna need the name right and instead of actually like doing uh adding all of like these props what I'm going to do is like I'm just going to consider um us getting like all of like the user data right so user over here is the person who has posted this particular tweet and we're gonna get all of their information inside user data um started one thing the other thing we're going to need is the post right so this contains like all of the like the tech tweet body um as well as like the image um the likes the bookmarks all of that stuff right I'm going to give it I'm going to give this some types so over here what we want is um user data right and this is going to have um um the type of user right so we already our Prisma client already has defined a type for user and it contains the exact same like it follows the exact same schema that we defined earlier so we have an ID name username email created ad updated all of that stuff right like so you can simply just use that and over here I'm also going to do the same thing for postdroid so we have post over here from Prisma client just import this and boom built up now what I'm going to do over here is basically um instead of saying profile image I'm just gonna write like user data dot profile image um and there will be we're gonna also add a string over here to get rid of that typescript error and now what I'm going to do is instead of name I want user data dot name right and then so this is one part of it I also want like the username right so over here I want uh Point weight to be a normal or 400 right I am going to basically change the color over here as well right and uh what else also gonna give it like a little bit of margin on the left hand side and over here I want to write at the rate and then user data dot username cool um okay now we're going to define or essentially render all of the Tweet body right so everything we stored from our tweet form which is basically in like it was um in in an HTML format right um uh Arduino if it was in an HTML format well um okay let me do this right so let's go back to our this place right and let's say we um adds uh we we write like a uh sort of slightly longer tweet so let me just write like something like Hello World um this is point one this is 0.2 right click submit it's gonna basically um show us the loader and it's submitted it and now let's basically go back to um let's go back to our mongodb right so that we can see uh what's going on over here this is going to take a second to log us in and now what we can do is go inside Twitter DB post right over here and again see we have like these divs um and like all of these like HTML tags over here right like so this is the content that we just submitted right so this is the Tweet we just posted and as you can see this is sort of like this is an this is the HTML from inside the content editable tab so what I'm going to do over here is basically um so what I want to do is um I wanna basically set the HTML inside of this div right so I'm just going to write HTML post dot body um right and what this will do is it's it will essentially um if we go back here it will put this entire HTML inside of this div right so it's going to get rendered exactly the same way all right um now whenever you're doing this like the reason it says dangerously dangerously said in our HTML is because this can lead to um some issues right and this can lead to some issues if you don't have checks on what is being fed over here right the value that you are giving us in our HTML right you could have given a whole bunch of problematic values over here so it's important that whenever we do something like this we have checks on the value that is being sent over here in our case it's like the post body which means we should um we should just make sure that the Tweet form where the user enters this value right and gets saved um has um like some checks just to make sure there's no like scripting attacks and things like that but for now let's uh just keep this as it is and I'm also going to add like some margin at the bottom and over here I'm now going to add like if the post has an image right so I'm just gonna say as the image is not black right then I want um an image otherwise I want null and over here um over here what I'm going to say is first of all I want some class names class names is going to be worth full rounded Excel right and then I'm going to add the source which will be as you can probably guess post um image right we are also going to need so we're going to set up width of 1000 height 1000 all tag um tweet image and add ice cream over here okay cool um so this is basically like this portion over here is the name and the username this portion over here is the body of the tweet this portion over here is like the image inside the Tweet if it has an image okay so now we're done with like this portion uh the other thing we probably want to add is um basically uh we're gonna add this container for all of the like um read tweet reply all of those buttons I'm just gonna say uh I know my cap 12. we're gonna give it some padding on the top right and add some buttons over here all right so when I say button basically what you want to do is um so it's going to have something like this right so uh we want some icons so first of all I'm gonna just go for my uh I'm going to choose an icon over here from like my hero icon package so um let's sort of go ahead with like this one right chat bubble um left Ellipsis icon right and and we're gonna um okay so we're gonna need two things over here so I'm gonna going to first give it like some height and width right but we're also gonna add like the number of replies this uh post has so uh let me first change this button into a flexbox right so Flex item Center Gap two and on hovering I want the color to change to 500 blue 500 right now once we're done with this we can go all the way over here and um over here what I want to do is just write post dot um comment IDs right dot length so if you remember um if you remember uh basically our schema right or we can even check the same thing over here we had comment IDs inside our post um object or post entry and this is going to be uh like a list of everyone who has commented under this post or this tweet and we can simply just check the length of that that array to get the number of replies um this has right now we're done with this I'm just gonna uh add other things over here as well right um okay so the next thing we need is sort of like this retweet icon and for that I'm just going to replace this with like um there's let me go back over here um open your icons and sort of like look at this one right so we need something like this right and uh I think there's like a better version of this right so Arrow um yeah we're gonna go with this one right arrow path rounded Square all right so let's go back to our editor and over here I'm going to replace this with our path download Square icon over here and for these two what we want to do is like they're going to represent the like and bookmark buttons right so over here we can for now I'm just gonna add like heart icon um and over here I'm going to add the bookmark icon right but um what I want to do is like basically conditionally render the heart icon right so if we have already liked this tweet I would want uh the heart icon from the solid uh package right so the field alt icon and if we haven't liked it it should show the outline heart icon right but for now let me just add these and check if like structurally we have um done a good job and over here for uh basically um so we're gonna add like other things over here right uh for displaying how many how many likes does this post have or um how many bookmarks does this post have because both of them um are going to like these numbers are supposed to change pretty quickly when you click on this button so we're gonna add some logic over here for now let me just write some random numbers over here so yeah something like this um okay and um okay in fact um okay this is fine for now right like let's let's leave it at um let's leave it at this and now what we want to do is in order for this to show up I'm gonna go back to my index dot TSX and over here instead of this list of tweets we are going to basically um do a mapping right so um till now I don't think we've fetched all of the tweets yet right so I'm going to do first is write a function to do just that so get complete all right and what this is going to do is it's going to call the API that we created earlier so slash API slash post right and this one is going to be a test request um over here we can go back and check so basically what you're doing is we are finding all of the tweets from our database we are ordering them um in descending order of their created at timestamp we are also fetching all of the corresponding user data we are returning all of that back over here right so um let's go back to index.tsx and over here if this spawns start status equals 200. you can just say await response Dot and this data is supposed to contain like both tweets and and the user data right so I'm going to do over here is the same like tweets set tweets use state for the type we can again use a post from our Prisma client um in fact this one is going to be an array of these posts so you can just leave it at that and you also have like um tweet user data and set tweet user data this one is going to be an array of users cool now what we want to do over here is basically let's just check what we have inside our apis basically once the system we get posts and user data so what I'm going to do is set tweets to data dot post right so this particular value and then basically um set tweet user data to data dot user data right now so we have what we've done basically is fetch we've fetched all of the tweets and we've asked we have basically set them inside of these things right so now what we can do um as we can call this function um over here first right so I believe we had a use effect somewhere over here right okay so once this is done right like we've uh created so if this was a new sign up we created a new user if it was not a new sign up we basically just um retrieved the username and the profile image right but now once this is done we can what we can basically do is is just say await get tweets right and we're gonna add some loading over here as well because this operation is supposed to take some time because we're fetchings uh we are supposedly fetching a lot of data from um from the database so I'm just going to add like this state over here right so as soon as the page loads this one is already like we're already already gonna show a loader over there um yeah once um this is done right like once this is done what we can do is basically set loading back to false now um okay so we have the tweets over here what I want to do um is basically make sure um that we have like the list of tweets along with the loader showing up over here the first thing I want um is if loading on a basically um basically show a loader over here right so um okay let me just Define a parent container first this one is going to be Flex um this device enter and give it some padding and uh okay if not uh we're gonna add the loader over here by the way so let me just write loading or not if not what we want to do is basically show all of the posts so if this is not as if this is not the case then um what we want to do is we put this in another line over here and what we can do is we can just say posts or not we have tweets dot map right and over here um I'm gonna basically say uh yeah there's gonna be like a value or so we'll just say something like post because of type post right underground also on also gonna retrieve the index right and once this is done we can map this over here to our tweet box all right tweet box is um coming from component slash feed box right the entire component that we just made for displaying all of our tweets now we're gonna add all of these all the props needed over here so if you hover over it you can see we need a user data and we need post right um so what I'm going to do is first of all because this is [Music] um we're iterating over this array so we need to add a key so I'm just going to add like post dot ID over here right um then we basically need the post so I'm just going to add the post and over here I'm also going to add user data equals user data right um okay we don't have the user data because we need um something like this cannot find yeah tweet user data yeah this one boom okay so let's go back and see what's happening so okay so we already have like these two tweets showing up right and we have like these buttons nicely showing up starting to look a little bit like Twitter now um Let me refresh this page right so we have loading and then these tweets show which is exactly what we wanted right so we wanted the loader to be shown like this when the tweets are being fetched from our backend once that is done please show the tweets cool and we have like all of these buttons now we're gonna make these buttons um functional as well um but okay so the um we're also going to add some more to each so that we can see what's happening when we scroll up but first um let me add let me actually add like a couple of functionalities over here so let's go ahead and implement the like and bookmark things first right so um when a user clicks on like or bookmark the first thing that we want to happen is for this button to get set right so we want this icon to be replaced with their solid counterpart instead of the outline one right the solid variant um and the other thing is we're gonna have to change some data in our database right so if we go back over here and we hover on post right so this is our post and we have liked user emails bookmark user emails and we're not gonna deal with this right now so what we want to do is add the current logged in users email inside the like user email or the bookmark user emails depending on what they are clicking right so in order for that to work we also need to pass in the current user email right so that is basically inside session dot user dot email we can go back over here and we can add this inside our prop as well see user email type here string done okay now we can actually implement the like and bookmark functionalities over here so let me save this go back over here and the first thing I want to do is basically import like the solid variants of the icons as well so heart icon and I'm going to write part icon solid and then what I want is bookmark icon as bookmark icon solid cool um next I want to basically Implement what happens when um when the user basically clicks on like the like or um only bookmark button right and before that so we're gonna do a couple of things over here so first of all we're gonna Implement some functions so for example the like function right um you're also gonna have async function bookmark right so these are the functions that we're gonna attach to the on click um inside our like and bookmark buttons but before that I also want to declare two states over here it's like emails um and I'm gonna say set light emails and over here I'm going to say state an array of strings and we're gonna initialize this with post dot like other emails right looks like we have it imported used it done now I'm going to do the same thing for bookmarked emails as well note that you can also use like the user IDs over here instead of like emails but um since we started out with like identifying a user based on their email because of my Google authentication I'm just going to stick to that for now but typically you can just replace like this with user IDs instead of like the user events over here right um cool so once you're done I'm gonna add post dot bookmark user emails right now over here I'm going to do a couple of things um okay let me just create like a new like um user emails object over here right um and if post Dot like user emails dot includes user emails so what we're trying to find out is is first of all has the user um has the user already liked this tweet or not like and if they have like this tweet their email is going to be inside the post dot like user emails all right right so we're checking for that um and we're gonna create two cases based on this so if they have already liked this email then what we want to do um is actually um so over here we're gonna remove the like right and over here we wanna basically so we're gonna implement this part first um over here what we're gonna do is dot dot host dot like user emails and we're gonna add username over here right and over here what I'm gonna do is basically just say new like user emails equals um boost dot light username and I'm going to filter this right so um we're going to use yeah we're going to use filter over here for this uh what I want is basically all the emails um that are not equal to username right let me actually add some console logs here so that we can we can see what's going on cool now once this is done what we're going to do the first thing is we're going to set this uh inside our state so that the button numbers can get updated quickly right and then we're going to send a recipe request right so I'm going to explain this flow in just a second let me first write down the code for um sending the request right so for this we're going to need another API that we haven't created yet right so what we want to do is like create an endpoint API endpoint for liking a particular tweet right changing the database numbers such that uh the current user's emails get gets added to the post liked emails like user emails um value right and over here I'll just write there's going to be a post request right so it's gonna have headers and this one is going to be content type application slash Json over here we're going to have a party so Json dot 25 and um we're just going to give like host.id over here right that's what we need to identify the post inside our database and we're going to send the light user emails with this new value right and once this is done we're gonna check if this worked right so response dot status equals 200. we are going to set um like emails back to the updated value from the database right cool the reason we are um the reason we are doing it like this right so what we are doing over here is first of all we are checking if the user has already liked the email right if yes we are updating the state over here um we are updating this state so that the changes get reflected in our button down here right in the icon and the number over here they get reflected immediately once that is done we send a request to um our like API so that it can make changes inside our database and um if the changes to get made nothing is going to change because data.post dots like user emails is going to contain the exact same set of user emails right that we set over here but for some reason if um it did not work right like we're gonna basically um we're going to uh set the um this state write emails back to what it was so that the user knows that there was for example a network issue or anything like that and when they clicked like it did not actually get registered all right so over here I'm just going to um okay we haven't defined data so I'll just write that down yet response dot Json cool um okay once this is done what um so this is sort of like what is going to happen when we click like some now let's change like this like button over here so I'm going to go down here and just say like emails dot length over here I'm going to change this icon to something like this what we want is if the user has liked um if we're gonna determine if the user email is inside the state like emails and I'm just going to Define like a quick function over here is liked and what this is going to do is it's going to return liked emails dot includes user email great and now let's go back over here and say is liked right if true we are going to use the solid icon with the same height and width if not if not we are going to use the outline icon over here right and this number is going to also update pretty much immediately now in order for this to work we need to create our like endpoint and we need to link this function right so what I'm going to do is go over here and let's see on click is basically um like um and I'm also actually I'm going to I'm going to do another thing over here um let me just leave it as it is right now and we're going to add functionalities as we proceed but for now basically this points to like so now the next thing we're going to do is create um an end point and we're gonna name it like dot TS inside our API directory so over here um the first thing I want to do is basically like copy this stuff right to create a function for a protected API route so over here and this is cool this is done [Music] um and now what I want to do is if request dot method equals post because we're only accepting post requests over here right if this doesn't work then I'm just gonna say something like I'm actually not gonna return 200 and I'm gonna I'm just gonna say um correct request okay over here um what we want to do is pretty simple so um we're gonna say cons post equals await Prisma dot post dot update and we need two things which post do we need to update the post with this ID and then we need the updated data which is going to be we just need this a little bit 40 dot like user emails done um now once this is done what we can do is we can just say res dot status 200 dot Json and we can just say um I'm just going to add a message here as well and I'm just going to say post cool so now the API is already um and we can go back to over here what I what we can do is let me just refresh this we have the loader we have the tweets coming in now we can we will be able to click here and as you can see it immediately gets updated right the icon gets filled the number gets updated and the request is sent after that once the request is sent we can actually go back to our database and we can check FF like that really worked so I'm just going to refresh I'm going to go to mongodb and refresh um my page and so now if we look at particular post you can see that we have added our email to the liked user emails which means the functionality worked right but we instead of waiting for uh the request to get completed and the database to get updated we actually updated this area first and in case the database doesn't get updated for any kind of like Network issue or any API issues uh we like this number would have gone back to zero and the icon would have gone back to uh like the outline icon right ah pretty good now we are going to basically do the exact same thing for the bookmark button as well so let's go back to tweet box and over here uh I'm going to basically uh copy this function first and just say bookmarked over here this is going to be bookmarked dot bookmarked emails I'm going to create a similar function over here um let me just copy this and just say bookmark coupons is declared okay we already had a function okay done um now over here what I want is new bookmarked user emails I wanted to change it let me just copy this right and change this and remember all right and over here I'm going to say bookmarked user emails and instead of hitting the like endpoint we are going to hit another endpoint uh called Pokemon um and over here we need set bookmark emails book not user emails right done so um that's all that's pretty much all the changes that are needed okay we also need like some other changes over here so instead of liked user emails we need like bookmarked user emails right and we are going to copy paste this in all of the places like so um okay looks like you're done and we can do the exact same thing what I'm going to do is add this as the on click function so bookmark on click equals bookmark and over here uh we're going to replace this icon foreign bookmarked um bookmark icon solid and add the class names H5 W5 and you can now replace this number with bookmarked emails dot length okay now let's go to our API directory and create another file called bookmark dot TS and let's copy okay I messed something up let's copy everything over from the like endpoint and just change a couple over here so instead of bookmarked emails uh light using emails what we want is bookmarked user emails with Mark user emails over here as well um and that's pretty much it we're sort of done let's go back and see if we can bookmark something right so let's click on bookmark um okay for some reason it triggered this as well so that means we've missed something let's go back to um our tweet box component and check what's happening over here right okay this is why we actually triggered the liked emails uh update as well because we need bookmarked set bookmarked emails over here um let's just go through this one line by line just to make sure we haven't missed anything else we have this we have this bookmarked bookmark um okay let's go back let's click on this bookmark okay now this works perfectly um if you click back on it it basically um unbookmarks it as well right and we can go back to our database and refresh this page just to verify that our data has been updated accordingly so if I go to my bookmark user emails like this one is now bookmarked right which is this to it and over here we basically have an empty array so this one is not bookmarked anymore cool so now we have completed the like and bookmark functionalities um the next thing we are going to do is basically um going to be the Tweet Details page so what we want is if we click on any of these tweets over here we it should um it should open up that tweet along with all of the replies um in this layout right great okay so the first thing we are going to do is go back to our editor and we're going to create a new directory inside our Pages um directory right and this one is going to be named or just do it right click and inside this we're going to create a new file and we are going to name this tid and square brackets dot TSX right so basically if someone clicks on a tweet we want them we want to change the url right we want to go to something like slash tweet slash the Tweet ID right something like that and in order for that to work we basically need a new route that we've just created so let's fill this up now support default function tweet yes and fill it up with this great now uh the first thing I want to do over here is um okay let's start by defining like some of the structure but before that what I want to do is retrieve this tid over here so does tid represents the post ID and we're going to use this ID to fetch all of the details all of the replies and every all of the images like everything related to this tweet from our database so let's just first get this tid the way to do that is by basically using um um not request dot query router dot query right we don't have a router object yet and we're going to Define it over here using the use router Hook from Nexus great so now we have like the tid with us what we can do is we can use this um tid to get data from database right using an API um now let's get back to these divs and over here we're going to basically um do a couple of things right so first off I want to say um at screen overflow y roll and I'm going to have this as Flex screw because this is going to be um like this entire area right like apart from the sidebar so sidebar like we have a parent Flex um container over here and basically the sidebar has a fixed width and everything else is supposed to be occupied by whatever is there on this particular route so over here we're gonna write Flex group uh give it a black background and a pointer of white now let's go inside this and declare another detail worth 100 flexbox and inside this so this is basically uh our header and what I'm going to do over here is um just declare like um the center portion of the other what do I mean by the center portion this portion right where home is written and instead of home we're gonna write like tweet over there and we're also going to add a back button um Okay so let's define border order neutral 600 give it like padding on the left and right side and okay before this let me actually it's actually render this page right so that we know what we are doing with our CSS so let me just write um this all of this is fine let me just write tweet over here cool now um I'm gonna go back to my index dot TSX and over here we are going to do um what we're going to do is we want this tweet box to be clickable so I'm gonna just say on click equals this is how you can programmatically change the route right you can just do a router.push but we don't have a router so we're gonna have to declare it um at the very top over here const router is user router let me actually put this above right so now that we're here we want to go down and over here I'm just going to say um flash tweet slash the post dot ID right so this is the exact route we want the user to go to when once they click on this right this does not have a non-click function yet so we're going to Define it over here so I'm just going to say on click and click is basically this function right and now what I'm going to do is over here I'm just going to write um on click equals onto it and there's something else we want to do over here so um one problem with the code right now is if the user clicks on this entire box right like or if they click on any of these buttons like our bookmark they're also clicking on the parent div right so it's going to trigger this on click along with this function so we don't want that and the way to do that is by wrapping this up in a function and just saying uh we're gonna receive an event over here a click event and we're gonna say stop propagation right so what this does is if you click on the like button for example it's not gonna register or it's not gonna um perform the on click action for the parent container right like that click does not propagate to the parent container and we're gonna do this exact same thing for our bookmark function as well so replace this with bookmark and boom okay now um what we can do is over here we can just write the ID right and now if we click on this you can see that it loads up the Tweet Details page right now the space does not have a lot so it just has tweet and the ID but as you can see the URL has changed and we have fetched that ID over here we are going to use this ID to get all of the details back from our apis great um so now let me delete all of this and now we can make changes the word here and see what's happening over there so over here the first thing I want to do is like declare a sort of header and for that work okay let me actually add the header tag first so motor this one is going to be vertical [Music] again let me actually just copy some things over from our index.tsx right because we've already declared the header and stuff over here it's just that we don't really need the sticky header over here right away we can actually make it sticky but okay let me just copy this first so if we go over here we can see that we have a flex screw of parent container over here within which we have like a header that's the first thing so I'm I'm just going to do this over here right and I'm going to replace this with tweet now if I go back I have this header box over here right now one thing I want to do is basically uh if we go over here I want to have a button over here right like this button is basically a sort of back button right over here and instead of just having a back symbol what I want is sort of like an arrow so I'm going to go back to Hero icons and just say um we're gonna go with like Arrow left and we just see what's happening what's happening over here so if I click on anything we have like this Arrow right this is the arrow we want to copy so we're gonna go with like Arrow left let's go back here go back to our editor over here I want Arrow left icon I'm gonna give it print and what we also want to add over here is like some gap between these two so that it looks neat and yeah this is this is already looking pretty okay I'm going to add some on click functions and stuff over here but before that um let's actually um okay let's actually add some styling first right first thing what I'm going to do is make it complete circles around it full we're gonna give it some padding and when someone focus on it I want like there to be a light gray Circle to appear so we're gonna give it a background color of white and add opacity of 20 percent right so if we go back and we hover we can see a small circle coming up over there we can actually test it with a lower opacity right awesome um okay now what we want to do over here is in if if someone um basically clicks on this I want them to go back to the um to the last page basically do the same thing as what happens when you click back on your browser and the way to do that is pretty simple you can just use this router object and call Dot back on it right and let's go back to our browser and see if it's working so if I click we are back to our home page if I click on another tweet uh this tweets URL holds up and we're gonna add all of the details over here okay great um okay so we're done with like this section like the header section let's go and see what else we have over here so um first thing I'm going to do is basically just copy these readers over here so um below order we're gonna go ahead and add these divs and we need another one now over here we are going to add all of our information so the first thing we need um so we're gonna do it like this like we want the Tweet to be displayed first then we want a sort of tweet form for posting replies under the tweet and then we want all of the replies to be listed down below so let's do it in that order all right the first thing um first thing I want to do is basically um have like let me just write these down right so we have tweet um so and then we have like form for replies and then we have um all of the replies cool um so in order for us to display all of this information we are going to have to fetch it from our database first and in order for us to do that um let's start by doing a couple of things over here so um the first thing I want to do apart from like this router stuff is actually um get our session object right because this is also some this is also a page which can't be accessed without the user login in so we're going to have to fetch our session object to check if we are logged in right and if we are logged in we should get back our user detail so use session we're going to set required true and I'm going to record this Hook from next Dot now what you can do is if um status equals loading you can just return a Dev that says and on loading right um if not we are good to go but over here I'm also going to create a use effect and I'm going to write um status and session only this is very similar to what we have done in our index.tsx page um and we are pretty much like we're gonna follow the same format in all of these components right so um over here I wanna basically fetch um the tweet details and replies okay so it should clear an async function first and call it from over here now let's fill this function so if we have session and um I'm gonna add two conditions over here so if this is not loading authenticator and loading have no overlap [Music] okay let's okay let's get back to that but what I also want over here is like if tid is present so I'm I'm also gonna add this right so in case this is like this and [Music] um tid's MTV are we we can't really load any details so we want this and over here okay cool now what we are going to do is we're going to fetch all of the data and for this um we're going to create a separate endpoint right and uh what I'm going to do over here is is just add ptid and the API path so we're going to say tid if response dot status equals 200 then we get the Json from the response and we're going to just follow um the similar format as our other apis because we haven't created this API yet because it's just going to return it in a very similar format so we can just write the code for handling the response right away over here what we want to do is um basically store the response in some states so let's declare some State over here what we want is um post that post okay let me check import you state import post done now what we want to add here is also the user data right so the user data basically over here means the user that has posted this this particular tweet or post right set user data is used it user done and over here what we can do is set post to something like data.post right we're gonna return it in this format inside user data to data dot user data [Music] um we are also going to add like a loader over here um and for that okay so we're also going to need like some more information over here but let's let's just start with this bit so let's create this API endpoint now in order to for us to do that what we are going to do is go inside our API folder we are going to create a new um file inside a new folder so tweet slash PID dot yes done and over here we are going to handle um the this API endpoint right um okay so what we want to do inside this is first of all I'm going to go ahead and put paste this starting section cool so now um this route is also protected and then what I'm going to do is get the tid from by doing this so equals dot query now we have the tid so we can basically just fetch this post from our database using Prisma so Prisma dot post dot find unique where ID equals the ID okay if we are able to find the post we will basically also find the user for this post right it's like the author of this post so I'll just say await is not user dot find unique where email equals post dot username now if you can find the user as well we should basically just return all of this data so we're going to say status 200 and over here we are expecting a couple of things message done and then post and then user cool um over here we mentioned user data let me replace this with just user once we are done with this we can return back right if this does not work uh we're going to say RS dot status we're going to not return like 200 and just say user not found I'll just say post found user not font right something like this and if we are over here um we can basically just say like if if the post does not exist we can just basically just say res dot status 201 you can just write a message post not found um okay now let's go back to our UI and we have the post data we have the user data over here um based on these we can basically um what we can do is we can basically start adding um some details over here so what I'm going to do is we're going to replace this part um and the easiest way to do that is by basically saying if we have post and we have user data um on a display um a tweet box right and over here we're going to say post equals post user data equals user data and we are going to not allow anyone to do an on click over here so I'll just uh add an empty function over here you also need the user email um so we're gonna add user Dot email and we're sort of done like I'm just gonna add the null in in the other case let's go back to our browser and as you can see we have like our tweet over here right click so let's maybe go back if I click on this tweet this tweet shows up right along with all of the like bookmark everything right now um I want to basically fill this up uh with like a tweet form and like the replies and everything else right so let's go back over here and let me first go back to index dot TSX and over here I'm going to copy like this function this div over here this div basically represents whatever happens over here so we're gonna fill that up uh so that we don't have to worry about it um afterwards so we have this we have this we're gonna add it right below oops foreign yeah now we have like this section in place and it has its own border so now it looks a little bit neat the next thing we need over here is like the four right um so we're here we need um the Tweet form right and now tweet form needs a bunch of uh things over here um so let's actually declare those things we're gonna need if we if we go on the Sprite like we have a bunch of things over here and we also need a key right to reset the form once the uh tweet has been submitted or in this case the reply has been submitted let's go back over here and start declaring these things right so text set text used it actually let me just go over here and and like instead of typing them all out I'm just gonna copy uh the bare minimum needed over here so we we have a profile image we have a base64 we need this we're gonna copy all of this over here and I think this this sort of finish let me paste this over here clear this for now so let's start adding stuff right so what we need is we need a key this is going to equal to 3 text equals text set text equals set text and face 64 this is for the image right because we can upload images inside replies too so set base64 page 64. and now we need a profile image equals profile image and we also need a couple other things so now what we need is an on sublet function right and I'm also going to change like the text of the button over here so instead of this submit I need a button that says Reply so we're gonna fix that as well um but okay let me just add a couple of things so let me declare a function over here async function reply and we can go over here and say one submit equals reply and um something else I'm going to change over here is if I go inside to it form I'm going to add another problem at the end that says label right and this one is going to be string and now what I'm going to do is go all the way down here and instead of this submit I'm going to write label and I'm going to go back to my index.tsx go to where my tweet form is and over here I'm going to write label equals submit right and inside our inside our tweet Details page I'm going to write enable equals 2i so if I go back we can see we have a reply button over here but if we go back to our home page we have a submit button over here right now let's fill uh the rest of it up so we need this profile image and all but we don't really have the profile image at the moment so uh we're gonna have to uh load that bit of data as well um and for that work uh what I'm going to do is basically use the uh user API endpoint that we created earlier so um what I want to do over here is we fetch the post details and now we are going to fetch the user details so once this section is done I want to basically call another function that says get current user so let's define this function over here async function get current user and over here what I'm going to do is use our user API accounts response equals a weight fetch slash API slash user and if you go and look inside our user API Handler we have the following so we need um the email inside uh the get request query param right and we're going to be we're going to find out the current user from the DB and return it inside this user object over here so let's do that and for that to work what we need is forms params new URL search params email and this one is going to be again fashion or let's just write session dot user dot email right and what I'm going to do over here is just add a question mark over here and add parallel right um once this is done you can check if the status is equals to 200 if yes um what I'm going to do over here is our will just take um okay first of all we'll get const data equals await response dot Json if data Dot message equals let's go back over here if it equals user found right like if it's in fact we can actually like deal with like both of these cases over here all of this one is um yeah like uh let's let's deal with this one first right so let's say uh user form I'm gonna go ahead and say set profile image to data dot user dot profile image done um okay now once this is done right over here um what you want to do is also get like the comments right um but for now let's let's sort of leave it at this and see what's happening so if we go back over here we can see that this um image now shows the blank profile picture image that we've set because it fetched it and set it as the state okay great um the other thing I want to do is basically fill in the reply function over here so reply is going to be very similar to the create tweet function right except that we're gonna have like something uh we're gonna add a parent ID because like this tweet is as a parent right it's a reply so let me go back over here and uh copy everything from this function right once this is done I'll just go over here paste so we're gonna add some extra things sir body image and user email are and I'm gonna add a paradigm now this parent ID is going to be the tid right and once this is done we are pretty much like yeah this function is sort of ready the only other function remaining is basically a function that gets all the replies or all the comments right let me see replies um so for this one what what we are going to do is let me just write const response is a weight um fetch slash API slash comment right and conspirants as new URL search parents over here I'm just going to add a sort of tid cool um we already checked this and this angles so this is fine uh let's let me just add params over here and what this endpoint is supposed to do is it's going to give me all of the replies for this particular tweet right the Tweet with this particular tid right and we haven't created this API endpoint yet so uh let's actually go ahead and do that so inside API I'm just going to click uh create a new file called comment.ts right and over here let me um let me just um okay let me do one more thing over here right because when we're fetching tweets so when we're um when we have a get request what we are doing over here is we're basically just um fetching all of the tweets and you want to do the exact same thing except that we wanna basically um and we're gonna basically fetch all the tweets with a certain parent ID so let me just copy all of this go to my comment dot TS paste this and over here what we are going to do is delete this because we are not handing a post request over here and yeah over here I'm gonna write where foreign ID equals tid right and what is tid tid is basically let me just write it over here um so this one is like request.query dot did right and I'm going to just add the ID over here a comma over here and everything else pretty much Remains the Same we're gonna return back posts and user data um okay let's save this file and we can also add another check over here uh with respect to like if the requester has a tid parameter or not but let's leave it like this for now and go back to our GUI so we're gonna go to tid.tsx and over here let's see uh let's see what we can do right so just if response to status is equals to 200 um what I'm going to do over here is basically just say conch data await response by Json right and over here I'm just going to set replies um to all of the posts that we get right and and what I'm going to do over here is that we haven't created any state for this so replies that replies and this one is an array of post const y user data that reply user data new state um done now let's go back over here and we're gonna set reply user data to data about user data okay now we have all of the replies over here and what we can do is we can just use this function to um list out um all of the replies over here right so let's first call this function right so once you 've received like the user details or not yet it replies as well right and I also also want to basically um I'm also gonna add a loading parameter because we're going to be fetching a whole lot of information and I want to set a loading State uh which is set to True while all of this is being fetched so use state Boolean and set it to True by fault um and um okay over here I'm going to once this is start um and we'll just adjust to false all right um okay [Music] um and once you've replied right over here I also want to call character flies over here because you want to refresh the list of replies because we've just sent a new reply right so this is cool this is done and over here um I'm gonna actually add um that loading through now we can go back down here and we can basically just list out all of the all of the replies over here and that's pretty simple to do because we're gonna follow the exact same format we did for our feed inside our index.tsx file so I'm just going to say post of type host index of type number and I'm gonna map it to um basically this tweet box over here right and now tweetbox needs a bunch of things starting with key so we're gonna say post.id and then we need the actual posts over here I'm just gonna say post you need the user data reply user data I and then we need um one click function so over here you can actually just leave it blank for now all right this basically means that someone clicks on a reply it doesn't open its own uh sort of tweet detail page so for now we can just leave it to plan we also need the user email which is going to be session dot user dot email okay done um there seems to be one error somewhere index done done okay um now let's try posting or apply right so let's say um I'm gonna just write um let's do it over here click reply and as you can see the reply starts appearing over here right uh pretty cool and what we can also do is by the way like we can add images over here so like um here so apply with an image and I'm gonna click this and select like anything over here let's say like this image right and as you can see the image opens up as well we're gonna click reply and it's going to take a second and just post the reply with the image as well so we can not only just upload images in our tweets we can also upload them in our replies because it follows the exact same structure in our database right pretty cool the only thing remaining over here is as you can see we haven't updated like this uh this number right like this should get updated to 2 because we have two replies over here right now and that is something we're gonna fix uh right now so um what I want to do is basically um once someone sends a reply so we're doing two things over here number one we are basically um so what we are doing over here is um we're creating a new post inside our database with like a certain parent ID so that marks a reply but we also need to go ahead and add uh uh just tweets ID right inside uh the comments um comments ID section of our parent tweet what do I mean by that well um let's go back to our post API right like over here API slash post so we are over here and we are creating this this thing right now we're done with this but what I want to also add over here is parent ID right which means this is our reply um and in this case what I want to do is I want to get the parent so let's say parent equals Prisma dot post dot find unique and I'm going to say where and over here I'm gonna say ID is quick Quest dot body dot ID right and this is going to give us the parent Tweet now what do we want to do with our parent tweet well um what I'm gonna say over here is like if parent dot comment IDs dot includes I'm gonna say um post dot ID because like this is the comment we just posted over here right so if if um if this is not the case right like if this is the case this is highly unlikely by the way but if this is not the case it already has like um it it doesn't already have this comment ID inside of its like this post ID inside of its comment IDs list we are going to add it over there all right and we're gonna say um first of all if you can find a parent I'm going to add a lot of checks over here just to make sure like things like some edge cases aren't missed out but if you have a parent over here I'm gonna just say updated parent and um oh wait where's my DOT user not user post dot update where ID equals um parent dot ID right and data equals this comment IDs is basically parent dot comment IDs and we're gonna add post.id over here right and once this is done right like this entire thing um yeah we can just go back to uh we can just just say done and record it on the comment rate over here so um right so now if if right now like there is one problem over here like we posted two replies right and as you can see we are scrolling up and like this is again having that blur effect right everything is going behind the header and a bit blurred which is cool but what I'm gonna do now is basically like these two replies were posted without this code right like where we updated the comment IDs which is why the parent has like zero comments so to speak um so what I'm gonna do over here um is basically um let me go back to my mongodb over here and refresh this page great so now we have like these two comments or these two replies over here I'm just going to delete them and I'm not this one this one delete now um I am going to do is basically refresh this page as well and we have no replies now and what I'm going to do is I'm going to uh just say like um post reply again right like which is like um 100 over here now if I click reply it's gonna basically take a second okay looks like something went wrong so we're gonna have to check image is missing the required Source property uh okay okay let's see what happened with the request yeah um every so now we we have like an issue over here with our updated code so we are over here right and um [Music] um request dot body dot parent ID over here this is what you want okay let's go back and I think this is not done but I want to know what happened so let's go back to our DB and check like what's happening over here right so let me refresh this page mongodb Pages don't have another reference to you're gonna have to refresh this every time you are checking something um and we have like this tweet over here right and this doesn't have any comment IDs which means like our code didn't work the way we wanted to do let me delete this again and go back over here refresh this right and just add um click reply and now we have a reply over here right and if we go back to our database refresh this you are going to be able to see this comments ID right so now if you have like this is the same ID as this right so it basically has this list of comments or list of replies for this particular post right and we have it attached over here so now we can use this comments ID to basically um change the number over here right like if we have three comment IDs over here that means we have three replies so we should replace this number with three let's go back to our um code go to component slash tweet box over here this is this is this is what you had written rights post comment ids.length the only problem is like when we posted um so what's gonna happen over here right now is it we never refreshed this data now it has refreshed because we switch back to the browser so we can see a reply over here we can also go back and it's going to show like the same reply over here right like this one if you click on it here's the reply great um but we didn't refresh this data right away which is why it basically um it basically took a while uh to to sort of like um change this number right for the next fix that um uh soon but for now we have like the speed going on and we have the ability to reply to a tweet we have the ability to like a tweet we have the ability to bookmark a tweet right um great now let's go ahead and build our bookmarks section because this is going to be pretty fast like it's it's very similar to this one except that we don't even have this tweet box over here right we just have a list of bookmarked tweets so yeah um great so now uh what I'm going to do is go over to my Pages directory create a new file that says bookmarks.dsx oh uh I forgot we have already created um this one somewhere right over here yeah and we have bookmarks you just have like this mt-ish div over here and we're going to replace this right and and this time it's going to be uh fairly quick because you can just go copy things from over here right like copy the basic structure from over here so what I want is I'm going to copy all of this and then just modify it so let me um right now over here we don't need like a lot of things um so let's start following these errors one by one first of all we need the router from the use router hook next we need to replace this with bookmarks the back button works as it is next uh we don't need um this tweet over here right next we don't need this and we don't even need a tweet font for replies so let's just get rid of that now instead of replies what I want is like bookmarked tweets and um bookmarked tweet user data yeah I'm just gonna write it like this cool so let's go ahead and add those things as a first up um it's actually instead of typing all of that out let us just copy the relevant bits right so we need this over here you need to import the use session hook go back now we need these two things as well let's go back over here and instead of this I what I want is book marked tweets that bookmarked tweets and I'm just going to copy it from over here and I'm going to import new state great uh so now we have this I'm also going to import tweetbox over here and we're going to write some more things so first of all um since you're using session we need to make sure that we are like authenticated if you're not authenticated it's going to show a loading screen over here so this is sort of done we also need to import a post from personal client over here and user again from Prisma client over here they take care of the types and now we need to actually fetch these bookmarked tweets right that's all we need to do right now um so over here what I want to do is I'm gonna have a use effects sort of similar to this uh so copy this over here import use effect and we have like loading and stuff um over here and we're gonna we haven't used the loading in our uh over here as well so let me actually take care of that as well but [Music] um basically what what you want to do over here is copy this line right and then over here I want something else I don't want these tids I don't even have a tid over here right so I'm going to just remove this and I will need like the current user as well or do I no I don't get rid of this and I don't need this stuff as well so let me get rid of that and instead of get replies I have like get bookmarks this is what I need now we're going to implement this function we think get bookmarks okay now this is where we need to fetch all of our bookmarked tweets so um in order to do that what we're going to be doing is um so we need we need um we need a couple of things over here right like so we need [Music] um foreign what we're going to do is if we go and check our database right so we have this thing called bookmarked user emails right and it's going to have your user email if you have bookmarked this particular post or this particular tweet so we're gonna be um uh fetching or we're going to be using uh that inside our API right and for that what I'm going to do is I'm going to just use create a new endpoint so this one is going to be called slash API slash bookmarks right and um what I'm going to do over here is also pass in like the user image so I'm just going to say const Rams is new URL search arms right over here I'll just add email equals session user dot email um that's great and now we can just append this at the end of our API endpoint so Plus params now if we get response dot status equals 200 we can basically um get the Json out of it and then what we can do is set bookmarked tweets to like data dot posts and that bookmark tweet user data row data diffuser data you need at least for the moment and we can after this like after we're we're sort of like done with this we can set loading to pause and we're gonna use that to display our loaders uh Neutron and so once this is done what we need to do is go inside our API folder over here and we're going to basically for some reason okay I believe we already have like an an API endpoint over here let me just check what's the error first right [Music] um Arrow left icon okay import this done now let's go back to API slash bookmark.ts right and over here um what I want to do so we have a post request over here right like we're using this post um method to um bookmark any tweet on behalf of a user right but we are also going to need another thing over here so if request dot method equals get what I'm going to do is I'm going to take constant email is required request dot query dot email right and now I'm going to basically fetch all of my um like bookmarked tweets and the way to do that is basically just save uh posts is await Prisma dot post dot find many and over here we're gonna write where bookmarked user emails as the email right so what this means is bookmarked user emails as a list or it's an array right so we wanna get all of the posts where this array has the email sent in our request query and this is the way we can do it in Prisma right this is why we're using prismite makes our code so much um like easier to understand right and after this I'm gonna do the exact same thing that we have done whenever we have fetched posts which is basically get the corresponding user data so I'm going to copy this stuff go down here paste it right nothing new all we are doing is just iterating over all of the posts that we found and getting their their author uh user data right and like we're returning all of this response over here so we're pretty much done with this now we can go back to our browser click bookmarks and um basically like we have the bookmarks head already we have the back button and now we need to like fetch uh now we need to fetch um we just need to call our API so let me go back to bookmarks.tsx over here and um okay we have this code sort of ready and we aren't seeing this is basically bookmarks over here just to keep the comments consistent but we are we aren't seeing anything over here so let's check what's happening okay um [Music] bookmarks responded with like a 404 which is weird um okay let's see what's happening over here uh it seems to be fine if we go back up we should see Slash FBI slash bookmarks this is okay if we go back over here we have request. method equals get we have the email and we have like all of this method over here and this one is cool and um let's go back to our homepage and click bookmarks again and just see what's happening console.log [Music] okay looks like we're sending uh like some sort of an incorrect so we have like email over here this is fine and let me just check what we're doing over here go to bookmarks this is fine um response headers request headers we have like all of this like we have the next dot cookie over here so this is good um all of this seems to be fine we are just okay I think I know what's happening like there's a type over here that's not bookmarks it's just bookmark right and now if I go back I can see my bookmarks cool right so this is the one to eat we bookmarked if we go back over here we can see like this is the one to eat my bookmark let's also bookmark this one for now all right and now we have these two tweets so let's go back to bookmarks page and we have these two Tweets in our bookmarks page right so um all right so we have the bookmarks page ready let's go ahead and build the profile page next all right so to build the profile page we're gonna go inside profile.tsx right now we just have this empty profile over here right and this is what gets shown so we have this profile but instead of that we're gonna basically make it a lot better so first of all what I'm going to do I'm going to copy pretty much like everything from over bookmark about that that seems to be one error over here cannot find name go to profile dot TSX and basically paste all of it here right I'm going to say I'm going to change this to profile and now we need to do something different right so we don't need the bookmarked tweets we need all of the tweets of the user themselves right so we're gonna change a couple of things first um first thing I'm going to do is just Add profile over here instead of bookmarks foreign and uh if you go back we can see that now we have profile header over here and we have the bookmarked tweets so we're going to change this section and for that what I'm going to do um is we want a section over here that basically displays the profile picture the name and the username and it allows us to change all right so it allows us to upload a new image over there um for for the profile picture right and for that we need to use the use Drops drop zone right like regard drop zone that we were using in our index.tsx file over here right so we had um sorry in our tweet form right so if we go to component slash tweet font we go over here uh you're gonna see um that we we had declared like these two things like a handle function and some uh and the use drops on the hook and this is what we need used to create the upload button and we're gonna do the same thing right now but in a slightly different format so let's go back to profile dot TSX over here and now what I'm going to do is we have this header this is fine this is fine um in and of itself before so over here I'm going to replace this with like user tweets right and we're gonna modify this later on and over here what I want is basically like the profile details okay um so what I want over here is basically I'm going to create a give it up order the order neutral 600. and I'm gonna give it like a padding of work right next uh what I'm going to say is basically um I'm going to create um the image upload button over here right and for that to work we need to go back to tweet for over here and copy these two functions so file.tsx they're over here we're gonna change all of the stuff later on but let's just go ahead and copy these two right and we need uh to import use drop zone and we need a state to store is 64s at base 64. done um so now we can use these two like this these these two props to create an upload button so let's go ahead and do that so I'm going to write over here as um I'm going to create or related because what I'm going to do is display the image and then add an upload button on top of it right at the very center so we're gonna do relative and um we're gonna say Flex justify between right and inside this I'm gonna add a div and over here I'm going to say get root props and inside this we can declare some classes so here I'm going to say absolute um top nine left nine and I'm gonna say over BG neutral [Music] um it's covered with like a darker gray version over here right and I'm going to also say over BG opacity I'm gonna set this to like 30 percent rounded full give it some padding course or pointer [Music] um yeah this is all we need now let's go inside this and basically create an input element here we're gonna say get input props and um we're gonna add like a camera icon over here camera icon is again imported from hero icons um that's pretty convenient h6w6 okay now that this is done we want to actually display the image as well so import image from next image over here um we are gonna write face 64. right and over here I'm going to say Alt and file picture word thousand right thousand and then some class names and over here I'm going to say words 28. i28 rounded full right so the reason we have like word 28 High 28 over here is because like we're basically so this Our Moment is like 112 pixels over here right and then we've given it um uh we're we're basically what you want to do is like we have um like we have this this camera icon of like 24 pixels Plus um basically the padding over here which is like why is this not showing up okay it's inside this one but it's basically um like four pixels right so we're gonna we're gonna have to Center the this camera icon button thingy over here like this upload button inside this image which is why we're using this relative parent diff okay now that this is done uh I wanna actually do a couple of things over here so the first thing we want to do is basically instead of doing this get bookmarks thing here we can we can just keep it keep this as it is but I want to do I want to fetch the user details first right so get user details and over here uh we can go all the way up over here and declare a function that says listen function get user details we want to get user details uh we'll just call um slash API slash user and we're going to add some params as before and the params are basically new URL search params okay we imported something else yeah search params email session user done um once you have this what you can do is if response dot status equals 200 cons data equals await response dot Json now we can basically uh fill in like all of our data so we're going to actually add some more States over here so I'm going to say conch name set name you state ring cons username that username you state print and this thing and what we can do over here is we can just go down over here and set some things up so set base64 as like data dot um like user dot profile image set name as data Dot user.name and set name as data dot user dot username okay use this over here right so now that this is done yeah this is all we need from get user details now and how is this working out because we're using slash API slash user so we can go inside over here as you can see what happens is if it can find a current user like it just sends back all the details all right so we're using the same API endpoint this one is also protected as we uh implemented before and let's go back to our profile over here and this is saved let's go back to browser and as you now as you can see we have a blank profile picture right the blank underscore PP dot web P so we have like this over here and we also have like this nice little camera written over here you can actually click this and we can upload a different image right and if we go back to our code and check the handle drop button it basically sets base64 as the new image so if I click over here and let's say add this profile picture it's going to change that picture right and now we can upload this picture to our database to change the profile data as well great um let's go back to our code and fill in like the uh the rest of the things so what I'm going to do over here is um we have like this stuff over here like we have related all of this is okay um but below this I want two things so okay one of them is going to be basically so I'm gonna just Define two P tags over here and I'm going to write um name and username over here I'm going to append this with at the rate so now we have like our name and username over here I'm going to add some class names to style this up the text so point pulled and I'm going to give it some border margin okay you can come over here and just give it like that neutral foreign right looks much better now um the other thing that I would probably undo is also add some bottom origin right over here right it looks a little bit neat now um great now what I'm going to do is also add like a sort of like save button over here so if we change the profile picture we should be able to save um we should be able to upload that to back to our database and save it and the way we can do that is by basically adding a button somewhere over here so um um I'm just going to go over here and add the button right this save and I'm going to make sure that this is um like all lined up this seems to be in line over here I'm just going to say items start so now this is all the way up there and I'm going to basically file this button up um so over here what I want to do is like where 24. 10 next item Center this is my Center and then like DD glue 500 . and I'm going to say all that code that looks much better now and um instead of just saying save always I want to basically um I want to do something over here right so what what I'm gonna write is like another function that says update profile right and wait and this one is going to be a post request so it's going to have some headers content type communication you have a body Json Dot streamify and over here uh we're gonna set um profile image you're also gonna actually if you go back to our user and point over here what it does is like if you have if you send a post request if you already have um if you can find a user with that email we're gonna update that user otherwise we're gonna create a new user right so we're gonna be going for this one and let's go back over here and let's just say email is session okay done so what I want to do is like once someone clicks I wanna actually just add another update over here that says updating that updating equals new state Julian um and I'm gonna write false over here what we are doing is we're going to set set updating YouTube and once you are done with this like uh it's gonna return like a 200 response over here you can just verify that points okay let's just write and set updating to false right and when's updating S2 I don't wanna uh show uh the save button I wanna have a loader over there so I'll just go down to this part and I'm gonna see if I'm updating is true um on a basically show a loaded over here otherwise I'm gonna say so loader can be taken up we already have a loader to find somewhere here sort of go down okay we're gonna have to go inside our tweet form over here if we go and click uh see this button so we have this load loader over here right so I'm just going to copy this go back over here and replace this with this great now uh the only thing left is on click equals complete profile right great um other thing that I want to sort of do and it's like once the profile is updated I want to actually refetch both of like all of these tweets right and for that we need to actually first fix this logic right so instead of get bookmark that we have somewhere over here instead of get bookmarks what we need is get user tweets right so we'll go back over here get user tweaks and um okay so if you want to get um get tweets for like a particular user we're gonna have to create an endpoint for that as well so let's actually save this for now go inside our API directory inside our Twitter create a new file over here that says user Dot TS right and over here what I want to do is basically so I'm going to start with this right instead of starting with a blank I'm gonna copy there's um paste it over here we don't need any post requests over in this endpoint but when it comes to uh like the get request instead of doing this bookmarked um thingy over here what I want to do is basically I want to say about user email equals request dot query dot email right or we already have like this parameter great um once this is done we can just leave everything else as it is and we can go back to our profile dot TSX and over here and we're gonna say tweet slash user and we're going to we can rename these as well so we can just say user tweets user send user tweets right go down here and select this to set user tweets all right and then go down here and set this to user tweets right and I'm going to change this one as well so instead of saying bookmark tweets user data I'm just going to say um user tweets user data and change it over here as well so go down here so that's the user to each user data and then we can go down here and change this one as well right now if you go back over here we have like all of our tweaks and let's try changing our profile picture right so I'm going to change it to this one and click save it shows me a loader and then what it's going to do is it's going to refresh all of these tweets okay we we haven't added that logic yet so let me go ahead and add that uh once we are done with this what I want to do the rate get deleted not user detail this is tweets right um so if you refresh this by the way so we haven't added the loader yet but as you can see my profile picture has changed and all of the tweets right let's try doing that once again so let me switch that up with like something else over here let's say like this one click save yeah so it's gonna send the uh profile picture and boom all of my profile pictures are changed right and they're also changed over here by the way I exchanged over here and once all of the tweets get loaded they are changed over here as well so now we have like a functioning profile uh page we have like a functioning bookmarks page and we have like the feed view the and all the tweets uh with the replies uh likes bookmarks everything right the only thing we need to do is like a bunch of polishing changes to make this UI a little bit smoother but before we do that what I'm going to do is add a log out button over here right because that's the only thing missing in our sidebar as of now so let's go to components slash layout dot TSX right and over here what I'm going to do is like I'm going to add a button so we had already implemented the sign out button at the very beginning of this video by the way all right I'm just going to re implement this uh over here with like some better styling so add these classes um over here and lower buttons are pretty simple right now all you need to do is call sign out which is a function you import from next Dot and once you're done with this you can basically just add an icon over here so I'm gonna go with like this uh there's this neat little icon for like logout write this one Arrow left on rectangle we're going to go over this one Arrow left on rectangle icon class names h6w6 and I'm just gonna say log out over here and I'm going to copy the same class names right like and um text LG and then uh called inline Flex on large screens and then font light right now if we go back over here we have the logout Button as well uh click on this we get logged out right over here and now we can sign back in with our Google account and we are taken back to our home page um after the login great now let us do some polishing changes to make the UI a little bit smooth with loaders and things like that together so let's add some polishing changes that we missed here and there right the first thing that I want to do is add we declared a loading state in in different places for example in our profile page right but it doesn't really do anything because we are not really using it for for any purpose right it's what I'm going to do um since I'm going to write a new condition over here C IS F we are loading the page what I want to do is like I'm going to copy this much paste it over here um oh now I'm going to just add um basically a new div over here and um this name is going to have a trading of it flex and item Center now Enterprise enter and I'm just going to draw it loading over here right if you go back click on profile okay so we need to fix this a little bit but we're going to do that in just one second the uh the other thing that we need to do over here we're gonna have to add like we have this bit so we have this border but we want to contain this loading um and end this section and um for that work we're we're basically going to go down here repeat this Dev over here and um I'm going to basically paste it down here that above that I'm just going to create another tip and give it um and flex right and this one is supposed to have it's supposed to be something like this right so I'm just going to add this stuff over here and what I'm going to do over here I'll just say okay and I'm gonna say man live stream right and um I'm gonna say relative minus top and there's a step what's happening over here okay this is not the one we need um we need it over here relative final stop stream right and um so now we have like a nice loading thing over here and then the profile loads pretty cool um the other thing the other thing we want to do is over here is black and the two tweets come up so let's go back we already have like a loading strip defined over here and we're gonna do something very similar um over here so let me just add a space over here copy this go to my bookmarks um look over here now we can see a nice loading um screen over here while the tweets loaded right the other bit is basically when it comes to um like this right like did you I'm not sure if you notice but if you click somewhere you can see there's like a bug over here and then over here while the image loads right to fix that we are going to go into these sections right so I'm going to go first into index and over here and we are going to go into profile image right so this we're going to change this to blank right so the default uh blank profile picture right we're gonna do the same thing over in key ID dot TSX right so we have this profile image over here we're gonna say slash blank cool um now let's go back and see what's happening so we saw how like this this um actually I'm also gonna write give it the same value over here blank underscore DB Dot Dot okay not this one this is the image that gets uploaded so we don't really want it to have anything over here but everything else is fine right so the blank profile picture comes in first and then it gets replaced by your profile picture same thing goes on over here it's blank and then it gets replaced by your actual user profile picture stored in the database right now this looks um a lot better there's one more thing I want to do so when we tweet something out where what we're basically doing over here is um let's go back to index.tsx right and when we tweet something what we are basically doing we've missed um two steps over here um so number one uh the submit button over here right like uh on submit we run this function tweet over here so what we should probably do is get tweets um after we've submitted right the other thing that we should probably do is set page 64 to basically a blank uh over here right and um and then this is reset the uploaded image right and this one is basically reset the content editable so now if we go back and let's say you want to read something right so there's like a tweet image I'm gonna click um I'm gonna select on image over here right here a bunch of these I'm going to select this one pretty cool we have like the close button and everything click submit and now it it's going to take a second to upload everything right and we see this loader in the meanwhile but what it's going to do is taking a little bit yeah it took a little bit of a time [Music] but basically um like please refresh all of the tweets right like refresh the tweets and your new tweet gets shown over here and then the loader vanishes and your Tweet form resets right so this is exactly what we want so that the user doesn't feel um like their their application is stuck right like they know that their tweet is getting uploaded and once the moment they see their tweet in their feed they can like give tweet font resets and it looks um are much better right we can actually um load the same tweets right and as you can see we we initially have like a blank profile picture over here as well and then it gets replaced with the actual profile picture so that one that that is pretty neat and we also have like uh we have the loading screen over here we can replace this with like a skeleton or sort of like a spinner or anything like that but basically um what you can do and this one by the way this one was a reply right like you could reply to replies as well because this is also a tweet so you can keep replying to replies recursively right and chain things up um and yeah this this sort of like this is this pretty much completes the basic functionalities that we had in mind and um one more thing I'm going to add over here is uh we're gonna go to our tweet detail page.tid.tsx and over here uh inside the reply function we're also gonna do something similar so I wanna set page 64 to like black right so this is the same logic um as what we applied over here like we need to reset the uploaded image we need to reset the content editable diff right and we also need to do something like this so we're gonna go into tid.tsx again um what I'm going to do is so we're we're already uh like when it comes to I think the Tweets we're already doing this this stuff over here I'm going to just push this on top over here and something else um something else I'm gonna do over here is uh we are basically going to fetch the um tweet like the parent tweet details again what do I mean by that well um if we go over here we have like this this function over here I'm gonna extract this out um desktop right so I'm gonna extract this out into another function get tweet details okay and I'm gonna just write away that read details over here so this basically sets the post and the user data and I'm gonna call this function over here again all right I'm gonna I'm gonna say avoid get to it now what does this do basically if you go on like any of these tweets right let's say let's go on this one like our very first tweets and now I'm gonna give it like right and I click reply what it's going to do is It's Gonna Keep uh this loader alive and it's gonna be uh it's gonna render the reply over here it's gonna change this number right that we updated so when we fetched tweet details again we refetched all of this data right and therefore we have like this number got updated from zero to one and then we reset this to it form right so this this looks um much better than what we had earlier where basically there was a gap between these updates happening and it it almost felt as if the app had had gotten stuck right cool so now we are done with um all of the functionalities right we have like our feed view we have uh we have the ability to post tweets upload images inside tweets um like tweets right like um uh and all of this stuff right like we can bookmark tweets and um we can reply to tweets then we can add we can also by the way add um out as you can see over here we can also um we can also add um images and our replies right and then we have like this nice bookmarks uh section where we can see all of our output bookmarked tweets and then we have uh basically a profile section where we can see all of our tweets as well as like we can change our profile picture and then we have like this nice logout button that's gonna basically log us out and the last thing that I'm going to do is just style this um sign in with Google button and for that I wouldn't recommend styling it yourself like you should basically like there's a couple of standard ways to do it and I have uh basically I've I've copied um like uh this from like uh someone's documentation and I'm gonna use the exact same styling over here right so I'm going to go to Pages login and you can you reuse this button uh uh the same way uh in in your applications as well so I'm just going to copy this go back to my code editor go to my login.tsx file and I'm going to replace this button with this right so it does the exact same thing we are signing in Google as the provider we pass in the provider we pass in the Callback URL and um yeah we basically the rest of it we basically have an image uh for the G logo and we're taking it directly from developers.google.com and um yeah we can now go back and see that we have like this nice sign in with Google button we can click on it it signs us back in into our home page and we have our feed over here that's pretty much it for this video if you have stuck around for so long um thanks a lot and thanks a brick turn for the support on my last video that was really overwhelming I'm Gonna Keep creating more of these with new Concepts so that we can learn uh new technologies and Frameworks and tricks together um I'm going to be uploading all of this code onto my GitHub the links links are going to be in the description I'm also going to link all of these documentations over there and add um all the timestamps uh and yeah don't forget to like And subscribe like the video subscribe to my channel for uh more content like this and thanks a lot
Info
Channel: Apoorv Nandan
Views: 8,586
Rating: undefined out of 5
Keywords:
Id: Nl1tc41NKo4
Channel Id: undefined
Length: 334min 25sec (20065 seconds)
Published: Sat May 06 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.