mirror of
https://github.com/r-freeman/portfolio.git
synced 2025-04-19 12:24:46 +00:00
Extract providers for comment component
All checks were successful
Build And Publish / BuildAndPublish (push) Successful in 3m16s
All checks were successful
Build And Publish / BuildAndPublish (push) Successful in 3m16s
This commit is contained in:
parent
45141726dd
commit
8cc62e5b78
24
app/context/CommentFormProvider.tsx
Normal file
24
app/context/CommentFormProvider.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import {createContext, ReactNode, RefObject, useContext, useRef} from 'react'
|
||||
|
||||
type CommentFormContext = {
|
||||
commentFormRef?: RefObject<HTMLTextAreaElement | null>
|
||||
focusCommentForm: () => void
|
||||
}
|
||||
|
||||
export const CommentFormContext = createContext<CommentFormContext | null>(null)
|
||||
|
||||
export const useCommentFormContext = () => useContext(CommentFormContext)
|
||||
|
||||
export default function CommentFormProvider({children}: { children: ReactNode }) {
|
||||
const commentFormRef = useRef<HTMLTextAreaElement>(null)
|
||||
|
||||
const focusCommentForm = () => {
|
||||
commentFormRef.current?.focus()
|
||||
}
|
||||
|
||||
return (
|
||||
<CommentFormContext.Provider value={{commentFormRef, focusCommentForm}}>
|
||||
{children}
|
||||
</CommentFormContext.Provider>
|
||||
)
|
||||
}
|
19
app/context/ReplyProvider.tsx
Normal file
19
app/context/ReplyProvider.tsx
Normal file
@ -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<ReplyContext | null>(null)
|
||||
|
||||
export const useReplyContext = () => useContext(ReplyContext)
|
||||
|
||||
export default function ReplyProvider({children}: { children: ReactNode }) {
|
||||
const [replyTo, setReplyTo] = useState<Comment | null>(null)
|
||||
|
||||
return (
|
||||
<ReplyContext.Provider value={{replyTo, setReplyTo}}>{children}</ReplyContext.Provider>
|
||||
)
|
||||
}
|
@ -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
|
||||
|
@ -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<HTMLButtonElement>) => {
|
||||
@ -132,18 +123,13 @@ const initialState: InitialState = {
|
||||
message: ''
|
||||
}
|
||||
|
||||
const CommentFormContext = createContext<{ focusCommentForm: () => void } | null>(null)
|
||||
|
||||
type CommentsFormsProps = {
|
||||
slug: string
|
||||
commentFormRef?: RefObject<HTMLTextAreaElement | null>
|
||||
}
|
||||
|
||||
Comments.Form = function Form({slug, commentFormRef}: CommentsFormsProps) {
|
||||
Comments.Form = function Form({slug}: { slug: string }) {
|
||||
const [parentId, setParentId] = useState<string | number | null>('')
|
||||
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<ReplyContextType | null>(null)
|
||||
|
||||
type CommentsProps = {
|
||||
slug: string
|
||||
comments?: Comment[]
|
||||
comments?: any
|
||||
}
|
||||
|
||||
export default function Comments({slug, comments}: CommentsProps) {
|
||||
const [replyTo, setReplyTo] = useState<Comment | null>(null)
|
||||
const commentFormRef = useRef<HTMLTextAreaElement>(null)
|
||||
|
||||
const focusCommentForm = () => {
|
||||
commentFormRef.current?.focus()
|
||||
}
|
||||
|
||||
return (
|
||||
<ReplyContext.Provider value={{replyTo, setReplyTo}}>
|
||||
<CommentFormContext.Provider value={{focusCommentForm}}>
|
||||
<ReplyProvider>
|
||||
<CommentFormProvider>
|
||||
<div className="mt-24">
|
||||
{comments &&
|
||||
<Comments.List comments={comments}/>
|
||||
}
|
||||
<Comments.Form slug={slug} commentFormRef={commentFormRef}/>
|
||||
<Comments.Form slug={slug}/>
|
||||
</div>
|
||||
</CommentFormContext.Provider>
|
||||
</ReplyContext.Provider>
|
||||
</CommentFormProvider>
|
||||
</ReplyProvider>
|
||||
)
|
||||
}
|
@ -22,4 +22,17 @@ export type Repo = {
|
||||
name: string
|
||||
color: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type Comment = {
|
||||
id: number
|
||||
content: string
|
||||
created_at: string
|
||||
parent_id: number | null
|
||||
user: {
|
||||
id: number
|
||||
name: string
|
||||
image: string
|
||||
}
|
||||
replies?: Comment[]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user