mirror of
https://github.com/r-freeman/portfolio.git
synced 2025-04-21 23:54:37 +00:00
Extract providers for comment component
All checks were successful
Build And Publish / BuildAndPublish (push) Successful in 3m13s
All checks were successful
Build And Publish / BuildAndPublish (push) Successful in 3m13s
This commit is contained in:
parent
45141726dd
commit
f2eecf06d3
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 {getComments} from '@/lib/getComments'
|
||||||
import {format} from 'date-fns'
|
import {format} from 'date-fns'
|
||||||
|
|
||||||
|
import type {Comment} from '@/types'
|
||||||
|
|
||||||
type ArticleLayout = {
|
type ArticleLayout = {
|
||||||
title: string
|
title: string
|
||||||
date: string
|
date: string
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'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 {useSession} from 'next-auth/react'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
@ -9,27 +9,18 @@ import {Button} from '@/components/ui/Button'
|
|||||||
import {GitHubIcon} from '@/components/icons/SocialIcons'
|
import {GitHubIcon} from '@/components/icons/SocialIcons'
|
||||||
import {ArrowLeftIcon} from '@/components/icons/ArrowLeftIcon'
|
import {ArrowLeftIcon} from '@/components/icons/ArrowLeftIcon'
|
||||||
import {getShortDurationFromNow} from '@/lib/dateFns'
|
import {getShortDurationFromNow} from '@/lib/dateFns'
|
||||||
|
import ReplyProvider, {useReplyContext} from '@/app/context/ReplyProvider'
|
||||||
|
import CommentFormProvider, {useCommentFormContext} from '@/app/context/CommentFormProvider'
|
||||||
|
|
||||||
type Comment = {
|
import type {Comment} from '@/types'
|
||||||
id: number
|
|
||||||
content: string
|
|
||||||
created_at: string
|
|
||||||
parent_id: number | null
|
|
||||||
user: {
|
|
||||||
id: number
|
|
||||||
name: string
|
|
||||||
image: string
|
|
||||||
}
|
|
||||||
replies?: Comment[]
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReplyButton = {
|
type ReplyButton = {
|
||||||
comment: Comment
|
comment: Comment
|
||||||
}
|
}
|
||||||
|
|
||||||
Comments.ReplyButton = function ReplyButton({comment}: ReplyButton) {
|
Comments.ReplyButton = function ReplyButton({comment}: ReplyButton) {
|
||||||
const replyContext = useContext(ReplyContext)
|
const replyContext = useReplyContext()
|
||||||
const commentFormContext = useContext(CommentFormContext)
|
const commentFormContext = useCommentFormContext()
|
||||||
const {data: session} = useSession()
|
const {data: session} = useSession()
|
||||||
|
|
||||||
const handleReplyButton = async (e: React.MouseEvent<HTMLButtonElement>) => {
|
const handleReplyButton = async (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
@ -132,18 +123,13 @@ const initialState: InitialState = {
|
|||||||
message: ''
|
message: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const CommentFormContext = createContext<{ focusCommentForm: () => void } | null>(null)
|
Comments.Form = function Form({slug}: { slug: string }) {
|
||||||
|
|
||||||
type CommentsFormsProps = {
|
|
||||||
slug: string
|
|
||||||
commentFormRef?: RefObject<HTMLTextAreaElement | null>
|
|
||||||
}
|
|
||||||
|
|
||||||
Comments.Form = function Form({slug, commentFormRef}: CommentsFormsProps) {
|
|
||||||
const [parentId, setParentId] = useState<string | number | null>('')
|
const [parentId, setParentId] = useState<string | number | null>('')
|
||||||
const [state, formAction, pending] = useActionState(addComment, initialState)
|
const [state, formAction, pending] = useActionState(addComment, initialState)
|
||||||
const {data: session} = useSession()
|
const {data: session} = useSession()
|
||||||
const replyContext = useContext(ReplyContext)
|
const replyContext = useReplyContext()
|
||||||
|
const commentFormContext = useCommentFormContext()
|
||||||
|
const commentFormRef = commentFormContext?.commentFormRef
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (replyContext?.replyTo?.parent_id !== null) {
|
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 = {
|
type CommentsProps = {
|
||||||
slug: string
|
slug: string
|
||||||
comments?: Comment[]
|
comments?: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Comments({slug, comments}: CommentsProps) {
|
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 (
|
return (
|
||||||
<ReplyContext.Provider value={{replyTo, setReplyTo}}>
|
<CommentFormProvider>
|
||||||
<CommentFormContext.Provider value={{focusCommentForm}}>
|
<ReplyProvider>
|
||||||
<div className="mt-24">
|
<div className="mt-24">
|
||||||
{comments &&
|
{comments &&
|
||||||
<Comments.List comments={comments}/>
|
<Comments.List comments={comments}/>
|
||||||
}
|
}
|
||||||
<Comments.Form slug={slug} commentFormRef={commentFormRef}/>
|
<Comments.Form slug={slug}/>
|
||||||
</div>
|
</div>
|
||||||
</CommentFormContext.Provider>
|
</ReplyProvider>
|
||||||
</ReplyContext.Provider>
|
</CommentFormProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -23,3 +23,16 @@ export type Repo = {
|
|||||||
color: 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…
x
Reference in New Issue
Block a user