diff --git a/app/context/CommentFormProvider.tsx b/app/context/CommentFormProvider.tsx new file mode 100644 index 0000000..77ada15 --- /dev/null +++ b/app/context/CommentFormProvider.tsx @@ -0,0 +1,24 @@ +import {createContext, ReactNode, RefObject, useContext, useRef} from 'react' + +type CommentFormContext = { + commentFormRef?: RefObject + focusCommentForm: () => void +} + +export const CommentFormContext = createContext(null) + +export const useCommentFormContext = () => useContext(CommentFormContext) + +export default function CommentFormProvider({children}: { children: ReactNode }) { + const commentFormRef = useRef(null) + + const focusCommentForm = () => { + commentFormRef.current?.focus() + } + + return ( + + {children} + + ) +} \ No newline at end of file diff --git a/app/context/ReplyProvider.tsx b/app/context/ReplyProvider.tsx new file mode 100644 index 0000000..7a4b659 --- /dev/null +++ b/app/context/ReplyProvider.tsx @@ -0,0 +1,19 @@ +import {createContext, ReactNode, useContext, useState} from 'react' +import type {Comment} from '@/types' + +type ReplyContext = { + replyTo: Comment | null + setReplyTo: (replyTo: Comment | null) => void +} + +export const ReplyContext = createContext(null) + +export const useReplyContext = () => useContext(ReplyContext) + +export default function ReplyProvider({children}: { children: ReactNode }) { + const [replyTo, setReplyTo] = useState(null) + + return ( + {children} + ) +} \ No newline at end of file diff --git a/components/layouts/ArticleLayout.tsx b/components/layouts/ArticleLayout.tsx index 63c5c11..00f9d96 100644 --- a/components/layouts/ArticleLayout.tsx +++ b/components/layouts/ArticleLayout.tsx @@ -10,6 +10,8 @@ import {getAllArticles} from '@/lib/getAllArticles' import {getComments} from '@/lib/getComments' import {format} from 'date-fns' +import type {Comment} from '@/types' + type ArticleLayout = { title: string date: string diff --git a/components/ui/Comments.tsx b/components/ui/Comments.tsx index a2c156c..69ceadd 100644 --- a/components/ui/Comments.tsx +++ b/components/ui/Comments.tsx @@ -1,6 +1,6 @@ 'use client' -import React, {createContext, ReactNode, RefObject, useActionState, useContext, useEffect, useRef, useState} from 'react' +import React, {ReactNode, useActionState, useEffect, useState} from 'react' import {useSession} from 'next-auth/react' import Image from 'next/image' import clsx from 'clsx' @@ -9,27 +9,18 @@ import {Button} from '@/components/ui/Button' import {GitHubIcon} from '@/components/icons/SocialIcons' import {ArrowLeftIcon} from '@/components/icons/ArrowLeftIcon' import {getShortDurationFromNow} from '@/lib/dateFns' +import ReplyProvider, {useReplyContext} from '@/app/context/ReplyProvider' +import CommentFormProvider, {useCommentFormContext} from '@/app/context/CommentFormProvider' -type Comment = { - id: number - content: string - created_at: string - parent_id: number | null - user: { - id: number - name: string - image: string - } - replies?: Comment[] -} +import type {Comment} from '@/types' type ReplyButton = { comment: Comment } Comments.ReplyButton = function ReplyButton({comment}: ReplyButton) { - const replyContext = useContext(ReplyContext) - const commentFormContext = useContext(CommentFormContext) + const replyContext = useReplyContext() + const commentFormContext = useCommentFormContext() const {data: session} = useSession() const handleReplyButton = async (e: React.MouseEvent) => { @@ -132,18 +123,13 @@ const initialState: InitialState = { message: '' } -const CommentFormContext = createContext<{ focusCommentForm: () => void } | null>(null) - -type CommentsFormsProps = { - slug: string - commentFormRef?: RefObject -} - -Comments.Form = function Form({slug, commentFormRef}: CommentsFormsProps) { +Comments.Form = function Form({slug}: { slug: string }) { const [parentId, setParentId] = useState('') const [state, formAction, pending] = useActionState(addComment, initialState) const {data: session} = useSession() - const replyContext = useContext(ReplyContext) + const replyContext = useReplyContext() + const commentFormContext = useCommentFormContext() + const commentFormRef = commentFormContext?.commentFormRef useEffect(() => { if (replyContext?.replyTo?.parent_id !== null) { @@ -214,37 +200,22 @@ Comments.Form = function Form({slug, commentFormRef}: CommentsFormsProps) { ) } - -type ReplyContextType = { - replyTo: Comment | null - setReplyTo: (replyTo: Comment | null) => void -} - -const ReplyContext = createContext(null) - type CommentsProps = { slug: string - comments?: Comment[] + comments?: any } export default function Comments({slug, comments}: CommentsProps) { - const [replyTo, setReplyTo] = useState(null) - const commentFormRef = useRef(null) - - const focusCommentForm = () => { - commentFormRef.current?.focus() - } - return ( - - + +
{comments && } - +
-
-
+ + ) } \ No newline at end of file diff --git a/types/index.ts b/types/index.ts index a7d74ce..088cf8c 100644 --- a/types/index.ts +++ b/types/index.ts @@ -22,4 +22,17 @@ export type Repo = { name: string color: string } -} \ No newline at end of file +} + +export type Comment = { + id: number + content: string + created_at: string + parent_id: number | null + user: { + id: number + name: string + image: string + } + replies?: Comment[] +}