1
00:00:02,020 --> 00:00:05,100
Now that we successfully spent a lot of time in the

2
00:00:05,100 --> 00:00:08,290
administration area and on the product management.

3
00:00:08,290 --> 00:00:10,850
Let's come back to the regular website.

4
00:00:10,850 --> 00:00:14,120
Visitors, no matter if they are logged in or not,

5
00:00:14,120 --> 00:00:17,560
they should be able to visit the shop and see the products

6
00:00:17,560 --> 00:00:19,080
here as well.

7
00:00:19,080 --> 00:00:21,560
Of course, they should not see the products

8
00:00:21,560 --> 00:00:25,210
with the option of then editing or deleting them,

9
00:00:25,210 --> 00:00:28,270
but they should see the products so that they are then able

10
00:00:28,270 --> 00:00:30,620
to view the details of a product.

11
00:00:30,620 --> 00:00:33,860
And ultimately also add a product to the cart if they want

12
00:00:33,860 --> 00:00:35,310
to.

13
00:00:35,310 --> 00:00:36,960
And for this all,

14
00:00:36,960 --> 00:00:41,430
we can go back to our page, or back and code precisely,

15
00:00:41,430 --> 00:00:45,080
and now work on more routes and more actions,

16
00:00:45,080 --> 00:00:47,250
more controller actions.

17
00:00:47,250 --> 00:00:49,920
Because we do, if we have a look at our routes,

18
00:00:49,920 --> 00:00:53,800
have a product route that renders this all products page.

19
00:00:53,800 --> 00:00:57,420
At the moment, we do it here in an anonymous function.

20
00:00:57,420 --> 00:00:59,740
Now I want to add a separate controller,

21
00:00:59,740 --> 00:01:01,140
a product controller,

22
00:01:01,140 --> 00:01:05,990
which is for the regular customers in the end, where I do

23
00:01:05,990 --> 00:01:08,020
render this route for slash products.

24
00:01:08,020 --> 00:01:11,000
And where we then later also add a route for viewing

25
00:01:11,000 --> 00:01:13,280
the details about a product.

26
00:01:13,280 --> 00:01:15,540
So therefore in the controllers folder,

27
00:01:15,540 --> 00:01:19,880
I'll add a new file, product or products dot controller dot

28
00:01:19,880 --> 00:01:21,210
JS.

29
00:01:21,210 --> 00:01:25,910
And in there I'll add a new function, get all products,

30
00:01:25,910 --> 00:01:28,950
which should be a controller action that is responsible for

31
00:01:28,950 --> 00:01:30,823
showing the all products page.

32
00:01:31,860 --> 00:01:36,860
And therefore we can now go to the route for that.

33
00:01:37,550 --> 00:01:41,400
Let me close to public folder, to the products route,

34
00:01:41,400 --> 00:01:46,400
and actually grab this code here, and delete this anonymous

35
00:01:46,900 --> 00:01:50,930
function here, and back in the product controller use

36
00:01:50,930 --> 00:01:53,850
res render, customer products, all products.

37
00:01:53,850 --> 00:01:56,920
And accept, request and response here.

38
00:01:56,920 --> 00:01:57,753
And of course,

39
00:01:57,753 --> 00:02:00,420
now we don't just want to render this page like this.

40
00:02:00,420 --> 00:02:03,100
We now also want to fetch all the products that should be

41
00:02:03,100 --> 00:02:05,320
displayed on this page.

42
00:02:05,320 --> 00:02:08,699
And that can be done with help of our product model.

43
00:02:08,699 --> 00:02:12,380
We're not limited to using that model for administration

44
00:02:12,380 --> 00:02:13,480
purposes.

45
00:02:13,480 --> 00:02:15,650
In that model, in the product model,

46
00:02:15,650 --> 00:02:19,420
we do after all have a find all static method,

47
00:02:19,420 --> 00:02:21,530
which does get us all the products,

48
00:02:21,530 --> 00:02:25,160
and that's exactly what we need now for this all products

49
00:02:25,160 --> 00:02:27,883
page that's facing our customers as well.

50
00:02:30,020 --> 00:02:33,950
Hence, we can add an import to the product model

51
00:02:33,950 --> 00:02:36,750
by requiring going up one level,

52
00:02:36,750 --> 00:02:39,410
models, product dot model.

53
00:02:39,410 --> 00:02:41,770
And then in this function,

54
00:02:41,770 --> 00:02:44,930
we can add async in front of it, since we'll use async

55
00:02:44,930 --> 00:02:47,000
await, because I want to call the product,

56
00:02:47,000 --> 00:02:50,500
find all, which returns a promise and I want to

