Skip to content

Instantly share code, notes, and snippets.

@zrod
Created August 18, 2017 02:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zrod/f5d9efd000c94774dafa10c90999e6aa to your computer and use it in GitHub Desktop.
Save zrod/f5d9efd000c94774dafa10c90999e6aa to your computer and use it in GitHub Desktop.
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import moment from 'moment';
import { Button, Comment, Form, Header, Message, Divider } from 'semantic-ui-react';
import { sprintf } from 'sprintf-js';
import * as validationRules from '../../../resources/ValidationRules';
import I18n from '../../../helpers/I18n';
moment.locale('pt_BR');
const i18n = new I18n(true);
export class CommentsBlock extends React.Component
{
static propTypes = {
auth: PropTypes.object.isRequired,
dispatch: PropTypes.func,
comments: PropTypes.array.isRequired,
resource: PropTypes.object.isRequired,
resourceActionNamespace: PropTypes.string.isRequired,
};
constructor(props) {
super(props);
this.state = {
body: '',
parentId: null,
error: '',
saving: false
};
this.updateState = this.updateState.bind(this);
this.submitComment = this.submitComment.bind(this);
this.displayReplyForm = this.displayReplyForm.bind(this);
}
generateCommentsBlock(comments) {
return (
<div>
{ comments.map(function(comment) {
let replies;
let replyButton = (
<Comment.Actions>
<a onClick={this.displayReplyForm}>{i18n.common.comments.reply}</a>
</Comment.Actions>
);
if (comment.replies && comment.replies.length > 0) {
const repliesBody = this.generateCommentsBlock(comment.replies);
replies = (<Comment.Group size="large">{repliesBody}</Comment.Group>);
}
return (
<Comment key={comment.id}>
<Comment.Avatar as="a" src={comment.author.avatar} />
<Comment.Content>
<Comment.Author as="a">{comment.author.name}</Comment.Author>
<Comment.Metadata>
<span>{moment(comment.created_at).calendar()}</span>
</Comment.Metadata>
<Comment.Text>{comment.comment}</Comment.Text>
{this.props.auth.authenticated && replyButton}
</Comment.Content>
{replies}
</Comment>
);
}, this) }
</div>
);
}
displayReplyForm() {
// stuck here now
}
updateState(event, { value }) {
this.setState({ body: value });
}
isValid() {
const body = this.state.body.replace(/\r?\n|\r/g, '');
let error;
let isValid = true;
if (!body) {
error = i18n.validation.comment.blank;
isValid = false;
}
if (body.length < validationRules.COMMENT_MIN_LENGTH) {
error = sprintf(i18n.validation.comment.short, [validationRules.COMMENT_MIN_LENGTH]);
isValid = false;
}
if (body.length >= validationRules.COMMENT_MAX_LENGTH) {
error = sprintf(i18n.validation.comment.long, [validationRules.COMMENT_MAX_LENGTH]);
isValid = false;
}
this.setState({error: error});
return isValid;
}
submitComment(event) {
event.preventDefault();
if (!this.isValid()) {
return;
}
this.setState({saving: true});
// Dispatch action
const actionType = this.props.resourceActionNamespace + '_SUBMIT_COMMENT';
const commentPayload = {
resourceId: this.props.resource.id,
body: this.state.body,
parent: this.state.parentId
};
const action = { type: actionType, payload: commentPayload };
this.props.dispatch(action);
}
render() {
const comments = this.generateCommentsBlock(this.props.comments);
const newCommentBody = this.state.body;
const error = this.state.error;
let errorMessage = '';
let commentForm = (
<Message warning>
<Link to={i18n.route.auth.login}>
{i18n.common.comments.authenticate}
</Link>
</Message>
);
if (error.length > 0) {
errorMessage = (<Message negative>{error}</Message>);
}
if (this.props.auth.authenticated) {
commentForm = (
<Form reply onSubmit={this.submitComment}>
{errorMessage}
<Form.TextArea
name="body"
onChange={this.updateState}
value={newCommentBody}
/>
<Button content={i18n.common.comments.new} labelPosition="left" icon="edit" primary />
</Form>
);
}
return (
<div>
<Header as="h2" dividing>
{i18n.interface.comments}
</Header>
<Comment.Group threaded size="large">
{commentForm}
<Divider hidden />
{comments}
</Comment.Group>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
auth: {authenticated: true} //state.auth
};
};
export default connect(mapStateToProps)(CommentsBlock);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment