So just before we create the inner page, let's go ahead inside of our lib tokens.ts here and let's go ahead and do this to do which says change to 15 minutes. But I don't want to do 15 minutes, I actually want to do 5 minutes to improve the security even more. So we just have to change to 5 x 60 x 8000 which will turn into milliseconds representing 5 minutes. Great. So now what I want you to do is I want you to go ahead and log in using your credentials like this.
So let me just log in and I don't have my two factor out enabled so I can just freely log in and we already know how we can get the current session instead of app protected settings page by using a wait out. But what if we want this to be a client component? How will that work exactly? So let's go ahead and remove asynchronous from here and let's change this to simply be an empty object. And then let's go ahead and mark this as use client and we also have to remove this action from our form we can no longer use that and we can also remove this imports like that there we go so now we have well a pretty much unusable settings page here.
So what we have to do is we have to add use session from NextOut React. So that's how you can use the session in client components. But if you click save here you're going to get an error that use session must be wrapped in a session provider. So we can do that inside of our app layout right here. But keep in mind you don't have to do it in the layout file.
So if you only want one part of your application to be wrapped inside of that provider you can do that here. You can create a layout in the protected and we are gonna do that later. We're gonna create a layout here so perhaps you can wrap it there. But you know it really doesn't matter for this tutorial. So now let's go ahead and let's import the session provider from next out react and let's also import out from at slash out and Then in here, let's turn this into an asynchronous function Let's get the session using await out And then let's wrap our entire HTML inside of a session provider.
And let's go ahead and pass the session to be session like this. And then once this refreshes, there we go. You can see that we have the exact same thing we had before, but this time using a completely different method. So our settings page is a client component which uses useSession. But one thing that is still not working is the sign out button.
So I'm gonna show you two ways that you can do this. The simplest way in a client component is to also import sign out from next slash out react and then you can add const onClick here, sign out. And then simply, well we can remove this form now and give this button an on click, on click, like that. So if I try and click sign out now, there we go. I am signed out.
And I'm gonna show you another method that you can use which is the combination of a client component and server actions. So you can do this if you want to, you can go inside of your actions and create a new file logout.ts, mark this as user server, import signout not from nextout react but from slash out and export const logout and in here await signout so we have to turn this into an asynchronous component. So why would you want to do this? Well, this is if you want to do some server stuff before you log out the user, right? So some server stuff, right?
And you know, that's what's cool about server actions because this leave completely separated from the JavaScript bundle so you can do some stuff like I don't know clearing some information about the user, removing the user, whatever you want to do before you log out the user. So that's another way You can do that and then what you can easily do here is simply import that logout from the actions logout and then you no longer need this. Like that, so you can try that out, sign out and it's still working Great. So now what I want to do is I want to bring your attention to this use session hook right here and you can see that in order for us to access the currently logged in user we have to go to .data and then .user right so that can get pretty annoying So every single time we need the user, we would have to write session.data?user. Every single time we would have to do this just to only get this information which we need from the user, which is the role, the ID, the image, and the email and the name.
So what I wanna do is a reusable component, sorry, a reusable hook called use current user. So let's go ahead and do that. In the root of your application, create a new folder called hooks. And then inside create a new file use current user.ts in here import the use session from next out react and simply export const use current user And let's go ahead and get this session using use session. And we are simply going to return session.data user.
So we don't have to write that every single time. And I'll go back inside of app, protected settings page. And instead of using session, change this to be the user and use current user from hooks, use current user and you can remove this import from here and then simply stringify the user. There we go. So we just created a reusable hook which we can use in every single client component to quickly get access to the currently logged in user with their ID, their role, whatever we want.
Perfect. So now what I want to do is I want to go ahead and create, well style this a little bit better, right? So I want to go inside of this app here, settings and let's go ahead and well for now remove this stringifying JSON, let's just leave the sign out button and let's create a class name here to be bg-white-padding-pen-and-rounded-excel for example. So it's not really visible now but it is going to be visible when we create a layout inside of this protected folder. So go ahead and create layout.tsx right here.
Let's go ahead and export the protected layout. Let's get the children. Let's just not misspell children. And inside of here, I'm gonna add a div and simply render those children. Now the errors should go away and let's create an interface protected layout props to get the children, which are type of react.reactNode.
So we can simply assign that here, protected layout props. There we go. So now I wanna go ahead and change this layout a bit. So give this a class name of HFullWithFullFlexFlexHole and gap y 10 and let's also give it items center and justify center. And then you can go ahead and give it any background color which you like for example this one or I'm just simply going to copy the one that I have inside of my out layout here so it's that nice gradient right here I'm going to copy that and replace it here of course that's not important for this tutorial.
Great, so now we have that. What I want to build now is the navbar component. So I'm simply gonna prepare it here above the children and write navbar like this. And obviously it's not defined so we're going to get an error. So let's go inside the protected folder and create a new folder underscore components and inside of here a new file navbar.tsx.
So the reason I'm putting it here and the reason I'm using this convention well the reason I'm using this convention is because I'm writing this inside of the app folder meaning that anything inside of a folder can easily become a route if I accidentally name a file page. So this is a good convention for you to use as I explained in my second chapter of this tutorial where we went over all different kinds of folders that exist in Next.js and I'm only going to use this navbar inside of this folder so that's why I'm not putting it here in the components it's not exactly reusable. So in here let's go ahead and let's mark this as use client and let's export PONS Navbar and let's return a div Navbar component. Then you can go back to your protected layout here and import the navbar component from .slash components navbar and there we go, you should no longer be getting any errors, instead you should clearly see the navbar component. Perfect.
So, now let's go inside of this navbar component and let's go ahead and create some items inside. So first of all, I'm going to give this a class name of BGSecondary. Flex, justify between, items center, adding four, rounded extra large, width of 600 pixels and shadow SM. So I'm not gonna make this inner content responsive, that's not the point of this tutorial, right? This is just something to demonstrate how we can use our current session inside of different types of components and this specific component is simply going to be used to navigate to different items and to have a little user button from where we are able to log out.
So inside of this navbar component create a div with a class name flex and gap x2 and then here outside of that div render a paragraph user button so this is where our user button will be which is going to be a reusable component which we're going to create very soon so inside of here let's go ahead and let's import button from components UI button and let's import link from next slash link but I believe that is a default export like that and let's also import use path name from next navigation so that we know where we are so let's get the path name here use path name and now we're always going to know on which page we are. So if I go ahead and add a button here and let's go ahead and give it an as child prop. Inside let's add a link component and an href to go to slash settings where we currently are and a text settings. There we go. We now have a button which will lead us to the settings page which we are currently on.
And now what I want to do is dynamically change the variant of this button just to simply indicate whether we are on this page or not. So I'm going to write variant is going to check if the path name is Slash settings in that case is gonna be default. Otherwise, it's gonna be outline like that So it's all in one line like this and you can see that nothing changes because we are on that page So now I'm going to copy this button here and I'm gonna put it as the first button. And this one is gonna check if we are on a server component example. And let's change this to slash server and change this to server as well.
And there we go, you can see how now we have a server navigation here if you click of course you're going to get a 404 because it does not exist. So let's copy and paste this button as well and let's change this new one to go to slash client and check for the client component. So this is where we're gonna put our server component example. This is where we're gonna put our client component example. And the last one is gonna be our admin.
So let's change this to slash admin, admin and admin. Like that. So very simple. We're not going to complicate it any further than this. And now let's create a reusable user button component.
But before we do that one, I want to create a reusable logout button. So let's go ahead and go inside of components out and just as we have the login button it would make sense that we have a logout button so we can reuse that and wrap it around anything that we want. So let's mark this as use client and let's create an interface LogoutButtonProps to have optional children and export const LogoutButton let's assign those, so LogoutButtonProps and let's simply extract the children and then in here I'm simply gonna call onClick and I'm going to import that logout from my actions, which we've created in the settings page right here when I demonstrated you an alternative way of logging out. So you can use this method or you can import sign out from next out react and then called sign out here is exactly the same, right? But this actions method allows you to do something on the server side before you log out the user so I'm simply going to use that just to show you different ways of doing things.
And in here we are simply going to return a span which will render the children and onClick is going to be onClick and let's give it a class name of CursorPointer. Great, so now I want to create a reusable user button component which will use this logout button around one of the fields when we click on our image. So let's go inside of our terminal here and let's go ahead and run the following. So let me just zoom out. Let's add npx chatcny-latest-add drop-down menu.
So we're gonna need this to open up the menu when we click on the user button right so we'll wait for this to install and besides this we're also gonna need an avatar component so make sure that you have the drop down menu and the avatar inside of your project and now let's go ahead and let's go inside of components out and create a new file userbutton.dsx right here So inside of this component here let's mark it as use client and let's go ahead and let's import everything we need from add components UI drop-down menu. So in here we need the drop-down menu itself, we need the drop-down menu content, we need the drop-down menu item and we need the drop-down menu trigger so we can open it by clicking on something and let's also go ahead and prepare all the imports we need from components UI avatar. So basically those two new components which we've just added. So avatar, avatar image and avatar fallback. Like that.
Great. And now let's go ahead and export const UserButton here. And let's go ahead and return a div UserButton. And now I want to add it inside of our reusable, well, not reusable navbar component, inside of protected components navbar. Instead of rendering a text user button, let's import the user button component from components out user button and it's going to be a self-closing tag.
So import the user button from here, go back to the user button and now we can clearly see what we are developing right here. Great. So let's change this to be a drop-down menu and now let's add a drop-down menu trigger and inside of here we're gonna go ahead and add an avatar component so let's add an avatar component let's add an avatar image component which is for now simply gonna have an empty source and let's set an avatar pullback component like that and inside you can write you know anything you want if the image doesn't load or you can put any icon for example we can import fa user from react icons fa So if I render FA user here, there we go. You can see how we have a little user icon. So let's give this avatar fallback a class name of VGSky500 and let's change this to class name text white.
There we go. So it matches our background. If you want you can also put that gradient that we reused a couple of times in our project. Great! So now in order to fill this avatar image source since this is a client component we can use our reusable hook.
So const user is going to be used current user and there we go. We now have access to the user so we can write user question mark dot image or undefined like that and you can see that nothing has changed because obviously I don't have any image inside of this user but we are gonna test out GitHub and Google login so you can see how the image is automatically gonna be shown here. So now go outside of the drop-down menu trigger and let's create the drop-down menu content which is very simply going to use our reusable logout button which we just created. So I'm going to change this input to go to components out because I like to be consistent and to indicate that this is a set of reusable components which we store in this out folder here. Great and inside of this logout button we are very simply going to use the drop down menu item and write logout.
Like that. So make sure that you have the drop down menu item here. And now when you click on this, there we go, you have the option to log out. And let's go ahead and just align this content a bit better. So let's give it a class name of Width40 and a line of end.
And you can also add a little icon here. So you can use React icons, you can use Redix icons, you can use Lucid, whatever you want. So I'm going to use Redix icons, Redix UI react icons because I have that installed if you have lucid icons you can use lucid react I believe it doesn't matter And let's go ahead and simply add an exit icon here and let's just style it a bit like that. And there we go, you can see how now we have a logout button which is working and if I try and log in with my social right now, so I pressed on GitHub here, that will log me back in And there we go, you can see how now we have a logout button which is working and if I try and log in with my social right now, so I pressed on GitHub here, that will log me back in and there we go, you can see how I have my image loaded right here. Perfect.
So we just wrapped up the beginning of our inside application here. What we're gonna do next is we're gonna create an example of a server component. So how to use all of these hooks and stuff in servers, how to use that in client, how to handle admin stuff and lastly we're gonna modify this settings page right here. Great, great job.