'use client' import React, {createContext, ReactNode, RefObject, useActionState, useContext, useEffect, useRef, useState} from 'react' import {useSession} from 'next-auth/react' import Image from 'next/image' import clsx from 'clsx' import {addComment, loginWithGitHub} from '@/app/actions/comments' import {Button} from '@/components/ui/Button' import {GitHubIcon} from '@/components/icons/SocialIcons' import {formatDistanceToNow} from 'date-fns' import {ArrowLeftIcon} from '@/components/icons/ArrowLeftIcon' type Comment = { id: number content: string created_at: string parent_id: number | null user: { id: number name: string image: string } replies?: Comment[] } type ReplyButton = { comment: Comment } Comments.ReplyButton = function ReplyButton({comment}: ReplyButton) { const replyContext = useContext(ReplyContext) const commentFormContext = useContext(CommentFormContext) const handleReplyButton = (e: React.MouseEvent) => { e.preventDefault() replyContext?.setReplyTo(comment) commentFormContext?.focusCommentForm() } return ( ) } Comments.Comment = function Comment({comment, children, isReply = false}: { comment: Comment, children?: ReactNode, isReply?: boolean }) { const {data: session} = useSession() return ( <>
{comment.user.name}

{comment.user.name}

{comment.content}

{session && }
{children} ) } type CommentsListProps = { comments: Comment[] } Comments.List = function List({comments}: CommentsListProps) { return ( <> {comments.length > 0 &&

Comments

{comments.map((comment) => ( {comment.replies && comment.replies.map(reply => ( ))} ))}
} ) } type CommentsStatusProps = { children: ReactNode } Comments.Status = function Status({children}: CommentsStatusProps) { const errorConditions = ['error', 'problem'] const isError = errorConditions.some(condition => children?.toString().toLowerCase().includes(condition)) return (

{children}

) } type InitialState = { message: string } const initialState: InitialState = { message: '' } const CommentFormContext = createContext<{ focusCommentForm: () => void } | null>(null) Comments.Form = function Form({slug, commentFormRef}: CommentsProps) { const [parentId, setParentId] = useState('') const [state, formAction, pending] = useActionState(addComment, initialState) const {data: session} = useSession() const replyContext = useContext(ReplyContext) useEffect(() => { if (replyContext?.replyTo?.parent_id !== null) { setParentId(replyContext?.replyTo?.parent_id ?? '') } else { setParentId(replyContext?.replyTo?.id) } }, [replyContext?.replyTo]) const handleKeyDown = (e: React.KeyboardEvent) => { if ((e.ctrlKey || e.metaKey) && (e.key === 'Enter' || e.key === 'NumpadEnter')) { e.preventDefault() e.currentTarget.form?.requestSubmit() } if (e.key === 'Escape' && replyContext?.replyTo !== null) { replyContext?.setReplyTo(null) commentFormRef?.current?.blur() } } return (
{!session ?
await loginWithGitHub()}>
:
replyContext?.setReplyTo(null)}>