"use client"; import * as React from "react"; import { useRouter } from "next/navigation"; import { useSession } from "next-auth/react"; import { format } from "date-fns"; import { Button } from "@/components/ui/button"; import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; import { ArrowLeft, MessageSquare, Edit, Trash2, Plus, Clock, User } from "lucide-react"; import TiptapEditor from "@/components/qna/tiptap-editor"; import { ImprovedCommentSection } from "./improved-comment-section"; import { createAnswer, deleteQna, deleteAnswer, updateAnswer, createComment, deleteComment, updateComment, } from "@/lib/qna/service"; import { Question } from "@/lib/qna/types"; interface QnaDetailProps { question: Question; } export default function QnaDetail({ question }: QnaDetailProps) { const router = useRouter(); const { data: session } = useSession(); // ------------------------------------------------------------------------- // STATE // ------------------------------------------------------------------------- const [answerContent, setAnswerContent] = React.useState(""); const [loading, setLoading] = React.useState(false); const [isAnswerDialogOpen, setIsAnswerDialogOpen] = React.useState(false); const [editingAnswerId, setEditingAnswerId] = React.useState(null); // ------------------------------------------------------------------------- // DERIVED // ------------------------------------------------------------------------- const isAuthor = session?.user?.id === question.author; const hasAnswers = (question.answers ?? []).length > 0; const userAnswer = question.answers?.find((a) => a.author === session?.user?.id) ?? null; // ------------------------------------------------------------------------- // HANDLERS – NAVIGATION // ------------------------------------------------------------------------- const handleGoBack = () => { router.push("/evcp/qna"); }; // ------------------------------------------------------------------------- // HANDLERS – QUESTION // ------------------------------------------------------------------------- const handleDeleteQuestion = async () => { try { await deleteQna(question.id); router.push("/evcp/qna"); router.refresh(); } catch (err) { console.error("질문 삭제 실패:", err); } }; // ------------------------------------------------------------------------- // HANDLERS – ANSWER // ------------------------------------------------------------------------- const handleSubmitAnswer = async () => { if (!answerContent.trim()) return; setLoading(true); try { await createAnswer({ qnaId: question.id, content: answerContent }); setAnswerContent(""); setIsAnswerDialogOpen(false); router.refresh(); } catch (err) { console.error("답변 저장 실패:", err); } finally { setLoading(false); } }; const handleUpdateAnswer = async (answerId: number) => { if (!answerContent.trim()) return; setLoading(true); try { await updateAnswer(answerId, answerContent); setAnswerContent(""); setEditingAnswerId(null); setIsAnswerDialogOpen(false); router.refresh(); } catch (err) { console.error("답변 수정 실패:", err); } finally { setLoading(false); } }; const handleDeleteAnswer = async (id: number) => { try { await deleteAnswer(id); router.refresh(); } catch (err) { console.error("답변 삭제 실패:", err); } }; const startEditingAnswer = (answer: any) => { setAnswerContent(answer.content); setEditingAnswerId(answer.id); setIsAnswerDialogOpen(true); }; const resetAnswerDialog = () => { setAnswerContent(""); setEditingAnswerId(null); setIsAnswerDialogOpen(false); }; return (
{/* 헤더 */}
{/*
*/} {/* {getCategoryLabel(question.category as any, 'ko')} */}
{isAuthor && !hasAnswers && (
질문 삭제 정말로 이 질문을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다. 취소 삭제
)}
{/* 메인 컨텐츠 */}
{/* 질문 영역 */}
{question.title}
{question.authorName}
{hasAnswers && (
답변 {question.answers?.length}개
)}
{/* 답변 영역 */}

답변 {hasAnswers ? `(${question.answers?.length})` : ''}

{session?.user && ( {editingAnswerId ? '답변 수정' : '새 답변 작성'} 질문에 대한 답변을 작성해주세요. 다른 사용자들이 이해하기 쉽도록 구체적으로 작성해주세요.
)}
{hasAnswers ? (
{question.answers?.map((answer, index) => (
{answer.authorName ?? `사용자 ${answer.author}`}
{format(new Date(answer.createdAt), "yyyy년 MM월 dd일 HH:mm")}
{session?.user?.id === answer.author && (
답변 삭제 정말로 이 답변을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다. 취소 handleDeleteAnswer(answer.id)} className="bg-destructive hover:bg-destructive/90" > 삭제
)}
{/* 답변별 댓글 섹션 */}
{ if (!session?.user?.id) return; try { await createComment({ content, answerId: answer.id }); router.refresh(); } catch (err) { console.error("댓글 작성 실패:", err); } }} onDeleteComment={async (commentId) => { try { await deleteComment(commentId); router.refresh(); } catch (err) { console.error("댓글 삭제 실패:", err); } }} onUpdateComment={async (commentId, content) => { try { await updateComment(commentId, content); router.refresh(); } catch (err) { console.error("댓글 수정 실패:", err); } }} />
))}
) : (

아직 등록된 답변이 없습니다.

{session?.user && ( )}
)}
); }