diff --git a/src/assets/deleteIcon.png b/src/assets/deleteIcon.png new file mode 100644 index 00000000..86ac5c07 Binary files /dev/null and b/src/assets/deleteIcon.png differ diff --git a/src/assets/plusIcon.png b/src/assets/plusIcon.png new file mode 100644 index 00000000..3e48a43c Binary files /dev/null and b/src/assets/plusIcon.png differ diff --git a/src/components/Header.jsx b/src/components/Header.jsx index 4e9fd554..797d44cb 100644 --- a/src/components/Header.jsx +++ b/src/components/Header.jsx @@ -49,7 +49,7 @@ const Header = () => { 자유게시판 중고마켓 diff --git a/src/components/pages/AddItem.jsx b/src/components/pages/AddItem.jsx index 4fcff77e..2ef8a287 100644 --- a/src/components/pages/AddItem.jsx +++ b/src/components/pages/AddItem.jsx @@ -1,6 +1,175 @@ +import { + itemWrapper, + addItem, + contentHeader, + headerButton, + addItemBox, + addItemImageWrapper, + plusIconStyle, + imgRowWrapper, + previewBox, + previewImg, + deleteImage, + alertMessage, + itemHashTagWrapper, + ItemTag, + hashTagContainer, +} from './AddItemStyle' +import plusIcon from '../../assets/plusIcon.png' +import deleteIcon from '../../assets/deleteIcon.png' +import { useRef, useState } from 'react'; + +/** @jsxImportSource @emotion/react */ const AddItem = () => { - return
AddItem
; + + const [imgPreviewUrl, setImgPreviewUrl] = useState(null); // 추가했을때 이미지프리뷰 + const [showWarning, setShowWarning] = useState(false); + const [itemName, setItemName] = useState(""); + const [itemDescription, setItemDiscription] = useState(""); + const [itemPrice, setItemPrice] = useState(""); + const [itemTag, setItemTag] = useState(""); + const [itemHashTag, setItemHashTag] = useState([]); + + const handleFileChange = (e) => { + const file = e.target.files?.[0]; + + if (imgPreviewUrl !== null) { + setShowWarning(true) + return + } + + if (file) { + const preview = URL.createObjectURL(file); + setImgPreviewUrl(preview) + } + } + + const handleFileDelete = () => { + setImgPreviewUrl(null); + setShowWarning(false); + } + + const handleSubmitButton = () => { + + } + + const handleDeleteTag = (tagToDelete) => { + setItemHashTag(itemHashTag.filter(tag => tag !==tagToDelete)); + } + + const tagEndRef = useRef(null); // 태그 생성시 스크롤 이동을 위함 + + return ( + <> +
+
+

상품 등록하기

+ +
+
+
+

상품 이미지

+
+ + {imgPreviewUrl && ( +
+ 선택한 사진 + +
+ )} +
+ +
+ + {showWarning && ( +

이미지는 한 장만 선택할 수 있습니다.

+ )} + +
+ + setItemName(e.target.value)}> +
+ +
+ + +
+ +
+ + setItemPrice(e.target.value)}> +
+ +
+ + setItemTag(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter"&& itemTag.trim() !== "") { + e.preventDefault(); + + const newTag = itemTag.trim(); + if (!itemHashTag.includes(newTag)) { + setItemHashTag((prev) => [...prev, newTag]) + } + setItemTag("") + //태그 생성시 스크롤 이동 + setTimeout(() => { + tagEndRef.current?.scrollIntoView({behavior: "smooth"}) + },0) + } + }} + > +
+ + {itemHashTag.length > 0 && ( +
+ {itemHashTag.map((tag) => ( +
+ + #{tag} + + +
+ ))} +
+
+ )} +
+ + + ); }; export default AddItem; \ No newline at end of file diff --git a/src/components/pages/AddItemStyle.js b/src/components/pages/AddItemStyle.js new file mode 100644 index 00000000..edc055e8 --- /dev/null +++ b/src/components/pages/AddItemStyle.js @@ -0,0 +1,201 @@ +import { css } from '@emotion/react'; + + +const itemWrapper = css` + + color: var(--gray-800); + font-weight: 700; + + > div { + margin-top: 32px; + } + + > div > input, textarea { + border-radius: 12px; + width: 100%; + height: 56px; + background: var(--gray-100); + margin-top: 16px; + padding-left: 20px; + border: none; + cursor: pointer; + + > span { + color: var(--gray-400); + font-weight: 400; + } + } + + > div > textarea { + height: 282px; + padding-top: 15px; + } + + // wrapper에 div 안 input, textarea, span 에 적용 + > div > input::placeholder, textarea::placeholder, span { + color: var(--gray-400); + font-weight: 400; + } +` + +const addItem = css` + max-width: 1200px; + margin: 0 auto; + padding: 0 16px; +` +const contentHeader = css` + width: auto; + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 24px; + > button { + border-radius: 8px; + border: none; + width: 74px; + height: 42px; + background: var(--gray-400); + color: white; + } +` + +const headerButton = css` + cursor: pointer; + + &:not(:disabled) { + background: var(--blue); + } + + &:disabled { + cursor: not-allowed; + } +` + +const addItemImageWrapper = css` + +` + +const addItemBox = css` + margin-top: 16px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 12px; + width: 282px; + aspect-ratio: 1/1; + background: var(--gray-100); + border-radius: 12px; + cursor: pointer; + + @media (max-width: 768px) { + width: 168px; + } +` + +const plusIconStyle = css` + width: 48px; + aspect-ratio: 1/1; +` + +const imgRowWrapper = css` + display: flex; + gap: 24px; + + @media (max-width: 768px) { + gap: 10px; + } +` + +const previewBox = css` + position: relative; + margin-top: 16px; + display: flex; + width: 282px; + aspect-ratio: 1/1; + + @media (max-width: 768px) { + width: 168px; + } + + > button { + position: absolute; + background: transparent; + border: none; + cursor: pointer; + top: 8px; + right: 8px; + transition: all 0.2s ease; + + &:hover { + transform: scale(1.1); + } + } +` + +const previewImg = css` + width: 100%; + aspect-ratio: 1/1; + object-fit: cover; + border-radius: 12px; +` + +const deleteImage = css` + width: 22px; + height: 24px; +` + +const alertMessage = css` + color: rgba(247, 71, 71, 1); + font-weight: 400; + font-size: 16px; +` + +const itemHashTagWrapper = css` + background: var(--gray-100); + border-radius: 26px; + display: inline-flex; + padding: 5px 12px 5px 16px;; + + > span { + color: var(--gray-800); + display: flex; + align-items: center; + } + + > button { + background: transparent; + border: none; + cursor: pointer; + padding-top: 2px; + } +` + +const ItemTag = css` + color: var(--gray-800); +` + +const hashTagContainer = css` + margin-top: 14px; + display: flex; + flex-wrap: wrap; + gap: 12px; +` + +export { + itemWrapper, + addItem, + contentHeader, + headerButton, + addItemBox, + addItemImageWrapper, + plusIconStyle, + imgRowWrapper, + previewBox, + previewImg, + deleteImage, + alertMessage, + itemHashTagWrapper, + ItemTag, + hashTagContainer, +}; \ No newline at end of file