Лента Lab5
This commit is contained in:
parent
dd87a58873
commit
bb8cc89e78
BIN
data.mv.db
BIN
data.mv.db
Binary file not shown.
@ -6,10 +6,12 @@ import com.webproglabs.lab1.lab34.model.Comment;
|
|||||||
public class CommentDto {
|
public class CommentDto {
|
||||||
private Long id;
|
private Long id;
|
||||||
private String text;
|
private String text;
|
||||||
|
private String authorLogin;
|
||||||
|
|
||||||
public CommentDto(Comment comment) {
|
public CommentDto(Comment comment) {
|
||||||
this.id = comment.getId();
|
this.id = comment.getId();
|
||||||
this.text = comment.getText();
|
this.text = comment.getText();
|
||||||
|
this.authorLogin = comment.getOwner().getLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
@ -17,4 +19,5 @@ public class CommentDto {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
public String getText() {return text;}
|
public String getText() {return text;}
|
||||||
|
public String getAuthor() {return authorLogin;}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package com.webproglabs.lab1.lab34.controller.mvc_controllers;
|
package com.webproglabs.lab1.lab34.controller.mvc_controllers;
|
||||||
|
|
||||||
|
import com.webproglabs.lab1.lab34.controller.CommentDto;
|
||||||
import com.webproglabs.lab1.lab34.controller.PostDto;
|
import com.webproglabs.lab1.lab34.controller.PostDto;
|
||||||
import com.webproglabs.lab1.lab34.controller.ProfileDto;
|
import com.webproglabs.lab1.lab34.controller.ProfileDto;
|
||||||
import com.webproglabs.lab1.lab34.model.Post;
|
import com.webproglabs.lab1.lab34.services.CommentService;
|
||||||
import com.webproglabs.lab1.lab34.services.PostService;
|
import com.webproglabs.lab1.lab34.services.PostService;
|
||||||
import com.webproglabs.lab1.lab34.services.ProfileService;
|
import com.webproglabs.lab1.lab34.services.ProfileService;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
@ -14,13 +15,13 @@ import java.util.ArrayList;
|
|||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/feed")
|
@RequestMapping("/feed")
|
||||||
public class FeedMvcController {
|
public class FeedMvcController {
|
||||||
|
|
||||||
private final ProfileService profileService;
|
private final ProfileService profileService;
|
||||||
private final PostService postService;
|
private final PostService postService;
|
||||||
|
private final CommentService commentService;
|
||||||
public FeedMvcController(ProfileService profileService, PostService postService) {
|
public FeedMvcController(ProfileService profileService, PostService postService, CommentService commentService) {
|
||||||
this.profileService = profileService;
|
this.profileService = profileService;
|
||||||
this.postService = postService;
|
this.postService = postService;
|
||||||
|
this.commentService = commentService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@ -72,4 +73,40 @@ public class FeedMvcController {
|
|||||||
postService.updatePost(id, postEditField);
|
postService.updatePost(id, postEditField);
|
||||||
return "redirect:/feed/" + authorId.toString();
|
return "redirect:/feed/" + authorId.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = {"commentModal/{authorId}/{postId}"})
|
||||||
|
public String getCommentModal(@PathVariable(required = false) Long authorId,@PathVariable(required = false) Long postId, Model model) {
|
||||||
|
model.addAttribute("selectedPost", new PostDto(postService.findPost(postId)));
|
||||||
|
model.addAttribute("profiles", profileService.findAllUsers().stream().map(ProfileDto::new).toList());
|
||||||
|
model.addAttribute("posts", postService.findAllPosts().stream().map(PostDto::new).toList());
|
||||||
|
model.addAttribute("selectedProfile", new ProfileDto(profileService.findUser(authorId)));
|
||||||
|
return "commentModal";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = {"comment/{authorId}/{postId}/"})
|
||||||
|
public String createComment(@PathVariable(required = false) Long authorId,@PathVariable(required = false) Long postId, @RequestParam(value="commentInputField") String commentInputField) {
|
||||||
|
commentService.addComment(commentInputField, authorId, postId);
|
||||||
|
return "redirect:/feed/" + authorId.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = {"/deleteComment/{id}/{authorId}"})
|
||||||
|
public String deleteComment(@PathVariable(required = false) Long id, @PathVariable(required = false) Long authorId) {
|
||||||
|
commentService.deleteComment(id);
|
||||||
|
return "redirect:/feed/" + authorId.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = {"commentEditModal/{id}/{authorId}"})
|
||||||
|
public String getCommentEditModal(@PathVariable(required = false) Long id,@PathVariable(required = false) Long authorId, Model model) {
|
||||||
|
model.addAttribute("selectedComment", new CommentDto(commentService.findComment(id)));
|
||||||
|
model.addAttribute("profiles", profileService.findAllUsers().stream().map(ProfileDto::new).toList());
|
||||||
|
model.addAttribute("posts", postService.findAllPosts().stream().map(PostDto::new).toList());
|
||||||
|
model.addAttribute("selectedProfile", new ProfileDto(profileService.findUser(authorId)));
|
||||||
|
return "editCommentModal";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = {"editComment/{authorId}/{commentId}/"})
|
||||||
|
public String editComment(@PathVariable(required = false) Long authorId,@PathVariable(required = false) Long commentId, @RequestParam(value="commentEditField") String commentEditField) {
|
||||||
|
commentService.updateComment(commentId, commentEditField);
|
||||||
|
return "redirect:/feed/" + authorId.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,30 @@
|
|||||||
package com.webproglabs.lab1.lab34.controller.mvc_controllers;
|
package com.webproglabs.lab1.lab34.controller.mvc_controllers;
|
||||||
|
|
||||||
|
import com.webproglabs.lab1.lab34.controller.ProfileDto;
|
||||||
|
import com.webproglabs.lab1.lab34.services.ProfileService;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/")
|
@RequestMapping("/")
|
||||||
public class ProfileMvcController {
|
public class ProfileMvcController {
|
||||||
|
private final ProfileService profileService;
|
||||||
|
|
||||||
|
public ProfileMvcController(ProfileService profileService) {
|
||||||
|
this.profileService = profileService;
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public String index() {
|
public String index() {
|
||||||
return "default";
|
return "default";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = {"profile/{login}"})
|
||||||
|
public String getProfile(@PathVariable(required = false) String login, Model model) {
|
||||||
|
model.addAttribute("profile", new ProfileDto(profileService.findUserByLogin(login)));
|
||||||
|
return "profilePage";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package com.webproglabs.lab1.lab34.repository;
|
package com.webproglabs.lab1.lab34.repository;
|
||||||
|
|
||||||
|
import com.webproglabs.lab1.lab34.model.Post;
|
||||||
import com.webproglabs.lab1.lab34.model.Profile;
|
import com.webproglabs.lab1.lab34.model.Profile;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface ProfileRepository extends JpaRepository<Profile, Long> {
|
public interface ProfileRepository extends JpaRepository<Profile, Long> {
|
||||||
|
List<Profile> findByLoginLike(String login);
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,12 @@ public class ProfileService {
|
|||||||
return profile.orElseThrow(EntityNotFoundException::new);
|
return profile.orElseThrow(EntityNotFoundException::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Profile findUserByLogin(String login) {
|
||||||
|
final Optional<Profile> profile = profileRepository.findByLoginLike(login).stream().findFirst();
|
||||||
|
return profile.orElseThrow(EntityNotFoundException::new);
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public List<Profile> findAllUsers() {
|
public List<Profile> findAllUsers() {
|
||||||
return profileRepository.findAll();
|
return profileRepository.findAll();
|
||||||
|
31
src/main/resources/templates/commentModal.html
Normal file
31
src/main/resources/templates/commentModal.html
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{feedPosts}" xmlns:th="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div layout:fragment="modalFeed">
|
||||||
|
|
||||||
|
<div class="modal fade" id="commentCreate" tabindex="-1" role="dialog" aria-labelledby="commentCreateLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="commentCreateLabel">Создать комментарий</h5>
|
||||||
|
</div>
|
||||||
|
<form th:action="@{/feed/comment/{id}/{postId}/{text} (id=${selectedProfile.id}, postId=${selectedPost.id}, text=${commentInputField}) }" method="post" class="modal-body text-center">
|
||||||
|
<p>Текст комментария:</p>
|
||||||
|
<input th:value="${commentInputField}" id="commentInputField" name="commentInputField" type="text" class="mb-2">
|
||||||
|
<br>
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
||||||
|
<button type="submit" class="btn btn-primary" >Сохранить</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -33,6 +33,9 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
$('#postEdit').modal('show');
|
$('#postEdit').modal('show');
|
||||||
|
$('#commentCreate').modal('show');
|
||||||
|
$('#commentEdit').modal('show');
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
30
src/main/resources/templates/editCommentModal.html
Normal file
30
src/main/resources/templates/editCommentModal.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{feedPosts}" xmlns:th="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div layout:fragment="modalFeed">
|
||||||
|
|
||||||
|
<div class="modal fade" id="commentEdit" tabindex="-1" role="dialog" aria-labelledby="commentEditLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="commentEditLabel">Редактировать комментарий</h5>
|
||||||
|
</div>
|
||||||
|
<form th:action="@{/feed/editComment/{id}/{commentId}/{text} (id=${selectedProfile.id}, commentId=${selectedComment.id}, text=${commentEditField}) }" method="post" class="modal-body text-center">
|
||||||
|
<p>Новый текст комментария:</p>
|
||||||
|
<input th:value="${commentEditField}" id="commentEditField" name="commentEditField" type="text" class="mb-2">
|
||||||
|
<br>
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
||||||
|
<button type="submit" class="btn btn-primary" >Изменить</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -29,9 +29,4 @@
|
|||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
window.onload = () => {
|
|
||||||
$('#postEdit').modal('show');
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</html>
|
</html>
|
@ -27,10 +27,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript">
|
|
||||||
window.onload = () => {
|
|
||||||
$('#postEdit').modal('show');
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -26,13 +26,13 @@
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
<div th:each="post: ${posts}" class="text-center mx-auto w-25 mb-3">
|
<div th:each="post: ${posts}" class="text-center mx-auto w-25 mb-3 ">
|
||||||
<div class="border p-2">
|
<div class="border p-2">
|
||||||
<p th:text="${post.text}" class="h4 text-start"></p>
|
<p th:text="${post.text}" class="h4 text-start"></p>
|
||||||
<div class="d-flex justify-content-between fst-italic">
|
<div class="d-flex justify-content-between fst-italic">
|
||||||
<div>
|
<div>
|
||||||
Автор:
|
Автор:
|
||||||
<a th:text="${post.getAuthor()}" class="text-start fst-italic" ></a>
|
<a th:text="${post.getAuthor()}" class="text-start fst-italic" th:href="@{/profile/{login}(login=${post.getAuthor()})}"></a>
|
||||||
</div>
|
</div>
|
||||||
<div th:if="${selectedProfile.getLogin() == post.getAuthor()}" class="d-flex justify-content-between fst-italic">
|
<div th:if="${selectedProfile.getLogin() == post.getAuthor()}" class="d-flex justify-content-between fst-italic">
|
||||||
<form th:action="@{/feed/deletePost/{id}/{authorId} (id=${post.id}, authorId=${selectedProfile.id})}" method="post" >
|
<form th:action="@{/feed/deletePost/{id}/{authorId} (id=${post.id}, authorId=${selectedProfile.id})}" method="post" >
|
||||||
@ -48,6 +48,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="border p-2" th:if="${post.comments.size() > 0}" >
|
||||||
|
<div class="text-start">
|
||||||
|
<p class="text-start h5">Комментарии:</p>
|
||||||
|
<div th:each="comment: ${post.comments}" >
|
||||||
|
<p class="fst-italic" th:text="${comment.getAuthor() + ':'}"> </p>
|
||||||
|
<div class="d-flex justify-content-between fst-italic">
|
||||||
|
<p class="ms-3" th:text="${comment.text}"></p>
|
||||||
|
|
||||||
|
<div th:if="${selectedProfile.getLogin() == comment.getAuthor()}" class="d-flex justify-content-between fst-italic">
|
||||||
|
<form th:action="@{/feed/deleteComment/{id}/{authorId} (id=${comment.id}, authorId=${selectedProfile.id})}" method="post" >
|
||||||
|
<button type="submit" class="btn btn-danger me-1 mb-1"> <i class="fa fa-trash" aria-hidden="true"> </i> </button>
|
||||||
|
</form>
|
||||||
|
<form th:action="@{/feed/commentEditModal/{id}/{authorId} (id=${comment.id}, authorId=${selectedProfile.id})}" method="get">
|
||||||
|
<button type="submit" class="btn btn-warning mb-1" data-bs-toggle="modal" data-bs-target="#postEdit" >
|
||||||
|
<i class="fa fa-pencil" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form th:action="@{/feed/commentModal/{authorId}/{postId}/ ( authorId=${selectedProfile.id}, postId=${post.id} ) }" method="get" class="text-end">
|
||||||
|
<button type="submit" class="btn btn-info mb-3" data-bs-toggle="modal" data-bs-target="#commentCreate">Добавить комментарий</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal fade" id="postCreate" tabindex="-1" role="dialog" aria-labelledby="postCreateLabel" aria-hidden="true">
|
<div class="modal fade" id="postCreate" tabindex="-1" role="dialog" aria-labelledby="postCreateLabel" aria-hidden="true">
|
||||||
@ -67,15 +95,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div layout:fragment="modalFeed"></div>
|
<div layout:fragment="modalFeed"></div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript">
|
|
||||||
window.onload = () => {
|
|
||||||
$('#postEdit').modal('show');
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
29
src/main/resources/templates/profilePage.html
Normal file
29
src/main/resources/templates/profilePage.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{default}">
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div layout:fragment="content">
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="text-start mx-auto w-25 border p-5">
|
||||||
|
<p class='h5'>Профиль</p>
|
||||||
|
<p th:text="${'Логин: ' + profile.login}"></p>
|
||||||
|
<p class='h6 '>Список постов пользователя: </p>
|
||||||
|
|
||||||
|
<div th:if="${profile.posts.size()>0}">
|
||||||
|
<div th:each="post: ${profile.posts}">
|
||||||
|
<p th:text="${post.text}" class="mb-3 ms-2 border p-2"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p th:unless="${profile.posts.size()>0}">
|
||||||
|
Нет постов
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user