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 (
+
+ );
+};
+
+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' ? (
+
+ ) : (
+
+ )}
+
+ );
+};
+
+export default Input;
diff --git a/src/pages/add-item/components/TagInput.jsx b/src/pages/add-item/components/TagInput.jsx
new file mode 100644
index 00000000..6c834c22
--- /dev/null
+++ b/src/pages/add-item/components/TagInput.jsx
@@ -0,0 +1,42 @@
+const TagInput = ({
+ tagInput,
+ handleTagChange,
+ handleTagKeyDown,
+ tag,
+ handleRemoveTag,
+}) => {
+ return (
+
+
+
+
+ {tag.map((tag, index) => (
+
+ #{tag}
+
+
+ ))}
+
+
+ );
+};
+
+export default TagInput;
diff --git a/src/pages/add-item/index.jsx b/src/pages/add-item/index.jsx
index ce861821..5c03c201 100644
--- a/src/pages/add-item/index.jsx
+++ b/src/pages/add-item/index.jsx
@@ -1,3 +1,15 @@
+import NavBar from '../../components/NavBar';
+import AddItemForm from './components/AddItemForm';
+
export default function AddItem() {
- return 상품추가페이지
;
+ return (
+ <>
+
+
+ >
+ );
}
diff --git a/src/pages/items/index.jsx b/src/pages/items/index.jsx
index ea010004..390122e3 100644
--- a/src/pages/items/index.jsx
+++ b/src/pages/items/index.jsx
@@ -82,7 +82,7 @@ export default function ItemPage() {
/>