diff --git a/src/app/(common)/(market)/items/(lists)/_components/ProductFilter.module.scss b/src/components/market/ProductFilter.module.scss
similarity index 100%
rename from src/app/(common)/(market)/items/(lists)/_components/ProductFilter.module.scss
rename to src/components/market/ProductFilter.module.scss
diff --git a/src/app/(common)/(market)/items/(lists)/_components/ProductFilter.tsx b/src/components/market/ProductFilter.tsx
similarity index 100%
rename from src/app/(common)/(market)/items/(lists)/_components/ProductFilter.tsx
rename to src/components/market/ProductFilter.tsx
diff --git a/src/app/(common)/(market)/_components/ProductForm.tsx b/src/components/market/ProductForm.tsx
similarity index 92%
rename from src/app/(common)/(market)/_components/ProductForm.tsx
rename to src/components/market/ProductForm.tsx
index 228c64ed8..d313be9c5 100644
--- a/src/app/(common)/(market)/_components/ProductForm.tsx
+++ b/src/components/market/ProductForm.tsx
@@ -12,11 +12,12 @@ import {
} from "@components/Field";
import { Button } from "@components/ui";
import useFormWithError from "@hooks/useFormWithError";
-import { ProductFormSchema, ProductFormType } from "@schemas/product";
+import { ProductFormSchema, ProductFormType } from "@/service/product.schema";
import { zodResolver } from "@hookform/resolvers/zod";
-import { Product } from "@type/product";
+import { Product } from "@/service/product.type";
import { FieldAdapter } from "@components/adaptor/rhf";
import { useRouter } from "next/navigation";
+import { isAxiosError } from "axios";
interface ProductAddFormProps {
mode: "add";
@@ -62,8 +63,12 @@ export default function ProductForm(props: ProductFormProps) {
mode === "add" ? "성공적으로 작성했습니다." : "성공적으로 수정했습니다."
);
router.replace(id ? `/items/${id}` : "/items");
- } catch (err) {
- throw err;
+ } catch (error) {
+ throw new Error(
+ isAxiosError(error)
+ ? error.response?.data.message
+ : "알 수 없는 에러가 발생했습니다."
+ );
}
}
diff --git a/src/app/(common)/(market)/items/(lists)/_components/ProductItem.module.scss b/src/components/market/ProductItem.module.scss
similarity index 100%
rename from src/app/(common)/(market)/items/(lists)/_components/ProductItem.module.scss
rename to src/components/market/ProductItem.module.scss
diff --git a/src/app/(common)/(market)/items/(lists)/_components/ProductItem.tsx b/src/components/market/ProductItem.tsx
similarity index 96%
rename from src/app/(common)/(market)/items/(lists)/_components/ProductItem.tsx
rename to src/components/market/ProductItem.tsx
index 0dbb3f603..24aafc3a0 100644
--- a/src/app/(common)/(market)/items/(lists)/_components/ProductItem.tsx
+++ b/src/components/market/ProductItem.tsx
@@ -3,7 +3,7 @@ import Link from "next/link";
import { Like, Thumbnail } from "@components/ui";
import { toWon } from "@util/formatter";
import styles from "./ProductItem.module.scss";
-import { Product } from "@type/product";
+import { Product } from "@/service/product.type";
function HighLightWithKeyword({
content,
diff --git a/src/app/(common)/(market)/items/(lists)/_components/ProductList.module.scss b/src/components/market/ProductList.module.scss
similarity index 100%
rename from src/app/(common)/(market)/items/(lists)/_components/ProductList.module.scss
rename to src/components/market/ProductList.module.scss
diff --git a/src/app/(common)/(market)/items/(lists)/_components/ProductList.tsx b/src/components/market/ProductList.tsx
similarity index 76%
rename from src/app/(common)/(market)/items/(lists)/_components/ProductList.tsx
rename to src/components/market/ProductList.tsx
index acbe48d52..2681a0e7b 100644
--- a/src/app/(common)/(market)/items/(lists)/_components/ProductList.tsx
+++ b/src/components/market/ProductList.tsx
@@ -4,46 +4,56 @@ import { useEffect } from "react";
import useParams from "@/hooks/useParams";
import usePagination from "@/hooks/usePagination";
import useResponsive from "@/hooks/useResponsive";
-import { Product } from "@type/product";
-import { PaginationResponse } from "@/types/common";
import { Message } from "@components/ui";
import { Pagination } from "@/components/Pagination";
import ProductListWrapper from "./ProductListWrapper";
import ProductItem from "./ProductItem";
+import { useGetProducts } from "@/service/product.queries";
+import { Loading } from "@/components/ui/Loading";
-interface ProductListProps {
- data: PaginationResponse
;
-}
-
-export default function ProductList({ data }: ProductListProps) {
+export default function ProductList() {
const { searchParams, handleParams } = useParams();
+
const page = Number(searchParams.get("page")) || 1;
const currentPageSize = Number(searchParams.get("pageSize")) || 10;
const keyword = searchParams.get("keyword") || "";
+ const orderBy = searchParams.get("orderBy") || "recent";
+ const visibleCount = 5;
const pageSize = useResponsive({
pc: 10,
tablet: 6,
mobile: 4,
});
- const visibleCount = 5;
- const { list, totalCount } = data;
- useEffect(() => {
- if (pageSize === currentPageSize) return;
-
- handleParams({ pageSize });
- }, [pageSize, currentPageSize, handleParams]);
+ const { data, isPending } = useGetProducts("all", {
+ page,
+ pageSize,
+ keyword,
+ orderBy,
+ });
const pagination = usePagination({
page,
pageSize,
- totalCount,
+ totalCount: data?.totalCount || 0,
visibleCount,
onChange: (pageNumber) => {
handleParams({ page: pageNumber.toString() });
},
});
+ const list = data?.list ?? [];
+
+ useEffect(() => {
+ if (pageSize === currentPageSize) return;
+
+ handleParams({ pageSize });
+ }, [pageSize, currentPageSize, handleParams]);
+
+ if (isPending) {
+ return loading...;
+ }
+
if (list.length === 0) {
return (
diff --git a/src/app/(common)/(market)/items/(lists)/_components/ProductListWrapper.module.scss b/src/components/market/ProductListWrapper.module.scss
similarity index 100%
rename from src/app/(common)/(market)/items/(lists)/_components/ProductListWrapper.module.scss
rename to src/components/market/ProductListWrapper.module.scss
diff --git a/src/app/(common)/(market)/items/(lists)/_components/ProductListWrapper.tsx b/src/components/market/ProductListWrapper.tsx
similarity index 90%
rename from src/app/(common)/(market)/items/(lists)/_components/ProductListWrapper.tsx
rename to src/components/market/ProductListWrapper.tsx
index 0a5ec7e4d..bb52e1745 100644
--- a/src/app/(common)/(market)/items/(lists)/_components/ProductListWrapper.tsx
+++ b/src/components/market/ProductListWrapper.tsx
@@ -1,6 +1,6 @@
import { ReactNode } from "react";
import clsx from "clsx";
-import { ListMode, Product } from "@/types/product";
+import { ListMode, Product } from "@/service/product.type";
import styles from "./ProductListWrapper.module.scss";
interface ProductListWrapper {
diff --git a/src/components/ui/Dropdown.tsx b/src/components/ui/Dropdown.tsx
index 27e5f4f0b..91139dbf0 100644
--- a/src/components/ui/Dropdown.tsx
+++ b/src/components/ui/Dropdown.tsx
@@ -3,6 +3,7 @@
import {
cloneElement,
createContext,
+ isValidElement,
ReactElement,
ReactNode,
useContext,
@@ -115,9 +116,11 @@ function Menu({ children }: { children: ReactNode }) {
function Item({
onClick,
children,
+ asChild = false,
}: {
onClick?: () => void;
children: ReactNode;
+ asChild?: boolean;
}) {
const { setIsOpen } = useDropdownDispatch();
@@ -128,6 +131,20 @@ function Item({
}
}
+ if (
+ asChild &&
+ isValidElement<{ onClick?: () => void; className?: string }>(children)
+ ) {
+ return (
+
+ {cloneElement(children, {
+ onClick: handleClick,
+ className: styles.item,
+ })}
+
+ );
+ }
+
return (