Initial commit

This commit is contained in:
2021-08-01 17:19:21 -04:00
commit 48bdeeba33
36 changed files with 23143 additions and 0 deletions

17
blog/client/src/App.js Normal file
View File

@@ -0,0 +1,17 @@
import React from 'react';
import PostCreate from './PostCreate';
import PostList from './PostList';
const App = () => {
return <div className="container">
<h1>Create Post</h1>
<PostCreate/>
<hr/>
<h1>Posts</h1>
<PostList/>
</div>;
};
export default App;

View File

@@ -0,0 +1,24 @@
import React, { useState } from 'react';
import axios from 'axios';
const CommentCreate = ({postID}) => {
const [content, setContent] = useState('');
const onSubmit = async (e) => {
e.preventDefault();
await axios.post(`http://localhost:4001/posts/${postID}/comments`, { content });
setContent('');
};
return <div>
<form onSubmit={onSubmit}>
<div className="form-group">
<label>New Comment</label>
<input className="form-control" onChange={e => setContent(e.target.value)} value={content}/>
</div>
<button className="btn btn-primary">Submit</button>
</form>
</div>;
}
export default CommentCreate;

View File

@@ -0,0 +1,24 @@
import React from 'react';
const CommentList = ({comments}) => {
const renderedComments = Object.values(comments).map(comment => {
let content;
if(comment.status === 'approved') {
content = comment.content;
} else if (comment.status === 'pending') {
content = 'This comment is awaiting moderation';
} else if (comment.status === 'rejected') {
content = 'This comment has been rejected';
}
return <li key={comment.id}>{content}</li>
});
return <ul>
{renderedComments}
</ul>;
}
export default CommentList;

View File

@@ -0,0 +1,26 @@
import React, { useState } from 'react';
import axios from 'axios';
const PostCreate = () => {
const [title, setTitle] = useState('');
const onSubmit = async (e) => {
e.preventDefault();
await axios.post('http://localhost:4000/posts', { title });
setTitle('');
};
return <div>
<form onSubmit={onSubmit}>
<div className="form-group">
<label>Title</label>
<input className="form-control" onChange={e => setTitle(e.target.value)} value={title}/>
</div>
<button className="btn btn-primary">Submit</button>
</form>
</div>;
}
export default PostCreate;

View File

@@ -0,0 +1,36 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import CommentCreate from './CommentCreate';
import CommentList from './CommentList';
const PostList = () => {
const [posts, setPosts] = useState({});
const fetchPosts = async () => {
try {
const res = await axios.get('http://localhost:4002/posts');
setPosts(res.data);
} catch (error) {
console.error(error);
}
};
useEffect(() => { fetchPosts(); }, []);
const renderedPosts = Object.values(posts).map(post => {
return <div className="card" style={{ width: '30%', marginBottom: '20px'}} key={post.id}>
<div className="card-body">
<h3>{post.title}</h3>
<CommentList comments={post.comments}/>
<CommentCreate postID={post.id}/>
</div>
</div>
});
return <div className="d-flex flex-row flex-wrap justify-content-between">
{renderedPosts}
</div>;
}
export default PostList;

7
blog/client/src/index.js Normal file
View File

@@ -0,0 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<App/>, document.getElementById('root')
);