Skip to content

Commit

Permalink
Merge pull request #500 from bounswe/web/last-enpoints-connections
Browse files Browse the repository at this point in the history
Web/last enpoints connections
  • Loading branch information
OguzTNCR authored Dec 13, 2024
2 parents 7f56025 + 7dea20c commit dbd7ab3
Show file tree
Hide file tree
Showing 12 changed files with 419 additions and 187 deletions.
24 changes: 14 additions & 10 deletions web/tradeverse/src/components/structure/Post.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { dislikePost, undislikePost } from "../../services/dislike";

const Post = ({ post }) => {
const { user } = AuthData();
const [isLiked, setIsLiked] = useState(post.isLiked);
const [isDisliked, setIsDisliked] = useState(post.isDisliked);
const [nofLikes, setNofLikes] = useState(post.nofLikes);
const [nofDislikes, setNofDislikes] = useState(post.nofDislikes);
const [isLiked, setIsLiked] = useState(post.isLikedByUser);
const [isDisliked, setIsDisliked] = useState(post.isDislikedByUser);
const [nofLikes, setNofLikes] = useState(post.likeCount);
const [nofDislikes, setNofDislikes] = useState(post.dislikeCount);

const handleLike = async () => {
if (!user.isAuthenticated) {
Expand All @@ -21,14 +21,16 @@ const Post = ({ post }) => {
try {
if (isLiked) {
// Unlike the post
const response = await unlikePost({ username: user.name, postId: post.id });
const token = localStorage.getItem("authToken");
const response = await unlikePost(token, post.id);
if (response?.successful) {
setNofLikes((prev) => Math.max(prev - 1, 0)); // Ensure likes don't go below zero
setIsLiked(false);
}
} else {
// Like the post
const response = await likePost({ username: user.name, postId: post.id });
const token = localStorage.getItem("authToken");
const response = await likePost(token,post.id);
if (response?.successful) {
setNofLikes((prev) => prev + 1);
setIsLiked(true);
Expand All @@ -54,14 +56,16 @@ const Post = ({ post }) => {
try {
if (isDisliked) {
// Remove dislike
const response = await undislikePost({ username: user.name, postId: post.id });
const token = localStorage.getItem("authToken");
const response = await undislikePost(token,post.id);
if (response?.successful) {
setNofDislikes((prev) => prev - 1); // Ensure dislikes don't go below zero
setIsDisliked(false);
}
} else {
// Dislike the post
const response = await dislikePost({ username: user.name, postId: post.id });
const token = localStorage.getItem("authToken");
const response = await dislikePost(token,post.id);
if (response?.successful) {
setNofDislikes((prev) => prev + 1);
setIsDisliked(true);
Expand Down Expand Up @@ -92,10 +96,10 @@ const Post = ({ post }) => {
<div className={styles.post}>
<div className={styles.userAndTag}>
<div className={styles.userDetailsContainer}>
<img src={post.author.profilePhoto} className={styles.userImage} />
<img src={post.author.userPhoto} className={styles.userImage} />
<div className={styles.userDetails}>
<h3>{`${post.author.name}`}</h3>
<p>{`@${post.author.username}`}</p>
<p>{`@${post.createdBy}`}</p>
</div>
</div>
<div className={styles.postTag}>
Expand Down
16 changes: 11 additions & 5 deletions web/tradeverse/src/components/structure/RenderNavigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,25 @@ export const RenderMenu = () => {
const [subforums, setSubforums] = useState([]); // State for subforums

useEffect(() => {
fetch("http://35.246.188.121:8080/api/post/get-subforums/non-recursive")
fetch("http://35.246.188.121:8080/api/subforum/all") // New endpoint
.then((response) => response.json())
.then((data) => {
if (data.successful) {
const formattedSubforums = data.subforums.map((subforum) => ({
// Assuming the API directly returns an array of subforums
if (Array.isArray(data)) {
const formattedSubforums = data.map((subforum) => ({
id: subforum.id,
name: subforum.title,
name: subforum.name, // Adjusted to the 'name' field
description: subforum.description, // Including description if needed
tagColor: subforum.tagColor, // Including tag color if needed
}));
setSubforums(formattedSubforums.slice(0, 5)); // Take the first 5 or fewer
setSubforums(formattedSubforums.slice(0, 5)); // Take the first 5 subforums
} else {
console.error("Unexpected data format:", data);
}
})
.catch((error) => console.error("Error fetching subforums:", error));
}, []);

const toggleDropdown = () => {
setIsDropdownOpen(!isDropdownOpen);
};
Expand Down
157 changes: 103 additions & 54 deletions web/tradeverse/src/components/structure/comment.js
Original file line number Diff line number Diff line change
@@ -1,89 +1,128 @@
import React, { useState } from "react";
import styles from "../styles/comment.module.css";
import { AuthData } from "../../auth/AuthWrapper";
import { createComment } from "../../services/post";
import { createComment, deleteComment } from "../../services/post";

const Comment = ({ comment, level }) => {
const Comment = ({ comment, level, onDeleteComment }) => {
const { user } = AuthData();
const [showReplyBox, setShowReplyBox] = useState(false);
const [replyText, setReplyText] = useState("");
const [nestedReplies, setNestedReplies] = useState(comment.replies || []); // Local state for nested replies

const handleReplyToggle = () => {
setShowReplyBox(!showReplyBox);
};

const createCommentContent = (content) => {
console.log(content);
if (!content || !Array.isArray(content)) return "No content available";

return content
.filter((item) => item.type === "text" || item.type === "tag")
.map((item) => item.value)
.join(" ");
};

// const handleReplySubmit = () => {
// if (!replyText.trim()) return;
// console.log("Reply submitted:", replyText, "to comment ID:", comment.id);
// // Add logic to save the reply via an API or update the local state
// setReplyText(""); // Clear the reply input box
// setShowReplyBox(false); // Hide the reply box
// };


const parseContent = (content) => {
const parts = content.split(/(@\w+)/); // Split by '@' followed by a word
const result = [];

parts.forEach((part) => {
if (part.startsWith("@")) {
// Handle tags
result.push({ type: "tag", value: part });
} else if (part.trim() !== "") {
// Handle regular text
result.push({ type: "text", value: part.trim() });
}
});

return result;
};

return parts
.filter((part) => part.trim() !== "")
.map((part) => {
if (part.startsWith("@")) {
return { type: "tag", value: part };
}
return { type: "text", value: part };
});
};

const handleReplySubmit = async () => {
if (!replyText.trim()) return;

const commentPayload = {
username: user.name,
parentID: comment.id,
content: [...parseContent(replyText)]
content: parseContent(replyText),
postID: comment.postID, // Use the postID from the comment
parentCommentID: comment.id, // The current comment's ID as the parent
};


try {
const response = await createComment(commentPayload); // Add comment via API
if (response.successful) {
const token = localStorage.getItem("authToken");
const response = await createComment(commentPayload, token); // Add reply via API

if (response && response.isSuccessful) {
const newReply = {
id: response.id, // Use the ID returned by the API
content: commentPayload.content,
createdBy: user.name,
creationDate: new Date().toISOString(), // Approximate creation date
replies: [], // New comments initially have no replies
postID: comment.postID,
parentCommentID: comment.id,
};

setReplyText(""); // Clear the input field
setShowReplyBox(false); // Hide reply box
setNestedReplies((prevReplies) => [...prevReplies, newReply]); // Add the new reply locally
} else {
alert("Failed to add comment.");
alert("Failed to add reply.");
}
} catch (error) {
console.error("Error adding comment:", error);
alert("Error adding comment.");
console.error("Error adding reply:", error);
alert("Error adding reply.");
}
};

const handleDelete = async () => {
if (!user.isAuthenticated) {
alert("Please log in to delete this comment.");
return;
}

try {
const token = localStorage.getItem("authToken");
const commentPayload = { commentId: comment.id }; // Payload with the comment ID
const response = await deleteComment(commentPayload, token); // Call deleteComment API

if (response && response.isSuccessful) {
alert("Comment deleted successfully.");
onDeleteComment(comment.id); // Notify parent to remove this comment
} else {
alert("Failed to delete comment.");
}
} catch (error) {
console.error("Error deleting comment:", error);
alert("Error deleting comment.");
}
};

const createCommentContent = (content) => {
if (!content || !Array.isArray(content)) return "No content available";

return content.map((item, index) => {
if (item.type === "text") {
return <span key={index}>{item.value} </span>;
}
if (item.type === "tag") {
return (
<span key={index} style={{ color: "blue" }}>
{item.value}{" "}
</span>
);
}
return null;
});
};

return (
<div className={styles.comment} style={{ marginLeft: `${level * 20}px` }}>
<div className={styles.commentUserDetails}>
<h5>{comment.author?.username || "Anonymous"}</h5>
<div className={styles.commentHeader}>
<h5>{comment.createdBy || "Anonymous"}</h5>
<span>{new Date(comment.creationDate).toLocaleString()}</span>
{user.isAuthenticated && comment.createdBy === user.name && (
<button
className={styles.deleteButton}
onClick={handleDelete}
title="Delete comment"
>
🗑️
</button>
)}
</div>
<p className={styles.commentText}>{createCommentContent(comment.content)}</p>

<button onClick={handleReplyToggle} className={styles.replyButton}>
{showReplyBox ? "Cancel" : "Reply"}
</button>
{user.isAuthenticated && (
<button onClick={handleReplyToggle} className={styles.replyButton}>
{showReplyBox ? "Cancel" : "Reply"}
</button>
)}

{showReplyBox && (
<div className={styles.replyBox}>
Expand All @@ -99,10 +138,20 @@ const Comment = ({ comment, level }) => {
</div>
)}

{comment.comments && comment.comments.length > 0 && (
{/* Render nested replies */}
{nestedReplies.length > 0 && (
<div className={styles.nestedComments}>
{comment.comments.map((nestedComment) => (
<Comment key={nestedComment.id} comment={nestedComment} level={level + 1} />
{nestedReplies.map((nestedComment) => (
<Comment
key={nestedComment.id}
comment={nestedComment}
level={level + 1}
onDeleteComment={(childId) => {
setNestedReplies((prevReplies) =>
prevReplies.filter((reply) => reply.id !== childId)
);
}}
/>
))}
</div>
)}
Expand Down
47 changes: 25 additions & 22 deletions web/tradeverse/src/components/structure/feed.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,23 @@ const Feed = ({ posts }) => {
const [selectedSubforum, setSelectedSubforum] = useState("");

useEffect(() => {
const fetchSubforums = async () => {
try {
const response = await fetch("http://35.246.188.121:8080/api/post/get-subforums/non-recursive");
const data = await response.json();

if (data.successful) {
const subforumList = data.subforums.map((subforum) => ({
fetch("http://35.246.188.121:8080/api/subforum/all") // New endpoint
.then((response) => response.json())
.then((data) => {
// Assuming the API directly returns an array of subforums
if (Array.isArray(data)) {
const formattedSubforums = data.map((subforum) => ({
id: subforum.id,
title: subforum.title,
name: subforum.name, // Adjusted to the 'name' field
description: subforum.description, // Including description if needed
tagColor: subforum.tagColor, // Including tag color if needed
}));
setSubforums(subforumList);
setSubforums(formattedSubforums); // Take the first 5 subforums
} else {
console.error("Failed to fetch subforums:", data.message);
console.error("Unexpected data format:", data);
}
} catch (error) {
console.error("Error fetching subforums:", error);
}
};

fetchSubforums();
})
.catch((error) => console.error("Error fetching subforums:", error));
}, []);

const handleInputChange = (e) => {
Expand Down Expand Up @@ -93,7 +90,11 @@ const Feed = ({ posts }) => {
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onload = () => {
const base64String = reader.result;
console.log("Base64 String:", base64String); // Debugging
resolve(base64String);
};
reader.onerror = (error) => reject(error);
});

Expand All @@ -107,7 +108,8 @@ const Feed = ({ posts }) => {
if (selectedImage) {
try {
const base64Image = await getBase64Image(selectedImage);
contentArray.push({ type: "image", value: base64Image });
const sanitizedBase64 = base64Image.split(",")[1]; // Removes metadata
contentArray.push({ type: "image", value: sanitizedBase64 });
} catch (error) {
toast.error("Error converting image to Base64.");
}
Expand All @@ -119,19 +121,20 @@ const Feed = ({ posts }) => {
}

const postPayload = {
username: user.name,
title: postTitle, // Use the new title input here
parentID: selectedSubforum,
subforumID: selectedSubforum,
content: contentArray,
};


// Make the API call
try {
const response = await fetch("http://35.246.188.121:8080/api/post/create-post", {
const token = localStorage.getItem("authToken");
const response = await fetch("http://35.246.188.121:8080/api/post/create", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
},
body: JSON.stringify(postPayload),
});
Expand Down Expand Up @@ -179,7 +182,7 @@ const Feed = ({ posts }) => {
<option value="">-- Select Subforum --</option>
{subforums.map((subforum) => (
<option key={subforum.id} value={subforum.id}>
{subforum.title}
{subforum.name}
</option>
))}
</select>
Expand Down
Loading

0 comments on commit dbd7ab3

Please sign in to comment.