Skip to content

Commit caece4c

Browse files
committed
Add Create Post component
1 parent 95bc465 commit caece4c

File tree

7 files changed

+124
-30
lines changed

7 files changed

+124
-30
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ define('JWT_AUTH_CORS_ENABLE', true);
4747

4848
iii. Now you can make a request to `/wp-json/jwt-auth/v1/token` REST API provided by the plugin. You need to pass
4949
username and password and it returns a user object and token . You can save the token in localstorage and send it in the headers
50-
of your protected route requests ( e.g. `/wp-json/wp/v2/posts` )
50+
of your protected route requests ( e.g. [Create Post](https://developer.wordpress.org/rest-api/reference/posts/#create-a-post) `/wp-json/wp/v2/posts` )
5151

5252
iiv. So whenever you send a request to WordPress REST API for your protected routes, you send the token received in the headers of
5353
your request

src/components/CreatePost.js

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import React from 'react';
2+
import axios from 'axios';
3+
import Loader from '../loader.gif';
4+
5+
class CreatePost extends React.Component {
6+
7+
constructor( props ) {
8+
super( props );
9+
10+
this.state = {
11+
title: '',
12+
content: '',
13+
userID: '',
14+
token: '',
15+
postCreated: false,
16+
message: '',
17+
loading: false
18+
}
19+
}
20+
21+
createMarkup = ( data ) => ({
22+
__html: data
23+
});
24+
25+
handleInputChange = ( event ) => {
26+
this.setState({ [event.target.name]: event.target.value });
27+
};
28+
29+
handleFormSubmit = ( event ) => {
30+
event.preventDefault();
31+
this.setState( { loading: true } );
32+
33+
const formData = {
34+
author: this.state.userID,
35+
title: this.state.title,
36+
content: this.state.content,
37+
status: 'publish'
38+
};
39+
40+
const wordPressSiteUrl = 'http://localhost:8888/wordpress';
41+
const authToken = localStorage.getItem( 'token' );
42+
43+
/**
44+
* Make a post request to node server route '/create-post',
45+
* to create a new post on WordPress
46+
*/
47+
axios.post( `${wordPressSiteUrl}/wp-json/wp/v2/posts`, formData, {
48+
headers: {
49+
'Content-Type': 'application/json',
50+
'Authorization': `Bearer ${authToken}`
51+
}
52+
} )
53+
.then( res => {
54+
this.setState( {
55+
loading: false,
56+
postCreated: !! res.data.id,
57+
message: res.data.id ? 'New Post Created' : ''
58+
} );
59+
} )
60+
.catch( err => {
61+
this.setState( { loading: false, message: err.response.data.message } );
62+
} );
63+
};
64+
65+
componentDidMount() {
66+
const userID = localStorage.getItem( 'userID' );
67+
const token = localStorage.getItem( 'token' );
68+
this.setState( { userID, token } );
69+
}
70+
71+
render() {
72+
73+
const { loading, message, postCreated } = this.state;
74+
75+
return(
76+
<form onSubmit={ this.handleFormSubmit } className="mt-5" style={{maxWidth: '800px'}}>
77+
<fieldset>
78+
<legend className="mb-4">Create Post</legend>
79+
80+
{ message && <div className={ `alert ${ postCreated ? 'alert-success' : 'alert-danger' }` } dangerouslySetInnerHTML={ this.createMarkup( message ) }/> }
81+
82+
<div className="form-group">
83+
<label htmlFor="title">Title</label>
84+
85+
<input type="text" name="title" onChange={ this.handleInputChange } className="form-control" id="title"/>
86+
87+
</div>
88+
<div className="form-group">
89+
<label htmlFor="content">Content</label>
90+
<textarea name="content" className="form-control" onChange={ this.handleInputChange } id="content" rows="3"/>
91+
</div>
92+
93+
<button type="submit" className="btn btn-secondary">Submit</button>
94+
</fieldset>
95+
{ loading && <img className="loader" src={Loader} alt="Loader"/> }
96+
</form>
97+
)
98+
}
99+
}
100+
export default CreatePost;

src/components/Dashboard.js

+2-21
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,13 @@
11
import React from 'react';
22
import Navbar from "./Navbar";
3+
import CreatePost from "./CreatePost";
34

45
class Dashboard extends React.Component {
56

67
constructor( props ) {
78
super( props );
89
}
910

10-
componentDidMount() {
11-
const siteUrl = 'http://localhost:8888/wordpress';
12-
fetch( `${siteUrl}/wp-json/wp/v2/posts`, {
13-
method: 'POST',
14-
headers: {
15-
'Accept': 'application/json',
16-
'Content-Type': 'application/json',
17-
'Authorization': `Bearer ${localStorage.getItem('token')}`
18-
},
19-
body: JSON.stringify( { title: 'Hello', content: 'content' } )
20-
} )
21-
.then( ( res ) => {
22-
res.json()
23-
.then( ( data ) => {
24-
console.warn( 'came', data );
25-
26-
} )
27-
} )
28-
.catch( err => console.warn( err ) );
29-
};
30-
3111

3212
render() {
3313
console.warn( localStorage.getItem( 'token' ) );
@@ -36,6 +16,7 @@ class Dashboard extends React.Component {
3616
<Navbar/>
3717
<div className="jumbotron">
3818
<h4>Welcome {this.props.userName && this.props.userName }!!</h4>
19+
<CreatePost/>
3920
</div>
4021
</React.Fragment>
4122
)

src/components/Login.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import Navbar from "./Navbar";
33
import { Redirect } from "@reach/router";
4+
import Loader from "../loader.gif";
45

56
class Login extends React.Component {
67

@@ -109,7 +110,7 @@ class Login extends React.Component {
109110
</label>
110111
<br/>
111112
<button className="btn btn-primary mb-3" type="submit">Login</button>
112-
<p>{ loading && 'Processing...' }</p>
113+
{ loading && <img className="loader" src={Loader} alt="Loader"/> }
113114
</form>
114115
</div>
115116
</React.Fragment>

src/loader.gif

113 KB
Loading

src/style.css

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.loader {
2+
position: absolute;
3+
left: 0;
4+
right: 0;
5+
top: 0;
6+
bottom: 0;
7+
margin: auto;
8+
width: 100px;
9+
}
10+
11+
.posts-container {
12+
margin-left: 16px;
13+
}
14+
15+
.post-content img{
16+
width: 100%;
17+
}

webpack.config.js

+2-7
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,9 @@ module.exports = {
2222
use: ['style-loader', 'css-loader'],
2323
},
2424
{
25-
test: /\.(png|jp?g|svg)$/,
25+
test: /\.(png|jp?g|svg|gif)$/,
2626
use: [{
27-
loader: "file-loader",
28-
options: {
29-
name: '[name].[ext]',
30-
outputPath: 'images/',
31-
publicPath: 'images/'
32-
}
27+
loader: "file-loader"
3328
}]
3429
}
3530
]

0 commit comments

Comments
 (0)