Skip to content

Commit

Permalink
feat: add new post form
Browse files Browse the repository at this point in the history
Users can add a post to a post list of selected category.
When users navigate to different category, category field is auto-updated based on path

States of all input fields are component state.

`PostForm` receives:
- `categories` props to display category selection list
- `category` props to set initial state for `category`. This state is updated every time there is a modified props

Generating new post id with `UUID` package
  • Loading branch information
iamthuypham committed Oct 16, 2017
1 parent 55362a4 commit 0230af7
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 16 deletions.
16 changes: 9 additions & 7 deletions frontend/node_modules/uuid/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0"
"redux-thunk": "^2.2.0",
"uuid": "^3.1.0"
},
"devDependencies": {
"react-scripts": "1.0.13"
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class App extends Component {
)}
</header>
<main>
<Route exact path='/:category' component={PostsByCategory}/>
<Route exact path='/:category' render={(props)=><PostsByCategory categories={categories} routing={props}/>}/>
<Route exact path='/:category/:post_id' component={PostWithComments}/>
</main>
</div>
Expand Down
77 changes: 77 additions & 0 deletions frontend/src/post/PostForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
const uuidv4 = require('uuid/v4');

class PostForm extends Component {
constructor(props) {
super(props);
this.state = ({
openForm: false,
title: '',
body: '',
author: '',
category: this.props.currentCategory
})
this.handleForm = this.handleForm.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleForm() {
this.setState({openForm: !this.state.openForm})
}
handleSubmit(e) {
e.preventDefault();
const newPost = {
id: uuidv4(),
title: this.state.title,
category: this.state.category,
body: this.state.body,
author: this.state.author,
timestamp: Date.now(),
}
console.log(newPost)
}
componentWillReceiveProps(nextProps) {
if (this.props.category !== nextProps.category) {
this.setState({
openForm: false,
title: '',
body: '',
author: '',
category: nextProps.category
})
}
}
render() {
const { categories } = this.props.categories
const { title, author, body, category } = this.state
return (
<div>
<button onClick={this.handleForm}>New Post</button>
{this.state.openForm &&
<form onSubmit={this.handleSubmit}>
<input type="text" name="title" placeholder="New Title" value={title} onChange={(e) => this.setState({ title: e.target.value })} required/>
<label>
Current category:
<select value={this.state.category} onChange={(e) => this.setState({ category: e.target.value })}>
<option value=''>Select a category</option>
{categories && categories.map((category) =>
<option key={category.name} value={`${category.name}`}>{category.name}</option>
)}
</select>
</label>
<input type="text" name="body" placeholder="New Content" value={body} onChange={(e) => this.setState({ body: e.target.value })} required/>
<input type="text" name="author" placeholder="Your Name" value={author} onChange={(e) => this.setState({ author: e.target.value })} required/>
<input type='submit' value='Submit'/>
</form>
}
</div>
)
}
}

PostForm.PropTypes = {
categories: PropTypes.array.isRequired
}

export default PostForm
13 changes: 8 additions & 5 deletions frontend/src/post/PostsByCategory.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,30 @@ import { Route, Link } from 'react-router-dom';

import PostItem from './PostItem';
import { fetchPostsByCategory } from './action';
import PostForm from './PostForm';

class PostsByCategory extends Component {
constructor(props) {
super(props);
}
componentWillReceiveProps(nextProps) {
if (this.props.location.pathname !== nextProps.location.pathname) {
const nextCategoryNameParam = nextProps.match.params.category
if (this.props.routing.match.params.category !== nextProps.routing.match.params.category) {
const nextCategoryNameParam = nextProps.routing.match.params.category
nextProps.dispatchFetchPostsByCategories(nextCategoryNameParam)
}
}
componentDidMount() {
const categoryNameParam = this.props.match.params.category
const categoryNameParam = this.props.routing.match.params.category
this.props.dispatchFetchPostsByCategories(categoryNameParam)
}

render() {
const { isFetching, posts, location } = this.props
const categoryNameParam = this.props.match.params.category
const { isFetching, posts, location, categories } = this.props
const categoryNameParam = this.props.routing.match.params.category
console.log(this.props)
return (
<div>
<PostForm category={categoryNameParam} categories={categories}/>
{!isFetching && posts.map((post) =>
<PostItem key={post.id} post={post} categoryOfThisPost={categoryNameParam}/>
)}
Expand Down

0 comments on commit 0230af7

Please sign in to comment.