diff --git a/public/ic_X.svg b/public/ic_X.svg
new file mode 100644
index 00000000..f6674f7f
--- /dev/null
+++ b/public/ic_X.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/App.jsx b/src/App.jsx
index 121e62d4..333937d6 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -22,7 +22,7 @@ function App() {
} />
} />
} />
- } />
+ } />
);
diff --git a/src/components/AddItem/AddItem.jsx b/src/components/AddItem/AddItem.jsx
new file mode 100644
index 00000000..749260c6
--- /dev/null
+++ b/src/components/AddItem/AddItem.jsx
@@ -0,0 +1,107 @@
+import { useState } from "react";
+
+import ProductImg from "./components/ProductImg";
+import styles from "./styles/AddItem.module.css";
+
+export default function AddItemContent() {
+ const [productName, setProductName] = useState("");
+ const [description, setDescription] = useState("");
+ const [price, setPrice] = useState("");
+ const [tagInput, setTagInput] = useState("");
+ const [tags, setTags] = useState([]);
+ const [imagePreview, setImagePreview] = useState(null);
+
+ const isFormValid =
+ productName && description && price && tags.length > 0 && imagePreview;
+
+ const handleKeyDown = (e) => {
+ if (e.key === "Enter") {
+ e.preventDefault();
+ const trimmed = tagInput.trim();
+ if (trimmed && !tags.includes(trimmed)) {
+ setTags((prev) => [...prev, trimmed]);
+ setTagInput("");
+ }
+ }
+ };
+
+ const handleDelete = (targetTag) => {
+ setTags((prevTags) => prevTags.filter((tag) => tag !== targetTag));
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/AddItem/components/ProductImg.jsx b/src/components/AddItem/components/ProductImg.jsx
new file mode 100644
index 00000000..b9a1a176
--- /dev/null
+++ b/src/components/AddItem/components/ProductImg.jsx
@@ -0,0 +1,54 @@
+import { useRef, useState } from "react";
+import styles from "./styles/ProductImg.module.css";
+
+export default function ProductImg({ preview, setPreview }) {
+ const inputRef = useRef(null);
+
+ const handleImageChange = (e) => {
+ const file = e.target.files?.[0];
+
+ if (preview) {
+ alert("이미지는 한 개만 업로드할 수 있습니다.");
+ return;
+ }
+
+ if (file) {
+ const reader = new FileReader();
+ reader.onloadend = () => {
+ setPreview(reader.result);
+ };
+ reader.readAsDataURL(file);
+ }
+ };
+
+ const handleDelete = () => {
+ setPreview(null);
+ };
+
+ return (
+
+
+
+ {preview && (
+
+
+

+
+ )}
+
+ );
+}
diff --git a/src/components/AddItem/components/styles/ProductImg.module.css b/src/components/AddItem/components/styles/ProductImg.module.css
new file mode 100644
index 00000000..4106c706
--- /dev/null
+++ b/src/components/AddItem/components/styles/ProductImg.module.css
@@ -0,0 +1,77 @@
+.wrapper {
+ display: flex;
+ gap: 2.4rem;
+}
+
+.uploadBox {
+ width: 28.2rem;
+ height: 28.2rem;
+ background-color: var(--gray100);
+ border-radius: 1.2rem;
+
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+
+ cursor: pointer;
+ overflow: hidden;
+
+ flex-shrink: 0;
+}
+
+.textContainer {
+ display: inline-flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.plus {
+ font-size: 5rem;
+ font-weight: 100;
+ color: var(--gray400);
+}
+
+.text {
+ font-size: 1rem;
+ color: var(--gray400);
+ font-weight: 400;
+}
+
+.imagePreviewBox {
+ width: 28.2rem;
+ height: 28.2rem;
+ border-radius: 1.2rem;
+ overflow: hidden;
+ position: relative;
+
+ flex-shrink: 0;
+}
+
+.previewImg {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ display: block;
+}
+
+.deleteButton {
+ position: absolute;
+ top: 8px;
+ right: 15px;
+
+ width: 20px;
+ height: 20px;
+}
+
+@media (max-width: 768px) {
+ .uploadBox {
+ width: 16.8rem;
+ height: 16.8rem;
+ }
+
+ .imagePreviewBox {
+ width: 16.8rem;
+ height: 16.8rem;
+ }
+}
diff --git a/src/components/AddItem/styles/AddItem.module.css b/src/components/AddItem/styles/AddItem.module.css
new file mode 100644
index 00000000..9faf8c31
--- /dev/null
+++ b/src/components/AddItem/styles/AddItem.module.css
@@ -0,0 +1,144 @@
+.container {
+ margin-top: 2.4rem;
+ margin-bottom: 6.9rem;
+
+ width: 120rem;
+ height: 100%;
+
+ margin-inline: auto;
+
+ display: flex;
+ flex-direction: column;
+ gap: 3.2rem;
+}
+
+.addContainer {
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.addTitle {
+ font-size: 2rem;
+ font-weight: 700;
+ line-height: 3.2rem;
+}
+
+.addBtn {
+ display: flex;
+ height: 42px;
+ padding: 1.2rem 2.3rem;
+ justify-content: center;
+ align-items: center;
+ gap: 1rem;
+
+ border-radius: 0.8rem;
+ background: var(--blue);
+
+ font-size: 1.6rem;
+ font-weight: 400;
+ color: var(--white);
+}
+
+.addBtn:hover {
+ background: var(--hover-button);
+}
+
+.addBtn:disabled {
+ background: var(--gray400);
+
+ font-size: 1.6rem;
+ font-weight: 400;
+ color: var(--gray100);
+
+ cursor: not-allowed;
+}
+
+.contentContainer {
+ display: flex;
+ flex-direction: column;
+ gap: 1.6rem;
+}
+
+.title {
+ font-size: 1.8rem;
+ font-weight: 700;
+}
+
+.input {
+ width: 100%;
+ height: 5.6rem;
+
+ border-radius: 1.2rem;
+}
+
+.input::placeholder {
+ font-size: 1.6rem;
+ color: var(--gray400);
+}
+
+.inputDescription {
+ resize: none;
+ width: 100%;
+ height: 28.2rem;
+ border-radius: 1.2rem;
+ border: none;
+ background-color: var(--gray100);
+
+ font-size: 1.6rem;
+ line-height: 2.4rem;
+
+ padding: 1.5rem 2.3rem;
+}
+
+.inputDescription::placeholder {
+ font-size: 1.6rem;
+ color: var(--gray400);
+}
+
+.tagList {
+ display: flex;
+ gap: 1.2rem;
+}
+
+.tag {
+ width: 11rem;
+ height: 3.6rem;
+ border-radius: 2.6rem;
+
+ position: relative;
+
+ background-color: var(--gray100);
+
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ gap: 0.8rem;
+
+ font-size: 1.6rem;
+ font-weight: 400;
+}
+
+.deleteBtn {
+ width: 2rem;
+ height: 2rem;
+}
+
+.deleteImg {
+ width: 100%;
+ height: 100%;
+}
+
+@media (max-width: 768px) {
+ .container {
+ width: 69.6rem;
+ }
+}
+
+@media (max-width: 426px) {
+ .container {
+ width: 34.4rem;
+ }
+}
diff --git a/src/components/Item/AllItems.jsx b/src/components/Item/AllItems.jsx
index 0f0fe909..61d0a608 100644
--- a/src/components/Item/AllItems.jsx
+++ b/src/components/Item/AllItems.jsx
@@ -4,8 +4,8 @@ import debounce from "lodash/debounce";
import { getProducts } from "../../api/itemAPI";
import { Link } from "react-router-dom";
-import ItemList from "./ItemList";
-import PageNation from "./PageNation";
+import ItemList from "./component/ItemList";
+import PageNation from "./component/PageNation";
import "./AllItem.css";
import Dropdown from "./component/Dropdown.jsx";
@@ -77,7 +77,7 @@ function AllItem() {
className="item-search"
placeholder="검색할 상품을 입력해주세요"
/>
-
+
상품 등록하기
diff --git a/src/components/Item/BestItem.jsx b/src/components/Item/BestItem.jsx
index 9bedb83a..3fd976ed 100644
--- a/src/components/Item/BestItem.jsx
+++ b/src/components/Item/BestItem.jsx
@@ -1,7 +1,7 @@
import { useState, useEffect, useCallback } from "react";
import debounce from "lodash/debounce";
-import ItemList from "./ItemList";
+import ItemList from "./component/ItemList";
import { getProducts } from "../../api/itemAPI";
const getPageSize = () => {
diff --git a/src/components/Item/ItemCard.css b/src/components/Item/component/ItemCard.css
similarity index 100%
rename from src/components/Item/ItemCard.css
rename to src/components/Item/component/ItemCard.css
diff --git a/src/components/Item/ItemCard.jsx b/src/components/Item/component/ItemCard.jsx
similarity index 100%
rename from src/components/Item/ItemCard.jsx
rename to src/components/Item/component/ItemCard.jsx
diff --git a/src/components/Item/ItemList.css b/src/components/Item/component/ItemList.css
similarity index 100%
rename from src/components/Item/ItemList.css
rename to src/components/Item/component/ItemList.css
diff --git a/src/components/Item/ItemList.jsx b/src/components/Item/component/ItemList.jsx
similarity index 100%
rename from src/components/Item/ItemList.jsx
rename to src/components/Item/component/ItemList.jsx
diff --git a/src/components/Item/PageNation.css b/src/components/Item/component/PageNation.css
similarity index 100%
rename from src/components/Item/PageNation.css
rename to src/components/Item/component/PageNation.css
diff --git a/src/components/Item/PageNation.jsx b/src/components/Item/component/PageNation.jsx
similarity index 100%
rename from src/components/Item/PageNation.jsx
rename to src/components/Item/component/PageNation.jsx
diff --git a/src/pages/AddItem.jsx b/src/pages/AddItem.jsx
index 95cf562b..72635533 100644
--- a/src/pages/AddItem.jsx
+++ b/src/pages/AddItem.jsx
@@ -1,5 +1,15 @@
+import AddItemContent from "../components/AddItem/AddItem";
+import Banner from "../components/Item/Banner";
+
function AddItem() {
- return 상품 등록 페이지
;
+ return (
+ <>
+
+
+ >
+ );
}
export default AddItem;
diff --git a/src/pages/Item.jsx b/src/pages/Item.jsx
index 856baa31..800d585e 100644
--- a/src/pages/Item.jsx
+++ b/src/pages/Item.jsx
@@ -7,7 +7,10 @@ import "../styles/item.css";
function Item() {
return (
<>
-
+
+
diff --git a/src/styles/common.css b/src/styles/common.css
index 6a3e4ae5..f84704a9 100644
--- a/src/styles/common.css
+++ b/src/styles/common.css
@@ -28,6 +28,8 @@ html {
button {
background-color: transparent;
border: none;
+ cursor: pointer;
+ padding: 0;
}
ul {
@@ -39,3 +41,12 @@ ul {
a {
text-decoration: none;
}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ margin: 0;
+}
diff --git a/vite.config.js b/vite.config.js
index 8b0f57b9..4990a01f 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,7 +1,8 @@
-import { defineConfig } from 'vite'
-import react from '@vitejs/plugin-react'
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
// https://vite.dev/config/
export default defineConfig({
+ base: "/",
plugins: [react()],
-})
+});