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 React, { useState } from 'react';
|
||||||
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
|
import PostList from './components/PostList';
|
||||||
import Home from './components/Home';
|
import NewPostForm from './components/NewPostForm';
|
||||||
import PostDetail from './components/PostDetail';
|
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 (
|
return (
|
||||||
<Router>
|
<div className="app">
|
||||||
<Routes>
|
<h1>Jodel Clone</h1>
|
||||||
<Route path="/" element={<Home />} />
|
<NewPostForm addPost={addPost} />
|
||||||
<Route path="/post/:id" element={<PostDetail />} />
|
<PostList
|
||||||
</Routes>
|
posts={posts}
|
||||||
</Router>
|
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;
|
|
||||||
169
src/App.scss
169
src/App.scss
@@ -1,33 +1,160 @@
|
|||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f6f7f9;
|
||||||
|
color: #4a4a4a;
|
||||||
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vote {
|
.app {
|
||||||
margin-left: 10px;
|
max-width: 800px;
|
||||||
display: inline-block;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vote:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 600px;
|
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.post {
|
h1 {
|
||||||
background-color: #fff;
|
color: #ff9908;
|
||||||
border: 1px solid #ddd;
|
text-align: center;
|
||||||
padding: 10px;
|
font-weight: normal;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment {
|
.new-post-form {
|
||||||
background-color: #fff;
|
display: flex;
|
||||||
border: 1px solid #ddd;
|
flex-direction: column;
|
||||||
padding: 10px;
|
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
input[type="text"] {
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 15px;
|
||||||
|
background-color: #ff9908;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-size: 1em;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #e68a00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-list {
|
||||||
|
.post {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
margin: 10px 0;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
.post-content {
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.votes {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #ff9908;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1.5em;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #e68a00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 1.2em;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-form {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
input[type="text"] {
|
||||||
|
padding: 10px;
|
||||||
|
flex: 1;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #ff9908;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1em;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #e68a00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.comments {
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
.comment {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
.votes {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 5px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #ff9908;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1.5em;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #e68a00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 1em;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
import WritePost from './WritePost';
|
|
||||||
import '../App.scss';
|
|
||||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
|
||||||
import {faCaretDown, faCaretUp} from "@fortawesome/free-solid-svg-icons"; // Importiere das Styling
|
|
||||||
|
|
||||||
function Home() {
|
|
||||||
const [posts, setPosts] = useState([]);
|
|
||||||
|
|
||||||
const handlePost = function(content) {
|
|
||||||
const newPost = {
|
|
||||||
id: posts.length + 1,
|
|
||||||
content: content,
|
|
||||||
upvotes: 0,
|
|
||||||
downvotes: 0
|
|
||||||
};
|
|
||||||
setPosts([...posts, newPost]);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="container"> {/* Verwende die Klasse container */}
|
|
||||||
<h1>Jodel Clone</h1>
|
|
||||||
<WritePost onPost={handlePost} />
|
|
||||||
{posts.map(post => (
|
|
||||||
<div key={post.id} className="post"> {/* Verwende die Klasse post */}
|
|
||||||
<p>{post.content}</p>
|
|
||||||
<div className="vote">
|
|
||||||
<FontAwesomeIcon icon={faCaretUp} onClick={() => console.log("upvote")} />
|
|
||||||
<FontAwesomeIcon icon={faCaretDown} onClick={() => console.log("downvote")} />
|
|
||||||
{post.upvotes - post.downvotes}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Home;
|
|
||||||
21
src/components/Modal.js
Normal file
21
src/components/Modal.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
import { faTimes } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import './Modal.scss';
|
||||||
|
|
||||||
|
const Modal = ({ isOpen, onClose, children }) => {
|
||||||
|
if (!isOpen) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="modal-overlay">
|
||||||
|
<div className="modal">
|
||||||
|
<button className="close-button" onClick={onClose}>
|
||||||
|
<FontAwesomeIcon icon={faTimes} />
|
||||||
|
</button>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Modal;
|
||||||
34
src/components/Modal.scss
Normal file
34
src/components/Modal.scss
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
.modal-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 600px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
font-size: 1.5em;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #ff9908;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/components/NewPostForm.js
Normal file
27
src/components/NewPostForm.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
const NewPostForm = ({ addPost }) => {
|
||||||
|
const [text, setText] = useState('');
|
||||||
|
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (text.trim()) {
|
||||||
|
addPost(text);
|
||||||
|
setText('');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form className="new-post-form" onSubmit={handleSubmit}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={text}
|
||||||
|
onChange={(e) => setText(e.target.value)}
|
||||||
|
placeholder="Schreibe einen neuen Jodel..."
|
||||||
|
/>
|
||||||
|
<button type="submit">Posten</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NewPostForm;
|
||||||
@@ -1,34 +1,24 @@
|
|||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faCaretUp, faCaretDown } from '@fortawesome/free-solid-svg-icons';
|
import { faCaretUp, faCaretDown } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
function Post({ post }) {
|
const Post = ({ post, upvotePost, downvotePost }) => {
|
||||||
const [upvotes, setUpvotes] = useState(post.upvotes);
|
|
||||||
const [downvotes, setDownvotes] = useState(post.downvotes);
|
|
||||||
|
|
||||||
const handleUpvote = () => {
|
|
||||||
// Logic to handle upvote
|
|
||||||
setUpvotes(upvotes + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDownvote = () => {
|
|
||||||
// Logic to handle downvote
|
|
||||||
setDownvotes(downvotes + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="post">
|
<div className="post">
|
||||||
<p>{post.content}</p>
|
<div className="post-content">
|
||||||
<div className="vote">
|
<p>{post.text}</p>
|
||||||
<FontAwesomeIcon icon={faCaretUp} onClick={handleUpvote} />
|
|
||||||
{upvotes}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="vote">
|
<div className="votes">
|
||||||
<FontAwesomeIcon icon={faCaretDown} onClick={handleDownvote} />
|
<button onClick={(e) => { e.stopPropagation(); upvotePost(post.id); }}>
|
||||||
{downvotes}
|
<FontAwesomeIcon icon={faCaretUp} />
|
||||||
|
</button>
|
||||||
|
<span>{post.upvotes - post.downvotes}</span>
|
||||||
|
<button onClick={(e) => { e.stopPropagation(); downvotePost(post.id); }}>
|
||||||
|
<FontAwesomeIcon icon={faCaretDown} />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Post;
|
export default Post;
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
import WriteComment from './WriteComment';
|
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
||||||
import { faCaretUp, faCaretDown } from '@fortawesome/free-solid-svg-icons';
|
|
||||||
import '../App.scss'; // Importiere das Styling
|
|
||||||
|
|
||||||
function PostDetail() {
|
|
||||||
const [comments, setComments] = useState([]);
|
|
||||||
|
|
||||||
const handleComment = function(comment) {
|
|
||||||
setComments([...comments, comment]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const calculateVotes = function(comment) {
|
|
||||||
return comment.upvotes - comment.downvotes;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleVote = function(index, type) {
|
|
||||||
const updatedComments = [...comments];
|
|
||||||
if (type === 'upvote') {
|
|
||||||
updatedComments[index].upvotes++;
|
|
||||||
} else if (type === 'downvote') {
|
|
||||||
updatedComments[index].downvotes++;
|
|
||||||
}
|
|
||||||
setComments(updatedComments);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="container"> {/* Verwende die Klasse container */}
|
|
||||||
<h2>Post Detail</h2>
|
|
||||||
<h3>Comments</h3>
|
|
||||||
{comments.map((comment, index) => (
|
|
||||||
<div key={index} className="comment"> {/* Verwende die Klasse comment */}
|
|
||||||
<p>{comment.content}</p>
|
|
||||||
<div className="vote">
|
|
||||||
<FontAwesomeIcon icon={faCaretUp} onClick={() => handleVote(index, 'upvote')} />
|
|
||||||
<FontAwesomeIcon icon={faCaretDown} onClick={() => handleVote(index, 'downvote')} />
|
|
||||||
{calculateVotes(comment)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
<WriteComment onComment={handleComment} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default PostDetail;
|
|
||||||
20
src/components/PostList.js
Normal file
20
src/components/PostList.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Post from './Post';
|
||||||
|
|
||||||
|
const PostList = ({ posts, upvotePost, downvotePost, onPostClick }) => {
|
||||||
|
return (
|
||||||
|
<div className="post-list">
|
||||||
|
{posts.map(post => (
|
||||||
|
<div key={post.id} onClick={() => onPostClick(post)}>
|
||||||
|
<Post
|
||||||
|
post={post}
|
||||||
|
upvotePost={upvotePost}
|
||||||
|
downvotePost={downvotePost}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PostList;
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
|
|
||||||
function WriteComment({ onComment }) {
|
|
||||||
const [content, setContent] = useState('');
|
|
||||||
|
|
||||||
const handleChange = function(e) {
|
|
||||||
setContent(e.target.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
onComment({ content: content, upvotes: 0, downvotes: 0 });
|
|
||||||
setContent('');
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h2>Write a Comment</h2>
|
|
||||||
<form onSubmit={handleSubmit}>
|
|
||||||
<textarea
|
|
||||||
value={content}
|
|
||||||
onChange={handleChange}
|
|
||||||
placeholder="Write your comment here..."
|
|
||||||
rows={4}
|
|
||||||
cols={50}
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<button type="submit">Submit</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default WriteComment;
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
|
|
||||||
function WritePost({ onPost }) {
|
|
||||||
const [content, setContent] = useState('');
|
|
||||||
|
|
||||||
const handleChange = function(e) {
|
|
||||||
setContent(e.target.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
// Hier die Logik für das Hinzufügen des Posts implementieren
|
|
||||||
// z.B. eine Funktion ausführen, die von der übergeordneten Komponente übergeben wurde
|
|
||||||
onPost(content);
|
|
||||||
// Setze den Inhaltsbereich zurück
|
|
||||||
setContent('');
|
|
||||||
};
|
|
||||||
|
|
||||||
return React.createElement(
|
|
||||||
'div',
|
|
||||||
null,
|
|
||||||
React.createElement('h2', null, 'Write a Post'),
|
|
||||||
React.createElement(
|
|
||||||
'form',
|
|
||||||
{ onSubmit: handleSubmit },
|
|
||||||
React.createElement('textarea', {
|
|
||||||
value: content,
|
|
||||||
onChange: handleChange,
|
|
||||||
placeholder: 'Write your post here...',
|
|
||||||
rows: 4,
|
|
||||||
cols: 50
|
|
||||||
}),
|
|
||||||
React.createElement('br', null),
|
|
||||||
React.createElement('button', { type: 'submit' }, 'Submit')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default WritePost;
|
|
||||||
Reference in New Issue
Block a user