WIP: Basic Jodel Application
This commit is contained in:
132
src/App.js
132
src/App.js
@@ -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;
|
||||
Reference in New Issue
Block a user