diff --git a/index.html b/index.html index 0c589ecc..c258e483 100644 --- a/index.html +++ b/index.html @@ -2,9 +2,13 @@ - - Vite + React + + + + + 판다마켓 +
diff --git a/public/favicon.png b/public/favicon.png new file mode 100644 index 00000000..299d0960 Binary files /dev/null and b/public/favicon.png differ diff --git a/public/vite.svg b/public/vite.svg deleted file mode 100644 index e7b8dfb1..00000000 --- a/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/icons/plus.svg b/src/assets/icons/plus.svg new file mode 100644 index 00000000..5bb9abf5 --- /dev/null +++ b/src/assets/icons/plus.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/icons/x.svg b/src/assets/icons/x.svg new file mode 100644 index 00000000..f6674f7f --- /dev/null +++ b/src/assets/icons/x.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/components/Button.jsx b/src/components/Button.jsx index 63addf4c..5a107124 100644 --- a/src/components/Button.jsx +++ b/src/components/Button.jsx @@ -1,8 +1,19 @@ -function Button({ children, onClick }) { +function Button({ children, type, onClick, disabled }) { + const buttonStyles = { + login: "w-128 h-48 rounded-lg bg-blue100 text-lg text-white font-semibold", + shopping: + "w-357 h-56 rounded-[40px] bg-blue100 text-2lg tablet:text-xl text-white font-semibold", + additem: + "py-8 px-24 rounded-lg bg-blue100 text-lg text-white font-semibold", + upload: + "w-74 h-42 rounded-lg bg-blue100 text-lg text-white font-semibold disabled:bg-gray400 disabled:cursor-not-allowed", + }; + return ( diff --git a/src/components/Header.jsx b/src/components/Header.jsx index 3fb49d47..c42f11e9 100644 --- a/src/components/Header.jsx +++ b/src/components/Header.jsx @@ -4,6 +4,7 @@ import logoText from "../assets/images/logo_text.svg"; import profile from "../assets/icons/profile.svg"; function Header() { + const active = location.pathname === "/items" || "/additems"; return (
@@ -16,9 +17,7 @@ function Header() { 자유게시판 - + 중고마켓 diff --git a/src/components/InputField.jsx b/src/components/InputField.jsx new file mode 100644 index 00000000..1374f2c5 --- /dev/null +++ b/src/components/InputField.jsx @@ -0,0 +1,31 @@ +function inputField({ type, label, value, onChange, onKeyDown, placeholder }) { + if (type === "input") { + return ( +
+
{label}
+ +
+ ); + } else if (type === "textarea") { + return ( +
+
{label}
+ +
+ ); + } +} + +export default inputField; diff --git a/src/components/ItemControls.jsx b/src/components/ItemControls.jsx index c0908222..7da6b757 100644 --- a/src/components/ItemControls.jsx +++ b/src/components/ItemControls.jsx @@ -18,7 +18,9 @@ function ItemControl({ isMobile, options }) {
전체상품
- +
@@ -44,7 +46,9 @@ function ItemControl({ isMobile, options }) { placeholder="검색할 상품을 입력해주세요" />
- +
diff --git a/src/pages/AddItemPage.jsx b/src/pages/AddItemPage.jsx index 7fe47cbc..bb355a64 100644 --- a/src/pages/AddItemPage.jsx +++ b/src/pages/AddItemPage.jsx @@ -1,5 +1,148 @@ +import { useState, useRef } from "react"; +import Button from "../components/Button"; +import Header from "../components/Header"; +import InputField from "../components/InputField"; +import plus from "../assets/icons/plus.svg"; +import x from "../assets/icons/x.svg"; + function AddItemPage() { - return
hi
; + const imgRef = useRef(null); + const [imgPreview, setImgPreview] = useState(""); + const [itemName, setItemName] = useState(""); + const [itemDetail, setItemDetail] = useState(""); + const [price, setPrice] = useState(""); + const [tagInput, setTagInput] = useState(""); + const [tags, setTags] = useState([]); + const isFormValid = itemName && itemDetail && price && tags.length > 0; + + const handleUploadImg = (e) => { + const file = e.target.files[0]; + if (file) { + const previewUrl = URL.createObjectURL(file); + setImgPreview(previewUrl); + } + }; + const handleDeleteImg = () => { + setImgPreview(""); + if (imgRef.current) { + imgRef.current.value = null; + } + }; + + const handleEnterTag = (e) => { + if (e.key === "Enter" && !e.nativeEvent.isComposing) { + e.preventDefault(); + const newTag = tagInput.trim(); + if (newTag && !tags.includes(newTag)) { + setTags([...tags, newTag]); + } + setTagInput(""); + } + }; + const handleDeleteTag = (index) => { + const newTags = [...tags]; + newTags.splice(index, 1); + setTags(newTags); + }; + + return ( +
+
+
+
+
상품 등록하기
+ +
+
+
상품 이미지
+
+ + {imgPreview ? ( + <> + 미리보기 + + + ) : ( + "" + )} +
+ {imgPreview ? ( +
+ *이미지 등록은 최대 1개까지 가능합니다. +
+ ) : ( + "" + )} +
+ setItemName(e.target.value)} + placeholder="상품명을 입력해주세요" + /> + setItemDetail(e.target.value)} + placeholder="상품 소개를 입력해주세요" + /> + setPrice(e.target.value)} + placeholder="판매 가격을 입력해주세요" + /> + setTagInput(e.target.value)} + onKeyDown={handleEnterTag} + placeholder="태그를 입력해주세요" + /> +
+ {tags.map((tag, index) => { + return ( + + #{tag} + handleDeleteTag(index)} + /> + + ); + })} +
+
+
+ ); } export default AddItemPage; diff --git a/src/pages/ItemsPage.jsx b/src/pages/ItemsPage.jsx index 8e42db29..24e0fc71 100644 --- a/src/pages/ItemsPage.jsx +++ b/src/pages/ItemsPage.jsx @@ -11,7 +11,7 @@ function ItemsPage() { const [sort, setSort] = useState("recent"); const [totalProducts, setTotalProducts] = useState(1); const [bestProducts, setBestProducts] = useState([]); - const [best, setBest] = useState(4); + const [best, setBest] = useState(""); const [totalPages, setTotalPages] = useState(1); const [itemsPerPage, setItemsPerPage] = useState(10); const [currentPage, setCurrentPage] = useState(1); diff --git a/src/pages/MainPage.jsx b/src/pages/MainPage.jsx index ef976150..e52bb485 100644 --- a/src/pages/MainPage.jsx +++ b/src/pages/MainPage.jsx @@ -1,4 +1,4 @@ -import { Link } from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; import MainSection from "../components/MainSection"; import logo from "../assets/images/logo.svg"; import logoText from "../assets/images/logo_text.svg"; @@ -7,8 +7,15 @@ import bottomImg from "../assets/images/home_bottom.svg"; import img1 from "../assets/images/home_01.svg"; import img2 from "../assets/images/home_02.svg"; import img3 from "../assets/images/home_03.svg"; +import Button from "../components/Button"; function MainPage() { + const navigate = useNavigate(); + + const handleButtonClick = () => { + navigate("/items"); + }; + return (
@@ -17,7 +24,9 @@ function MainPage() {
- +
@@ -27,9 +36,9 @@ function MainPage() { 일상의 모든 물건을
거래해보세요 - - - +