WIP: Basic Jodel Application

This commit is contained in:
Pete Gerlach
2024-06-02 13:48:26 +02:00
parent d2778cd922
commit f36ea7a34b
11 changed files with 384 additions and 215 deletions

View File

@@ -1,18 +1,126 @@
import React, { useState } from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Home from './components/Home';
import PostDetail from './components/PostDetail';
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";
const App = () => {
const [posts, setPosts] = useState([]);
const [selectedPost, setSelectedPost] = useState(null);
const [comment, setComment] = useState('');
const addPost = (text) => {
const newPost = { id: Date.now(), text, comments: [], upvotes: 0, downvotes: 0 };
setPosts([newPost, ...posts]);
};
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 handlePostClick = (post) => {
setSelectedPost(post);
};
const handleCommentSubmit = (e) => {
e.preventDefault();
if (comment.trim() && selectedPost) {
addComment(selectedPost.id, comment);
setComment('');
}
};
const closeModal = () => {
setSelectedPost(null);
setComment('');
};
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/post/:id" element={<PostDetail />} />
</Routes>
</Router>
<div className="app">
<h1>Jodel Clone</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"
value={comment}
onChange={(e) => setComment(e.target.value)}
placeholder="Kommentieren..."
/>
<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>
</div>
)}
</Modal>
</div>
);
}
export default App;
export default App;