diff --git a/src/App.jsx b/src/App.jsx index b7744c15..6d47df6a 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -8,7 +8,7 @@ export default function App() { } /> } /> - } /> + } /> ); } diff --git a/src/pages/add-item/components/AddItemForm.jsx b/src/pages/add-item/components/AddItemForm.jsx new file mode 100644 index 00000000..cef83520 --- /dev/null +++ b/src/pages/add-item/components/AddItemForm.jsx @@ -0,0 +1,190 @@ +import Input from './Input'; +import { useState, useRef, useEffect } from 'react'; +import TagInput from './TagInput'; + +const AddItemForm = () => { + const [formData, setFormData] = useState({ + name: '', + description: '', + price: '', + tag: [], + img: null, + }); + + const [tagInput, setTagInput] = useState(''); + const [productImg, setProductImg] = useState(null); + const [previewImg, setPreviewImg] = useState(null); + const [isSubmitable, setIsSubmitable] = useState(false); + const fileInputRef = useRef(null); + + useEffect(() => { + const { name, description, price, tag } = formData; + const allFilled = + name.trim() && + description.trim() && + price.trim() && + Array.isArray(tag) && + tag.length > 0; + setIsSubmitable(!!allFilled); + }, [formData]); + + const handleImgUpload = (e) => { + const file = e.target.files?.[0]; + if (!file) return; + + setProductImg(file); + + const reader = new FileReader(); + reader.onload = () => { + setPreviewImg(reader.result); + }; + reader.readAsDataURL(file); + + setFormData((prev) => ({ + ...prev, + img: file, + })); + }; + + const handleChange = (e) => { + const { name, value } = e.target; + setFormData((prev) => ({ + ...prev, + [name]: value, + })); + }; + + const handleTagChange = (e) => { + setTagInput(e.target.value); + }; + + const handleTagKeyDown = (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + const value = tagInput.trim(); + if (value && !formData.tag.includes(value)) { + setFormData((prev) => ({ + ...prev, + tag: [...prev.tag, value], + })); + setTagInput(''); + } + } + }; + + const handleRemoveTag = (tagToRemove) => { + setFormData((prev) => ({ + ...prev, + tag: prev.tag.filter((tag) => tag !== tagToRemove), + })); + }; + + const imgOnClick = () => { + fileInputRef.current?.click(); + }; + + return ( +
+
+
+

상품 등록하기

+ +
+ +
+

+ 상품 이미지 +

+
+
+
+
+
이미지 등록
+
+ + {previewImg && ( +
+ preview + +
+ )} +
+ + +
+ +
+ + + + + + + +
+
+
+ ); +}; + +export default AddItemForm; diff --git a/src/pages/add-item/components/Input.jsx b/src/pages/add-item/components/Input.jsx new file mode 100644 index 00000000..38341070 --- /dev/null +++ b/src/pages/add-item/components/Input.jsx @@ -0,0 +1,34 @@ +const Input = ({ + type = 'text', + placeholder = '입력', + value, + onChange, + inputName = '상품', + name, +}) => { + return ( +
+

{inputName}

+ {type === 'textarea' ? ( +