Skip to content

Commit

Permalink
Merge pull request #104 from softeerbootcamp4th/feature/32-admincomment
Browse files Browse the repository at this point in the history
[feat] 어드민 기대평 페이지 구현
  • Loading branch information
lybell-art authored Aug 16, 2024
2 parents 339c4a9 + d6900ca commit 5451298
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 63 deletions.
55 changes: 41 additions & 14 deletions src/adminPage/features/comment/id/Comments.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,69 @@ export default function Comments({
eventId,
checkedComments,
setCheckedComments,
page,
setAllId,
}) {
const data = useQuery(eventId, () =>
fetchServer(
`/api/v1/admin/comments?eventId=${eventId}&page=${0}&size=15`,
).then((res) => res.comments),
const data = useQuery(
eventId,
() =>
fetchServer(
`/api/v1/admin/comments?eventId=${eventId}&page=${page}&size=15`,
).then(({ comments }) => {
setAllId(comments.map((comment) => comment.id));
return comments;
}),
[page],
);

function onChangeCheckbox(e, id) {
if (e.target.checked) {
setCheckedComments((oldSet) => new Set([...oldSet, id]));
} else {
function getDate(createdAt) {
const yy = createdAt.slice(2, 4);
const mm = createdAt.slice(5, 7);
const dd = createdAt.slice(8, 10);
return `${yy}-${mm}-${dd}`;
}

function getTime(createdAt) {
const hh = createdAt.slice(11, 13);
const mm = createdAt.slice(14, 16);
const ss = createdAt.slice(17, 19);
return `${hh}:${mm}:${ss}`;
}

function checkComment(id) {
if (checkedComments.has(id)) {
setCheckedComments((oldSet) => {
const newSet = new Set(oldSet);
newSet.delete(id);
return newSet;
});
} else {
setCheckedComments((oldSet) => new Set([...oldSet, id]));
}
}

return (
<div className="mt-3 flex flex-col gap-1">
<div className="mt-1 mb-5 flex flex-col gap-1 w-full">
{data.map((comment) => (
<div
key={comment.id}
className="py-1 grid grid-cols-[1fr_5fr_15fr] bg-neutral-50"
onClick={() => checkComment(comment.id)}
className="w-full py-1 grid grid-cols-[1fr_5fr_15fr] bg-neutral-50 items-center hover:bg-blue-100"
>
<input
type="checkbox"
onChange={() => checkComment(comment.id)}
checked={checkedComments.has(comment.id)}
onChange={(e) => onChangeCheckbox(e, comment.id)}
className="w-4 h-4 place-self-center"
/>

<span className="text-body-s place-self-center">
{comment.createdAt}
</span>
<div className="place-self-center flex items-center gap-1 text-body-s">
<span>{getDate(comment.createdAt)}</span>

<span className="text-neutral-500">
{getTime(comment.createdAt)}
</span>
</div>

<span className="text-body-s">{comment.content}</span>
</div>
Expand Down
59 changes: 59 additions & 0 deletions src/adminPage/features/comment/id/DeleteButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useMutation } from "@common/dataFetch/getQuery.js";
import openModal from "@common/modal/openModal.js";
import { fetchServer } from "@common/dataFetch/fetchServer.js";
import ConfirmModal from "@admin/modals/ConfirmModal.jsx";
import AlertModal from "@admin/modals/AlertModal.jsx";

export default function DeleteButton({
eventId,
checkedComments,
setCheckedComments,
}) {
const num = checkedComments.size;
const mutation = useMutation(eventId, () =>
fetchServer("/api/v1/admin/comments", {
method: "DELETE",
body: {
commentIds: [...checkedComments],
},
})
.then(() => {
openModal(
<AlertModal title="삭제" description="기대평이 삭제되었습니다." />,
);
setCheckedComments(new Set());
})
.catch((e) => {
alert("삭제 실패");
console.log(e);
}),
);

const deleteConfirmModal = (
<ConfirmModal
title="삭제"
description={
<>
<span>이 동작은 다시 돌이킬 수 없습니다.</span>
<br />
<span>{num}개의 기대평을 삭제하시겠습니까?</span>
</>
}
onConfirm={mutation}
/>
);

function deleteComments() {
if (!num) return;
openModal(deleteConfirmModal);
}

return (
<button
onClick={deleteComments}
className="self-end px-5 py-1 bg-red-300 text-white hover:bg-red-500 rounded-lg"
>
삭제
</button>
);
}
2 changes: 1 addition & 1 deletion src/adminPage/features/comment/id/Loading.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Spinner from "@common/components/Spinner";

export default function Loading() {
return (
<div className="flex justify-center items-center w-full h-60 bg-slate-50">
<div className="flex justify-center items-center w-full h-[600px] bg-slate-50">
<Spinner />
</div>
);
Expand Down
71 changes: 40 additions & 31 deletions src/adminPage/features/comment/id/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,66 @@ import Suspense from "@common/components/Suspense";
import Loading from "./Loading.jsx";
import Comments from "./Comments.jsx";
import { useState } from "react";
import { fetchServer } from "@common/dataFetch/fetchServer.js";
import Pagination from "@admin/components/Pagination";
import DeleteButton from "./DeleteButton.jsx";

export default function AdminCommentID({ eventId }) {
const [checkedComments, setCheckedComments] = useState(new Set());
const [page, setPage] = useState(1);
const [formString, setFormString] = useState("");
const [allId, setAllId] = useState([]);

function deleteComments() {
const num = checkedComments.size;
if (!num) return;

fetchServer("/api/v1/admin/comments", {
method: "DELETE",
body: {
commentIds: [...checkedComments],
},
})
.then(() => {
alert(num + "개의 기대평 삭제 완료.");
setCheckedComments(new Set());
})
.catch((e) => {
console.log(e);
function selectAll() {
if (allId.every((id) => checkedComments.has(id))) {
setCheckedComments((oldSet) => {
const newSet = new Set(oldSet);
allId.forEach((id) => {
newSet.delete(id);
});
return newSet;
});
} else {
setCheckedComments((oldSet) => new Set([...oldSet, ...allId]));
}
}

function searchComment(e) {
e.preventDefault();
console.log(e.target.searchText.value + "검색");

if (formString) {
console.log(formString + "검색");
}
}

return (
<div className="flex flex-col w-full">
<button
onClick={deleteComments}
className="self-end px-5 py-1 bg-red-300 text-white hover:bg-red-500 rounded-lg"
>
삭제
</button>
<div className="flex flex-col w-full items-center">
<DeleteButton
eventId={eventId}
checkedComments={checkedComments}
setCheckedComments={setCheckedComments}
/>

<form onSubmit={searchComment} className="mt-5 w-full relative">
<form onSubmit={searchComment} className="mt-3 w-full relative">
<input
type="text"
name="searchText"
value={formString}
onChange={(e) => setFormString(e.target.value)}
placeholder="검색 단어 입력"
className="bg-neutral-50 focus:bg-white w-full px-4 py-2 rounded-lg"
className="bg-neutral-50 focus:bg-white w-full px-4 py-2 rounded-lg text-body-s"
/>

<img
onClick={searchComment}
src="/icons/search.png"
alt="검색"
className="absolute top-1/2 -translate-y-1/2 right-4"
className="cursor-pointer absolute top-1/2 -translate-y-1/2 right-4"
/>
</form>

<div className="mt-3 py-2 grid grid-cols-[1fr_5fr_15fr] bg-blue-50 place-items-center">
<span>선택</span>
<div className="mt-3 py-1 w-full grid grid-cols-[1fr_5fr_15fr] bg-blue-50 place-items-center text-body-s select-none">
<span onClick={selectAll} className="cursor-pointer">
선택
</span>
<span>작성 시간</span>
<span>기대평 내용</span>
</div>
Expand All @@ -66,8 +71,12 @@ export default function AdminCommentID({ eventId }) {
eventId={eventId}
checkedComments={checkedComments}
setCheckedComments={setCheckedComments}
page={page - 1}
setAllId={setAllId}
/>
</Suspense>

<Pagination currentPage={page} setPage={setPage} maxPage={10} />
</div>
);
}
17 changes: 1 addition & 16 deletions src/adminPage/features/comment/mock.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,6 @@
import { http, HttpResponse } from "msw";
import getRandomString from "@common/mock/getRandomString";

function getRandomString(len) {
// const startCode = 0xac00;
// const endCode = 0xd7a3;

const startCode = 0x0750;
const endCode = 0x077f;

let str = "";
for (let i = 0; i < len; i++) {
const randomCode =
Math.floor(Math.random() * (endCode - startCode + 1)) + startCode;
str += String.fromCharCode(randomCode);
}

return str;
}

function getSampleEventList() {
const len = 10;
Expand Down
2 changes: 1 addition & 1 deletion src/adminPage/pages/CommentsIDPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function CommentsPage() {
return (
<Container>
<div className="flex flex-col w-full p-20">
<span className="text-title-l pb-10">기대평</span>
<span className="text-title-l pb-5">기대평</span>

<AdminCommentID eventId={eventId} />
</div>
Expand Down
17 changes: 17 additions & 0 deletions src/common/mock/getRandomString.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export default function getRandomString(len) {
/* 한글
const startCode = 0xac00;
const endCode = 0xd7a3;
*/
const startCode = 0x0750;
const endCode = 0x077f;

let str = "";
for (let i = 0; i < len; i++) {
const randomCode =
Math.floor(Math.random() * (endCode - startCode + 1)) + startCode;
str += String.fromCharCode(randomCode);
}

return str;
}

0 comments on commit 5451298

Please sign in to comment.