diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index c388c72a..7ae65358 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -15,9 +15,11 @@ class CommentsController < ApplicationController comment = Comment.new(comment_params) if comment.save - render json: comment, status: :no_content + render json: comment, status: :created else - render json: I18n.t('errors.unauthorized'), status: :unauthorized + render json: { + error: I18n.t('errors.comment.create', message: comment.errors.full_messages) + }, status: :unprocessable_entity end end @@ -26,7 +28,7 @@ class CommentsController < ApplicationController def comment_params params .require(:comment) - .permit(:body) + .permit(:body, :parent_id) .merge( user_id: current_user.id, post_id: params[:post_id] diff --git a/app/javascript/actions/submitComment.ts b/app/javascript/actions/submitComment.ts new file mode 100644 index 00000000..b7cd5c82 --- /dev/null +++ b/app/javascript/actions/submitComment.ts @@ -0,0 +1,82 @@ +import { Action } from 'redux'; +import { ThunkAction } from 'redux-thunk'; +import { State } from '../reducers/rootReducer'; + +import ICommentJSON from '../interfaces/json/IComment'; + +export const COMMENT_SUBMIT_START = 'COMMENT_SUBMIT_START'; +interface CommentSubmitStartAction { + type: typeof COMMENT_SUBMIT_START; + parentId: number; +} + +export const COMMENT_SUBMIT_SUCCESS = 'COMMENT_SUBMIT_SUCCESS'; +interface CommentSubmitSuccessAction { + type: typeof COMMENT_SUBMIT_SUCCESS; + comment: ICommentJSON; +} + +export const COMMENT_SUBMIT_FAILURE = 'COMMENT_SUBMIT_FAILURE'; +interface CommentSubmitFailureAction { + type: typeof COMMENT_SUBMIT_FAILURE; + parentId: number; + error: string; +} + +export type CommentSubmitActionTypes = + CommentSubmitStartAction | + CommentSubmitSuccessAction | + CommentSubmitFailureAction; + +const commentSubmitStart = (parentId): CommentSubmitStartAction => ({ + type: COMMENT_SUBMIT_START, + parentId, +}); + +const commentSubmitSuccess = ( + commentJSON: ICommentJSON, +): CommentSubmitSuccessAction => ({ + type: COMMENT_SUBMIT_SUCCESS, + comment: commentJSON, +}); + +const commentSubmitFailure = (parentId, error): CommentSubmitFailureAction => ({ + type: COMMENT_SUBMIT_FAILURE, + parentId, + error, +}); + +export const submitComment = ( + postId, + body, + parentId, + authenticityToken, +): ThunkAction> => async (dispatch) => { + dispatch(commentSubmitStart(parentId)); + + try { + const res = await fetch(`/posts/${postId}/comments`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + 'X-CSRF-Token': authenticityToken, + }, + body: JSON.stringify({ + comment: { + body, + parent_id: parentId, + }, + }), + }); + const json = await res.json(); + + if (res.status === 201) { + dispatch(commentSubmitSuccess(json)); + } else { + dispatch(commentSubmitFailure(parentId, json.error)); + } + } catch (e) { + dispatch(commentSubmitFailure(parentId, e)); + } +} \ No newline at end of file diff --git a/app/javascript/components/Comments/Comment.tsx b/app/javascript/components/Comments/Comment.tsx index 76ec5ac9..4f05be55 100644 --- a/app/javascript/components/Comments/Comment.tsx +++ b/app/javascript/components/Comments/Comment.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { FormEvent } from 'react'; +import NewComment from './NewComment'; import { MutedText } from '../shared/CustomTexts'; import { CommentRepliesState } from '../../reducers/commentRepliesReducer'; @@ -16,6 +17,7 @@ interface Props { reply: CommentRepliesState; handleToggleCommentReply(): void; handleCommentReplyBodyChange(e: FormEvent): void; + handleSubmitComment(body: string, parentId: number): void; } const Comment = ({ @@ -29,6 +31,7 @@ const Comment = ({ reply, handleToggleCommentReply, handleCommentReplyBodyChange, + handleSubmitComment, }: Props) => (
@@ -41,9 +44,11 @@ const Comment = ({
{ reply.isOpen ? -