‫In this video,
‫we're gonna build the user account page
‫mostly using concepts that we already know
‫and already used before.
‫And let's start by taking a look
‫at what I actually mean with the user account page
‫in our reference website so here on natours.dev.
‫So we already rendered this menu here
‫on our website,
‫but when we click then on this user
‫we get access to the user account page.
‫And so here, we can change some basic settings,
‫also upload a new photo,
‫but this one we are going to do
‫in the next section actually,
‫and the user can also update his password on this page.
‫Then, on the left side there are some menu items,
‫which we will not really implement
‫so we will only implement the menu,
‫but not really the pages that they point to,
‫and then if the user is an administrator
‫we also render this part down here.
‫Okay, so this is what we will be building in this lecture,
‫and in the next couple of lectures we will then
‫actually take care of really updating the settings.
‫So, basically making these buttons here work.
‫All right?
‫But for now, it's just rendering this page here
‫on this .me URL.
‫Okay?
‫So, let's start with the pug template.
‫All right, and so as always,
‫I already have this accountTemplate here.
‫So let's grab that, copy it,
‫and then create a new view down here,
‫which I'm calling account.
‫And now we want to extend the base
‫and we want to create a block called content as always.
‫And then in here is where we actually paste our content.
‫All right?
‫Now we need to indent all of this
‫to make it inside of the block.
‫Great, so, here first we have our navigation, right?
‫So settings, bookings, reviews, and billings
‫that we saw there on the left side of the page,
‫and then we also have the Admin navigation, right?
‫And they already see a lot of duplicate code here.
‫So basically this list item elements here,
‫they appear actually eight times.
‫So four times up here and four times down here
‫so let's very quickly just create a mixin for them
‫to make our code look a bit cleaner.
‫All right, so I'm gonna go ahead
‫and actually copy one of these.
‫And then create a new mixin called navItem.
‫Okay, so we did that before.
‫So this is very similar.
‫So what do we need to pass into this mixin
‫in order to basically customize each of these items?
‫Well, what's going to change is the link.
‫Also the text, so settings, bookings, et cetera.
‫So that's text.
‫Then also the icon is going to be changing,
‫and finally you see that this first one here
‫has the side-nav--active class, right?
‫And so we will also specify an active like here basically.
‫And then when we want to mark an item as active
‫we will simply pass in through here.
‫Okay?
‫So now we need to fix the indentation here.
‫And then pass in our data.
‫Next is the text.
‫So this, of course at this point,
‫is nothing new so I'm doing it pretty quickly here, right?
‫So icon and then the name of the icon that we pass in.
‫So just like we did it before,
‫and then finally this active here,
‫remember, will be either true or false.
‫And if it is true then we want to add this class.
‫So let's copy it.
‫And then here let's specify the class attribute.
‫And then just like we did,
‫let's do a turnery statement in here.
‫So saying if active, basically,
‫then here we want to have side-nav--active.
‫And if not then we want nothing.
‫So an empty class name, basically.
‫All right.
‫And so now we can replace this with our mixin.
‫So that's called navItem, and so remember,
‫we write + and then navItem.
‫So here the link is an empty link.
‫And actually for all of them for now.
‫Then
‫Settings,
‫then the name of the icon which is also settings,
‫but in lowercase.
‫And then finally this one is actually active,
‫and so we pass in true.
‫All right, let's duplicate it.
‫Have a briefcase and we have My Bookings.
‫Let's make that lowercase.
‫All right, duplicate it two more times.
‫So here we have star
‫and then here credit-card
‫for billing.
‫All right.
‫And now we have the admin navigation.
‫And this one will only be visible
‫if the current user is an administrator.
‫So let's actually define that using an if statement.
‫And so here we need to test if the user role
‫equals to admin, right?
‫And so that's, again,
‫one of these more complex if statements
‫and so we have to use JavaScript for that.
‫So I'm using here unbuffered code again.
‫And then if
‫and so we will have access to the user variable in here.
‫So just as we did in other templates.
‫So basically we're gonna pass it into here.
‫And then of course, the user has the role attribute,
‫and so we test if it's admin.
‫And if it is then we want to display all of this.
‫And so it now needs to be one level indented.
‫Okay?
‫And of course now we want to replace all of these here
‫with our mixin as well.
‫So four times.
‫This one is called map.
‫Manage tours.
‫This one is Manage users.
‫Manage reviews.
‫And then finally we have one with the briefcase.
‫And this one doesn't have the text here,
‫but it is Manage bookings.
‫All right.
‫So let's get rid of that and continue our work down here.
‫So this one here will be the form
‫for changing the user settings.
‫And so the personal data will be here in these values, okay?
‫So basically in an HTML input element,
‫the value is kind of a predefined text
‫that we can put inside an input element.
‫And so usually what we put there
‫is the current value of that input,
‫so of that field.
‫And so right now, that's of course the name of the user.
‫And so let's put that here.
‫User.name.
‫And then down here it's then of course
‫the email.
‫And here we also have the image of the user.
‫So image slash users slash the image name itself.
‫Okay.
‫Then down here there's nothing to do.
‫All right?
‫And actually that's it.
‫So that's really all the data
‫that's coming from the user object
‫that we have to put in.
‫Okay, so that is the template.
‫Let's now go ahead and add the route to the viewRouter.
‫So right here, and this one is gonna be called /me.
‫And so we're gonna have a controller called getAccount.
‫Now this one here, of course,
‫is actually going to be a protected route, right?
‫Because only if we are actually logged in
‫we will get access to this page.
‫And so we need to use our protect middleware here.
‫So that's an authController.protect.
‫Okay?
‫So just as we did with all or other protected routes.
‫Now one problem that I see with this
‫is that this protect middleware here
‫is very similar to the isLoggedIn.
‫And so we will actually do some duplicate operations there,
‫which is not ideal.
‫Because remember that this isLoggedIn
‫will run for all the requests, right?
‫So let's quickly take a look at these
‫so that I can make my point.
‫So in protect we get the current user down here.
‫So we have this findById here.
‫But we do the same
‫down here in loggedIn, okay?
‫And so by using isLoggedIn and protect at the same time,
‫we will do this query twice.
‫And so that is not ideal of course.
‫And so let's put this isLoggedIn here
‫only under routes which are not protected, okay?
‫Because on the protected route
‫this check if the user is logged in
‫will actually happen as well, right?
‫But not in this middleware,
‫but then in the protect middleware
‫because it basically checks for that as well, right?
‫So let's cut it from here and simply paste it
‫in other routes which are not protected.
‫Okay, make sense?
‫And so like this we do not have this problem
‫of basically doing the exact same query twice
‫in all the protected middlewares.
‫And that's a bit better for our performance.
‫Now this one thing that we do in the isLoggedIn
‫that we currently do not do in protect
‫is this here.
‫So we put a current user on the response.locals.
‫And so let's actually do the same
‫now in the currentUser.
‫And so let's do the same here in the protect middleware.
‫So you put the currentUser both on request.user
‫and on response.locals, all right?
‫So that we can then automatically use it
‫in all the templates after it.
‫So in this case, in our account template, all right?
‫So give it a save.
‫And now we need to add this getAccount controller
‫in order to, of course, fix this error
‫that we get currently.
‫So that's in viewsController,
‫.getAccount request and response.
‫And you will see in a second why we only need these two.
‫So to get the account page,
‫all we really need to do is to simply render that page.
‫We don't even need to query for the current user
‫because that has already been done
‫in the protect middleware, right?
‫And so really all we really need to do
‫is to do something like this.
‫So copy this code,
‫and then here account.
‫And let's give it a title of Your account.
‫All right, so that makes that error disappear.
‫And now as a final piece of the puzzle,
‫let's add the correct link, actually, in the header.
‫So here in our header right now the link
‫doesn't point to this account page, right?
‫So it points to nowhere.
‫And so it should now point to /me.
‫Okay, and so that should be the final piece
‫to actually make it work.
‫And so let's log in here now
‫with test one, two, three, four.
‫We are successfully logged in.
‫And now upon clicking here we get our page.
‫Fantastic.
‫Now there's one error here with the User photo.
‫So let's fix that.
‫But beside that, actually all of it is working just fine.
‫We also get this menu here because we are currently in admin
‫and so let's test that also in a second
‫to see if it disappears for other users.
‫And actually we also get this error down here
‫because we have a failed request for the image.
‫And so we already see that we're
‫probably doing something wrong there.
‫And so here in the image, of course,
‫it's not user.name, it is user.photo.
‫So give that a save, reload here.
‫And now indeed, there we go.
‫All right?
‫So now let's log out, see what happens then.
‫And then we get this kind of error.
‫And that's basically because we're trying to access
‫this protected route while not being logged in.
‫All right?
‫So let's try that again now.
‫So if we try to log in with /me,
‫then we get you are not logged in, okay?
‫And before we got that weird looking error
‫because we're actually right now in development.
‫But in production, of course,
‫we wouldn't see that weird error that we saw before.
‫Right?
‫But what we see now is that, of course,
‫our route really is protected.
‫So we cannot access it if we're not logged in.
‫Now just to finish,
‫let's actually log in with some other account
‫just to see if the administrator part also works.
‫So let's, again, use Laura here.
‫And you see that she is just a regular user.
‫All right.
‫And now we get her user account, without of course,
‫the admin menu.
‫Okay, perfect.
‫So that is building the account page.
‫And as I said before, in the next video,
‫we will then take care of actually
‫updating these account settings.