57
00:02:50,500 --> 00:02:53,393
await this to get my products.

58
00:02:54,640 --> 00:02:56,500
Now, as always, this could fail

59
00:02:56,500 --> 00:02:58,960
and therefore I will accept the next

60
00:02:58,960 --> 00:03:02,800
argument, so that we can try catch this.

61
00:03:02,800 --> 00:03:07,730
So, try getting all products, and catch any potential errors

62
00:03:07,730 --> 00:03:11,870
we might be facing and only render if we succeeded.

63
00:03:11,870 --> 00:03:14,860
So inside of the try block, and then the catch block,

64
00:03:14,860 --> 00:03:18,800
I'll call next error, two forward this potential error,

65
00:03:18,800 --> 00:03:20,683
to the error handling middleware.

66
00:03:22,220 --> 00:03:24,920
And then here in the try block where we know that we

67
00:03:24,920 --> 00:03:27,890
succeeded, I will pass a second argument,

68
00:03:27,890 --> 00:03:31,560
a second parameter value to this rendered template.

69
00:03:31,560 --> 00:03:35,360
And that will be my products data here.

70
00:03:35,360 --> 00:03:38,200
So the products which have fetched here are passed

71
00:03:38,200 --> 00:03:42,423
as products into this template here, like this.

72
00:03:44,290 --> 00:03:47,260
They are made available under a product key.

73
00:03:47,260 --> 00:03:50,550
And that means that now in this all products template,

74
00:03:50,550 --> 00:03:53,440
we can loop through all the products to output the product

75
00:03:53,440 --> 00:03:54,883
items there as well.

76
00:03:55,890 --> 00:03:57,700
Now, before we do that, let's first of all,

77
00:03:57,700 --> 00:04:00,170
export this controller action.

78
00:04:00,170 --> 00:04:01,003
And again,

79
00:04:01,003 --> 00:04:04,430
I will export an object so that we can group multiple

80
00:04:04,430 --> 00:04:07,790
controller actions together in that object and export all of

81
00:04:07,790 --> 00:04:09,030
them.

82
00:04:09,030 --> 00:04:13,630
So here I will export, get all products,

83
00:04:13,630 --> 00:04:15,250
as I want to name it.

84
00:04:15,250 --> 00:04:18,233
Hence, I added the S here, like this.

85
00:04:19,591 --> 00:04:23,950
And then in the products route, we can import this,

86
00:04:23,950 --> 00:04:25,620
the products controller.

87
00:04:25,620 --> 00:04:28,900
We can import this here by going up one level, diving into

88
00:04:28,900 --> 00:04:32,460
controllers and using the products controller.

89
00:04:32,460 --> 00:04:35,670
And then here for this, get slash products route.

90
00:04:35,670 --> 00:04:38,890
We can use products controller dot get all products

91
00:04:38,890 --> 00:04:40,633
and point at this action.

92
00:04:42,500 --> 00:04:45,730
Now, however, in the customer folder, that's important,

93
00:04:45,730 --> 00:04:48,750
not in the admin folder but in, the customer folder.

94
00:04:48,750 --> 00:04:51,550
There, I have all products EJS.

95
00:04:51,550 --> 00:04:54,300
And here I now want to output my list

96
00:04:54,300 --> 00:04:59,300
of products by using a for-of loop here in my template.

97
00:04:59,560 --> 00:05:03,520
And by going through all the products, which I get,

98
00:05:03,520 --> 00:05:05,500
and we have that products key here,

99
00:05:05,500 --> 00:05:08,300
because we're passing that into the template in our render

100
00:05:08,300 --> 00:05:10,773
function, in the controller action.

101
00:05:11,980 --> 00:05:14,660
And there, I then want to repeat list items.

102
00:05:14,660 --> 00:05:15,930
And in those lists items,

103
00:05:15,930 --> 00:05:19,540
I in the end want to output product items just as I'm doing

104
00:05:19,540 --> 00:05:21,260
it in the admin area.

105
00:05:21,260 --> 00:05:24,110
There, I have these product items and in the end,

106
00:05:24,110 --> 00:05:26,680
I want to use the same approach now,

107
00:05:26,680 --> 00:05:29,690
the only difference will be that I do want to show

108
00:05:29,690 --> 00:05:30,993
a different action.

109
00:05:31,950 --> 00:05:34,690
But since I want to use the same snippet,

110
00:05:34,690 --> 00:05:37,110
we can actually turn this product item

111
00:05:37,110 --> 00:05:40,190
EJS into a shared include.

112
00:05:40,190 --> 00:05:44,210
So we could go to shared, and in includes there,

