From ea2d36de1c43308d2eb601e45ee3c537d89a4913 Mon Sep 17 00:00:00 2001
From: MisbehavedNinjaRadiator
<120029998+MisbehavedNinjaRadiator@users.noreply.github.com.>
Date: Sat, 28 Jun 2025 16:44:48 +0200
Subject: [PATCH] Feed funktioniert, infinite scroll funktioniert nicht mehr
---
code/frontend/src/components/Post.tsx | 122 ++++++++++++++-------
code/frontend/src/components/feed/Feed.tsx | 56 ++++++----
code/frontend/src/components/feed/feed.css | 4 +-
3 files changed, 116 insertions(+), 66 deletions(-)
diff --git a/code/frontend/src/components/Post.tsx b/code/frontend/src/components/Post.tsx
index edaa81e..9e52b7e 100644
--- a/code/frontend/src/components/Post.tsx
+++ b/code/frontend/src/components/Post.tsx
@@ -14,57 +14,79 @@ import FavoriteIcon from '@mui/icons-material/Favorite';
import ShareIcon from '@mui/icons-material/Share';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import MoreVertIcon from '@mui/icons-material/MoreVert';
+import api from "../api/axios";
interface ExpandMoreProps extends IconButtonProps {
expand: boolean;
}
interface PostProps {
- postId: number;
+ postId: string;
}
+interface PostResponse {
+ description: string;
+ status: string;
+ likes: number;
+ tags: string[];
+ user: {
+ id: string;
+ name: string;
+ };
+ createdAt: string;
+ updatedAt: string;
+ images: {
+ originalName: string;
+ mimetype: string;
+ url: string;
+ }[];
+ following: boolean;
+}
+
const ExpandMore = styled((props: ExpandMoreProps) => {
const { expand, ...other } = props;
return ;
-})(({ theme }) => ({
+})(({ theme, expand }) => ({
marginLeft: 'auto',
transition: theme.transitions.create('transform', {
duration: theme.transitions.duration.shortest,
}),
- variants: [
- {
- props: ({ expand }) => !expand,
- style: {
- transform: 'rotate(0deg)',
- },
- },
- {
- props: ({ expand }) => !!expand,
- style: {
- transform: 'rotate(180deg)',
- },
- },
- ],
+ transform: expand ? 'rotate(180deg)' : 'rotate(0deg)',
}));
-export default function Post({postId}: PostProps) {
+export default function Post({ postId }: PostProps) {
const [expanded, setExpanded] = React.useState(false);
- const content = "Fetch content here";
- const expandedContent = "Fetch expanded here"
- const title = "Fetch heading here";
- const createdAt = "Fetch created at here";
- const user = "Fetch user here";
- const media = "Fetch media here (path)";
+ const [post, setPost] = React.useState(null);
- const handleExpandClick = () => {
- setExpanded(!expanded);
- };
+ React.useEffect(() => {
+ getPostbyID();
+ // eslint-disable-next-line
+ }, [postId]);
+ async function getPostbyID(): Promise {
+ try {
+ const response = await api.get(`/posts/getPost/{postId}?postId=${postId}`);
+ //const response = await api.get(`http://localhost:3001/api/posts/getPost/{postId}?postId=${postId}`);
+ setPost(response.data);
+ } catch (error) {
+ console.error("Failed to fetch post:", error);
+ }
+ }
+
+ if (!post) {
+ return (
+
+
+ Loading...
+
+
+ );
+ }
return (
-
+
- {user ? user.charAt(0).toUpperCase() : 'U'} //Todo: when fetching change to user.name or sth
+
+ {post.user.name.charAt(0).toUpperCase()}
}
action={
@@ -72,17 +94,32 @@ export default function Post({postId}: PostProps) {
}
- title={title}
- subheader= {createdAt}
- />
-
+ {post.images && post.images.length > 0 && (
+
+ )}
-
- {content}
+
+ {post.description}
+
+
+ Status: {post.status}
+
+
+ Likes: {post.likes}
+
+
+ Tags: {post.tags.join(", ")}
+
+
+ Following: {post.following ? "Ja" : "Nein"}
@@ -94,7 +131,7 @@ export default function Post({postId}: PostProps) {
setExpanded(!expanded)}
aria-expanded={expanded}
aria-label="show more"
>
@@ -103,7 +140,12 @@ export default function Post({postId}: PostProps) {
- {expandedContent}
+
+ Erstellt am: {new Date(post.createdAt).toLocaleString()}
+
+
+ Zuletzt aktualisiert: {new Date(post.updatedAt).toLocaleString()}
+
diff --git a/code/frontend/src/components/feed/Feed.tsx b/code/frontend/src/components/feed/Feed.tsx
index 6bf3dd2..a6f0ee5 100644
--- a/code/frontend/src/components/feed/Feed.tsx
+++ b/code/frontend/src/components/feed/Feed.tsx
@@ -1,34 +1,45 @@
import React, { useState, useEffect, useRef } from "react";
import Post from "../Post";
import "./feed.css";
+import api from "../../api/axios";
+
+interface PostListItem {
+ id: string;
+ createdAt: string;
+ description: string;
+}
function Feed() {
- const [posts, setPosts] = useState([]);
+ const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(false);
const [hasMore, setHasMore] = useState(true);
+ const [nextCursor, setNextCursor] = useState(null);
const feedRef = useRef(null);
const PAGE_SIZE = 10;
- // Dummy fetch function that simulates loading posts by ID
- const fetchPosts = () => {
- if (loading) return;
+ const fetchPosts = async () => {
+ if (loading || !hasMore) return;
setLoading(true);
+ try {
+ const params: any = { limit: PAGE_SIZE };
+ if (nextCursor) params.createdAt = nextCursor;
+ interface FeedResponse {
+ posts: PostListItem[];
- setTimeout(() => {
- setPosts((prev) => {
- const newPosts = [];
- for (let i = 0; i < PAGE_SIZE; i++) {
- newPosts.push(prev.length + i + 1);
- }
- return [...prev, ...newPosts];
- });
- setLoading(false);
-
- // Stop after 50 posts, just as an example
- if (posts.length + PAGE_SIZE >= 50) {
- setHasMore(false);
+ nextCursor: string | null;
}
- }, 800);
+ const response = await api.get("/feed?limit=10");
+ //const response = await api.get("http://localhost:3001/api/feed?limit=10");
+ console.log("Feed response:", response.data);
+ const { posts: newPosts, nextCursor: newCursor } = response.data;
+ setPosts((prev) => [...prev, ...newPosts]);
+ setNextCursor(newCursor);
+ setHasMore(!!newCursor && newPosts.length > 0);
+ } catch (error) {
+ console.error("Error fetching posts:", error);
+ } finally {
+ setLoading(false);
+ }
};
useEffect(() => {
@@ -39,24 +50,23 @@ function Feed() {
const onScroll = () => {
const feed = feedRef.current;
if (!feed || loading || !hasMore) return;
-
if (feed.scrollTop + feed.clientHeight >= feed.scrollHeight - 100) {
fetchPosts();
}
};
-
const feed = feedRef.current;
feed?.addEventListener("scroll", onScroll);
return () => {
feed?.removeEventListener("scroll", onScroll);
};
- }, [loading, hasMore]);
+ }, [loading, hasMore, nextCursor]);
return (
- {posts.map((postId) => (
-
+ {posts.length === 0 && !loading && Keine Posts gefunden.
}
+ {posts.map((post) => (
+
))}
{loading && Loading more posts...
}
{!hasMore && No more posts
}
diff --git a/code/frontend/src/components/feed/feed.css b/code/frontend/src/components/feed/feed.css
index 880344d..ed98bfc 100644
--- a/code/frontend/src/components/feed/feed.css
+++ b/code/frontend/src/components/feed/feed.css
@@ -1,9 +1,7 @@
-
.feedContainer {
display: flex;
flex-direction: column;
- height: 100vh;
- overflow: hidden;
+ min-height: calc(100vh - var(--Header-height));
background-color: #f9f9f9;
}