diff --git a/apps/portal/prisma/migrations/20221108061935_add_comment_deletion/migration.sql b/apps/portal/prisma/migrations/20221108061935_add_comment_deletion/migration.sql new file mode 100644 index 00000000..bb64e690 --- /dev/null +++ b/apps/portal/prisma/migrations/20221108061935_add_comment_deletion/migration.sql @@ -0,0 +1,5 @@ +-- DropForeignKey +ALTER TABLE "ResumesComment" DROP CONSTRAINT "ResumesComment_parentId_fkey"; + +-- AddForeignKey +ALTER TABLE "ResumesComment" ADD CONSTRAINT "ResumesComment_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "ResumesComment"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/apps/portal/prisma/schema.prisma b/apps/portal/prisma/schema.prisma index 04493fa9..4a530ac4 100644 --- a/apps/portal/prisma/schema.prisma +++ b/apps/portal/prisma/schema.prisma @@ -187,7 +187,7 @@ model ResumesComment { resume ResumesResume @relation(fields: [resumeId], references: [id], onDelete: Cascade) votes ResumesCommentVote[] user User @relation(fields: [userId], references: [id], onDelete: Cascade) - parent ResumesComment? @relation("parentComment", fields: [parentId], references: [id]) + parent ResumesComment? @relation("parentComment", fields: [parentId], references: [id], onDelete: Cascade) children ResumesComment[] @relation("parentComment") } diff --git a/apps/portal/src/components/resumes/comments/ResumeCommentListItem.tsx b/apps/portal/src/components/resumes/comments/ResumeCommentListItem.tsx index a87139a8..b75a6160 100644 --- a/apps/portal/src/components/resumes/comments/ResumeCommentListItem.tsx +++ b/apps/portal/src/components/resumes/comments/ResumeCommentListItem.tsx @@ -120,7 +120,7 @@ export default function ResumeCommentListItem({ )} - {isCommentOwner && !isDeletingComment && ( + {isCommentOwner && ( diff --git a/apps/portal/src/components/resumes/comments/comment/ResumeCommentDeleteForm.tsx b/apps/portal/src/components/resumes/comments/comment/ResumeCommentDeleteForm.tsx index ba60eda9..25f6444e 100644 --- a/apps/portal/src/components/resumes/comments/comment/ResumeCommentDeleteForm.tsx +++ b/apps/portal/src/components/resumes/comments/comment/ResumeCommentDeleteForm.tsx @@ -1,15 +1,49 @@ import { Button, Dialog } from '@tih/ui'; + +import { useGoogleAnalytics } from '~/components/global/GoogleAnalytics'; + +import { trpc } from '~/utils/trpc'; type ResumeCommentDeleteFormProps = Readonly<{ + id: string; isDeletingComment: boolean; setIsDeletingComment: (value: boolean) => void; }>; export default function ResumeCommentDeleteForm({ + id, isDeletingComment, setIsDeletingComment, }: ResumeCommentDeleteFormProps) { - const onDelete = () => { - setIsDeletingComment(false); + const { event: gaEvent } = useGoogleAnalytics(); + + const trpcContext = trpc.useContext(); + const commentDeleteMutation = trpc.useMutation( + 'resumes.comments.user.delete', + { + onSuccess: () => { + // Comments updated, invalidate query to trigger refetch + trpcContext.invalidateQueries(['resumes.comments.list']); + }, + }, + ); + + const onDelete = async () => { + return commentDeleteMutation.mutate( + { + id, + }, + { + onSuccess: () => { + setIsDeletingComment(false); + + gaEvent({ + action: 'resumes.comment_delete', + category: 'engagement', + label: 'Delete comment', + }); + }, + }, + ); }; const onCancel = () => { @@ -21,7 +55,9 @@ export default function ResumeCommentDeleteForm({ isShown={isDeletingComment} primaryButton={ setIsDeletingComment(false)}> - Note that this is irreversible! + + Note that deleting this comment will delete all its replies as well. + This action is also irreversible! Please check before confirming! + ); } diff --git a/apps/portal/src/server/router/resumes/resumes-comments-user-router.ts b/apps/portal/src/server/router/resumes/resumes-comments-user-router.ts index e33a399b..10036b74 100644 --- a/apps/portal/src/server/router/resumes/resumes-comments-user-router.ts +++ b/apps/portal/src/server/router/resumes/resumes-comments-user-router.ts @@ -99,4 +99,16 @@ export const resumesCommentsUserRouter = createProtectedRouter() }, }); }, + }) + .mutation('delete', { + input: z.object({ id: z.string() }), + async resolve({ ctx, input }) { + const { id } = input; + + return await ctx.prisma.resumesComment.delete({ + where: { + id, + }, + }); + }, });