I finally implemented the review tab for article approval and rejection and did some other stuff. This time with a clean PR - my GIT skills magically improved and i shall work with a fresh branch from now on.
https://github.com/knacksteem/knacksteem.org
https://github.com/knacksteem/knacksteem.org/pull/9
"Do you have any talent? If yes! then KnackSteem is for you."
"Rewards people with talents, it can be any talent, anything you know how to do best is highly welcome on the platform."
The main work of this PR was about creating a new route/page for moderation. The review tab lists all pending articles and there are buttons for approving and rejecting articles. Here´s the full list of changes, more or less from the commit history:
This is how it looks like now, with the new review tab and the fancy buttons for approval/rejection:
We may need to change the position later, if we decide to add the tags to the articles overview. Right now, they are only visible on the detail page anyway. But that´s just a few lines of code to copy over if needed - the technical term would be "easy peasy".
FYI: Right now, the Review link is visible for everyone for testing. Article approval with the API is only possible for mods though.
Some React components were missing PropTypes , they are basically there to tell other components what properties are required or used, and what datatype you need to provide. For example:
IconText.propTypes = {
type: PropTypes.string.isRequired,
text: PropTypes.string.isRequired
}
PropTypes was included in React earlier, but since some versions you have to install "prop-types" with npm and import it with import PropTypes from 'prop-types'.
One weird bug happened in the posting part. On Steemit, all the tags showed up correctly in the default view. When i tried to edit the article, only the category tag was correct and all the others were mangled - all characters showed up sorted alphabetically. There was an easy fix though, i just did not use the SteemConnect API correctly. You just have to send an Array, no magic involved:
await api.comment('', tags[0], store.user.username, newPermLink, title, body, {tags: tags});
(actions/articles.js)
In order to detect the user role for the visibility of some additional stuff like the review tab, i implemented the already existing backend API to get the data of a specific user. It gets stored as "userObject" in the user reducer of redux. If there is no user, the userObject will be an empty object:
//get user details from database, including the user role (supervisor, moderator, contributor)
let userData = await apiGet('/stats/users', {
username: response.user
});
dispatch({
type: types.USER_GET,
username: response.user,
userObject: (userData.data && userData.data.results) ? userData.data.results[0] : {},
userObjectSteemit: response,
accessToken: accessToken
});
(actions/user.js)
The old ArticleListItem component is used for the general article overview and the new view for pending articles. It just needed a small update to include buttons for moderation. If the status is pending, two buttons are visible for approval and rejection:
{(status === 'pending') &&
<div className="mod-functions">
<Button size="small" type="primary" onClick={onApproveClick}>Approve</Button>
<Button size="small" type="danger" onClick={onRejectClick}>Reject</Button>
</div>
}
(components/ArticleListItem/index.js)
Two new actions have been implemented for approval and rejection, this is what the approval action looks like. It includes an API request to the /moderation/moderate endpoint, the difference between the approval and rejection action is the parameter "approved". It´s still a good idea to create separate actions for them, those actions may have different error handling later:
/**
* approve article by mod
*/
export const approveArticle = (permlink) => {
return async (dispatch, getState) => {
const store = getState();
try {
//approve article with permalink and status
await apiPost('/moderation/moderate', {
permlink: permlink,
approved: true,
access_token: store.user.accessToken
});
} catch (error) {
console.log(error);
} finally {
//reload pending articles after approval
dispatch(getArticlesPending());
}
};
};
(actions/articles.js)
The component for the review tab is completely new, it loads the pending articles only and uses the existing articles reducer. There was no need to create a separate reducer array just for pending articles as you can only view one list anyway. Working with redux actions is great, you just have to dispatch your action somewhere in a component and the component updates itself if the redux reducer changes. Gobal state ftw:
componentDidMount() {
const {dispatch} = this.props;
dispatch(getArticlesPending());
//on scroll, load the next batch of articles
window.addEventListener('scroll', this.onScroll);
}
The whole code can be found on Github, feel free to contact me for any recommendations on it. I am always happy to improve.
My GitHub Account: https://github.com/ateufel