113
00:05:44,210 --> 00:05:48,840
we could copy in the product item.

114
00:05:48,840 --> 00:05:50,830
So in the shared includes folder,

115
00:05:50,830 --> 00:05:53,370
we could also place it in a sub-folder there,

116
00:05:53,370 --> 00:05:56,123
but I'll just add it into includes like this for now.

117
00:05:57,070 --> 00:06:00,840
And then back in the admin, all products EJS file,

118
00:06:00,840 --> 00:06:05,590
I now do want to include that shared product item file.

119
00:06:05,590 --> 00:06:08,710
So in the admin folder, I go up one level.

120
00:06:08,710 --> 00:06:10,950
So that I'm in the admin folder,

121
00:06:10,950 --> 00:06:12,280
I was in the product folder.

122
00:06:12,280 --> 00:06:15,260
I go up one level into the admin folder,

123
00:06:15,260 --> 00:06:18,410
go up one level so that I'm in the views folder,

124
00:06:18,410 --> 00:06:21,400
and then dive into the shared folder,

125
00:06:21,400 --> 00:06:25,070
and from there into the includes folder.

126
00:06:25,070 --> 00:06:28,060
So that I'm now in the shared includes folder,

127
00:06:28,060 --> 00:06:30,113
where I find the product item.

128
00:06:31,050 --> 00:06:33,390
And with that we can remove the product item

129
00:06:33,390 --> 00:06:36,963
here in the admin products includes folder.

130
00:06:38,730 --> 00:06:41,260
And it's now in yet the same path.

131
00:06:41,260 --> 00:06:44,950
Hence, I'll copy that from the admin all products EJS file,

132
00:06:44,950 --> 00:06:47,300
which I want to use in the customer products,

133
00:06:47,300 --> 00:06:49,123
all products EJS file.

134
00:06:50,120 --> 00:06:52,020
We go up two levels, so that

135
00:06:52,020 --> 00:06:54,080
from inside products in the customer folder,

136
00:06:54,080 --> 00:06:57,160
we go into the views folder, and then we dive into shared

137
00:06:57,160 --> 00:07:00,490
includes, and use that product item EJS file.

138
00:07:00,490 --> 00:07:04,780
And I still pass my product data under a product key into

139
00:07:04,780 --> 00:07:08,510
that snippet, because in that product item snippet,

140
00:07:08,510 --> 00:07:10,423
I am referring to product.

141
00:07:11,920 --> 00:07:14,210
Now, the actions of course will differ,

142
00:07:14,210 --> 00:07:17,390
based on whether we're an administrator, or not.

143
00:07:17,390 --> 00:07:22,390
And therefore actually I want to check if locals is admin,

144
00:07:23,800 --> 00:07:27,640
if that is true here, and only if that is the case,

145
00:07:27,640 --> 00:07:30,690
I want to show these two actions.

146
00:07:30,690 --> 00:07:33,640
Because as a regular user we should not be able

147
00:07:33,640 --> 00:07:35,493
to edit or delete items.

148
00:07:36,430 --> 00:07:39,000
Instead in the else case,

149
00:07:39,000 --> 00:07:44,000
which we can write like this here, in the else case here,

150
00:07:44,630 --> 00:07:46,610
let's also close this of course.

151
00:07:46,610 --> 00:07:50,080
In that case, I want to show a regular link,

152
00:07:50,080 --> 00:07:55,080
which still gets a class of BTN and BTN Alt though.

153
00:07:55,530 --> 00:08:00,530
Which leads to slash products slash the ID of that product,

154
00:08:00,820 --> 00:08:03,940
which should give us the detail page for the product,

155
00:08:03,940 --> 00:08:06,350
which we have yet to add.

156
00:08:06,350 --> 00:08:11,350
Here in the URL we can use EJS to inject the product ID

157
00:08:11,380 --> 00:08:15,683
into that generated URL, or into that generated path here.

158
00:08:16,620 --> 00:08:18,533
And there I'll say, View Details.

159
00:08:19,660 --> 00:08:22,613
So that's the link we see as a non-administrator.

160
00:08:23,690 --> 00:08:26,200
Now, with that, if we reload here,

161
00:08:26,200 --> 00:08:29,320
I don't see any products because I don't have any products

162
00:08:29,320 --> 00:08:30,630
yet.

163
00:08:30,630 --> 00:08:33,913
If I quickly log in as an administrator,

164
00:08:35,350 --> 00:08:38,730
and I manage products, and I add a new product,

165
00:08:38,730 --> 00:08:39,923
like a keyboard,

166
00:08:41,100 --> 00:08:46,100
and I choose a file, this is a keyboard, give it a price.

