Skip to content
Snippets Groups Projects
Commit 47d4d2ef authored by Richard Githuba's avatar Richard Githuba
Browse files

deleting a post now working

parent 02949bac
No related branches found
No related tags found
No related merge requests found
package polish_community_group_11.polish_community.feed.controllers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;
import polish_community_group_11.polish_community.feed.models.FeedImpl;
import polish_community_group_11.polish_community.feed.repository.FeedRepository;
import polish_community_group_11.polish_community.feed.services.FeedService;
import polish_community_group_11.polish_community.register.models.User;
import polish_community_group_11.polish_community.register.services.UserService;
import java.util.List;
......@@ -14,18 +21,47 @@ import java.util.List;
public class FeedApisController {
private final FeedRepository feedRepository;
private final UserService userService;
private final FeedService feedService;
private static final Logger log = LoggerFactory.getLogger(FeedApisController.class);
public FeedApisController(FeedRepository feedRepository, FeedService feedService) {
public FeedApisController(FeedRepository feedRepository, FeedService feedService, UserService userService) {
this.feedService = feedService;
this.feedRepository = feedRepository;
this.userService = userService;
}
// getting all posts
@GetMapping
public List<FeedImpl> getAllPosts() {
return feedRepository.getAllPosts();
log.info("Fetching all posts");
// getting current user
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User currentUser = null;
if (auth != null && auth.isAuthenticated() && !auth.getPrincipal().equals("anonymousUser")) {
String email = auth.getName();
log.info("User Email: " + email);
currentUser = userService.findByEmail(email);
log.info("Current User: " + currentUser);
}
List<FeedImpl> posts = feedRepository.getAllPosts();
// set isEditable flag for each post depedant on whether they are an admin or own the post
for (FeedImpl post : posts) {
log.info("Role ID: " + currentUser.getRoleId());
boolean isSuperAdmin = currentUser != null && currentUser.getRoleId() == 1;
log.info("IsSuperAdmin: " + isSuperAdmin);
boolean isOwner = currentUser != null && post.getUserId() == currentUser.getId();
log.info("IsPostOwner: " + isOwner);
post.setIsEditable(isSuperAdmin || isOwner);
log.info("PostIsEditable: " + post.getIsEditable());
}
return posts;
}
//getting them by id
......@@ -63,14 +99,36 @@ public class FeedApisController {
}
}
// deleting a post
@DeleteMapping("/{postId}")
public ResponseEntity<Void> deletePost(@PathVariable int postId) {
try {
// get logged in user
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
FeedImpl post = feedRepository.getPostById(postId);
if (post == null) {
return ResponseEntity.notFound().build();
}
// get current user
UserDetails userDetails = (UserDetails) auth.getPrincipal();
User currentUser = userService.findByEmail(userDetails.getUsername());
// check if admin or post owner
boolean isSuperAdmin = currentUser.getRoleId() == 1;
boolean isPostOwner = post.getUserId() == currentUser.getId();
if (!isSuperAdmin && !isPostOwner) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
feedRepository.deletePost(postId);
return ResponseEntity.ok().build();
} catch (Exception e) {
return ResponseEntity.notFound().build();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
......
......@@ -30,6 +30,12 @@ public interface Feed {
int getLikesCount();
void setLikesCount(int likesCount);
boolean getIsEditable();
void setIsEditable(boolean isEditable);
int getPostId();
}
\ No newline at end of file
......@@ -21,4 +21,16 @@ public class FeedImpl implements Feed {
private String authorOrganization;
private List<String> tags;
private int likesCount;
private boolean isEditable;
@Override
public boolean getIsEditable() {
return isEditable;
}
@Override
public void setIsEditable(boolean isEditable) {
this.isEditable = isEditable;
}
}
......@@ -34,12 +34,35 @@
gap: 20px;
}
.post-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.author-details{
display: flex;
gap: 10px;
align-items: center;
}
.post-manipulation > button {
border: none;
background-color: transparent;
cursor: pointer;
}
.post-manipulation {
display: flex;
gap: 15px;
}
.delete-post {
color: var(--tertiary-color);
}
.edit-post {
color: var(--secondary-text-color);
}
.profile-picture{
width: 46px;
height: 46px;
......
body {
section {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
section {
max-width: 1200px;
width: 100%;
padding: 20px;
}
......
......@@ -23,6 +23,7 @@ body {
min-height: 100vh; /* Ensures the body covers the viewport height */
display: flex;
flex-direction: column;
margin: 0;
}
.main-content {
......@@ -132,7 +133,6 @@ nav.sidebar {
.footer {
position: relative;
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* grid layout */
grid-template-rows: auto auto;
......
......@@ -45,6 +45,8 @@ function renderPosts() {
async function renderPost(post) {
const postElement = postTemplate.content.cloneNode(true);
const deleteButton = postElement.querySelector('.delete-post');
deleteButton.style.display = post.isEditable ? 'block' : 'none';
postElement.querySelector('.author').textContent = post.authorName;
postElement.querySelector('.author-title').textContent = post.authorOrganization;
postElement.querySelector('.post-title').textContent = post.postTitle;
......@@ -83,6 +85,31 @@ async function renderPost(post) {
const postDiv = postElement.querySelector('.post');
postDiv.dataset.postId = post.postId;
//deleting post
if (post.isEditable) {
deleteButton.addEventListener('click', async () => {
if (confirm('Are you sure you want to delete this post?')) {
try {
const response = await fetch(`${API_BASE_URL}/${post.postId}`, {
method: 'DELETE',
credentials: 'include'
});
if (!response.ok) {
throw new Error('Failed to delete post');
}
const postDiv = deleteButton.closest('.post');
postDiv.remove();
posts = posts.filter(p => p.postId !== post.postId);
} catch (error) {
console.error('Error deleting post:', error);
alert('Error deleting post. Please try again.');
}
}
});
}
postFeed.appendChild(postElement);
}
......
......@@ -21,6 +21,7 @@
<!-- using template since I want to use it in javascript -->
<template id="post-template">
<div class="post">
<div class="post-header">
<div class="author-details">
<div class="profile-picture">
<!--add the profile picture later -->
......@@ -30,6 +31,16 @@
<p class="author-title"></p>
</div>
</div>
<div class="post-manipulation">
<button title="Delete post" class="edit-post" id="edit-post">
<i class="bi bi-pencil"></i>
</button>
<button title="Edit post" class="delete-post" id="delete-post">
<i class="bi bi-trash3"></i>
</button>
</div>
</div>
<div class="post-details">
<h3 class="post-title"></h3>
<p class="post-description"></p>
......@@ -42,15 +53,15 @@
</div>
<div class="post-meta">
<div class="post-actions">
<button class="like-button">
<button title="Like post" class="like-button">
<i class="bi bi-hand-thumbs-up"></i>
<span class="like-count">0</span>
</button>
<button>
<button title="Commend on post">
<i class="bi bi-chat-left"></i>
<span>35</span>
</button>
<button>
<button title="Share post">
<i class="bi bi-share"></i>
</button>
</div>
......
......@@ -8,7 +8,7 @@
<title>HOME</title>
<link rel="stylesheet" href="/css/home/home.css">
</head>
<body>
<section layout:fragment="content">
<h1>Welcome to our Community</h1>
<p>Connect, Share, and Grow Together</p>
......@@ -66,6 +66,6 @@
<button>Get Started</button>
</section>
</body>
</html>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment