In this chapter, we're going to go ahead and develop the dashboard navbar, which should, together with the dashboard sidebar, wrap up the dashboard layout. So in the previous chapter, we have developed this part right here, and now we're going to focus on this. So two things will happen in the navbar. First, we're going to have the collapse button so that we can collapse the sidebar if needed. And the second one will, while it looks like an input, it's actually going to be a button which is going to open a command model so that we will be able to search for any agent or any meeting using a global search and we will also have a little shortcut to open it.
So let's start by creating the dashboard navbar. As always make sure you have your app running and let's go ahead and do the following. Let's go inside of source, app, dashboard, layout and before you write anything double check you are on your main branch here and now inside of the main inside of the main element I'm going to add dashboard navbar component now let's go inside of the modules dashboard components and now inside add dashboard navbar.tsx like this. So let's go ahead and mark this as use client. And let's export const dashboard navbar.
Instead of a div, let's return a nav element here and say hello navbar. Let's go back to the layout and let's import the dashboard navbar from modules. And now when you go here, when you refresh above this page you should see hello navbar right here. So now we're going to continue developing that. I'm going to give this nav element a class name flex px of 4 gap x of 2 items center py3 border bottom and bg of background.
There we go. So already looks much better. And I just can't help but notice that we are missing a little gap here in the user button between the avatar and the info. So let's quickly go inside of dashboard, user button here. And let's find that.
So in here, we have drop down menu trigger here and looks like we are missing the gap here. So let's just add gap x two. And there we go, that keeps it separated like that. So let's continue going back inside of the that nav dashboard navbar here and let's add a Nate a button component from components UI button And in here I'm going to render a panel left icon from Lucid React. And I'm going to give this a class name of size 9 and a variant of outline like this.
So now I have this button here. Right now when I click on it, it doesn't do much. But what I can do, since I've wrapped my entire dashboard instead of a sidebar provider, I can now access use sidebar in any of its children from components UI sidebar. And in here I can get the current state of the sidebar, I can get to toggle it, and I can also extract is mobile. So what I'm going to do is the following.
I'm going to add onClick here to be toggleSidebar. So now when a user clicks, it opens and closes. And Now what I'm going to do is dynamically render this. So let's just encapsulate this and let's check. In parentheses, if state is collapsed or if is mobile, which means it's automatically collapsed, we are rendering the panel left icon.
Otherwise, render panel left close icon from Lucid React. Now, let me just collapse these so they are easier to look at. And now let's go ahead and just add a little class name here, size four, inside. So now you can see that we have actual different icons representing different actions, right? But if you enter a mobile mode, you will see how it will behave.
Exactly the same. Perfect. So now that we've established that, Let's go ahead and handle the button next to it, which is the search button. So in here, I'm going to give this button a variant of outline, a size of small, and on click for now just an empty arrow function. And in here I'm going to add a class name height 9, width of 240 pixels, justify start, font normal, text muted foreground, hover text muted foreground.
Basically I'm doing this to override the usual effect where the color of the text changes on hover. That's why I'm writing the same color on hover. And that will be it. And inside of here, I'm going to add a search icon from Lucid React. And you can already see how this looks like.
So it's very clearly a button. We're just going to mask it as an input. There we go, like this. And what I want to do here is add a KBD element, which will basically just be a shortcut representation. Because besides clicking on this button, you will also be able to do a keyboard shortcut to open the global search.
So inside of here, add a span element and go ahead and write the following. And hashtag 8984 and then a column like this. And this will render a command icon, right? So obviously, depending on Windows or Mac, This will be the control icon, but it's basically the meta key. You can, of course, change it if you want to detect user's operating system and then display control.
But most people understand what this means. So now let's go ahead and style this just a bit better. So first of all, I want to give this span a class name of text extra small and I'm going to give this one a class name ML auto so that will push it to the end here. Pointer, events, none. Inline flex, height 5, select, none.
Items, center, gap 1, rounded, border, border, my apologies, background, muted, px 1.5, font, mono, text, 10 pixels, font, medium, text, muted, foreground, and opacity. No, actually, we don't have to do anything with the opacity. There we go. So now you can see that this looks like an actual keyboard shortcut. It's very recognizable, right?
Perfect. What I want to do before we move forward is one thing. Just check one thing. So if you go into the source app layout, you can see that we are currently using the Geist font. How about we change this to instead use inter.
And let's go ahead and call this inter and simply set the inter font. We don't need the variable. So you can just add inter like this. And you can just add inter dot last name here. Like that.
So this should change the font of the app to be inter, which I think suits better in this case. Now we can go back inside of the dashboard navbar here. And what I want to do now is I want to simply create that command, even though it's not going to do much because we don't have anything in the database to search for, and we don't have any API created. But let's just prepare for it, right? So wrap the entire thing inside of a fragment here, because semantically it will not be inside of the navbar, it will be here.
So dashboard command, that's the component we're going to create. And go inside of here and create dashboard dash command the SX so all of them live here together let's export the dashboard command here and inside of here what you are going to do is you will return command dialogue from components UI command. And then inside of here add the command input from components UI command. And now what we have to do is we have to create the props for this. So let's create an interface props, open boolean, set open, dispatch from react, set state action from react and then Boolean inside.
Now let's go ahead and modify this and let's the structure open and set open here. Let's pass in the open and on open change set open like this. And besides the let's actually add some attributes of the command input placeholder will be find a meeting or agent like this. And below this, let's add a command list from components UI command. And then let's add command item from components UI command.
And in here, I will simply write test and I will give this, I'm not sure it needs anything. We can just do a test like this and let's leave it like this so now let's go inside of the dashboard navbar and let's import this from dot slash dashboard command like that And what we have to do now is we have to implement the use state control for this. So command open, set command open, use state from react and set it to false by default. And let's just move this up here. And let's go ahead and add this to be open, command open and set open to be set command open.
And now let's go ahead and use the button or search to be set command open. And let's simply toggle so the current value and just the reverse of the current value. So now when you click this, you can see that it opens up, right. And you can see how it uses this filtering search, it doesn't work properly yet, because we don't have an actual API to call and search for meetings or agents, right? But that's how our global search will work.
And one thing we have to do is just implement the shortcut here. So the way we can do that is by using a useEffect. Let's add a useEffect here from react. Make sure you have imported this. You don't have to put anything in the dependency array.
Define a function called down, which will accept a keyboard event. If event.key is equal a and if we are pressing a meta key, or we are pressing the control key, so compatible both on Windows and Unix systems, we will prevent default and simply toggle the current command status. And then let's add a document add event listener key down to call the function down. And important on unmount we need to remove that event listener on key down and pass the reference to the function. So now when you press command and the letter K it should open.
Let's see did I implement this correctly. I had to refresh. There we go. So without clicking I can now open and close it. Perfect.
So we just added the dashboard navbar. And now let's wrap it up by adding a responsive drawer to dashboard user button. So basically, right now, if you go into mobile mode and open this and click here, you can see that it's not exactly usable, right? You can't really use mobile like this. So what we're going to do is we're going to implement a drawer.
We already have that inside of our components. So what we can do is go back to our dashboard user button. The reason I'm doing this is so that we start getting familiar with our way of adding responsivity here. So what we need to do is we have to import all components from drawer the same way we added all components from drop-down. So from components UI drawer which is a chat CNUI component so source components UI drawer right here drawer content description footer header title and trigger and it works very very similarly They pretty much share the same base, same platform.
So what we're going to do is the following. We're going to get const isMobile using useIsMobile, which we also have. If you're wondering where did this come from, well, also, ShadCNUI, one of the components, needs it. In case you are using some different version and you don't have it, you can pause the screen and just write the hook yourself. It is pretty simple.
It's not really that complicated. But there is probably maybe doesn't use it. Oh, use is mobile. And there we go. The sidebar component uses it, right.
So that's why we have it in our project, in case you were wondering. So now we're going to use it in the dashboard user button. And what we're going to do is the following after this, we're going to do if is mobile, we're going to do an early return. And similarly to this, we will open a drawer here, and then a drawer trigger, which will have an as child option. And in here, what we can do actually, I think we can just copy this thing like that.
And then literally just copy what's inside of this drop-down menu trigger. So all the way to here. And add it here. This will ensure that the trigger button looks the same on mobile. But that's just the trigger.
Because now what we have to do is we have to add drawer content. And in here a drawer header and a drawer title with data user name. And in here, data user email. This will be drawer description and make sure to change the closing tag as well. Outside of the drawer header, open up the drawer footer.
And in here, we are simply going to add the two buttons. So let's add a button from components UI button, variant of outline, onClick, empty function, because this is the credit card icon and billing option. Give it a class name of size four and text black. Go ahead and copy and paste this and change this one to be our on logout method. Log out icon and logout.
Just like that. So now when you go ahead and click on mobile, you will see that you have a much, much nicer experience. You have a proper drawer. When switching to desktop, it will open in a normal drop-down menu. So that's how we are going to handle responsivity in this project.
And the buttons should work normally. Let's see, log out. There we go. Perfect responsivity. Great.
Amazing, amazing job. I think that wraps it up. So we added the responsivity. And now let's go ahead and just merge the pull request here. So I have opened this, I have some changes.
I'm going to go inside of here, clicking on my branch, creating a new branch, 07, this is dashboard navbar I believe, correct. Ensure that you can see the new branch here, Go ahead and click the plus to add to stage all changes. 07 dashboard navbar, commit and publish the branch. There we go. Now let's go ahead and open the pull request on GitHub.
And let's see the review from CodeRabbit. And here we have the summary. We introduced the navigation bar, the dashboard layout for improved navigation. We added a command palette interface for the dashboard for quick searching or selecting items. We updated the user menu to provide a mobile friendly drawer experience, improving the usability on mobile devices.
And we simplified and updated the apps font to use inter for a cleaner appearance. That's exactly what we did. This was a pretty short chapter. In here, we have a sequence diagram. If you need further or visual explanation of how our drawer works, for example, detecting the mobile or detecting the desktop, as well as the dashboard command visualization here.
Perfect, and may I say no big comments, some nitpick comments here, as you can see, but no large comments that need any action. Great, so let's go ahead and merge this pull request and once the pull request is merged let's go back here, select the branch name, go back to main or origin main and go ahead and click this to synchronize the changes and click OK. And then when you click on your source control here and go inside of the graph you will see that we just merged 07 dashboard navbar. Amazing, amazing job. Let's mark this as completed and see you in the next chapter.