Skip to content

Commit

Permalink
Merge pull request #176 from youmdang/React-염정훈-sprint6
Browse files Browse the repository at this point in the history
[염정훈] Sprint6
  • Loading branch information
jyh0521 authored Jun 30, 2024
2 parents 7038410 + 29f7f03 commit 8e866cd
Show file tree
Hide file tree
Showing 22 changed files with 602 additions and 91 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/node_modules
/.pnp
.pnp.js
.env

# testing
/coverage
Expand Down
23 changes: 23 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-native-dotenv": "^3.4.11",
"react-router-dom": "^6.23.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
Expand Down
Binary file added public/images/i-close.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/i-plus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/i-profile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="ko">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
Expand Down
9 changes: 4 additions & 5 deletions src/api.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
export async function getProducts({ pageSize, order }) {
const query = `pageSize=${pageSize}&orderBy=${order}`;
const response = await fetch(
`https://panda-market-api.vercel.app/products?page=1&${query}`
);
export async function getProducts({ page, pageSize, order }) {
const apiUrl = process.env.REACT_APP_API_URL;
const query = `page=${page}&pageSize=${pageSize}&orderBy=${order}`;
const response = await fetch(`${apiUrl}.vercel.app/products?${query}`);
const body = await response.json();
return body;
}
157 changes: 157 additions & 0 deletions src/components/AddItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import { useEffect, useRef, useState } from "react";

function AddItem() {
const [formData, setFormDate] = useState({
name: "",
info: "",
price: "",
tag: "",
});
const [addItemBtn, setAddItemBtn] = useState("");
const [btnDisabled, setBtnDisabled] = useState(true);
const [inputFileUrl, setInputFileUrl] = useState(null);
const inputFileImg = useRef(null);
const imgAccept = ".jpg, .jpeg, .png";

const inputChange = (e) => {
// input value 상태 변경
const { name, value } = e.target;
setFormDate({
...formData,
[name]: value,
});
};

const inputFileChange = () => {
const inputFile = inputFileImg.current.files[0];
console.log(inputFile);

if (inputFile) {
const fileUrl = URL.createObjectURL(inputFile);
setInputFileUrl(fileUrl);
}
};

const addImgDelete = () => {
setInputFileUrl(null);
};

const validAddItem = () => {
// 유효성 검사
if (
formData.name !== "" &&
formData.info !== "" &&
formData.price !== "" &&
formData.tag !== ""
) {
setAddItemBtn("on");
setBtnDisabled(false);
} else {
setAddItemBtn("");
setBtnDisabled(true);
}
};

useEffect(() => {
// input 데이터 변경 될때마다 유효성 검사 실행
validAddItem();
}, [formData]);

return (
<section className="add-item-wrap max-wrap">
<form method="post">
<div className="add-item-title">
<h2>상품 등록하기</h2>
<button type="button" disabled={btnDisabled} className={addItemBtn}>
등록
</button>
</div>
<div className="add-input">
<h3 className="add-input-title">상품 이미지</h3>
<div className="add-img-list">
<label htmlFor="add-input-img" className="add-img-area">
<img src="/images/i-plus.png" alt="플러스 아이콘" />
이미지 등록
</label>
<input
id="add-input-img"
type="file"
ref={inputFileImg}
accept={imgAccept}
onChange={inputFileChange}
/>
{inputFileUrl ? (
<div className="add-img-item">
<img src={inputFileUrl} alt="상품 등록 이미지" />
<button type="button" onClick={addImgDelete}></button>
</div>
) : (
""
)}
</div>
</div>
<div className="add-input">
<label htmlFor="add-input-name" className="add-input-title">
상풍명
</label>
<input
id="add-input-name"
type="text"
name="name"
placeholder="상품명을 입력해주세요."
value={formData.name}
onChange={inputChange}
/>
</div>
<div className="add-input">
<label htmlFor="add-input-info" className="add-input-title">
상품 소개
</label>
<textarea
id="add-input-info"
name="info"
placeholder="상품 소개를 입력해주세요."
value={formData.info}
onChange={inputChange}
></textarea>
</div>
<div className="add-input">
<label htmlFor="add-input-price" className="add-input-title">
판매가격
</label>
<input
id="add-input-price"
type="number"
name="price"
placeholder="판매 가격을 입력해주세요."
value={formData.price === NaN ? null : formData.price}
onChange={inputChange}
/>
</div>
<div className="add-input">
<label htmlFor="add-input-tag" className="add-input-title">
태그
</label>
<input
id="add-input-tag"
type="text"
name="tag"
placeholder="태그를 입력해주세요."
value={formData.tag}
onChange={inputChange}
/>
<ul className="tag-list">
<li>
티셔츠 <button type="button"></button>
</li>
<li>
상의 <button type="button"></button>
</li>
</ul>
</div>
</form>
</section>
);
}

export default AddItem;
74 changes: 48 additions & 26 deletions src/components/AllProduct.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Link } from "react-router-dom";
import { getProducts } from "../api.js";
import { useEffect, useState } from "react";

