Skip to content

Commit

Permalink
feat: 답글 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
kimkimjunjun committed Sep 28, 2024
1 parent 474a0dc commit 55ea050
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 56 deletions.
196 changes: 140 additions & 56 deletions src/app/board/[boardId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import menubars from "@/dummy/menubars.svg"
import deleteReply from "@/services/board/delete/deleteReply";
import { PostAirSVG, PostBusSVG, PostBycicleSVG, PostCarSVG, PostTrainSVG } from "@/components/transportsvg/post";
import backbutton from "@/dummy/backbutton.svg"
import { updatePostComment } from "@/services/board/patch/editComments";

export default function BoardPage({ params }: { params: { boardId: number } }) {
const accessToken = Cookies.get("accessToken");
Expand All @@ -54,6 +55,31 @@ export default function BoardPage({ params }: { params: { boardId: number } }) {
const [parentIds, setParentIds] = useState(0);
const [soloReply, setSoloReply] = useState(false);
const [replyStates, setReplyStates] = useState<boolean[]>([]);
const [editingIndexes, setEditingIndexes] = useState<{ [key: number]: boolean }>({}); // 수정 상태를 관리할 객체
const [updateReply, setUpdateReply] = useState('');
const [myUpdateReply, setMyUpdateReply] = useState<{ [key: number]: boolean }>({});

const toggleEdit = (index: number) => {
setEditingIndexes((prev) => ({
...prev,
[index]: !prev[index], // 해당 인덱스의 수정 상태 토글
}));
};

const toggleMyEdit = (index: number) => {
setMyUpdateReply((prev) => ({
...prev,
[index]: !prev[index], // 해당 인덱스의 수정 상태 토글
}));
};

const handleEditContent = (index: number, content: string) => {
// 수정된 내용을 처리하는 로직 추가
setUpdateReply(content);
toggleEdit(index); // 수정 상태 다시 토글
};

console.log(editingIndexes)

const { data: postData, refetch: postRefetch } = useQuery({
queryKey: ["postData"],
Expand Down Expand Up @@ -195,6 +221,15 @@ export default function BoardPage({ params }: { params: { boardId: number } }) {
postRefetch();
} catch (e) { }
};

const commentEditHandler = async (commentIds: number) => {
try {
await updatePostComment(commentIds, updateReply);
toggleEdit(commentIds)
setUpdateReply('');
commentRefetch();
} catch (e) { }
}
const commentReplyHandler = async (replymemIds: string, replyNicknames: string, mentionCommentIds: number) => {
const commentData = {
postId: Number(params.boardId),
Expand Down Expand Up @@ -605,10 +640,10 @@ export default function BoardPage({ params }: { params: { boardId: number } }) {

return (
<div className="mb-[2.5rem]" key={key}>
<div className={`py-[2rem] mr-[2rem]`}>
<div className={`pt-[1rem] py-[0.5rem] mr-[2rem]`}>
<div className="flex items-center">
<Image
className="w-[2.8rem] h-[2.8rem] flex items-center rounded-full"
className="w-[2.8rem] h-[2.8rem] flex items-center rounded-full mt-[0.2em]"
src={coData.member.profileUrl}
alt=""
width={28}
Expand All @@ -617,8 +652,11 @@ export default function BoardPage({ params }: { params: { boardId: number } }) {
<span className="ml-[1.4rem] text-[1.8rem] font-semibold flex items-center">
{coData.member.nickName}
</span>
{userInfo?.memberId === coData.member.memberId && (
<Image className="w-[2.8rem] h-[2.8rem] ml-auto cursor-pointer" src={menubars} alt="" />
)}
</div>
<div className="ml-[4rem]">
<div className="ml-[4rem] my-[0.5rem]">
<span className="text-[1.4rem] font-normal text-[#292929]">
{coData.content}
</span>
Expand Down Expand Up @@ -653,13 +691,10 @@ export default function BoardPage({ params }: { params: { boardId: number } }) {
</span>
</div>
<div className="relative">
<span className="absolute text-[#FFBACA] text-[1.4rem] ml-[4.5rem]">
@{coData.member.nickName}
</span>
<input
className="w-[70%] outline-none ml-[10rem] text-[1.4rem] font-normal pl-[1.5rem]"
className="w-[70%] outline-none ml-[2.5rem] text-[1.4rem] font-normal pl-[1.5rem]"
type="text"
placeholder="에게 답글쓰기"
placeholder={`${coData.member.nickName}에게 답글쓰기`}
value={replyComment}
onChange={(e) => setReplyComment(e.target.value)}
/>
Expand All @@ -677,9 +712,13 @@ export default function BoardPage({ params }: { params: { boardId: number } }) {
{coData?.children.map((childData: any, childIndex: number) => {
const createDateTime = new Date(childData.createDateTime);
const formattedDateTimes = `${createDateTime.getFullYear()}.${String(createDateTime.getMonth() + 1).padStart(2, "0")}.${String(createDateTime.getDate()).padStart(2, "0")} ${String(createDateTime.getHours()).padStart(2, "0")}:${String(createDateTime.getMinutes()).padStart(2, "0")}`;
console.log(childData);

const isEditing = editingIndexes[childData.id] || false;
const openEditing = myUpdateReply[childData.id] || false;

console.log(childData, isEditing);
return (
<div className={`bg-[#F5F5F5] w-[95%] py-[2rem] px-[1.6rem] mx-[4rem] rounded-[0.8rem]`} key={childIndex}>
<div className={`bg-[#F5F5F5] w-[95%] pt-[2rem] ${isEditing ? "pb-[4rem]" : "pb-[2rem] "} px-[1.6rem] mx-[4rem] rounded-[0.8rem]`} key={childIndex}>
<div className="flex items-center">
<Image
className="w-[2.8rem] h-[2.8rem] flex items-center rounded-full"
Expand All @@ -691,53 +730,98 @@ export default function BoardPage({ params }: { params: { boardId: number } }) {
<span className="ml-[1.4rem] text-[1.8rem] font-semibold flex items-center">
{childData.member.nickName}
</span>
{userInfo?.memberId === childData.member.memberId && (
<div className="flex ml-auto">
<Image className="w-[2.8rem] h-[2.8rem] cursor-pointer" src={menubars} alt="" onClick={() => toggleMyEdit(childData.id)} />
{openEditing && (
<div className="absolute flex flex-col ml-auto bg-white shadow-md rounded-md -ml-[4.5rem] mt-[2rem] animate-dropdown z-20 rounded-[0.8rem]" style={{ opacity: 0, transform: 'translateY(-10px)' }}>
<span className="px-[2rem] py-[1rem] cursor-pointer text-red-500" onClick={() => { deleteReplyHandler(childData.id); toggleMyEdit(childData.id) }}>삭제</span>
<span className="px-[2rem] py-[1rem] cursor-pointer" onClick={() => { handleEditContent(childData.id, childData.content); toggleMyEdit(childData.id) }}>수정</span>
</div>
)}
</div>
)}

</div>
<span className="text-[1.4rem] font-normal ml-[4.4rem] text-[#292929] mt-[1rem]">
<span className="text-[#FFBACA] text-[1.4rem] mr-[1rem]">
@{childData.mentionMemberNickName}
</span>
{childData.content}
</span>
<div className="flex ml-[4.5rem] text-[1.2rem] text-[#9D9D9D] items-center">
<span>{formattedDateTimes}</span>
<hr className="mx-[1rem] h-[1rem] w-[0.1rem] bg-[#9D9D9D]" />
<div>
{replyOpen[index] && rreplyOpen[childData.id] ? (
<span
className="cursor-pointer"
onClick={() => {
toggleReply(index);
toggleRreply(childData.id);
}}
{isEditing ? (
<div className="w-[95%] h-[3.3rem] shadowall my-[1rem] ml-[4rem] pt-[0.6rem] flex flex-col border border-[#CFCFCF] bg-white rounded-[0.8rem] relative">
<div className="w-full">
<div className="relative">
<input
className="w-full h-fit outline-none text-[1.4rem] font-normal pl-[1.5rem]"
type="text"
placeholder={`${coData.member.nickName}에게 답글쓰기`}
value={updateReply}
onChange={(e) => setUpdateReply(e.target.value)}
/>
</div>
</div>
<div className="flex ml-auto mt-[1rem]">
<button
className="hover:bg-[#292929] hover:text-white bg-[#FB3463] text-white rounded-[0.8rem] text-[1.6rem] font-semibold w-[6.6rem] h-[2.5rem] flex ml-auto mr-[1.4rem] items-center justify-center"
onClick={() => { commentReplyHandler(replymemId, replyNickname, replyId); commentEditHandler(childData.id) }}
>
답글취소
</span>
) : (
<span
className="cursor-pointer"
onClick={() => {
toggleReply(index);
toggleRreply(childData.id);
setParentIds(childData.parentId)
setReplyId(childData.id);
setReplyNickname(childData.member.nickName);
setReplyMemId(childData.member.memberId);
}}
수정
</button>
<button
className="hover:bg-[#292929] hover:text-white bg-[#9D9D9D] text-white rounded-[0.8rem] text-[1.6rem] font-semibold w-[6.6rem] h-[2.5rem] flex ml-auto mr-[1.4rem] items-center justify-center"
onClick={() => { commentReplyHandler(replymemId, replyNickname, replyId); handleEditContent(childData.id, childData.content) }}
>
답글달기
취소
</button>
</div>
</div>
) : (
<div>
<div className="text-[1.4rem] font-normal ml-[4.4rem] text-[#292929] my-[0.5rem] pr-[3rem]">
<span className="text-[#FFBACA] text-[1.4rem] mr-[1rem]">
@{childData.mentionMemberNickName}
</span>
)}
{userInfo?.memberId === childData.member.memberId && (
<span className="ml-[1rem] cursor-pointer" onClick={() => deleteReplyHandler(childData.id)}>삭제</span>
)}
{/* 답글이 열렸을 때 추가적인 요소를 보여줄 수 있습니다 */}
{replyOpen[index] && (
<div className="reply-input">
{/* 답글 입력 폼이나 추가적인 내용을 여기에 추가할 수 있습니다 */}
{childData.content}
</div>
<div className="flex ml-[4.5rem] text-[1.2rem] text-[#9D9D9D] items-center">
<span>{formattedDateTimes}</span>
<hr className="mx-[1rem] h-[1rem] w-[0.1rem] bg-[#9D9D9D]" />
<div>
{replyOpen[index] && rreplyOpen[childData.id] ? (
<span
className="cursor-pointer"
onClick={() => {
toggleReply(index);
toggleRreply(childData.id);
}}
>
답글취소
</span>
) : (
<span
className="cursor-pointer"
onClick={() => {
toggleReply(index);
toggleRreply(childData.id);
setParentIds(childData.parentId)
setReplyId(childData.id);
setReplyNickname(childData.member.nickName);
setReplyMemId(childData.member.memberId);
}}
>
답글달기
</span>
)}


{/* 답글이 열렸을 때 추가적인 요소를 보여줄 수 있습니다 */}
{replyOpen[index] && (
<div className="reply-input">
{/* 답글 입력 폼이나 추가적인 내용을 여기에 추가할 수 있습니다 */}
</div>
)}
</div>
)}
</div>
</div>
</div>
)}


</div>
);
})}
Expand All @@ -756,17 +840,17 @@ export default function BoardPage({ params }: { params: { boardId: number } }) {
<span className="ml-[1.4rem] text-[1.8rem] font-semibold flex items-center">
{memberDatas?.result.nickName}
</span>
{userInfo?.memberId === coData.member.memberId && (
<Image className="w-[2.8rem] h-[2.8rem] ml-auto" src={menubars} alt="" />
)}
</div>
<div className="relative">
<span className="absolute text-[#FFBACA] text-[1.4rem] ml-[4.5rem]">
@{replyNickname}
</span>
<input
className="w-[70%] outline-none ml-[10rem] text-[1.4rem] font-normal pl-[1.5rem]" // padding-left 추가
className="w-[70%] outline-none ml-[2.5rem] text-[1.4rem] font-normal pl-[1.5rem]" // padding-left 추가
type="text"
value={replyComment}
onChange={(e) => setReplyComment(e.target.value)}
placeholder="에게 답글쓰기"
placeholder={`${replyNickname}에게 답글쓰기`}
/>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/app/user/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ const UserPage = ({ params }: { params: { id: string } }) => {
className={activeTab === TABS.TICKET ? "text-[#fa3463]" : ""}
>
티켓
<span className="text-[#fa3463] ml-1">{userBoardCount}</span>
</span>
</button>
<button
Expand Down
11 changes: 11 additions & 0 deletions src/services/board/patch/editComments.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import axios from "axios";

const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL;

export const updatePostComment = async (commentId: number, content: string) => {
const response = await axios.patch(`${backendUrl}/api/comment`, {
commentId,
content,
});
return response.data.result;
};

0 comments on commit 55ea050

Please sign in to comment.