Skip to content

Commit

Permalink
[Feat/#73] 관리자 페이지 수정(필터 조건 추가 & 상품 순서 변경 기능) (#74)
Browse files Browse the repository at this point in the history
* feat: 관리자 상품 조회 순서 변경 기능 추가

* feat: 관리자 상품 추가 모달에 카테고리 반영

* feat: 관리자 페이지 주문 조회 staleTime 추가

* feat: 관리자 주문 조회 필터 조건 추가(주문 번호, 보내는 분, 받는 분)

* design: 관리자 상품 조회 페이지 행 cursor 변경
  • Loading branch information
gudusol authored Jan 14, 2025
1 parent c215ec1 commit e8429e7
Show file tree
Hide file tree
Showing 12 changed files with 345 additions and 76 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"svgr": "npx @svgr/cli -d src/assets/svg --ignore-existing --typescript --no-dimensions public/svg"
},
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@emotion/react": "^11.13.3",
"@tanstack/react-query": "^5.56.2",
"@tanstack/react-query-devtools": "^5.62.16",
Expand Down
1 change: 1 addition & 0 deletions src/apis/domains/admin/useFetchOrders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,6 @@ export const useFetchOrders = (query: queryType) => {
},
initialPageParam: -1, // 초기 페이지 파라미터 설정
select: (data) => (data.pages ?? []).flatMap((page) => page?.orders),
staleTime: 1000 * 60,
});
};
42 changes: 42 additions & 0 deletions src/apis/domains/admin/usePatchSequence.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { adminPatch } from "@apis/api";
import { QUERY_KEY } from "@apis/queryKeys/queryKeys";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { ErrorResponse, MutateResponseType } from "@types";

interface PatchProductSequence {
productId: number;
currentSequence: number;
newSequence: number;
}

const patchProductSequence = async ({
productId,
currentSequence,
newSequence,
}: PatchProductSequence): Promise<MutateResponseType> => {
try {
const response = await adminPatch<MutateResponseType>(
`api/v1/product/sequence/${productId.toString()}?currentSequence=${currentSequence}&newSequence=${newSequence}`
);
return response.data;
} catch (error) {
const errorResponse = error as ErrorResponse;
const errorData = errorResponse.response.data;
throw errorData;
}
};

export const usePatchSequence = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({
productId,
currentSequence,
newSequence,
}: PatchProductSequence) =>
patchProductSequence({ productId, currentSequence, newSequence }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [QUERY_KEY.PRODUCT_LIST_ALL] });
},
});
};
6 changes: 5 additions & 1 deletion src/pages/Admin/components/Filter/Filter.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ export const rowStyle = (theme: Theme) => css`
background-color: ${theme.color.white};
`;

export const inputWrapper = css`
width: 20rem;
`;

