Skip to content

Commit

Permalink
feat: 리뷰 조회 및 갱신에 react query 사용
Browse files Browse the repository at this point in the history
  • Loading branch information
scarf005 committed Aug 28, 2023
1 parent d80fd2c commit afe4e00
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 88 deletions.
74 changes: 31 additions & 43 deletions src/api/reviews/useGetReviews.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,40 @@
import { useState, useEffect } from "react";
import { useApi } from "../../hook/useApi";
import { Review } from "../../type";
import type { contract } from "@jiphyeonjeon-42/contracts";
import type { ClientInferRequest } from "@ts-rest/core";
import { useState } from "react";
import { client } from "~/util/tsRestClient";

export const useGetReviews = () => {
const [params, setParams] = useState({
titleOrNickname: "",
page: 1,
disabled: "-1",
});

const [result, setResult] = useState({
reviewList: [],
lastPage: 5,
});
type QueryArgs = ClientInferRequest<typeof contract.reviews.get>["query"];

const setPage = (page: number) => {
setParams({ ...params, page });
};
const setQuery = (query: string) => {
setParams({ ...params, titleOrNickname: query });
};
const setSelectedType = (type: string | undefined) => {
if (type) setParams({ ...params, disabled: type });
};

const { request } = useApi("get", "reviews", {
...params,
page: params.page - 1,
});

const refineResponse = (response: any) => {
const { items } = response.data;
const { totalPages } = response.data.meta;

setResult({ reviewList: items, lastPage: totalPages });
export const useGetReviews = () => {
const [search, setSearch] = useState<string | undefined>();
const [page, setPage] = useState(1);
const [visibility, setVisibility] = useState<"public" | "hidden" | "all">(
"all",
);

const queryArgs: QueryArgs = {
search,
page,
visibility,
perPage: 10,
sort: "desc",
};

useEffect(() => {
request(refineResponse);
}, [params]);
const query = client.reviews.get.useQuery(
["reviews", queryArgs],
{ query: queryArgs },
{
keepPreviousData: true,
staleTime: 1000 * 60 * 60,
},
);

return {
page: params.page,
page,
setPage,
setQuery,
selectedType: params.disabled,
setSelectedType,
reviewList: result.reviewList as Review[],
lastPage: result.lastPage,
setSearch,
visibility,
setVisibility,
data: query.data?.body,
};
};
10 changes: 2 additions & 8 deletions src/api/reviews/usePatchReviewsId.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import { useEffect, useState } from "react";
import { useApi } from "../../hook/useApi";
import { queryClient } from "~/index";
import { useNewDialog } from "../../hook/useNewDialog";
import { client } from "../../util/tsRestClient";

export const usePatchReviewsId = () => {
const { addErrorDialog, addDialogWithTitleAndMessage } = useNewDialog();

const mutation = client.reviews.patch.useMutation({
onSuccess: () => {
console.log("local success");
addDialogWithTitleAndMessage("patched", "처리되었습니다", "", () =>
window.location.reload(),
);
},
onSuccess: () => queryClient.invalidateQueries(["reviews"]),
onError: err => {
switch (err.status) {
case 401:
Expand Down
37 changes: 16 additions & 21 deletions src/component/reviewManagement/ReviewManagement.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
import { useGetReviews } from "../../api/reviews/useGetReviews";
import { otherManagementTabList } from "../../constant/tablist";
import Banner from "../utils/Banner";
import Tabs from "../utils/Tabs";
import Filter from "../utils/Filter";
import Management from "../utils/Management";
import Tabs from "../utils/Tabs";
import ReviewManagementListItem from "./ReviewManagementListItem";
import Filter from "../utils/Filter";

type Visibility = "all" | "public" | "hidden";

const reviewFilterList = [
{ name: "공개만 보기", type: "0" },
{ name: "비공개만 보기", type: "1" },
];
{ name: "공개만 보기", type: "public" },
{ name: "비공개만 보기", type: "hidden" },
] satisfies { name: string; type: Visibility }[];

const ReviewManagement = () => {
const {
page,
setPage,
setQuery,
selectedType,
setSelectedType,
reviewList,
lastPage,
} = useGetReviews();
const { page, setPage, data, visibility, setVisibility, setSearch } =
useGetReviews();

const setUndefinedReSelected = (newType: string) => {
setSelectedType(newType === selectedType ? "-1" : newType);
const setVisiblityWithUnset = (value: "public" | "hidden") => {
setVisibility(visibility === value ? "all" : value);
};

return (
Expand All @@ -32,7 +27,7 @@ const ReviewManagement = () => {
<Tabs tabList={otherManagementTabList} />
<Management
searchBarPlaceHolder="도서명이나 닉네임을 검색하세요"
setQuery={setQuery}
setQuery={setSearch}
TitleFragement={
<>
<span className="review-management__list__id">ID</span>
Expand All @@ -46,17 +41,17 @@ const ReviewManagement = () => {
<>
<Filter
filterList={reviewFilterList}
selectedType={selectedType}
setSelectedType={setUndefinedReSelected}
selectedType={visibility}
setSelectedType={setVisiblityWithUnset as (_: string) => void}
/>
{reviewList.map(review => (
{data?.items.map(review => (
<ReviewManagementListItem review={review} />
))}
</>
}
page={page}
setPage={setPage}
lastPage={lastPage}
lastPage={data?.meta.totalPages ?? 1}
/>
</main>
);
Expand Down
32 changes: 16 additions & 16 deletions src/component/reviewManagement/ReviewManagementListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
import { MouseEventHandler } from "react";
import { usePatchReviewsId } from "../../api/reviews/usePatchReviewsId";
import { Review } from "../../type";
import Edit from "../../asset/img/edit.svg";
import Image from "../utils/Image";
import "../../asset/css/ReviewManagementList.css";
import Edit from "../../asset/img/edit.svg";
import { useNewDialog } from "../../hook/useNewDialog";
import Image from "../utils/Image";

import { contract } from "@jiphyeonjeon-42/contracts";
import type { ClientInferResponseBody } from "@ts-rest/core";

type Review = ClientInferResponseBody<
typeof contract.reviews.get,
200
>["items"][number];

type Props = {
review: Review;
};

const ReviewManagementListItem = ({ review }: Props) => {
const { setReviewId } = usePatchReviewsId();
const mutation = usePatchReviewsId();
const { addConfirmDialog } = useNewDialog();

const requestConfirmToUpdate: MouseEventHandler = e => {
const requestConfirmToUpdate: MouseEventHandler = () => {
const job = review.disabled ? "공개" : "비공개";

addConfirmDialog(
"리뷰확인",
`리뷰를 ${job}하시겠습니까?`,
`[${review.title}]\n\n리뷰내용 : ${review.content}`,
() => {
setReviewId(review.reviewsId);
},
() => mutation.mutate({ params: { reviewsId: review.id } }),
);
};

return (
<div className="review-management__list__item" key={review.reviewsId}>
<span className="review-management__list__id">{review.reviewsId}</span>
<div className="review-management__list__item" key={review.id}>
<span className="review-management__list__id">{review.id}</span>
<span className="review-management__list__created-at">
<span className="review-management__list__year">
{review.createdAt.slice(0, 5)}
</span>
<span className="review-management__list__date">
{review.createdAt.slice(5, 10)}
</span>
{review.createdAt.split("T")[0]}
</span>
<span className="review-management__list__nickname">
{review.nickname}
Expand Down

0 comments on commit afe4e00

Please sign in to comment.