Skip to content

Commit

Permalink
Merge pull request #482 from bounswe/feature/FE-comments-likes
Browse files Browse the repository at this point in the history
Add comments, likes. Fix tags
  • Loading branch information
Halil-Ibrahim-Kasapoglu authored Dec 14, 2024
2 parents 8aef665 + 78c35e0 commit 85f62b1
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 149 deletions.
59 changes: 36 additions & 23 deletions frontend/src/components/community/CommunityPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,62 @@ import "../../styles/community/CommunityPage.css";
import PostCard from "./PostCard";
import "../../styles/Page.css";
import { useNavigate } from "react-router-dom";
import {apiClient} from "../../service/apiClient";
import { apiClient } from "../../service/apiClient";

const CommunityPage = () => {
const [searchTerm, setSearchTerm] = useState("");
const [sortOrder, setSortOrder] = useState("dsc");
const [searchActive, setSearchActive] = useState(false);
const [posts, setPosts] = useState([]);
const [tags, setTags] = useState({});
const [users, setUsers] = useState({});
const navigate = useNavigate();

useEffect(() => {
const fetchPosts = async () => {
try {
const response = await apiClient.get("/posts");
const tagsResponse = await apiClient.get("/tags");
if (!tagsResponse.data) throw new Error("Failed to fetch tags");
const tagsById = tagsResponse.data.reduce((acc, tag) => {
acc[tag.id] = tag.name;
return acc;
}, {});
setTags(tagsById);

const usersResponse = await apiClient.get("/users");
console.log(usersResponse);
const usersById = usersResponse.data.reduce((acc, user) => {
acc[user.id] = user.username;
console.log(acc);
return acc;
}, {});
setUsers(usersById);

console.log(usersById);
const transformedPosts = response.data.map((post) => ({
"post-id": post.id,
user: usersById[post.author] || "Unknown",
title: post.title,
content: [{ type: "plain-text", "plain-text": post.content }],
comments: [],
likes: post.liked_by.length,
tags: post.tags.map((tagId) => tagsById[tagId] || "Unknown"),
"publication-date": new Date(post.created_at).toLocaleDateString(),
}));
const transformedPosts = await Promise.all(
response.data.map(async (post) => {
try {
const commentsResponse = await apiClient.get(
`/comments/post-comments/${post.id}`
);

return {
"post-id": post.id,
user: usersById[post.author] || "Unknown",
title: post.title,
content: [{ type: "plain-text", "plain-text": post.content }],
comments: commentsResponse.data,
likes: post.liked_by?.length || 0,
tags: post.tags || [],
"publication-date": new Date(post.created_at),
};
} catch (error) {
console.error(
`Error fetching comments for post ${post.id}:`,
error
);
return {
"post-id": post.id,
user: usersById[post.author] || "Unknown",
title: post.title,
content: [{ type: "plain-text", "plain-text": post.content }],
comments: 0,
likes: post.liked_by?.length || 0,
tags: post.tags || [],
"publication-date": new Date(post.created_at),
};
}
})
);
setPosts(transformedPosts);
} catch (error) {
console.error("Error fetching posts:", error);
Expand Down
38 changes: 16 additions & 22 deletions frontend/src/components/community/CreatePostPage.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { useState, useEffect, useRef } from "react";
import { useNavigate } from "react-router-dom";
import "../../styles/community/CreatePostPage.css";
import {apiClient} from "../../service/apiClient";
import { apiClient } from "../../service/apiClient";
import userService from "../../service/userService";

const CreatePostPage = () => {
const navigate = useNavigate();
Expand Down Expand Up @@ -29,23 +30,12 @@ const CreatePostPage = () => {
}, [navigate]);

useEffect(() => {
const mockTags = [
{ id: 1, name: "Stock Analysis" },
{ id: 2, name: "BIST30" },
{ id: 3, name: "S&P" },
{ id: 4, name: "NASDAQ" },
{ id: 5, name: "Dow Jones" },
{ id: 6, name: "USA" },
{ id: 7, name: "Türkiye" },
];

const fetchTags = async () => {
try {
const response = await apiClient.get("/tags");
setAvailableTags(response.data);
} catch (error) {
console.error("Failed to fetch tags, using mock data", error);
setAvailableTags(mockTags);
console.error("Failed to fetch tags!", error);
}
};

Expand Down Expand Up @@ -100,10 +90,11 @@ const CreatePostPage = () => {
}

const tagIds = selectedTags.map((tag) => tag.id);
const userID = userService.getUserId();
const postData = {
title,
content: description,
author: 2,
author: userID,
liked_by: [],
tags: tagIds,
portfolios: [],
Expand Down Expand Up @@ -147,14 +138,17 @@ const CreatePostPage = () => {

<div className="tag-selection-section">
<div className="tag-search-container" ref={tagSearchRef}>
<input
type="text"
className="tag-search-input"
placeholder="Search or select tags..."
value={searchQuery}
onChange={handleSearchChange}
onFocus={() => setShowTagSuggestions(true)}
/>
<div className="tag-input-wrapper">
<input
type="text"
className="tag-search-input"
placeholder="Search or select tags..."
value={searchQuery}
onChange={handleSearchChange}
onFocus={() => setShowTagSuggestions(true)}
/>
<button className="new-button">+ Add Tag</button>
</div>
{showTagSuggestions && (
<div className="tag-suggestions-box">
{filteredTags.map((tag, index) => (
Expand Down
102 changes: 51 additions & 51 deletions frontend/src/components/community/PostCard.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,62 @@
import React from 'react';
import { FaHeart, FaComment } from 'react-icons/fa';
import { useNavigate } from 'react-router-dom';
import '../../styles/community/PostCard.css';
import React from "react";
import { FaHeart, FaComment } from "react-icons/fa";
import { useNavigate } from "react-router-dom";
import "../../styles/community/PostCard.css";

const getColorForTag = (tag) => {
const asciiValue = tag.charCodeAt(0);
const colors = [
'#3498db',
'#e74c3c',
'#2ecc71',
'#f1c40f',
'#9b59b6'
];
return colors[asciiValue % 5];
const tagName = typeof tag === "string" ? tag : tag.name;
const asciiValue = tagName.charCodeAt(0);
const colors = ["#3498db", "#e74c3c", "#2ecc71", "#f1c40f", "#9b59b6"];
return colors[asciiValue % 5];
};

const PostCard = ({ post }) => {
const navigate = useNavigate();
const navigate = useNavigate();

const navigateToPost = (postId) => {
navigate(`/post/${postId}`);
};
const navigateToPost = (postId) => {
navigate(`/post/${postId}`);
};

return (
<div className="post-card">
<div className="post-header">
<h2>{post.title}</h2>
<p className="post-meta">
Published on: <span>{new Date(post['publication-date']).toLocaleDateString()}</span> by <span>{post['user']}</span>
</p>
</div>
<p>{post.content[0]["plain-text"]}</p>
<div className="post-info">
<div className="post-stats">
<span className="likes">
<FaHeart className="icon like-icon" /> {post.likes}
</span>
<span className="comments-box">
<FaComment className="icon comment-icon" /> { post.comments.length }
</span>
</div>
<button className="view-button" onClick={() => navigateToPost(post["post-id"])}>
View Post
</button>
</div>
<div className="post-tags">
{post.tags.map((tag, index) => (
<span
key={index}
className="post-tag"
style={{ backgroundColor: getColorForTag(tag) }}
>
{tag}
</span>
))}
</div>
return (
<div className="post-card">
<div className="post-header">
<h2>{post.title}</h2>
<p className="post-meta">
Published on:{" "}
<span>{new Date(post["publication-date"]).toLocaleDateString()}</span>{" "}
by <span>{post["user"]}</span>
</p>
</div>
<p>{post.content[0]["plain-text"]}</p>
<div className="post-info">
<div className="post-stats">
<span className="likes">
<FaHeart className="icon like-icon" /> {post.likes}
</span>
<span className="comments-box">
<FaComment className="icon comment-icon" /> {post.comments.length}
</span>
</div>
);
<button
className="view-button"
onClick={() => navigateToPost(post["post-id"])}
>
View Post
</button>
</div>
<div className="post-tags">
{post.tags.map((tag, index) => (
<span
key={index}
className="post-tag"
style={{ backgroundColor: getColorForTag(tag) }}
>
{tag}
</span>
))}
</div>
</div>
);
};

export default PostCard;
Loading

0 comments on commit 85f62b1

Please sign in to comment.