Skip to content

Commit

Permalink
sprint mission 6 제출합니다
Browse files Browse the repository at this point in the history
  • Loading branch information
BossTeemo committed Jun 28, 2024
1 parent 5871f30 commit 45603b6
Show file tree
Hide file tree
Showing 4 changed files with 328 additions and 7 deletions.
4 changes: 4 additions & 0 deletions src/components/Layout/Header.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
color: var(--blue);
}

.globalHeader nav ul li a.active {
color: #3692ff;
}

.loginLink {
font-size: 16px;
font-weight: 600;
Expand Down
11 changes: 8 additions & 3 deletions src/components/Layout/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React from "react";
import Logo from "../../assets/images/logo/logo.svg";
import { Link, NavLink } from "react-router-dom";
import { Link, NavLink, useLocation } from "react-router-dom";
import "./Header.css";

// react-router-dom의 NavLink를 이용하면 활성화된 네비게이션 항목을 하이라이트해줄 수 있어요!
function getLinkStyle({ isActive }) {
return { color: isActive ? "var(--blue)" : undefined };
}

function Header() {
const location = useLocation();

return (
<header className="globalHeader">
<div className="headerLeft">
Expand All @@ -24,7 +25,11 @@ function Header() {
</NavLink>
</li>
<li>
<NavLink to="/items" style={getLinkStyle}>
<NavLink
to="/items"
style={getLinkStyle}
className={location.pathname === "/additem" ? "active" : ""}
>
중고마켓
</NavLink>
</li>
Expand Down
171 changes: 171 additions & 0 deletions src/pages/AddItemPage/AddItemPage.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
.add-item-container {
padding: 20px;
max-width: 1200px;
margin: 0 auto;
display: flex;
flex-direction: column;
align-items: flex-start;
}

.main-title-wrapper {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}

.main-title {
font-size: 28px;
font-weight: 700;
line-height: 33.41px;
text-align: left;
}

.submit-button {
display: inline-block;
width: 88px;
height: 42px;
border-radius: 8px;
background: #9ca3af;
color: white;
border: none;
cursor: not-allowed;
}

.submit-button.active {
background-color: var(--blue);
cursor: pointer;
}

form {
width: 100%;
display: flex;
flex-direction: column;
}

.sub-title {
font-size: 18px;
font-weight: 700;
line-height: 21.48px;
text-align: left;
margin-bottom: 12px;
}

.image-upload {
margin-bottom: 24px;
display: flex;
flex-direction: row;
}

.image-upload-label {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
background: #f3f4f6;
padding: 50px;
text-align: center;
border-radius: 12px;
width: 282px;
height: 282px;
border: none;
color: #9ca3af;
margin-right: 24px;
}

.image-upload-label span {
font-size: 3rem;
}

#image-upload-input {
display: none;
}

.uploaded-image-container {
position: relative;
display: inline-block;
}

.uploaded-image {
width: 282px;
height: 282px;
object-fit: cover;
border-radius: 12px;
}

.remove-image-button {
position: absolute;
width: 20px;
height: 20px;
top: 8px;
right: 8px;
background-color: #3692ff;
color: white;
border: none;
border-radius: 50%;
cursor: pointer;
}

.add-item-container .form-input {
margin-bottom: 24px;
padding: 15px;
border: none;
border-radius: 12px;
width: 100%;
background: #f3f4f6;
box-sizing: border-box;
font-size: 16px;
font-weight: 400;
line-height: 24px;
text-align: left;
}

textarea.form-input {
height: 150px;
}

.tags-container {
margin-top: 10px;
display: flex;
flex-wrap: wrap;
}

.tag {
display: inline-block;
background-color: #f9fafb;
border-radius: 26px;
padding: 12px 12px 12px 16px;
margin-right: 12px;
margin-top: -12px;
}

.tag button {
width: 20px;
height: 20px;
background-color: #9ca3af;
color: #ffffff;
border: none;
border-radius: 9999px;
cursor: pointer;
margin-left: 5px;
}

@media (min-width: 768px) {
.form-input {
padding: 20px;
}
}

@media (min-width: 1024px) {
.form-input {
padding: 20px;
}
}

@media (min-width: 1280px) {
.form-input {
padding: 20px;
}
}
149 changes: 145 additions & 4 deletions src/pages/AddItemPage/AddItemPage.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,148 @@
import React from "react";
import React, { useState, useEffect } from "react";
import "./AddItemPage.css";

function AddItemPage() {
return <div>AddItemPage</div>;
}
const AddItemPage = () => {
const [formData, setFormData] = useState({
title: "",
description: "",
price: "",
tags: "",
image: null,
});

const [tags, setTags] = useState([]);
const [isFormValid, setIsFormValid] = useState(false);

const handleChange = (e) => {
const { name, value } = e.target;
setFormData({ ...formData, [name]: value });
};

const handleImageChange = (e) => {
if (e.target.files.length > 0) {
setFormData({ ...formData, image: e.target.files[0] });
}
};

const handleTagChange = (e) => {
if (e.key === "Enter") {
e.preventDefault();
const tagValue = e.target.value.trim();
if (tagValue && !tags.includes(tagValue)) {
setTags([...tags, tagValue]);
e.target.value = "";
}
}
};

const removeTag = (index) => {
setTags(tags.filter((_, i) => i !== index));
};

const removeImage = () => {
setFormData({ ...formData, image: null });
};

useEffect(() => {
const { title, description, price } = formData;
setIsFormValid(title && description && price);
}, [formData]);

const handleSubmit = (e) => {
e.preventDefault();
// 상품 등록 로직 구현
};

return (
<div className="add-item-container">
<div className="main-title-wrapper">
<div className="main-title">상품 등록하기</div>
<button
type="submit"
className={`submit-button ${isFormValid ? "active" : ""}`}
disabled={!isFormValid}
>
등록
</button>
</div>

<form onSubmit={handleSubmit}>
<h3 className="sub-title">상품 이미지</h3>
<div className="image-upload">
<label htmlFor="image-upload-input" className="image-upload-label">
<span>+</span>
<p>이미지 등록</p>
</label>
<input
id="image-upload-input"
type="file"
onChange={handleImageChange}
accept="image/*"
disabled={!!formData.image} // 이미지가 이미 업로드된 경우 비활성화
/>
{formData.image && (
<div className="uploaded-image-container">
<img
src={URL.createObjectURL(formData.image)}
alt="상품 이미지"
className="uploaded-image"
/>
<button
type="button"
className="remove-image-button"
onClick={removeImage}
>
X
</button>
</div>
)}
</div>
<h3 className="sub-title">상품명</h3>
<input
type="text"
name="title"
placeholder="상품명을 입력해주세요"
onChange={handleChange}
className="form-input"
value={formData.title}
/>
<h3 className="sub-title">상품 소개</h3>
<textarea
name="description"
placeholder="상품 소개를 입력해주세요"
onChange={handleChange}
className="form-input"
value={formData.description}
></textarea>
<h3 className="sub-title">판매가격</h3>
<input
type="number"
name="price"
placeholder="판매 가격을 입력해주세요"
onChange={handleChange}
className="form-input"
value={formData.price}
/>
<h3 className="sub-title">태그</h3>
<input
type="text"
placeholder="태그를 입력해주세요"
onKeyDown={handleTagChange}
className="form-input"
/>
<div className="tags-container">
{tags.map((tag, index) => (
<span key={index} className="tag">
{tag}{" "}
<button type="button" onClick={() => removeTag(index)}>
X
</button>
</span>
))}
</div>
</form>
</div>
);
};

export default AddItemPage;

0 comments on commit 45603b6

Please sign in to comment.