diff --git a/docs/sprint6.md b/docs/sprint6.md
index 609f14d1..9f16be2b 100644
--- a/docs/sprint6.md
+++ b/docs/sprint6.md
@@ -11,25 +11,25 @@
- [x] 중고마켓 페이지 url path를 "/items"으로 설정하세요.
- [x] 페이지 주소가 "/items" 일 때 상단내비게이션바의 "중고마켓" 버튼의 색상은 "3692FF"입니다.
-- [ ] 중고마켓 페이지 판매 중인 상품은 본인이 만든 GET 메서드를 사용해 주세요.
-- [ ] 다만 좋아요 순 정렬 기능은 제외해 주세요.
-- [ ] 사진은 디폴트 이미지로 프론트엔드에서 처리해주세요.
-- [ ] 베스트 상품 목록 조회는 구현하지 않습니다.
-- [ ] '상품 등록하기' 버튼을 누르면 "/registration" 로 이동합니다. ( 빈 페이지 )
+- [x] 중고마켓 페이지 판매 중인 상품은 본인이 만든 GET 메서드를 사용해 주세요.
+- [x] 다만 좋아요 순 정렬 기능은 제외해 주세요.
+- [x] 사진은 디폴트 이미지로 프론트엔드에서 처리해주세요.
+- [x] 베스트 상품 목록 조회는 구현하지 않습니다.
+- [x] '상품 등록하기' 버튼을 누르면 "/registration" 로 이동합니다. ( 빈 페이지 )
### 상품 등록 페이지
-- [ ] PC, Tablet, Mobile 디자인에 해당하는 상품 등록 페이지를 만들어 주세요.
-- [ ] 상품 등록 url path는 "/registration"입니다.
-- [ ] 상품 등록은 본인이 만든 POST 메서드를 사용해 주세요.
-- [ ] 등록 성공 시, 해당 상품 상세 페이지로 이동합니다. (빈페이지)
+- [x] PC, Tablet, Mobile 디자인에 해당하는 상품 등록 페이지를 만들어 주세요.
+- [x] 상품 등록 url path는 "/registration"입니다.
+- [x] 상품 등록은 본인이 만든 POST 메서드를 사용해 주세요.
+- [x] 등록 성공 시, 해당 상품 상세 페이지로 이동합니다. (빈페이지)
## 심화 요구사항
### 상품 등록 페이지
-- [ ] 모든 입력 input box에 빈 값이 있을 경우, 등록 버튼이 비활성화됩니다.
-- [ ] 태그를 입력한 후 엔터키를 누르면, 그 태그가 칩 형태로 쌓입니다.
+- [x] 모든 입력 input box에 빈 값이 있을 경우, 등록 버튼이 비활성화됩니다.
+- [x] 태그를 입력한 후 엔터키를 누르면, 그 태그가 칩 형태로 쌓입니다.
- [ ] 상품명, 상품 소개, 판매 가격, 태그에 대한 유효성 검사 Custom Hook을 만들어주세요. 유효성 검사를 통과하지 않을 경우, 각 input에 빨간색 테두리와, 각각의 Input 아래에 빨간색 에러 메시지를 보여주세요.
- 유효한 조건
diff --git a/src/components/productRegistration/ProductNameInput.tsx b/src/components/productRegistration/ProductNameInput.tsx
index e37ddaaa..c2310608 100644
--- a/src/components/productRegistration/ProductNameInput.tsx
+++ b/src/components/productRegistration/ProductNameInput.tsx
@@ -8,7 +8,7 @@ const ProductNameInput = () => {
return (
상품명
- setProductName(e.target.value)} />
+ setProductName(e.target.value)} />
);
};
diff --git a/src/components/productRegistration/ProductPriceInput.tsx b/src/components/productRegistration/ProductPriceInput.tsx
index b0aeb1ac..dceec917 100644
--- a/src/components/productRegistration/ProductPriceInput.tsx
+++ b/src/components/productRegistration/ProductPriceInput.tsx
@@ -1,5 +1,5 @@
import { useAtom } from "jotai";
-import { TextArea, ProductInputContainer, RegistrationH2 } from "./ProductRegistrationComponent";
+import { ProductInputContainer, RegistrationH2, Input } from "./ProductRegistrationComponent";
import { productPriceState } from "../../jotai/atoms/productFormState";
const ProductPriceInput = () => {
@@ -8,7 +8,12 @@ const ProductPriceInput = () => {
return (
판매가격
-
);
};
diff --git a/src/components/productRegistration/ProductRegistrationComponent.tsx b/src/components/productRegistration/ProductRegistrationComponent.tsx
index 6d771528..dd12b7ac 100644
--- a/src/components/productRegistration/ProductRegistrationComponent.tsx
+++ b/src/components/productRegistration/ProductRegistrationComponent.tsx
@@ -1,17 +1,29 @@
-import { FormEvent, ReactNode } from "react";
+import { FormEvent, KeyboardEvent, ReactNode } from "react";
import styled from "styled-components";
import ProductNameInput from "./ProductNameInput";
import ProductDescriptionInput from "./ProductDescriptionInput";
import ProductPriceInput from "./ProductPriceInput";
import ProductTagsInput from "./ProductTagsInput";
import RegistrationTitle from "./RegistrationTitle";
+import { useAtom } from "jotai";
+import { productFormState } from "../../jotai/atoms/productFormState";
+import { createProduct } from "../../apis/ProductService";
+import { useNavigate } from "react-router-dom";
const ProductRegistrationForm = styled.form`
- margin-top: 2.6rem;
- margin-bottom: 16.2rem;
+ padding-top: 2.6rem;
+ padding-bottom: 16.2rem;
width: 120rem;
display: flex;
flex-direction: column;
+ ${(props) => props.theme.media.medium} {
+ width: 100%;
+ padding: 1.8rem 2.4rem 19.4rem 2.4rem;
+ }
+ ${(props) => props.theme.media.small} {
+ width: 100%;
+ padding: 2.4rem 1.6rem 18.6rem 1.6rem;
+ }
`;
export const RegistrationH2 = styled.h2`
@@ -38,10 +50,27 @@ export const TextArea = styled.textarea`
`;
function ProductRegistrationComponent({ children }: { children: ReactNode }) {
- const handleSubmit = (e: FormEvent) => {
+ const [productForm, setProductForm] = useAtom(productFormState);
+ const navigate = useNavigate();
+
+ const handleSubmit = async (e: FormEvent) => {
e.preventDefault();
+ const newProduct = await createProduct({ ...productForm, price: Number(productForm.price) });
+ setProductForm();
+ navigate(`/product/${newProduct._id}`);
+ };
+
+ const preventEnter = (e: KeyboardEvent) => {
+ if (e.key === "Enter") {
+ e.preventDefault();
+ }
};
- return {children};
+
+ return (
+
+ {children}
+
+ );
}
export default ProductRegistrationComponent;
diff --git a/src/components/productRegistration/ProductTagsInput.tsx b/src/components/productRegistration/ProductTagsInput.tsx
index cd8b83c6..dc8d2a59 100644
--- a/src/components/productRegistration/ProductTagsInput.tsx
+++ b/src/components/productRegistration/ProductTagsInput.tsx
@@ -19,6 +19,7 @@ const ProductTagsInput = () => {
태그
setProductTag(e.target.value)}
diff --git a/src/components/productRegistration/RegistrationTitle.tsx b/src/components/productRegistration/RegistrationTitle.tsx
index ab169b9d..dab2a2c2 100644
--- a/src/components/productRegistration/RegistrationTitle.tsx
+++ b/src/components/productRegistration/RegistrationTitle.tsx
@@ -1,4 +1,6 @@
+import { useAtomValue } from "jotai";
import styled from "styled-components";
+import { productFormState } from "../../jotai/atoms/productFormState";
const RegistrationTitleContainer = styled.div`
width: 100%;
@@ -22,10 +24,13 @@ const RegistrationButton = styled.button`
`;
const RegistrationTitle = () => {
+ const productForm = useAtomValue(productFormState);
+ const disabled = Object.entries(productForm).some((array) => !array[1].length);
+
return (
상품 등록하기
-
+
등록
diff --git a/src/jotai/atoms/productFormState.ts b/src/jotai/atoms/productFormState.ts
index 0d6e8eab..f6d182a9 100644
--- a/src/jotai/atoms/productFormState.ts
+++ b/src/jotai/atoms/productFormState.ts
@@ -10,9 +10,18 @@ export const productTagState = atom("");
export const productTagsState = atom([]);
-export const productForm = atom((get) => ({
- name: get(productNameState),
- description: get(productDescriptionState),
- price: get(productPriceState),
- tags: get(productTagsState),
-}));
+export const productFormState = atom(
+ (get) => ({
+ name: get(productNameState),
+ description: get(productDescriptionState),
+ price: get(productPriceState),
+ tags: get(productTagsState),
+ }),
+ (get, set) => {
+ set(productNameState, "");
+ set(productDescriptionState, "");
+ set(productPriceState, "");
+ set(productTagState, "");
+ set(productTagsState, []);
+ }
+);
diff --git a/src/pages/Product.tsx b/src/pages/Product.tsx
new file mode 100644
index 00000000..3d9005b4
--- /dev/null
+++ b/src/pages/Product.tsx
@@ -0,0 +1,10 @@
+import { useParams } from "react-router-dom";
+
+function Product() {
+ // 구현 예정
+ const { id } = useParams();
+
+ return {id}
;
+}
+
+export default Product;
diff --git a/src/router.tsx b/src/router.tsx
index 82e27263..e7e0188f 100644
--- a/src/router.tsx
+++ b/src/router.tsx
@@ -3,6 +3,7 @@ import Root from "./Root";
import Home from "./pages/Home";
import Products from "./pages/Products";
import ProductRegistrationComponent from "./pages/ProductRegistration";
+import Product from "./pages/Product";
const router = createBrowserRouter([
{
@@ -21,6 +22,10 @@ const router = createBrowserRouter([
path: "/registration",
element: ,
},
+ {
+ path: "/product/:id",
+ element: ,
+ },
],
},
]);