00:02
First, what I want to do is finish honing out our application shell. And it looks like we're already good to go here for our authentication layout. We have our little nav bar up here, and that's really all that we need for these.
00:12
So let's go ahead and structure out our app layout as well. So we can hide all of that back away, get back into our text editor, make sure that we are inside of our app layout. Okay. In addition to our user,
00:22
we will eventually, whenever we get to, actually, let's see, when we get to our user, we're going to go ahead and create a new user. Eventually, whenever we get to actually having authenticated users,
00:31
have organizations, both an active and a list of them that we'll need inside of our app shell. And if I bring up the finished product here again, to remind you a little bit of what this will look like,
00:41
we're going to have a bar just up at the top that has this little dropdown where we can add in and manage our organization. So we're going to list all the organizations right here.
00:50
And then we also need access to the active organization to be able to edit, delete, and to mark it as actually active. Then we have links to our course, difficulty, status, and accesses. And then over here on the right-hand side,
01:00
we have our little user panel with the user's name and then links to their various settings and to be able to log out. So that's our end goal for our application shell.
01:10
So let's first nuke what we have so far in our app layout. And let's set up the little sticky bar first. So we'll do div class flex, set the min height to screen
01:20
to ensure that we're at least taking up the full screen height width full, and then flex column. Inside of here, we'll put our sticky header.
01:28
So we'll do header here with a class and we'll use sticky to position it sticky to the top. Make sure that it's on top by setting Z50,
01:36
set it to flex, set the height to H16, items center, set a gap of four, a border, bottom, BG background,
01:46
and PX4MDPX6. Inside of this header is where everything that we just saw at the top is going to go, including our little user panel over on the right-hand side.
01:56
Outside of the header, we're going to want the remainder of our application content. So we'll consider that main. So we'll add that instead of a main element
02:04
with a class, flex, min, height, and we're gonna use the calc function here to do 100 VH. And then we wanna do minus.
02:13
So I'm gonna use an underscore there to simulate a space, minus, and then another underscore for another space. And then we'll wanna grab our theme spacing dot 16.
02:23
And essentially what we're doing there is we're subtracting the same spacing that we're using as the height of our header from that 100 VH that we wanna use for the remainder of our page contents.
02:33
Then we'll do flex one, flex, call, a gap of four, BG, muted, and then we can set the opacity of that to 40,
02:41
P4, MD, gap, eight, and MD, P of 10. Okay, so since the page content is going to go inside of the main,
02:50
this is where we're going to want our slot to go so that whatever we define inside of the page is going to go inside of this main element.
02:57
Everything else renders automatically with our layout. Now we will get to this momentarily, but we're gonna have our user panel on the bottom half of our header here,
03:07
and we'll just add in a div placeholder for that right now. Above, we're going to want the remainder of our navigation, which is the left-hand side that we had saw whenever we took a look at it,
03:17
this left-hand portion here. So let's go to our app components, and let's right-click, new file, and let's add in a navigation.vue file
03:26
because all of the links, both the desktop and mobile versions of them, tend to take up a bit of space. So we will want our script, lang TS there,
03:36
and let's also make that a setup script. Let's go ahead and import a couple of icons just so that we have them at the ready. We're going to want the menu icon,
03:44
the slash icon, as well as the route icon from loose side view next, and then let's add in our template. We're gonna have a nav element with a class.
03:54
So on mobile, we'll want this to be hidden, and then we'll do a gap of five, text small, and items center,
04:02
and then MD, we'll switch that from hidden to flex, and then LG, we'll set the gap to six. All right, and we're going to want a link that points to our slash courses page.
04:12
Now we're gonna add links for pages here that don't quite exist. These are pages that we will eventually get to, so we're just going to go ahead and sub them all out so that we don't have to return back here.
04:22
All right, so class, flex, item center, gap two, text, LG, font, semi bold, MD, text base. Make sure to end that link.
04:32
Not sure why that always gets the end wrong there on these link components, but do be sure to end your link there. Then we're gonna have the route icon here,
04:41
class H6, and width six. That's gonna be our little logo. So to compliment that, we'll have a span class SR only,
04:50
so that it's only visible for screen readers, with the actual name of plot line, of course. Then we will do a div class flex items center,
05:00
and we'll do a slash here as a little divider from our logo into the organization selects
05:07
with a class text slate 300, width four, H4, and then let's negative rotate it by 12. Oops, don't need to put anything inside of there,
05:17
so we can just self close that tag. Let's give that a copy and a paste. And then in between those two slashes is where our org select will go.
05:26
And we'll just do a little to do org select text there so that something is claiming that space. Now we can wrap that up in a span too if we want. Okay, so since we don't have any organizations to put here,
05:36
we'll just leave that to do text there. Then we're onto the remainder of our links. So we'll do a link href slash courses. In terms of our application, the courses page is pretty much going to be
05:46
the homepage inside of the application. We'll have a separate homepage, which is kind of like the landing page, which won't itself be in a Nordschaft page. And then let's give this a class of,
05:54
we'll create one called desktop link so that if we need to change it at any point in time, we just have one central location to change it.
06:02
And then we can conditionally add in a class called active if the page's URL starts with slash courses. Now to access the page instead of our template, we can just do dollar sign page.
06:12
This will get us the exact same thing that we had saw whenever we took a look at the use page composable inside of our setup script. The only difference is it's globally available
06:21
inside of our templates to use at any point in time. So we reach for our page URL, and we just want to check whether or not it starts with slash courses. If it does, then we'll consider this link active
06:31
and we'll give it a class as such. Then we need to end our link. I was trying not to have to do that. There we go. End our link and give it the text of courses. I'm going to copy that.
06:41
We also have our difficulties, statuses, and access levels. So our difficulties, there we go, and update the link for that too.
06:51
Difficulties, copy that and paste it down there with our starts with check. Then we have statuses, statuses, and statuses.
06:58
And lastly, our access levels, paste that there and switch this text to access levels. Now for the mobile version of this,
07:07
if I pull my browser back up here and we shrink it down, you'll see that we have this little hamburger pop out with this, what shodcmvue calls a sheet. So we're going to want to install this sheet
07:17
so that we can have it fly out whenever we click that hamburger button and close back away whenever we close it out. Hide that back away, hit command shift P
07:25
and look for shodcmvue. And we want to add new component called a sheet. That'll run a command for us. Don't know why my terminal is so big.
07:34
Close that down a little bit there. And we can close the terminal out altogether there. Outside of our navigation, which is hidden on mobile, we're going to want to show this sheet.
07:44
And the sheet comes with several different components. It also has a sheet trigger, which is where the button goes to be able to trigger the show of the sheet. So inside of this triggers,
07:54
where's the actual trigger buttons gonna go? So we'll have the click event cascade down to the child of this trigger by adding the as child flag on that component.
08:03
And then we'll add in our button component and we'll do a variant of outline to make it an outline button. Size of icon, because we're gonna put an icon inside of it.
08:13
And then a class of shrink zero MD hidden so that our button is not visible outside of the small screen sizes. And we will put our menu icon in here
08:23
with a class width five H five. And then we'll also do a span class, another SR only with toggle navigation menu.
08:33
Okay, in addition to the sheet trigger is also the sheet content. So we'll add in our sheet content. And as a prop for this,
08:41
we can designate what side we want the sheet to open with. We're gonna want it to open up on the left hand side because that's where our button's going to be. And then inside of here, we're gonna have another nav,
08:50
which will be our mobile navigation that we saw inside of the actual pop out sheet vertically. So add a class of grid,
08:58
a gap of six text LG to make the text a little bit bigger and font medium, if I can spell everything. For the most part, this is all gonna be the exact same content.
09:08
So we can really scroll up to our nav, give all of the contents there a copy and a paste. And let's fix the indentation there. And one thing I'm just noticing
09:18
is on my production finished app, I never put away to swap the organization on the mobile view. So we're going to want to do that. So we'll just leave that similar to how it is on the desktop.
09:28
Just leave it inside of that navigation there, but we will not need the slashes to separate our content. So we can just take all of that out and we'll just leave our to do org right there.
09:37
For our courses link, the MD class that we have is not going to be applicable for this as it won't be shown on MD. And then for our mobile links,
09:45
we want to switch from desktop link to mobile link. And we'll add those classes in here next. So just copy that and paste it for each one of those. All right.
09:55
And then down at the bottom of our component, we'll add in a style and we'll scope it to this specific component.
10:02
So we'll do .desktop link for our desktop links. And we'll use Tailwind to apply text muted foreground,
10:10
transition colors and hover text foreground. There we go. And then whenever it is active,
10:18
so we'll use CSS's native nesting capabilities here to do and .active. Then we'll apply text foreground like so.
10:27
The only real difference between our desktop link and our mobile links is that we don't want the transition. So we will just get rid of that. Probably not a big enough of a deal
10:35
to split those out between two separate classes, but that's okay. Always gives us room for expansion in the future. So there is our current navigation. I'm gonna give that a save
10:44
and it's gonna format everything for me. Let's jump back into our app layout now and add it on in. So we'll do navigation right there. And then eventually we're going to want to pass through
10:54
all of the same props that we have inside our app layout through to the navigation, which is going to be our organization, the active one. And then our organization's list,
11:03
all of the user's organizations and then the user itself. So we'll go ahead and just V bind and pass through all of the props that we have accessible
11:11
through our app layout into our navigation component. Well, let's go ahead and give it a save and see exactly what all we have at present. So open up our browser again. So we didn't change anything here with our off layout
11:21
and the app layout is our default layout. So if we just jump back into that homepage that Inertia initially set us up with, we should see our layout right here.
11:30
We have our little logo, the slashes, our to do org select, and then our course, difficulty, status and access level links. Cool, so before we run this out,
11:39
let's get our user panel added in on the right-hand side. For this, we're going to want to install another component from ShodCN and this one will be our dropdown menu.
11:48
So we'll go ahead and get that installed. Okay, we can discard that terminal. If you want to put this inside of another component, you can. I'm going to go ahead and put it directly inside of our app layout.
11:58
So on our div, let's first add in classes, flex, width, full, items, center, and justify end.
12:06
Then let's add in our dropdown menu component. And just like our sheet, that too comes with a dropdown menu trigger component.
12:15
And again, we're going to use a button as our trigger. So we'll do as child to cascade the event down. Add our button in with a variant of secondary
12:24
and another size of icon because it'll just be an icon inside of it. And we'll do class rounded full to make it a circle. Let's go ahead and jump up
12:34
and import an icon called user, let's see, circle right there from lucid view next. And then let's make use of it. User circle, just like so.
12:43
Class width five H five. And then we'll do a span class SR only toggle user menu. Again, just like our sheet,
12:53
we also have a dropdown menu content component that we'll want to put after our trigger. And we're going to want to specify the alignment
13:02
to be the end, the right-hand side, so that it doesn't end up going outside the bounds of our screen. So we'll do end there. Now the dropdown menus come with a bunch
13:11
of separate subcomponents that we can use inside of our menu content, like labels, separators, items, and even radio items that we'll use later on for our organization.
13:21
So all of that's inside of the documentation. If you want to see what all it came with, we're going to go ahead and just make use of the things that we need here. And we'll use the dropdown menu label
13:30
to list out our user's name. So we'll do drop down menu label. Now we don't have a username to display yet.
13:38
So we'll just do username right there and then we'll do a separator. So dropdown menu separator. Sorry, we can self-close that.
13:47
And then we'll do a dropdown menu item. And we want this to be a link. So we can specify what component we want to use
13:55
for the dropdown menu item by providing in an as prop and then passing in our link component. Now, since we're passing a reference of the link component,
14:05
we are actually going to need to have it imported inside of this file. So we'll add an import here for our link, despite it being a global component
14:13
so that we can actually use it as a prop. Then for the href of our link, we'll want to point this eventually to our settings,
14:21
whoops, settings, not seedings, slash profile page. And this will be our profile settings. We can give this dropdown menu item a copy and paste it in two more times
14:31
because we're also going to have their account settings and the organization settings as well. So this will be settings slash accounts
14:40
and settings slash organization. Then we'll want another separator and one more link. So we'll give that another copy, paste,
14:48
and this one will be our log out button. Again, we'll use this as link and we'll pass the href as just slash log out,
14:56
but we're also going to want this to make a post request rather than a get. So we'll add a method attribute onto it of type post. Now, an alternative here to using the as method
15:06
to make these all links is you could just add in a literal link component with your props specified on it, just like so,
15:14
and log out there and your link, and then cascade the click event from the dropdown menu to the child by passing as child in
15:23
so that whenever you click on the dropdown menu item and it registers that, it will reach for the child and pass that click event through in turn clicking the link. So that's an alternative
15:32
if you don't like this as approach. You can do that on any one of your links where we do this. Okay, give that a save. And we should be, for the most part, good to go here.
15:42
Let's go ahead and jump back into our browser and it's a little squished, but we can go ahead and click on our user menu and everything looks good there. Let's see why this is squished. So right click there, inspect,
15:52
and I bet you it's the width full that we put on our user menu wrapping div. So let's try to go back into here
15:59
and switch this width full with flex one instead. Give that a save, jump back into our browser, and yeah, that looks better. Okay, cool. If we close out our dev tools there,
16:09
click on the little wrench if you're using the developer version of Firefox, and we can click on the responsive design mode to open that up, test out our mobile menu, looks good there, awesome,
16:19
and expand it on out and there's our desktop view. Cool, so apart from our toast management, which we will get to here in a bit,
16:26
our app layout and our off layout should be all good to go.