Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:01,180 --> 00:00:02,070
In this video,
2
00:00:02,070 --> 00:00:04,620
we're gonna build the user account page
3
00:00:04,620 --> 00:00:07,270
mostly using concepts that we already know
4
00:00:07,270 --> 00:00:08,823
and already used before.
5
00:00:10,560 --> 00:00:12,470
And let's start by taking a look
6
00:00:12,470 --> 00:00:15,340
at what I actually mean with the user account page
7
00:00:15,340 --> 00:00:20,230
in our reference website so here on natours.dev.
8
00:00:20,230 --> 00:00:22,920
So we already rendered this menu here
9
00:00:22,920 --> 00:00:24,210
on our website,
10
00:00:24,210 --> 00:00:27,430
but when we click then on this user
11
00:00:27,430 --> 00:00:30,210
we get access to the user account page.
12
00:00:30,210 --> 00:00:33,349
And so here, we can change some basic settings,
13
00:00:33,349 --> 00:00:35,807
also upload a new photo,
14
00:00:35,807 --> 00:00:37,540
but this one we are going to do
15
00:00:37,540 --> 00:00:39,013
in the next section actually,
16
00:00:40,043 --> 00:00:44,690
and the user can also update his password on this page.
17
00:00:44,690 --> 00:00:47,590
Then, on the left side there are some menu items,
18
00:00:47,590 --> 00:00:49,740
which we will not really implement
19
00:00:49,740 --> 00:00:52,120
so we will only implement the menu,
20
00:00:52,120 --> 00:00:55,027
but not really the pages that they point to,
21
00:00:55,027 --> 00:00:57,840
and then if the user is an administrator
22
00:00:57,840 --> 00:01:00,690
we also render this part down here.
23
00:01:00,690 --> 00:01:04,379
Okay, so this is what we will be building in this lecture,
24
00:01:04,379 --> 00:01:06,440
and in the next couple of lectures we will then
25
00:01:06,440 --> 00:01:09,440
actually take care of really updating the settings.
26
00:01:09,440 --> 00:01:13,113
So, basically making these buttons here work.
27
00:01:14,227 --> 00:01:15,060
All right?
28
00:01:15,060 --> 00:01:17,620
But for now, it's just rendering this page here
29
00:01:17,620 --> 00:01:19,443
on this .me URL.
30
00:01:21,370 --> 00:01:22,610
Okay?
31
00:01:22,610 --> 00:01:25,343
So, let's start with the pug template.
32
00:01:26,250 --> 00:01:28,080
All right, and so as always,
33
00:01:28,080 --> 00:01:30,873
I already have this accountTemplate here.
34
00:01:32,050 --> 00:01:34,453
So let's grab that, copy it,
35
00:01:37,810 --> 00:01:40,253
and then create a new view down here,
36
00:01:42,730 --> 00:01:44,360
which I'm calling account.
37
00:01:44,360 --> 00:01:46,810
And now we want to extend the base
38
00:01:51,281 --> 00:01:56,270
and we want to create a block called content as always.
39
00:01:56,270 --> 00:01:59,863
And then in here is where we actually paste our content.
40
00:02:00,740 --> 00:02:02,010
All right?
41
00:02:02,010 --> 00:02:04,000
Now we need to indent all of this
42
00:02:05,850 --> 00:02:09,803
to make it inside of the block.
43
00:02:10,639 --> 00:02:15,640
Great, so, here first we have our navigation, right?
44
00:02:15,670 --> 00:02:18,540
So settings, bookings, reviews, and billings
45
00:02:18,540 --> 00:02:21,020
that we saw there on the left side of the page,
46
00:02:21,020 --> 00:02:25,430
and then we also have the Admin navigation, right?
47
00:02:25,430 --> 00:02:28,590
And they already see a lot of duplicate code here.
48
00:02:28,590 --> 00:02:31,770
So basically this list item elements here,
49
00:02:31,770 --> 00:02:34,950
they appear actually eight times.
50
00:02:34,950 --> 00:02:38,970
So four times up here and four times down here
51
00:02:38,970 --> 00:02:41,730
so let's very quickly just create a mixin for them
52
00:02:41,730 --> 00:02:44,330
to make our code look a bit cleaner.
53
00:02:44,330 --> 00:02:46,310
All right, so I'm gonna go ahead
54
00:02:46,310 --> 00:02:48,610
and actually copy one of these.
55
00:02:48,610 --> 00:02:52,953
And then create a new mixin called navItem.
56
00:02:55,600 --> 00:02:57,480
Okay, so we did that before.
57
00:02:57,480 --> 00:02:59,120
So this is very similar.
58
00:02:59,120 --> 00:03:01,500
So what do we need to pass into this mixin
59
00:03:01,500 --> 00:03:05,100
in order to basically customize each of these items?
60
00:03:05,100 --> 00:03:07,773
Well, what's going to change is the link.
61
00:03:08,960 --> 00:03:13,960
Also the text, so settings, bookings, et cetera.
62
00:03:14,790 --> 00:03:16,360
So that's text.
63
00:03:16,360 --> 00:03:19,240
Then also the icon is going to be changing,
64
00:03:19,240 --> 00:03:21,980
and finally you see that this first one here
65
00:03:21,980 --> 00:03:25,690
has the side-nav--active class, right?
66
00:03:25,690 --> 00:03:30,530
And so we will also specify an active like here basically.
67
00:03:30,530 --> 00:03:33,110
And then when we want to mark an item as active
68
00:03:33,110 --> 00:03:35,390
we will simply pass in through here.
69
00:03:35,390 --> 00:03:36,762
Okay?
70
00:03:36,762 --> 00:03:39,573
So now we need to fix the indentation here.
71
00:03:47,530 --> 00:03:49,123
And then pass in our data.
72
00:03:54,930 --> 00:03:56,363
Next is the text.
73
00:03:59,900 --> 00:04:01,900
So this, of course at this point,
74
00:04:01,900 --> 00:04:06,607
is nothing new so I'm doing it pretty quickly here, right?
75
00:04:07,910 --> 00:04:12,000
So icon and then the name of the icon that we pass in.
76
00:04:12,000 --> 00:04:13,860
So just like we did it before,
77
00:04:13,860 --> 00:04:15,640
and then finally this active here,
78
00:04:15,640 --> 00:04:18,220
remember, will be either true or false.
79
00:04:18,220 --> 00:04:21,839
And if it is true then we want to add this class.
80
00:04:21,839 --> 00:04:22,753
So let's copy it.
81
00:04:23,950 --> 00:04:27,063
And then here let's specify the class attribute.
82
00:04:29,820 --> 00:04:31,470
And then just like we did,
83
00:04:31,470 --> 00:04:33,910
let's do a turnery statement in here.
84
00:04:33,910 --> 00:04:38,480
So saying if active, basically,
85
00:04:38,480 --> 00:04:42,003
then here we want to have side-nav--active.
86
00:04:43,010 --> 00:04:45,490
And if not then we want nothing.
87
00:04:45,490 --> 00:04:47,243
So an empty class name, basically.
88
00:04:49,030 --> 00:04:49,980
All right.
89
00:04:49,980 --> 00:04:53,800
And so now we can replace this with our mixin.
90
00:04:53,800 --> 00:04:57,270
So that's called navItem, and so remember,
91
00:04:57,270 --> 00:05:00,180
we write + and then navItem.
92
00:05:01,820 --> 00:05:05,230
So here the link is an empty link.
93
00:05:05,230 --> 00:05:07,520
And actually for all of them for now.
94
00:05:07,520 --> 00:05:08,353
Then
95
00:05:09,780 --> 00:05:10,623
Settings,
96
00:05:12,420 --> 00:05:14,980
then the name of the icon which is also settings,
97
00:05:14,980 --> 00:05:16,083
but in lowercase.
98
00:05:18,341 --> 00:05:21,060
And then finally this one is actually active,
99
00:05:21,060 --> 00:05:22,323
and so we pass in true.
100
00:05:25,541 --> 00:05:28,057
All right, let's duplicate it.
101
00:05:31,710 --> 00:05:36,513
Have a briefcase and we have My Bookings.
102
00:05:37,680 --> 00:05:39,490
Let's make that lowercase.
103
00:05:39,490 --> 00:05:43,090
All right, duplicate it two more times.
104
00:05:43,090 --> 00:05:44,480
So here we have star
105
00:05:48,360 --> 00:05:49,990
and then here credit-card
106
00:05:53,600 --> 00:05:56,423
for billing.
107
00:05:59,550 --> 00:06:00,383
All right.
108
00:06:04,270 --> 00:06:06,820
And now we have the admin navigation.
109
00:06:06,820 --> 00:06:08,560
And this one will only be visible
110
00:06:08,560 --> 00:06:11,660
if the current user is an administrator.
111
00:06:11,660 --> 00:06:15,660
So let's actually define that using an if statement.
112
00:06:15,660 --> 00:06:18,370
And so here we need to test if the user role
113
00:06:18,370 --> 00:06:20,360
equals to admin, right?
114
00:06:20,360 --> 00:06:21,270
And so that's, again,
115
00:06:21,270 --> 00:06:23,450
one of these more complex if statements
116
00:06:23,450 --> 00:06:26,410
and so we have to use JavaScript for that.
117
00:06:26,410 --> 00:06:29,441
So I'm using here unbuffered code again.
118
00:06:29,441 --> 00:06:30,640
And then if
119
00:06:32,560 --> 00:06:35,710
and so we will have access to the user variable in here.
120
00:06:35,710 --> 00:06:38,290
So just as we did in other templates.
121
00:06:38,290 --> 00:06:41,200
So basically we're gonna pass it into here.
122
00:06:41,200 --> 00:06:44,750
And then of course, the user has the role attribute,
123
00:06:44,750 --> 00:06:47,210
and so we test if it's admin.
124
00:06:47,210 --> 00:06:51,230
And if it is then we want to display all of this.
125
00:06:51,230 --> 00:06:54,963
And so it now needs to be one level indented.
126
00:06:56,760 --> 00:06:57,593
Okay?
127
00:06:57,593 --> 00:07:00,270
And of course now we want to replace all of these here
128
00:07:00,270 --> 00:07:03,023
with our mixin as well.
129
00:07:07,900 --> 00:07:09,083
So four times.
130
00:07:10,370 --> 00:07:13,003
This one is called map.
131
00:07:14,380 --> 00:07:15,613
Manage tours.
132
00:07:23,350 --> 00:07:24,823
This one is Manage users.
133
00:07:38,080 --> 00:07:39,323
Manage reviews.
134
00:07:41,400 --> 00:07:43,800
And then finally we have one with the briefcase.
135
00:07:46,450 --> 00:07:49,030
And this one doesn't have the text here,
136
00:07:49,030 --> 00:07:50,723
but it is Manage bookings.
137
00:07:55,548 --> 00:07:56,830
All right.
138
00:07:56,830 --> 00:08:01,830
So let's get rid of that and continue our work down here.
139
00:08:01,850 --> 00:08:03,830
So this one here will be the form
140
00:08:03,830 --> 00:08:06,130
for changing the user settings.
141
00:08:06,130 --> 00:08:10,600
And so the personal data will be here in these values, okay?
142
00:08:10,600 --> 00:08:14,460
So basically in an HTML input element,
143
00:08:14,460 --> 00:08:17,300
the value is kind of a predefined text
144
00:08:17,300 --> 00:08:20,220
that we can put inside an input element.
145
00:08:20,220 --> 00:08:21,690
And so usually what we put there
146
00:08:21,690 --> 00:08:23,930
is the current value of that input,
147
00:08:23,930 --> 00:08:25,160
so of that field.
148
00:08:25,160 --> 00:08:28,780
And so right now, that's of course the name of the user.
149
00:08:28,780 --> 00:08:30,130
And so let's put that here.
150
00:08:34,940 --> 00:08:36,480
User.name.
151
00:08:36,480 --> 00:08:40,202
And then down here it's then of course
152
00:08:40,202 --> 00:08:42,693
the email.
153
00:08:45,610 --> 00:08:49,343
And here we also have the image of the user.
154
00:08:54,060 --> 00:08:59,060
So image slash users slash the image name itself.
155
00:09:01,610 --> 00:09:02,443
Okay.
156
00:09:04,350 --> 00:09:06,783
Then down here there's nothing to do.
157
00:09:07,720 --> 00:09:08,670
All right?
158
00:09:08,670 --> 00:09:10,470
And actually that's it.
159
00:09:10,470 --> 00:09:12,640
So that's really all the data
160
00:09:12,640 --> 00:09:14,620
that's coming from the user object
161
00:09:14,620 --> 00:09:15,823
that we have to put in.
162
00:09:17,300 --> 00:09:20,110
Okay, so that is the template.
163
00:09:20,110 --> 00:09:25,110
Let's now go ahead and add the route to the viewRouter.
164
00:09:25,460 --> 00:09:29,813
So right here, and this one is gonna be called /me.
165
00:09:32,480 --> 00:09:35,560
And so we're gonna have a controller called getAccount.
166
00:09:37,940 --> 00:09:39,330
Now this one here, of course,
167
00:09:39,330 --> 00:09:42,470
is actually going to be a protected route, right?
168
00:09:42,470 --> 00:09:45,240
Because only if we are actually logged in
169
00:09:45,240 --> 00:09:48,260
we will get access to this page.
170
00:09:48,260 --> 00:09:52,020
And so we need to use our protect middleware here.
171
00:09:52,020 --> 00:09:55,973
So that's an authController.protect.
172
00:09:57,360 --> 00:09:58,730
Okay?
173
00:09:58,730 --> 00:10:02,100
So just as we did with all or other protected routes.
174
00:10:02,100 --> 00:10:04,500
Now one problem that I see with this
175
00:10:04,500 --> 00:10:06,560
is that this protect middleware here
176
00:10:06,560 --> 00:10:09,280
is very similar to the isLoggedIn.
177
00:10:09,280 --> 00:10:12,270
And so we will actually do some duplicate operations there,
178
00:10:12,270 --> 00:10:13,610
which is not ideal.
179
00:10:13,610 --> 00:10:16,500
Because remember that this isLoggedIn
180
00:10:16,500 --> 00:10:19,930
will run for all the requests, right?
181
00:10:19,930 --> 00:10:22,400
So let's quickly take a look at these
182
00:10:22,400 --> 00:10:24,203
so that I can make my point.
183
00:10:25,300 --> 00:10:30,300
So in protect we get the current user down here.
184
00:10:30,720 --> 00:10:33,020
So we have this findById here.
185
00:10:33,020 --> 00:10:34,580
But we do the same
186
00:10:36,757 --> 00:10:39,650
down here in loggedIn, okay?
187
00:10:39,650 --> 00:10:44,010
And so by using isLoggedIn and protect at the same time,
188
00:10:44,010 --> 00:10:45,720
we will do this query twice.
189
00:10:45,720 --> 00:10:48,410
And so that is not ideal of course.
190
00:10:48,410 --> 00:10:51,980
And so let's put this isLoggedIn here
191
00:10:51,980 --> 00:10:55,210
only under routes which are not protected, okay?
192
00:10:55,210 --> 00:10:56,660
Because on the protected route
193
00:10:56,660 --> 00:10:58,690
this check if the user is logged in
194
00:10:58,690 --> 00:11:02,270
will actually happen as well, right?
195
00:11:02,270 --> 00:11:03,870
But not in this middleware,
196
00:11:03,870 --> 00:11:05,450
but then in the protect middleware
197
00:11:05,450 --> 00:11:09,000
because it basically checks for that as well, right?
198
00:11:09,000 --> 00:11:12,573
So let's cut it from here and simply paste it
199
00:11:12,573 --> 00:11:15,393
in other routes which are not protected.
200
00:11:18,550 --> 00:11:20,300
Okay, make sense?
201
00:11:20,300 --> 00:11:23,340
And so like this we do not have this problem
202
00:11:23,340 --> 00:11:26,400
of basically doing the exact same query twice
203
00:11:26,400 --> 00:11:28,580
in all the protected middlewares.
204
00:11:28,580 --> 00:11:31,680
And that's a bit better for our performance.
205
00:11:31,680 --> 00:11:34,722
Now this one thing that we do in the isLoggedIn
206
00:11:34,722 --> 00:11:36,900
that we currently do not do in protect
207
00:11:36,900 --> 00:11:39,880
is this here.
208
00:11:39,880 --> 00:11:43,510
So we put a current user on the response.locals.
209
00:11:43,510 --> 00:11:45,534
And so let's actually do the same
210
00:11:45,534 --> 00:11:48,220
now in the currentUser.
211
00:11:48,220 --> 00:11:51,543
And so let's do the same here in the protect middleware.
212
00:11:53,020 --> 00:11:56,510
So you put the currentUser both on request.user
213
00:11:56,510 --> 00:11:59,590
and on response.locals, all right?
214
00:11:59,590 --> 00:12:01,600
So that we can then automatically use it
215
00:12:01,600 --> 00:12:03,690
in all the templates after it.
216
00:12:03,690 --> 00:12:07,560
So in this case, in our account template, all right?
217
00:12:07,560 --> 00:12:08,693
So give it a save.
218
00:12:10,080 --> 00:12:14,040
And now we need to add this getAccount controller
219
00:12:14,040 --> 00:12:16,903
in order to, of course, fix this error
220
00:12:16,903 --> 00:12:18,293
that we get currently.
221
00:12:19,450 --> 00:12:20,900
So that's in viewsController,
222
00:12:27,467 --> 00:12:32,467
.getAccount request and response.
223
00:12:34,370 --> 00:12:37,170
And you will see in a second why we only need these two.
224
00:12:38,100 --> 00:12:39,580
So to get the account page,
225
00:12:39,580 --> 00:12:43,370
all we really need to do is to simply render that page.
226
00:12:43,370 --> 00:12:45,910
We don't even need to query for the current user
227
00:12:45,910 --> 00:12:47,760
because that has already been done
228
00:12:47,760 --> 00:12:50,030
in the protect middleware, right?
229
00:12:50,030 --> 00:12:51,810
And so really all we really need to do
230
00:12:51,810 --> 00:12:54,110
is to do something like this.
231
00:12:54,110 --> 00:12:55,870
So copy this code,
232
00:12:55,870 --> 00:12:59,030
and then here account.
233
00:12:59,030 --> 00:13:04,030
And let's give it a title of Your account.
234
00:13:04,430 --> 00:13:07,840
All right, so that makes that error disappear.
235
00:13:07,840 --> 00:13:09,880
And now as a final piece of the puzzle,
236
00:13:09,880 --> 00:13:13,063
let's add the correct link, actually, in the header.
237
00:13:15,000 --> 00:13:18,110
So here in our header right now the link
238
00:13:18,110 --> 00:13:21,670
doesn't point to this account page, right?
239
00:13:21,670 --> 00:13:24,043
So it points to nowhere.
240
00:13:25,110 --> 00:13:27,713
And so it should now point to /me.
241
00:13:28,820 --> 00:13:32,380
Okay, and so that should be the final piece
242
00:13:32,380 --> 00:13:33,763
to actually make it work.
243
00:13:34,980 --> 00:13:36,840
And so let's log in here now
244
00:13:38,281 --> 00:13:40,513
with test one, two, three, four.
245
00:13:42,050 --> 00:13:44,320
We are successfully logged in.
246
00:13:44,320 --> 00:13:48,950
And now upon clicking here we get our page.
247
00:13:48,950 --> 00:13:50,590
Fantastic.
248
00:13:50,590 --> 00:13:54,030
Now there's one error here with the User photo.
249
00:13:54,030 --> 00:13:55,270
So let's fix that.
250
00:13:55,270 --> 00:13:59,460
But beside that, actually all of it is working just fine.
251
00:13:59,460 --> 00:14:03,750
We also get this menu here because we are currently in admin
252
00:14:03,750 --> 00:14:06,370
and so let's test that also in a second
253
00:14:06,370 --> 00:14:08,903
to see if it disappears for other users.
254
00:14:11,180 --> 00:14:14,150
And actually we also get this error down here
255
00:14:14,150 --> 00:14:17,500
because we have a failed request for the image.
256
00:14:17,500 --> 00:14:19,070
And so we already see that we're
257
00:14:19,070 --> 00:14:20,920
probably doing something wrong there.
258
00:14:22,070 --> 00:14:25,860
And so here in the image, of course,
259
00:14:25,860 --> 00:14:30,500
it's not user.name, it is user.photo.
260
00:14:30,500 --> 00:14:33,670
So give that a save, reload here.
261
00:14:33,670 --> 00:14:35,483
And now indeed, there we go.
262
00:14:36,840 --> 00:14:37,673
All right?
263
00:14:37,673 --> 00:14:41,200
So now let's log out, see what happens then.
264
00:14:41,200 --> 00:14:43,460
And then we get this kind of error.
265
00:14:43,460 --> 00:14:46,200
And that's basically because we're trying to access
266
00:14:46,200 --> 00:14:49,417
this protected route while not being logged in.
267
00:14:49,417 --> 00:14:50,250
All right?
268
00:14:51,470 --> 00:14:54,540
So let's try that again now.
269
00:14:54,540 --> 00:14:58,720
So if we try to log in with /me,
270
00:14:58,720 --> 00:15:01,920
then we get you are not logged in, okay?
271
00:15:01,920 --> 00:15:04,550
And before we got that weird looking error
272
00:15:04,550 --> 00:15:07,070
because we're actually right now in development.
273
00:15:07,070 --> 00:15:08,290
But in production, of course,
274
00:15:08,290 --> 00:15:11,850
we wouldn't see that weird error that we saw before.
275
00:15:11,850 --> 00:15:12,710
Right?
276
00:15:12,710 --> 00:15:15,410
But what we see now is that, of course,
277
00:15:15,410 --> 00:15:16,930
our route really is protected.
278
00:15:16,930 --> 00:15:20,090
So we cannot access it if we're not logged in.
279
00:15:20,090 --> 00:15:21,270
Now just to finish,
280
00:15:21,270 --> 00:15:23,750
let's actually log in with some other account
281
00:15:23,750 --> 00:15:28,390
just to see if the administrator part also works.
282
00:15:28,390 --> 00:15:31,320
So let's, again, use Laura here.
283
00:15:31,320 --> 00:15:33,520
And you see that she is just a regular user.
284
00:15:41,620 --> 00:15:42,543
All right.
285
00:15:44,780 --> 00:15:47,950
And now we get her user account, without of course,
286
00:15:47,950 --> 00:15:49,740
the admin menu.
287
00:15:49,740 --> 00:15:51,380
Okay, perfect.
288
00:15:51,380 --> 00:15:53,570
So that is building the account page.
289
00:15:53,570 --> 00:15:55,830
And as I said before, in the next video,
290
00:15:55,830 --> 00:15:57,700
we will then take care of actually
291
00:15:57,700 --> 00:16:00,213
updating these account settings.
21792
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.