So now let's go ahead and let's create our server example. So in this example I'm going to show you how to fetch the current user using a server component and how to fill some information. So let's go inside of the app folder protected and let's create a new folder called server. And inside the server create a new file page.dsx. Let's go ahead and export the server page and let's write a server page inside and now when you click inside of your navbar here you should be redirected to the server without 404 just confirm that your url is slash server make sure that this folder name is server make sure in your navbar that you are redirecting to slash server in the href here and that your path name is matching.
Great, so we already know how to fetch the session, right? So we have to mark this as an asynchronous function and then we do session and then we do await out from at slash out and then inside of here what we can do is json.stringify and paste that session inside. So we already know how to do that. We can see the information here but we have the same problem. If we want to get just the user we have to go to data and then we have to fetch the user.
Is it session.user or this right? So you can see that we still need an additional step here. So let's go ahead and improve that by creating a reusable lib for server components. Just as we created a reusable lib for client components, let's go ahead and create a reusable lib called auth.ts inside of the lib folder. And in here, let's go ahead and let's import auth from at slash auth and let's export const current user to be an asynchronous function which will, oh make this an arrow function which will get the session using await auth and simply return session.user.
Like that. And then we can go back to our server page and in here, so it's located in app protected server page, and in here, instead of using this, we can use user to be await current user from libauth and we can remove this import and then we can use the user inside like this and there we go now we get just the user like that So you can see the difference is that when we're using this Auth we have session?user but when we use useSession from nextAuthReact we use session.data.user so in case this changes in the future, you know, you never know you can try it yourself, maybe it will change to user right but for now for me it's .data and then .user like that great so now we have this and what we can do now is we can create a reusable component called user info so you can put this pretty much everywhere You can create it inside of this components, you can create inside of this components. I don't know, I'm just going to put it inside of Auth even though it's not exactly reusable for Auth. So perhaps simply put it inside of components.
It really doesn't matter. So userinfo.tsx and this is going to be an agnostic component. So we are not going to define whether this is a client or server component. We're not going to care. It's going to become either server or client depending on the parent.
So if the parent page is a server component and if you import a component which doesn't have anything defined that component will also be a server component. But if you import it inside of a page which has UseClient at the top then the component will automatically become a client component. So for now make sure that the server page doesn't have the use client and we're not going to care about what this is. And let's go ahead and create an interface user info props and the optional user which it can accept is going to be our extended user from add slash next out. So if you remember we have this next out DTS and in here we export a type extended user where we assign the role, right?
So then we can use that as the expected type here. So we don't have to manually write, you know, user and extend the role manually. We can just reuse this. All right. So it's going to accept the user and an optional, actually a required label, which is a string.
And let's export const user info here. And let's go ahead and destructure those props, so user info props. We'll accept the user and the label. And let's go ahead and return a card from .slash uicard which we already have installed or components uicard however you want it let's render this card and let's render the card header from components uicard as well so make sure you add this input and inside we're gonna add a paragraph with a label and let's give this a class name of text to Excel font semi-bold and text center And now let's go back to our app protected server page right here. And instead of rendering this, let's render user info from components user info as I've added this export here.
And let's go ahead and pass in the user to be user. And let's pass in the label to be for example server component like that and if you want to you can add a little emoji here. Let me just open this up for example we can use a laptop or something like that. So server component and there we go now we have a label that this is a server component. Great so let's go back inside of the user info and let's actually develop this.
So I want to give this card a class name of width 600 pixels and the shadow of medium just it looks a tiny bit better so it matches our navbar here. And now we're simply going to render a bunch of information for the user so you can see that we can easily access all of that. So below the card header, add the card content which you can import from here. So yeah, I mean you're practically done with everything that we have to learn about Auth. All I'm going to teach you now is how to render that information and how to render admin stuff, for example.
We're going to create some reusable components for the admin. But yeah, if you're just looking at how to create a login and stuff, you're done. You don't have to watch further. But if you're interested in stuff like this, continue watching. So we have space Y4 here, and now let's create a div with a class name here, flex, flex row, item center, justify, between, rounded lg, border, padding three, and shadow small.
And inside of here, we're gonna create a paragraph representing what we are trying to show so this is going to be an id of the user which is going to have a text small and font medium like that. And then we're gonna create a paragraph here, which is going to render user.id like that. And there we go. We have the user ID here. So let's go ahead and give this a class name of truncate In case the ID gets long.
Text extra small, max width is going to be 180 pixels. Font is going to be mono. Padding is going to be 1, BG slate 100 and rounded medium. There we go. So now we have a nice little representation of our ID here.
And now we can just copy and paste this entire div and render the next item which is going to be the username. So user.name right here. There we go, we have the name. And what I recommend you actually do for now is log out if you're using an OAuth and go inside of your credential login because we're gonna have to show different things depending on whether we're logged in as credentials or as something else. So let me try this again.
So I should be redirected to the settings page and if we go to the server here there we go, I can see my new name and everything. Perfect. So let's go ahead and copy and paste this again. So this one is going to be our email and it's going to render user.email here. There we go.
We have the email and let's go ahead and copy it again. This one is going to be our role so we can get user.role here. There we go, you can see how it says user here. And let's go ahead and do the last one which is going to be our two-factor authentication like that and inside of here we're going to render user is two-factor oh so we didn't extend the user to have the status of two-factor authentication here. So for now, let's simply write off like that.
And let's go ahead and go inside of our out file so we can extend the callbacks here. So we need to extend the token and we need to extend the session here to accept whether the user has two-factor on or off. So we can render that. So we can easily do that by adding token.isToFactorEnabled to be existing user isToFactorEnabled like that. And then in here, we can copy and paste this and check if we have token isToFactorEnabled and if we have session.user in that case let's go ahead and add user isToFactorEnabled is going to be token isToFactorEnabled like that And let's actually just check for session user because this can be false, right?
So we don't want to mess that up. So all in one line like this. And now obviously we have to go back inside of our nextAuth.d.ts and add the isToFactorEnabled to be a boolean like that. And then we can change this to be as boolean like this. And now the errors are gone.
And you can see how the ourSession.user now expects the property isToFactorEnabled Great! So now let's go ahead and let's go back inside of our app protected server. Oh, sorry, no. Components, user info here. And then in here, we can check if user is to factor enabled on, otherwise off.
Like that. Perfect. So let me just style this is to factor enable. If you want to you can leave it like this. What I'm gonna do is I'm gonna add a new component from ShadCN called badge.
So npx ShadCN UI latest add badge. Like this. And then I'm gonna go ahead and import the badge from .slash UI badge or components UI badge. And then in here, instead of rendering it inside of a paragraph here, what I'm going to do is render a badge. So we have like a clear indicator, so variant.
If user is to factor enabled, we're going to use success, otherwise destructive. And I think we don't have the Variant success, so we are getting this error here. So what we have to do is we have to go inside of the badge component so inside of your components UI badge right here let's simply add a new variant here so success is going to be border transparent vg emerald 500 and text primary foreground and then inside of your user info you will no longer have an error or the success variant because it can exist so make sure that you added success and that you wrote success here. Like this. There we go.
So you can see how now it says off like it's a danger thing. So let me just see how if I have my Prisma Studio running. I don't. So let me go ahead inside the terminal here and run mtxprisma studio like this and I'm gonna find my user here and I'm gonna go ahead and enable two-factor authentication for this user so true save the change and once I refresh here there we go You can see that now two-factor authentication is on. Perfect.
So that's it. We finished an example of how to, you know, use user data in a server component. So basically all we need to do is we need to use our hook not our hook, sorry, not in the, is it server here? Yeah, so await current user, our lib current user which gets the session like that, as easy as that. Now let's go ahead and copy this server component and paste it here and rename it to client and what we have to do now is we have to replace this with client page and we have to mark this as use client So this will be a client component that you have, right?
I mean, we've already done this, you know, but I just want to explicitly tell you now so you can hear use use current user Like that and that's it That's absolutely it. So when you click on the client here, there we go We have exact same information and let's just change this client to actually tell you that it is a client component and let's use a different icon like a phone for example. There we go. So this is a client component, this is a server component and we can get the exact same information using different methods one with a hook and one with a lib. Perfect!
So we just wrapped server and client components what's left is to create admin example where I'm going to create another reusable component called role gate so you can specifically hide some content from normal users by using that component. And we're going to demonstrate an API call being protected for admins and a server action being protected for admins only. And then lastly we're going to create our settings.