Skip to content

Commit

Permalink
Merge pull request #21 from L-Steinmacher/refactor
Browse files Browse the repository at this point in the history
refactor: userController hook to abstract and clean up CommentLayout
  • Loading branch information
L-Steinmacher authored Sep 21, 2023
2 parents 868896d + ddfac58 commit 3c00713
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 217 deletions.
86 changes: 15 additions & 71 deletions src/components/commentLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,28 @@
import { signIn, useSession } from 'next-auth/react';
import { type RefObject, useRef, useState, useEffect } from 'react';
import { signIn } from 'next-auth/react';
import ReCAPTCHA from 'react-google-recaptcha';

import { api } from '~/utils/api';
import { type Comment } from '~/interfaces/comments';

import { typedBoolean } from '~/utils/miscUtils';
import CommentCard from './commentCard';
import useController from '~/hooks/useController';

const RECAPTCHA_SITE_KEY = process.env.NEXT_PUBLIC_RECAPTCHA_KEY;
const isDev = process.env.NODE_ENV === 'development';

export function CommentLayout({ slug }: { slug: string }) {
const { data: commentsData } = api.comments.getCommentsForPost.useQuery({
slug,
});

const [submitting, setSubmitting] = useState<boolean>(false);
const [token, setToken] = useState<string | null>('');
const [comment, setComment] = useState<string>('');
const [allComments, setAllComments] = useState<Comment[]>(
commentsData || [],
);
const [errors, setErrors] = useState<string[]>([]);
const [gotime, setGotime] = useState<boolean>(false);

const { data: sessionData } = useSession();

const commentContainerRef: RefObject<HTMLDivElement> = useRef(null);
const userIsLoggedIn = !!sessionData;

const utils = api.useContext();
// const createCommentMutation = api.comments.createComment.useMutation();

useEffect(() => {
if (commentsData) {
setAllComments(commentsData);
}
}, [commentsData]);

const addComment = api.comments.createComment.useMutation({
onSuccess: async () => {
await utils.comments.getCommentsForPost.refetch({ slug });
const lastComment = commentContainerRef.current
?.lastElementChild as HTMLElement | null;
if (lastComment) {
lastComment.scrollIntoView({ behavior: 'smooth' });
}
},
onError: error => {
console.error('Error adding comment:', error);
setErrors(prevErrors => [...prevErrors, error.message]);
},
onSettled: () => {
setSubmitting(false);
setComment('');
setGotime(false);
},
});

const submitComment = () => {
setErrors([]);

addComment.mutate({
content: comment,
postSlug: slug,
token: token || '',
});
};
const {
submitting,
setSubmitting,
setToken,
comment,
setComment,
allComments,
errors,
setGotime,
commentContainerRef,
userIsLoggedIn,

// First we wait for the recaptcha token to be set, only then will the boolean gotime to be true
useEffect(() => {
console.log('useEffect', comment);
if (!gotime) {
return;
}
submitComment();
// linkter wants submitComment in dep array but that causes issues.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [gotime]);
} = useController({ slug })

return (
<div>
Expand Down Expand Up @@ -133,7 +78,6 @@ export function CommentLayout({ slug }: { slug: string }) {
tabIndex={2}
aria-label="Submit comment button"
onClick={e => {
console.log('clicked', gotime);
e.preventDefault();
setGotime(true);
}}
Expand Down
89 changes: 89 additions & 0 deletions src/hooks/useController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { useSession } from "next-auth/react";
import { type RefObject, useEffect, useRef, useState } from "react";
import { type Comment } from "~/interfaces/comments";
import { api } from "~/utils/api";

export default function useController({ slug }: { slug: string}) {
const { data: commentsData } = api.comments.getCommentsForPost.useQuery({
slug,
});

const [submitting, setSubmitting] = useState<boolean>(false);
const [token, setToken] = useState<string | null>('');
const [comment, setComment] = useState<string>('');
const [allComments, setAllComments] = useState<Comment[]>(
commentsData || [],
);
const [errors, setErrors] = useState<string[]>([]);
const [gotime, setGotime] = useState<boolean>(false);

const { data: sessionData } = useSession();

const commentContainerRef: RefObject<HTMLDivElement> = useRef(null);
const userIsLoggedIn = !!sessionData;

const utils = api.useContext();
// const createCommentMutation = api.comments.createComment.useMutation();

useEffect(() => {
if (commentsData) {
setAllComments(commentsData);
}
}, [commentsData]);

const addComment = api.comments.createComment.useMutation({
onSuccess: async () => {
await utils.comments.getCommentsForPost.refetch({ slug });
const lastComment = commentContainerRef.current
?.lastElementChild as HTMLElement | null;
if (lastComment) {
lastComment.scrollIntoView({ behavior: 'smooth' });
}
},
onError: error => {
console.error('Error adding comment:', error);
setErrors(prevErrors => [...prevErrors, error.message]);
},
onSettled: () => {
setSubmitting(false);
setComment('');
setGotime(false);
},
});

const submitComment = () => {
setErrors([]);

addComment.mutate({
content: comment,
postSlug: slug,
token: token || '',
});
};

// First we wait for the recaptcha token to be set, only then will the boolean gotime to be true
useEffect(() => {
if (!gotime) {
return;
}
submitComment();
// linkter wants submitComment in dep array but that causes issues.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [gotime]);

return {
addComment,
allComments,
comment,
commentContainerRef,
errors,
gotime,
setComment,
setGotime,
setToken,
setSubmitting,
submitting,
token,
userIsLoggedIn,
};
}
146 changes: 0 additions & 146 deletions src/hooks/useSubmitComment.ts

This file was deleted.

0 comments on commit 3c00713

Please sign in to comment.