restructured code (modal => internal view)

This commit is contained in:
Pete Gerlach
2024-06-11 15:26:17 +02:00
parent 0ab53963fb
commit 5ef0b504e1
4 changed files with 213 additions and 267 deletions

View File

@@ -1,12 +1,12 @@
import React, {useEffect, useState} from 'react';
import PostList from './components/PostList';
import NewPostForm from './components/NewPostForm';
import Modal from './components/Modal';
import './App.scss';
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faCaretDown, faCaretUp} from "@fortawesome/free-solid-svg-icons";
import {faCaretDown, faCaretUp, faTimes} from "@fortawesome/free-solid-svg-icons";
import {postApi} from "./api/posts.api";
import {locationUtils} from "./utils/location";
import Post from "./components/Post";
const App = () => {
const [posts, setPosts] = useState([]);
@@ -15,7 +15,9 @@ const App = () => {
useEffect(() => {
if(posts.length === 0) {
loadPosts().then(data => setPosts(data))
loadPosts().then(data => setPosts(data));
} else {
console.log(posts);
}
})
@@ -24,50 +26,17 @@ const App = () => {
return await postApi.getPostsByCoords(location.lon, location.lat);
}
const addPost = (text) => {
const newPost = { id: Date.now(), text, comments: [], upvotes: 0, downvotes: 0 };
setPosts([newPost, ...posts]);
const addPost = async (title, text) => {
await postApi.createNewPost(title, text);
loadPosts().then(data => setPosts(data));
};
const addComment = (postId, commentText) => {
const newComment = { id: Date.now(), text: commentText, upvotes: 0, downvotes: 0 };
setPosts(posts.map(post =>
post.id === postId ? { ...post, comments: [...post.comments, newComment] } : post
));
};
const upvotePost = (postId) => {
setPosts(posts.map(post =>
post.id === postId ? { ...post, upvotes: post.upvotes + 1 } : post
));
};
const downvotePost = (postId) => {
setPosts(posts.map(post =>
post.id === postId ? { ...post, downvotes: post.downvotes + 1 } : post
));
};
const upvoteComment = (postId, commentId) => {
setPosts(posts.map(post =>
post.id === postId ? {
...post,
comments: post.comments.map(comment =>
comment.id === commentId ? { ...comment, upvotes: comment.upvotes + 1 } : comment
)
} : post
));
};
const downvoteComment = (postId, commentId) => {
setPosts(posts.map(post =>
post.id === postId ? {
...post,
comments: post.comments.map(comment =>
comment.id === commentId ? { ...comment, downvotes: comment.downvotes + 1 } : comment
)
} : post
));
const vote = (postId, reaction) => {
// TODO postApi.reactToPost(postId)
};
const handlePostClick = (post) => {
@@ -82,56 +51,66 @@ const App = () => {
}
};
const closeModal = () => {
const closePost = () => {
setSelectedPost(null);
setComment('');
};
return (
<div className="app">
<h1>SWA - Jodel</h1>
<NewPostForm addPost={addPost} />
<PostList
posts={posts}
addComment={addComment}
upvotePost={upvotePost}
downvotePost={downvotePost}
upvoteComment={upvoteComment}
downvoteComment={downvoteComment}
onPostClick={handlePostClick}
/>
<Modal isOpen={!!selectedPost} onClose={closeModal}>
{selectedPost && (
<div>
<p>{selectedPost.text}</p>
<form className="comment-form" onSubmit={handleCommentSubmit}>
<input
type="text"
{!selectedPost && (
<div>
<h1>SWA - Jodel</h1>
<NewPostForm addPost={addPost}/>
<PostList
posts={posts}
addComment={addComment}
vote={vote}
onPostClick={handlePostClick}
/>
</div>
)}
{selectedPost && (
<div className="single-post-view">
<div className="close-post">
<FontAwesomeIcon className={"close-button"} onClick={closePost} icon={faTimes}/>
</div>
<Post post={selectedPost} vote={vote}></Post>
<form className="comment-form" onSubmit={handleCommentSubmit}>
<div className="textarea-container">
<textarea
rows={15}
value={comment}
onChange={(e) => setComment(e.target.value)}
placeholder="Kommentieren..."
maxLength={500}
/>
<button type="submit">Kommentieren</button>
</form>
<div className="comments">
{selectedPost.comments.map((comment) => (
<div key={comment.id} className="comment">
<p>{comment.text}</p>
<div className="votes">
<button onClick={() => upvoteComment(selectedPost.id, comment.id)}>
<FontAwesomeIcon icon={faCaretUp} />
</button>
<span>{comment.upvotes - comment.downvotes}</span>
<button onClick={() => downvoteComment(selectedPost.id, comment.id)}>
<FontAwesomeIcon icon={faCaretDown} />
</button>
</div>
</div>
))}
<div className="char-count-container">
<span className={comment.length === 500 ? "char-count max-char-count" : "char-count"}>
{comment.length} / 500
</span>
</div>
</div>
<button type="submit">Kommentieren</button>
</form>
<div className="comments">
{selectedPost.comments.map((comment) => (
<div key={comment.id} className="comment">
<p>{comment.text}</p>
<div className="votes">
<button onClick={() => vote(selectedPost.id, comment.id)}>
<FontAwesomeIcon icon={faCaretUp}/>
</button>
<span>{comment.upvotes - comment.downvotes}</span>
<button onClick={() => vote(selectedPost.id, comment.id)}>
<FontAwesomeIcon icon={faCaretDown}/>
</button>
</div>
</div>
))}
</div>
)}
</Modal>
</div>
)}
</div>
);
}