diff --git a/.gitignore b/.gitignore index 4d29575d..26d11f4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +node_modules # dependencies /node_modules @@ -21,3 +22,4 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + diff --git a/src/App.js b/src/App.js index d9fe58ce..b7283cd0 100644 --- a/src/App.js +++ b/src/App.js @@ -3,6 +3,7 @@ import Header from "./components/Header"; import HomePage from "./pages/Homepage/HomePage"; import CommunityPage from "./pages/CommunityPage/CommunityPage"; import ProductsPage from "./pages/ProductsPage/ProductsPage"; +import AddItemPage from "./pages/AddItemPage/AddItemPage"; import LoginPage from "./pages/LoginPage/LoginPage"; function App() { @@ -14,6 +15,7 @@ function App() { } /> } /> } /> + } /> } /> diff --git a/src/api.js b/src/api.js index 1d81755a..784c169d 100644 --- a/src/api.js +++ b/src/api.js @@ -10,3 +10,16 @@ export async function getProducts(params = {}) { const body = await response.json(); return body; } + + +export async function postProducts(data) { + const response = await fetch(`${BASE_URL}/products`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(data), + }); + + if (!response.ok) throw new Error("상품 등록 실패"); + + return await response.json(); +} diff --git a/src/assets/X.png b/src/assets/X.png new file mode 100644 index 00000000..009ff15c Binary files /dev/null and b/src/assets/X.png differ diff --git a/src/assets/plus.png b/src/assets/plus.png new file mode 100644 index 00000000..df2fb448 Binary files /dev/null and b/src/assets/plus.png differ diff --git a/src/components/Header.css b/src/components/Header.css index 33a07c69..ff554b75 100644 --- a/src/components/Header.css +++ b/src/components/Header.css @@ -8,6 +8,11 @@ align-items: center; } + +.logo img { + display: none; +} + .logo { display: flex; justify-content: center; @@ -42,6 +47,11 @@ } @media (min-width: 768px) { + + .logo img { + display: block; + } + .logo a { font-size: 25.63px; } diff --git a/src/pages/AddItemPage/AddItemPage.jsx b/src/pages/AddItemPage/AddItemPage.jsx new file mode 100644 index 00000000..fcee6a04 --- /dev/null +++ b/src/pages/AddItemPage/AddItemPage.jsx @@ -0,0 +1,202 @@ +import { useRef, useState } from "react"; +import "./additem.css"; +import { postProducts } from "../../api"; +import plus from "../../assets/plus.png"; +import xbtn from "../../assets/X.png"; + +function AddItemPage() { + const [newItem, setNewItem] = useState({ + images: null, + tagInput: "", + tags: [], + price: "", + description: "", + name: "", + }); + + const [imageAlert, setImageAlert] = useState(""); + const fileInputRef = useRef(null); + + const handleInputChange = (field, value) => { + setNewItem((prev) => ({ ...prev, [field]: value })); + }; + + const handleTagKeyDown = (e) => { + if (e.key === "Enter" && newItem.tagInput.trim() !== "") { + e.preventDefault(); + const newTag = newItem.tagInput.trim(); + if (!newItem.tags.includes(newTag)) { + setNewItem((prev) => ({ + ...prev, + tags: [...prev.tags, newTag], + tagInput: "", + })); + } + } + }; + + const handleRemoveTag = (tagToRemove) => { + setNewItem((prev) => ({ + ...prev, + tags: prev.tags.filter((tag) => tag !== tagToRemove), + })); + }; + + const handleImageClick = () => { + if (newItem.images) { + setImageAlert(`*이미지 등록은 최대 1개까지 가능합니다.`); + return; + } + fileInputRef.current.click(); + }; + + const handleCreateItem = async () => { + const itemData = { + images: newItem.images, + tags: newItem.tags, + price: newItem.price, + description: newItem.description, + name: newItem.name, + }; + + const result = await postProducts(itemData); + + if (result) { + setNewItem({ + images: null, + tags: [], + price: "", + description: "", + name: "", + }); + } + }; + + const isFormValid = + newItem.name.trim() !== "" && + newItem.description.trim() !== "" && + newItem.price !== "" && + newItem.tags.length > 0; + + return ( + <> +
+
+

상품 등록하기

+ +
+
+
+

상품 이미지

+
+ + {newItem.images && ( +
+ preview + +
+ )} +
+ {imageAlert &&

{imageAlert}

} +
+
+

상품명

+ handleInputChange("name", e.target.value)} + className="item__input" + placeholder="상품명을 입력해주세요" + /> +
+
+

상품 소개

+