Transcript for:
Building a Full Stack Social Media Application

Hello friends today we are going to create a full stack social media application using the latest version of nextjs this is the homepage on the left side we can see our profile card the menu and the advertisement component on the right side we have the following requests that we can accept or reject upcoming birthdays and again the advertisement component this is the Post Feed that includes all the posts from our friends we can like or unlike the post and we can leave a comment here we have the user stories and each story is available for 24 hours we can add a new story and we can add a new post let's write a description and upload an [Music] image if we are the owner of the post we can click here and delete it let's check the user profile here is the user details and the user information we can follow or unfollow this user if I follow it's going to send a request and that user can accept or reject our request as we can do here let's take it back and here we can block the user and if we are blocked by any user we won't be able to see their profile page anymore let's see our profile we can update the user information using this [Music] form we can also change the count information using this component it's a great project to understand the new versions of react and nextjs in this tutorial we'll be using all the new features of react 19 we'll be using server actions to send the forms use form action hook to receive the data from the back end and to use optimistic hook to update the UI immediately and after completing our application we will deploy it using hostinger as you know it's the hosting sponsor of the channel and I create different projects using hostinger every month and for this project I'm going to choose a VPS hosting because it's a fullstack application and we need to run nodejs but don't worry we'll install our application and database using Cloud panel in a minute and these servers are super fast because they use mvme as this and one of the most powerful processors and the best thing is you can deploy all your full stack applications on a single server let's choose the most popular one and if you use the link in the description below and lamad Dev coupon code here you'll get an extra discount after purchasing you are ready to set up your server you can choose any location and you can install any of these server panels I prefer using Cloud panel because it's really fast and easy to use let's add the panel password and the server password and finish the setup it's going to take a while and after that it will be ready to deploy our applications so if you are ready let's create our app and deploy it here okay I created a new folder and inside this folder I'm going to install my nextjs application to do that you can open your terminal and write here MPX create next [Music] app but if you do that it's going to install the latest table version which is nextjs 14 but I want to use the upcoming version nextjs 15 because we can use all the new features of react 19 like the new compiler use action State hook use optimistic hook and all the other great features so what you can do is you can visit my GitHub repository you can find the link in the description and in this repository we have the starter Branch this is an empty nextjs 15 application there is no unnecessary files and styles so we can start everything from scratch and at the end of the video I'm going to create here one more branch and it's going to be the completed version of the application and it will be an open- source project it's 100% free you can use it anywhere you want so I appreciate if you could give a star for this project after doing this you can clone this repository just come here and copy this URL and use your terminal and write git clone and this URL but the better way is to Fork my project because it will create your own repository as you can see this is my test account it's going to create a new repository and right now you can use your own repository and it will be much easier to keep track of your progress so every day when you finish your coding you can push your changes here so right now you can copy your own link here I'm going to be using my own account and I will see kit clone paste your url here Dot and enter as you can see all our files are here but we don't have the dependencies let's install mpm install and perfect it's ready to start let's start up application mpm run Dev as you can see we are using paral rendering and react compiler and also we are using nextjs turbo okay let's visit this URL and as you can see we have a text here and this is our homepage before creating anything let me show you the main structure of our application this is our nextjs application and inside our application we are going to have our Pages like the login page homepage profile page and a single post page to do that we are going to need the next Jaz app rer so inside the source folder we are going to have our app rouder and after that we will be able to create our pages and we will also have our small components like the nabar left and right menu or whatever it might be and we will also have the nextjs server actions as you know after nextjs 13 we can use server components so we don't have to create an API route to communicate with the database so let's create here a database we can fact the data on our pages and server components so we are going to make the requests and get a response let's say data fetching so basically they are going to be our get requests and we need to update the data on our components to do that we are going to be using server actions let's say data mutation and we will make make all the post update and delete requests for this project you can use any database provider you want because we will be using Prisma RM so instead of connecting to database directly we are going to be using Prisma and it's going to connect to our database and make all the requests so it doesn't matter which database you are are using the syntax will be the same so what about our database I'll create here my diagram and let's use this AI feature so I will write here what I exactly want to create and it's going to generate all the tables and relationships I'll say create a Prisma schema for a social media app I'm going to be using a relational database so let's add it here and let's write our requirements I will say users can update their information let's write our Fields here name surname description City school work and website URL they can also add multiple posts they can comment on posts they can follow each other but when we click on the follow button we are not going to directly follow the user instead we will send a friend request must be sent before following if the receiver accepts our request the sender becomes a follower users can also unfollow or block each other they can like posts or comments and they can add user stories but we are going to have an expires at date because they will be visible for 24 hours okay let's generate and let's see what we have as you can see we have the user here and all our fields and each user can create posts user ID is here where is our comments here again user ID and post ID we can like posts and comments we have the follow request sender ID and receiver ID is a user ID we have the followers table users can block each other and stories as you can see it added here expires at date and this is what we exactly want if you want to change anything you can click here and change your Fields I'm not going to add or delete any field but maybe I can change my names it's going to be image this AI was really accurate we don't have to change anything and this is the main structure of our application we are going to make our cruit operations here and pass them to our components so we are ready to design our application and after that we are going to come back and take care of the Authentication if you watched my nextjs video you know how to create Pages we create Pages using nextjs App directory inside the source folder as you can see we have the app directory and inside this Roots folder we have the page file here and this is our homepage but I also want to create my profile page when we visit profile and any user ID here we are going to see the user profile file and this user ID will be dynamic it can be anything so what I'm going to do is I'm going to create a folder called profile and I'm going to add the dynamic user ID and finally I will create my page I'll say new folder profile and insight we are going to have the user IDs but remember it's going to be dynamic and inside this folder I will create my page let's create our function by the way if you don't know how I'm using this shortcut you can visit my GitHub page again and you can find my cipit here okay let's change the page name I'll say profile page and that's all so even if I change my username here as you can see we are still in the profile page so creating pages are that easy if I try to reach the profile page as you can see it's not found because we don't have the page TSX inside profile folder Let me Give an example I'll say settings and I will not have any dynamic rout here I will direct to say p TSX and as you can see it's here okay you probably already know how to create Pages I'm not going to Deep dive into every little detail let's open up our example and see what's inside the homepage we have a number here and we have have three components this left bar the Post Feed and this right bar we are going to design all these components but before let's take care of this Nar because when we visit our profile page as you can see all these components are different but our nbar is still the same and also for the login page and register page again we are going to see our nowb bar so let's create this and use it in our layout if you remember inside the app directory we have the layout file and whatever you write inside this layout will be visible on error Pages let's check as you can see test if I visit the homepage again it's here so I can create my number component and use it here to do that inside the source folder I'm going to create a new folder and it's going to be components let's create our first component number I'm going to create my function quickly and let's use it inside the layout just like that before creating our items let's give this space if I shrink my page you can see that we have a small padding here and if I extend my page we have more space again we are going to increase that space uh for the biggest screen so let's create a container here and I'm going to R my number and let's say with full I'm going to give back ground and I will say for the MD screen the padding X will be8 for the large screen is going to be 16 for the X SL screen it's going to be 32 and finally for the 2x large it's going to be 64 as you can see padding X means padding left and right just like that let's open our console okay perfect and I can do the same thing for my other items as you can see this space is the same so I'm going to Dr my children with this do just like that I can delete here and I'm going to change my background let's say 100 and as you can see for the small screen we don't have any padding let's add I forgot this just like that okay so let's take care of our napar items we have three sections for the big screen these logo these links and search input and finally this login link and if we are authenticated we are going to see here some icons and our user Avatar but since we are using Tailwind let's take care of the small screen first as you can see at the beginning we are going to have only our logo div and this menu button and when I click here we are going to see our mobile menu so let's create our logo and this menu I'm going to open up my naar and I will create my DS let's say left I'm going to create two more Center and the right side and at the beginning for the small screen we don't have anything inside the center so I will say hidden and inside the left component left de we are going to have a link we are going to be using nextjs link and let's write our website name I will give my URL and it's going to be the homepage and inside the Right View we are going to have our mobile menu we can directly write our component here but since we need a user interaction our component should be a client side component we cannot click on the server component and we cannot store our state here so what I'm going to do is I'm going to create a new component let's say mobile minu and I'm going to use it here so let's create our button if you want to you can use an image it will be easier but I prefer using my HTML elements because when I click here I want to see this animation to do that I'm going to create a do and inside we are going to have three lines top Center and bottom and when we click on this container this parent container I'm going to remove this second one let me zoom in and I'm going to change the position of the first and the third one I will see another D they are going to be self close divs and let's say width six height 1 I'm going to give a background color which is blue 500 and let's give round it small it basically adds border radius and I'm going to create two more items and let's separate them I prefer using flexbox I will say flx column and I'm going to give a gap between them let's give two and I will say csor pointer just like that but space is too big here so I'm going to be using a specific number 4.5 pixels okay it's much better right now before our menu and this animation let's separate our items on the nbar I say Flex align item Center and justy content will be space between and also I'm going to give a specific height for my Nar and it's going to be 24 which is 96 pixels just like that I'm going to shrink my page okay perfect let's give a style for our logo font will be bolt text will be bigger and I'm going to change my color actually let's make this darker and right now when I click on this button I want to see my menu here to do that we are going to need a use State hook I will say const is open set is open and at the beginning it's going to be false let me close this menu and when I click on this button I'm going to change my state if if it's false it's going to be true if it's true it's going to be false set is open and I will say take the previous value and write here the opposite if I save I'm going to see my error here as you can see because we are using a hook and also we are using an onclick event here that means our component should be a client component right now I can write my condition I'll say if it's open create here A D and inside this D we are going to have our links I'm going to import nextjs link and the first one will be the homepage let's write here some links and let's give a style in our example let me zoom out and I click here it contains all our screen so I can give absolute positioning and the initial point of our component will be this point left zero and top 24 remember we gave 24 for this number so I will see position absolute left zero top 24 I'll say withd full and the height will be full screen but remember 24 of our screen is this number so we can use a calculate method and I will say 100 VH minus 96 pixels 24 means 96 pixels okay let's give a background it's going to be white and I'm going to Center my items Flex column item Center and justy Center I will click as you can see they are here let's give a gap between them and the font weight will be bigger let's say medium Tex will be x large and the Z index will be bigger than one because our component should be over everything we shouldn't see here something else okay let's take care of our animation here so instead of quot here I'm going to be using back tick and I'm going to wrap my class name just like that and I'm going to write here a condition I will say if it's open I'm going to be using rotate and it's going to be 45° and if it's not it's going to be an empty string of course it's not open it is open and let's do the same thing for the other one but this time it's going to be minus 45° and for the middle line I will say if it's open it's opacity will be zero so we are not going to see it I will click and as you can see there is something wrong here because by default when we transform our items it takes the middle of the lines as the origin point but I don't want to move this and this points I just want to move the right sides here and here so our origin point will be left not Center so let's write here origin left I will do the same thing for this one and perfect but we don't have any animation I'll say the timing function will be is in out so it's going to be slower and also I'm going to give my animation duration let's say 500 I will do the same thing for the others just like that and right now we have a great animation here I'm going to zoom out and perfect but what about bigger screen let's check our example as you can see for the medium screens we are not going to have our logo here we are going to see only our links and here we are going to see the login link and as I said if we are logged in we are going to see here some icons let's do that actually I'm going to close here here we don't need layout let's close this terminal and I'm going to come back and I'm going to create my links inside Center I'll say links let's create a container and I'm going to write here my first link it's going to be homepage but as you realize we also have icon here so let's create xjs image and after I'll say span and homepage let's add our image here all the are in the public folder it's inside this starter Branch so you don't have to upload anything and I will say home. PNG and remember if you are using nexts image you have to give here with and height let's say 16 and I'm going to separate this image and this link so I can use flag and GAP and if you remember at the beginning it was hidden but for the MD screen it's going to be flxs let's check our example again we are going to have two more links and here the login link I'm going to create two more it's going to be friends and stories of course if you want to you can add more items I'm going to close here for the MD screen as you can see they are here but they are not horizontal and we can see our logo here so for the left side I'll say if it's empty make it hidden but for the LG screen it's going to be visible again so I will say block okay let let's make them horizontal flags and gap between each link will be six and tex will be gray 600 just like that and for the bigger screen we are going to see our logo but as you can see our links are centered but in our example it starts here to do that we can give a specific width for our left component so I will say with and it's going to be 20% and for the center I'll say 50% in this case we are going to have 30% and it's going to be the right side okay perfect but our item is here let's move it to the end I'll say flx box item Center gap between each item will be four because remember if we are authenticated we are going to see here some icons and our profile picture and I will say justy and so we are going to see our items at the end of the component by the way there is something wrong with our images let's give class name and let's enter our items okay I'm going to change my font size actually let's directly change our Center component I will say text small okay and for the MD screen I'm going to remove this icon I will say MD hidden okay right now I can add my link let's close here and here we are going to have a condition when we visit our website firstly we are going to see here a loading spinner and we are going to check if we are authenticated or not if not we are going to see this link and we click here we can can login and register and after that we are on the homepage and we can see our icons and the user image here and when I refresh the page as you can see it's loading again I'm going to refresh loading and our icons so if you want to let's take care of the authentication it's going to be really easy because we are going to be using Clerk right now we'll create our authentication using Clerk and after that we'll be able to get the authenticated users information and we can use it on our client or server components so it will be easier to pass the user information when we fatch or update the data so we can verify our user information here and on the server actions for example when we want to fatch all the followers of a user we can get the information from Clerk and use it here or here and also we can protect our routes if we are not authenticated we will not be able to see the homepage to do that we are going to be using nextjs middleware we'll write our authentication role and protect the routes so whenever we make a request to see our pages middleware is going to check whether we are authenticated or not and if the route is protected we'll be redirected to login page and we are going to create our middleware rules using this off but there is something important here when we create a new user we should also create the user on our database and this ID should be exactly the same ID because we are using our user ID almost everywhere to do that whenever we create a new user we should get the notification from Clerk and we can do it easily using web hooks in app rer we can create pages but also we can create API routes and in this route we'll create an endpoint let's say web hooks and we will Define this endpoint on our clerk dashboard and after that whenever any event happens we are going to get a notification I will say events there are many events we can subscribe but the most important is create user update user and delete user so whenever we change our user status we are going to collect the information using this API endpoint and after that we will be able to create a new user on our database and I will say post H and delete requests so this is the main structure of our authentication so let's see how to install Clerk if you scroll down you are going to see a link in the description and when you visit that link you are going to see the clerk's website this is the easiest way to create authentication we don't have to implement anything from scratch clerk is going to handle everything for us so we don't have to worry about the security sessions user tokens client and server components everything will be ready in a minute you don't have to design anything you can simply use clerk components after that users will be able to login log out manage their profiles let's check our application I'm going to click here as you can see this is a clerk component that we can see our information manage our account update the user information and also when you log out and open up the signin page you are going to see this beautiful component that we can sign in or sign up and also if you don't have more than 10,000 users on your application clerk is completely free this is why I started using clerk I can use it for all my small applications for free let's open up our dashboard and create a new application I'm going to give a name as you can see there are many options here I will choose email username maybe Facebook GitHub okay that's enough I'm going to create my application and after that we are going to need this dependency let's copy I'm going to zoom in I will come back open up my terminal and mpm install Clerk nextjs and after that we should create an EMV file and inside this file we are going to pass our publishable and secret key let's copy this I'm going to open my menu and inside the root folder I'm going to create a new file and it's going to be EMV let's paste and remember if you are using an EMV file make sure that you add this inside the kit ignore okay we already have it it here so when you push your project to GitHub nobody will be able to see your secret keys and after that we should create a middleware it basically allows us to protect our routes let me copy and paste and after I'm going to explain if you are using a source folder make sure that your middleware file is inside this folder and I'm going to paste my code so what this Clerk middleware does is it basically intercepts our requests and check the authorization for example if you remember we have the settings page here and if we are not authenticated we shouldn't see this page so we can write here our Rule and we can protect our settings page by default all our pages will be public but if you want to you can add here your protected routes I'll say const is protect route and we are going to be using Create route matcher and we can add our routes inside this array and I will say settings and if you want to protect everything inside this folder you can use it like that and if you have any other page you can write it here but I'm just going to show this settings page and right now we are going to check our route and if it's protected we are going to be using clerk protect method to do that we are going to check the user authentication and the user request and I will say if the URL the user visits is inside this protected route check the authentication and if the user is not authenticated protect this route so I will say if is protected route and I'm going to pass here my request and we are going to be using off and protect right now if we are not authenticated we will not be able to see this page clerk is going to redirect us to the login page and finally we are going to wrap our application with this clerk provider and after that we will be able to use our components let's do that I'm going to copy this open up my layout and wrap my entire application with this provider let's import it comes from clock nextjs and that's all let's use our components I'm going to close here open my no bar and as I said we are going to have three states when we visit our website firstly it's going to be loading and after that it's going to check if we are authenticated or not if we are not authenticated we are going to see this link and if we are authenticated we are going to see our icons let's do that the first component we are going to be using is clerk loading and if it's loading show here a spinner I will just copy and paste my spinner here just like that I just searched for Tailwind Spinners and I found this website it was the first website you can check here some Spinners and loading indicators and you can copy them you don't have to create this from scratch and after that if it's looted we are going to check if we are signed in or not signed in again from clerk next Jaz let's say signed in and also we can use signed out so if we are not authenticated we are going to see this text I'm going to save and as you can see signed out I'm going to refresh my page loading and sign out right now instead of this text let's add our icons I'm going to create a div here and I'll say csor pointer and I'm going to add my image Insight let's say 20 height 20 and it's going to be people.png let's create two more is going to be messages and notifications and finally I'm going to show the user button again CL nextjs and if we are signed out if we are not authenticated I'm going to create here a do and again we are going to have an image here login.png and I'm going to add here a link and let's say login or register just like that let's make them horizontal Flex align item Center and gap between the image and this text will be two just like that let's make this smaller so when I click on this button we are going to see our signin page and when I click here we are going to see the sign up page it's really easy to do that let's come here I'm going to open up the documentation and as you can see we are going to create our route using this folder name and we are going to create our page and inside this page we are going to add this sign up component let's copy this and inside the app directory I'm going to create a new file sign up page and let's copy here just like that so I can do the same thing for the signin page let's copy here right now on only thing I should do is add my signin and sign up URL inside the EMV file I'm going to copy open up em and that's all and let's check I'm going to click here as you can see the sign in page let's close here okay it's not centered and the height is smaller so let's create here a container wrap our component and remember the height of the Nar is 24 so again I can use here the calculate method and I'm going to Center my item let's do the same thing for the signning Page by the way it should return our do just like that okay I'm going to copy here and WRA my component and perfect so sign in and sign up oops it's empty because I didn't save okay let's try to sign up I'm going to give a username and a password as you can see it sends a mail I'm going to check quickly it's here let's copy and paste and we are on the homepage right now and when I click on my profile picture I can see my details I can update my profile and when I click here I'll be able to see my devices and it's that easy guys right now we can continue our design I'm going to check my example again this is the small screen medium and for the large screen we are going to see our logo just like that and after that I'm going to add here a search input so let's close everything open up nowb bar I'm going to close my menu and after my links here I'm going to add one more div and it's going to be my search input let's give a placeholder I'll say search we are not going to have any background and I'm going to delete the outline after that I'm going to add my icon its size will be 14 and the source will be search.png and at the beginning it's going to be hidden and if it's x large it's going to be Flex box I'm going to give a padding insight and the background color and I'm going to Center my input and this image okay I'm going to give a border radius and after I'm going to separate my items it's going to be X lar and let's find the main container which is Center we are using flex boox and I will say item Center and just five will be between just like that okay perfect maybe I can increase the size of this icon okay it's much better so let's take care of our homepage at the beginning we are going to have only this feed component that we can see our posts and after large screen we are going to see this right bar and after X large we are going to see this left bar so let's create our components and use it in the homepage I will close here I will open up my homepage this is going to be the main container it's going to be horizontal and gap between each component will be six and I'm going to create different containers for each item for the left side Center and right and at the beginning left and right will be hidden if it's ALG it's going to be visible and for the left menu it's going to be X slat and for the mobile screens the center will be full if it's LG the right menu will be visible so I can give here any specific width let's say 70% and here is going to be 30% and if the left menu is visible here is going to be 50% and here is going to be 20% okay I'm going to save open my menu and create my components left menu right menu and for the center we are going to have the user stories we are going to have this add new post component and after user posts so I will say at post. TSX and post feed let's use them on the homepage left menu right menu and I can create here a container and inside we are going to have the stories at post component and the user feed component and for each item I can give a space just like that let's see okay but there is no space here let's give a padding and perfect so let's take care of the stories first I'm going to open my Mobile screen and let's see what we are going to have as you can see we have a main container and inside we have the stories and I can scroll horizontally so inside this main container I'm going to create another container and inside I'm going to add my stories but before let's give here a padding background will be white round it will be LG and I'm going to give a shadow let's say MD and we can scroll this on the X AIS so I will say overflow scroll and the text will be small okay and each element will be horizontal so I'm going to be using flx box and gap between each story will be eight and I can add my first story here let's see what's inside we are going to have an image and the username but as you realize first one is not the user story we can actually click here and add a new story so let's design the others first and after we are going to come back and design the first one so I can say flax flax column I'm going to Center my items and gap between the image and the username will be two that's say csor pointer and inside we can create our image size will be 20 it's going to be a circle so I can use rounded full and I'm going to give a ring so we can see this circle here this blue circle by the way I should import of course we should give with and height let's see it's 80 pixels just like that and after the image I can write here the username let's create a span I'm just going to generate a random first name and the font will be medium and let's see okay maybe I can decrease the font size okay it's exactly the same right now I can add other stories but before let's add here an example image to do that we can use peas.com let's choose any image here paste here but remember next CH doesn't allow us to use external images if you want to use this domain you should add it to maxj configuration let's open our menu find the next config and here I'm going to add one more item and it's going to be images and we can add our domain names inside this array you can add here the connection protocol it's going to be only https and the host name will be the domain name so if you want to add more domains you can add it just like that the domain name here but for now it's going to be only this one I'm going to save and refresh and perfect let's add the others I will say story and as you can see there's a problem here because by default the size of the second div is full so it's going to try to not overflow but it's not important because we are using overflow scroll so I will say with the maximum content just like that so let's get rid of this scroll bar as far as I know you cannot do this directly in Tailwind so I'm going to create here a class name let's open our menu and find the global CSS and here I'm going to be using my class name and for the Chrome browsers I'm going to write webkit scroll bar and display will be none and for other browsers I'm just going to say scroll bar with and it's going to be n and and perfect so let's see what's inside this component we are going to have two sections this Avatar and the post details and inside the post details again we are going to have two containers this text container which includes this input and emoji and this container that includes our options let's create I'll close them open up add post we are going to have AAR and we are going to have post inside this post we are going to have text input and post options okay let's give here exactly the same padding background and Border radius it was ALG and I will say make them horizontal give a gap between Al and the post and also I'll say just five between and the text will be small let's add our image here actually instead of do I can directly add my image its size will be 12 object back fit cover and it's going to be a circle just like that let's give exactly the same image here or any other let's give the width and height and inside this post we are going to have the text input which includes our text area so again we are going to need an image but the source will be emoji.png and its size will be 20 and let's say cursor pointer so we can click and choose any emoji and also I'm going to align this item because here it's on the end of the component so I say self and let's check of course the container is not flexbox I'll say flex and the gap between text input and Emoji will be for let's give here a placeholder what on your mind and I will give a class name the background will be slate 100 and around it will be LG just like that but as you can see it's not containing all our component so let's see the size of the main div I'll say background threat 200 as you can see it doesn't fit inside the rest of the component to do that we can use flex one perfect and I can do the same thing for this text input if I say Flex one it's going to fit inside the container and also I can give here any padding let's delete this background and the padding will be two okay so let's add our options firstly I'll say Flex item Center gap between each item will be four and I'm going to separate these options and these post inputs that's say for and I'm going to change the text color I'm going to add my first item and if you remember each item has an image and text so I will copy this paste here add photo it's going to be 20 we don't need any class name here and after that I'll write my text let's give a class name for the parent I'll say flx item Center gap between the image and text will be two and csor pointer okay the image name is different let's check Okay add image so let's do the same thing for the others it's going to be add video why I named them like that not anyway add video add event and this one I think okay okay but if I shrink my page as you can see they are too close to each other to prevent this I can use here Flex wrap so if it doesn't fit inside this container it's going to move our items into the next line okay awesome end should be here I think okay and after that we can create our posts again I'm going to create a container here that has this border and white background and after that we are going to create one more component that includes our post details so let's open up feet I'm going to give exactly the same style here by the way where is our shadow it's going to be empty okay let's copy this save and paste here and our posts will be vertical so I can use flex column and gap between each post will be 12 so let's create our posts post. TSX component name and I'm going to use it here just like that okay let's close this menu and design our post so inside the post component we are going to have the user div the description div and the interaction div and for the comments we are going to create different component so let's create our items and they are going to be vertical plags flag column and gap between each item will be four we are going to have user D we are going to have the description D and interaction actually we can create different component for this one because we are going to be using new state hook and we are going to change our state but anyway for the design purpose it can stay like that so let's add here our user Avatar and username and and for the right side we are going to have this icon so I'm going to create another div for the image and the text I'm going to create the user image it's going to be 10 and again it's going to be Circle let's add here any image don't forget to give the width and height 40 and after this Avatar I can add my username so let's create a span and I will generate a random name and the font will be medium okay so let's add our icon here I'll add one more image and it's going to be more. PNG let's change the width and height we don't need any class name and let's separate this item and this icon Flex item Center and just file will be B between just like that and for the description we can have only text or the text with the image so I will say Flex box is going to be vertical and the gap between items will be four let's create our image to do that I'm going to create a parent D width will be full and the minimum height will be 96 and and our image will fit inside this D so I'm going to be using relative I'm going to copy this paste here let's choose any image and since we are using the parent we don't have to write width and height I will just say fil and I will give a class name because the object fit will be C and round it will be empty after that I can write my description let's create a P tag and right here a random sentence just like that okay awesome about the interaction for the left side we are going to have two items and for the right side we are going to have only this item so let's separate them first flex item Center justify between and text will be small and we are going to have two Dives it's going to have two items inside let's create the first one let me zoom in as you can see it's going to be rounded we are going to give a background and separate our items here so let's say flx item Center gap between each item and I'm going to give my background I'm going to give some padding and Border radius actually let's say x large okay there is nothing inside I'm going to add my image this pipe sign and the number again I'm going to need an image let's say like. pangi and I'm going to give class name and the cursor will be pointer after that I'm going to create a span it's going to be this pipe text will be Gray and another span and it's going to be the number let's say 500 but there is something important here for the bigger screen as you can see we have a text here so inside this number let's create another span and it's going to be likes but at the beginning it's going to be hidden and and if it's empty it's going to be in line let's do the same thing for the other one it's going to be comment and for the last one that is going to be inside this div just like that okay for the bigger screen we are going to see our text but we don't have any space and what else actually this color is lighter and there is a space here I'll say margin top let's say four and instead of 100 I'm going to be using 50 okay it's much better right now so we can take care of our commments after this do I can add my commments component by the way there's a space here also so instead of margin top let's say margin y so it's going to add margin to top and bottom I'm going to open my menu inside components I will say comments let's add it here okay and let's see what we have here we are going to have two sections we can write a comment here and we can see all the other comments so let's create two Dives I'll say write and the comments I can quickly give Flex item Center and gap between the image and text input will be four let's create an image Source it's going to be eight and again it's going to be a circle it's going to be 32 pixels so let's give width and height and again I'm going to choose any image here oops it's a video and after that I'm going to create one more D because inside this D we are going to have our input and this Emoji let's see placeholder write a commment again we are not going to have any background color and the outline and I'm going to use my emoji here and it's going to be cursor pointer let's see okay again I'm going to separate my items we are going to do exactly the same thing here it's going to be Flex one so it's going to fit inside our container and also they are going to be horizontal item Center justy between and I'm going to give background color round it will be x large text will be small and I'm going to give padding horizontally and vertically withd will be full and I I can use flex one here just like that and for this div I can write exactly the same thing flx one so it's going to fix our AAR here and after that I can write our command list right now we are going to have three items this image this container and this icon I'll see comment inside we are going to have Avatar description and the icon let's add it here quickly the size will be 16 and it's going to be cursor pointer actually let's give our size here also and it's going to be more. PNG and for Avatar I can actually copy exact the same image here just like that but this time size will be bigger just like that and what about here we are going to have the username description and again this interaction container so let's separate them first flags flags column gap between each item and firstly we are going to add here our username font will be medium A P tag again random sentence and here is going to be the like button and the reply button and inside the like button again we are going to have three items the first one will be the like image the second one will be the pipe and this one will be the like number let's give class names again it's going to be grade 300 and here is going to be 500 let's change the image like PNG that's change here by the way and after this button I'm going to create one more div and I will say reply okay let's make this horizontal and after I'm going to separate my items here is going to be plx item Center gap between items will be eight tax will be a small and tax will be gray 500 and for this D again flx item Center and gap between image this pipe and this number will be four okay let's give a space here by the way our main container should be horizontal so we can see our Avatar here description here and this icon here on the right side so I will say Flex gap between each item and also I'll say justy between and the margin top will be six okay awesome but there's a problem here to prevent this I'm going to be using Flex one and perfect for the small screen bigger and for the large screen we are going to see our right bar here let's check what else we can add that's all I I think so let's take care of the right bar I'm going to come here close everything and I will open right menu and inside we are going to have three components friend requests birthdays and sponsored ads but there is something important here if we are on the profile page as you can see we are going to have two more items here this user information and the user media so for each page we are going to have different items so we can get the type of the page as a prop we can actually directly get the user ID if there is user ID that means we are on the profile page so we can show this information and the media if there is no user ID we are going to have only these items user ID and its type will be a string of course it's not going to be required and let's separate our items and the first item will be friend requests you can directly write them here but also you can create new components and advertisement okay let's use them here just like that and again for this component we can take a prop because as you can see we also have here the advertisement component but here is a little bit smaller so gap between each item is smaller also so I will say size we are going to have three options it's going to be small medium or large we are going to use small for the left side medium for the right right side and large for the Post here since we are designing the right side let's give here size medium and let's take care of the friend requests firstly I'm going to give my padding background round it we are doing exactly the same thing here as we gave for this story this and this component we are going to have a shadow Bo for the radius background color and I will do the same thing for the other components just like that and after that we are going to have a title here which includes two texts this and this so let's say here is going to be as Spen friend requests it's going to be gray and I'm going to add here a link see all it can stay like that for now I'm going to give a class name it's going to be blue and the Tex will be X small just like that let's separate them flx justy between item Center and the font will be medium okay perfect what about our items again two sections the first one will be image and username and the second one will be these icons and for each item again I'm going to give a space so we can use here flexbox and gap between each item so let's create our first user actually let's say user again Flex item Center and justify Center and as I said we are going to have two divs first one is going to include our user image and the username it's going to be a circle and the object will be cover let's give our width and height let's paste an image and inside this de we are going to have two icons the first one will be accept and here is going to be reject I'm going to decrease this size it's going to be 20 and here is going to be cursor pointer let's give a class for this username font will be semi bolt and I'm going to give gap between items just like that let's do the same thing for this D Flags Gap three and the justy will be an so we are going to see our items at the end of the div okay but they are not separated user Flex just by Center it will be separated let's check our background okay oh I said just by Center of course it's going to be between okay so let's create two more users just like that and what about here again we are going to have a title exactly the same user and here we are going to create one more div so I'm going to copy and paste exactly the same items instead of those icons we are going to add this button and also we are going to add this component I'm going to copy this and the first user and paste here let's import this image and this link actually we don't need this link here let's write our title here's going to be username user image but here is going to be a button let's say celebr and its background will be blue text will be white and it's going to be X small I'm going to give paddings and the round it will be MD just like that of course we should separate our items as we did here okay let's create one more container and add this image and those texts after this user I'll say upcoming I'm going to give a padding Insight change my background round it will be algae flx align item Center and the gap between the image and text will be four let's add our image I'm going to copy this paste here change the source it's going to be gift PNG and size will be 24 I can delete here and finally let's add our items the parent de will be a link that's import and we are going to have two texts inside and they are going to be vertical gap between items will be one and again text X small let's write the first span what was the name upcoming birthdays and one more see the others it's going to be gray 500 and here is going to be a little bit darker let's say 700 and the font will be semi bolt just like that and what about here again title after image this image and title container description and a button let's open up our component and inside and bottom and here I'm going to separate my items text will be Gray and the font will be medium I'm going to have two spans just like that I can also use here my image let's do that it's going to be more PNG let's say 16 okay and after that let's add our image again I'm going to create a container and for each size I'm going to give different image size firstly for the parent de I'm going to give different gap between each item according to our size because again and remember this Gap is different than this Gap so I'll say Flex Flex colum I'm going to give margin top and I'm going to write my condition if the size is small the Gap will be two if it's not it's going to be four let's create our parent div for the image I'll say fill and if you are using fill the parent should be relative and the class name will be rounded alga and the object will be cover let's add here our image and again for each screen size I'm going to give different height here so I'm going to write it like that width will be full and for each screen I'm going to give different height let's say 24 if the size is MD it's going to be 36 and if it's the biggest it's going to be 48 and after that we are going to have one more D and it's going to include our image and the title let's check by the way it looks great I'm going to add one more de here I will say flexbox item Center and gap between the image and the text will be four let's add here our image it's going to 24 round it will be full and also I'm going to give the width and height and after this image I can write my title it's going to be blue color and the font will be medium and finally we are going to have the description and this button I'm going to create a P tag and for each screen type I'm going to give different text as you can see it's longer than this one and also its Tex size is smaller class name if the size is small the text will be X small if it's not m is going to be small and inside again I'm going to write my condition if the size is small the text will be smaller if the size is medium it's going to be a little bit longer and if it's not it's going to be the longest by the way it should be colum and let's see okay and finally a button and I will say learn more BG will be gray 200 text will be darker gray I'm going to give padding Insight text will be X Mo and round it will be LG just like that and what about other items let's check our profile page we are going to have the user information and the user media so let's create our components I'm going to close them open my menu let's create a new component and it's going to be user information card and one more user media card and let's open our profile page and again I'm going to add here my left Center and right components to do that I can copy and paste from the home page just like that of course we don't have any stories at post we are going to have feed left and right menu and after that we are going to add here our power picture profile picture and other information just like that but for now let's take care of this card I will give here a user ID it can be anything for now and also inside the write menu I can write my condition I'll say if there is user ID show my cards if not show nothing and inside we are going to have your user info cart and media card and also I can pass this user ID here and here because later when we have the database using this ID we are going to get the user information and the user images so let's take them as a prop just like that so let's see what we are going to have again I'm going to give exactly the same order padding background and these titles and after we are going to have different items here so let's open an example here this one I will copy here and I'm going to paste and here is going to be user information I can do the same thing for the other one and here is going to be user media and after that we are going to have our name surname and the username and after a description a d here that shows the city school work and after that we are going to have another de that shows our website and the joint date finally a button that we can follow the user and this blog text let's do that I'll say bottom firstly I'm going to give flax column separate my items and the TX will be gray 500 firstly I'm going to create my title div flx item Center Gap will be two and the first one will be the username sorry name and surname and the second one will be the username let's say small and here is going to be pier and the color will be let's say black and after the name we are going to have a P tag it can be our description something like that we don't have any class name here I'm going to create a do which includes an image and a text and this is going to be Bol let's give width and height and I will say city.png or what was the name okay map PNG let's separate them just like that and I'm going to add two more items here and here is going to be the school and here is going to be the work and after let's add another div that includes our website and this date again Flex item Center but this time justy will be between the first one and the second one first one includes the link image and the link itself so I'm going to separate them let's copy this paste and here is going to be link PNG and let's add here our link just like that and I'm going to change the text color text blue 500 and the font will be medium and I'm going to do exactly the same for the date I'm going to separate my items we are going to have an image date. PNG and I'm going to add here a pen and let's write the date I'm going to check perfect and let's create our button and the block text I will save follow and a span here and it's going to be block user let's make this red I'm going to change its position s and so it's going to be at the end of the component text will be X small and the cursor will be pointer and here background will be blue text will be white it's going to be small and Border radius will be mty let's give a padding and perfect so let's take care of the user media we are going to have eight items for each image we are going to have a parent we are going to separate them the container will be Flex box but again we are going to be using Flex Dr so after four items it's going to use a new line and move those items here media cards firstly let's say flexbox G between each item I will say just five between and finally flag strap and inside let's create our first item we are going to have an image I will say F of course it should be relative and I will say class name object fit will be col and round it will be MD let's add any image here and I'm going to give my width and height just like that we are going to have four items but I didn't use four here because remember we have a gap between each item so it's going to be 20% of the component just like that let's add more items and perfect so we finished our right bar let's take care of the left bar as you can see we have a menu here but for the homepage we are going to also add here the user card so again we are going to have a condition but let's come back close everything and I will open up the left menu and again I'm going to get my type it's going to be home or profile page and if it's the home homepage we are going to see this profile cart if type equals home show me the profile cart let's create I'm going to call my component here and after that let's create our menu firstly I'm going to separate all my items using flax column and here again I'm going to give my shadow padding and other details just like that I'm going to change to text color it's going to be gray and 500 I'll say Flags Flags column and I'm going to give space between each link it's going to be two let me close this menu and let's create our first link I'm going to import and the first one will be my posts and I'm going to add this image I'm going to give width and height is going to be 20 and the source will be posts. PNG let's give a style for this link I will say Flex item Center gap between image and text will be four I'm going to give some padding and I'm going to give this effect as you can see when I hover over it changes the background firstly I will say rounded LG and when I H over the BG will be slate 100 so I will do exactly the same thing for the others so I can directly copy and paste we will just change the name and image there is nothing different but before let's give this HR after this link I'll say HR tag I'll say border top one border will be gray 50 width will be 36 and I'm going to Center my item using self Center let me zoom in here so let me copy and paste the others or I can change the names because I know some of you don't want me to copy and paste anything so this is going to be activity here is going to be Marketplace events albums videos news courses lists and settings okay perfect and after that I'm going to add this advertisement but this time size will be small I the way we don't need this HR here and awesome so let's take care of this profile card again I'll will give my shadow ping and text it's going to be Flex flag column and gap between items will be six and inside I'm going to have the image container its height will be 20 and the position will be relative because we are going to be using fill for this image let me zoom in this is going to be our C picture and this is going to be the profile picture and its Position will be absolute let's create the first one I'll say fill and round it will be empty and one more is going to be rounded full let's give width and height its Position will be absolute I'm going to Center this horizontally using left zero right zero and margin Auto and it's going to be in the middle of the cover picture and since we are using height 12 if I say bottom six actually minus bottom 6 it's going to be centered and also I'm going to give this ring is going to be white and I will give Z index because we are using absolute and it's going to be over this color picture let's add some images [Music] and this one by the way I'll say object fit of course we cannot see it because we are on the profile page but if I open up the homepage it should be here but it's not by the way we have two posts here let's remove this one okay we set type here but we didn't use it on our homepage as you can see I'll say type and it's going to be home and it's going to be profile okay there is something wrong here okay we didn't give any width and height and we are not going to be using fill it's going to be only cover picture and perfect okay after that let's add our details username followers and this button by the way they should be Circle there's something wrong here we are going to fix that after this do I'm going to create one more do and I will say span this username font will be semi bolt and after that followers by the way let's give here class name H 20 flx flax column gap between items will be two and I'm going to Center my items okay let's add followers again they are going to be horizontal and gap between items and insight we are going to have images and they are going to be horizontal let's copy this paste here just like that let's say two more images and after that I'm going to create a span and text will be X small and it's going to be gray and finally our button and I will say my profile text will be white again X small I'm going to give some padding and the r that will be MD okay so we' finished our homepage let's take care of the profile page it's really easy yeah just going to add here the user information again the cover picture profile picture name and here we are going to have three items let's open up our page here and before this feed I'm going to create a div I will say flax flax column I'm going to Center everything vertically and horizontally I will do exactly the same thing here I'm going to create a main container I'll give my width and height and here I'll create my image it's going to be the cover picture so I will say fill and the class name will be object cover again let's add some images I'm trying to find something horizontal okay and one more image and this is going to be our profile picture just like that this time it's not going to be fill I will give width and height and let's write it here also round it will be full it's going to be absolute and again left zero right zero margin Auto and since our height is 32 I will say minus bottom 16 and let's give rink again this time it's going to be four and its color will be white if you want to you can give here border radius okay and after that our username after this do I'll say H1 tag class name where see I'm going to give margin top margin bottom and its size will be really big and the font will be medium and after that we are going to have three items posts followers and following so let's say flexbox item Center justify Center and gap between each item and margin bottom will be four let's create the first one it's going to be vertical so again Flex column and item Center we going to have two spans and the first one will be the number font medium and the second one will be the title posts and text will be small let's create two more followers and following let's change the numbers okay awesome let's check our small screen perfect medium large and x l okay awesome if you want to you can add more components here and here but it can stay like that if we need anything else we can add them later right now we can take care of our backand I'm going to close everything here open up my homepage and close everything here and right now we are going to create our database for this tutorial I'm going to be using MySQL but you can use anything you want because we will make our database request using Prisma orm so doesn't matter which database you are using the syntax will be the same to create database you can use any cloud service but as far as I know you cannot create a free database on planet scale anymore if you don't want to pay anything additional you can deploy your own database you can do it by installing MySQL on your server and make all the configuration you can use Ducker or if you use cloud panel like I do you can directly install your database in a minute to do that I'm going to open my cloud panel and I'm going to create my application here since we are using nextjs our application will be a not JS application you can write your domain here and if you are using a custom domain make sure that you change your DNS and use your server IP address our application will run on this port number let's create okay it's ready I'm just going to click here and databases and I will say add database let's give a name and that's all our MySQL data datase is ready and it's running on this port number and to reach this database on the development mode I have to add my local IP address to the White list otherwise I will not be allowed to use the database so I'm going to come back use the admin area security and here I'm going to add a new rule I'm going to choose my SQL and here I'm going to add my address let's give a name okay right now I can reach to my database I can create all my tables and add some items inside let's remember again my database name is social username is lamad Dev and the password is lad password and this is our server IP address and our database is running on this port number so let's install Prisma and connect to our database so I'm going to come here open my terminal and I will say mpm install Prisma let's check the documentation I'm going to zoom in and let quick start or we can choose any database here let's check okay we installed our dependency and right now we are going to initialize our Prisma schema I'm going to copy here and paste and if I open my menu let's close here as you can see there is a folder here and inside we have our Prisma schema our database provider will be MySQL and as you can see database URL is inside the EMV file let's check it's automatically added here when we initialize our Prisma right now I'm going to change my database URL let's see how we should change it connect your database and our database URL should be like that MySQL username user password and here is going to be our server address and MySQL is running on this port number and here is going to be our database name so I'm going to copy here paste it's going to be lad Dev Lada password Here is going to be social and I'm going to add here my server IP address just like that let's save and here let's check what's next as you can see in our schema we can create any table of course we are not going to use it but I'm going to create here an example so you can understand better after that I'm going to delete that so let's create a model I will say test and inside we should need a unique ID it's going to be an integer and I should say that it's a unique ID so we can find our items using this ID and by default when we create any item inside this table it's going to automatically increment the ID number so when we create our first item the ID will be one if weate create another one is going to be two so we don't have to give a specific ID but we can have let's say name it's type will be string you can write here any limit like maximum 255 characters we can have description again string but this time I can say it's not required it can be empty you can give any number using integer you can give any book ion and that's enough for the test let's try to push our table to the database to do that I will just say MPX Prisma DB and push and that's all let's see I'm going to manage my database of course we are not going to use this panel I'm just showing that our table is here let's see the structure as you can see name description number is published so our database works right now instead of using this panel we are going to be using Prisma studio so I will say MPX Prisma and Studio as you can see it runs on this port number let's copy and open up and our database is here and the test table is empty we don't need to use this studio but it's really easy to see changes we can see all our items here and tables when we want to check the relationships between our tables we can use that studio because for example when we delete any post here we should also delete the post commands so we can see the changes easily okay so right now instead of this test we are going to write our social media application schema my first model will be user each user has a unique ID but it's going to be a string because we are using Clerk and it uses string for the IDS let's write here ID and if user has a username again string but it's going to be unique it's important because on our application when we visit our profile page we are going to be using the user names so they should be unique and users can have avatars it's going to be string but it will be optional so I'm going to write here a question Mark and I'll will write the others C picture username I mean the first name and the surname description what US CD school work and website they are going to be optional because when we create our user we are not going to have any of them and finally we are going to have the created ad dat and it's going to be a date time and by default it's going to be the current date just like that and after that we can create the post model again I will say ID but this time it's going to be integer and we are going to increase the number it's an ID and after that we are going to have the post description string we are going to have the created ad dat if you want to you can also add the updated ad date we might want to update our posts and here is going to be updated update so whenever we change our item it's going to update this field and after that we are going to have the light model I'm going to copy here we are going to have the ID and created at dat and I'm going to write My Relations later actually we can do it right now I think it will be easier to understand each user can create a post and each post has a user the relationship is going to be one to many because we can create multiple posts so I'll write here my relation I will say user is going to be the user model and relation and Fields will be user ID and the reference will be the ID inside the user model so I have to create my user id here it's going to be a string and each user can have multiple posts so I will say post and post array so when I try to find my post I can do it using my user ID and it's going to fatch all the posts of this user and there's something important here when we delete our user we should also delete all the posts of that user so I will say UND delete Cascade so let's do the same thing for the like I'm going to C copy here again we are going to have the user user ID string each user can have multiple likes and also each post has multiple likes so I will do the same thing for the post post is going to be the post model I'm going to write here the post ID and its type will be integer but we can also like the commments let's create here I'm going to write it like that comment we'll have ID description created and updated at each user can have multiple commments and each commment belong to to a post post ID and integer in this case each post will have multiple commands just like that and right now we can like our commands as you can see it automatically added this here so even if I don't write this since we have the likes here when I use option shift and F it's going to automatically add it here okay in this case I'm going to make this optional because our like can be for the comment or post we don't know which one and again it's going to be on delete cascate and after that we can follow any user so let's say follower I'm going to copy here ID and created at and I'm going to write my user but this time we are going to have two users the first one will be the follower and the second one will be the following in this case I should change here let's say follower ID just like that and since we are using the same model we can write here a name so it will be easier to find our followers and followings let's say user followers so let's write our items here each user can have multiple followers and I'm going to write my relation name user followers and I will do the same thing for the followings again follower but this time our relation will be followings this is why we are using this relation okay and of course we cannot follow users directly when we click here we are going to send a request so I'm going to create one more model and it's going to be follow request ID created at and again we are going to be using two users uh let's say Center sender ID receiver and receiver ID let's write our relationship follow request sent and received let's add them to our user and after that I'm going to add here one more thing so let's say follow request send follow request array and the relationship will be follow request sent and I will do the same thing for the received okay there is something wrong of course it should be capital and here again okay but I'm going to write one more thing here and it's going to be unique sender and receiver ID because we cannot send multiple following requests we can send only ones so this combination should be unique so let's do the same thing for the block blocker and blocked I will say blocks sent blocks received and and let's write them here blocks and blocks received don't forget to make them capital and here is going to be block and there's something wrong here blocks sent okay if you want to you can change the name let's say blocks and blocked by and finally we are going to create our stories I will say ID created at and also we are going to have the expires at because after 24 hours they are not going to be available anymore and I will say user let's remove here PS will be user ID and I will say unique because our relationship will be one to one each user can create only one story of course you can change here you can create multiple stories but let's use it like that that's all I think if we make any mistake we can come back and fix them for now it can stay like that let's push it to our database remember MPX Prisma DB and push so let's try to add our first post to do that we are going to need the presma client so using that client we can fetch our posts comments or any other table here we can add new items we can update and delete let's open up the documentation I'm going to copy here and paste and let's see how to send a request as you can see we are going to import the Prisma client and using this Prisma we are going to make the cruit operations here is an example Prisma the model name and if you say find many it's going to patch all the users and also you can write here any condition like username equals lad Dev in this case it's going to patch our user information or here if you want to create a new user we are going to be using this method and inside this object we are going to pass our data like name email or whatever it might be we are going to use all of them but before let's create a new file and Export our client I'm going to close here open my menu and inside the source folder I'm going to create a new folder let's say library and inside client Dot TS I'm going to import my Prisma client from Prisma client let's initialize const Prisma new Prisma client and I'm going to export this but be careful here on the development mode whenever you use this Prisma it's going to create a new database connection but for the production we are going to have only one connection basically we are going to Define our client here and we will say if it's connected don't create any other client otherwise you will have thousands of clients on your production and it will cause some problems let's see how to do that I'm going to come here and as you can see your application should create only one instance I'm going to click here and we are going to export our client just like this we are going to initialize our client and we are going to assign this to this Global variable and whenever we connect to our client again it's going to check this variable and if the client exists it's going to use it if not it's going to create a new client so let's copy here and paste and right now we don't have to worry about the production let's export this by default okay I'm going to close here and here and let's try to add our first item I'm going to open my component new post what was the name at post and remember inside our schema this description is required and also we can add any image that is going to be optional let's save and push it again okay let's create we have the text area here of course we are going to be using server actions so I'm going to come here and I will say const Test action it's going to be an Asing function because we are going to make a request and let's say try catch block if there is an error we are going to show it here so we are going to run our action whenever we send our form let's make this a form and I'll say action and Test action in this case I can reach to my text area using this name let's say description and I'm going to add here a button when we click on this button it's going to send this description so we can take this data form data its type will be form data and to reach our description we will say form data doget and we are going to write the name of the input which is description and I will say as string and I'm going to send this to my post to do that we are going to be using the Prisma client and it comes from library and client and I'm going to choose my model which is is post and I will say create and I will pass my data here and it's going to be description as you can see there's a problem here that because each post has a user so we have to pass here our user ID but we don't have any user yet let's create one I'm going to comment this out for now and remember how we are taking our user ID using Clerk I will say const user ID and that comes from clerk off let's see console log user ID I'm going to open my terminal and there is a problem here because our action should be a server action okay I'm going to log in right now and my user ID is here so let's create a user I'm going to do this manually and after when we create a new user using clerk we are also going to create that user into our database but for now for the test purpose I'm going to open up my studio remember to open this you have to write MPX Prisma and studio and let's find our user and I'm going to add a new record its ID will be this ID it should be exactly the same ID let's say username others are optional they can stay like that I'm going to add and our user is here I'm going to update my username okay so let's send our post right now I'm going to open here and this user ID will be this user ID and of course it can be null so if you're are not authenticated we shouldn't send anything so I will say if there is no user don't do anything just return okay let's test I'm going to click here open my terminal and as you can see post 200 I forgot to add here console lock let's say const response of course it should be await and let's see what's inside this response Let's test I'm going to send as you can see it has changed and if we check our terminal we can see our post here and its ID is one our description is here created an updated ad and this is our user ID so everything works perfectly so right now I can delete here and I'm going to leave it empty we are going to create our server actions and write all our mutations but for now let's take care of the authentication when we create a new user we should also add it to our database to do that we are going to be using cler web hooks I will open up the documentation and let's search for web Hooks and as you can see it allows us to receive event notifications so whenever any changes happen on our clerk account it's going to send us a notification and we will check its event type if it's the user creation we are going to get the user information and add it to our database let's do that I'm going to open up my dashboard and here we should write our endpoint but since we are using Local Host we cannot use it here it should be a domain name to do that we can use anr it allows us to generate a domain for our Local Host let's log in and right now I'm going to install my application you can choose your operating system here and open your terminal let's paste this and after we are going to add our configuration and after that we are going to pass here our local server in our case it's going to be Local Host 3000 and it's going to generate a unique domain and we can use it on our dashboard let's do that I will copy here paste and it's going to be 3,000 as you can see this is our unique domain I'm going to copy this and paste it here and and we are going to choose our event and it's going to be user created and also remember we can manage our account using this component and here we can change our profile picture and username and again when we update our profile here we are also going to update the user inside the database so I'm going to choose update as well and let's create so it's going to send the notifications to this endpoint but how we are going to catch those notifications to do that we can use API routes let's come back open our menu and inside the app directory I'm going to create my API folder and inside I'm going to create my endpoint and let's say repb hooks I say clerk because we can use different web Hooks and inside I'm going to create my route so we can use this route to reach to clerk events it's going to be API web Hooks and clerk I'm going to save and we are going to test it right now but before let's see how to verify our web Hook connection because we are going to use our endpoint for only clerk web hooks nobody else should be able to use this route to do that we should verify our connection sync data I'm going to click as you can see we already created our domain and it also explains how to create a unique domain if you do that it's going to create something like that so you don't have to write different domains for each session but I'm going to leave it like that we addit our API endpoint and selected our events and right now we are going to pass our web hook secret to EMV file because using this secret we will be make sure that the request comes from clerk so let's copy this and paste inside EMV by the way I'm going to close here just like that and let's see our secret I'm going to come here and I'm going to copy my secret just like that and after that our route should be public but by default it's already public and right after that we are going to be using this library because clerk is sending requests using swix let's open again paste to our terminal and right after that we can write our configuration we will get the post requests and we are going to check our web hook key and if it doesn't exist we are going to throw an error and after that we are going to check the header that comes from the Clark request and using this ID Tim stamp and signature it's going to create a key and using this function we are going to verify that key so we will make sure that it comes from Clerk and our account and after that we can get the event type like user creation or user update and we can get all the user information using event. data you don't have to memorize anything here just copy and paste I will copy and paste here and let's see our event type and the data Insight I'm going to save let's delete our user I'm going to open my dashboard users and let's remove this let's come back and refresh the page page and I'm going to sign in again let's give a username and let's see our terminal as you can see I'm going to close this menu the type of the event is user created and inside this body we have all the information we need like email address created at date name username or whatever it might be so using this information I can also create user using my database let's do that I'm going to comment this out and I'll write my condition I'll say if the event type equals user do created I'm going to write a TR catch block I will console lock this error and also we are going to return a new response failed to create the user and I can send here a status cot let's say 500 and here let's use our Prisma client await Prisma do user. create and inside the data we are going to pass the user ID which is event data. ID remember it's here this is our user ID let's import this by the way and I will say username we are going to get the data but remember it's a string so we can use here Json pars and we are going to pass here the body and inside we have the data and the username and what else I can do I can add my avatar body data. image URL and if there is no image we are going to be using no avatar.png and I can also create C picture and it's going to be no cover.png let's create a new response user has been created and the status will be 200 and I'm going to write one more condition here and it's going to be user updated and this time we are going to update our user of course we should select our user first to do that we can use where condition and the user ID will be again event data. ID and we can update our username and aatar let's change here and that's all if it's not user created or updated we are just going to return status to 100 let's say web hook received but we are not doing anything I'm going to save and let's delete our user again I'm going to refresh delete the user and inside Studio I'm going to delete this user and let's try to log in I'm going to refresh my page by the way our homepage should be protected because if we are not logged in that means we don't have any friends any posts stories so I'm going to open up my middleware and I'm going to add here one more URL and it's going to be the homepage right now if I refresh my page as you can see we are on the login page let's login username and let's check our database I'm going to refresh and as you can see our user is here this is our AAR C picture and others are empty okay and let's try to update our username I'm going to click here manage account and update my username I will save and let's check I'll will refresh again and perfect this is how we are using clerk web hooks so we don't need them anymore I can close and let's try to fetch our user firstly I'm going to update here let's close everything open up profile cart it's going to be a server component so we can fatch our item directly so I will say const user AWA I will call Prisma user model I will say find first where the user ID will be the current user ID so again I'm going to use clerk const user ID that comes from off clo nextjs server and I'm going to use it here and by the way if there is no user ID I'll say return null we are not going to see our cart and let's see our user I will open my console and as you can see the user is is here but there is something important here we also need this follower number if you are using Prisma it's really easy to fetch that let's remember our schema inside the user we have the followers array so we are going to select this field but we are not going to fatch all the users we have we are going to fatch only the number of followers to do that I'm going to write here include we are going to fetch numbers so we should say underscore count and I'm going to select only followers just like that and let's see right now I'm going to save open my console and this time we have this count object and inside we have the followers number so we can use them as you can see name and ser name is null so we can use our username we have the AAR here and the followers number so this is our C picture so I will say use the user Avatar but remember it's optional so it can be null to prevent any error here let's say no avatar.png and again again if there is no user in the database we shouldn't see anything so I will say return no and here is going to be actually here is Avatar here is cow just like that and here is going to be name and surname but remember they can be empty so I will say if we have the username and the user surname use them here name space and surname and if we don't have the first name and surname we are going to be using user do user name and here user. count do followers as you can see it doesn't allow us to use this domain name for the images we should use next just configuration and add our domain name here like that I will refresh and perfect zero followers username Avatar and cover picture so let's add any cover here inside the public folder I'm going to add my image okay let's refresh and perfect so let's do the same thing for the profile page profile and the username it was Lama I think and using this name I can fatch my user let's close here and here and inside profile if you remember we were using ID but I'm going to change here and let's say username if you want to you can also use ID but I prefer using username so let's say async const user await please my client user find First and this time inside the condition I'm going to pass my username but how we are going to reach to this username since we are using a dynamic route here we can directly use our username with params inside params we have the username and it's a string let's call it here just like that again if you're not familiar with this params or app rather you can watch my next js14 video so username will be username and since we are using the same name it can stay like that and what else we are going to need let's say include and since we changed our route name I think it has a conflict if you have this kind of Errors just open your console kill your process and delete this next folder and I'm going to run it again mpm run Dev let's refresh again okay it's here so right now we are going to be using our cover profile picture username and also we are going to need the post number followers number and following number so we are going to do exactly the same thing here underscore count and we are going to select followers followings and posts and if there is no user I'm going to return not found page it comes from nextjs navigation let's see I'm going to write another username for for and not found of course you can change this page Style Just create your not found page and make this black but it can stay like that let's take care of our user but before I want to check one more thing if we are blocked by this user we shouldn't see the profile page so let's get our user ID and check if we are blocked or not I'll say const user ID that comes from Clark off but since we are using user here it's better to change the name let's say current user and I will write here my database request firstly let's say is blocked if we are authenticated that means if we have the user ID we are going to check our block table Prisma block and find First and we are going to pass here the blocker ID and blocked ID again I'm going to be using where condition and inside blocker ID is going to be this users ID and blocked ID will be our user ID so if it exists is blocked will be true so let's say const response if there is a response this block will be true and if we are not authenticated is blocked will be false okay and right now I'm going to return not found again I'm going to pass here is blocked okay right now we can use a our items here let's close this menu and we will do exactly the same thing here user. C if it doesn't exist no C AAR first name and last name remember what we are doing here firstly we should check our user. first name and surname if they exist we are going to use them if not we are going to use user. username and here is going to be user. count. posts user dot count. followers and followings let's see I'm going to refresh okay not found let's check our user name okay Lama oh I said if it's not blocked if it should be if it's blocked okay so right now I can use my information here if you remember we are passing here the user ID instead of this ID let's pass our user let's open up the right menu and here is going to be user and its type will be user that comes from Prisma client so we can directly get the type from the schema as you can see and I will say if there's a user use the information card and the media card and again I'm going to change my props just like that and here okay so inside the information we can use this user I'll do exactly the same thing here let's copy this and paste here is going to be user do username if there is a description we are going to show it here just like that and I will do the same thing for the others if there's a city use it here scroll and work and finally the website just like that and here is going to be the created ad date but I cannot use it directly here firstly I should format my date so firstly I'm going to take the created ad date and it's going to be new date and I will pass here user do created at date and after that let's say const and I'm going to take this date and I'm going to transform this into local date string it's going to be English and us and we are going to take the year month and day it's going to be numeric and day so let's use it right now just like that and I'm going to write here joint and right now it's going to give the month name the day and the year as you can see we have only username and right now let's take care of these follow and block buttons firstly we are going to check our following status here it can be following not following or follow request sent and here it can be blocked or not blocked so let's attach those details first to do that I will say async and we are going to have three states is user blocked let's say false is following and is following request sent let's get our user ID user ID let's say current user it comes from clerk off and I will say if there's a current user there's a typo here fetch our following and block status first here I will say const block response await Prisma client loog table and find First and let's write our condition here remember we have blocker and blocked ID it's going to be the current user ID and blocked ID will be user. ID so is user blocked will be true otherwise it's going to be false so I can do the same thing for the others follow response we are going to check the follower table and the follower ID will be current user ID and the following ID will be the user ID and if there's a response that means we already follow this user so is following will be true and last one will be follow request and we have the sender ID and the receiver ID if you forget the naming just check your schema everything is here actually let's see request response and if it exists that means we already sent the request is follow sent will be true by the way since we are patching data here we can use suspense block on our right menu so our application will be faster we are going to see our menu here and after we are going to patch our data let's say suspense that comes from react and the fallback will be loading we can show here any loading indicator or any skeleton but it can stay like that and I will do the same thing for the media card because we are going to fch those images so during the loading we can show this text in this case we don't have to wait we can see our right menu immediately and right now using these variables I can change my status but to do that I'm going to create one more component because it's going to be a client component we are going to be using on click event to do that let's open our menu and create one more component let's actually organize our components I'm going to create a new folder I will say feed and I'm going to pass my feed here comments at post actually it's not inside the feed it can stay here we have post and one more folder let's say left menu and we are going to have here this left menu and the profile cart and one more and it's going to be right menu and we can pass here birthdays requests right menu user info and media card okay of course after doing this you should fix your path let's check here I'm going to remove them and import again I should have done this at the beginning but anyway it will not take long and for this page just like that inside feets why it doesn't work let's close everything I'm going to save here open up feed okay let's restart our application again I'm going to terminate and delete my next folder let's run it again oh okay what was the reason I don't know but it works right now okay there is something wrong on the left menu let's import them and the right menu everything looks okay let's refresh okay okay right now I can create my component inside right menu I will say user infoart interaction let's create our component and make this a client [Music] component and use it inside our card component it's the media card it's going to be this component and right now I'm going to delete this button and span let's cut and call our interaction component just like that and we are going to pass our user ID because we are going to need it when we follow our block to user we are also going to need the current user ID and I will pass is user blocked is following and is following sent okay let's take them as a prop but before I'm going to paste my items just like that so I'm going to write my props here and right now I'm going to write my types it's going to be a string string buan buan and buum don't forget to add semicolons and here here is going to be colum let's change our texts I will say if user is blocked it's going to be unblock user if it's not block user and here I will say if it's following it's going to be following if it's not we are going to check if we sent the request or not if we sent it's going to be friend request sent and if it's not we will say follow so we can click and follow the user let's change our style I will say with pull just like that and move this block to here here I can actually delete this do we already have inside the info card as you can see we can use exactly the same style right now what I'm going to do is wrap my items with HDML form element because when we click them we are going to call our actions so I will say form I'm going to rra my button again another form I can move this to my form otherwise it's going to be on the left okay so let's try to send the friend request and see how slow it is to change this follow button and after that I'm going to show you how to use use optimistic hook so I'm going to create our first action actually let's close everything open up our component again and inside the source folder if you remember we have the library and inside I'm going to create one more file let's say actions. TS everything inside this file is going to run on the server so I can say use server and I'm going to create my first action when we click on this button we are going to call this action so let's say switch follow I will say export const switch follow a sync function and we are going to get the user ID and firstly we are going to check if we already follow this user or not if we follow when we click on this button we are going to unfollow this user first see I'm going to get my user id you can also take this as a prop but I prefer using inside my server and let's write try catch block if there's an error console loog and throw this error of course I should write my type it's going to be string and and firstly I'm going to check the existing follow await Prisma follower table find First and I'm going to write my condition and remember we have the follower ID and following ID it's going to be the current user ID and here is going to be user ID of course if there is no current user ID I'm going to throw an error and let's say user is not authenticated and of course it's going to be following ID and I will say if it exists I'm to delete this existing follow since we have the item here we can use its ID Prisma follower do delete and inside the condition we can pass our ID which is existing follow. ID and if we don't have the existing follow that means we are not following that user so right now we are going to check if we sent the follow request or not if we already sent we are going to remove it if we didn't send before we are going to create a new request so again const existing follow request A8 Prisma follow request find First and the condition remember we have the sender ID and it's going to be the current user ID and here is going to be the receiver ID and if we already have we are going to remove it await Prisma again follow request delete and I can pass the ID of this request so I will say where ID equals existing follow request. ID and if not finally we are not following this user we didn't send a request before in this case we can create a new request follow request. create and I'm going to pass data here and I'm going to copy this and paste here I hope you understood here we are taking care of all our states in one function so let's run our action I'm going to come here let's close this menu and I'm not going to directly call my action because we are going to change our states here so we are going to use those props inside a use State hook const let's say user State set user State use State hook and I'm going to pass my items here let's say following is going to be is following blocked is going to be is blocked sorry is user blocked and finally following request sent okay right now I can use my state here okay it's exactly the same I'm using this state because when we switch follow we are going to update our items and change those texts so let's create here a function const follow Asing function and I'm going to use try catch block and I'm going to call my action here and remember we are going to pass the user ID that comes from this prop just like that and if everything is okay we are going to update this state so I will say set user state I'm going to take the previous value and I'm going to spread this value because we are not going to change blocked but we are going to change our following and request status so I will say If the previous following value is true it's going to be false so if we are already following this user when I click here it's going to be false so we are going to see the follow text here and if it was already false we are not going to change anything it's still going to be false and what about this I will say if we are not following this user at the beginning and also if we didn't send the request before it's going to be true otherwise it's going to be false if we are already following this user we are not going to change this state it was false it's still going to be false but if we are not following this time we are going to check if we already sent the request or not if we already sent we are going to remove our request and it's going to be false but if we didn't send before it's going to be true so let's see I'm going to use this action here I will save and let's click I'm going to click and friend request sent if I click again it removes the request and it says follow but as you realize when I click here there is a small latency I'm going to click 3 2 1 as you can see there's a latency and if you have thousands of users is going to be much slower because what we are doing here is firstly we are waiting the response from this action and after updating our status but after react 19 we can update our UI immediately using use optimistic hook so as soon as I click on this button I'm going to update my state using that hook and after I'm going to wait my answer if everything is okay I'm going to set my state and use optimistic Hook is going to use the value inside this state and if there's an error use optimistic Hook is going to take the changes back let's open up the documentation and try to understand better I'm going to zoom in as you can see we are going to have the optimistic State here and the function that we want to run and we are going to pass here our state that will be this state and we are going to run this update function in this function we are going to update our state immediately and we are going to wait the answer from the back end if everything is okay or if there is an error it's going to update our state this user State and use up optimistic Hook is going to change that state according to user State let's see the example by the way it's a New Concept if you are having trouble to understand don't worry you have to practice and try to understand let's scroll down okay there's a great example here if I write anything here and sent as you can see it optimistically changes our state let's actually open the bigger screen okay let's see our main State as you can see it's here it's an array and it shows our messages as you can see there is only one message here and what we are going to try to do is when we write here anything and click on this button we are going to try to send it to our database but during this process instead of waiting we are going to directly show our text here and next to this text we can write sending like that and after the successful response we are going to update our main State and use optimistic Hook is going to use that text from this state it's not going to write sending anymore let's see there's is a form action here and inside we are running our optimistic function and we are passing here the message that we write inside this input use optimistic hook takes that message and adds that inside our state so if we use here optimistic messages instead of this main messages we can see our changes immediately after that we are going to run our server action it's going to send this message to database and it's going to update our main State here use optimistic Hook is going to check if everything is okay or if there is anything wrong if there is a successful response or the error response it's going to use this main State again so I'm going to close here here and here let's write our hook I will come here and say const optimistic follow and the function name switch optimistic follow you can give any name you want it doesn't matter let's use our hook I'm going to pass here my main state which is us user State and here we are going to write our function we can take the previous state so here we are going to do exactly the same thing I'm going to spread my previous state and I'm going to change to following and following request sent of course here is going to be State and right now instead of the main State we are going to be using optimistic State just like that and we are going to call our function when we run this follow function we can pass any argument here and change our state using that value but we don't have any let's leave it empty and let's see right now as you can see it's exactly the same state but when I click here it immediately changes my UI and sends my request I'm going to click again 3 2 1 and perfect let's make a mistake on purpose when we try to create new request I'm going to change this name as you can see it changes my UI immediately but as soon as we get the answer from the data datase it changes our state to initial State again I'm going to click 3 2 1 and perfect this is why we are using optimistic hook right now I can do the same thing for the Block action let's create our action I'll say const actually export const switch block again we are going to get the user ID it's going to be a string I'm going to get my user ID and let's write try catch if there's an error console lock and throw and again when we click on this button we are going to check if we already blocked that user or not if we did we are going to delete that block if we didn't block this user before we are going to create a new block so I'll say const existing block A8 Prisma do block table find First and again blocker ID the current ID and the blocked ID will be the user ID it's going to be blocker and blocked and again if we don't have the user ID we are going to throw an error user is not authenticated and right now if we have the existing block we can delete that block await pisma block table and delete we can use this ID where the ID will be existing block. ID and if we didn't block this user before we are going to create a new block block. create and we are going to pass our data here and the blocker ID and blocked ID I'm going to save and let's use it I'm going to create one more function and we can create different optimistic hook or we can use just one hook because our state includes this blocked also so instead of optimistic follow let's say optimistic State and switch optimistic State okay and I can write here a condition this time I can send my value and it can be either follow or block and I will say if the value equals follow return this state I'm going to delete this brackets here and if not I'm going to write the previous state and I'm going to change blocked and it's going to be the opposite of the previous value by the way there is something wrong here oops I forgot C here and perfect so if we pass here follow it's going to change the state like that if it's Block it's going to change the state like that by the way let's change the name it's going to be switch optimistic State and let's do the same thing for this block again I'm going to be using my function and this time it's going to be block and I will say try catch await switch block and we are going to pass the user ID and if everything is okay we are going to update our main State set user state I'm going to take the previous value and I'm going to change the blog field let's drop this and that's all let's use this action right now okay there's a the typo here let's see I'm going to refresh and click here okay nothing happened because we are not using a button here if there is no button we cannot send our form let's click again and perfect I'm going to click 3 2 1 and and it's immediately here let's take this back and let's test last time I'm going to click print request send and block user okay perfect if you want to you can separate your forms instead of directly writing them inside the parent you can separate them but it can stay like that so let's take care of these media I'm going to close them open my media component and here I'll will say async and we are going to try to patch all the images from the posts of course belonging this user so I will come here and say const post with media I'll will say O8 Prisma do Post model and I will say find many we are going to fch all the posts of this user but we are going to add here a limit the maximum number of the posts will be eight let's import firstly I'm going to pass my user ID user ID will be user. ID and also I'm going to fatch the posts with images if we have only description we are not going to have any image so we don't need them so I will say image not null and I will say take only eight item and order by the created ad date descending let's use them right now I can delete all these items I'm going to leave only one of them and I'll write a condition I will say H with media do length map through this item and for each post show this div if not right here no media F so let's give here a unique key it's going to be post. ID and instead of this Source we are going to show pause. image there is a problem here because image which is optional but since we are fetching posts with images we are sure that it exists just like that I'm going to save as you can see no media found let's check our studio find the posts okay we removed our posts so let's create another one I'm going to copy my user ID let's say description I will pass any image here but before let's choose our user as you can see we can choose it like that and let's open up pexels and add this image I'm going to save let's refresh the page and as you can see our item is here and we have one post okay it works by the way let's take care of the friend requests and of course this is our profile page we shouldn't see this follow and block user forms here let's open our information card again and of course if there is no user ID we shouldn't see this interaction and also this ID shouldn't be equal to user. ID let's WRA them like that okay there is still a problem oh there's a mistake here by the way we don't use this we don't need this actually because we are using our current user ID in the server actions so I'm going to delete this and I'm going to save okay and I can update this button also if you are the owner of this profile page I'm going to add here a button that we can update our information I'm going to come back I'm going to write a condition if the current user ID equals user ID we are going to show our update button if not we are going to show this link and inside I'm going to create one more component and I will say update user just like that of course it's going to be user. ID okay it's here we are going to take care of this later before let's see how to accept or decline our requests let's open up our component I'll close everything here and friend requests I will say async and I'm going to patch all the requests we have again we are going to need our ID and if there is no user ID we shouldn't see this component so I will say return n and if we have the user ID we can patch our requests A8 Prisma follow requests find many we are going to fatch all the requests we have and we are going to pass here Our receiver ID and it's going to be the user ID and also we are going to need the user inform information as you can see we need this AAR and username so again I can use include let's check our schema inside follow request we have the center so using this field we can get all the information just like that and again if we don't have any request we are not going to see this component request. length if it equals zero return no and finally we can map through our requests and show the users so let's remove them I will remove the second and the third one and let's WRA this and I'm going to be using my array and show my requests but there's something important here when I accept or decline this request we should remove this request immediately so again we can use use optimistic hook and if you are using a hook your component should be a client component if you want to you can fatch your requests in the client component but if you are fetching something I highly recommend you to use a server component so what we can do here is we can create another component friend request list and it's going to be use client let's create our component and let's cut here and use our friend request list component just like that and I'm going to pass my requests let's take this as a prop I'm going to write my type but before let me paste my items import this image okay so I'm not going to write here request because remember we are not fetching only our requests we are also fetching the user so we should include this sender also so I'm going to write here my type and I will say request with user and let's call all the request from Prisma client oops it's not here oh it's follow request okay and also I'm going to add my sender and its type will be user again it comes from Prisma client so let's use it here and right now I can map through my items after that we are going to be using use optimistic hook for each request we are going to call this D by the way it's going to be an array let's wrap this div and we need to add a unique key here and I will say request. ID okay as you can see it's not here because we don't have any request so let's create a new user and send a request okay I created a new user so let's find our profile oops llama and I'm going to send a request let's see I'm going to refresh my page and as you can see we have a request here so let's change the user information request I'm going to close this menu sender Avatar and if it doesn't exist no avatar.png and here remember what we were doing we are going to get the username and surname and if it doesn't exist we are going to show this username and I will say request do sender okay and perfect right now I can write my X we are going to have two actions accept and decline let's open our server actions I'm going to create a new one export const accept follow request async and we are going to get the user ID and we are going to get the current user ID ID from clerk off and as we always do if there is no user send this error and again we are going to try to find the existing request and we are going to delete that request and add this user to our followers list so I will say const existing H request await Prisma follow request dot find First and as we always do I'm going to pass my users here sender will be the user ID and the receiver will be the current user ID because this user is sending the request and after if it exists we are going to delete this request we are not going to need this anymore so we are not going to see it here I will say delete and the ID will be exit existing follow request. ID and finally we are going to create a new follower do create we are going to pass our data and the follower ID will be the user ID and the following ID will be the current user ID so this user is going to follow us if we accept I can catch my Errors By the way okay so let's do the same thing for the decline request again we are going to find the request and delete it but this time we are not going to create any follow we are just going to remove the request okay let's come here and let's create our optimistic request firstly I'm going to create a use State request list or let's say State use Tate hook and I'm going to pass it here and after I'm going to create my optimistic function and in any case we are going to remove this item so it's going to be easy const optimistic requests and remove optimistic request let's call our hook here we are going to take our main State this is going to be the previous state and a value and this is going to be the ID of the request because using this ID we are going to remove our item from the request State so let's see state. filter for each request check the request IDs and make sure that it doesn't equal this value so we are going to filter our items just like that so let's create our functions for the forms first one will be accept ACN we are going to pass the request ID it's going to be a number and also the user ID and it's going to be a string and we are going to call our function here and we are going to pass our request ID so it's going to remove this from the state and after I will say try catch we are going to call our server action accept follow request and we are going to pass here our user ID and if everything is okay finally we can update our main state I'm going to take the previous value and I'm going to filter just like that let's do the same thing for the decline again we are going to remove and here is going to be decline follow request so let's call them here I'm going to create a form it's going to be the except function but remember we should pass here the request ID and the user ID I will say request. ID and request do sender ID let's create here a button and wrap our image I will do the same thing here and here is going to be Decline and we are going to be using optimistic requests just like that let's see I'm going to refresh my page and let's accept as you can see it's gone if I refresh my page it's not here anymore because John is following us right now of course you don't have to use use optimistic for that when we create our comments we are going to see the real benefit but anyway I wanted to show you how to use it so what else we can do we can update our profile page remember we created a component I'm going to close them and open update and I'm going to come here and say use client and we are going to take the user as a prop let's open up our information card and we are going to pass our user here firstly I'm going to create a span and I will say update let's give a class name text will be blue and it's going to be X small and the cursor will be pointer okay and when I click on this button I'm going to show my form here so let's create here a state that we can decide if the form is open or not set open new state hook and at the beginning it's going to be false and when we click on this button we are going to update our state and it's going to be true and if it's true we we can show our form to do that I can create a div here and it's going to be our overlay and its Position will be absolute it's going to contain all our screen and in the middle of that overlay we are going to show the form so let's say absolute with screen height screen let's go top and left background will be black and the background opacity will be let's say 65 let's Center everything Flags item Center justy Center and this overlay should be over everything so I'm going to give here Z index just like that and inside I can create my form let's give a class name I'm going to give a padding background will be white rounded will be ALG I'm going to give a shadow so let's say flax flax column and gap between items will be two and for the small screens it's going to be full screen for MD it's going to be smaller and for x large it's going to be even smaller let's see okay it's here but why it's open because we didn't write any condition here I will say if it's open so when I click here we can see our form and also I can create here a button that we can close this form so here I'll say d and you can use any image but I'm going to be using X and when we click on this button we are going to close our model so set open will be false actually let's write here handle close because when we update our user we are going to refresh our information and after that we are going to close our model let's give a class name it's going to be absolute because I'm going to show it somewhere here and if you are using absolute positioning the parent should be relative but we are using absolute here so let's move our item inside the form just like that now I will say text algae and I'm going to give my position right two top three and the cursor will be pointer just like that okay so let's create our H1 tag and I'm going to write here a text and I will say if you want to change the username or the avatar use this Nar button let's do that I'll say H1 tag update profile and after that I'm going to create a div and inside let's say use the nowbar profile to change the AAR or username and I will say margin top text will be X small and the text will be gray and right now we can create a d that we can update our C picture let's say label cover picture and I'm going to create another D here that we can show our c p picture and a text that we can click and change it so I will say Flex item Center and gap between image and text will be two and cursor pointer let's say image I will give width and height since we are using the C picture I'm going to make it horizontal you can give any number and let's give our last name by the way I will import okay height will be eight round it will be MD and object cover and after that let's create a span and I will say change text will be X small I will give underline and change the color let's open okay let's give our cover picture Source remember we have the user here I will say user do c and if it doesn't exist no c.png okay let's go space here I will say flags flags column G between items will be four and also I'm going to give margin vertically just like that after when we click on this do we are going to show the uploading component but for now it can stay like that let's design our form firstly I'm going to create a main div that covers all our input and I will say flax flax W remember why we are using this our items will be horizontal but if they don't fit inside this form container flx St will move them to other line I will say justy between in any case I'm going to give Gap and for XL screen Gap will be four let's create our first input we are going to have a label and input Insight so let's say flx flx call and gap between label and input will be four let's create our label text will be X small and gray and let's say first name and after my input and I will say placeholder and and I'm going to be using my user and I will say use the name and if it doesn't exist right here an example just like that let's say input and I'm going to create some other items here is going to be surname surname or the example here is going to be description user description or an example City here is going to be skull let's say MIT work apple and finally website okay I can delete the others right now I can create here a button I'll say update let's say background blue I'm going to give some padding and margin top round it will be empty text will be white and let's check as you can see we don't have any style for the inputs I forgot to give let's give quickly I'm going to choose all my inputs and I'll say class name firstly I'm going to give a ring and its color will be gray let's give some padding I'm going to give a specific padding just like that round it will be empty and the text will be small okay but we should see here two items let's say title C picture upload oh because I said input here but it should be inside this D remember this is our parent du I'll say rer so I'm going to delete other containers here and this div and I'm going to move them to my rupper so let's copy them and paste here let's see right now and perfect so let's create our server action and send our inputs actions and I will create my action here export const update profile it's going to be async later we are going to upload our C picture but for now let's update our profile without image I'm going to get the form data and remember how we are reaching to data inside the form we should give unique IDs for our inputs let's do that I'll see name website this is going to be work here is going to be skull C description surname and name okay so we can get our username just like that from data. getet and the input name which is name and I will say as string but instead of doing the same thing for others one by one we can get all the fields from the form data const fields and I'll say object from entries and I'm going to pass here my form data and it's going to return all the fields inside the form let's see console log fields and I'm going to call my action where is our form here let's import open our terminal and write here something description City school work and website if I send as you can see all our items are here but before send sending them to our database firstly I want to verify them because I want to make sure that they are string and we are going to give a limit to do that we are going to install a library I'll say mpm install zot okay let's close here and let's create our zot object I'll say const profile Z that comes from zot object and inside I'm going to write my fields we are going to have the C picture Z do string its type will be string and it's going to be optional you don't have to add this and one more I'll say first name again string optional but also I'm going to give here maximum and it's going to be 60 if you want to you can write additional requirements but it can stay like that I just wanted to show you and I'm going to write the others surname description but if I remember correctly description is okay it's the long version and let's change here okay and I'm going to change this number it can be longer City school work and website and right now I'm going to validate my fields to do that I'll say const validated fields and I'm going to be using my object profile and save pass and I'm going to pass here my fields and if there is any problem if it's not validated it's going to return us an error let's say if validated Fields is not successful we are going to return an error but for now let's say console lock validated Fields do error do flatten and we are going to show all the field errors I'm going to save Let's test it I'm going to make this maximum one and if if I write something longer than one as you can see it shows this error string must contain maximum one character and which field as you can see name okay so after validating our inputs finally we can send them to our datab base try catch console lock this this error and after we are going to send our errors but for now let's try to update our profile I'll say Prisma user. update where and the ID will be user ID of course we need to get this from clerk I will say if it doesn't exist return error later we are going to change it and here I'm going to pass my data and it's going to be validated Fields do data okay there is something wrong of course if there is an error we should return anything as I said we are going to change them don't worry about them let's see I will say John do I will update let's refresh the page okay it's still the same because I forgot to change here let's try again I will refresh and as you can see our user is updated but if I try to change change only my username I'm going to refresh and let's check our inputs and as you can see it updated my first name but removed my surname because we are passing here an empty string and it updates our surname to prevent this I'm going to filter my Fields let's say con filtered Fields again object from entries and inside again object this time I'm going to be using n3s and I'm going to pass my fields and I'm going to filter them I will get all the keys and values and I will say if the value equals an empty string don't take them if it doesn't move them to filtered fields in this case if we have an empty string in one of our fields we are not going to take them so let's paste this filtered Fields here I'm going to save this time let's say jnto I'm going to update refresh my page I'm going to come here I'm just going to change my surname and you are going to going to see that John is still here I'm going to update refresh and perfect this is how we are updating our profile but what about the C picture to do that we are going to be using cloudinary let's open up cloud.com and login and this is going to be your Cloud name we are going to be using this and after that click on settings find the upload by the way you don't have to pay anything it has a really generous fre tier and as you can see those are our previous applications so I'm going to create a new one and let's say social it's going to be unsigned and you can write any folder name let's say uploads and I'm going to save so we are also going to use this upload preset let's open up our documentation and see how to use cloudinary widget so I'm going to open up the nextjs documentation next. cloud. and firstly we are going to install this Library that's let's open our console mpm install next Cloud after that as you can see we can use this upload widget we are going to pass here upload preset let's copy this close here and open our component and right now I'm going to wrap my items with this Cloud inary widget let's paste it here and instead of this button I'm going to show this do just like that so when we click on this do we are going to open our widget just like that okay our preset name is social let's import okay it's not coming by way there's something wrong here it's because it's not compatible with next ja 15 I think let's try to use yarn next J cloudinary since we are using nextjs 15 and react 19 you might have some small problems but after this table versions you're not going to have any problem and let's see how it works when I click here as you can see it opens this component so we can drag and drop our images we can add any URL here camera and any storage provider so it handles everything for us I think we need also add our API script so let's come here and open up API keys and I'm going to paste my API secret let's copy this open the EMV file so I will say next public cloudinary API key and I'm going to paste it here and also I'm going to paste my cloud name it's lad Dev and also I'm going to add my API secret and it's here I'm going to copy just like that I'm going to save and let's see I'm going to come here open my model and click here it opens our widget so we can upload any image and if it's successful it's going to return the result so I will say on success and we are going to take that result and let console look I'm going to choose any image and as you can see we have an object here and inside we have the info and inside this object we have the secure URL and it includes our image path so we can use it firstly I'm going to create a use state that we can store our image I'll say C set C type will be any and if we have the result we are going to update our image set C and I'll say result doino and right now I'm going to also send my image URL by default it's just sending the form data so I'm going to take it pass it here and I'm going to send my URL which is c. secure URL let's take this here I'll say C and its type will be string so right now I can pass my cover here I'm going to spread all the fields inside these fields but also I'm going to pass here cover let's see right now I'm going to refresh open my form let's choose any image this one chain door my description City school work and website I'm going to update let's refresh the page and as you can see we have a problem here that because we didn't add this URL to nexj configuration I'm going to add one more object here and it's going to be cloud.com I will refresh and our col picture is here okay but when we send our form we cannot see any error or success message to communicate with the server actions we can use use action State hook basically we are going to create an initial State at the beginning success and error will be false and we are going to send that state to our actions and we can take this and update it in our function let me show you and you are going to understand better so instead of directly sending our data I'm going to create use action State hook const State form action and use action State hook and here we are going to write our server action which is update profile and we are going to send our initial State at the beginning success will be false and error will be false let me actually open up the documentation so I can explain better as you can see it's the new feature let me scroll down okay there is an example here as you can see we have a form and a button and when we click on this button instead of calling our server action directly we are calling this form action that comes from use action State and we have the initial State here we are passing this to server action its value is zero at the beginning our number will be zero and we are passing here the server action as you can see it's here it takes our previous state which is zero and form data and here you can make any cruit operation or whatever you want and finally you should return a new state as you can see it increasing the previous state so when I click on this button it was Zero at the beginning is going to be one and we can use that State anywhere we want and in our case our state is success and error when we update our profile if it's successful we are going to return success true error false and if there's an error success false error true and using this state we can show our success or error message so after our button I'll say if state do success right here as span profile has been updated and if there is an error something went wrong let's give class name is going to be green and here is going to be red of course instead of writing this specific error you can return your error message but it can stay like that let's pass it to our action server action as you can see there's an error here so I'm going to come here and say previous state it's going to include success which is bullan and error and here is going to be our payload so let's take our data and cover from the payload const from data and cover from payot okay right now if we have any problem we can update our state so success will be false error will be true as you can see we are returning a string this time I will say success and error will be true I can do the same thing here and and here and if everything is okay this time success will be true and error will be false I'm going to save as you can see there is no error anymore and this time I'm going to call this form action and I'm going to pass my form data and cover picture just like that and let's say cover and if we don't have any image instead of sending null let's send an empty string because remember we are filtering our object here if it's an empty string we are not going to take it let's see our Spence as you can see there's no problem anymore so let's see right now I'm going to come here open my form let's say John I'm going to update and as you can see there is no problem and if I come here and change my maximum here let's write something I will update and this time something went wrong okay it works and as I said instead of true and false you can send your error and show it here and if you remember we have the handle close function here so when we close our form we are going to refresh our page of course course if it's successful to do that I'm going to be using use router hook const router use router that comes from next navigation don't use this one it's a previous version and where is our function okay here let's move it over this function and I will say if it's Successful by the way we should move this also and if it's successful we are going to be using the rou and we are going to refresh the page let's see I'm going to come here again chain I'm going to update it's successful and when I close here it's going to change my name okay awesome this is how we are using use action State and I want to show one more hook that we can use with react 19 and it's going to be use form status hook where is our button here so I'm going to cut this button I'll open my menu and I'll create a new component and it's going to be update button and it's going to be a client component because we are going to be using a hook and that hook will be use form status hook so when we click on this button this Hook is going to change the status of the progress and it's going to be pending and if there is an answer from the server action the pending will be false so let's use it here it's going to be disabled when it's pending of course it's going to be a button and I will say if it's pending right here updating if it's not update let's write our background again padding will be two margin top two and rounded will be MD text color is white and when it's disabled I'm going to change the background opacity and it's going to be 50 and also if it's disabled let me close this menu the cursor will be not allowed okay let's use it I'm going to import and let's see I'm going to click here change my username I'm going to update as you can see it was pending and we have the response right now so this is how we are using use form status hook that's all I think we can fatch our posts if we are on the profile page we are going to fatch all the posts belonging this user but if we are on the homepage we are going to Fouch our friends posts so let's come here close everything and open up feed right now I can take my username as a prop so let's say username and it's going to be a string but it will be optional because for the homepage we are not going to need any username so let's open up our profile page find the feat and pass here our username I will save and right now we can fatch our posts firstly I'm going to take the current user ID from Clark and I'm going to create a post list here and if there's a username post will be await Prisma dopost find Min I'm going to write my condition here and I will pass my username firstly let's choose the user and the username will be this username of course we should say async and also we are going to get the likes and we are going to check if the current users's ID is inside this array or not and also we are going to need the user information and finally these commments count let's do that after the condition I will say include user information will be true we are going to get the likes but if I say true it's going to get all the user informations but we are just going to need IDs here so we can check whether our current ID is inside or not so I will say select only user ID and finally I will say count select comments and true we are going to need the commments number and also we can sort our items so I will say order by created at date so we are going to see the latest posts but if we don't have username that means we are on the homepage so we can fatch all the posts that belong our friends so I will say if there is no username but user ID firstly we are going to fatch all the user IDs from the people that we follow so I will say const following await Prisma follower find mini and the follower ID will be the current users ID and again we are just going to need user IDs we don't need any unnecessary information so I will say select we are just going to need the following ID let's remember again inside the follower table we have the follower ID and following ID we are passing our ID here and we are collecting all the IDS belonging our folls and after that we are going to check whether our ID is inside this following array or not let's see what we have inside I'm going to refresh the page and follow the previous user what was the name it was John I think okay let's follow this user I will come here and accept this request and right now we are following this user but it doesn't have any post let's create quickly I will choose my users and I'm going to take this user ID and create a new post let's say test from John we don't need anything else and I'm going to paste my user ID or I can select my user here it's easier and I'm going to save let's see I'm going to refresh as you can see there is one post if I open the homepage and my terminal you are going to see that we have an array and it includes this object so let's get rid of this follower ID take only this user ID so I'll say const following IDs following map and for each item Insight we are going to return following ID oops okay it's the follower ID this is our ID it should be following ID of course so it's going to return all the people that we follow and right now let's see what we have as you can see there is only this user ID so we are going to have multiple IDs here so we are going to fatch all the posts of those users now let's say post await Prisma do paul. find Min I'm going to write my condition and the user ID will be inside this array so I'm going to be using in and following IDs and again we are going to fetch the user information likes and comments number and we are going to sort them I will save and let's remove those posts I'm just going to leave one of them and I can map through my posts for firstly I will say post do length if it exists we are going to call our posts if not no post found let's copy this and I will say post do map by the way let's write here a type and for each post Insight we are going to return this post let's give a uni key post. ID and we are going to pass our post here let's take it as a prop and again I'm going to write my type here because it includes also our user like X and count so let's see type post type and we are going to take the post from Prisma client and also we are going to have the user it's type will be user and also we are going to have likes remember it's an array and it includes our user IDs because we are selecting only ID is here so user ID will be string and finally we are going to have count and it's going to include our comments let's use it here by the way it's exactly the same name so let's change it as post type and let's change here feed post type and I'm going to use it here okay I'm going to move this here let's see okay we don't have any problem right now we can use our posts firstly this is going to be the user image so I will say post. user do aatar and if it doesn't exist no avatar.png and here is going to be username and surname remember what we are doing if post. user.name and surname exist we are going to use them if not we are going to use the username let's write the post Image First first see I write a condition and I will say if it exists let's use it here and I'm going to write my description post. description let's see okay our post is here we have the user information and description there is no image so let's take care of the likes and and comments by the way I'm going to change here we are not going to write the numbers so I will just say share then we click here we'll be able to share this post so what about here again we are going to need a client component so let's come back close everything and create our component so let's open our menu and inside feed I'm going to create a new file and let's say post interaction it's going to be a client component so right now I'm going to copy here and paste inside my component let's import this image and we are going to need the post ID we are going to need the likes and the comment number because when we like this post we are going to need the post ID we are also going to check the likes array remember it includes the user IDs and if our ID is inside that array we are going to see here a blue icon and also we are going to need this number so let's write our types it's going to be number strings array and number let's close this menu and use our component here I'm going to pass my post ID likes and the command number count. comments let's import our component and there is a problem here because remember inside the likes array we have the user IDs what I want to do is get rid of this user ID and take only strings so I will say map for each like we are going to return like. user ID okay there is something wrong again okay there's a typo okay let me check there is no problem firstly we are going to need the current users ID because we are going to check our user ID let me check if we Define this here or not okay it's not here so let's say con user ID I'm not going to be using o because remember we are using a client component so I have to use use out hook and remember it also returns is looted we are going to need it and after that I'm going to write my like State const like State set like state use State hook and inside we are going to have two items the first one will be like count and at the beginning we are going to be using likes array and its length and we are going to have is liked and I will say if there is a user ID check the likes array and if it includes our user ID that means we like this post before otherwise it's going to be false I'm using this state because again we are going to be using use optimistic hook as soon as I click on this button I'm going to change my icon and increase this number and if I click again I'm going to decrease the number so let's create I'll say optimistic like and switch optimistic like let's call our hook and I'm going to pass here my state and after we'll get the previous state and the value and we are going to return like count and I'm going to check if if we like this post before or not previous state DOT is liked in this case I'm going to decrease my number take the previous number and minus one otherwise I'm going to increase and what about is likeed I'm just going to change the previous is like okay let's use it here like count and I'm going to write here a condition actually I can use it inside this Source I will say if it's liked it's going to be like. PNG if not it's going to be like. PNG and of course we are going to need a form and a button and let's right here an action I'll say like action I'm going to use it here async firstly I'm going to run my optimistic function and I'm going to change my state we don't have any value let's leave it empty and after after that try catch block and let's create our action const switch like of course export const so we are going to need here the post ID is going to be a number and we are going to need our user user ID clerk off so let's make our request firstly we are going to check if we like this post before or not if we did we are going to remove it if we didn't we are going to create a new like we are doing exactly the same thing so let's see const existing like wait Prisma do like and find first let's write our condition the post ID will be this post ID and the user ID will be our user ID and again if there is no user ID throw an error of course it should be an async function and using this existing like ID we can remove it I will say if it exists a wait Prisma like. delete where the ID will be existing like do ID and if it doesn't exist wait Prisma like. create and I'm going to pass my data and it's going to be post ID and user ID and if there is any error console lock and throw so let's use it and I'm going to pass here the post ID and if everything is okay I can update my main State and I will do exactly the same thing here take the previous state and return them I'm going to save and let's see I'm going to like this post as you can see it works as we expected okay using use optimistic hook for this like button or the following button on the profile page was not crucial but when we add our comments we are going to see its benefits better because as soon as I add my comment I'm going to add it here and for the title we are going to write comment is sending so user is going to know that the progress is not completed yet and after the successful database request we are going to show here our username by the way let's test our like I'm going to like this post and refresh my page as you can see it's still here that means it's on the database okay let's add our comment inside the post component we have the comments component so we can take the post ID and fatch all the commments belonging that post and again we can create a client component so we can use the optimistic hook so I will say async post ID and let's say const comments await Prisma command table find mini and I'm going to pass here my post ID and also we are going to need the user information because we are going to be using this AAR and username remember how we are doing this I'll just say include user true so let's create our client component I'll say comment list I'm going to copy here and paste let's import the image okay there is something wrong here okay we need a parent let's use fragments and we are going to need our list so let's say commments commments and also we are going to need the post ID because when we add a new commment we are going to be using this post ID let's see comments and post ID and this is going to be number and here is going to be commments with users so let's create our type it's going to be comment and also we are going to have the user insight and let's use it here and of course it's an array let's see okay there is no problem let's close this menu and again we are going to need our user ID but also we are going to need our user image because we are going to be using this here and when we add a new post we are going to need our username so let's get the user information from clerk but be careful we are on the client component so we have to use a hook so I will say const user and that comes from use user hook and that includes all the information we have let's create our state I'll say use State hook and we are going to pass our commments here and let's create one more use State and it's going to be our description at the beginning it's going to be an empty string and whenever we change our input we are going to update this state so let's come here find the input and I will say on change event set description event Target value and here is going to be our Avatar user do aatar if it doesn't exist no Avatar of course if the user exists by the way we are using Clark it's not going to be Avatar it's going to be image URL and actually we can wrap our entire application and write our condition if there is no user we are not going to see this new command section okay so let's write here form if you want to you can add here a button but since we are using an input when we write something here and enter it's going to send our form so let's create our optimistic hook const optimistic commments and add optimistic comment use optimistic hook and inside I'm going to pass my main State and after that we are going to get the previous state and value and its type will be command with user and we are going to return an array and we are going to pass this value here and the previous date so we are going to leave all the previous commments and we are going to add a new one so right now we can use our array I'm going to wrap this comment where it ends here and I will say optimistic commands do map and for each command inside we are going to return this div I'm going to cut this and paste here let's give our uni key and here is going to be command. user. aatar and no Avatar PNG and here is going to be first name and the surname and if they don't exist we are going to be using our username if there is a name and and surname we are going to use them if not we are going to be using the username here is going to be the description and again as we did for the post you can get all the likes and you can add here the like button but let's leave it like that firstly we are going to add our comment and let's write our action I'm going to save here open my actions and I will say export const add command of course it's going to be async and we are going to need the host ID is going to be a number and the description let's get our user ID and as we always do I'm going to throw this error and I will say try catch I'll say const created comment Prisma command. create let's pass our data here description user ID and the post ID and we are also going to need our user information because after adding our comment we are going to update our state this is why we are going to need this created comment so I'm going to return that let's console lock this error and that's all let's use it I'm going to save my file come here and let right here a function that we can can use our server action so I'll say const at async parly I will say if there is no user or description you're not going to do anything I'll will just say return and after that we are going to be using our optimistic function and remember we are going to need our value here but before that let's say try catch const created comand is going to come from our server action and we are going to need the post ID and the description and finally we can update our state I will say take the previous Val value add our created commment and spread the previous comments so here we need to create a command with user so we are going to need a command ID let's use math and random it's not important because it's going to be visible just a second the important point is our description and our aatar so I'm going to pass here the description we need a created ad date and its type is date so let's create date. now and we are also going to need updated ad date actually for this we can use our library or anyway let's write everything here and I'm going to pass here the user ID again it's not important but you can give our ID it's not going to be visible we are going to need the post ID again you can give any number you want but let's use our post ID and finally we can add our user ID will be user ID let's see what else we need username aatar cover name name surname descriptions T school and work we have to write all of them but as I said they can be empty the important part is our AAR so I'm going to be using my user and IM and if it doesn't exist no avatar.png let's say name surname City and others and we are going to need the created ad date and finally I'm going to write my username and this is going to be visible also so let's say sending please wait we have are missing our C picture I think let's see what else okay description and that's all okay I'm going to save and let's see I'm going to write test enter nothing happened because we didn't use our function I'm going to use it here let's write it again I'm going to enter okay it was here but it's gone because there is a mistake oh we didn't pass here post id post. id okay let's see again I'm going to refresh my page and I'm going to write test me enter and as you can see our Command is here let's test again just like that this is why use optimistic Hook is so important you can immediately update your UI and it's going to be much better for the user experience by the way I didn't change this number let's open our poost interaction component okay I'll say command number as you can see we have two comments okay so let's add a post and story and complete our tutorial I'm going to open my action and I will say export const add post let's open our component and I'm going to close the others by the way we are going to need our user avar here and it's going to be a client component let's remove this and here I'll will say user and use user hook and also we can use is loaded and I will say if it's not loaded return loading and here I can use my AAR and we have the form here and inside there is a text area again we can create a use State set description and it's going to be an empty string let's update you want Target and value and also we are going to need an image let's create one more use State I'll say any and again I'm going to be using my widget so let's open update user component and copy our widget and paste it here I'm going to import I will say set image and instead of this D I'm going to return my image and this text okay and when we click on this two we are going to open our widget so I'll say onclick open by the way you can also take the widget object after setting our state we can close this widget just like that so we don't have to click on the button to close our widget okay let's change our button actually we can create a new component because I want to use use form status hook add post button use client const pending use form status hook it's going to be a button and I will say disable this this button if it's pending and I will say if it's pending right here sending if it's not sent let's give class name if it's disabled it's going to be lighter and the cursor will be not allowed we can also add here a spinner again I'm going to copy and paste you don't have to memorize anything here just search for Tailwind Spinners and you are going to see tons of examples and I will say sending let's say flag align item Center and gap between spinner and sending will be two let's also give here some padding margin top will be two round it will be empty and the text color will be white let's use it here so let's drop this okay but why it's light oh it should be 500 if it's disabled it's going to be 300 okay so when I click on this button I'm going to call my action I'll say add post but if you are using form action by default you are sending your form data so let's say form data send this dat data and also sent our image and it's going to be image do secure URL and if it doesn't exist we can send an empty string let's import this and let's write here form data and also an image of course we don't need this we are going to directly send our string okay so right now we can take our description remember we have the name here but while we are using this state if you want to you can delete this description State you can directly use our form data but remember we have an emoji here when I click here we'll be able to choose any image and update our state but since we are not using the stable version of next Jazz and react this library is not compatible but in any case I'm going to add it to GitHub repository you can check and see how to use it so I can leave this description here I'm going to update this file for now let's use our form data so I will say const description form data dog and description if there is no description I will just say return and again you can use use form action hook and you can return your error let's get our user ID or I can validate my description and it's going to be Z do string minimum will be one and the maximum will be 255 let's validate our description I'm going to pass here my description if it's not successful you can send your error and if everything is okay we can create here try catch block and and send our post I will say await Prisma dopost do create and I'm going to pass my data the description will be validated description. data of course if we have any error I'm just going to return and we are going to have the user ID and the image and as we always do if there is no user ID we can throw this error and after that if everything is okay we can revalidate our path so it's going to revalidate our post and we can see our post here so I will say the Home Path I will save let actually console lock our errors in any case I'm going to refresh test me I'm going to choose an image I'm going to send okay it's not here let's check our terminal okay we don't have any problem I'm going to check my feed okay as you can see we are patching all our friends posts but it doesn't include our ID so additionally I'm going to add my ID here so let's say const IDs user ID and all the following IDs so let's use it here and as you can see our post is here let's test it again I'm going to send and perfect so what about the story firstly we are going to have here an add button when we click here again we are going to show our our widget and we can select any image and after that we are going to add it here but before let's fetch all the stories from the friends so I'm going to come here close everything open up stories I'll say async const stories O8 Prisma stor is table let's import this okay and I'll will say find many firstly I'll will say the expires at date will be greater than this date because when we create a story it's going to be available for 24 hours and after that it's going to expire so we are not going to see it here again we are going to need all our followings IDs remember inside Feit we are getting all our followings but actually there is a shortcut we can use it here and firstly I'm going to be using or because it can be our following stories and our own stories firstly let's take care of our followings I will say story user and its followers and some of those followers will be us so let's say follower ID equals our current user ID so let's call this I'll say current user ID just like that of of course if it doesn't exist we are not going to see this component okay here is a little bit complicated this is why I use this method there are some nested items here basically we are searching for a story let's open up our schema and inside our story we have a user and that user has some followers because remember inside user we have the followers and inside the followers we have the follower ID we are searching ID inside the follower inside the user inside the story and also the user ID can be our current user ID so we can see our stories also and finally we are going to need the user information because we are going to use this name and image so I'm going to come here and say include user and true okay you can choose this method or this method and after that let's use it but again I'm going to create a client component because I want to use use optimistic hook and also we are going to need here a widget so we will use a click event story list. TSX I'm going to get the stories and also we can get the user ID it's going to be a string and this is going to be story with user so let's write our type let's import this also okay let's use it here and it's going to be an array let's pass our stories and user ID so I'm going to copy one of these stories and remove the rest of them and let's call our component I'm going to pass my stories and the user ID okay I'm going to save close this menu let's come here and I'm going to paste this post let's import here we are going to change this Source but before let's create our main State I'll say story list set story list and I'm going to pass my stories here and one more use State and it's going to be our image and it's going to be our cloudinary image and actually we can delete this user ID because we are going to need our AAR here so I can use use user hook and get my user information so let's remove this and I will say const user use user hook and let's create our optimistic hook optimistic stories add optimistic story we are going to pass here our main State the previous state and the value and again we are going to pass here story with user and it's going to return us an array we are going to get all the previous stories and also we are going to add here the new story which is value there's a typo here and let's use it here optimistic stories. map for each story Insight we are going to call this D I'm going to give my unique key and here is going to be story. user. aatar and here is going to be story do user.name and if it doesn't exist story. user. username okay I'm going to open up add post component copy this widget and paste it here by the way we can use here fragments okay let's import this widget we are going to set our image we are going to close our widget and here is going to be again this do and I will say if there is an image use the secure URL if not use the user Avatar and if it doesn't exist finally use the no Avatar and here I'll say add a story and let's open this widget here on click event and open and I'm going to create here a do and we are going to write here a plus sign and let's say position absolute text 6X large and the text will be gray let's see let's move this plus sign and of course the parent should be relative okay it's on the middle when I click here it's going to open this widget we can choose any image and after choosing we can create here a button that we can add our story so let's actually write here a condition I'll say if there's an image create here a form if not show this span and inside we are going to have a button and I will say sent let's give class name quickly TX will be X small BG blue padding will be one and round it will be empty let's give text color okay but when I click here it's going to open my widget again because we have on click event here so instead of here let's use it on our image okay so when I click here I'm going to add my story optimistically and after that we are going to run a server action by the way let's give here object f and I will say At Con at Asing function and I'll will say if there is no URL don't do anything and I will say add optimistic story it can stay like that for now and I will say try catch and let's call our server action you don't have yet let's create we are going to do exactly the same thing here I'll say add story but we are going to have only image we don't need this description or any validation and I will say Prisma story. create image and user ID and also I will give expires at date date do now and I'm going to add one more date okay but there is something wrong here let's open up our schema we don't have any image let's add it's going to be a string I'll will save and push it to my database I'll say MPX Prisma DB and push okay but if you remember we can add only one story so if we already have a story we are going to remove it and create a new one so let's say const existing story await Prisma Story table find First and we are going to pass here our user ID and if it exists we are going to remove it and the ID will be existing story. ID and we are going to need our created story because we are using optimistic hook so let's say const created story and return this we are not going to revalidate anything and remember we also need our user information User will be true okay let's use it right now I'm going to import and pass my URL okay and remember when we add a new command we are giving all this information so we will be doing exactly the same thing we are going to have the image we are going to need the expir adate and we don't need this by the way if it's loading if there is no user and not loaded we are going to return loading and if it's loaded and there is no User it's going to be null and if it's loaded and there is a user we are going to be using our component and again let's say sending by the way there is something wrong okay we cannot use use optimistic conditionally so instead of this let's get the user ID from the parent so I will say user ID and let's remove this condition also and finally we can set our story let's say const created story and I'll will say take the previous and spread it here and what's wrong here it says it can be undefined but we are returning here story with user I'm going to check here one more time let's test by the way I'm going to also set my image and it's going to be null again and going to refresh my page let's choose an image I'm going to send and perfect okay this is how we are sending stories and there is one more thing we can do when I click here we are going to show a div and we will have a delete button let's quickly create our action export const delete post async we are going to need our post ID and as we always do let's import our user ID because we can delete only our posts so I will say try catch a wait Prisma post delete where the ID will be post ID and the user ID will be user ID and that's all after that we can revalidate our path just like that so let's open our post component by the way since we are fetching data in these components we can use suspense I will say fallback loading and there is our icon here right now I'm going to copy this create a new component let's say post info use client we are going to get the post ID and I'm going to create a use State hook it's going to be open set open at the beginning is going to be false and when I click on this image we are going to show a do so let's say on click event set open will be the opposite of previous state and after that I will say if it's open show here a do and it's going to be absolute so let's say relative here top will be four right will be zero let's give background padding order radius and I'm going to separate my items and let's give shadow and z index and inside I'm going to create a d csor pointer and let's say view repost and here is going to be a form and inside let's create our delete button and we are going to call our action but remember we are going to need a ID if you want to you can create here a hidden input and set your post ID or you can use nextjs bind method so I'm going to create here delete post with ID and we are going to call the delete post action and I will say bind and we can pass here anything we want and I will pass the post ID and let's call it here I'll say post info and I'll write my post ID let's give width here I'm going to make it bigger and let's make it red if you want to again you can use use form status hook and you can show your pending spinner but in this case I can use it for each post but it should be only for our posts by the way let's write here cursor pointer and I'm going to come here and write my condition I will say user ID it should be post. user. ID but we don't have user ID okay we are protecting our request in the action if it doesn't belong to us we are not able to delete it but in any case we should do it on the client also so I'm going to click here delete and it's gone okay awesome so we finished our project of course you can add new features you can add multiple stories you can add here some other stuff user birthdays but it's enough for this tutorial I think I don't have anything else and unique to show you these likes exactly the same we can can add stories posts like and dislike them add comments patch our posts user information we can see our friend requests media and update our user and we can also update our account okay that's all I think so we are ready to deploy our application let's terminate our local server and right now I'm going to push my application to my GitHub account remember we were using this repository and I have the starter Branch here right now I'm going to create the completed branch and I'm going to push my application there of course you should use your own repository so I'll say get in it I'm going to add everything let's write a comment it doesn't matter I'm going to add my origin and let's create a new branch of course you don't have to and the branch name and I will say get push origin and the branch name before doing that make sure that your em file file is hidden let's check our git ignore as you can see it's here I'm going to push let's refresh and it's here right now I'm going to use this repos story on my server and we are going to run our application there let's open up our server dashboard and if you remember we created our application here it's a not Jaz application and it runs on this port number since our next ja application runs on this number we are not going to change here so let's install the SSL certificate I'm going to come here let's encrypt and at this point make sure that you changed your main DNS you should be using your server IP address after doing that you will be able to install the SSL certificate okay it's ready right now we can use https connection and if you remember we created here our database if you want to you can create a new one let's say production DB lad Dev and Lama password okay we can't use the same username let's say production um production password and since we are using the same IP address for our not JS application and database we don't have to give any security rule we can directly use our database and no better s can reach to this database we can use only this IP so let's come here and right now we are going to connect to our server to do that let's open up the settings SSH keys and add SSH key right now I'm going to generate a new key on my computer and I'm going to add it here so whenever I try to connect to my server on my local desktop it's going to verify this key and it's going to allow us to enter our server so let's open up our terminal and I'm going to create a new key to do that I'm going to write this comment I'm going to save enter again and right now I'm going to copy my key to do that I'm going to be using this command okay let's give a name and paste it here I'm going to add it's going to take a while right after that we'll be able to connect to our server okay it's ready let's remember our connection this is our IP address and we can connect to our server using this command let's clear here I'm going to paste yes and we are connected if you remember our site user is L social so I'm going to come here and I will say sudu and this user let's open up the root and let's see what's inside we are going to open up this HD dogs and if I say LS you can see that our application is here let's open up and right now I'm going to install my application let's come here copy our URL and I will say git by the way we can directly use git not JS mpm since we created here a not ja application everything is ready to use I will say git clone let's clear here first and I'll say get clone and I'm going to be using a single branch and the branch name will be completed if you don't have any branch you don't have to do this I'm going to paste my URL and I'm going to install everything here so I will say dot and enter let's see okay okay our application is here let's install our dependencies mpm install and after that I'm going to add my EMV file let's delete here and I'm going to copy here and I'm going to create my EMV file file but there's a problem here since we are using the nextjs 15 you might have some problems some libraries are not compatible remember it's not the stable version but we can force to install them and it's ready I want to warn you again this is not the stable version but since it's just a tutorial there's nothing to worry about so let's create our EMV file and I'm going to edit let's paste our em here but this time I'm going to change my database remember production lad Dev production password the IP address will be the same let's check again okay and the database name is production DB and if you remember we are using a clerk web hook let's open up the dashboard and web Hooks and we are using using this endpoint this time we can add our domain https social. l. API rep Hooks and clerk again I'm going to choose my event create it and update it let me check again social lad API web hes clock okay let's copy our secret key and paste it here we don't have to change anything here I'm going to save using control X yes and enter right now we are going to build our application and I will say that it's the production mpm run B build and I will say forse and after building our application we can start okay it's ready right now let's start our application again production mpm and start I will enter and it's ready let's check I will come here and our application is here and our connection is secure we are using https let's log in and there's a problem because we created a new database but we didn't push anything so let's terminate this process I'm going to push my changes to database remember how we are doing this MPX Prisma DB and push and since we are using the same IP add address as you can see we don't have any problem and it's super fast and right now I will do exactly the same thing and I'm going to start and let's see I'm going to refresh and our application is here but when we created our account we didn't have the user table so I'm going to sign out let's delete our user I'm going to choose users and let's delete let's come back and log in again I'm going to give my username so let's see test and it's here if I refresh my page you can see that it's on our database that's like and as you realize compared to development mode it's much much faster I can't even see the sending indicator here I'm going to enter 3 2 1 as you can see it was just milliseconds okay since we are using the local connection if I close my terminal we are not going to be connected anymore to prevent this we can use pm2 so I'm going to kill my process and I will say mpm install pm2 globally and after that I'll say pm2 start mpm we can give any name here let's say social and start and I'm going to save this pm to save so even if we restart our server it's going to run it again let's check I'm going to refresh and it works okay it's that easy and that's all guys I hope you liked it if you learned something new today please like the video you can support lad by joining the channel or using the link in the description below don't forget to follow lamad social media accounts I hope I'll see you in the next tutorial goodbye