167
00:08:47,780 --> 00:08:49,810
It's awesome.

168
00:08:49,810 --> 00:08:54,510
Definitely helps with typing like this.

169
00:08:54,510 --> 00:08:58,010
Then we have it here, and let's add a second product here,

170
00:08:58,010 --> 00:08:59,870
The Magic Track Pad,

171
00:08:59,870 --> 00:09:04,870
which I'm using, great for replacing a mouse.

172
00:09:08,050 --> 00:09:13,050
This helps a lot with smoothly navigating around

173
00:09:14,850 --> 00:09:16,683
on your system.

174
00:09:18,170 --> 00:09:22,660
I'm using it for recording my videos.

175
00:09:22,660 --> 00:09:25,100
If I click save, I have this as well.

176
00:09:25,100 --> 00:09:28,210
And now if I do log out and I go back to the regular shop

177
00:09:28,210 --> 00:09:30,270
page, which our customers see,

178
00:09:30,270 --> 00:09:32,920
I see my products here as well.

179
00:09:32,920 --> 00:09:36,490
However, the styling is missing, and the styling is missing

180
00:09:36,490 --> 00:09:40,170
because of course, in the admin all products page,

181
00:09:40,170 --> 00:09:43,823
we are including the products CSS file.

182
00:09:44,670 --> 00:09:48,130
We need to do the same thing in our customer facing all

183
00:09:48,130 --> 00:09:49,840
products page now.

184
00:09:49,840 --> 00:09:52,360
So, here, before we close the head tag,

185
00:09:52,360 --> 00:09:55,350
we want to include this link, which links to styles,

186
00:09:55,350 --> 00:09:56,873
products CSS.

187
00:09:59,160 --> 00:10:02,620
Once we do that, if we reload, we're one step closer,

188
00:10:02,620 --> 00:10:05,790
but we're still not there, because in our admin

189
00:10:05,790 --> 00:10:07,360
all products EJS file,

190
00:10:07,360 --> 00:10:10,790
we also see that we've got this ID on the unordered list

191
00:10:10,790 --> 00:10:12,700
that holds our products.

192
00:10:12,700 --> 00:10:15,470
And of course that's missing at the moment in the customer

193
00:10:15,470 --> 00:10:18,420
products, all products EJS file.

194
00:10:18,420 --> 00:10:20,490
There we don't even have the unordered list

195
00:10:20,490 --> 00:10:22,600
and we definitely need that, of course.

196
00:10:22,600 --> 00:10:26,380
And we need that ID on that list because that ID is used for

197
00:10:26,380 --> 00:10:27,970
styling.

198
00:10:27,970 --> 00:10:30,230
Now, we won't have a clash with that other,

199
00:10:30,230 --> 00:10:31,820
same ID in the other page,

200
00:10:31,820 --> 00:10:34,770
because these are two different pages and they are loaded

201
00:10:34,770 --> 00:10:35,770
for different paths.

202
00:10:36,630 --> 00:10:39,813
So this ID will at most be once on the page.

203
00:10:40,930 --> 00:10:45,920
Now we can move this code here into this grid,

204
00:10:45,920 --> 00:10:48,693
into this unordered list here, like this.

205
00:10:49,650 --> 00:10:50,770
And now with that,

206
00:10:50,770 --> 00:10:55,010
if we now saved this customer facing all products page,

207
00:10:55,010 --> 00:10:56,863
now we've got the proper look here.

208
00:10:57,970 --> 00:11:01,120
Now, regarding the details, we might want to center this.

209
00:11:01,120 --> 00:11:05,900
And to achieve that we can go to the products CSS file,

210
00:11:05,900 --> 00:11:09,220
which I now use for both the administration and the customer

211
00:11:09,220 --> 00:11:11,150
part, which is fine.

212
00:11:11,150 --> 00:11:14,210
And there for product item actions,

213
00:11:14,210 --> 00:11:19,210
I, in the end, now just want to have justify content center.

214
00:11:20,700 --> 00:11:23,450
If we do that, it's centered.

215
00:11:23,450 --> 00:11:26,970
Let's quickly check if the administration styles are broken

216
00:11:26,970 --> 00:11:30,660
now, if I log into my admin account.

217
00:11:30,660 --> 00:11:32,290
Nope, that looks good.

218
00:11:32,290 --> 00:11:35,830
So, therefore now this works.

219
00:11:35,830 --> 00:11:38,030
And now we want to make sure that when we click

220
00:11:38,030 --> 00:11:41,040
view details, we actually show the details page

221
00:11:41,040 --> 00:11:42,173
for a product.