export const productSelectStyle = (theme: Theme) => css`
width: 40rem;
width: 30rem;
${theme.font["subhead-m-14"]}
& #react-select-3-listbox {
Expand Down
80 changes: 65 additions & 15 deletions src/pages/Admin/components/Filter/Filter.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useEffect, useState } from "react";
import { Button, DateSelect } from "@components";
import { Button, DateSelect, Input } from "@components";
import FilterAttribute from "../FilterAttribute/FilterAttribute";
import {
buttonContainer,
filterContainer,
filterTable,
inputWrapper,
productSelectStyle,
rowStyle,
statusSelectStyle,
Expand All @@ -28,10 +29,15 @@ const statusOptions: Option[] = [
];

interface FilterProps {
orderReceivedDateRef: React.MutableRefObject<Dayjs | null>;
deliveryDateRef: React.MutableRefObject<Dayjs | null>;
productRef: React.MutableRefObject<Option | null>;
statusRef: React.MutableRefObject<Option | null>;
filterRef: {
orderNumberRef: React.MutableRefObject<string | null>;
senderNameRef: React.MutableRefObject<string | null>;
recipientNameRef: React.MutableRefObject<string | null>;
orderReceivedDateRef: React.MutableRefObject<Dayjs | null>;
deliveryDateRef: React.MutableRefObject<Dayjs | null>;
productRef: React.MutableRefObject<Option | null>;
statusRef: React.MutableRefObject<Option | null>;
};
handleSearchClick: () => void;
handleResetClick: () => void;
}
Expand All @@ -42,10 +48,7 @@ interface GroupedOption {
}

const Filter = ({
orderReceivedDateRef,
deliveryDateRef,
productRef,
statusRef,
filterRef,
handleSearchClick,
handleResetClick,
}: FilterProps) => {
Expand All @@ -60,6 +63,9 @@ const Filter = ({
},
]);

const [orderNumber, setOrderNumber] = useState<string | null>(null);
const [senderName, setSenderName] = useState<string | null>(null);
const [recipientName, setRecipientName] = useState<string | null>(null);
const [orderReceivedDate, setOrderReceivedDate] = useState<Dayjs | null>(
null
);
Expand Down Expand Up @@ -91,6 +97,9 @@ const Filter = ({
}, [isSuccessProduct, productData]);

const handleResetState = () => {
setOrderNumber(null);
setSenderName(null);
setRecipientName(null);
setOrderReceivedDate(null);
setDeliveryDate(null);
setProduct(null);
Expand All @@ -102,12 +111,55 @@ const Filter = ({
return (
<article css={filterContainer}>
<div css={filterTable}>
<div css={rowStyle}>
<FilterAttribute label="주문 번호">
<div css={inputWrapper}>
<Input
type="text"
value={orderNumber?.toString() || ""}
placeholder="주문 번호"
onChange={(e) => {
filterRef.orderNumberRef.current = e.target.value;
setOrderNumber(e.target.value);
}}
/>
</div>
</FilterAttribute>
</div>
<div css={rowStyle}>
<FilterAttribute label="보내는 분">
<div css={inputWrapper}>
<Input
type="text"
value={senderName || ""}
placeholder="보내는 분"
onChange={(e) => {
filterRef.senderNameRef.current = e.target.value;
setSenderName(e.target.value);
}}
/>
</div>
</FilterAttribute>
<FilterAttribute label="받는 분">
<div css={inputWrapper}>
<Input
type="text"
value={recipientName || ""}
placeholder="받는 분"
onChange={(e) => {
filterRef.recipientNameRef.current = e.target.value;
setRecipientName(e.target.value);
}}
/>
</div>
</FilterAttribute>
</div>
<div css={rowStyle}>
<FilterAttribute label="접수 날짜">
<DateSelect
selected={orderReceivedDate}
onChange={(date) => {
orderReceivedDateRef.current = date;
filterRef.orderReceivedDateRef.current = date;
setOrderReceivedDate(date);
}}
/>
Expand All @@ -116,7 +168,7 @@ const Filter = ({
<DateSelect
selected={deliveryDate}
onChange={(date) => {
deliveryDateRef.current = date;
filterRef.deliveryDateRef.current = date;
setDeliveryDate(date);
}}
/>
Expand All @@ -131,13 +183,11 @@ const Filter = ({
value={product}
onChange={(selectedOption) => {
const selectValue = selectedOption as Option | null;
productRef.current = selectedOption as Option | null;
filterRef.productRef.current = selectedOption as Option | null;
setProduct(selectValue);
}}
/>
</FilterAttribute>
</div>
<div css={rowStyle}>
<FilterAttribute label="상태">
<Select
css={statusSelectStyle}
Expand All @@ -146,7 +196,7 @@ const Filter = ({
value={status}
onChange={(selectedOption) => {
const selectValue = selectedOption as Option | null;
statusRef.current = selectValue;
filterRef.statusRef.current = selectValue;
setStatus(selectValue);
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import {
} from "./ProductAddModal.style";
import { useState } from "react";
import { usePostProduct } from "@apis/domains/admin/usePostProduct";
import { CategoryType } from "@types";

interface ModalProps {
onClose: () => void;
category: CategoryType;
}

const ProductAddModal = ({ onClose }: ModalProps) => {
const [isTrial, setIsTrial] = useState(true);
const ProductAddModal = ({ onClose, category }: ModalProps) => {
const [isTrial, setIsTrial] = useState(category === "experience");
const [productName, setProductName] = useState<string>("");
const [productPrice, setProductPrice] = useState<number>(0);

Expand Down
Loading

0 comments on commit e8429e7

Please sign in to comment.