Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"use client";

import {
getCommentsDisclosure,
postCommentsDisclosure,
} from "@/src/apis/comment";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";

const QUERY_KEY = ["comments-disclosure"];

export default function CommentsDisclosurePage() {
const queryClient = useQueryClient();
const { data, isLoading, isError } = useQuery(
QUERY_KEY,
getCommentsDisclosure
);
Comment on lines +13 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

TanStack Query v5 이상을 사용 중이라면 useQuery의 인자를 객체 형태({ queryKey, queryFn })로 전달해야 합니다. 현재의 방식은 v4 이하의 문법이므로, 프로젝트의 라이브러리 버전에 맞춰 최신 문법을 적용하는 것을 권장합니다.

Suggested change
const { data, isLoading, isError } = useQuery(
QUERY_KEY,
getCommentsDisclosure
);
const { data, isLoading, isError } = useQuery({
queryKey: QUERY_KEY,
queryFn: getCommentsDisclosure,
});


const { mutate: updateDisclosure, isLoading: isUpdating } = useMutation(
postCommentsDisclosure,
{
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: QUERY_KEY });
},
onError: () => {
alert("댓글 공개 상태 변경에 실패했습니다. 잠시 후 다시 시도해주세요.");
},
}
);
Comment on lines +18 to +28

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

useMutation 또한 v5에서는 객체 형태의 인자를 사용하며, isLoading 속성은 isPending으로 변경되었습니다. 일관성 있는 최신 문법 사용을 권장합니다.

  const { mutate: updateDisclosure, isLoading: isUpdating } = useMutation({
    mutationFn: postCommentsDisclosure,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: QUERY_KEY });
    },
    onError: () => {
      alert("댓글 공개 상태 변경에 실패했습니다. 잠시 후 다시 시도해주세요.");
    },
  });


if (isLoading) {
return <div className="mt-10">로딩중...</div>;
}

if (isError || data === undefined) {
return <div className="mt-10">에러 발생</div>;
}

const nextDisclosure = !data;

return (
<section className="mt-10 flex flex-col gap-4 max-w-xl">
<h2 className="text-xl font-semibold">댓글 전체 공개 상태 관리</h2>
<div className="rounded-lg border p-6 flex items-center justify-between">
<div className="text-lg font-medium">
현재 상태:{" "}
<span className={data ? "text-primary" : "text-gray-500"}>
{data ? "활성화" : "비활성화"}
</span>
</div>
<button
type="button"
className={`rounded-md text-white px-4 py-2 disabled:bg-gray-300 ${
nextDisclosure
? "bg-blue-500 hover:bg-blue-600"
: "bg-gray-500 hover:bg-gray-600"
}`}
onClick={() => updateDisclosure(nextDisclosure)}
disabled={isUpdating}
>
{nextDisclosure ? "활성화" : "비활성화"}
</button>
</div>
</section>
);
}
1 change: 1 addition & 0 deletions frontend/components/admin/AdminTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default function AdminTabs() {
const tabs = [
{ name: "멤버 권한 변경", href: `/admin/${generation}` },
{ name: "지원서 on/off", href: `/admin/${generation}/on-off` },
{ name: "댓글 전체 공개 on/off", href: `/admin/${generation}/comments-disclosure` },
];

return (
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/apis/comment/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,16 @@ export const getCommentsIsLike = async (commentId: string) => {

return data;
};

export const getCommentsDisclosure = async () => {
const { data } = await https.get<boolean | string>(`/comments/disclosure`);
return data === true || data === "true";
};

export const postCommentsDisclosure = async (isDisclosure: boolean) => {
const { data } = await https.post<boolean | string>(
`/comments/disclosure`,
`${isDisclosure}`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

isDisclosure를 템플릿 리터럴을 사용하여 문자열로 변환하여 전송하고 있습니다. axios 인스턴스 설정에서 Content-Typeapplication/json으로 설정되어 있으므로, 불리언 값 자체를 전달하여 JSON 표준 타입을 따르는 것이 더 적절합니다.

Suggested change
`${isDisclosure}`
isDisclosure

);
return data === true || data === "true";
};