Expand All @@ -15,50 +16,70 @@ const responsivePageSize = () => {
}
};

const recent = "recent";
const favorite = "favorite";

function AllProduct() {
const [products, setProducts] = useState([]);
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [order, setOrder] = useState("recent");
const [order, setOrder] = useState(recent);
const [dropArrow, setDropArrow] = useState("");
const [dropDisplay, setDropDisplay] = useState("none");
const [orderTxt, setOrderTxt] = useState("최신순");
const [pagesNum, setPagesNum] = useState([1, 2]);

const handleLoad = async (options) => {
let { list } = await getProducts(options);
setProducts(list);
// console.log(list);
};

const handleDropClick = () => {
dropArrow === "" ? setDropArrow("on") : setDropArrow("");
dropDisplay === "none" ? setDropDisplay("block") : setDropDisplay("none");
setDropArrow(dropArrow === "" ? "on" : "");
setDropDisplay(dropDisplay === "none" ? "block" : "none");
};

const handleNewsOrder = (e) => {
const menuTxt = e.target.textContent;
setOrderTxt(menuTxt);
setDropArrow("");
setDropDisplay("none");
setOrder("recent");
setOrder(recent);
};

const handleBestOrder = (e) => {
const menuTxt = e.target.textContent;
setOrderTxt(menuTxt);
setDropArrow("");
setDropDisplay("none");
setOrder("favorite");
setOrder(favorite);
};

const pageNumClick = (page) => {
setPage(page);
};

const prevPageBtn = () => {
if (page !== 1) {
setPage(page - 1);
}
};

const nextPageBtn = () => {
if (page !== pagesNum.length) {
setPage(page + 1);
}
};

useEffect(() => {
handleLoad({ pageSize, order });
handleLoad({ page, pageSize, order });

const handleResize = () => {
setPageSize(responsivePageSize());
};

window.addEventListener("resize", handleResize);
}, [order, pageSize]);
}, [page, order, pageSize]);

return (
<>
Expand All @@ -67,7 +88,9 @@ function AllProduct() {
<h2>판매중인 상품</h2>
<div className="product-info-menu">
<input type="search" placeholder="검색할 상품을 입력해주세요." />
<button type="button">상품 등록하기</button>
<Link to="/AddItem" className="item-add-btn">
상품 등록하기
</Link>
<div className="drop-menu">
<p className={dropArrow} onClick={handleDropClick}>
{orderTxt}
Expand Down Expand Up @@ -118,27 +141,26 @@ function AllProduct() {
<div className="pageNav">
<ul>
<li>
<button type="button">
<button type="button" onClick={prevPageBtn}>
<img src="/images/i-arrow-left.png" alt="왼쪽 화살표" />
</button>
</li>
<li className="on">
<button type="button">1</button>
</li>
<li>
<button type="button">2</button>
</li>
<li>
<button type="button">3</button>
</li>
<li>
<button type="button">4</button>
</li>
<li>
<button type="button">5</button>
</li>
{pagesNum.map((pageNum) => {
return (
<li key={pageNum} className={pageNum === page ? "on" : ""}>
<button
type="button"
onClick={() => {
pageNumClick(pageNum);
}}
>
{pageNum}
</button>
</li>
);
})}
<li>
<button type="button">
<button type="button" onClick={nextPageBtn}>
<img src="/images/i-arrow-right.png" alt="왼쪽 화살표" />
</button>
</li>
Expand Down
Loading

0 comments on commit 8e866cd

Please sign in to comment.