Skip to content

Commit 6627ca8

Browse files
committed
Fix course view
1 parent df12daf commit 6627ca8

File tree

15 files changed

+153
-171
lines changed

15 files changed

+153
-171
lines changed

backend/src/main/java/com/youdemy/controller/CourseController.java

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55

66
import com.fasterxml.jackson.databind.ObjectMapper;
77
import com.youdemy.model.Lesson;
8+
import com.youdemy.model.OrderP;
89
import com.youdemy.model.User;
910
import com.youdemy.repository.UserRepository;
11+
import com.youdemy.service.OrderPService;
1012
import com.youdemy.service.UserService;
1113

1214
import org.json.JSONObject;
@@ -41,6 +43,9 @@ public class CourseController {
4143
@Autowired
4244
private UserRepository userRepository;
4345

46+
@Autowired
47+
private OrderPService orderPService;
48+
4449
@ModelAttribute
4550
public void addAttributes(Model model, HttpServletRequest request) {
4651
Principal principal = request.getUserPrincipal();
@@ -101,19 +106,36 @@ public Page<Course> getCurrentCourse(@RequestParam Optional<Integer> page,
101106
public String showCourse(Model model, @PathVariable long id, HttpServletRequest request) {
102107
Optional<Course> course = courseService.findById(id);
103108
if (course.isPresent()) {
104-
model.addAttribute("course", course.get());
105109
Principal principal = request.getUserPrincipal();
106110
if(principal != null) {
107111
String userName = principal.getName();
108112
Optional<User> user = userRepository.findByFirstName(userName);
109-
long userId;
110-
userId = user.get().getId();
113+
long userId = user.get().getId();
111114
model.addAttribute("userId", userId);
112-
if(course.get().getAuthor().getId() == userId) {
115+
116+
if(course.get().getAuthor().getId() == userId
117+
|| model.getAttribute("admin") == Boolean.valueOf(true)) {
113118
model.addAttribute("owner", true);
119+
model.addAttribute("hasAccess", true);
114120
}
115-
121+
122+
ArrayList<OrderP> orders = new ArrayList<>(orderPService.findByUserId(userId));
123+
124+
orders.forEach(order -> {
125+
Course orderCourse = courseService.findById(order.getCourse()).get();
126+
if(orderCourse.getId() == course.get().getId())
127+
model.addAttribute("hasAccess", true);
128+
});
129+
}
130+
131+
// Empty lesson video urls if user doesn't have access to course
132+
if(model.getAttribute("hasAccess") == null) {
133+
course.get().getLessons().forEach(lesson -> {
134+
lesson.setVideoUrl("");
135+
});
116136
}
137+
138+
model.addAttribute("course", course.get());
117139

118140
return "course";
119141
} else {
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11
package com.youdemy.controller;
22

3+
import com.youdemy.model.Course;
34
import com.youdemy.model.VideoThumbnail;
45
import com.youdemy.repository.VideoThumbnailRepository;
6+
import com.youdemy.service.VideoThumbnailService;
57
import org.springframework.beans.factory.annotation.Autowired;
68
import org.springframework.core.io.ByteArrayResource;
79
import org.springframework.core.io.Resource;
810
import org.springframework.web.bind.annotation.*;
911
import org.springframework.web.multipart.MultipartFile;
1012

1113
import java.io.IOException;
14+
import java.util.Optional;
1215

1316
@RestController
1417
public class VideoThumbnailController {
1518

1619
@Autowired
17-
private VideoThumbnailRepository videoThumbnailRepository;
20+
private VideoThumbnailService videoThumbnailService;
1821

1922
@PostMapping(value = "/image/new")
20-
Long uploadVideoThumbnail(@RequestParam("image") MultipartFile image) throws IOException {
23+
public Long uploadVideoThumbnail(@RequestParam("image") MultipartFile image) throws IOException {
2124
VideoThumbnail videoThumbnail = new VideoThumbnail();
2225
videoThumbnail.setName(image.getName());
2326
videoThumbnail.setData(image.getBytes());
2427
videoThumbnail.setType(image.getContentType());
2528

26-
return videoThumbnailRepository.save(videoThumbnail).getId();
29+
return videoThumbnailService.save(videoThumbnail);
2730
}
2831

2932
@GetMapping(value = "/image/{imageId}")
30-
Resource downloadVideoThumbnail(@PathVariable String imageId) {
31-
byte[] data = videoThumbnailRepository.findById(Long.valueOf(imageId))
32-
.orElseThrow(() -> new IllegalArgumentException("Image not found"))
33-
.getData();
34-
35-
return new ByteArrayResource(data);
33+
public @ResponseBody byte[] downloadVideoThumbnail(@PathVariable String imageId) {
34+
Optional<VideoThumbnail> thumbnail = videoThumbnailService.get(Long.parseLong(imageId));
35+
return thumbnail.map(VideoThumbnail::getData).orElse(null);
3636
}
3737

3838
}

backend/src/main/java/com/youdemy/model/Course.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ public class Course {
1414
private long id;
1515

1616
private String title;
17+
18+
@Column(columnDefinition = "TEXT")
1719
private String description;
20+
1821
private int price;
1922

2023
private String tagsString;

backend/src/main/java/com/youdemy/model/Lesson.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ public class Lesson {
1212
private long id;
1313

1414
private String title;
15+
16+
@Column(columnDefinition = "TEXT")
1517
private String description;
18+
1619
private String videoUrl;
1720
private long imageId;
1821

backend/src/main/java/com/youdemy/repository/OrderPRepository.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
import com.youdemy.model.OrderP;
66

7+
import java.util.List;
8+
79
public interface OrderPRepository extends JpaRepository<OrderP, Long>{
8-
10+
11+
List<OrderP> findByUser(Long userId);
912

1013
}

backend/src/main/java/com/youdemy/service/OrderPService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ public class OrderPService {
1818
public Optional<OrderP> findById(long id) {
1919
return repository.findById(id);
2020
}
21+
22+
public List<OrderP> findByUserId(long userId) {
23+
return repository.findByUser(userId);
24+
}
2125

2226
public boolean exist(long id) {
2327
return repository.existsById(id);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.youdemy.service;
2+
3+
import com.youdemy.model.VideoThumbnail;
4+
import com.youdemy.repository.LessonRepository;
5+
import com.youdemy.repository.VideoThumbnailRepository;
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.stereotype.Service;
8+
9+
import java.util.Optional;
10+
11+
@Service
12+
public class VideoThumbnailService {
13+
14+
@Autowired
15+
private VideoThumbnailRepository videoThumbnailRepository;
16+
17+
public long save(VideoThumbnail thumbnail) {
18+
return videoThumbnailRepository.save(thumbnail).getId();
19+
}
20+
21+
public Optional<VideoThumbnail> get(long id) {
22+
return videoThumbnailRepository.findById(id);
23+
}
24+
}

backend/src/main/resources/static/js/courses.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ let page = 1;
66

77
const renderTags = tags => {
88
const tagsHtml = tags.reduce((html, tag) => {
9-
return html + `\n <span class="badge bg-primary rounded-pill m-1">${tag}</span>`
9+
return html + `\n <span class="badge bg-primary rounded-pill me-1">${tag}</span>`
1010
}, "");
1111

1212
console.log(tagsHtml);

backend/src/main/resources/static/js/newCourse.js

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -138,19 +138,12 @@ const printLessons = () => {
138138
lessonsContainer.innerHTML = '';
139139

140140
lessons.forEach(({title, description, imageId, url}) => {
141-
const imageUrl = `https://localhost:8443/image/${imageId}`;
142-
143-
fetch(imageUrl, {headers})
144-
.then(response => response.blob())
145-
.then(blob => {
146-
const imageObjectURL = URL.createObjectURL(blob);
147-
148-
const lessonElement = document.createElement('div');
149-
lessonElement.classList.add('card', 'mb-3', 'p-0');
150-
lessonElement.innerHTML = `
141+
const lessonElement = document.createElement('div');
142+
lessonElement.classList.add('card', 'mb-3', 'p-0');
143+
lessonElement.innerHTML = `
151144
<div class="row g-0">
152145
<div class="col-md-4">
153-
<img src="${imageObjectURL}" style="object-fit: cover" class="img-fluid rounded-start h-100" alt="${title}">
146+
<img src="https://localhost:8443/image/${imageId}" style="object-fit: cover" class="img-fluid rounded-start h-100" alt="${title}">
154147
</div>
155148
<div class="col-md-8">
156149
<div class="card-body">
@@ -162,8 +155,7 @@ const printLessons = () => {
162155
</div>
163156
`;
164157

165-
lessonsContainer.appendChild(lessonElement);
166-
});
158+
lessonsContainer.appendChild(lessonElement);
167159
});
168160
}
169161

backend/src/main/resources/templates/course.html

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,28 +25,45 @@
2525
<body>
2626
{{> header}}
2727
<main>
28-
<div class=container>
28+
<div class="container mt-5 pb-5">
2929

30-
<div class="row mb-3">
31-
<div class="col-md-8 themed-grid-col" style="height:500px">
32-
<iframe width=100% height=100% src="https://www.youtube.com/embed/aLUHoorbeQk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
30+
<div class="row mb-3 mt-5">
31+
<div id="detailsContainer" class="col-md-8 themed-grid-col" style="height:500px">
32+
{{#course}}
33+
<h2>{{title}}</h2>
34+
<img width="560" height="315" src="https://localhost:8443/courses/thumbnail/{{id}}" alt="Course Image">
35+
<div class="mt-2">
36+
{{#tags}}
37+
<span class="badge bg-primary rounded-pill me-1">{{.}}</span>
38+
{{/tags}}
39+
</div>
40+
<p class="mt-4">{{description}}</p>
41+
{{/course}}
3342
</div>
3443
<div class="col-md-4 themed-grid-col">
3544
<div class="d-flex flex-column align-items-stretch flex-shrink-0 bg-white" style="width: 380px;">
36-
<a href="/" class="d-flex align-items-center flex-shrink-0 p-3 link-dark text-decoration-none border-bottom">
37-
<svg class="bi me-2" width="30" height="24"><use xlink:href="#bootstrap"></use></svg>
38-
<span class="fs-5 fw-semibold">Course "{{course.title}}"</span>
39-
</a>
40-
<div class="list-group list-group-flush border-bottom scrollarea">
45+
<h3 class="mb-3">Lessons</h3>
4146
{{#course.lessons}}
42-
<a href="#" class="list-group-item list-group-item-action active py-3 lh-tight" aria-current="true">
43-
<div class="d-flex w-100 align-items-center justify-content-between">
44-
<strong class="mb-1">{{title}}</strong>
45-
</div>
46-
<div class="col-10 mb-1 small">{{description}}</div>
47-
</a>
48-
{{/course.lessons}}
49-
</div>
47+
<div class="card mb-3 p-0">
48+
<div class="row g-0">
49+
<div class="col-md-4">
50+
<img src="https://localhost:8443/image/{{imageId}}" style="object-fit: cover" class="img-fluid rounded-start h-100" alt="{{title}}">
51+
</div>
52+
<div class="col-md-8">
53+
<div class="card-body">
54+
<h5 class="card-title">{{title}}</h5>
55+
<p class="card-text">{{description}}</p>
56+
{{#hasAccess}}
57+
<a href="#watch{{id}}" onclick="showVideo({{id}})" class="btn btn-primary">Watch</a>
58+
{{/hasAccess}}
59+
{{^hasAccess}}
60+
<a href="#" onclick="" class="btn btn-primary disabled">Watch</a>
61+
{{/hasAccess}}
62+
</div>
63+
</div>
64+
</div>
65+
</div>
66+
{{/course.lessons}}
5067
</div>
5168
</div>
5269
</div>

0 commit comments

Comments
 (0)